// ==UserScript==
// @name [GC] - Underwater Fishing Data Logger
// @namespace Grundo's Cafe
// @match https://www.grundos.cafe/water/fishing/
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.addStyle
// @grant GM.notification
// @grant GM.xmlHttpRequest
// @version 1.3.6
// @license MIT
// @author Cupkait
// @icon https://i.imgur.com/4Hm2e6z.png
// @description Fishing rewards sorting, logging and Discord Webhooks.
// @require https://update.greasyfork.org/scripts/489454/1467893/%5BGC%5D%20-%20Underwater%20Fishing%20Prizes%20Library.js
// ==/UserScript==
const userName = /user=(.*?)"/g.exec(document.body.innerHTML)[1];
const buttonFishAll = document.querySelector('input[value="Fish with Everyone!"]');
const buttonFishOne = document.querySelector('input[value="Reel in Your Line"]');
var webHooks = GM.getValue("webHooks", []);
if (window.location.href.endsWith('settings')) {
document.querySelector('main').remove();
}
async function getCurrentPetLevels() {
try {
const response = await fetch("/quickref/");
if (!response.ok) {
throw new Error('Network response was not ok');
}
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const petList = doc.querySelector("#quickref_petlist").children;
const petLevels = {};
Array.from(petList).forEach(pet => {
const petrefName = pet.querySelector("a").getAttribute("href").match(/_name=(.*?)$/)[1];
const petFishingLevel = pet.querySelectorAll("span")[12].textContent.match(/Fishing : (.*?)$/)[1];
petLevels[petrefName] = petFishingLevel;
});
sessionStorage.setItem('petLevels', JSON.stringify(petLevels));
} catch (error) {
console.error("Error fetching data:", error);
return null;
}
}
async function collectFishingResults() {
let displayResults = document.createElement("div");
displayResults.innerHTML = "Loading results... please wait.";
displayResults.id = "displayResults";
displayResults.style.cssText =
"color: green; text-align: center; link-color:green; font-size:14px; font-weight:bold;";
document.querySelector("div#page_content > main").insertAdjacentElement("beforebegin", displayResults);
const resultsList = document.querySelectorAll('.center-items');
const resultsDiv = document.querySelector('.flex-column')
let results = [];
let highlights = false;
const goodPrizes = document.createElement('div');
if (resultsList.length > 0) {
displayResults.innerHTML = await `Your fishing results have been <a href="https://lookerstudio.google.com/reporting/ec18c798-ee62-4a7d-8315-5569c8de5ef6" target="_blank">submitted</a>.`;
resultsList.forEach(result => {
var name = result.querySelector('strong').textContent;
var item = result.querySelector('p').textContent.match(/ a (.*?)!/)[1];
var cooldown = result.querySelectorAll('strong')[1].textContent;
var image = result.querySelectorAll('img')[1].src;
var newlevel = result.querySelectorAll("p")[1].textContent.includes("fishing level") ? result.querySelectorAll("p")[1].textContent.match(/\d+/)[0] : null;
var storedLevels = JSON.parse(sessionStorage.getItem('petLevels'));
var oldlevel = storedLevels && storedLevels[name];
results.push({ name, item, cooldown, image, oldlevel, newlevel });
sendResultToDatabase(name, oldlevel, newlevel, item, cooldown);
const prize = prizes.find(prize => prize.item === item);
if (prize) {
highlights = true
goodPrizes.append(result);
generatePrizeWebhooks(name, oldlevel, item, image);
} else {
console.log("Prize sucked, no webhook sent.")
};
});
if (highlights === true) {
const fishingstyle = document.createElement('style');
fishingstyle.innerHTML = `
.center-items img {
transform: translate3d(0, 0, 0);
mix-blend-mode: multiply;
}
`;
//document.head.appendChild(fishingstyle);
goodPrizes.classList.add("center-items");
goodPrizes.style.backgroundColor = "#efef404f";
goodPrizes.style.border = "2px solid black"
resultsDiv.insertAdjacentElement('beforebegin', goodPrizes);
}
} else {
const resultSingle = document.querySelector('#page_content .center');
if (resultSingle) {
var name = document.querySelectorAll('#userinfo a')[2].textContent;
var item = resultSingle.querySelector("img").alt;
var cooldown = resultSingle.querySelector('strong').textContent;
var image = resultSingle.querySelector('img').src;
var newlevel = resultSingle.querySelectorAll("p")[1].textContent.includes("fishing level") ? resultSingle.querySelectorAll("p")[1].textContent.match(/\d+/)[0] : null;
var storedLevels = JSON.parse(sessionStorage.getItem('petLevels'));
var oldlevel = storedLevels && storedLevels[name];
results.push({ name, item, cooldown, image, oldlevel, newlevel });
sendResultToDatabase(name, oldlevel, newlevel, item, cooldown);
const prize = prizes.find(prize => prize.item === item);
if (prize) {
console.log("Valid prize identified.")
generatePrizeWebhooks(name, oldlevel, item, image);
} else {
console.log("Prize sucked, no webhook sent.")
};
}}
}
// Only collect results if you've actually attempted to fish.
if (document.referrer.endsWith("/water/fishing/") && document.querySelector('main').textContent.includes("You reel in your line and get")) {
collectFishingResults();
}
//else {createFishHookSettings();}
// Only fetch current fishing levels when you click the button to fish.
if (buttonFishOne || buttonFishAll) {
document.addEventListener("click", async function(event) {
if (event.target === buttonFishOne || event.target === buttonFishAll) {
event.preventDefault();
await getCurrentPetLevels();
event.target.form.submit();
}
});
}
function getTimestamp() {
const currentDate = new Date();
const pstOffset = -8 * 60; // PST offset is UTC-8
const timestampPST = new Date(currentDate.getTime() + pstOffset * 60 * 1000);
return timestampPST.toISOString().replace("T", " ").replace("Z", "");
}
async function sendResultToDatabase(name, oldlevel, newlevel, item, cooldown) {
let opts = {
mode: "no-cors",
referrer: "no-referrer",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
};
const logResponse = `https://docs.google.com/forms/d/e/1FAIpQLSdBhJS1NSxHCmy32BqH0DEdQRJci1IVPOWUFcaothsiZjXu-w/formResponse?usp=pp_url&entry.886049257=${userName}&entry.343654154=${name}&entry.1922136733=${oldlevel}&entry.693447328=${newlevel}&entry.881968876=${item}&entry.303510013=${cooldown}&entry.1110645895=`;
try {
await fetch(logResponse, opts);
} catch (error) {
// Do nothing
}
}
async function generatePrizeWebhooks(name, oldlevel, item, image) {
console.log("Webhook generated.")
const webHooks = await GM.getValue("webHooks", []);
const hook = {
content: null,
embeds: [
{
description:
`${item}?\nWhat a great prize!`,
color: 9356588,
author: {
name: `${userName} took ${name} fishing...`,
},
thumbnail: {
url: `${image}`,
},
},
],
username: "Underwater Fishing Prizes",
avatar_url: "https://i.imgur.com/4Hm2e6z.png",
attachments: [],
};
for (const webhook of webHooks) {
try {
await sendMessage(hook, webhook);
console.log("Message sent successfully.");
} catch (error) {
console.error("Error sending message:", error);
}
}
}
async function sendMessage(hook, webhook) {
console.log("Webhook triggered.");
return new Promise((resolve, reject) => {
GM.xmlHttpRequest({
method: "POST",
url: webhook,
headers: {
"Content-Type": "application/json"
},
data: JSON.stringify(hook),
onload: function(response) {
if (response.status >= 200 && response.status < 300) {
resolve(response.responseText);
} else {
reject(new Error(`Request failed with status ${response.status}`));
}
},
onerror: function(error) {
reject(error);
}
});
});
}
async function createFishHookSettings() {
const wrapperContainer = document.createElement("div");
wrapperContainer.id = "wrapContainer";
wrapperContainer.style.position = "relative";
wrapperContainer.style.borderBottom = "3px solid";
wrapperContainer.style.padding = "5px 10px 5px 0px";
wrapperContainer.style.height = "30px";
wrapperContainer.style.width = "100%";
wrapperContainer.style.top = "0px";
wrapperContainer.style.left = "0px";
wrapperContainer.style.backgroundColor = "#d2d0cc";
wrapperContainer.style.boxShadow = "5px 0 5px rgba(0, 0, 0, 0.5)";
const wrapperSettings = document.createElement("button");
wrapperSettings.textContent = "Fish Hook Settings";
wrapperSettings.id = "wrapSettings";
wrapperSettings.style.position = "relative";
wrapperSettings.style.fontSize = "12px";
wrapperSettings.style.fontWeight = "bold";
wrapperSettings.style.fontFamily = "courier";
wrapperSettings.style.padding = "0px";
wrapperSettings.style.width = "100%";
wrapperSettings.style.height = "auto";
wrapperSettings.style.border = "1px solid rgb(204, 204, 204)";
wrapperSettings.style.cursor = "pointer";
wrapperSettings.style.backgroundColor = "transparent";
const wrapperMenu = document.createElement("div");
wrapperMenu.id = "wrapMenu";
wrapperMenu.style.display = "none";
wrapperMenu.style.borderRadius = "15px 15px 15px 0px";
wrapperMenu.style.borderBottom = "3px solid";
wrapperMenu.style.position = "absolute";
wrapperMenu.style.width = "200px";
wrapperMenu.style.height = "250px";
wrapperMenu.style.bottom = "0%";
wrapperMenu.style.left = "100%";
wrapperMenu.style.margin = "-3px";
wrapperMenu.style.padding = "10px";
wrapperMenu.style.backgroundColor = "#d2d0cc";
wrapperMenu.style.boxShadow = "5px 0 5px rgba(0, 0, 0, 0.5)";
const firstButton = document.createElement("button");
firstButton.textContent = "Add a Webhook";
firstButton.id = "menubutton";
firstButton.style.height = "35px";
firstButton.style.width = "98%";
firstButton.style.margin = "5px 3px";
firstButton.style.backgroundColor = "transparent";
firstButton.style.borderRadius = "5px";
firstButton.style.boxShadow = "5px 0 5px rgba(0, 0, 0, 0.5)";
firstButton.addEventListener("click", addWebhook);
wrapperMenu.appendChild(firstButton);
wrapperContainer.appendChild(wrapperSettings);
wrapperContainer.appendChild(wrapperMenu);
document.getElementById("sb_edge").appendChild(wrapperContainer);
wrapperSettings.addEventListener("click", () => {
wrapperMenu.style.display = wrapperMenu.style.display === "none" ? "block" : "none";
});
async function addWebhook() {
var newWebhook = prompt(
"Paste one webhook URL to add to your script.\n\nIf you want to add multiple, do one at a time."
);
if (newWebhook) {
let webHooks = await GM.getValue("webHooks", []);
if (!Array.isArray(webHooks)) {
webHooks = [];
}
webHooks = [...new Set(webHooks)];
if (!webHooks.includes(newWebhook)) {
webHooks.push(newWebhook);
await GM.setValue("webHooks", webHooks);
alert("Webhook added successfully!");
} else {
webHooks = [...new Set(webHooks)];
await GM.setValue("webHooks", webHooks);
alert("This webhook URL is already added.");
}
}
}
GM.addStyle(`
#wrapContainer, #wrapSettings, #wrapMenu {
background-color: #d2d0cc;
}
#wrapSettings {
cursor: pointer;
}
#wrapMenu {
display: none;
border-radius: 15px 15px 15px 0px;
border-bottom: 3px solid;
position: absolute;
width: 200px;
height: 250px;
bottom: 0%;
left: 100%;
margin: -3px;
padding: 10px;
box-shadow: 5px 0 5px rgba(0, 0, 0, 0.5);
}
`);
}
createFishHookSettings();
GM.addStyle(`
#hookButton {
width: 480px;
height:20px;
display: flex;
justify-content: flex-end;
}
`);