您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Collects reward and the items requested from quests to put into a shared spreadsheet for stats. https://docs.google.com/spreadsheets/d/17lADRhz5POPYPxKRa6ZVYlJuKuYxxev0_bxnFPbK0Bk/edit?gid=1499161972#gid=1499161972
- // ==UserScript==
- // @name GC - Quest Reward Stat Collector
- // @namespace https://greasyfork.org/en/users/1202961-twiggies
- // @version 1.92
- // @description Collects reward and the items requested from quests to put into a shared spreadsheet for stats. https://docs.google.com/spreadsheets/d/17lADRhz5POPYPxKRa6ZVYlJuKuYxxev0_bxnFPbK0Bk/edit?gid=1499161972#gid=1499161972
- // @author Twiggies
- // @match https://www.grundos.cafe/winter/snowfaerie/complete/
- // @match https://www.grundos.cafe/halloween/witchtower/complete/
- // @match https://www.grundos.cafe/halloween/esophagor/complete/
- // @match https://www.grundos.cafe/island/kitchen/complete/
- // @match https://www.grundos.cafe/halloween/braintree/complete/
- // @icon https://www.google.com/s2/favicons?sz=64&domain=grundos.cafe
- // @grant GM_registerMenuCommand
- // @grant GM_setValue
- // @grant GM_getValue
- // @license MIT
- // ==/UserScript==
- let giveUsername = GM_getValue("sendUsername");
- //This function asks if you want your username to be sent or not.
- function usernamePrompt() {
- if (window.confirm("Would you like to send your username with your quest data? Press OK for Yes, or cancel for No.\nThis can be prompted again in the script extension's menu.")) {
- GM_setValue("sendUsername",true);
- giveUsername = true;
- }
- else {
- GM_setValue("sendUsername",false);
- giveUsername = false;
- }
- }
- //Adds the prompt for asking about username sending to the menu.
- const usernameMenuCommand = GM_registerMenuCommand("Set Send Username", function() {
- usernamePrompt();
- }, "u");
- if (giveUsername == undefined) {
- usernamePrompt();
- }
- let formLink = '';
- let returnButton = null;
- let submitDiv = document.createElement("div");
- submitDiv.innerHTML = "Submitting Quest Data...";
- submitDiv.id = "submitDiv";
- function taeliaRewards() {
- let rewardSpan = document.querySelector('div.center > div.flex-column.big-gap > span');
- if (rewardSpan == undefined) {
- return '';
- }
- let rewardText = rewardSpan.innerText;
- console.log(`Text: ${rewardText}`)
- //If text does not start with 'Taelia gives you a' then LEAVE.
- if (rewardText.startsWith('Taelia gives you a ') == false) {
- return '';
- }
- returnButton = document.querySelector('input.form-control[type="button"][value="Approach Taelia again..."]');
- returnButton.disabled = true;
- rewardSpan.insertAdjacentElement('afterend', submitDiv)
- //Taelia rewards should always be in the following format:
- //"Taelia gives you a Crazy Crisp Taco, Poison Snowball, and 17,983 Neopoints!!"
- //so "Taelia gives you a [Item], [SnowballItem], and [NP] Neopoints!!"
- //We need to figure out a way to split these out. Unfortunately, items can sometimes have commas in them (none of the items Taelia can reward atm does, but I want to future proof it), so we can't just split by comma.
- //I think I can work backwards instead. I know how to get the Neopoints...
- let neopoints = Number(rewardText.match(/(?! )\d*,?\d+(?= Neopoints!!)/)[0].replaceAll(',',''))
- console.log(`Neopoints: ${neopoints}`)
- //Now we get rid of the neopoints section.
- rewardText = rewardText.replace(/, and \d*,?\d+ Neopoints!!/g,'');
- console.log(`Text 2: ${rewardText}`)
- let snowBallItem = rewardText.match(/((?=, ).+ Snowball)|(, Snow \w*ball)|(, Frozen Pile of Dung)/gi)[0].trim();
- //Remove the , from the start if it's there.
- if (snowBallItem.startsWith(', ')) {
- snowBallItem = snowBallItem.slice(2).trim();
- }
- snowBallItem = encodeURIComponent(snowBallItem);
- console.log(`Snowball: ${snowBallItem}`)
- //Now get rid of the snowball section... Hoping it doesn't add a snowball that has a ', ' in it. Or a snowball that doesn't end in snowball.
- rewardText = rewardText.replace(/((?=, ).+ Snowball)|(, Snow \w*ball)|(, Frozen Pile of Dung)/gi,'')
- console.log(`Text 3: ${rewardText}`)
- //Now get the ice cream machine coupon item
- let couponItem = rewardText.match(/((?=, ).+ Ice Cream Machine Coupon)/gi);
- if (couponItem != null) {
- couponItem = couponItem[0].trim()
- //Remove the , from the start if it's there.
- if (couponItem.startsWith(', ')) {
- couponItem = couponItem.slice(2).trim();
- }
- couponItem = encodeURIComponent(couponItem);
- console.log(`Coupon: ${couponItem}`)
- //Now get rid of the coupon section...
- rewardText = rewardText.replace(/((?=, ).+ Ice Cream Machine Coupon)/gi,'')
- console.log(`Text 4: ${rewardText}`)
- }
- //Now for the last item. We just need to remove the beginning part... and we're good!
- let item1 = encodeURIComponent(rewardText.replace('Taelia gives you a ','').trim());
- console.log(`Item: ${item1}`)
- return `https://docs.google.com/forms/d/e/1FAIpQLSd426f2LiLlDYPnvGnIt-IUOB5tfvnNjNfIujx0V_sQROGtYw/formResponse?usp=pp_url&entry.1167335245=Taelia&entry.1736384931=${neopoints}&entry.1829837696=${item1}&entry.558379744=${snowBallItem}` + (couponItem != null ? `&entry.1082355197=${couponItem}` : '')
- }
- function ednaRewards() {
- const npRewardSpan = document.querySelector('div#quest_grid ~span');
- const itemRewardSpan = document.querySelector('div#quest_grid ~span ~span')
- if (npRewardSpan == undefined || itemRewardSpan == undefined) {
- return '';
- }
- let npRewardText = npRewardSpan.innerText;
- console.log(`npRewardText: ${npRewardText}`)
- let itemRewardText = itemRewardSpan.innerText;
- if (npRewardText.startsWith('Yes! I have all the ingredients!') == false || itemRewardText.startsWith('The old witch gives you ') == false) {
- return '';
- }
- returnButton = document.querySelector('input.form-control[type="button"][value="Approach the witch again..."]');
- returnButton.disabled = true;
- itemRewardSpan.insertAdjacentElement('afterend', submitDiv)
- //Extract the neopoints out of the text.
- let neopoints = Number(npRewardText.match(/\d+,+\d*(?!NP!)/gi)[0].replaceAll(',',''));
- console.log(`Neopoints: ${neopoints}`)
- //Extract the items... Edna reward text can come in two forms:
- // "The old witch gives you Spooky Lime Pudding !!"
- // And if she also rewards a second item:
- //"The old witch gives you Spooky Lime Pudding and Bottled Earth Faerie!!"
- // So if she gives a second item, it'll always be a bottled faerie, I'm pretty sure. So this will be based on that since there's probably lots of items with 'and' in the name.
- //So first, let's remove the starting text that'll always be there.
- itemRewardText = itemRewardText.replace("The old witch gives you ",'');
- //And then remove the two !! at the end. Just twim two chars off the end.
- itemRewardText = itemRewardText.slice(0, -2).trim()
- console.log(`itemRewardText: ${itemRewardText}`)
- //If there is ' and Bottled [x] Faerie', we want to split that out. If there's no extra faerie item it'll just be null.
- let faerieText = itemRewardText.match(/(?! and )Bottled .+ Faerie/g);
- console.log(`faerieText: ${faerieText}`);
- //We'll now remove the faerie text ,if it's there.
- itemRewardText = encodeURIComponent(itemRewardText.replace(/ and Bottled .+ Faerie/g,'').trim())
- console.log(`itemRewardText2: ${itemRewardText}`)
- let url = `https://docs.google.com/forms/d/e/1FAIpQLSd426f2LiLlDYPnvGnIt-IUOB5tfvnNjNfIujx0V_sQROGtYw/formResponse?usp=pp_url&entry.1167335245=Edna&entry.1736384931=${neopoints}&entry.1829837696=${itemRewardText}`
- if (faerieText != null) {
- url = url + `&entry.558379744=${encodeURIComponent(faerieText[0])}`
- }
- return url;
- }
- function esoRewards() {
- let itemRewardSpan = document.querySelector('div.center > div.flex-column.big-gap > span');
- if (itemRewardSpan == undefined) {
- return '';
- }
- let itemRewardText = itemRewardSpan.innerText;
- console.log(`Text: ${itemRewardText}`)
- //If text does not start with 'The Esophagor gives you ' then LEAVE.
- if (itemRewardText.startsWith('The Esophagor gives you ') == false) {
- return '';
- }
- let neopointRewardSpan = itemRewardSpan.nextElementSibling;
- let neopointRewardText = neopointRewardSpan.innerText;
- returnButton = document.querySelector('input.form-control[type="button"][value="Approach the Esophagor again..."]');
- returnButton.disabled = true;
- neopointRewardSpan.insertAdjacentElement('afterend', submitDiv)
- //Eso rewards will be in the following format:
- //Item: "The Esophagor gives you Roast Tentacle!!"
- //NP: "He also drops 9,360 NP; you pocket it quickly!"
- let neopoints = Number(neopointRewardText.match(/(?! )\d*,?\d+(?= NP;)/g)[0].replaceAll(',',''))
- console.log(`Neopoints: ${neopoints}`)
- //Get rid of the static text and clip of the !! at the end.
- itemRewardText = encodeURIComponent(itemRewardText.replace('The Esophagor gives you ','').slice(0, -2).trim());
- console.log(`Text 2: ${itemRewardText}`)
- return `https://docs.google.com/forms/d/e/1FAIpQLSd426f2LiLlDYPnvGnIt-IUOB5tfvnNjNfIujx0V_sQROGtYw/formResponse?usp=pp_url&entry.1167335245=Esophagor&entry.1736384931=${neopoints}&entry.1829837696=${itemRewardText}`
- }
- function kitchenRewards() {
- const rewardConfirmationSpan = document.querySelector('div#quest_grid ~span ~span')
- if (rewardConfirmationSpan == undefined) {
- return '';
- }
- //If text does not start with 'The Esophagor gives you ' then LEAVE.
- if (rewardConfirmationSpan.innerText.startsWith('The Chef waves his hands, and you may collect your prize...') == false) {
- return '';
- }
- returnButton = document.querySelector('input.form-control[type="button"][value="Approach the Chef Again"]');
- returnButton.disabled = true;
- //Look for the active pet, this is so we can check if it got a stat boost.
- const activePet = document.querySelector('#userinfo a[href*="/quickref/"]').innerText.trim();
- //Because the kitchen quest can have a few possible different formats of rewards, we'll loop through each element after the reward confirmation and do stuff based on that.
- let statBoost = '';
- let itemReward = '';
- let neopoints = '';
- let url = 'https://docs.google.com/forms/d/e/1FAIpQLSd426f2LiLlDYPnvGnIt-IUOB5tfvnNjNfIujx0V_sQROGtYw/formResponse?usp=pp_url&entry.1167335245=Kitchen'
- //Get the next element.
- let nextElement = rewardConfirmationSpan.nextElementSibling;
- while (nextElement != null && !(nextElement.tagName == "DIV" && nextElement.childElementCount == 2 && nextElement.classList.contains('half-width'))){
- //If it is a stat boost...
- if (nextElement.innerText.startsWith(`${activePet} gained `)) {
- statBoost = nextElement.innerText.match(/ of .+/g)[0].replace(' of ','').trim();
- url += '&entry.2021892051=' + statBoost
- }
- //If it is an item...
- else if (nextElement.innerText.startsWith('You get ')) {
- itemReward = encodeURIComponent(nextElement.innerText.replace('You get ','').slice(0,-2).trim());
- url += '&entry.1829837696=' + itemReward;
- }
- //If it's codestones...
- else if (nextElement.innerText.includes('a sack of codestones')) {
- url += '&entry.558379744=Codestones'
- }
- //If it's neopoints...
- else if (nextElement.innerText.startsWith('You also get ')) {
- neopoints = Number(nextElement.innerText.match(/(?! )\d*,?\d+(?= Neopoints!)/)[0].replaceAll(',',''))
- url += '&entry.1736384931=' + neopoints
- }
- nextElement = nextElement.nextElementSibling;
- }
- nextElement.insertAdjacentElement('beforebegin', submitDiv)
- return url;
- }
- function brainTreeRewards() {
- const wholeElement = document.querySelector('div.flex-column.big-gap')
- if (wholeElement == undefined || wholeElement.innerText.startsWith('Thank you, you are correct!') == false) {
- return '';
- }
- returnButton = document.querySelector('input.form-control[type="button"][value="Return to Haunted Woods"]');
- returnButton.disabled = true;
- let itemElement = wholeElement.children[3];
- itemElement.insertAdjacentElement('afterend', submitDiv)
- let itemReward = itemElement.innerText.slice(0,-2);
- return `https://docs.google.com/forms/d/e/1FAIpQLSd426f2LiLlDYPnvGnIt-IUOB5tfvnNjNfIujx0V_sQROGtYw/formResponse?usp=pp_url&entry.1167335245=Brain+Tree&entry.1829837696=${itemReward}`
- }
- //Only run if no quest items are NO. So exit if there's a single NO.
- let noNo = false;
- const itemList = document.querySelectorAll('.quest-text strong:nth-child(2)')
- //ALso get the items that were requested.
- let itemsRequested = {item0:"",item1:"",item2:"",item3:""}
- //Loop through each quest item to check if already got.
- for (let i = 0; i < itemList.length; i++) {
- if (itemList[i].innerText === "NO") {
- noNo = true;
- break;
- }
- else {
- itemsRequested['item'+i] = itemList[i].previousElementSibling.innerText;
- }
- }
- //If all the items have been gotten then the quest is done, so continue.
- if (noNo == false) {
- if (window.location.href == 'https://www.grundos.cafe/winter/snowfaerie/complete/') {
- formLink = taeliaRewards();
- }
- else if (window.location.href == 'https://www.grundos.cafe/halloween/witchtower/complete/') {
- formLink = ednaRewards();
- }
- else if (window.location.href == 'https://www.grundos.cafe/halloween/esophagor/complete/') {
- formLink = esoRewards();
- }
- else if (window.location.href == 'https://www.grundos.cafe/island/kitchen/complete/') {
- formLink = kitchenRewards();
- }
- else if (window.location.href == 'https://www.grundos.cafe/halloween/braintree/complete/') {
- formLink = brainTreeRewards();
- }
- if (formLink != '') {
- if (giveUsername) {
- formLink += '&entry.1732136035=' + document.querySelector('#userinfo a[href*="userlookup/?user="]').innerText.trim();
- }
- //Add the requested quest items.
- if (itemsRequested.item0 != "") {
- formLink += '&entry.669064702=' + itemsRequested.item0;
- }
- if (itemsRequested.item1 != "") {
- formLink += '&entry.1797043340=' + itemsRequested.item1;
- }
- if (itemsRequested.item2 != "") {
- formLink += '&entry.1426587972=' + itemsRequested.item2;
- }
- if (itemsRequested.item3 != "") {
- formLink += '&entry.1031263455=' + itemsRequested.item3;
- }
- let opts = {
- mode: "no-cors",
- //redirect: "follow",
- referrer: "no-referrer",
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- }
- }
- let response = fetch(formLink, opts)
- .then(response => {
- // handle the response
- console.log("Quest Data Submitted");
- submitDiv.innerHTML = '<a href="https://docs.google.com/spreadsheets/d/17lADRhz5POPYPxKRa6ZVYlJuKuYxxev0_bxnFPbK0Bk/edit?gid=1499161972#gid=1499161972" style="color:green; text-decoration: underline">Quest Data Submitted!</a>';
- returnButton.disabled = false;
- })
- .catch(error => {
- // handle the error
- console.log("Error: " + error);
- console.log(response)
- returnButton.disabled = false;
- submitDiv.innerHTML = `Failed to submit quest data: ${error}`;
- submitDiv.style.color = "red"
- });
- }
- }