Auto somi

자동 복호화/국룰입력/다운(Kiosk, Mega, GoogleDrive, goFile)

当前为 2025-05-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Auto somi
  3. // @name:ko 자동 소미
  4. // @namespace http://tampermonkey.net/
  5. // @description 자동 복호화/국룰입력/다운(Kiosk, Mega, GoogleDrive, goFile)
  6. // @version new 2.8
  7. // @author 김머시기
  8. // @match https://kiosk.ac/c/*
  9. // @match https://kio.ac/c/*
  10. // @match https://kone.gg/*
  11. // @match https://arca.live/b/*
  12. // @match https://mega.nz/*
  13. // @match https://gofile.io/d/*
  14. // @match https://workupload.com/*
  15. // @match https://drive.google.com/file/d/*
  16. // @match https://drive.google.com/drive/folders/*
  17. // @match https://drive.usercontent.google.com/download?id*
  18. // @icon https://lh3.google.com/u/0/d/18OVO7VmnwIuHK6Ke-z7035wKFmMKZ28W=w1854-h959-iv1
  19. // @grant GM.setValue
  20. // @grant GM.getValue
  21. // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
  22. // @grant GM.registerMenuCommand
  23. // @grant GM_registerMenuCommand
  24. // @grant GM_unregisterMenuCommand
  25. // @grant GM_getValue
  26. // @grant GM_setValue
  27. // @license MIT
  28. // @run-at document-end
  29. // ==/UserScript==
  30. 'use strict';
  31. let chkp = [,,,, atob('c29taXNvZnQ=')], Down_Option, PageLoading = [], isT = [,,], MenuID = [null, null], host = document.URL.split('/')[2], npw = [], pw = [atob('c29taXNvZnQ='),atob('MjAyNXNvbWlzb2Z0'),
  32. // =============================== Settings =======================================
  33. // 추가하길 원하는 비밀번호 따옴표 - 쉼표로 구분해서 바로 아래줄에 넣으면 됨 ex) '1234', '2024국룰', '!국룰!'
  34.  
  35. ];
  36. PageLoading[0] = 1000;     // 페이지 로딩 시간 조절 (1000당 1초)
  37. Down_Option = 0;           // Kiosk 다운로드 옵션 0:Basic, 1:Fast, 2:일괄 다운로드
  38. // ======================================================================================
  39.  
  40. function getKoneGGContentElement() {
  41.     if (host !== 'kone.gg') return null;
  42.     const proseContainer = document.querySelector('div.prose-container');
  43.     if (!proseContainer || !proseContainer.shadowRoot) return null;
  44.     const contentDiv = proseContainer.shadowRoot.querySelector('div.content');
  45.     return contentDiv;
  46. }
  47.  
  48.  
  49.  
  50. function handleBlockingModals(currentHost) {
  51.     if (currentHost === 'kone.gg') {
  52.         const nsfwOverlayContainer = document.querySelector('div.relative.min-h-60 > div.absolute.w-full.h-full.backdrop-blur-2xl');
  53.         if (nsfwOverlayContainer && nsfwOverlayContainer.offsetParent !== null) {
  54.             const viewContentButton = nsfwOverlayContainer.querySelector('div.flex.gap-4 button:nth-child(2)');
  55.             if (viewContentButton && viewContentButton.textContent?.includes('콘텐츠 보기')) {
  56.                 viewContentButton.click();
  57.                 return new Promise(resolve => setTimeout(resolve, 500));
  58.             } else {
  59.                 const modalSelectorsKone = [
  60.                     '.age-verification-popup',
  61.                     '.content-overlay.block',
  62.                 ];
  63.                 modalSelectorsKone.forEach(selector => hideElement(selector));
  64.             }
  65.         }
  66.     } else if (currentHost === 'arca.live') {
  67.         const modalSelectorsArca = [
  68.             { selector: '.adult-confirm-modal', action: 'hide' },
  69.             { selector: '.fc-dialog', action: 'hide' },
  70.             { selector: '#preview-block-layer', action: 'hide' },
  71.             { selector: 'div[class*="adult-channel-confirm"]', action: 'hide' },
  72.             { selector: 'div.modal[data-id="confirmAdult"] div.modal-footer button.btn-primary', action: 'click'},
  73.             { selector: 'button.btn-primary.btn.text-light[data-bs-dismiss="modal"]', action: 'click' }
  74.         ];
  75.         modalSelectorsArca.forEach(item => {
  76.             const elements = document.querySelectorAll(item.selector);
  77.             elements.forEach(element => {
  78.                 if (element && element.offsetParent !== null) {
  79.                     if (item.action === 'click') {
  80.                         element.click();
  81.                     } else {
  82.                         hideElement(item.selector);
  83.                     }
  84.                 }
  85.             });
  86.         });
  87.     }
  88.  
  89.     function hideElement(selector) {
  90.         try {
  91.             const elements = document.querySelectorAll(selector);
  92.             if (elements.length > 0) {
  93.                 elements.forEach(el => {
  94.                     if (el.offsetParent !== null) {
  95.                         el.style.setProperty('display', 'none', 'important');
  96.                     }
  97.                 });
  98.             }
  99.         } catch (e) {
  100.             console.error(e);
  101.         }
  102.     }
  103.     return Promise.resolve();
  104. }
  105.  
  106.  
  107. async function toggleDown(){
  108. isT[0]=!isT[0];
  109. if(!isT[0] && isT[1]){
  110. isT[1]=false;
  111. await GM.setValue('isT[1]', isT[1]);
  112. }
  113. await GM.setValue('isT[0]', isT[0]);
  114. updateDown();
  115. updateTab();
  116. }
  117. async function toggleTab(){
  118. isT[1]=!isT[1];
  119. if(!isT[0] && isT[1]){
  120. isT[0]=true;
  121. await GM.setValue('isT[0]', isT[0]);
  122. }
  123. await GM.setValue('isT[1]', isT[1]);
  124. updateDown();
  125. updateTab();
  126. }
  127. function updateDown(){
  128. if(MenuID[0] !==null)GM_unregisterMenuCommand(MenuID[0]);
  129. MenuID[0]=GM_registerMenuCommand(`자동 다운로드  ${isT[0] ? 'ON' : 'OFF'}`, toggleDown, { autoClose: false, title: `자동 다운로드 ${isT[0] ? '켜짐' : '꺼짐'}`});
  130. }
  131. function updateTab(){
  132. if(MenuID[1] !==null)GM_unregisterMenuCommand(MenuID[1]);
  133. MenuID[1]=GM_registerMenuCommand(`자동 닫기  ${isT[1] ? 'ON' : 'OFF'}`, toggleTab, { autoClose: false, title: `자동 닫기 ${isT[1] ? '켜짐' : '꺼짐'}`});
  134. }
  135. function doDec() {
  136.     if (chkp[3] !== chkp[4]) return;
  137.  
  138.     let targets = [];
  139.  
  140.     if (host === 'arca.live') {
  141.         targets = [
  142.             document.querySelector('body div.article-body > div.fr-view.article-content'),
  143.             ...document.querySelectorAll('div.article-comment#comment div.comment-content, div.article-comment div.comment-content')
  144.         ].filter(el => el !== null);
  145.     } else if (host === 'kone.gg') {
  146.         const koneContentElement = getKoneGGContentElement();
  147.         const comments = document.querySelectorAll('p.text-sm.max-w-xl.whitespace-pre-wrap');
  148.         const listItems = document.querySelectorAll('ol.list-decimal li p');
  149.         targets = [koneContentElement, ...comments, ...listItems].filter(el => el !== null);
  150.     }
  151.  
  152.     if (targets.length === 0 || (targets.length === 1 && !targets[0])) return;
  153.  
  154.     function dec(target, reg) {
  155.         try {
  156.             if (!target || !target.innerHTML) return;
  157.             const original = target.innerHTML;
  158.             const matches = [...original.matchAll(reg)];
  159.             if (matches.length === 0) return;
  160.  
  161.             let result = original;
  162.             let decodedCount = 0;
  163.             for (const match of matches) {
  164.                 let encoded = match[0];
  165.                 let decoded = encoded;
  166.                 try {
  167.                     while (decoded && typeof decoded === 'string' && !decoded.startsWith('http') && decoded.length > 10 && decoded.length < 1000) {
  168.                         let tempDecoded = atob(decoded);
  169.                         if (tempDecoded === decoded) break;
  170.                         decoded = tempDecoded;
  171.                     }
  172.                     if (decoded && typeof decoded === 'string' && decoded.startsWith('http')) {
  173.                         const linkHTML = `<a href="${decoded}" target="_blank" rel="noreferrer" style="color:#007bff; text-decoration:underline; word-break:break-all;">${decoded}</a>`;
  174.                         result = result.replace(encoded, linkHTML);
  175.                             decodedCount++;
  176.                     }
  177.                 } catch (e) {
  178.                 }
  179.             }
  180.             if (target.innerHTML !== result) {
  181.                 target.innerHTML = result;
  182.             }
  183.         } catch (e) {
  184.             console.error(e, target);
  185.         }
  186.     }
  187.  
  188.     for (const target of targets) {
  189.         if (!target) continue;
  190.         const links = target.querySelectorAll('a');
  191.         links.forEach(a => {
  192.             a.setAttribute('rel', 'noreferrer');
  193.         });
  194.  
  195.         dec(target, /aHR0c[0-9A-Za-z+/=]{8,}/g);
  196.         dec(target, /YUhSMG[0-9A-Za-z+/=]{8,}/g);
  197.         dec(target, /WVVoU[0-9A-Za-z+/=]{8,}/g);
  198.         dec(target, /V1ZWb[0-9A-Za-z+/=]{8,}/g);
  199.     }
  200.     setTimeout(doDlsiteContextAware, 100);
  201. }
  202.  
  203.  
  204. function doDlsiteContextAware() {
  205.     let atc;
  206.     if (host === 'arca.live') {
  207.         atc = document.querySelector('.article-body .article-content');
  208.     } else if (host === 'kone.gg') {
  209.         atc = getKoneGGContentElement();
  210.     }
  211.  
  212.     if (!atc) return;
  213.  
  214.     let titleEl;
  215.     if (host === 'arca.live') {
  216.         titleEl = document.querySelector('.title-row .title') || document.querySelector('.board-title .title');
  217.     } else if (host === 'kone.gg') {
  218.         titleEl = [...document.querySelectorAll('h1')].find(el =>
  219.             el.textContent?.match(/RJ[0-9]{6,10}/i)
  220.         );
  221.     }
  222.  
  223.     const keywordPattern = /(꺼|거|퍼|RJ|rj|Rj|rJ|VJ|vj|Vj|vJ|DL|dl|Dl|dL)[\s:()\[\]#-]*([0-9]{6,10})/g;
  224.     const fullRJPattern = /\b(RJ|rj|Rj|rJ|VJ|vj|Vj|vJ|퍼|꺼|거|DL|dl|Dl|dL)([0-9]{6,10})\b/g;
  225.  
  226.     let titleText = '';
  227.     if (titleEl?.childNodes) {
  228.         titleText = Array.from(titleEl.childNodes)
  229.             .map(n => n.textContent?.trim() || '')
  230.             .join(' ');
  231.     }
  232.  
  233.     const bodyText = atc.textContent || '';
  234.     const fullText = titleText + '\n' + bodyText;
  235.  
  236.     const matchList1 = [...fullText.matchAll(keywordPattern)].map(m => ({ prefix: m[1], code: m[2] }));
  237.     const matchList2 = [...fullText.matchAll(fullRJPattern)].map(m => ({ prefix: m[1], code: m[2] }));
  238.  
  239.     const linkCodes = Array.from(atc.querySelectorAll('a[href]'))
  240.         .map(a => {
  241.             const match = a.href.match(/(RJ|VJ)([0-9]{6,10})/i);
  242.             return match ? { prefix: match[1].toUpperCase(), code: match[2] } : null;
  243.         })
  244.         .filter(Boolean);
  245.  
  246.     const splitNodeMatches = [];
  247.     const allNodes = [...atc.querySelectorAll('*:not(script):not(style):not(a)')];
  248.     const validPrefixes = ['꺼','거','퍼','RJ','rj','Rj','rJ','VJ','vj','Vj','vJ','DL','dl','Dl','dL'];
  249.  
  250.     for (const node of allNodes) {
  251.         const children = [...node.childNodes];
  252.         for (let i = 0; i < children.length - 1; i++) {
  253.             const a = children[i], b = children[i + 1];
  254.             if (a.nodeType !== Node.TEXT_NODE || b.nodeType !== Node.TEXT_NODE) continue;
  255.  
  256.             const aText = (a.textContent || '').replace(/\s+/g, '');
  257.             const bText = (b.textContent || '').trim();
  258.             if (!/^\d{6,10}$/.test(bText)) continue;
  259.             for (const prefix of validPrefixes) {
  260.                 if (aText.endsWith(prefix)) {
  261.                     splitNodeMatches.push({ prefix, code: bText });
  262.                     break;
  263.                 }
  264.             }
  265.         }
  266.     }
  267.  
  268.     const extraFromTitle = [];
  269.     const matchInTitleStart = titleText.match(/^[\[]?([0-9]{6,10})[\]]?/);
  270.     if (matchInTitleStart) extraFromTitle.push({ prefix: 'RJ', code: matchInTitleStart[1] });
  271.  
  272.     const allCodes = [
  273.         ...matchList1,
  274.         ...matchList2,
  275.         ...linkCodes,
  276.         ...splitNodeMatches,
  277.         ...extraFromTitle
  278.     ];
  279.  
  280.     const seen = new Set();
  281.     const uniqueCodes = allCodes.filter(({ code }) => {
  282.         if (!code || seen.has(code)) return false;
  283.         seen.add(code);
  284.         return true;
  285.     });
  286.  
  287.     if (uniqueCodes.length === 1) {
  288.         const { code, prefix } = uniqueCodes[0];
  289.         if (!code) return;
  290.  
  291.         const mappedPrefix = ['vj', 'vJ', 'Vj', 'VJ', '퍼'].includes(prefix.toLowerCase()) ? 'VJ'
  292.                             : ['rj', 'rJ', 'Rj', 'RJ', '꺼', '거', 'dl', 'dL', 'Dl', 'DL'].includes(prefix.toLowerCase()) ? 'RJ'
  293.                             : prefix.toUpperCase();
  294.  
  295.         const fullCode = `${mappedPrefix}${code}`;
  296.         const link = `https://www.dlsite.com/maniax/work/=/product_id/${fullCode}.html`;
  297.  
  298.         const existing = atc.querySelector('.dlsite-link-appended');
  299.         if (existing) existing.remove();
  300.  
  301.         const wrapper = document.createElement('div');
  302.         wrapper.className = 'dlsite-link-appended';
  303.         wrapper.style.marginTop = '15px';
  304.         wrapper.style.padding = '10px 0';
  305.         wrapper.style.borderTop = '1px dashed #aaa';
  306.  
  307.         const a = document.createElement('a');
  308.         a.href = link;
  309.         a.target = '_blank';
  310.         a.rel = 'noreferrer';
  311.         a.textContent = `[DLsite] ${fullCode}`;
  312.         a.style.display = 'block';
  313.         a.style.marginBottom = '5px';
  314.         a.style.color = '#1e90ff';
  315.  
  316.         wrapper.appendChild(a);
  317.         atc.appendChild(wrapper);
  318.         return;
  319.     }
  320.  
  321.  
  322.     if (uniqueCodes.length > 1) {}
  323.     const combinedPattern = new RegExp(`${keywordPattern.source}|${fullRJPattern.source}`, 'gi');
  324.     let linkConversionCount = 0;
  325.  
  326.     const walk = (node) => {
  327.         if (node.nodeType === Node.TEXT_NODE) {
  328.             const text = node.textContent;
  329.             if (!text) return;
  330.             let lastIndex = 0;
  331.             let match;
  332.             const frag = document.createDocumentFragment();
  333.  
  334.             while ((match = combinedPattern.exec(text)) !== null) {
  335.                 const before = text.slice(lastIndex, match.index);
  336.                 const number = match[2] || match[4];
  337.                 const prefix = (match[1] || match[3] || '').toLowerCase();
  338.                 const mappedPrefix = ['vj', 'vJ', 'Vj', 'VJ', '퍼'].includes(prefix) ? 'VJ'
  339.                                     : ['rj', 'rJ', 'Rj', 'RJ', '꺼', '거', 'dl', 'dL', 'Dl', 'DL'].includes(prefix) ? 'RJ'
  340.                                     : prefix.toUpperCase();
  341.                 const fullCode = `${mappedPrefix}${number}`;
  342.  
  343.                 const a = document.createElement('a');
  344.                 a.href = `https://www.dlsite.com/maniax/work/=/product_id/${fullCode}.html`;
  345.                 a.textContent = match[0];
  346.                 a.target = '_blank';
  347.                 a.rel = 'noreferrer';
  348.                 a.style.color = '#1e90ff';
  349.  
  350.                 if (before) frag.appendChild(document.createTextNode(before));
  351.                 frag.appendChild(a);
  352.                     linkConversionCount++;
  353.                 lastIndex = match.index + match[0].length;
  354.             }
  355.  
  356.             if (lastIndex < text.length) {
  357.                 frag.appendChild(document.createTextNode(text.slice(lastIndex)));
  358.             }
  359.  
  360.             if (frag.childNodes.length > 0 && node.parentNode && frag.textContent !== node.textContent) {
  361.                  node.parentNode.replaceChild(frag, node);
  362.             }
  363.         } else if (
  364.             node.nodeType === Node.ELEMENT_NODE &&
  365.             node.tagName &&
  366.             !['A', 'SCRIPT', 'STYLE'].includes(node.tagName.toUpperCase())
  367.         ) {
  368.             for (const child of [...node.childNodes]) {
  369.                 walk(child);
  370.             }
  371.         }
  372.     };
  373.  
  374.     walk(atc);
  375.     if(linkConversionCount > 0) {}
  376. }
  377.  
  378.  
  379. async function chkPW(){
  380. chkp[3]=await GM.getValue('chkp[3]');
  381. isT[0]=await GM.getValue('isT[0]', true);
  382. isT[1]=await GM.getValue('isT[1]', false);
  383. updateDown();
  384. updateTab();
  385.  
  386. if(host=='arca.live' || host=='kone.gg'){
  387. if(chkp[3] !=chkp[4]){
  388. const chk=prompt(decodeURI(atob('JUVBJUI1JUFEJUVCJUEzJUIwJUVEJTk5JTk1JUVDJTlEJUI4')));
  389. if(chk?.toLowerCase()==chkp[4]) {
  390.                 await GM.setValue('chkp[3]', chkp[4]);
  391.             } else {
  392. GM.setValue('chkp[3]', false);
  393. alert(decodeURI(atob('JUVBJUI1JUFEJUVCJUEzJUIwJUVDJTlEJUI0JTIwJUVDJTlEJUJDJUVDJUI5JTk4JUVEJTk1JTk4JUVDJUE3JTgwJTIwJUVDJTk1JThBJUVDJThBJUI1JUVCJThCJTg4JUVCJThCJUE0')));
  394. }
  395. } else {
  396.         }
  397. }
  398. }
  399. async function inputPW() {
  400.     let inputElem = document.querySelector(chkp[0]), btnElem = document.querySelector(chkp[1]);
  401.     if (!inputElem ) {
  402.         if (isT[0] === true && !document.querySelector('.files-list, #download-section')) {
  403.              await setTimeout(DBtn, PageLoading[1] || 1000);
  404.         }
  405.         return;
  406.     }
  407.  
  408.     const combinedPw = [...new Set([...pw, ...npw])];
  409.  
  410.     if (chkp[3] == chkp[4]) {
  411.         try {
  412.             for (let i = 0; i < combinedPw.length; i++) {
  413.                 if (!combinedPw[i]) continue;
  414.                 if (!inputElem) break;
  415.  
  416.                 inputElem.value = combinedPw[i];
  417.  
  418.                 if (host == 'kio.ac') {
  419.                     inputElem.dispatchEvent(new Event('input', { bubbles: true }));
  420.                     inputElem.dispatchEvent(new Event('change', { bubbles: true }));
  421.                     await new Promise(res => setTimeout(res, 50));
  422.                     if(btnElem) btnElem.click();
  423.                 } else {
  424.                     if(btnElem) btnElem.click();
  425.                     else {
  426.                         const enterEvent = new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true });
  427.                         inputElem.dispatchEvent(enterEvent);
  428.                     }
  429.                 }
  430.  
  431.                 await new Promise(res => setTimeout(res, 800));
  432.  
  433.                 const successIndicator = document.querySelector('.files-list, #download-section, .download-link, .btn-download, .main-button-download');
  434.                 const errorIndicator = document.querySelector('.text-error, .text-red-500, .error-message, .incorrect-password, [class*="error"], [id*="error"]');
  435.  
  436.                 if (successIndicator && successIndicator.offsetParent !== null) {
  437.                     break;
  438.                 } else if (errorIndicator && errorIndicator.offsetParent !== null) {
  439.                     if (inputElem) inputElem.value = '';
  440.                 } else {
  441.                 }
  442.             }
  443.             if (isT[0] == true) {
  444.                 await setTimeout(DBtn, PageLoading[1] || 1000);
  445.             }
  446.  
  447.         } catch (e) {
  448.             console.error(e);
  449.             if (isT[0] == true) {
  450.                 await setTimeout(DBtn, PageLoading[1] || 1000);
  451.             }
  452.         }
  453.     } else {
  454.     }
  455. }
  456.  
  457. async function kioskdone(){
  458. try {
  459. await new Promise(res=> setTimeout(res, 3000));
  460. for(var i=0, jj=0; jj!=1; i++){
  461. console.log(i);
  462. await new Promise(res=> setTimeout(res, 1000));
  463. if(document.querySelector('.flex.flex-row.text-xs.justify-between div:nth-child(2)').innerText=='done'){
  464. console.log(i);
  465. await setTimeout(()=> { window.open('', '_self').close()}, 2000);
  466. jj++;
  467. }
  468. }
  469. } catch(e){ if(isT[1]==true && isT[2]==true)setTimeout(()=> { window.open('', '_self').close()}, 1000); }
  470. }
  471. async function DBtn(){
  472. if(isT[0] !== true) {
  473.         return;
  474.     }
  475.  
  476. if(host=='mega.nz') {
  477.         try {
  478.             const resumeButton = document.querySelector('.mega-button.positive.resume.js-resume-download');
  479.             if (resumeButton) {
  480.                 resumeButton.click();
  481.                 await new Promise(res => setTimeout(res, 500));
  482.             }
  483.  
  484.             const standardDownloadButton = document.querySelector('.mega-button.positive.js-default-download.js-standard-download');
  485.             if (standardDownloadButton) {
  486.                 standardDownloadButton.click();
  487.                 await new Promise(res => setTimeout(res, 2000));
  488.             }
  489.  
  490.             const continueDownloadButton = document.querySelector('.mega-button.large.positive.download.continue-download');
  491.             if (continueDownloadButton) {
  492.                 continueDownloadButton.click();
  493.             }
  494.         } catch(e) {
  495.             console.error(e);
  496.         }
  497.     } else {
  498.         try {
  499.             let btns = document.querySelectorAll(chkp[2]);
  500.             let delayMultiplier = (PageLoading[0] || 1000) + 600;
  501.             if(btns.length > 1){
  502.                 btns.forEach((btn, index) => {
  503.                     setTimeout(() => {
  504.                         btn.click();
  505.                     }, index * delayMultiplier);
  506.                 });
  507.             } else if(btns.length === 1){
  508.                 btns[0].click();
  509.             } else {
  510.             }
  511.         } catch(e){ console.error(e); }
  512.     }
  513.  
  514. if(isT[1]==true && isT[2]==true){
  515.         let btnsForDelay = document.querySelectorAll(chkp[2]);
  516. let totalDelay = (btnsForDelay.length > 1) ? (btnsForDelay.length * ((PageLoading[0] || 1000) + 600) + 700) : 1300;
  517. if(host=='kiosk.ac'){
  518. setTimeout(()=> { kioskdone(); }, totalDelay);
  519. } else if(host=='kio.ac'){
  520. setTimeout(()=> { window.open('', '_self').close()}, totalDelay+1000);
  521. } else {
  522. setTimeout(()=> { window.open('', '_self').close()}, totalDelay);
  523. }
  524. }
  525. }
  526.  
  527. function FindPW(){
  528.     let atc;
  529.     if (host === 'arca.live') {
  530.         atc = document.querySelector('body div.article-body > div.fr-view.article-content');
  531.     } else if (host === 'kone.gg') {
  532.         atc = getKoneGGContentElement();
  533.     }
  534.  
  535.     if (!atc || !atc.innerHTML) return;
  536.  
  537.     let tempContent = atc.innerHTML;
  538.     tempContent=tempContent.replace(/ /g, ' ').replace(/( ){2,}/g, ' ');
  539. tempContent=tempContent.replace(/국룰/g, 'ㄱㄹ');
  540.  
  541. let regexx=/(대문자)/;
  542.  
  543. if(regexx.test(tempContent)) {
  544.         const smpeopleUpper = atob('U01QRU9QTEU=');
  545.         if (npw.indexOf(smpeopleUpper) === -1) {
  546.             npw.push(smpeopleUpper);
  547.         }
  548.     }
  549.  
  550. function dec(reg){
  551.         let foundPasswordsInDec = 0;
  552. try {
  553.             let currentLoopContent = tempContent;
  554.             const processedTexts = new Set();
  555.  
  556. while(true){
  557.                 const matchResult = reg.exec(currentLoopContent);
  558.                 if (!matchResult) break;
  559.  
  560. let matchedText = matchResult[0];
  561.                 if (processedTexts.has(matchedText)) {
  562.                     currentLoopContent = currentLoopContent.replace(matchedText, `__SKIPPED_${Math.random().toString(36).substring(2, 10)}__`);
  563.                     continue;
  564.                 }
  565.  
  566.                 let DECed = matchedText.replace(/(ㄱㄹ)/g, '국룰');
  567. let DECedd = DECed.replace(/\s|[+]|(은|는|이|가)|(전부)|(대문자로)|(대문자)|(비밀번호)|(패스워드)|(비번)|(ㅂㅂ)|(암호)|(ㅇㅎ)|(키오스크맘)|(키오스크)|(입니다)|(이고)|(이며)|(임다)|(같다)|(처럼)|(틀리다)|(입니다요)/g, '');
  568. DECedd = DECedd.split(/[(입)(임)(이)(이)(이)(입)(임)(같)(처)(틀)]/g)[0];
  569.                 DECedd = DECedd.replace(/[<>]/g, '');
  570.  
  571. let dat;
  572.                 if (host === 'arca.live') {
  573.                     const dateEl = document.querySelector('.article-info .date .body');
  574.                     if (dateEl && typeof dateEl.innerText === 'string' && dateEl.innerText.trim() !== '') {
  575.                         dat = dateEl.innerText.split(' ')[0];
  576.                     } else {
  577.                         dat = undefined;
  578.                     }
  579.                 }
  580.  
  581. let regexa=/(오늘)|(날짜)|(날자)/g;
  582. if(dat && regexa.test(DECedd)){
  583. DECedd=DECedd.replace(regexa, '');
  584.                     const dateParts = dat.split(/\-/g);
  585.                     if (dateParts.length === 3) {
  586.                         const year = dateParts[0].slice(2);
  587.                         const month = dateParts[1];
  588.                         const day = dateParts[2];
  589.                         let dateFormats=[month + day, month + '-' + day, year + month + day, dat.replace(/-/g,'')];
  590.                         for(let k=0;k<dateFormats.length;k++){
  591.                             const finalPw = DECedd.replace(/국룰/g,chkp[4]) + dateFormats[k];
  592.                             if(finalPw.length > 2 && npw.indexOf(finalPw)=='-1') {
  593.                                 npw.push(finalPw);
  594.                                 foundPasswordsInDec++;
  595.                             }
  596.                         }
  597.                     }
  598. } else {
  599.                     const finalPw = DECedd.replace(/국룰/g,chkp[4]);
  600.                     if(finalPw && finalPw.length > 2 && npw.indexOf(finalPw)=='-1') {
  601.                         npw.push(finalPw);
  602.                         foundPasswordsInDec++;
  603.                     }
  604.                 }
  605.                 processedTexts.add(matchedText);
  606.                 currentLoopContent = currentLoopContent.replace(matchedText, `__PROCESSED_${Math.random().toString(36).substring(2, 15)}__`);
  607. }
  608.             if (foundPasswordsInDec > 0) {}
  609. GM.setValue('npw', npw);
  610. } catch(e){ console.error(e); }
  611. }
  612. dec(/[(<p>\s*)*]{0,}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#$%&=]{0,}(ㄱㄹ){1,1}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#$%&=]{0,}[(\s*</p>)*]{0,}/);
  613. setTimeout(aaa, 100);
  614. }
  615.  
  616. function waitForKoneContent() {
  617.     let attempts = 0;
  618.     const maxAttempts = 20;
  619.     const checkInterval = setInterval(async () => {
  620.         attempts++;
  621.         await handleBlockingModals(host);
  622.  
  623.         const atc = getKoneGGContentElement();
  624.         const titleEl = [...document.querySelectorAll('h1.flex, h1.text-xl')].find(el =>
  625.             /RJ[0-9]{6,10}|VJ[0-9]{6,10}/i.test(el.textContent || '')
  626.         );
  627.  
  628.         const hasBase64 = atc && /aHR0c|YUhSMG|WVVoU|V1ZWb/.test(atc.textContent || '');
  629.  
  630.         if (atc && (titleEl || hasBase64) && (atc.textContent || '').length > 10) {
  631.             clearInterval(checkInterval);
  632.             FindPW();
  633.             setTimeout(() => {
  634.                 doDec();
  635.                 doDlsiteContextAware();
  636.             }, 300);
  637.         } else if (attempts >= maxAttempts) {
  638.             clearInterval(checkInterval);
  639.         } else {
  640.         }
  641.     }, 300);
  642. }
  643.  
  644.  
  645. async function aaa() {
  646.     const saved = await GM.getValue('npw');
  647.     if (Array.isArray(saved)) {
  648.         npw = [...new Set([...npw, ...saved])];
  649.     } else {
  650.     }
  651. }
  652.  
  653.  
  654. (async () => {
  655.     await chkPW();
  656.     await handleBlockingModals(host);
  657.  
  658.     if (host === 'arca.live') {
  659.         FindPW();
  660.         setTimeout(doDec, 200);
  661.     } else if (host === 'kone.gg') {
  662.         waitForKoneContent();
  663.     }
  664.  
  665.     if(host=='kio.ac'){
  666.         await aaa();
  667.         chkp[0]='.overflow-auto.max-w-full.max-h-full.flex-grow.p-1 input:nth-of-type(1)';
  668.         chkp[1]='.flex.flex-col-reverse button:nth-of-type(1)';
  669.         chkp[2]='.p-2.align-middle .flex.align-middle button:nth-of-type(1)';
  670.         isT[2]=true;
  671.         PageLoading[1]=3500;
  672.         setTimeout(inputPW, (PageLoading[0] || 1000) + 2000);
  673.     }
  674.     if(host=='mega.nz'){
  675.         await aaa();
  676.         chkp[0]='#password-decrypt-input';
  677.         chkp[1]='.mega-button.positive.fm-dialog-new-folder-button.decrypt-link-button';
  678.         chkp[2]='.mega-button.positive.js-default-download.js-standard-download';
  679.         PageLoading[1]=4000;
  680.         isT[2]=false;
  681.         setTimeout(inputPW, (PageLoading[0] || 1000) + 1800);
  682.     }
  683.     if(host=='kiosk.ac'){
  684.         await aaa();
  685.         chkp[0]='.input.shadow-xl.flex-grow';
  686.         chkp[1]='.btn.btn-ghost.w-full.mt-2.rounded-md';
  687.         if(Down_Option==2)
  688.             chkp[2]='.flex.justify-between.w-full .flex.gap-2 .btn.btn-ghost';
  689.         else
  690.             chkp[2]='#vexplorer-body .hover\\:bg-neutral .dropdown button, #vexplorer-body > div > div > div.flex.justify-between.w-full > div.flex.gap-2 > button:not(.btn-disabled)';
  691.  
  692.         if(Down_Option==0)
  693.             isT[2]=true;
  694.         else
  695.             isT[2]=false;
  696.         PageLoading[1]=3000;
  697.         setTimeout(inputPW, (PageLoading[0] || 1000));
  698.     }
  699.     if(host=='workupload.com'){
  700.         await aaa();
  701.         chkp[0]='#passwordprotected_file_password';
  702.         chkp[1]='#passwordprotected_file_submit';
  703.         chkp[2]='a.btn.btn-prio[href*="/file/"]';
  704.         if(Down_Option==0)
  705.             isT[2]=true;
  706.         else
  707.             isT[2]=false;
  708.         PageLoading[1]=2000;
  709.         setTimeout(inputPW, (PageLoading[0] || 1000));
  710.     }
  711.     if(host=='drive.google.com'){
  712.         await aaa();
  713.         if(document.URL.includes('/file/d/')){
  714.             const fileId = document.URL.split('/d/')[1].split('/')[0];
  715.             if (fileId) {
  716.                 window.location.href=`https://drive.usercontent.google.com/download?id=${fileId}&export=download&authuser=0`;
  717.             }
  718.         }
  719.         if(document.URL.includes('/drive/folders/')){
  720.             setTimeout(()=> {
  721.                 if(isT[0]==true) {
  722.                     const downloadAllButton = document.querySelector('div[aria-label="모두 다운로드"], div[data-tooltip="모두 다운로드"]');
  723.                     if (downloadAllButton) {
  724.                         downloadAllButton.click();
  725.                     } else {
  726.                         const firstItemDownloadButton = document.querySelector('div[role="gridcell"][data-is-shared="false"] div[aria-label*="다운로드"]');
  727.                          if(firstItemDownloadButton) {
  728.                             firstItemDownloadButton.click();
  729.                          }
  730.                     }
  731.                 }
  732.             }, (PageLoading[0] || 1000) + 1500);
  733.  
  734.             chkp[2]='.h-De-Vb.h-De-Y';
  735.             PageLoading[1]=1;
  736.             isT[2]=true;
  737.             setTimeout(()=> { if(isT[0]==true) setTimeout(DBtn, 3500);}, (PageLoading[0] || 1000));
  738.         }
  739.     }
  740.     if(host=='drive.usercontent.google.com'){
  741.         await aaa();
  742.         chkp[2]='form[method="POST"] button[type="submit"], input[type="submit"][value="다운로드"], button.jfk-button-action';
  743.         isT[2]=true;
  744.         setTimeout(()=> { if(isT[0]==true) DBtn();}, 100);
  745.     }
  746.     if(host=='gofile.io'){
  747.         await aaa();
  748.         chkp[0]='#filesErrorPasswordInput';
  749.         chkp[1]='#filesErrorPasswordButton';
  750.         chkp[2]='button.btn-download, a.btn-download, #rowFolderCenter button[data-bs-target="#filesList"] + div .btn-outline-secondary';
  751.         PageLoading[1]=3000;
  752.         isT[2]=true;
  753.         setTimeout(inputPW, (PageLoading[0] || 1000));
  754.     }
  755. })();
  756.  
  757.  
  758. (function () {
  759.     'use strict';
  760.     if (location.host !== 'kone.gg') return;
  761.  
  762.     function hookDecodeTriggerOnButton() {
  763.         const container = document.querySelector('div.flex.items-center.justify-between.p-4');
  764.         if (!container) {
  765.             return;
  766.         }
  767.  
  768.         const button = container.querySelector('button[data-slot="button"]');
  769.         if (!button) {
  770.             return;
  771.         }
  772.         if (button.dataset._somi_hooked === '1') {
  773.             return;
  774.         }
  775.  
  776.         button.dataset._somi_hooked = '1';
  777.  
  778.         button.addEventListener('click', async () => {
  779.             await handleBlockingModals(host);
  780.             setTimeout(() => {
  781.                 FindPW();
  782.                 setTimeout(() => {
  783.                     doDec();
  784.                     doDlsiteContextAware();
  785.                 }, 300);
  786.             }, 500);
  787.         });
  788.     }
  789.  
  790.     hookDecodeTriggerOnButton();
  791.  
  792.     const observer = new MutationObserver(async (mutationsList, obs) => {
  793.         hookDecodeTriggerOnButton();
  794.         await handleBlockingModals(host);
  795.     });
  796.     observer.observe(document.body, { childList: true, subtree: true });
  797. })();
  798.  
  799. (function () {
  800.     'use strict';
  801.     if (location.host !== 'kone.gg') return;
  802.  
  803.     let lastUrl = location.href;
  804.     let mainProcessingIntervalId = null;
  805.  
  806.     const observer = new MutationObserver(async () => {
  807.         const currentUrl = location.href;
  808.         if (currentUrl !== lastUrl) {
  809.             lastUrl = currentUrl;
  810.             if (mainProcessingIntervalId) {
  811.                 clearInterval(mainProcessingIntervalId);
  812.             }
  813.             await handleBlockingModals(host);
  814.             observeAndRunKoneFunctions();
  815.         }
  816.     });
  817.  
  818.     observer.observe(document.body, { childList: true, subtree: true });
  819.  
  820.     async function observeAndRunKoneFunctions() {
  821.         const start = Date.now();
  822.         const timeout = 8000;
  823.  
  824.         if (mainProcessingIntervalId) {
  825.             clearInterval(mainProcessingIntervalId);
  826.         }
  827.  
  828.         mainProcessingIntervalId = setInterval(async () => {
  829.             await handleBlockingModals(host);
  830.             const atc = getKoneGGContentElement();
  831.             const hasText = atc && (atc.textContent || '').length > 20;
  832.             const hasEncoded = atc && /aHR0c|YUhSMG|WVVoU|V1ZWb/.test(atc.textContent || '');
  833.             const hasDlsiteLink = atc && atc.querySelector('a[href*="dlsite.com"]');
  834.  
  835.             if (atc && (hasText && (hasEncoded || hasDlsiteLink))) {
  836.                 clearInterval(mainProcessingIntervalId);
  837.                 mainProcessingIntervalId = null;
  838.                 FindPW();
  839.                 setTimeout(() => {
  840.                     doDec();
  841.                     doDlsiteContextAware();
  842.                 }, 300);
  843.             }
  844.  
  845.             if (Date.now() - start > timeout) {
  846.                 clearInterval(mainProcessingIntervalId);
  847.                 mainProcessingIntervalId = null;
  848.             }
  849.         }, 300);
  850.     }
  851.  
  852.     (async () => {
  853.         await handleBlockingModals(host);
  854.         observeAndRunKoneFunctions();
  855.     })();
  856. })();