// ==UserScript==
// @name Neopets - Bank improvements for Beta
// @namespace np
// @version 2020.12.30
// @description Various improvements to shop till and bank, including a bank interest calculator.
// @author x
// @include http://www.neopets.com/market.phtml?type=till
// @include http://www.neopets.com/bank.phtml*
// @grant GM_getValue
// @grant GM_setValue
// @downloadURL https://update.greasyfork.icu/scripts/419172/Neopets%20-%20Bank%20improvements%20for%20Beta.user.js
// @updateURL https://update.greasyfork.icu/scripts/419172/Neopets%20-%20Bank%20improvements%20for%20Beta.meta.js
// ==/UserScript==
/************************************************************************
* Removed @require jQuery.
* This lets us use $(document).ajaxSuccess without needing unsafeWindow.
* As of 2020-12-25, neopets beta is using jQuery v3.4.1;
* the version number can be checked in console with $().jquery
************************************************************************/
if (!GM_getValue) {
GM_getValue = (key, val) => localStorage[key] || val;
GM_setValue = (key, val) => localStorage[key] = val;
}
if (!GM_getValue("config")) {
let config = {
deposit : 0,
withdraw : 0,
calc_visible : true
};
GM_setValue("config", config);
}
let config = GM_getValue("config");
//-----------------------------------------------------------------------
const url = location.href;
const isBeta = $("[class^='nav-pet-menu-icon']").length > 0;
if (url.includes("bank") && isBeta) {
const np = $("#npanchor").text().replace(/,/g, "");
const bank = $("#txtCurrentBalance1").text().replace(/[^\d]/g, "");
$("#frmDeposit :input[name='amount']").val(config.deposit || np);
$("#frmWithdraw :input[name='amount']").val(config.withdraw || bank);
$("#frmUpgradeAccount :input[name='amount']").val(np);
$("#frmWithdraw").on("submit", function () {
const amtWithdraw = $("#frmWithdraw :input[name='amount']").val();
if (amtWithdraw !== 0 && !amtWithdraw.match(/[^\d]/g)) {
config.withdraw = amtWithdraw;
GM_setValue("config", config);
}
});
$("h2:contains('Interest')").parent().parent().after(`
`);
$("#hide-calculator").on("click", function () {
const $hideArea = $(this).next();
if ($hideArea.is(":visible")) {
$hideArea.hide(200);
config.calc_visible = false;
} else {
$hideArea.show(200);
config.calc_visible = true;
}
GM_setValue("config", config);
});
/********************************************************
* --- Calculator ---
*
* You can type in "k", "m", and "b" to instantly insert
* 3, 6 and 9 zeroes respectively.
*
* Example: type 22.5k to instantly input 22500,
* 35.55m to instantly input 35550000.
*
* Since the maximum amount of NP in the bank right now
* is 2,147,483,647 the feature above will not convert
* bank balance amounts above this limit.
********************************************************/
// Initial values
const interestRate = 0.01 * parseFloat($("#txtAnnualInterestRate").find("b").html());
$("#interest-account-type").val(interestRate.toString());
$("#acc-balance").val(bank);
$("#daily-interest").val(Math.ceil(bank * interestRate / 365));
const validateInput = input => !input.match(/[^\d]+/g);
const validateLength = (input, length) => input.length <= length;
$("#interest-account-type").on("change", function() {
const newInterestRate = parseFloat(this.value);
const bankBal = $("#acc-balance").val();
$("#daily-interest").val(Math.ceil(bankBal * newInterestRate / 365));
});
$("#boon-enabled").on("change", function (e) {
const checked = e.target.checked;
const interestRate = parseFloat($("#interest-account-type").val());
const bankBal = $("#acc-balance").val();
const newDailyInterest = checked ?
Math.ceil(bankBal * (interestRate + 0.03) / 365) :
Math.ceil(bankBal * interestRate / 365);
$("#daily-interest").val(newDailyInterest);
});
$("#daily-interest").on("input", function (e) {
const key = e.originalEvent.data;
let newVal;
if (key === "k") {
newVal = (parseFloat(this.value) * 1000).toString();
this.value = validateLength(newVal, 6) ? newVal : this.value;
}
const daily = this.value;
if (validateInput(daily)) {
const newBal = daily === "" ? "" : Math.floor(daily * 365 / interestRate);
$("#acc-balance").val(newBal);
}
});
$("#acc-balance").on("input", function (e) {
const key = e.originalEvent.data;
let newVal;
if (key === "k") {
newVal = (parseFloat(this.value) * 1000).toString();
this.value = validateLength(newVal, 10) ? newVal : this.value;
}
if (key === "m") {
newVal = (parseFloat(this.value) * 1000000).toString();
this.value = validateLength(newVal, 10) ? newVal : this.value;
}
if (key === "b") {
newVal = (parseFloat(this.value) * 1000000000).toString();
this.value = validateLength(newVal, 10) ? newVal : this.value;
}
const bal = this.value;
if (validateInput(bal)) {
const newDaily = bal === "" ? "" : Math.ceil(bal * interestRate / 365);
$("#daily-interest").val(newDaily);
}
});
/*
Daily Interest: 33,909 NP
*/
// prevent input while xhr is sending
$(document).ajaxStart(function () {
$("#interest-account-type").prop("disabled", true);
$("#boon-enabled").prop("disabled", true);
$("#daily-interest").prop("disabled", true);
$("#acc-balance").prop("disabled", true);
});
// Auto-update the calculator values after a deposit/withdrawal or collecting interest.
$(document).ajaxSuccess(function (event, xhr, settings) {
// for collecting interest, the xhr completes before the bank balance is updated,
// so we read the response data instead
try {
const response = JSON.parse(xhr.responseText);
// check that this xhr is related to bank updating
if (response["final_balance"] || response["new_balance"]) {
const updatedBal = parseInt(response["final_balance"]) || response["new_balance"];
const updatedInterestRate = 0.01 * parseFloat($("#txtAnnualInterestRate").find("b").html());
const updatedDaily = Math.ceil(updatedBal * updatedInterestRate / 365);
$("#daily-interest").val(updatedDaily);
$("#acc-balance").val(updatedBal);
}
} catch (e) {
// response probably isn't in JSON format
// ie - not related to bank xhr
}
// re-enable calculator
$("#interest-account-type").prop("disabled", false);
$("#boon-enabled").prop("disabled", false);
$("#daily-interest").prop("disabled", false);
$("#acc-balance").prop("disabled", false);
});
}
/*
if (url.includes("till")) {
const till = $("p:contains('You currently have')").find("b").text().replace(/[^\d]/g, "");
if (till !== "0") {
$("form[action='process_market.phtml']").find("input[name='amount']").val(till);
}
}
*/