Skip to content

Commit

Permalink
Merge pull request #408 from rraumberger/main
Browse files Browse the repository at this point in the history
Adjust tail window size and position
  • Loading branch information
alainbryden authored Oct 26, 2024
2 parents 9f8ed23 + 341ad29 commit 25ffeda
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 33 deletions.
4 changes: 2 additions & 2 deletions Tasks/contractor.js.solver.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { jsonReviver } from '../helpers.js'
import { jsonReviver, tail } from '../helpers.js'
const fUnsolvedContracts = '/Temp/unsolved-contracts.txt'; // A global, persistent array of contracts we couldn't solve, so we don't repeatedly log about them.

let heartbeat = null;
Expand Down Expand Up @@ -84,7 +84,7 @@ export async function main(ns) {
if (quietSolve) {
const message = `Done solving ${contractsDb.length}. ${contractsDb.length - failureCount} succeeded, and ${failureCount} failed. See tail logs for errors.`
if (failureCount > 0)
ns.tail();
tail(ns);
ns.toast(message, 'success');
ns.tprint(message);
}
Expand Down
6 changes: 3 additions & 3 deletions autopilot.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
log, getFilePath, getConfiguration, instanceCount, getNsDataThroughFile, runCommand, waitForProcessToComplete,
getActiveSourceFiles, tryGetBitNodeMultipliers, getStocksValue, unEscapeArrayArgs,
formatMoney, formatDuration, getErrorInfo
formatMoney, formatDuration, getErrorInfo, tail
} from './helpers.js'

