Greasy Fork is available in English.

Auto Simya

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

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
  1. // ==UserScript==
  2. // @name Auto Simya
  3. // @name:ko 심야 자동 식당
  4. // @namespace http://tampermonkey.net/
  5. // @description 심챈 자동 복호화/국룰입력/다운(Kiosk, Mega, GoogleDrive, goFile)
  6. // @version 9.5
  7. // @author 김머시기
  8. // @match https://kiosk.ac/c/*
  9. // @match https://kio.ac/c/*
  10. // @match https://arca.live/b/*
  11. // @match https://mega.nz/*
  12. // @match https://gofile.io/d/*
  13. // @match https://workupload.com/*
  14. // @match https://drive.google.com/file/d/*
  15. // @match https://drive.google.com/drive/folders/*
  16. // @match https://drive.usercontent.google.com/download?id*
  17. // @icon https://lh3.google.com/u/0/d/18OVO7VmnwIuHK6Ke-z7035wKFmMKZ28W=w1854-h959-iv1
  18. // @grant GM.setValue
  19. // @grant GM.getValue
  20. // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
  21. // @grant GM.registerMenuCommand
  22. // @grant GM_registerMenuCommand
  23. // @grant GM_unregisterMenuCommand
  24. // @grant GM_getValue
  25. // @grant GM_setValue
  26. // @license MIT
  27. // @run-at document-end
  28. // ==/UserScript==
  29. 'use strict';
  30. let chkp = [,,,, atob('c21wZW9wbGU=')], Down_Option, PageLoading = [], isT = [,,], MenuID = [null, null], host = document.URL.split('/')[2], pw = [atob('c21wZW9wbGU='),
  31. // =============================== Settings =======================================
  32. // 추가하길 원하는 비밀번호 따옴표 - 쉼표로 구분해서 바로 아래줄에 넣으면 됨 ex) '1234', '2024국룰', '!국룰!'
  33.  
  34. ];
  35. PageLoading[0] = 1000; // 페이지 로딩 시간 조절 (1000당 1초)
  36. Down_Option = 0; // Kiosk 다운로드 옵션 0:Basic, 1:Fast, 2:일괄 다운로드
  37. // ======================================================================================
  38. async function toggleDown(){
  39. isT[0]=!isT[0];
  40. if(!isT[0] && isT[1]){
  41. isT[1]=false;
  42. await GM.setValue('isT[1]', isT[1]);
  43. }
  44. await GM.setValue('isT[0]', isT[0]);
  45. updateDown();
  46. updateTab();
  47. }
  48. async function toggleTab(){
  49. isT[1]=!isT[1];
  50. if(!isT[0] && isT[1]){
  51. isT[0]=true;
  52. await GM.setValue('isT[0]', isT[0]);
  53. }
  54. await GM.setValue('isT[1]', isT[1]);
  55. updateDown();
  56. updateTab();
  57. }
  58. function updateDown(){
  59. if(MenuID[0] !==null)GM_unregisterMenuCommand(MenuID[0]);
  60. MenuID[0]=GM_registerMenuCommand(`자동 다운로드  ${isT[0] ? 'ON' : 'OFF'}`, toggleDown, { autoClose: false, title: `자동 다운로드 ${isT[0] ? '켜짐' : '꺼짐'}`});
  61. }
  62. function updateTab(){
  63. if(MenuID[1] !==null)GM_unregisterMenuCommand(MenuID[1]);
  64. MenuID[1]=GM_registerMenuCommand(`자동 닫기  ${isT[1] ? 'ON' : 'OFF'}`, toggleTab, { autoClose: false, title: `자동 닫기 ${isT[1] ? '켜짐' : '꺼짐'}`});
  65. }
  66. function doDec(){
  67. if (chkp[3] == chkp[4]) {
  68. const targets = [
  69. document.querySelector('body div.article-body > div.fr-view.article-content'), // 본문
  70. ...document.querySelectorAll('div.article-comment#comment, div.article-comment') // 댓글
  71. ];
  72.  
  73. function dec(target, reg){
  74. try {
  75. while (reg.test(target.innerHTML)) {
  76. let DECed = reg.exec(target.innerHTML)[0];
  77. while (DECed.match(/aHR0c[0-9A-Za-z+/-]{8,}[=]{0,2}/g) == null) {
  78. DECed = atob(DECed);
  79. }
  80. DECed = atob(DECed);
  81. target.innerHTML = target.innerHTML.replace(reg, `<a href=${DECed} target='_blank' rel='noreferrer'>${DECed}</a>`);
  82. }
  83. } catch (e) { console.log(e, target); }
  84. }
  85.  
  86. for (const target of targets) {
  87. if (!target) continue;
  88. dec(target, /aHR0c[0-9A-Za-z+/-]{8,}[=]{0,2}/);
  89. dec(target, /YUhSMG[0-9A-Za-z+/-]{8,}[=]{0,2}/);
  90. dec(target, /WVVoU[0-9A-Za-z+/-]{8,}[=]{1,2}/);
  91. dec(target, /V1ZWb[0-9A-Za-z+/-]{8,}[=]{0,2}/);
  92. }
  93.  
  94. setTimeout(doDlsiteContextAware, 100);
  95. }
  96. }
  97.  
  98. function doDlsiteContextAware() {
  99. const atc = document.querySelector('.article-body .article-content');
  100. const titleEl = document.querySelector('.title-row .title') || document.querySelector('.board-title .title');
  101. if (!atc) return;
  102.  
  103. const keywordPattern = /(꺼|거|퍼|RJ|rj|Rj|rJ|VJ|vj|Vj|vJ|DL|dl|Dl|dL)[\s:()\[\]#-]*([0-9]{6,10})/g;
  104. const fullRJPattern = /\b(RJ|rj|Rj|rJ|VJ|vj|Vj|vJ|퍼|꺼|거|DL|dl|Dl|dL)([0-9]{6,10})\b/g;
  105.  
  106. let titleText = '';
  107. if (titleEl?.childNodes) {
  108. titleText = Array.from(titleEl.childNodes)
  109. .map(n => n.textContent.trim())
  110. .join(' ');
  111. }
  112.  
  113. const bodyText = atc.textContent || '';
  114. const fullText = titleText + '\n' + bodyText;
  115.  
  116. const matchList1 = [...fullText.matchAll(keywordPattern)].map(m => ({ prefix: m[1], code: m[2] }));
  117. const matchList2 = [...fullText.matchAll(fullRJPattern)].map(m => ({ prefix: m[1], code: m[2] }));
  118.  
  119. const linkCodes = Array.from(atc.querySelectorAll('a[href]'))
  120. .map(a => {
  121. const match = a.href.match(/(RJ|VJ)([0-9]{6,10})/i);
  122. return match ? { prefix: match[1].toUpperCase(), code: match[2] } : null;
  123. })
  124. .filter(Boolean);
  125.  
  126. const splitNodeMatches = [];
  127. const allNodes = [...atc.querySelectorAll('*')];
  128. const validPrefixes = ['꺼','거','퍼','RJ','rj','Rj','rJ','VJ','vj','Vj','vJ','DL','dl','Dl','dL'];
  129.  
  130. for (const node of allNodes) {
  131. const children = [...node.childNodes];
  132. for (let i = 0; i < children.length - 1; i++) {
  133. const a = children[i], b = children[i + 1];
  134. const aText = (a.textContent || '').replace(/\s+/g, '');
  135. const bText = (b.textContent || '').trim();
  136. if (!/^\d{6,10}$/.test(bText)) continue;
  137. for (const prefix of validPrefixes) {
  138. if (aText.includes(prefix)) {
  139. splitNodeMatches.push({ prefix, code: bText });
  140. break;
  141. }
  142. }
  143. }
  144. }
  145.  
  146. const extraFromTitle = [];
  147. const match = titleText.match(/^[\[]?([0-9]{6,10})[\]]?/);
  148. if (match) extraFromTitle.push({ prefix: 'RJ', code: match[1] });
  149.  
  150. const allCodes = [
  151. ...matchList1,
  152. ...matchList2,
  153. ...linkCodes,
  154. ...splitNodeMatches,
  155. ...extraFromTitle
  156. ];
  157.  
  158. const seen = new Set();
  159. const uniqueCodes = allCodes.filter(({ code }) => {
  160. if (seen.has(code)) return false;
  161. seen.add(code);
  162. return true;
  163. });
  164.  
  165. if (uniqueCodes.length <= 1) {
  166. const { code, prefix } = uniqueCodes[0];
  167. if (!code) return;
  168.  
  169. const mappedPrefix = ['vj', 'vJ', 'Vj', 'VJ', '퍼'].includes(prefix.toLowerCase()) ? 'VJ'
  170. : ['rj', 'rJ', 'Rj', 'RJ', '꺼', '거', 'dl', 'dL', 'Dl', 'DL'].includes(prefix.toLowerCase()) ? 'RJ'
  171. : prefix.toUpperCase();
  172.  
  173. const fullCode = `${mappedPrefix}${code}`;
  174. const link = `https://www.dlsite.com/maniax/work/=/product_id/${fullCode}.html`;
  175.  
  176. const existing = atc.querySelector('.dlsite-link-appended');
  177. if (existing) existing.remove();
  178.  
  179. const wrapper = document.createElement('div');
  180. wrapper.className = 'dlsite-link-appended';
  181. wrapper.style.marginTop = '15px';
  182. wrapper.style.padding = '10px 0';
  183. wrapper.style.borderTop = '1px dashed #aaa';
  184.  
  185. const a = document.createElement('a');
  186. a.href = link;
  187. a.target = '_blank';
  188. a.rel = 'noreferrer';
  189. a.textContent = `[DLsite] ${fullCode}`;
  190. a.style.display = 'block';
  191. a.style.marginBottom = '5px';
  192. a.style.fontWeight = 'bold';
  193. a.style.color = '#1e90ff';
  194.  
  195. wrapper.appendChild(a);
  196. atc.appendChild(wrapper);
  197. return;
  198. }
  199.  
  200. const combinedPattern = new RegExp(
  201. `${keywordPattern.source}|${fullRJPattern.source}`,
  202. 'gi'
  203. );
  204.  
  205. const walk = (node) => {
  206. if (node.nodeType === Node.TEXT_NODE) {
  207. const text = node.textContent;
  208. let lastIndex = 0;
  209. let match;
  210. const frag = document.createDocumentFragment();
  211.  
  212. while ((match = combinedPattern.exec(text)) !== null) {
  213. const before = text.slice(lastIndex, match.index);
  214. const number = match[2] || match[4];
  215. const prefix = (match[1] || match[3] || '').toLowerCase();
  216. const mappedPrefix = ['vj', 'vJ', 'Vj', 'VJ', '퍼'].includes(prefix) ? 'VJ'
  217. : ['rj', 'rJ', 'Rj', 'RJ', '꺼', '거', 'dl', 'dL', 'Dl', 'DL'].includes(prefix) ? 'RJ'
  218. : prefix.toUpperCase();
  219. const fullCode = `${mappedPrefix}${number}`;
  220.  
  221. const a = document.createElement('a');
  222. a.href = `https://www.dlsite.com/maniax/work/=/product_id/${fullCode}.html`;
  223. a.textContent = fullCode;
  224. a.target = '_blank';
  225. a.rel = 'noreferrer';
  226. a.style.color = '#1e90ff';
  227. a.style.fontWeight = 'bold';
  228.  
  229. if (before) frag.appendChild(document.createTextNode(before));
  230. frag.appendChild(a);
  231. lastIndex = match.index + match[0].length;
  232. }
  233.  
  234. if (lastIndex < text.length) {
  235. frag.appendChild(document.createTextNode(text.slice(lastIndex)));
  236. }
  237.  
  238. if (frag.childNodes.length > 0) {
  239. node.replaceWith(frag);
  240. }
  241. } else if (
  242. node.nodeType === Node.ELEMENT_NODE &&
  243. !['A', 'SCRIPT', 'STYLE'].includes(node.tagName)
  244. ) {
  245. for (const child of [...node.childNodes]) {
  246. walk(child);
  247. }
  248. }
  249. };
  250.  
  251. walk(atc);
  252. }
  253.  
  254.  
  255. async function chkPW(){
  256. chkp[3]=await GM.getValue('chkp[3]');
  257. isT[0]=await GM.getValue('isT[0]', true);
  258. isT[1]=await GM.getValue('isT[1]', false);
  259. updateDown();
  260. updateTab();
  261. if(host=='arca.live'){
  262. if(chkp[3] !=chkp[4]){
  263. const chk=prompt(decodeURI(atob('JUVBJUI1JUFEJUVCJUEzJUIwJUVEJTk5JTk1JUVDJTlEJUI4')));
  264. if(chk?.toLowerCase()==chkp[4]) await GM.setValue('chkp[3]', chkp[4]);
  265. else {
  266. GM.setValue('chkp[3]', false);
  267. alert(decodeURI(atob('JUVBJUI1JUFEJUVCJUEzJUIwJUVDJTlEJUI0JTIwJUVDJTlEJUJDJUVDJUI5JTk4JUVEJTk1JTk4JUVDJUE3JTgwJTIwJUVDJTk1JThBJUVDJThBJUI1JUVCJThCJTg4JUVCJThCJUE0')));
  268. }
  269. }
  270. }
  271. }
  272. async function inputPW(){
  273. let inputElem=document.querySelector(chkp[0]), btnElem=document.querySelector(chkp[1]);
  274. if(chkp[3]==chkp[4]){
  275. try {
  276. for(let i=0; i < pw.length; i++){
  277. if(host=='kio.ac'){
  278. inputElem.value=pw[i];
  279. inputElem.dispatchEvent(new Event('input', { bubbles: true }));
  280. inputElem.dispatchEvent(new Event('change', { bubbles: true }));
  281. setTimeout(()=> {btnElem.click()}, 10);
  282. } else {
  283. inputElem.value=pw[i];
  284. btnElem.click();
  285. }
  286. if(i < pw.length - 1){ if(pw[i] !=null && pw[i] !='')await new Promise(res=> setTimeout(res, 800));
  287. } else { if(isT[0]==true)await setTimeout(DBtn, PageLoading[1]); }
  288. }
  289. } catch(e){ await setTimeout(DBtn, PageLoading[1]); }
  290. }
  291. }
  292. async function kioskdone(){
  293. try {
  294. await new Promise(res=> setTimeout(res, 3000));
  295. for(var i=0, jj=0; jj!=1; i++){
  296. console.log(i);
  297. await new Promise(res=> setTimeout(res, 1000));
  298. if(document.querySelector('.flex.flex-row.text-xs.justify-between div:nth-child(2)').innerText=='done'){
  299. console.log(i);
  300. await setTimeout(()=> { window.open('', '_self').close()}, 2000);
  301. jj++;
  302. }
  303. }
  304. } catch(e){ if(isT[1]==true && isT[2]==true)setTimeout(()=> { window.open('', '_self').close()}, 1000); }
  305. }
  306. async function DBtn(){
  307. if(isT[0] !== true) return; // 수정 1: 자동 다운로드 OFF 시 즉시 종료
  308. if(host=='mega.nz')await document.querySelector('.mega-button.positive.resume.js-resume-download').click();
  309. try {
  310. let btns = document.querySelectorAll(chkp[2]);
  311. let delayMultiplier = PageLoading[0] + 600;
  312. if(btns.length > 1){
  313. btns.forEach((btn, index) => {
  314. setTimeout(() => { btn.click(); }, index * delayMultiplier);
  315. });
  316. } else if(btns.length === 1){
  317. btns[0].click();
  318. }
  319. if(host=='mega.nz')
  320. await setTimeout(()=> { document.querySelector('.mega-button.large.positive.download.continue-download').click()}, 2000);
  321. if(isT[1]==true && isT[2]==true){ // 수정 2: 자동 탭 닫기 kio.ac 포함
  322. let totalDelay = (btns.length > 1) ? (btns.length * delayMultiplier + 700) : 1300;
  323. if(host=='kiosk.ac'){
  324. setTimeout(()=> { kioskdone(); }, totalDelay);
  325. } else if(host=='kio.ac'){
  326. setTimeout(()=> { window.open('', '_self').close()}, totalDelay);
  327. } else {
  328. setTimeout(()=> { window.open('', '_self').close() }, totalDelay);
  329. }
  330. }
  331. }catch(e){ console.log(e); }
  332. }
  333. function FindPW(){
  334. const atc=document.querySelector('body div.article-body > div.fr-view.article-content');
  335. atc.innerHTML=atc.innerHTML.replace(/(&nbsp;)/g, ' ');
  336. atc.innerHTML=atc.innerHTML.replace(/국룰/g, 'ㄱㄹ');
  337. let rgx=/[(<p>)]{0,0}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#$%&=]{0,}(ㄱㄹ){1,}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#($)%&=\(\)(&nbsp;)]{0,}[(</p>)]{0,0}/;
  338. let regexx=/(대문자)/;
  339. if(regexx.test(regexx.exec(atc.innerHTML))===true)pw[pw.length]=atob('U01QRU9QTEU');
  340. function dec(reg){
  341. try {
  342. while(reg.test(atc.innerHTML)){
  343. let DECed=reg.exec(atc.innerHTML)[0].replace(/(ㄱㄹ)/g, '국룰');
  344. let DECedd=DECed.replace(/\s|[+]|(&nbsp;)|은|는|이|(전부)|(대문자로)|(대문자)|(비밀번호)|(패스워드)|(비번)|(ㅂㅂ)|(암호)|(ㅇㅎ)|(키오스크맘)|(키오스크)/g, '');
  345. DECedd=DECedd.split(/[(입)(임)(이다)(이고)(이며)(입니다)(임다)(같)(처럼)(틀)]/g)[0];
  346. let dat=document.querySelector('.date .body').innerText.split(' ')[0];
  347. let regexa=/(오늘)|(날짜)|(날자)/g;
  348. if(regexa.test(DECedd)===true){
  349. DECedd=DECedd.replace(regexa, '');
  350. let md=[dat.split(/\-/g)[1] + dat.split(/\-/g)[2],dat.split(/\-/g)[1] +'-'+ dat.split(/\-/g)[2],dat.replace(/\-/g, ''),dat];
  351. for(let i=0;i<4;i++){
  352. pw[pw.length]=DECedd.replace(/국룰/g,chkp[4])+md[i];
  353. }
  354. } else { if(pw.indexOf(DECedd.replace(/국룰/g,chkp[4]))=='-1')pw[pw.length]=DECedd.replace(/국룰/g,chkp[4]); }
  355. atc.innerHTML=atc.innerHTML.replace(reg, '1ㅂㅁ2ㅈㄴ3ㄷㅇ4ㄱㄹ1qa2ws3ed4rf');
  356. atc.innerHTML=atc.innerHTML.replace(/(1ㅂㅁ2ㅈㄴ3ㄷㅇ4ㄱㄹ1qa2ws3ed4rf)/g,DECed);
  357. }
  358. GM.setValue('pw', pw);
  359. } catch(e){ console.log(e, atc); }
  360. }
  361. dec(/[(<p>)]{0,0}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#$%&=]{0,}(ㄱㄹ){1,1}[ㄱ-ㅣ가-힣0-9A-Za-z\s~`!^\_+@\#$%&=]{0,}[(</p>)]{0,0}/);
  362. setTimeout(aaa, 100);
  363. }
  364. async function aaa(){ pw=await GM.getValue('pw'); }
  365. chkPW();
  366. if(host=='arca.live'){
  367. FindPW();
  368. setTimeout(doDec, 10);
  369. }
  370. if(host=='kio.ac'){
  371. aaa();
  372. chkp[0]='.overflow-auto.max-w-full.max-h-full.flex-grow.p-1 input:nth-of-type(1)';
  373. chkp[1]='.flex.flex-col-reverse button:nth-of-type(1)';
  374. chkp[2]='.p-2.align-middle .flex.align-middle button:nth-of-type(1)';
  375. isT[2]=true;
  376. PageLoading[1]=3500;
  377. setTimeout(inputPW, PageLoading[0] + 2000);
  378. }
  379. if(host=='mega.nz'){
  380. aaa();
  381. chkp[0]='#password-decrypt-input';
  382. chkp[1]='.mega-button.positive.fm-dialog-new-folder-button.decrypt-link-button';
  383. chkp[2]='.mega-button.positive.js-default-download.js-standard-download';
  384. PageLoading[1]=4000;
  385. isT[2]=false;
  386. setTimeout(inputPW, PageLoading[0] + 1800);
  387. }
  388. if(host=='kiosk.ac'){
  389. aaa();
  390. chkp[0]='.input.shadow-xl.flex-grow';
  391. chkp[1]='.btn.btn-ghost.w-full.mt-2.rounded-md';
  392. if(Down_Option==2)
  393. chkp[2]='.flex.justify-between.w-full .flex.gap-2 .btn.btn-ghost';
  394. else
  395. chkp[2]='#vexplorer-body .hover.cursor-pointer .flex .dropdown.group button';
  396. if(Down_Option==0)
  397. isT[2]=true;
  398. else
  399. isT[2]=false;
  400. PageLoading[1]=3000;
  401. setTimeout(inputPW, PageLoading[0]);
  402. }
  403. if(host=='workupload.com'){
  404. aaa();
  405. chkp[0]='#passwordprotected_file_password';
  406. chkp[1]='#passwordprotected_file_submit';
  407. chkp[2]='.btn.btn-prio';
  408. if(Down_Option==0)
  409. isT[2]=true;
  410. else
  411. isT[2]=false;
  412. PageLoading[1]=2000;
  413. setTimeout(inputPW, PageLoading[0]);
  414. }
  415. if(host=='drive.google.com'){
  416. aaa();
  417. if(document.URL.split('/')[3] + document.URL.split('/')[4]=='filed')
  418. window.location.href=`https://drive.usercontent.google.com/download?id=${document.URL.split('/')[5]}&export=download`;
  419. if(document.URL.split('/')[3] + document.URL.split('/')[4]=='drivefolders'){
  420. setTimeout(()=> { if(isT[0]==true)setTimeout(()=> { document.querySelector('.pc7nUb.kXQBpc.Dk9rmd:nth-child(2)').click()}, 1500)}, PageLoading[0]);
  421. chkp[2]='.h-De-Vb.h-De-Y';
  422. PageLoading[1]=1;
  423. isT[2]=true;
  424. setTimeout(()=> { if(isT[0]==true)setTimeout(DBtn, 3500)}, PageLoading[0]);
  425. }
  426. }
  427. if(host=='drive.usercontent.google.com'){
  428. aaa();
  429. chkp[2]='.goog-inline-block.jfk-button.jfk-button-action';
  430. isT[2]=true;
  431. setTimeout(()=> { if(isT[0]==true)DBtn()}, 1);
  432. }
  433. if(host=='gofile.io'){
  434. aaa();
  435. chkp[0]='#filesErrorPasswordInput';
  436. chkp[1]='#filesErrorPasswordButton';
  437. chkp[2]='.btn.btn-outline-secondary.btn-sm.p-1.text-white';
  438. PageLoading[1]=3000;
  439. isT[2]=true;
  440. setTimeout(inputPW, PageLoading[0]);
  441. }