您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds the ability to have multiple virtual bank accounts within your bank as well as transfer/withdraw from each
// ==UserScript== // @name [GC] Bank Account Optimizer // @namespace http://tampermonkey.net/ // @version 1.2 // @license MIT // @description Adds the ability to have multiple virtual bank accounts within your bank as well as transfer/withdraw from each // @author Heda // @match https://www.grundos.cafe/bank/ // @grant none // ==/UserScript== (function () { 'use strict'; const parseNP = str => parseInt(str.replace(/,/g, '').match(/\d+/)?.[0] || '0'); const formatNP = num => num.toLocaleString() + " NP"; const accountInfo = [...document.querySelectorAll('p')].find(p => p.innerHTML.includes('Account Type') && p.innerHTML.includes('Current Balance') ); if (!accountInfo) return; const accountType = (accountInfo.innerHTML.match(/<strong class="green">(.+?)<\/strong>/) || [])[1] || "Unknown"; const baseMainBalance = parseNP((accountInfo.innerHTML.match(/Current Balance<\/strong> : ([\d,]+) NP/) || [])[1]); const balances = { account1: getStoredBalance("account1", baseMainBalance), account2: getStoredBalance("account2", 0), account3: getStoredBalance("account3", 0) }; const dropdowns = []; const container = document.createElement("div"); Object.assign(container.style, { display: "flex", flexWrap: "wrap", gap: "20px", margin: "20px 0" }); const hr = document.querySelector('hr'); hr.parentNode.insertBefore(container, hr); container.appendChild(createAccountBox(1, balances.account1, true)); container.appendChild(createAccountBox(2, balances.account2)); container.appendChild(createAccountBox(3, balances.account3)); updateTransferDropdowns(); hookDepositForms(); function getStoredBalance(key, fallback) { const stored = localStorage.getItem(key); return stored !== null ? parseInt(stored) : fallback; } function saveBalance(key, value) { localStorage.setItem(key, value.toString()); const display = document.querySelector(`#${key}`); if (display) display.innerText = formatNP(value); } function getAccountName(key, fallback) { return localStorage.getItem(`${key}_name`) || fallback; } function saveAccountName(key, name) { localStorage.setItem(`${key}_name`, name); const title = document.querySelector(`#title-${key}`); if (title) title.textContent = name; updateTransferDropdowns(); } function updateTransferDropdowns() { dropdowns.forEach(({ dropdown, fromKey }) => { dropdown.innerHTML = ""; Object.keys(balances).forEach(key => { if (key !== fromKey) { const option = document.createElement("option"); option.value = key; option.textContent = getAccountName(key, key); dropdown.appendChild(option); } }); }); } function resetToDefault(key) { const value = balances[key]; balances.account1 += value; balances[key] = 0; saveBalance("account1", balances.account1); saveBalance(key, 0); saveAccountName(key, key === "account2" ? "Account #2" : "Account #3"); } function resetMainToBase() { balances.account1 = baseMainBalance; saveBalance("account1", balances.account1); } function createAccountBox(accountNum, balance, isMain = false) { const key = `account${accountNum}`; const box = document.createElement("div"); Object.assign(box.style, { border: "2px solid #999", padding: "15px 20px", borderRadius: "10px", background: "#333", color: "#fff", minWidth: "300px", flex: "1", position: "relative" }); const inputStyle = ` padding: 6px; height: 32px; border-radius: 5px; border: 1px solid #888; background: #444; color: white; width: 100%; `; const labelStyle = ` display: flex; align-items: center; justify-content: center; text-align: center; padding: 6px; height: 32px; border-radius: 5px; background: #555; color: white; cursor: pointer; user-select: none; font-size: 14px; font-weight: bold; `; const accountName = getAccountName(key, `Account #${accountNum}`); const title = document.createElement("div"); title.id = `title-${key}`; title.style.cssText = "font-size: 22px; font-weight: bold; text-decoration: underline; color: #fff; text-shadow: 1px 1px 2px #000; text-align: center; margin-bottom: 10px;"; title.textContent = accountName; const resetButton = document.createElement("label"); resetButton.textContent = "✕"; resetButton.title = isMain ? "Reset to actual balance from bank" : "Click to set account to default"; Object.assign(resetButton.style, { position: "absolute", top: "5px", left: "5px", background: "#555", color: "white", padding: "4px 8px", borderRadius: "6px", cursor: "pointer", fontWeight: "bold", fontSize: "16px" }); resetButton.onclick = () => isMain ? resetMainToBase() : resetToDefault(key); const details = document.createElement("div"); details.style.textAlign = "center"; details.innerHTML = ` <p><strong style="color:#ccc;">Account Type:</strong> <span style="color:#9f9;">${accountType}</span></p> <p><strong style="color:#ccc;">Current Balance:</strong> <span id="${key}" style="color:#fff;">${formatNP(balance)}</span></p> <hr style="border: 1px solid #888; margin: 12px auto;"> `; const row = document.createElement("div"); Object.assign(row.style, { display: "flex", justifyContent: "space-between", gap: "15px" }); const renameInput = document.createElement("input"); renameInput.placeholder = "Rename..."; renameInput.style = inputStyle; const renameBtn = document.createElement("label"); renameBtn.textContent = "Rename"; renameBtn.style = labelStyle; renameBtn.onclick = () => { const name = renameInput.value.trim(); if (name) { saveAccountName(key, name); renameInput.value = ''; } }; const transferInput = document.createElement("input"); transferInput.placeholder = "Amount"; transferInput.style = inputStyle; const transferDropdown = document.createElement("select"); transferDropdown.style = inputStyle; const transferBtn = document.createElement("label"); transferBtn.textContent = "Transfer NP"; transferBtn.style = labelStyle; transferBtn.onclick = () => { const amount = parseNP(transferInput.value); const toKey = transferDropdown.value; if (amount <= 0 || balances[key] < amount || !(toKey in balances)) { alert("Invalid or insufficient funds"); return; } balances[key] -= amount; balances[toKey] += amount; saveBalance(key, balances[key]); saveBalance(toKey, balances[toKey]); transferInput.value = ""; }; dropdowns.push({ dropdown: transferDropdown, fromKey: key }); const withdrawInput = document.createElement("input"); withdrawInput.placeholder = "Amount"; withdrawInput.style = inputStyle; const withdrawBtn = document.createElement("label"); withdrawBtn.textContent = "Withdraw"; withdrawBtn.style = labelStyle; withdrawBtn.onclick = () => { const amount = parseNP(withdrawInput.value); if (amount <= 0 || balances[key] < amount) { alert("Invalid or insufficient funds"); return; } const form = document.querySelector('form[action="/bank/withdraw_np/"]'); const amountInput = form?.querySelector('input[name="amount"]'); if (!form || !amountInput) { alert("Could not find withdrawal form"); return; } amountInput.value = amount; balances[key] -= amount; saveBalance(key, balances[key]); setTimeout(() => form.submit(), 100); }; const renameCol = document.createElement("div"); renameCol.style.flex = "1"; renameCol.append(renameInput, renameBtn); const transferCol = document.createElement("div"); transferCol.style.flex = "1"; transferCol.append(transferInput, transferDropdown, transferBtn); const withdrawCol = document.createElement("div"); withdrawCol.style.flex = "1"; withdrawCol.append(withdrawInput, withdrawBtn); row.append(renameCol, transferCol, withdrawCol); box.append(resetButton, title, details, row); return box; } function hookDepositForms() { const depositForm = document.querySelector('form[action="/bank/deposit_np/"]:not(.button-group)'); const depositAllForm = document.querySelector('form.button-group[action="/bank/deposit_np/"]'); if (depositForm) { depositForm.addEventListener("submit", () => { const amount = parseNP(depositForm.querySelector('input[name="amount"]')?.value || '0'); if (amount > 0) { balances.account1 += amount; saveBalance("account1", balances.account1); } }); } if (depositAllForm) { const button = depositAllForm.querySelector('button[name="amount"]'); depositAllForm.addEventListener("submit", () => { const amount = parseNP(button?.value || '0'); if (amount > 0) { balances.account1 += amount; saveBalance("account1", balances.account1); } }); } } })();