let options; // The options used at construction time
Expand Down Expand Up @@ -235,7 +235,7 @@ async function checkOnDaedalusStatus(ns, player, stocksValue) {
// See if we've already joined this faction
if (player.factions.includes("Daedalus")) {
alreadyJoinedDaedalus = true;
// If we previously took any action to "rush" Daedalus, keep the momentum going by restarting work-for-factions.js
// If we previously took any action to "rush" Daedalus, keep the momentum going by restarting work-for-factions.js
// so that it immediately re-assesses priorities and sees there's a new priority faction to earn reputation for.
if (prioritizeHackForDaedalus || reservingMoneyForDaedalus) {
let reason;
Expand Down Expand Up @@ -863,7 +863,7 @@ function shouldWeKeepRunning(ns) {
/** Helper to launch a script and log whether if it succeeded or failed
* @param {NS} ns */
function launchScriptHelper(ns, baseScriptName, args = [], convertFileName = true) {
ns.tail(); // If we're going to be launching scripts, show our tail window so that we can easily be killed if the user wants to interrupt.
tail(ns); // If we're going to be launching scripts, show our tail window so that we can easily be killed if the user wants to interrupt.
let pid, err;
try { pid = ns.run(convertFileName ? getFilePath(baseScriptName) : baseScriptName, 1, ...args); }
catch (e) { err = e; }
Expand Down
22 changes: 11 additions & 11 deletions casino.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
log, getConfiguration, getFilePath, waitForProcessToComplete,
runCommand, getNsDataThroughFile, getActiveSourceFiles, getErrorInfo
runCommand, getNsDataThroughFile, getActiveSourceFiles, getErrorInfo, tail
} from './helpers.js'

// Note to self: This script doesn't use ram-dodging in the inner loop, because we want to
Expand Down Expand Up @@ -37,7 +37,7 @@ export async function main(ns) {
const saveSleepTime = options['save-sleep-time'];
verbose = options['enable-logging'];
if (verbose)
ns.tail()
tail(ns)
else
ns.disableLog("ALL");

Expand All @@ -48,7 +48,7 @@ export async function main(ns) {
* @param {silent} (default false) Set to true to suppress the warning popup if throwError is false and something has focus.
* @returns {Promise<boolean>} false if focus was not stolen, true if it was and `throwErrorIfNot` is false. */
async function checkForStolenFocus(throwError = true, retries = 0, silent = false) {
// See if we are on the "focus" (work/study/training) screen
// See if we are on the "focus" (work/study/training) screen
const btnUnfocus = await tryfindElement(ns, "//button[text()='Do something else simultaneously']");
if (!btnUnfocus) return false; // All good, we aren't focus-working on anything
let baseMessage = "It looks like something stole focus while casino.js was trying to automate the casino.";
Expand All @@ -57,7 +57,7 @@ export async function main(ns) {
// Otherwise, log a warning, and return true (focus was stolen)
log(ns, (silent ? `INFO` : `WARNING`) + `: ${baseMessage}\nTrying to un-focus it so we can keep going...`, false, (silent ? undefined : `WARNING`));
await click(ns, btnUnfocus); // Click the button that should let us take back focus and return to the casino
// Now we should confirm that we're no longer doing focus work (that the click above worked) by recursing.
// Now we should confirm that we're no longer doing focus work (that the click above worked) by recursing.
retries--; // Decrement "retries" each time we discover we're still on the focus screen.
return await checkStillAtCasino(retries <= 0, retries); // If out of retries, throw error on next failure
}
Expand All @@ -72,7 +72,7 @@ export async function main(ns) {
// Check whether we're still on the casino page
let stillAtCasino = await tryfindElement(ns, "//h4[text()='Iker Molina Casino']", silent ? 3 : 10);
if (stillAtCasino) return true; // All seems good, nothing is stealing focus
// If we're not still at the casino, see if we are on the "focus" (work/study/training) screen
// If we're not still at the casino, see if we are on the "focus" (work/study/training) screen
const focusWasStolen = await checkForStolenFocus(throwError, silent ? 3 : 1);
// If we aren't meant to log a warning, or focus was stolen (which has now been deal with) we can return
if (focusWasStolen || silent)
Expand Down Expand Up @@ -204,7 +204,7 @@ export async function main(ns) {
} catch (err) {
// The first 5 errors that occur, we will start over and retry
if (++priorAttempts < 5) {
ns.tail(); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
tail(ns); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
verbose = true; // Switch on verbose logs
log(ns, `WARNING: casino.js Caught (and suppressed) an unexpected error while navigating to blackjack. ` +
`Error was:\n${getErrorInfo(err)}\nWill try again (attempt ${priorAttempts} of 5)...`, false, 'warning');
Expand Down Expand Up @@ -273,7 +273,7 @@ export async function main(ns) {
'Cannot find the Hit/Stay buttons, but there is no game-over text (win/lose/tie) either.';
if (startGameRetries++ >= 5) // Retry up to 5 times before giving up and crashing out.
throw new Error(errMessage + ` Gave up after 5 retry attempts.\n${supportMsg}`);
ns.tail(); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
tail(ns); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
verbose = true; // Switch on verbose logs
log(ns, `WARNING: ${errMessage} Trying again...`, false, 'warning');
continue; // Back to 4.1 (Place bet, and try to start a new game)
Expand Down Expand Up @@ -311,14 +311,14 @@ export async function main(ns) {
const errMessage = `an unexpected error in the middle of a game of blackjack:\n${getErrorInfo(err)}`;
if (midGameRetries++ >= 5) // Retry up to 5 times before giving up and crashing out.
throw new Error(`After ${priorAttempts} attempts, casino.js continues to catch ${errMessage}`);
ns.tail(); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
tail(ns); // Since we're having difficulty, pop open a tail window so the user is aware and can monitor.
verbose = true; // Switch on verbose logs
log(ns, `WARNING: casino.js Caught (and suppressed) ${errMessage}\n` +
`Will try again (attempt ${midGameRetries} of 5)...`, false, 'warning');
}
} // Once the above loop is over winLoseTie is guaranteed be set to some non-null value

// Step 4.6: Take action depending on whether we won, lost, or tied
// Step 4.6: Take action depending on whether we won, lost, or tied
switch (winLoseTie) {
case "tie": // Nothing gained or lost, we can immediately start a new game.
continue;
Expand All @@ -340,12 +340,12 @@ export async function main(ns) {
}
}
catch (err) {
ns.tail(); // Display the tail log if anything goes wrong so the user can review the logs
tail(ns); // Display the tail log if anything goes wrong so the user can review the logs
log(ns, `ERROR: casino.js Caught a fatal error while playing blackjack:\n${getErrorInfo(err)}\n${supportMsg}`, true, 'error');
}
}

/** This helper function will help us detect if we lost, won or tied.
/** This helper function will help us detect if we lost, won or tied.
* @param {NS} ns
* @returns {Promise<null|"win"|"lose"|"tie">} null indicates no outcome could be detected (game either not over or still in progres) */
async function getWinLoseOrTie(ns) {
Expand Down
6 changes: 3 additions & 3 deletions crime.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { instanceCount, getNsDataThroughFile, formatDuration, formatNumberShort } from './helpers.js'
import { instanceCount, getNsDataThroughFile, formatDuration, formatNumberShort, tail } from './helpers.js'
import { crimeForKillsKarmaStats } from './work-for-factions.js'

const crimes = ["shoplift", "rob store", "mug", "larceny", "deal drugs", "bond forgery", "traffick arms", "homicide", "grand theft auto", "kidnap", "assassinate", "heist"]
Expand All @@ -10,7 +10,7 @@ export async function main(ns) {
if (await instanceCount(ns) > 1) return; // Prevent multiple instances of this script from being started, even with different args.
ns.disableLog('sleep');
let crime = ns.args.length == 0 ? undefined : ns.args.join(" "); // Need to join in case the crime has a space in it - it will be treated as two args
ns.tail();
tail(ns);
if (!crime || ns.args.includes(argFastCrimesOnly)) // More sophisticated auto-scaling crime logic
await crimeForKillsKarmaStats(ns, 0, 0, Number.MAX_SAFE_INTEGER, ns.args.includes(argFastCrimesOnly));
else // Simple crime loop for the specified crime
Expand All @@ -30,7 +30,7 @@ async function legacyAutoCrime(ns, crime = "mug") {
ns.tprint("User have been busy for too long. auto-crime.js exiting...");
return;
}
ns.tail(); // Force a tail window open when auto-criming, or else it's very difficult to stop if it was accidentally closed.
tail(ns); // Force a tail window open when auto-criming, or else it's very difficult to stop if it was accidentally closed.
let wait = 10 + (await getNsDataThroughFile(ns, 'ns.singularity.commitCrime(ns.args[0])', null, [crime]));
ns.print(`Karma: ${formatNumberShort(ns.heart.break())} Committing crime \"${crime}\" and sleeping for ${formatDuration(wait)}...`);
await ns.sleep(wait);
Expand Down
8 changes: 4 additions & 4 deletions go.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* - Insight (alainbryden)
*/

import { getConfiguration, instanceCount, log, getErrorInfo, getActiveSourceFiles, getNsDataThroughFile } from "./helpers";
import { getConfiguration, instanceCount, log, getErrorInfo, getActiveSourceFiles, getNsDataThroughFile, tail } from "./helpers";

const argsSchema = [
['cheats', true], // (Now true by default - but still an option for backwards compatibility) This is only possible if you have BN14.2
Expand All @@ -26,7 +26,7 @@ export function autocomplete(data, args) {
}

/** Main script entrypoint.
* Note that to protect against "shared global memory", the entire script is wrapped in the body of the main function.
* Note that to protect against "shared global memory", the entire script is wrapped in the body of the main function.
* @param {NS} ns */
export async function main(ns) {
let cheats = false;
Expand Down Expand Up @@ -97,7 +97,7 @@ export async function main(ns) {
const sourceFiles = await getActiveSourceFiles(ns, true);
// Enable cheats if we have SF14.2 or higher (unless the user disabled cheats).
cheats = !runOptions['disable-cheats'] && (sourceFiles[14] ?? 0) >= 2;
if (!silent) { ns.tail() }
if (!silent) { tail(ns); }

ns.disableLog("go.makeMove")

Expand All @@ -110,7 +110,7 @@ export async function main(ns) {
catch (err) {
log(ns, `WARNING: go.js Caught (and suppressed) an unexpected error:\n${getErrorInfo(err)}`, false, 'warning');
log(ns, `INFO: Will sleep for 10 seconds than try playing again.`, false);
ns.tail();
tail(ns);
await ns.sleep(10 * 1000);
}
}
Expand Down
11 changes: 11 additions & 0 deletions helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -802,3 +802,14 @@ export function unEscapeArrayArgs(args) {
const escapeChars = ['"', "'", "`"];
return args.map(arg => escapeChars.some(c => arg.startsWith(c) && arg.endsWith(c)) ? arg.slice(1, -1) : arg);
}

/**
* Custom tail function which also applies default resizes and tail window placement.
* This algorithm is not perfect but for the most part should not generate overlaps of the window's title bar.
* @param {NS} ns The nestcript instance passed to your script's main entry point
*/
export function tail(ns) {
ns.tail();
ns.resizeTail(ns.ui.windowSize()[0] * 0.75, ns.ui.windowSize()[1] * 0.25, ns.pid);
ns.moveTail(250, (ns.pid % 13) * 35, ns.pid);
}
5 changes: 3 additions & 2 deletions stanek.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
log, disableLogs, getFilePath, getConfiguration, formatNumberShort, formatRam,
getNsDataThroughFile, waitForProcessToComplete, getActiveSourceFiles, instanceCount, unEscapeArrayArgs
getNsDataThroughFile, waitForProcessToComplete, getActiveSourceFiles, instanceCount, unEscapeArrayArgs,
tail
} from './helpers.js'

// Default sripts called at startup and shutdown of stanek
Expand Down Expand Up @@ -109,7 +110,7 @@ export async function main(ns) {
await ns.sleep(lastLoopSuccessful ? 10 : 1000); // Only sleep a short while between charges if things are going well
lastLoopSuccessful = false;
try {
if (!options['no-tail']) ns.tail(); // Keep a tail window open unless otherwise configured
if (!options['no-tail']) tail(ns); // Keep a tail window open unless otherwise configured
await checkOnChargeScript();
const fragmentsToCharge = await getFragmentsToCharge(ns);
if (fragmentsToCharge === undefined) continue;
Expand Down
16 changes: 8 additions & 8 deletions work-for-factions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
instanceCount, getConfiguration, getNsDataThroughFile, getFilePath, getActiveSourceFiles, tryGetBitNodeMultipliers,
formatDuration, formatMoney, formatNumberShort, disableLogs, log, getErrorInfo
formatDuration, formatMoney, formatNumberShort, disableLogs, log, getErrorInfo, tail
} from './helpers.js'

let options;
Expand Down Expand Up @@ -592,11 +592,11 @@ export async function crimeForKillsKarmaStats(ns, reqKills, reqKarma, reqStats,
if (await isValidInterruption(ns, currentWork)) return;
if (lastCrime) {
log(ns, `Committing Crime "${lastCrime}" Interrupted. (Now: ${crimeType ?? currentWork.type}) Restarting...`, false, 'warning');
ns.tail(); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep doing crime
tail(ns); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep doing crime
}
let focusArg = shouldFocus === undefined ? true : shouldFocus; // Only undefined if running as imported function
crimeTime = await getNsDataThroughFile(ns, 'ns.singularity.commitCrime(ns.args[0], ns.args[1])', null, [crime, focusArg])
if (shouldFocus) ns.tail(); // Force a tail window open when auto-criming with focus so that the user can more easily kill this script
if (shouldFocus) tail(ns); // Force a tail window open when auto-criming with focus so that the user can more easily kill this script
}
// Periodic status update with progress
if (lastCrime != crime || (Date.now() - lastStatusUpdateTime) > statusUpdateInterval) {
Expand Down Expand Up @@ -884,7 +884,7 @@ export async function workForSingleFaction(ns, factionName, forceUnlockDonations
if (await isValidInterruption(ns, currentWork)) return;
log(ns, `Work for faction ${factionName} was interrupted (Now: ${JSON.stringify(currentWork)}). Restarting...`, false, 'warning');
workAssigned = false;
ns.tail(); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep working
tail(ns); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep working
}
// Periodically check again what the best faction work is (may change with stats over time)
if ((Date.now() - lastStatusUpdateTime) > statusUpdateInterval)
Expand All @@ -901,7 +901,7 @@ export async function workForSingleFaction(ns, factionName, forceUnlockDonations
if (!workAssigned) {
if (await startWorkForFaction(ns, factionName, bestFactionJob, shouldFocus)) {
workAssigned = true;
if (shouldFocus) ns.tail(); // Keep a tail window open if we're stealing focus
if (shouldFocus) tail(ns); // Keep a tail window open if we're stealing focus
} else {
log(ns, `ERROR: Something went wrong, failed to start "${bestFactionJob}" work for faction "${factionName}" (Is gang faction, or not joined?)`, false, 'error');
break;
Expand Down Expand Up @@ -1139,7 +1139,7 @@ export async function workForMegacorpFactionInvite(ns, factionName, waitForInvit
if (await isValidInterruption(ns, currentWork)) return;
log(ns, `Leadership studies were interrupted. classType="${classType}" Restarting...`, false, 'warning');
isStudying = false; // If something external has interrupted our studies, take note
ns.tail(); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep studying
tail(ns); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep studying
}
if (!isStudying) { // Study at ZB university if CHA is the limiter.
if (await studyForCharisma(ns, shouldFocus))
Expand Down Expand Up @@ -1170,11 +1170,11 @@ export async function workForMegacorpFactionInvite(ns, factionName, waitForInvit
if (isWorking) { // Log a warning if we discovered that work we previously began was disrupted
log(ns, `Work for company ${companyName} was interrupted (Now: ${JSON.stringify(currentWork)}). Restarting...`, false, 'warning');
isWorking = false;
ns.tail(); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep working
tail(ns); // Force a tail window open to help the user kill this script if they accidentally closed the tail window and don't want to keep working
}
if (await getNsDataThroughFile(ns, `ns.singularity.workForCompany(ns.args[0], ns.args[1])`, null, [companyName, shouldFocus])) {
isWorking = true;
if (shouldFocus) ns.tail(); // Keep a tail window open if we're stealing focus
if (shouldFocus) tail(ns); // Keep a tail window open if we're stealing focus
} else {
log(ns, `Something went wrong, failed to start working for company "${companyName}".`, false, 'error');
break;
Expand Down

0 comments on commit 25ffeda

Please sign in to comment.