
ScriptInfo
FILE LOCATION: My Personal Repo (pending to the 1-click Installation next week)
ABSTRACT: ScriptInfo helps you troubleshoot script errors or to get help with odd script behavior. ScriptInfo will give you a report of installed scripts and their versions, as well as what line each script starts on. It will also connect the line number of a given sandbox error to the script that contains that line. Using ScriptInfo you can immediately tell what version of a script you are using, as well as the particular line number where you might be getting an error.
Introduction
Scripters try to write good code to help Roll20 users, but from time to time mistakes are made. Not all edge cases -- or, worse, use cases -- are detected, or a bug escaped our notice during testing and lurks in the code, waiting to spring. Finding that bug, even when the sandbox reports a line number where the error happened, can sometimes be tricky. Here's why...
When your game's sandbox spins up, all of the scripts you have installed are collated into a single, long file of javascript code. A script might be 1000 lines of code, but if it follows another script with 2000 lines of code, it will actually span lines 2001-3000. It isn't always feasible, practical, or even possible to manually count lines of code until we discover which line the reported error number represents. This is where ScriptInfo can help.
With ScriptInfo, you can run a different report to learn that an error on line X represents line Y of script Z. For a simple example, imagine you have 10 scripts installed (ScriptA, ScriptB, ScriptC, etc.), each consisting of 100 lines of code. You get an error that lists line #304 as where the error occurred. ScriptInfo would tell you that line #304 represents line 4 of ScriptD
Limitations
ScriptInfo interrogates a particular object in javascript that script authors must opt-in to use. If a script does not report to this object, ScriptInfo won't be able to get the information it needs, though it will still be able to tell you more general information (such as that an error occurred x-lines after a given script and/or y-lines before a given script). Many of the more widely used scripts available in the one-click do make use of this centralized reporting object, including TokenMod (as well as the rest of The Arcane Scriptomancer's scripts: RecursiveTables, GroupInit, etc.), ScriptCards, Reporter, Supernotes, Spawn, SmartAoE, and all of the metascripts.
Syntax and Usage
To get the report of all scripts, use the command:
!scriptinfo
To get a report connecting a line number to the particular script where it exists, use the same scriptinfo handle, followed by the line number you wish to know about:
!scriptinfo 2549
You can supply multiple lines you're interested in by separating them with a space:
!scriptinfo 180 2021 15024
For Scripters: Making Your Script Work with this Object
1.
var API_Meta = API_Meta || {};
API_Meta.SCRIPTNAME = { offset: Number.MAX_SAFE_INTEGER, lineCount: -1 };
{ try { throw new Error(''); } catch (e) { API_Meta.SCRIPTNAME.offset = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - (13)); } }
What's Happening
That bit of code establishes the API_Meta object if necessary, but leaves it as is if the object has already been initialized by another script.
Note: This is probably the only time, and the only sort of usage, where you would want to use var as your variable declaration syntax. You're better off using either let or const every other time you instantiate a variable, however for this particular usage, we specifically need the hoisting that var provides, as well as the redefinability.
After making sure API_Meta is available, the code establishes two properties (offset and lineCount) with dummy data.
Finally, in a try/catch block, it intentionally throws an error so that the error stack can be parsed for the line number. Since we know the line on which we threw the error, we can use math to understand our script's overall starting line (see the steps, below, for more information).
2.
Replace every instance of SCRIPTNAME with your script's unique name.
3.
Somewhere in your code, inject your script version into the the API_Meta object:
API_Meta.SCRIPTNAME.version = '1.0.0';
4.
Fix your offset math. At the end of the catch block in the above example, 13 is being subtracted as a part of the offset equation. This number represents the row where we threw the error. Change this number to match the line of the error; if you paste these lines into your code so that the error occurs on line 8, you'd change that 13 to an 8.
5.
Paste this code as the last line in your code, after your script's final closure:
{ try { throw new Error(''); } catch (e) { API_Meta.SCRIPTNAME.lineCount = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - API_Meta.SCRIPTNAME.offset); } }
What's Happening
As before, we throw an error and catch the return so that we can parse the current line. This time, we subtract the original offset we derived so that we know our lineCount.
Note: Be sure to include an empty line at the end of your code. There is a bug in the sandbox where if your script does not have a trailing empty line your script can cause those installed after it in the sandbox to fail.
6.
As in #2, replace all instances of SCRIPTNAME with your script's unique name.