您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
base64코드 자동복호화
当前为
// ==UserScript== // @name kone base64 자동복호화 // @namespace http://tampermonkey.net/ // @version 0.241 // @description base64코드 자동복호화 // @author SYJ // @match https://arca.live/* // @match https://kone.gg/s/somisoft* // @icon https://www.google.com/s2/favicons?sz=64&domain=arca.live // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @license MIT // ==/UserScript== // 자주 바뀜. 취약한 셀렉터 const SHADOW_ROOT_SELECTOR = "body main div.prose-container"; async function main(){ const isAutoMode = await GM_getValue('toggleVal', true); if (isAutoMode) { setTimeout(autoApply, 1000); } else { setTimeout(manuallyApply, 1000); } } function doDecode(text) { ///'use strict'; let result = text; result = dec(/aHR0c[0-9A-Za-z+]{20,}[=]{0,2}/, result); //aHR0c:1회인코딩된것. result = dec(/YUhSMGN[0-9A-Za-z]{20,}[=]{0,2}/, result); //YUhSMGN:2회인코딩된것. result = dec(/WVVoU01HTklUVFp[0-9A-Za-z+]{20,}[=]{0,2}/, result); //aHR0c:1회인코딩된것. result = dec(/V1ZWb1UwMUhUa2[0-9A-Za-z]{20,}[=]{0,2}/, result); //YUhSMGN:2회인코딩된것. result = dec(/[0-9A-Za-z]{30,}[=]{1,2}/, result); //문자열 30회 + '=' 1~2회 result = dec(/[0-9A-Za-z]{200,}[=]{0,2}/, result); //문자열 200회 + '=' 0~2회 return result; } function dec(reg, text) { let result = text; try { while (reg.test(result)) { const original = reg.exec(result)[0]; let decoded = original; while (decoded.match(/aHR0c[0-9A-Za-z]{8,}[=]{0,2}/) == null){ decoded = atob(decoded); } decoded = atob(decoded); console.log(decoded); result = result.replace(original, decoded); } return result; } catch(e) { console.log('er', e); return text;} } function applyATag(el){ if (original === decodedLink) return; while(el.firstChild) el.removeChild(el.firstChild); el.appendChild(makeATag(decodedLink)); } function manuallyApply() { document.body.addEventListener('dblclick', function(e) { console.log('더블클릭 감지! 🎉',e.target,event.composedPath()[0]); const el = e.composedPath()[0]; const nodes = Array.from(el.childNodes).filter(node=>node.nodeType ===Node.TEXT_NODE) for (const node of nodes){ const original = node.textContent; const decodedLink = doDecode(original); console.log(node, original, decodedLink); if (original === decodedLink) return; linkifyTextNode(node, decodedLink); } }) } // 텍스트노드 중 url을 찾아 a태그로 변환. (액션 포함) function linkifyTextNode(Node, text) { // URL 매칭 (https:// 로 시작해서 공백 전까지) const urlRegex = /(https?:\/\/[^\s]+)/; const match = urlRegex.exec(text); if (!match) return; // URL 없으면 종료 const url = match[0]; const start = match.index; const urlLen = url.length; // "텍스트1 URL 텍스트2" 꼴의 텍스트노드를 세 개로 분리 // 1) URL 앞부분과 뒤를 분리 const textNode = document.createTextNode(text); const afterUrlStart = textNode.splitText(start); const afterUrlEnd = afterUrlStart.splitText(urlLen); const beforeUrlStart = textNode; // 3) <a> 요소 생성 후 URL 텍스트 노드 대신 교체 const a = makeATag(url) Node.parentNode.replaceChild(a, Node); a.before(beforeUrlStart); a.after(afterUrlEnd); } function autoApply() { const contents = Array.from(document.body.querySelectorAll('main p')); const mainContents = Array.from(document.querySelector(SHADOW_ROOT_SELECTOR)?.shadowRoot?.querySelectorAll('p') ?? []); contents.push(...mainContents); for (const tag of contents) { const nodes = Array.from(tag.childNodes).filter(node=>node.nodeType ===Node.TEXT_NODE) for (const node of nodes){ const original = node.textContent; const decodedLink = doDecode(original); if (original === decodedLink) {continue;} linkifyTextNode(node, decodedLink); } } } function makeATag(link){ const aTag = document.createElement('a'); aTag.href = link; aTag.textContent = link; aTag.target = '_blank'; aTag.rel = 'noreferrer'; return aTag; } window.addEventListener('load', ()=>{ main(); setInterval(main, 1500); }); // UI /* 프롬프트형 입력 (async function(){ let v = await GM_getValue('myValue', 123); let menuId; function registerMenu(){ if(menuId) GM_unregisterMenuCommand(menuId); // 레이블에 현재 v 를 포함 menuId = GM_registerMenuCommand( `설정 입력 (현재 값: ${v})`, async () => { const input = prompt('새 값을 입력하세요:', v); if(input !== null){ const n = parseInt(input); if(!isNaN(n)){ v = n; await GM_setValue('myValue', v); registerMenu(); // 메뉴 레이블 갱신 } else { alert('숫자만 입력하세요'); } } } ); } registerMenu(); // — 여기서 v 를 실제 화면에 표시하거나 쓰고 싶다면, // document.body.append(`현재 값: ${v}`) 같은 DOM 추가로 처리하세요. })(); */ (async function() { // 1) 값 로드 let val = await GM_getValue('toggleVal', false); let menuId; // 2) 배지 생성 /* const badge = document.createElement('div'); Object.assign(badge.style, { position: 'fixed', top: '10px', right: '10px', padding: '4px 8px', background: 'rgba(0,0,0,0.7)', color: '#fff', fontSize: '14px', borderRadius: '4px', zIndex: '9999', }); document.body.append(badge); */ // 3) 렌더 함수 function render() { // 메뉴 해제 후 다시 등록 if (menuId) GM_unregisterMenuCommand(menuId); menuId = GM_registerMenuCommand( `자동모드 토글 (현재: ${val?'ON':'OFF'})`, toggleValue ); // 배지 업데이트 //badge.textContent = `현재 값: ${val}`; } // 4) 토글 함수 (즉시 UI 업데이트 포함) async function toggleValue() { const newVal = !val; await GM_setValue('toggleVal', newVal); val = newVal; // 변수 갱신 render(); // 메뉴·배지 즉시 갱신 } // 초기 렌더 render(); })();