您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds "Save current rig layout" & "Empty rig layout" quick actions to a Cracking crime.
当前为
// ==UserScript== // @name Torn Rigs Layout Switcher // @namespace https://github.com/SOLiNARY // @version 0.5.2 // @description Adds "Save current rig layout" & "Empty rig layout" quick actions to a Cracking crime. // @author Ramin Quluzade, Silmaril [2665762] // @license MIT License // @match https://www.torn.com/loader.php?sid=crimes* // @match https://www.torn.com/loader.php?sid=crimes#/cracking // @match https://sliw.co/rig/* // @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com // @grant unsafeWindow // @grant GM_addStyle // @run-at document-start // ==/UserScript== (async function() { 'use strict'; const IS_DEBUG = false; const isTampermonkeyEnabled = typeof unsafeWindow !== 'undefined'; setScriptVersion(); if (!checkCurrentSite()){ return; } let rigLayouts = localStorage.getItem("silmaril-rigs-layout-switcher-layouts") ?? ""; let rigLayoutsArray = rigLayouts.split(','); checkUrlForImport(); class ComponentInfo { constructor(x = null, y = null, item = null, x2 = null, y2 = null, action = null) { this.x = x; this.y = y; this.item = item; this.x2 = x2; this.y2 = y2; this.action = action; } } const rfcvArg = "rfcv="; let rfcv = localStorage.getItem("silmaril-rigs-layout-switcher-rfcv") ?? null; const crimesReadUrl = '/loader.php?sid=crimesData&step=crimesList&typeID=10&'; const crimesWriteUrl = '/loader.php?sid=crimesData&step=prepare&typeID=10&crimeID=204&value1='; let rfcvUpdatedThisSession = false; let mutationFound = false; let panelAdded = false; IS_DEBUG ? console.log('rigLayouts', rigLayouts, rigLayoutsArray) : null; let currentRig = 0; let rigsInfo = {0: [], 1: [], 2: []}; let requestsQueue = []; const { fetch: originalFetch } = isTampermonkeyEnabled ? unsafeWindow : window; const customFetch = async (...args) => { let [resource, config] = args; let response = await originalFetch(resource, config); let fetchUrl = response.url; if (fetchUrl.indexOf(crimesReadUrl) >= 0 || fetchUrl.indexOf(crimesWriteUrl) >= 0) { try { const jsonData = await response.clone().json(); const rig = fetchUrl.indexOf(crimesReadUrl) >= 0 ? jsonData.DB.crimesByType.rig : jsonData.DB.additionalInfo.prepareInfo.rig; IS_DEBUG ? console.log('rig.chassis', rig.chassis) : null; rig.chassis.forEach((rigData, rigId) => { IS_DEBUG ? console.log('rigData', rigData) : null; IS_DEBUG ? console.log('rigId', rigId) : null; IS_DEBUG ? console.log('rigData.components', rigData.components) : null; let items = []; if (rigData.components == null) { rigsInfo[rigId] = []; return; } rigData.components.forEach((componentData) => { if (componentData.ID == 0) { return; } let componentInfo = new ComponentInfo(componentData.coords[0].x, componentData.coords[0].y, componentData.ID); if (componentData.coords[1] != null) { componentInfo.x2 = componentData.coords[1].x; componentInfo.y2 = componentData.coords[1].y; } items.push(componentInfo); }); rigsInfo[rigId] = items; }); IS_DEBUG ? console.log('rigsInfo', rigsInfo) : null; } catch (error) { console.log('[TornRigsLayoutSwitcher] No targets, skipping the script init', error); } } if (rfcvUpdatedThisSession) { return response; } if (!rfcvUpdatedThisSession){ let rfcvIdx = fetchUrl.indexOf(rfcvArg); if (rfcvIdx >= 0){ rfcv = fetchUrl.substr(rfcvIdx + rfcvArg.length); localStorage.setItem("silmaril-loadout-switcher-rfcv", rfcv); document.querySelectorAll("div.silmaril-torn-rigs-layout-switcher-container button").forEach((button) => button.classList.remove("disabled")); rfcvUpdatedThisSession = true; } } return response; }; if (isTampermonkeyEnabled){ unsafeWindow.fetch = customFetch; } else { window.fetch = customFetch; } const styles = ` .wave-animation { position: relative; overflow: hidden; } .wave { pointer-events: none; position: absolute; width: 100%; height: 33px; background-color: transparent; opacity: 0; transform: translateX(-100%); animation: waveAnimation 3s cubic-bezier(0, 0, 0, 1); } @keyframes waveAnimation { 0% { opacity: 1; transform: translateX(-100%); } 100% { opacity: 0; transform: translateX(100%); } } `; if (isTampermonkeyEnabled){ GM_addStyle(styles); } else { let style = document.createElement("style"); style.type = "text/css"; style.innerHTML = styles; while (document.head == null){ await sleep(50); } document.head.appendChild(style); } const setLayoutUrl = "/loader.php?sid=crimesData&step=prepare&typeID=10&crimeID=204&value1={layout}&rfcv={rfcv}"; const resetTemplate = `{"step":"resetRig","chassisID":{rig}}`; const layoutTemplate = `{"step":"{step}","chassisID":{rig},"ID":{component},"coords":[{shortComponent}{longComponent}]}`; const coordinatesTemplate = `{"x":{xCoordinate},"y":{yCoordinate}}`; const add = 'add'; const remove = 'remove'; const componentIds = { "eCPU": 1, "CPU": 2, "HPCPU": 3, "Fan": 4, "Water Block": 5, "Heat Sink": 6, "PSU": 7, "None": 0 }; const observerTarget = document.querySelector("html"); const observerConfig = { attributes: false, childList: true, characterData: false, subtree: true }; const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutationItem) { if (mutationFound || panelAdded){ observer.disconnect(); return; } let mutation = mutationItem.target; if (mutation.classList == "crime-root cracking-root") { IS_DEBUG ? console.log('MATCHED RIG', mutation.querySelector('div.rig___aY5rF')) : null; const rigDiv = mutation.querySelector('div.rig___aY5rF'); if (rigDiv == null) { IS_DEBUG ? console.log('no rig found') : null; return; } IS_DEBUG ? console.log('Rig Found!') : null; mutationFound = true; observer.disconnect(); const buttonContainer = document.createElement('div'); buttonContainer.className = 'silmaril-rigs-layout-switcher-templates'; const waveDiv = document.createElement('div'); waveDiv.className = 'wave'; buttonContainer.appendChild(waveDiv); addEmptyAndLayoutButtons(buttonContainer); const spamButton = document.createElement('button'); spamButton.id = 'silmaril-rigs-layout-switcher-spam-button'; spamButton.type = 'button'; spamButton.className = 'torn-btn non-deletable disabled'; spamButton.textContent = 'No layout chosen'; spamButton.addEventListener('click', async event => { if (event.target.classList.contains('disabled')){ return; } const urlToProcess = requestsQueue.shift(); await sendSetLayoutRequest(urlToProcess); if (requestsQueue.length == 0) { event.target.classList.add('disabled'); event.target.textContent = 'All requests completed!'; } else { event.target.textContent = `Spam click ${requestsQueue.length} more times!`; } }); if (!panelAdded){ mutation.querySelector('div.currentCrime___KNKYQ').append(getRigChoices(), getLayoutActions(mutation), buttonContainer, spamButton); panelAdded = true; } } }); }); observer.observe(observerTarget, observerConfig); function setScriptVersion() { try { if (isTampermonkeyEnabled) { unsafeWindow.tornRigLayoutSwitcherVersion = GM_info.script.version; } else { window.tornRigLayoutSwitcherVersion = '0.5'; } } catch (e) { console.error('[TornRigsLayoutSwitcher] Failed to get script version!', e); } } function checkCurrentSite() { try { const currentUrl = window.location.href; const url = new URL(currentUrl); const domain = url.hostname; return domain.indexOf('torn.com') > 0; } catch (e) { console.error('[TornRigsLayoutSwitcher] Not Torn domain!', e); return false; } } function checkUrlForImport() { try { const importString = getUrlParameter('rig-import'); console.log('Initial value of rig-import:', importString); if (importString === null || importString.length < 75) { return; }; removeUrlParameter('rig-import'); console.log('Updated URL:', window.location.href); let rigsToImport = {}; for (let i = 0; i < 3; i++) { let rigToImport = []; for (let y = 0; y < 5; y++) { for (let x = 0; x < 5; x++) { const currentChar = importString[x + y * 5 + i * 25]; switch (currentChar){ case 'b': case 'P': case 'V': console.log(`[${x},${y}] Empty Slot`, currentChar); break; case 'e': console.log(`[${x},${y}] eCPU`); rigToImport.push({'x': x, 'y': y, 'item': 1}); break; case 'c': console.log(`[${x},${y}] CPU`); rigToImport.push({'x': x, 'y': y, 'item': 2}); break; case 'h': console.log(`[${x},${y}] HPCPU`); rigToImport.push({'x': x, 'y': y, 'item': 3}); break; case 'f': console.log(`[${x},${y}] Fan`); rigToImport.push({'x': x, 'y': y, 'item': 4}); break; case 'w': console.log(`[${x},${y}] Water Block`); rigToImport.push({'x': x, 'y': y, 'item': 5}); break; case 's': console.log(`[${x},${y}] Heat Sink`); rigToImport.push({'x': x, 'y': y, 'item': 6}); break; case 'p': console.log(`[${x},${y}] PSU Horizontal`); rigToImport.push({'x': x, 'y': y, 'item': 7, 'x2': x + 1, 'y2': y}); break; case 'v': console.log(`[${x},${y}] PSU Vertical`); rigToImport.push({'x': x, 'y': y, 'item': 7, 'x2': x, 'y2': y + 1}); break; default: console.log(`[${x},${y}] Unknown character`, currentChar); break; } } } if (rigToImport.length > 0) { rigsToImport[`rig-case.${i}`] = rigToImport; } } console.log('rigsToImport', rigsToImport); importLayout(rigsToImport); } catch (e) { console.error('[TornRigsLayoutSwitcher] Failed to import from URL!', e); } } function addEmptyAndLayoutButtons(root){ const empty = document.createElement('button'); empty.type = 'button'; empty.className = 'torn-btn non-deletable'; empty.textContent = 'Empty'; empty.setAttribute('data-action', 'remove'); empty.addEventListener('click', () => {handleLoadoutClick(root)}); root.appendChild(empty); addLayoutButtons(root); } function getRigChoices(){ const rigChoiceWrapper = document.createElement('ul'); rigChoiceWrapper.role = 'tablist'; rigChoiceWrapper.className = 'torn-tabs tabs-dark ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all'; const rigChoice1 = document.createElement('li'); rigChoice1.id = 'silmaril-rigs-layout-switcher-choice-1'; rigChoice1.role = 'button'; rigChoice1.ariaSelected = 'true'; rigChoice1.setAttribute('data-disable', '0'); rigChoice1.className = 'ui-state-default ui-corner-top ui-tabs-active ui-state-active'; rigChoice1.addEventListener('click', event => { IS_DEBUG ? console.log('event', event) : null; currentRig = 0; event.target.parentNode.classList.add('ui-tabs-active'); event.target.parentNode.classList.add('ui-state-active'); let rig2 = document.getElementById('silmaril-rigs-layout-switcher-choice-2'); rig2.classList.remove('ui-tabs-active'); rig2.classList.remove('ui-state-active'); let rig3 = document.getElementById('silmaril-rigs-layout-switcher-choice-3'); rig3.classList.remove('ui-tabs-active'); rig3.classList.remove('ui-state-active'); IS_DEBUG ? console.log('currentRig', currentRig) : null; }); const rigChoiceLink1 = document.createElement('a'); rigChoiceLink1.innerText = 'Chassis #1'; rigChoice1.append(rigChoiceLink1); const rigChoice2 = document.createElement('li'); rigChoice2.id = 'silmaril-rigs-layout-switcher-choice-2'; rigChoice2.role = 'button'; rigChoice2.ariaSelected = 'false'; rigChoice2.setAttribute('data-disable', '0'); rigChoice2.className = 'ui-state-default ui-corner-top'; rigChoice2.addEventListener('click', event => { IS_DEBUG ? console.log('event', event) : null; currentRig = 1; event.target.parentNode.classList.add('ui-tabs-active'); event.target.parentNode.classList.add('ui-state-active'); let rig1 = document.getElementById('silmaril-rigs-layout-switcher-choice-1'); rig1.classList.remove('ui-tabs-active'); rig1.classList.remove('ui-state-active'); let rig3 = document.getElementById('silmaril-rigs-layout-switcher-choice-3'); rig3.classList.remove('ui-tabs-active'); rig3.classList.remove('ui-state-active'); IS_DEBUG ? console.log('currentRig', currentRig) : null; }); const rigChoiceLink2 = document.createElement('a'); rigChoiceLink2.innerText = 'Chassis #2'; rigChoice2.append(rigChoiceLink2); const rigChoice3 = document.createElement('li'); rigChoice3.id = 'silmaril-rigs-layout-switcher-choice-3'; rigChoice3.role = 'button'; rigChoice3.ariaSelected = 'false'; rigChoice3.setAttribute('data-disable', '0'); rigChoice3.className = 'ui-state-default ui-corner-top'; rigChoice3.addEventListener('click', event => { IS_DEBUG ? console.log('event', event) : null; currentRig = 2; event.target.parentNode.classList.add('ui-tabs-active'); event.target.parentNode.classList.add('ui-state-active'); let rig1 = document.getElementById('silmaril-rigs-layout-switcher-choice-1'); rig1.classList.remove('ui-tabs-active'); rig1.classList.remove('ui-state-active'); let rig2 = document.getElementById('silmaril-rigs-layout-switcher-choice-2'); rig2.classList.remove('ui-tabs-active'); rig2.classList.remove('ui-state-active'); IS_DEBUG ? console.log('currentRig', currentRig) : null; }); const rigChoiceLink3 = document.createElement('a'); rigChoiceLink3.innerText = 'Chassis #3'; rigChoice3.append(rigChoiceLink3); rigChoiceWrapper.append(rigChoice1, rigChoice2, rigChoice3); IS_DEBUG ? console.log('rigChoiceWrapper', rigChoiceWrapper) : null; return rigChoiceWrapper; } function getLayoutActions(root){ const actionsContainer = document.createElement('div'); actionsContainer.className = 'silmaril-torn-rigs-layout-switcher-container'; const saveCurrentLayout = document.createElement('button'); saveCurrentLayout.type = 'button'; saveCurrentLayout.className = 'torn-btn'; saveCurrentLayout.textContent = 'Save current layout'; saveCurrentLayout.addEventListener('click', () => { IS_DEBUG ? console.log('save current layout') : null; let userInput = prompt("Please enter a unique name for a layout (DO NOT USE COMMAS ',')" ?? '').toLowerCase(); if (userInput !== null && userInput.length > 0) { rigLayouts = localStorage.getItem("silmaril-rigs-layout-switcher-layouts") ?? ""; rigLayoutsArray = rigLayouts.split(','); if (!rigLayoutsArray.includes(userInput)) { rigLayoutsArray.push(userInput); rigLayouts = rigLayoutsArray.join(','); localStorage.setItem("silmaril-rigs-layout-switcher-layouts", rigLayouts); } localStorage.setItem(`silmaril-rigs-layout-switcher-layout-${userInput}`, JSON.stringify(rigsInfo[currentRig], customReplacer)); root.querySelectorAll("div.silmaril-rigs-layout-switcher-templates > button:not(.non-deletable)").forEach((item) => item.remove()); addLayoutButtons(root.querySelector('div.currentCrime___KNKYQ > div.silmaril-rigs-layout-switcher-templates')); } else { console.error("[TornRigsLayoutSwitcher] User cancelled the layout naming input."); } }); const deleteLayout = document.createElement('button'); deleteLayout.type = 'button'; deleteLayout.className = 'torn-btn'; deleteLayout.textContent = 'Delete layout'; deleteLayout.addEventListener('click', () => { IS_DEBUG ? console.log('delete layout') : null; let userInput = prompt("Please enter a name of a layout to delete" ?? '').toLowerCase(); if (userInput !== null && userInput.length > 0) { rigLayouts = localStorage.getItem("silmaril-rigs-layout-switcher-layouts") ?? ""; rigLayoutsArray = rigLayouts.split(','); rigLayoutsArray = rigLayoutsArray.filter(item => item !== userInput); rigLayouts = rigLayoutsArray.join(','); localStorage.setItem("silmaril-rigs-layout-switcher-layouts", rigLayouts); localStorage.removeItem(`silmaril-rigs-layout-switcher-layout-${userInput}`); root.querySelectorAll("div.silmaril-rigs-layout-switcher-templates > button:not(.non-deletable)").forEach((item) => item.remove()); addLayoutButtons(root.querySelector('div.currentCrime___KNKYQ > div.silmaril-rigs-layout-switcher-templates')); } else { console.error("[TornRigsLayoutSwitcher] User cancelled the layout naming input."); } }); const exportAllLayouts = document.createElement('button'); exportAllLayouts.type = 'button'; exportAllLayouts.className = 'torn-btn'; exportAllLayouts.textContent = 'Export all layouts'; exportAllLayouts.addEventListener('click', () => { IS_DEBUG ? console.log('export all layouts') : null; rigLayouts = localStorage.getItem("silmaril-rigs-layout-switcher-layouts") ?? ""; rigLayoutsArray = rigLayouts.split(','); let allLayoutsToExport = {}; rigLayoutsArray.forEach((layoutName) => { if (layoutName == ''){ return; } try { const layoutInfo = localStorage.getItem(`silmaril-rigs-layout-switcher-layout-${layoutName}`); IS_DEBUG ? console.log(`layout ${layoutName}`, layoutInfo) : null; allLayoutsToExport[layoutName] = JSON.parse(layoutInfo); IS_DEBUG ? console.log('allLayoutsToExport step', allLayoutsToExport) : null; } catch (e) { return; } }); IS_DEBUG ? console.log('allLayoutsToExport final', allLayoutsToExport) : null; const allLayoutsToExportRaw = JSON.stringify(allLayoutsToExport, customReplacer); IS_DEBUG ? console.log('allLayoutsToExport stringify', allLayoutsToExportRaw) : null; prompt('Copy the text below & share it with friends!', allLayoutsToExportRaw); }); const exportLayout = document.createElement('button'); exportLayout.type = 'button'; exportLayout.className = 'torn-btn'; exportLayout.textContent = 'Export layout'; exportLayout.addEventListener('click', () => { IS_DEBUG ? console.log('export layout') : null; let userInput = prompt("Please enter a name of a layout to export" ?? '').toLowerCase(); if (userInput !== null && userInput.length > 0) { let layoutToExport = {}; try { const layoutInfo = localStorage.getItem(`silmaril-rigs-layout-switcher-layout-${userInput}`); if (layoutInfo == null) { console.log('[TornRigsLayoutSwitcher] No layout with this name!', userInput); return; } IS_DEBUG ? console.log(`layout ${userInput}`, layoutInfo) : null; layoutToExport[userInput] = JSON.parse(layoutInfo); } catch (e) { return; } IS_DEBUG ? console.log('layoutToExport final', layoutToExport) : null; const layoutToExportRaw = JSON.stringify(layoutToExport, customReplacer); IS_DEBUG ? console.log('layoutToExport stringify', layoutToExportRaw) : null; prompt('Copy the text below & share it with friends!', layoutToExportRaw); } else { console.error("[TornRigsLayoutSwitcher] User cancelled the layout naming input."); } }); const importLayouts = document.createElement('button'); importLayouts.type = 'button'; importLayouts.className = 'torn-btn'; importLayouts.textContent = 'Import layouts'; importLayouts.addEventListener('click', () => { IS_DEBUG ? console.log('save current layout') : null; let userInput = prompt("Please copy-paste the string which has been shared with you" ?? '').toLowerCase(); if (userInput !== null && userInput.length > 0) { try { const allLayoutsToImport = JSON.parse(userInput); importLayout(allLayoutsToImport); } catch (e) { return; } root.querySelectorAll("div.silmaril-rigs-layout-switcher-templates > button:not(.non-deletable)").forEach((item) => item.remove()); addLayoutButtons(root.querySelector('div.currentCrime___KNKYQ > div.silmaril-rigs-layout-switcher-templates')); } else { console.error("[TornRigsLayoutSwitcher] User cancelled the layout naming input."); } }); actionsContainer.append(saveCurrentLayout, deleteLayout, exportAllLayouts, exportLayout, importLayouts); return actionsContainer; } async function addLayoutButtons(root){ rigLayoutsArray.forEach((layout) => { if (layout == ''){ return; } const button = document.createElement('button'); button.type = 'button'; button.className = rfcv === null ? 'torn-btn disabled' : 'torn-btn'; button.textContent = layout; button.setAttribute('data-action', 'add'); button.addEventListener('click', () => {handleLoadoutClick(root, layout)}); root.appendChild(button); }) } function importLayout(allLayoutsToImport) { IS_DEBUG ? console.log('allLayoutsToImport', allLayoutsToImport) : null; const allLayoutNamesToImport = Object.keys(allLayoutsToImport); rigLayouts = localStorage.getItem("silmaril-rigs-layout-switcher-layouts") ?? ""; rigLayoutsArray = rigLayouts.split(','); allLayoutNamesToImport.forEach((layoutName) => { if (layoutName == ''){ return; } IS_DEBUG ? console.log('layoutName', layoutName) : null; IS_DEBUG ? console.log('layout', allLayoutsToImport[layoutName]) : null; try { if (!rigLayoutsArray.includes(layoutName)) { rigLayoutsArray.push(layoutName); } localStorage.setItem(`silmaril-rigs-layout-switcher-layout-${layoutName}`, JSON.stringify(allLayoutsToImport[layoutName], customReplacer)); IS_DEBUG ? console.log('layougetLayout', localStorage.getItem(`silmaril-rigs-layout-switcher-layout-${layoutName}`)) : null; } catch (e) { console.error("[TornRigsLayoutSwitcher] Error while importing Layout", e); return; } }); rigLayouts = rigLayoutsArray.join(','); localStorage.setItem("silmaril-rigs-layout-switcher-layouts", rigLayouts); } async function handleLoadoutClick(root, layoutName = null){ let action = event.target.getAttribute('data-action'); if (event.target.classList.contains('disabled')){ return; } IS_DEBUG ? console.log('rigsInfo', rigsInfo) : null; let currentLayout = rigsInfo[currentRig]; currentLayout.forEach(cell => { if (cell.x2 != null && cell.y2 != null) { // Swap the values if (cell.x == cell.x2 && cell.y > cell.y2) { cell.y2 = [cell.y, cell.y = cell.y2][0]; } if (cell.y == cell.y2 && cell.x > cell.x2) { cell.x2 = [cell.x, cell.x = cell.x2][0]; } } }); let layoutItemsToBeRemoved = []; let layoutItemsToBeAdded = []; if (layoutName == null) { let resetRig = new ComponentInfo(); resetRig.action = 'resetRig'; action = 'resetRig'; layoutItemsToBeRemoved.push(resetRig); } else { let newLayout = JSON.parse(localStorage.getItem(`silmaril-rigs-layout-switcher-layout-${layoutName}`)); newLayout.forEach(cell => { if (cell.x2 != null && cell.y2 != null) { // Swap the values if (cell.x == cell.x2 && cell.y > cell.y2) { cell.y2 = [cell.y, cell.y = cell.y2][0]; } if (cell.y == cell.y2 && cell.x > cell.x2) { cell.x2 = [cell.x, cell.x = cell.x2][0]; } } }); for (let x = 0; x < 5; x++) { for (let y = 0; y < 5; y++) { let currentCell = currentLayout.filter(cell => cell.x == x && cell.y == y); let newCell = newLayout.filter(cell => cell.x == x && cell.y == y); if (currentCell.length == 0) { if (newCell.length == 0) { IS_DEBUG ? console.log(`[${x},${y}] no cells, no conflict`) : null; continue; } else { IS_DEBUG ? console.log(`[${x},${y}] adding new cell`) : null; IS_DEBUG ? console.log('newCell[0]', newCell[0]) : null; let clonedCell = newCell[0]; clonedCell.action = 'add'; layoutItemsToBeAdded.push(clonedCell); } } else { if (newCell.length == 0) { IS_DEBUG ? console.log(`[${x},${y}] removing old cell`) : null; IS_DEBUG ? console.log('currentCell[0]', currentCell[0]) : null; let clonedCell = currentCell[0]; clonedCell.action = 'remove'; layoutItemsToBeRemoved.push(clonedCell); } else { IS_DEBUG ? console.log(`[${x},${y}] comparing cells`) : null; IS_DEBUG ? console.log('currentCell[0]', currentCell[0]) : null; IS_DEBUG ? console.log('newCell[0]', newCell[0]) : null; if (currentCell[0].item == newCell[0].item && currentCell[0].x2 == newCell[0].x2 && currentCell[0].y2 == newCell[0].y2) { IS_DEBUG ? console.log(`[${x},${y}] same cells, no conflict`) : null; continue; } else { IS_DEBUG ? console.log(`[${x},${y}] diff cells, remove & add`) : null; let oldClonedCell = currentCell[0]; oldClonedCell.action = 'remove'; layoutItemsToBeRemoved.push(oldClonedCell); let newClonedCell = newCell[0]; newClonedCell.action = 'add'; layoutItemsToBeAdded.push(newClonedCell); } } } } } } const layoutItems = [...layoutItemsToBeRemoved, ...layoutItemsToBeAdded]; IS_DEBUG ? console.log('currentLayout', currentLayout) : null; IS_DEBUG ? console.log('layoutItems', layoutItems) : null; await saveSetLayoutRequestsToQueue(action, currentRig, layoutItems, root); } function saveSetLayoutRequestsToQueue(action, rig, items, root){ // console.log('items', items); requestsQueue = []; const urlWithRfcv = setLayoutUrl.replace("{rfcv}", rfcv); if (action == 'resetRig') { const layoutUrl = resetTemplate.replace("{rig}", rig); const url = urlWithRfcv.replace("{layout}", layoutUrl); requestsQueue.push(url); } else { items.forEach((item) => { const coordinates = coordinatesTemplate.replace("{xCoordinate}", item.x).replace("{yCoordinate}", item.y); let layoutUrl2 = layoutTemplate.replace("{step}", item.action).replace("{rig}", rig).replace("{component}", item.item).replace("{shortComponent}", coordinates); let layoutUrl; if (item.x2 != null) { const coordinatesLong = coordinatesTemplate.replace("{xCoordinate}", item.x2).replace("{yCoordinate}", item.y2); layoutUrl = layoutUrl2.replace("{longComponent}", `,${coordinatesLong}`); } else { layoutUrl = layoutUrl2.replace("{longComponent}", ""); } const url = urlWithRfcv.replace("{layout}", layoutUrl); requestsQueue.push(url); }); } let spamButton = document.getElementById('silmaril-rigs-layout-switcher-spam-button'); spamButton.textContent = `Spam click ${requestsQueue.length} more times!`; spamButton.classList.remove('disabled'); } async function sendSetLayoutRequest(url){ await fetch(url, { method: 'GET', }) .then(response => { if (response.ok) { // console.log('component change request OK'); } else { console.error("[TornRigsLayoutSwitcher] Set Layout request failed:", response); } }) .catch(error => { console.error("[TornRigsLayoutSwitcher] Error setting Layout:", error); }); } function customReplacer(key, value) { // Omit properties with null values or specific strings if (value === null || value === 'add' || value === 'remove' || value === 'move') { return undefined; } return value; } // Function to get the value of a URL parameter by name function getUrlParameter(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } // Function to remove a URL parameter by name function removeUrlParameter(name) { const urlParams = new URLSearchParams(window.location.search); urlParams.delete(name); const searchParamsString = urlParams.toString(); // Handle the presence of a fragment identifier const hash = window.location.hash; // Create the updated URL const newUrl = window.location.pathname + (searchParamsString ? '?' + searchParamsString : '') + hash; // Replace the current state to update the URL without triggering a page reload history.replaceState({}, document.title, newUrl); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址