Various bugfix/cleanup (#489)

* parseCommands no longer removes excess whitespace (it was unneeded and also had a bug in it relating to commands that ended in a quote mark)
* more documentation and some variable renaming
* Fix script editor focus bug on navigating to the editor from sidebar
* Fix initialization for lastNodeReset and lastAugReset
This commit is contained in:
Snarling 2023-04-24 15:48:49 -04:00 committed by GitHub
parent 9004b12256
commit 62adaf3006
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 26 deletions

@ -1792,8 +1792,11 @@ function createDeprecatedProperty(
Terminal.warn(`Deprecated property ${propName} accessed from ns.${ctx.functionPath} return value.`); Terminal.warn(`Deprecated property ${propName} accessed from ns.${ctx.functionPath} return value.`);
Terminal.warn(`This is no longer supported usage and will be removed in a later version.`); Terminal.warn(`This is no longer supported usage and will be removed in a later version.`);
Terminal.warn(message); Terminal.warn(message);
Terminal.info(`Note that this message can also appear if you iterate through the object's values.`);
Terminal.info(`This message will only be shown once per game session for each deprecated property accessed.`);
} }
return value; return value;
}, },
enumerable: true,
}); });
} }

@ -669,8 +669,13 @@ function evaluateVersionCompatibility(ver: string | number): void {
if (anyPlayer.hashManager?.upgrades) { if (anyPlayer.hashManager?.upgrades) {
anyPlayer.hashManager.upgrades["Company Favor"] ??= 0; anyPlayer.hashManager.upgrades["Company Favor"] ??= 0;
} }
anyPlayer.lastAugReset ??= anyPlayer.lastUpdate - anyPlayer.playtimeSinceLastAug; if (!anyPlayer.lastAugReset || anyPlayer.lastAugReset === -1) {
anyPlayer.lastNodeReset ??= anyPlayer.lastUpdate - anyPlayer.playtimeSinceLastBitnode; anyPlayer.lastAugReset = anyPlayer.lastUpdate - anyPlayer.playtimeSinceLastAug;
}
if (!anyPlayer.lastNodeRest || anyPlayer.lastNodeReset === -1) {
anyPlayer.lastNodeReset = anyPlayer.lastUpdate - anyPlayer.playtimeSinceLastBitnode;
}
const newDirectory = resolveDirectory("v2.3FileChanges/") as Directory; const newDirectory = resolveDirectory("v2.3FileChanges/") as Directory;
for (const server of GetAllServers()) { for (const server of GetAllServers()) {
let invalidScriptCount = 0; let invalidScriptCount = 0;

@ -131,12 +131,13 @@ export function Root(props: IProps): React.ReactElement {
GetServer(openScripts[i].hostname) === null && openScripts.splice(i, 1); GetServer(openScripts[i].hostname) === null && openScripts.splice(i, 1);
} }
if (currentScript && GetServer(currentScript.hostname) === null) { if (currentScript && GetServer(currentScript.hostname) === null) {
currentScript = openScripts[0]; currentScript = openScripts[0] ?? null;
if (currentScript === undefined) currentScript = null;
} }
useEffect(() => { useEffect(() => {
if (currentScript !== null) { if (currentScript !== null) {
const tabIndex = currentTabIndex();
if (typeof tabIndex === "number") onTabClick(tabIndex);
updateRAM(currentScript.code); updateRAM(currentScript.code);
} }
}, []); }, []);
@ -481,13 +482,7 @@ export function Root(props: IProps): React.ReactElement {
} }
function currentTabIndex(): number | undefined { function currentTabIndex(): number | undefined {
if (currentScript !== null) { if (currentScript) return openScripts.findIndex((openScript) => currentScript === openScript);
return openScripts.findIndex(
(script) =>
currentScript !== null && script.path === currentScript.path && script.hostname === currentScript.hostname,
);
}
return undefined; return undefined;
} }

@ -12,25 +12,27 @@ function parseArg(arg: string): string | number | boolean {
return arg; return arg;
} }
/** Split a commands string (what is typed into the terminal) into multiple commands */ /** split a commands string into a commands array */
export function splitCommands(commandString: string): string[] { export function splitCommands(commandsText: string): string[] {
const commandArray = commandString.match(/(?:'[^']*'|"[^"]*"|[^;"])*/g); // regex to match each entire command separately, without the semicolon included.
if (!commandArray) return []; const commandRegex = /(?:'[^']*'|"[^"]*"|[^;])*/g;
return commandArray.map((command) => command.trim()); const commands = commandsText.match(commandRegex);
if (!commands) return [];
return commands.map((command) => command.trim());
} }
/** Split commands string while also applying aliases */ /** parse a commands string, including alias substitution, into a commands array */
export function parseCommands(commands: string): string[] { export function parseCommands(commandsText: string): string[] {
// Remove any unquoted whitespace longer than length 1 // Split the commands, apply aliases once, then split again and filter out empty commands.
commands = commands.replace(/(?:"[^"]*"|'[^']*'|\s{2,})+?/g, (match) => (match.startsWith(" ") ? " " : match)); const commands = splitCommands(commandsText).map(substituteAliases).flatMap(splitCommands).filter(Boolean);
// Split the commands, apply aliases once, then split again and filter out empty strings. return commands;
const commandsArr = splitCommands(commands).map(substituteAliases).flatMap(splitCommands).filter(Boolean);
return commandsArr;
} }
/** get a commandArgs array from a single command string */
export function parseCommand(command: string): (string | number | boolean)[] { export function parseCommand(command: string): (string | number | boolean)[] {
const commandArgs = command.match(/(?:("[^"]*"|'[^']*'|[^\s]+))+?/g); // Match every command arg in a given command string
const argDetection = /(?:("[^"]*"|'[^']*'|[^\s]+))/g;
const commandArgs = command.match(argDetection);
if (!commandArgs) return []; if (!commandArgs) return [];
const argsToReturn = commandArgs.map(parseArg); return commandArgs.map(parseArg);
return argsToReturn;
} }