您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Calculates the cost of the Grundos Cafe Quest items as the user searches for them on the Shop Wiz. Displays the info in a table above the Shop Wiz Search. Does not include Main Shops. Only Shop Wiz.
当前为
// ==UserScript== // @name Grundos Cafe Quest Cost Calculator // @namespace https://www.grundos.cafe // @namespace https://grundos.cafe // @version 0.21 // @description Calculates the cost of the Grundos Cafe Quest items as the user searches for them on the Shop Wiz. Displays the info in a table above the Shop Wiz Search. Does not include Main Shops. Only Shop Wiz. // @author Dark_Kyuubi // @match https://www.grundos.cafe/market/wizard* // @match https://grundos.cafe/market/wizard* // @match https://www.grundos.cafe/winter/snowfaerie* // @match https://grundos.cafe/winter/snowfaerie* // @match https://www.grundos.cafe/halloween/witchtower* // @match https://grundos.cafe/halloween/witchtower* // @match https://www.grundos.cafe/halloween/esophagor* // @match https://grundos.cafe/halloween/esophagor* // @match https://www.grundos.cafe/island/kitchen* // @match https://grundos.cafe/island/kitchen* // @icon https://www.google.com/s2/favicons?sz=64&domain=grundos.cafe // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @license MIT // ==/UserScript== class Item { constructor(name, cost) { this.name = name; this.cost = cost; } } //Map serialization and proper Map checking is pain let quests = new Map(); let questsGrid = document.createElement('div'); const styles = ` .quest-item,.quest-giver,.final-cost { width: 100%; height: 100%; border: 1px solid black; ` let styleSheet = document.createElement("style"); (function () { 'use strict'; const storedQuests = GM_getValue('quests'); console.log("storedQuest: ", storedQuests); if (storedQuests) { console.log("storedQuests is not undefined or null, attempting to parse storedQuests"); const parsedStoredQuests = JSON.parse(storedQuests)?.reduce((m, [key, val]) => m.set(key, val), new Map()); console.log("parsedStoredQuests: ", parsedStoredQuests); if (parsedStoredQuests instanceof Map) { quests = parsedStoredQuests; } } if (!window.location.href.includes("wizard")) { GM_setValue('fromQuest', false); let questGiver = determineQuestGiver(); if (window.location.href.includes("complete")) { if (!document.querySelector("strong.red")) { quests.delete(questGiver); quests.size == 0 ? GM_deleteValue('quests') : updateStoredQuests(); } } else { getNewQuestItems(questGiver); } document.querySelectorAll('.searchhelp>a[href*="wizard"]').forEach(el => el.onclick = function () { GM_setValue('fromQuest', true); }) } else { let shopWizResult = document.querySelector('.sw_results'); if (quests.size > 0 && GM_getValue('fromQuest', false) && shopWizResult) { pushStyle(); showCalculatedQuestsSumOnWiz(shopWizResult); GM_setValue('fromQuest', false); } } function showCalculatedQuestsSumOnWiz(shopWizResult) { collectShopWizPrice(); questsGrid.setAttribute('style', getGridStyle()); createQuestGiverHeaders(); createQuestItemRows(); createQuestSumRow(); //to find it easier in the DOM for debugging purposes questsGrid.className = 'quest-grid'; //try not to insert on main Shop Wiz page, only on result page document.getElementsByTagName('main')[0]?.insertBefore(questsGrid, shopWizResult); } function getGridStyle() { let gridStyle = 'display: grid; border: 1px solid black;text-align: center;'; //columns gridStyle += 'grid-template-columns: repeat(' + quests.size + ', 1fr);'; return gridStyle; } function createQuestItemRows() { for (let i = 0; i < 4; i++) { for (const key of quests.keys()) { let itemName = quests.get(key)[i]?.name; if (!itemName) { itemName = "-"; } questsGrid.innerHTML += '<div class="quest-item">' + itemName + '</div>'; }; } } function collectShopWizPrice() { let swItem = document.querySelector('.nomargin>strong')?.innerHTML.substring(18, undefined).trim(); let swPrice = parseInt(document.querySelector('.sw_results>.data>strong')?.innerHTML.match(/\d+/g).join('')); if (swItem && swPrice) { updatePriceForQuestItems(swItem, swPrice); updateStoredQuests(); } } function getNewQuestItems(questGiver) { //when you accept a quest, they are listed in .shop-item, when you return to a quest, they are listed as .quest-item... that's annoying. let questItemsElements = document.querySelectorAll('.shop-item').size > 0 ? document.querySelectorAll('.shop-item') : document.querySelectorAll('.quest-item'); if (questItemsElements) { console.log("questItemsElements: ", questItemsElements); let questItems = getQuestItems(questItemsElements); console.log("questItems: ", questItems); quests.set(questGiver, questItems); updateStoredQuests(); } } })(); function pushStyle() { styleSheet.innerText = styles; document.head.appendChild(styleSheet); } function createQuestSumRow() { for (const key of quests.keys()) { let items = quests.get(key); let sum = 0; for (const item of items) { sum += item.cost; } questsGrid.innerHTML += '<div class="final-cost">' + sum + '</div>'; } } function createQuestGiverHeaders() { for (const key of quests.keys()) { console.log("adding " + key + " to header row"); questsGrid.innerHTML += '<div class="quest-giver">' + key + '</div>'; }; } function updateStoredQuests() { GM_setValue('quests', JSON.stringify(Array.from(quests))); } function updatePriceForQuestItems(swItem, swPrice) { for (const arrayOfValues of quests.values()) { for (const value of arrayOfValues) { if (value.name === swItem) { console.log("udpating: ", value.name); value.cost = swPrice; } } }; } function getQuestItems(questItemsElements) { let questItems = []; for (let i = 0; i < questItemsElements?.length; i++) { let questItemName = questItemsElements[i].querySelector('strong').innerHTML; let item = new Item(questItemName, null); questItems[i] = item; } return questItems; } function determineQuestGiver() { if (window.location.href.includes('snowfaerie')) { return 'snowfaerie'; } else if (window.location.href.includes('witchtower')) { return 'edna'; } else if (window.location.href.includes('esophagor')) { return 'esophagor'; } else if (window.location.href.includes('kitchen')) { return 'kitchen'; } }