您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
깡계확인 스크립트(글 5개나 댓글 5개 미만 표시) 및 핫딜챈 한정 핫딜챈 작성글 비율 표시
当前为
// ==UserScript== // @name 아카라이브 깡계확인 및 핫딜챈 비율표시 // @namespace http://kemomimi.com/ // @version 1.6 // @description 깡계확인 스크립트(글 5개나 댓글 5개 미만 표시) 및 핫딜챈 한정 핫딜챈 작성글 비율 표시 // @match https://arca.live/b/*/* // @grant GM_xmlhttpRequest // @connect arca.live // @grant GM_getValue // @grant GM_setValue // ==/UserScript== // 화이트리스트 추가 function addItem(newItem) { let savedArray = JSON.parse(GM_getValue("whlteArray", "[]")); savedArray.push(newItem); GM_setValue("whlteArray", JSON.stringify(savedArray)); } // 화이트리스트 삭제 function deleteItem(itemToDelete) { let savedArray = JSON.parse(GM_getValue("whlteArray", "[]")); let index = savedArray.indexOf(itemToDelete); if (index > -1) { savedArray.splice(index, 1); GM_setValue("whlteArray", JSON.stringify(savedArray)); } } function removeUnsafe() { if (window.location.href.includes('/hotdeal/')) { const link = document.querySelector('table a'); let href = link.getAttribute('href'); let title = link.getAttribute('title'); let text = link.textContent; href = href.replace('https://unsafelink.com/', ''); const newLink = document.createElement('a'); newLink.href = href; newLink.title = title; newLink.textContent = text; newLink.target = "_blank"; newLink.className = "external"; newLink.rel = "external nofollow noopener noreferrer"; link.parentNode.replaceChild(newLink, link); } } const firstLink = document.querySelector('.article-head .info-row .user-info a'); const dataFilterValue = firstLink.getAttribute('data-filter'); var showFlag = true; const button = document.createElement('button'); let savedArray = JSON.parse(GM_getValue("whlteArray", "[]")); if (!savedArray.includes(dataFilterValue)) { button.textContent = '➕'; button.title = "핫딜비율&깡계 표시 숨기기" }else{ button.textContent = '➖'; button.title = "핫딜비율&깡계 표시하기" showFlag = false; } button.style.cursor = 'pointer'; button.style.backgroundColor = 'transparent'; button.style.border = 'none'; button.addEventListener('click', function() { let savedArray = JSON.parse(GM_getValue("whlteArray", "[]")); if (!savedArray.includes(dataFilterValue)) { addItem(dataFilterValue); button.textContent = '✅화이트리스트에 추가됨'; setTimeout(() => location.reload(), 1000); } else { deleteItem(dataFilterValue); button.textContent = '✅화이트리스트에서 제거됨'; setTimeout(() => location.reload(), 1000); } }); const member = document.querySelector('.member-info'); if (!showFlag){ member.appendChild(button); }else if (firstLink && showFlag) { const targetURL = firstLink.href; // GET 요청 보내기 GM_xmlhttpRequest({ method: 'GET', url: targetURL, onload: function(response) { removeUnsafe(); const htmlData = response.responseText; const parser = new DOMParser(); const doc = parser.parseFromString(htmlData, 'text/html'); if(doc.querySelectorAll('.error-code').length >=1){ firstLink.style.fontSize = '17px'; firstLink.style.fontWeight = 'bold'; firstLink.style.color = 'red'; firstLink.style.textDecoration = 'line-through'; firstLink.textContent += ' (삭제된 계정)'; member.appendChild(button); }else{ const cardBlockElement = doc.querySelector('.card-block'); const childNodes = cardBlockElement.childNodes; var post = 0 var coment = 0 var hotdeal = 0 var washyourid = 0 var flag = 0 var channels = new Set() // 채널 이름을 저장할 Set for (const node of childNodes) { if (node.nodeType === Node.ELEMENT_NODE) { if(node.className == "clearfix"){ flag+=1 } if(node.className== "user-recent" && flag==0){ post+=1 const colTitleNodes = node.querySelectorAll('.col-title span'); colTitleNodes.forEach(span => { const channelName = span.textContent.trim() if(channelName.endsWith(' 채널')) { channels.add(channelName.slice(0, -3)) // '채널' 문자열 제거 후 Set에 추가 } if(channelName === "핫딜 채널") { hotdeal += 1; } if(channelName === "세탁 채널") { washyourid += 1; } }); }else if(node.className== "user-recent" && flag==1){ coment+=1 } } } var channelString = Array.from(channels).join(', '); firstLink.title = "활동 채널: " + channelString; if (window.location.href.includes('/hotdeal/')) { const table = document.querySelector('.article-body table'); if (table) { const newRow = table.insertRow(0); const cell1 = newRow.insertCell(0); cell1.textContent = '최근 활동챈'; cell1.className = 'displayName'; // 두 번째 셀을 생성하고 채널 목록을 추가합니다. const cell2 = newRow.insertCell(1); cell2.textContent = channelString; } else { console.log('테이블을 찾을 수 없습니다.'); } } if (window.location.href.includes('/hotdeal/')) { // 핫딜챈 var hotdealRatio = ((hotdeal/post)*100).toFixed(0) if(post<=5 || coment<=5){ firstLink.style.fontSize = '17px'; firstLink.style.fontWeight = 'bold'; firstLink.style.color = 'red'; firstLink.textContent += ' (핫딜챈 비율:'+hotdealRatio+'% 최근 글:'+post+' 댓글:'+coment+')'; member.appendChild(button); }else if(washyourid>=1){ firstLink.style.fontSize = '17px'; firstLink.style.fontWeight = 'bold'; firstLink.style.color = 'red'; var washedHotdealRatio = ((hotdeal/(post-washyourid))*100).toFixed(0) firstLink.textContent += ' (세탁챈 글:'+washyourid+' 핫딜챈 비율:'+washedHotdealRatio+'%)'; member.appendChild(button); }else{ if (hotdealRatio >= 70){ firstLink.style.color = 'red'; } if(hotdealRatio >= 90){ firstLink.style.fontWeight = 'bold'; firstLink.style.fontSize = '17px'; } firstLink.textContent += ' (핫딜챈 비율: '+hotdealRatio+'%)'; member.appendChild(button); } } else if(washyourid>=1){ firstLink.style.fontSize = '17px'; firstLink.style.fontWeight = 'bold'; firstLink.style.color = 'red'; firstLink.textContent += ' (세탁챈 글:'+washyourid+' 글:'+(post-washyourid)+' 댓글:'+coment+')'; member.appendChild(button); } else if(post<=5 || coment<=5){ firstLink.style.fontSize = '17px'; firstLink.style.fontWeight = 'bold'; firstLink.style.color = 'red'; firstLink.textContent += ' (최근 글:'+post+' 댓글:'+coment+')'; member.appendChild(button); }else{ //firstLink.textContent += ' (최근 글:'+post+' 댓글:'+coment+')'; } } } }); } else { //console.log('링크를 찾을 수 없음'); } //댓글 비동기 스크립트 (@Holon 작성 코드 긴빠이) const usernameElement = document.querySelector('.username.d-none.d-sm-inline'); const usernameText = usernameElement.textContent.trim(); // 공백 제거 let dataFilterValues = {}; var numOfRequests = 0; var numOfStyle = 0; function setLinkStyle(link, post, comment) { // console.log('P :' + post + ' C : ' + comment); if (post === 0 && comment === 0) { link.style.fontWeight = 'bold'; link.style.color = 'red'; // link.style.textDecoration = 'line-through'; link.textContent += ' [삭제된 계정]'; } else { link.style.color = ((post <= 10 && comment <= 10) || comment <= 5) ? 'red' : ((post <= 10 && comment > 10) || comment <= 10) ? 'orange' : ((post < 15 && comment > 14 ) || comment <= 14) ? 'lightgreen' : ''; if (post < 15 || comment < 15) { link.textContent += ` [최근 글: ${post < 15 ? post : '🆗'} 댓글: ${comment < 15 ? comment : '🆗'}]`; } } numOfStyle++; } async function fetchDataAndSetStyle(link) { const targetURL = link.href; const dataFilterValue = link.getAttribute('data-filter').trim(); numOfRequests++; if (usernameText !== dataFilterValue && !dataFilterValues[dataFilterValue]) { dataFilterValues[dataFilterValue] = { post: 0, comment: 0 }; return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url: targetURL, onload: function (response) { const htmlData = response.responseText; const parser = new DOMParser(); const doc = parser.parseFromString(htmlData, 'text/html'); console.log(dataFilterValue); // DEBUG if (doc.querySelectorAll('.error-code').length >= 1) { } else { const cardBlockElement = doc.querySelector('.card-block'); const childNodes = cardBlockElement.childNodes; let postCount = 0; let commentCount = 0; let flag = 0; for (const node of childNodes) { if (node.nodeType === Node.ELEMENT_NODE) { if (node.className === "clearfix") { flag += 1; } if (node.className === "user-recent" && flag === 0) { postCount += 1; } else if (node.className === "user-recent" && flag === 1) { commentCount += 1; } } } dataFilterValues[dataFilterValue] = { post: postCount, comment: commentCount }; } resolve(); } }); }); } } (async () => { console.time('Execution Time'); const promises = []; console.log("Data Sorting..."); // DEBUG document.querySelectorAll('#comment .info-row .user-info a').forEach(link => { promises.push(fetchDataAndSetStyle(link)); }); await Promise.all(promises); console.log("Labeling..."); // DEBUG document.querySelectorAll('#comment .info-row .user-info a').forEach(secondLink => { const secondDataFilterValue = secondLink.getAttribute('data-filter').trim(); if (dataFilterValues[secondDataFilterValue]) { const { post, comment } = dataFilterValues[secondDataFilterValue]; setLinkStyle(secondLink, post, comment); } }); console.timeEnd('Execution Time'); console.log('Req : ' + numOfRequests + ' Sty : ' + numOfStyle); console.log(dataFilterValues); })();