fix training status script to work for users without premium

This commit is contained in:
Holly McFarland 2026-05-23 16:45:59 -04:00
parent 0cea3d1481
commit ec025c6c79
2 changed files with 98 additions and 98 deletions

View File

@ -1,30 +1,30 @@
# monorail's neopets userscripts # monorail's neopets userscripts
Quality of life userscripts for neopets.com Quality of life userscripts for neopets.com
To use any of these scripts, first ensure you have Tampermonkey installed in your browser. To use any of these scripts, first ensure you have Tampermonkey installed in your browser.
- [Tampermonkey for Firefox](https://addons.mozilla.org/en-CA/firefox/addon/tampermonkey/) - [Tampermonkey for Firefox](https://addons.mozilla.org/en-CA/firefox/addon/tampermonkey/)
- Links for other browsers available from the [Tampermonkey home page](https://www.tampermonkey.net/) - Links for other browsers available from the [Tampermonkey home page](https://www.tampermonkey.net/)
Once you have Tampermonkey, click the name of the script you want to install. A confirmation window will appear that allows you to inspect the source code and pages that it will run on, if you so desire. Once you're happy, click "install", and the scripts will start working for you the next time you load the relevant Neopets page. Once you have Tampermonkey, click the name of the script you want to install. A confirmation window will appear that allows you to inspect the source code and pages that it will run on, if you so desire. Once you're happy, click "install", and the scripts will start working for you the next time you load the relevant Neopets page.
### Safety notes: ### Safety notes:
All of my scripts that have been approved by the /r/neopets Discord mod team as safe and fair are marked with a ✅ after their name. If a previous version has been approved, a link to that one will be provided separately. All of my scripts that have been approved by the /r/neopets Discord mod team as safe and fair are marked with a ✅ after their name. If a previous version has been approved, a link to that one will be provided separately.
**No** userscripts, not mine or anyone else's, have been officially approved by TNT. Make peace with that before installing any script to use on Neopets. **No** userscripts, not mine or anyone else's, have been officially approved by TNT. Make peace with that before installing any script to use on Neopets.
---- ----
## [Move Training Pets To Top](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/branch/main/scripts/move-training-pets-to-top.user.js) ✅ ## [Move Training Pets To Top](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/branch/main/scripts/move-training-pets-to-top.user.js) ([Approved version](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/commit/91e72b22d2d508240da43239d24f4ee32d3c3931/scripts/move-training-pets-to-top.user.js) )
On the status page for the Swashbuckling Academy, Mystery Island Training School, or Secret Ninja Training School\*, move any pets enrolled in a course (whether they're waiting for payment, actively training, or waiting for "course complete" confirmation) to the top of the list. Useful if your battledome pet happens to get sorted near the bottom by default, requiring you to scroll. On the status page for the Swashbuckling Academy, Mystery Island Training School, or Secret Ninja Training School\*, move any pets enrolled in a course (whether they're waiting for payment, actively training, or waiting for "course complete" confirmation) to the top of the list. Useful if your battledome pet happens to get sorted near the bottom by default, requiring you to scroll.
\*I haven't tested this script at the Secret Ninja Training School because I don't have a pet even *close* to level 250. I have reason to believe it should work there, but I would appreciate confirmation from anyone who's able to test it out. \*I haven't tested this script at the Secret Ninja Training School because I don't have a pet even *close* to level 250. I have reason to believe it should work there, but I would appreciate confirmation from anyone who's able to test it out.
## [Stock Highlighter](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/branch/main/scripts/stock-highlighter.user.js) ([Approved version](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/commit/91e72b22d2d508240da43239d24f4ee32d3c3931/scripts/stock-highlighter.user.js) ✅) ## [Stock Highlighter](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/branch/main/scripts/stock-highlighter.user.js) ([Approved version](https://git.hollymcfarland.com/monorail/NeopetsUserscripts/raw/commit/91e72b22d2d508240da43239d24f4ee32d3c3931/scripts/stock-highlighter.user.js) ✅)
When checking your stock portfolio, automatically sort all stocks by current value and highlight any that are over your sell price. The sell price defaults to 60 neopoints but can be configured on the page itself. When viewing lists of stocks to purchase, sort them by current value, deemphasize those that are too cheap to buy, and highlight those at exactly the buy price. When checking your stock portfolio, automatically sort all stocks by current value and highlight any that are over your sell price. The sell price defaults to 60 neopoints but can be configured on the page itself. When viewing lists of stocks to purchase, sort them by current value, deemphasize those that are too cheap to buy, and highlight those at exactly the buy price.
Custom sell prices and a checkbox for whether or not the stock boon is enabled are handled in real time and are automatically saved. Custom sell prices and a checkbox for whether or not the stock boon is enabled are handled in real time and are automatically saved.

View File

@ -1,70 +1,70 @@
// ==UserScript== // ==UserScript==
// @name Move Training Pets To Top // @name Move Training Pets To Top
// @namespace https://hollymcfarland.com // @namespace https://hollymcfarland.com
// @version 1.0 // @version 1.1
// @description At the three battledome training areas in Neopia, move pets currently in a course or waiting for input to the top of the list // @description At the three battledome training areas in Neopia, move pets currently in a course or waiting for input to the top of the list
// @author monorail // @author monorail
// @match https://www.neopets.com/pirates/academy.phtml?type=status // @match https://www.neopets.com/pirates/academy.phtml?type=status
// @match https://www.neopets.com/island/training.phtml?type=status // @match https://www.neopets.com/island/training.phtml?type=status
// @match https://www.neopets.com/island/fight_training.phtml?type=status // @match https://www.neopets.com/island/fight_training.phtml?type=status
// @icon https://www.google.com/s2/favicons?sz=64&domain=neopets.com // @icon https://www.google.com/s2/favicons?sz=64&domain=neopets.com
// @grant none // @grant none
// ==/UserScript== // ==/UserScript==
/* /*
Note that this has not been tested in the Secret Ninja Training School, simply Note that this has not been tested in the Secret Ninja Training School, simply
because I don't have any pets even close to level 250. But the DOM looks the because I don't have any pets even close to level 250. But the DOM looks the
same at the Swashbuckling Academy and the Mystery Island Training School so, same at the Swashbuckling Academy and the Mystery Island Training School so,
I assume it'll work there too? If someone let me know I'd appreciate it haha I assume it'll work there too? If someone let me know I'd appreciate it haha
*/ */
(function() { (function() {
'use strict'; 'use strict';
function getPairs(iter) { function getPairs(iter) {
/* /*
Given an iterable (something that can be converted to an array, anyway), return Given an iterable (something that can be converted to an array, anyway), return
an array of two-length arrays containing each element once, in the same order an array of two-length arrays containing each element once, in the same order
e.g. getPairs([1, 2, 3, 4, 5, 6]) => [[1, 2], [3, 4], [5, 6]] e.g. getPairs([1, 2, 3, 4, 5, 6]) => [[1, 2], [3, 4], [5, 6]]
*/ */
// The function getting mapped here behaves differently depending on the parity // The function getting mapped here behaves differently depending on the parity
// of the index. // of the index.
// Odd index => Empty array // Odd index => Empty array
// Even index => Array of array(!!) of the element at that index and the one after it // Even index => Array of array(!!) of the element at that index and the one after it
// Then because it's getting _flat_mapped, the whole thing is flattened by one level. // Then because it's getting _flat_mapped, the whole thing is flattened by one level.
// Empty arrays disappear and the arrays of arrays become just two-length arrays // Empty arrays disappear and the arrays of arrays become just two-length arrays
// https://stackoverflow.com/a/57851980/2114129 // https://stackoverflow.com/a/57851980/2114129
return [...iter].flatMap((_, i, a) => i % 2 ? [] : [a.slice(i, i + 2)]); return [...iter].flatMap((_, i, a) => i % 2 ? [] : [a.slice(i, i + 2)]);
} }
// Table that shows each pet // Table that shows each pet
const statusTable = document.querySelector(".content > p:nth-child(6) > table:nth-child(1) > tbody:nth-child(1)"); const statusTable = document.querySelector(".content tbody");
for (let [header, pet] of getPairs(statusTable.children)) { for (let [header, pet] of getPairs(statusTable.children)) {
// Each "pet" here refers to a <tr> element representing that pet's status. // Each "pet" here refers to a <tr> element representing that pet's status.
// Every pet has at exactly two <td> elements as children. The first displays // Every pet has at exactly two <td> elements as children. The first displays
// their image and stats and the second shows any applicable status (i.e. the // their image and stats and the second shows any applicable status (i.e. the
// pet is waiting for payment, currently training, or waiting for "course // pet is waiting for payment, currently training, or waiting for "course
// complete" confirmation). This second element is empty for pets with no status // complete" confirmation). This second element is empty for pets with no status
// at all. // at all.
// Any pet that has any kind of status at all should be moved to the top, and // Any pet that has any kind of status at all should be moved to the top, and
// ideally we'd also like to otherwise preserve the order. To accomplish this, // ideally we'd also like to otherwise preserve the order. To accomplish this,
// what we're actually going to do is take every pet that _doesn't_ have a // what we're actually going to do is take every pet that _doesn't_ have a
// status (i.e. the second <td> child is empty) and move it to the bottom. We // status (i.e. the second <td> child is empty) and move it to the bottom. We
// do this on a copy of the list of children so we don't hit any pet more than // do this on a copy of the list of children so we don't hit any pet more than
// once or skip any, and it's all done in the correct order. // once or skip any, and it's all done in the correct order.
// To move an element to the bottom, we just have to append it as a child to // To move an element to the bottom, we just have to append it as a child to
// the element it's already a child of. Because Neopets uses tables for layout // the element it's already a child of. Because Neopets uses tables for layout
// in current year, the header above each pet is actually a completely separate // in current year, the header above each pet is actually a completely separate
// element, so those are handled at the same time. // element, so those are handled at the same time.
if (pet.lastChild.childElementCount === 0) { if (pet.lastChild.childElementCount === 0) {
statusTable.appendChild(header); statusTable.appendChild(header);
statusTable.appendChild(pet); statusTable.appendChild(pet);
} }
} }
})(); })();