您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Upload Market
// ==UserScript== // @name Upload_Market_by_el9in // @namespace Upload_Market_by_el9in // @version 0.2 // @description Upload Market // @author el9in // @match https://lzt.market/mass-upload/* // @icon https://www.google.com/s2/favicons?sz=64&domain=zelenka.guru // @grant none // @license el9in // ==/UserScript== (function() { 'use strict'; const maxThreads = 3; const inputElement = document.querySelector('input[type="hidden"][name="_xfToken"]'); const xfTokenValue = inputElement.value; const finishLoadElement = document.querySelector('div.MassUploadFinishedBadge.finishedBadge.hidden.mn-15-0'); const url = window.location.href; const parts = url.split('/'); const id = parts[parts.length - 2]; const check = []; const divElements = document.querySelectorAll('div.account'); const massUploadStats = document.querySelector('.MassUploadStats'); const checked = massUploadStats.querySelector('.checked.label'); const remaining = massUploadStats.querySelector('.left.label'); const success = massUploadStats.querySelector('.success.label'); const error = massUploadStats.querySelector('.error.label'); var checkedCount = checked.textContent | 0; var remainingCount = remaining.textContent | 0; var successCount = success.textContent | 0; var errorCount = error.textContent | 0; divElements.forEach((divElement) => { const accountStatusElement = divElement.querySelector('.AccountStatus > .muted'); const entryId = divElement.getAttribute('data-entry-id'); check.push({ entryId, statusElement: accountStatusElement }); }); function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function checkAccount(accountData,close) { const Local = { times: 0, maxTimes: 20 }; if(accountData.statusElement) accountData.statusElement.textContent = 'EL9IN: Начата проверка.'; while(true) { if(Local.times >= Local.maxTimes) return 0; const response = await fetch(`https://lzt.market/mass-upload/${id}/check-account`, { "headers": { "accept": "application/json, text/javascript, */*; q=0.01", "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7", "content-type": "application/x-www-form-urlencoded; charset=UTF-8", "x-ajax-referer": `https://lzt.market/mass-upload/${id}/`, "x-requested-with": "XMLHttpRequest", "Referer": `https://lzt.market/mass-upload/${id}/`, "Referrer-Policy": "strict-origin-when-cross-origin" }, "body": `entry_id=${accountData.entryId}&_xfRequestUri=%2Fmass-upload%2F${id}%2F&_xfNoRedirect=1&_xfToken=${xfTokenValue}&_xfResponseType=json`, "method": "POST" }); const req = await response.json(); const { error, item } = req; if(error == "captcha") { if(accountData.statusElement) accountData.statusElement.textContent = `EL9IN: ${error}`; Local.times++; await sleep(500); continue; } else if(error != null) { if(accountData.statusElement) accountData.statusElement.textContent = `EL9IN: ${error}`; Local.times++; errorCount ++; error.textContent = errorCount; return 0; } else { successCount ++; success.textContent = successCount; const { link } = item; if(accountData.statusElement) accountData.statusElement.textContent = `EL9IN: Успешно добавили ${link}`; if(close == true) { const itemMarketId = extractIDFromURL(link); try { const status = await fetch(`https://lzt.market/${itemMarketId}/open-close?&_xfRequestUri=%2F${itemMarketId}%2F&_xfNoRedirect=1&_xfToken=${xfTokenValue}&_xfResponseType=json`, { "headers": { "accept": "application/json, text/javascript, */*; q=0.01", "accept-language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7", "x-ajax-referer": `https://lzt.market/${itemMarketId}/`, "x-requested-with": "XMLHttpRequest", "Referer": `https://lzt.market/${itemMarketId}/`, "Referrer-Policy": "strict-origin-when-cross-origin" }, "body": null, "method": "GET" }); const { _redirectStatus } = await status.json(); if(_redirectStatus == "ok") { const svgHTML = ` <svg viewBox="0 0 24 24" width="20" height="20" stroke="rgb(156 164 91)" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"> <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> </svg> `; accountData.statusElement.insertAdjacentHTML('afterend', svgHTML); } } catch(error) { return 2; } } } return 1; } } const startStopButton = document.getElementById('MassStartStopButton'); if(startStopButton) { const newButton = document.createElement('button'); const newButtonAPI = document.createElement('button'); newButton.id = 'MassStartStopButtonByEl9in'; newButton.classList.add('toggle', 'primary', 'button'); newButton.textContent = 'Начать и закрыть (EL9IN)'; newButton.style.marginLeft = '3px'; startStopButton.parentNode.insertBefore(newButton, startStopButton.nextSibling); newButton.addEventListener('click', async function() { startStopButton.parentNode.removeChild(startStopButton); newButton.parentNode.removeChild(newButton); newButtonAPI.parentNode.removeChild(newButtonAPI); runCheckAccounts(check,false); }); newButtonAPI.id = 'MassStartStopButtonAPIByEl9in'; newButtonAPI.classList.add('toggle', 'primary', 'button'); newButtonAPI.textContent = 'Начать (EL9IN)'; newButtonAPI.style.marginLeft = '3px'; startStopButton.parentNode.insertBefore(newButtonAPI, startStopButton.nextSibling); newButtonAPI.addEventListener('click', async function() { startStopButton.parentNode.removeChild(startStopButton); newButton.parentNode.removeChild(newButton); newButtonAPI.parentNode.removeChild(newButtonAPI); runCheckAccounts(check,false); }); } async function runCheckAccounts(check,close) { const semaphore = new Semaphore(maxThreads); const promises = []; for (let ck of check) { await semaphore.acquire(); promises.push( (async () => { await checkAccount(ck,close); semaphore.release(); })() ); checkedCount ++; checked.textContent = checkedCount; remainingCount --; remaining.textContent = remainingCount; } await Promise.all(promises); if (finishLoadElement) { finishLoadElement.classList.remove('hidden'); } } class Semaphore { constructor(maxCount) { this.maxCount = maxCount; this.counter = 0; this.waiters = []; } acquire() { if (this.counter < this.maxCount) { this.counter++; return Promise.resolve(); } else { return new Promise(resolve => { this.waiters.push(resolve); }); } } release() { if (this.waiters.length > 0) { const waiter = this.waiters.shift(); waiter(); } else { this.counter--; } } } function extractIDFromURL(url) { const trimmedURL = url.endsWith('/') ? url.slice(0, -1) : url; const parts = trimmedURL.split('/'); const id = parts[parts.length - 1]; return id; } })();