mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-22 17:23:00 +02:00
Merge pull request #1418 from danielyxie/dev
grow, weaken, time compression
This commit is contained in:
Vendored
+18
-18
File diff suppressed because one or more lines are too long
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
@@ -11,10 +11,11 @@ Source-File minus 1 is extremely weak because it can be fully level up quickly.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export enum Exploit {
|
export enum Exploit {
|
||||||
UndocumentedFunctionCall = "UndocumentedFunctionCall",
|
|
||||||
Unclickable = "Unclickable",
|
|
||||||
PrototypeTampering = "PrototypeTampering",
|
|
||||||
Bypass = "Bypass",
|
Bypass = "Bypass",
|
||||||
|
PrototypeTampering = "PrototypeTampering",
|
||||||
|
Unclickable = "Unclickable",
|
||||||
|
UndocumentedFunctionCall = "UndocumentedFunctionCall",
|
||||||
|
TimeCompression = "TimeCompression",
|
||||||
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
||||||
// editing your save file, yes you could add them all, no we don't care
|
// editing your save file, yes you could add them all, no we don't care
|
||||||
// that's not the point.
|
// that's not the point.
|
||||||
@@ -24,11 +25,12 @@ export enum Exploit {
|
|||||||
const names: {
|
const names: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
} = {
|
} = {
|
||||||
UndocumentedFunctionCall: "by looking beyond the documentation.",
|
Bypass: "by circumventing the ram cost of document.",
|
||||||
EditSaveFile: "by editing your save file.",
|
EditSaveFile: "by editing your save file.",
|
||||||
PrototypeTampering: "by tampering with Numbers prototype.",
|
PrototypeTampering: "by tampering with Numbers prototype.",
|
||||||
|
TimeCompression: "by compressing time",
|
||||||
Unclickable: "by clicking the unclickable.",
|
Unclickable: "by clicking the unclickable.",
|
||||||
Bypass: "by circumventing the ram cost of document.",
|
UndocumentedFunctionCall: "by looking beyond the documentation.",
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ExploitName(exploit: string): string {
|
export function ExploitName(exploit: string): string {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Player } from "../Player";
|
||||||
|
import { Exploit } from "./Exploit";
|
||||||
|
|
||||||
|
function tampering(): void {
|
||||||
|
if (Player.exploits.includes(Exploit.PrototypeTampering)) return;
|
||||||
|
// Tampering
|
||||||
|
const a = 55;
|
||||||
|
setInterval(function () {
|
||||||
|
if (a.toExponential() !== "5.5e+1") {
|
||||||
|
Player.giveExploit(Exploit.PrototypeTampering);
|
||||||
|
}
|
||||||
|
}, 15 * 60 * 1000); // 15 minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeCompression(): void {
|
||||||
|
if (Player.exploits.includes(Exploit.TimeCompression)) return;
|
||||||
|
// Time compression
|
||||||
|
let last = new Date().getTime();
|
||||||
|
function minute(): void {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
if (now - last < 500) {
|
||||||
|
// time has been compressed.
|
||||||
|
Player.giveExploit(Exploit.TimeCompression);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last = now;
|
||||||
|
setTimeout(minute, 1000);
|
||||||
|
}
|
||||||
|
setTimeout(minute, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startExploits(): void {
|
||||||
|
tampering();
|
||||||
|
timeCompression();
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import { Player } from "../Player";
|
|
||||||
import { Exploit } from "./Exploit";
|
|
||||||
|
|
||||||
export function startTampering(): void {
|
|
||||||
const a = 55;
|
|
||||||
setInterval(function () {
|
|
||||||
if (a.toExponential() !== "5.5e+1") {
|
|
||||||
Player.giveExploit(Exploit.PrototypeTampering);
|
|
||||||
}
|
|
||||||
}, 15 * 60 * 1000); // 15 minutes
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
|
||||||
|
|
||||||
import { isString } from "./utils/helpers/isString";
|
import { isString } from "./utils/helpers/isString";
|
||||||
import { AllServers } from "./Server/AllServers";
|
import { AllServers } from "./Server/AllServers";
|
||||||
import { WorkerScript } from "./Netscript/WorkerScript";
|
import { WorkerScript } from "./Netscript/WorkerScript";
|
||||||
|
|
||||||
export function netscriptDelay(time: number, workerScript: WorkerScript): Promise<void> {
|
export function netscriptDelay(time: number, workerScript: WorkerScript): Promise<void> {
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
workerScript.delay = setTimeoutRef(() => {
|
workerScript.delay = window.setTimeout(() => {
|
||||||
workerScript.delay = null;
|
workerScript.delay = null;
|
||||||
resolve();
|
resolve();
|
||||||
}, time);
|
}, time);
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ import { Exploit } from "./Exploits/Exploit";
|
|||||||
import { Router } from "./ui/GameRoot";
|
import { Router } from "./ui/GameRoot";
|
||||||
|
|
||||||
import { numeralWrapper } from "./ui/numeralFormat";
|
import { numeralWrapper } from "./ui/numeralFormat";
|
||||||
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
|
||||||
import { is2DArray } from "./utils/helpers/is2DArray";
|
import { is2DArray } from "./utils/helpers/is2DArray";
|
||||||
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
||||||
|
|
||||||
@@ -1045,7 +1044,6 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return Promise.reject(workerScript);
|
return Promise.reject(workerScript);
|
||||||
}
|
}
|
||||||
const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable;
|
const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable;
|
||||||
server.moneyAvailable += 1 * threads; // It can be grown even if it has no money
|
|
||||||
processSingleServerGrowth(server, threads, Player, host.cpuCores);
|
processSingleServerGrowth(server, threads, Player, host.cpuCores);
|
||||||
const moneyAfter = server.moneyAvailable;
|
const moneyAfter = server.moneyAvailable;
|
||||||
workerScript.scriptRef.recordGrow(server.ip, threads);
|
workerScript.scriptRef.recordGrow(server.ip, threads);
|
||||||
@@ -1389,7 +1387,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const spawnDelay = 10;
|
const spawnDelay = 10;
|
||||||
setTimeoutRef(() => {
|
setTimeout(() => {
|
||||||
if (isNaN(threads) || threads <= 0) {
|
if (isNaN(threads) || threads <= 0) {
|
||||||
throw makeRuntimeErrorMsg("spawn", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
|
throw makeRuntimeErrorMsg("spawn", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
|
||||||
}
|
}
|
||||||
@@ -4072,7 +4070,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
checkSingularityAccess("softReset", 3);
|
checkSingularityAccess("softReset", 3);
|
||||||
|
|
||||||
workerScript.log("softReset", "Soft resetting. This will cause this script to be killed");
|
workerScript.log("softReset", "Soft resetting. This will cause this script to be killed");
|
||||||
setTimeoutRef(() => {
|
setTimeout(() => {
|
||||||
prestigeAugmentation();
|
prestigeAugmentation();
|
||||||
runAfterReset(cbScript);
|
runAfterReset(cbScript);
|
||||||
}, 0);
|
}, 0);
|
||||||
@@ -4091,7 +4089,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
}
|
}
|
||||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||||
workerScript.log("installAugmentations", "Installing Augmentations. This will cause this script to be killed");
|
workerScript.log("installAugmentations", "Installing Augmentations. This will cause this script to be killed");
|
||||||
setTimeoutRef(() => {
|
setTimeout(() => {
|
||||||
installAugmentations();
|
installAugmentations();
|
||||||
runAfterReset(cbScript);
|
runAfterReset(cbScript);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import { Script } from "./Script/Script";
|
|||||||
import { AllServers } from "./Server/AllServers";
|
import { AllServers } from "./Server/AllServers";
|
||||||
import { BaseServer } from "./Server/BaseServer";
|
import { BaseServer } from "./Server/BaseServer";
|
||||||
import { Settings } from "./Settings/Settings";
|
import { Settings } from "./Settings/Settings";
|
||||||
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
|
||||||
|
|
||||||
import { generate } from "escodegen";
|
import { generate } from "escodegen";
|
||||||
|
|
||||||
@@ -264,7 +263,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<WorkerScript
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (interpreter.step()) {
|
if (interpreter.step()) {
|
||||||
setTimeoutRef(runInterpreter, Settings.CodeInstructionRunTime);
|
setTimeout(runInterpreter, Settings.CodeInstructionRunTime);
|
||||||
} else {
|
} else {
|
||||||
resolve(workerScript);
|
resolve(workerScript);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -13,7 +13,6 @@ import { loadStockMarket, StockMarket } from "./StockMarket/StockMarket";
|
|||||||
|
|
||||||
import { GameSavedEvents } from "./ui/React/Snackbar";
|
import { GameSavedEvents } from "./ui/React/Snackbar";
|
||||||
|
|
||||||
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
|
||||||
import * as ExportBonus from "./ExportBonus";
|
import * as ExportBonus from "./ExportBonus";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
||||||
@@ -102,7 +101,7 @@ class BitburnerSaveObject {
|
|||||||
a.download = filename;
|
a.download = filename;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
setTimeoutRef(function () {
|
setTimeout(function () {
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
import { calculateRamUsage } from "./RamCalculations";
|
import { calculateRamUsage } from "./RamCalculations";
|
||||||
import { ScriptUrl } from "./ScriptUrl";
|
import { ScriptUrl } from "./ScriptUrl";
|
||||||
|
|
||||||
import { setTimeoutRef } from "../utils/SetTimeoutRef";
|
|
||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||||
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ export class Script {
|
|||||||
a.download = filename;
|
a.download = filename;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
setTimeoutRef(function () {
|
setTimeout(function () {
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ export function processSingleServerGrowth(server: Server, threads: number, p: IP
|
|||||||
}
|
}
|
||||||
|
|
||||||
const oldMoneyAvailable = server.moneyAvailable;
|
const oldMoneyAvailable = server.moneyAvailable;
|
||||||
|
server.moneyAvailable += 1 * threads; // It can be grown even if it has no money
|
||||||
server.moneyAvailable *= serverGrowth;
|
server.moneyAvailable *= serverGrowth;
|
||||||
|
|
||||||
// in case of data corruption
|
// in case of data corruption
|
||||||
|
|||||||
@@ -13,10 +13,11 @@ export const TerminalHelpText: string[] = [
|
|||||||
"check [script] [args...] Print a script's logs to Terminal",
|
"check [script] [args...] Print a script's logs to Terminal",
|
||||||
"clear Clear all text on the terminal ",
|
"clear Clear all text on the terminal ",
|
||||||
"cls See 'clear' command ",
|
"cls See 'clear' command ",
|
||||||
"connect [ip/hostname] Connects to a remote server",
|
"connect [hostname] Connects to a remote server",
|
||||||
"download [script/text file] Downloads scripts or text files to your computer",
|
"download [script/text file] Downloads scripts or text files to your computer",
|
||||||
"expr [math expression] Evaluate a mathematical expression",
|
"expr [math expression] Evaluate a mathematical expression",
|
||||||
"free Check the machine's memory (RAM) usage",
|
"free Check the machine's memory (RAM) usage",
|
||||||
|
"grow Spoof money in a servers bank account, increasing the amount available.",
|
||||||
"hack Hack the current machine",
|
"hack Hack the current machine",
|
||||||
"help [command] Display this help text, or the help text for a command",
|
"help [command] Display this help text, or the help text for a command",
|
||||||
"home Connect to home computer",
|
"home Connect to home computer",
|
||||||
@@ -39,6 +40,7 @@ export const TerminalHelpText: string[] = [
|
|||||||
"tail [script] [args...] Displays dynamic logs for the specified script",
|
"tail [script] [args...] Displays dynamic logs for the specified script",
|
||||||
"top Displays all running scripts and their RAM usage",
|
"top Displays all running scripts and their RAM usage",
|
||||||
"unalias [alias name] Deletes the specified alias",
|
"unalias [alias name] Deletes the specified alias",
|
||||||
|
"weaken [server] Reduce the security of a server",
|
||||||
"wget [url] [target file] Retrieves code/text from a web server",
|
"wget [url] [target file] Retrieves code/text from a web server",
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -151,7 +153,7 @@ export const HelpTexts: IMap<string[]> = {
|
|||||||
"and down arrow keys is still valid. Also note that this is permanent and there is no way to undo this. Synonymous with 'clear' command",
|
"and down arrow keys is still valid. Also note that this is permanent and there is no way to undo this. Synonymous with 'clear' command",
|
||||||
],
|
],
|
||||||
connect: [
|
connect: [
|
||||||
"connect [hostname/ip]",
|
"connect [hostname]",
|
||||||
" ",
|
" ",
|
||||||
"Connect to a remote server. The hostname or IP address of the remote server must be given as the argument ",
|
"Connect to a remote server. The hostname or IP address of the remote server must be given as the argument ",
|
||||||
"to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To ",
|
"to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To ",
|
||||||
@@ -190,6 +192,12 @@ export const HelpTexts: IMap<string[]> = {
|
|||||||
"Display's the memory usage on the current machine. Print the amount of RAM that is available on the current server as well as ",
|
"Display's the memory usage on the current machine. Print the amount of RAM that is available on the current server as well as ",
|
||||||
"how much of it is being used.",
|
"how much of it is being used.",
|
||||||
],
|
],
|
||||||
|
grow: [
|
||||||
|
"grow",
|
||||||
|
"",
|
||||||
|
"Spoof transactions in the current server. Increasing the money available by hacking. Requires root access.",
|
||||||
|
"See the wiki page for hacking mechanics.",
|
||||||
|
],
|
||||||
hack: [
|
hack: [
|
||||||
"hack",
|
"hack",
|
||||||
" ",
|
" ",
|
||||||
@@ -394,6 +402,12 @@ export const HelpTexts: IMap<string[]> = {
|
|||||||
" ",
|
" ",
|
||||||
"It is not necessary to differentiate between global and non-global aliases when using 'unalias'",
|
"It is not necessary to differentiate between global and non-global aliases when using 'unalias'",
|
||||||
],
|
],
|
||||||
|
weaken: [
|
||||||
|
"weaken",
|
||||||
|
"",
|
||||||
|
"Reduces the security level of the current server. Decreasing the time it takes for all operations on this server.",
|
||||||
|
"Requires root access. See the wiki page for hacking mechanics.",
|
||||||
|
],
|
||||||
wget: [
|
wget: [
|
||||||
"wget [url] [target file]",
|
"wget [url] [target file]",
|
||||||
" ",
|
" ",
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ export class Link {
|
|||||||
export class TTimer {
|
export class TTimer {
|
||||||
time: number;
|
time: number;
|
||||||
timeLeft: number;
|
timeLeft: number;
|
||||||
action: "h" | "b" | "a";
|
action: "h" | "b" | "a" | "g" | "w";
|
||||||
|
|
||||||
constructor(time: number, action: "h" | "b" | "a") {
|
constructor(time: number, action: "h" | "b" | "a" | "g" | "w") {
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.timeLeft = time;
|
this.timeLeft = time;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
@@ -62,7 +62,11 @@ export interface ITerminal {
|
|||||||
startAnalyze(): void;
|
startAnalyze(): void;
|
||||||
startBackdoor(player: IPlayer): void;
|
startBackdoor(player: IPlayer): void;
|
||||||
startHack(player: IPlayer): void;
|
startHack(player: IPlayer): void;
|
||||||
|
startGrow(player: IPlayer): void;
|
||||||
|
startWeaken(player: IPlayer): void;
|
||||||
finishHack(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
finishHack(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
|
finishGrow(player: IPlayer, cancelled?: boolean): void;
|
||||||
|
finishWeaken(player: IPlayer, cancelled?: boolean): void;
|
||||||
finishBackdoor(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
finishBackdoor(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
finishAnalyze(player: IPlayer, cancelled?: boolean): void;
|
finishAnalyze(player: IPlayer, cancelled?: boolean): void;
|
||||||
finishAction(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
finishAction(router: IRouter, player: IPlayer, cancelled?: boolean): void;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { AllServers } from "../Server/AllServers";
|
|||||||
import { removeLeadingSlash, isInRootDirectory, evaluateFilePath } from "./DirectoryHelpers";
|
import { removeLeadingSlash, isInRootDirectory, evaluateFilePath } from "./DirectoryHelpers";
|
||||||
import { checkIfConnectedToDarkweb } from "../DarkWeb/DarkWeb";
|
import { checkIfConnectedToDarkweb } from "../DarkWeb/DarkWeb";
|
||||||
import { iTutorialNextStep, iTutorialSteps, ITutorial } from "../InteractiveTutorial";
|
import { iTutorialNextStep, iTutorialSteps, ITutorial } from "../InteractiveTutorial";
|
||||||
import { GetServerByHostname, getServer, getServerOnNetwork } from "../Server/ServerHelpers";
|
import { GetServerByHostname, getServer, getServerOnNetwork, processSingleServerGrowth } from "../Server/ServerHelpers";
|
||||||
import { ParseCommand, ParseCommands } from "./Parser";
|
import { ParseCommand, ParseCommands } from "./Parser";
|
||||||
import { SpecialServerIps, SpecialServerNames } from "../Server/SpecialServerIps";
|
import { SpecialServerIps, SpecialServerNames } from "../Server/SpecialServerIps";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
@@ -27,6 +27,8 @@ import {
|
|||||||
calculateHackingExpGain,
|
calculateHackingExpGain,
|
||||||
calculatePercentMoneyHacked,
|
calculatePercentMoneyHacked,
|
||||||
calculateHackingTime,
|
calculateHackingTime,
|
||||||
|
calculateGrowTime,
|
||||||
|
calculateWeakenTime,
|
||||||
} from "../Hacking";
|
} from "../Hacking";
|
||||||
import { numeralWrapper } from "../ui/numeralFormat";
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||||
@@ -42,6 +44,7 @@ import { connect } from "./commands/connect";
|
|||||||
import { download } from "./commands/download";
|
import { download } from "./commands/download";
|
||||||
import { expr } from "./commands/expr";
|
import { expr } from "./commands/expr";
|
||||||
import { free } from "./commands/free";
|
import { free } from "./commands/free";
|
||||||
|
import { grow } from "./commands/grow";
|
||||||
import { hack } from "./commands/hack";
|
import { hack } from "./commands/hack";
|
||||||
import { help } from "./commands/help";
|
import { help } from "./commands/help";
|
||||||
import { home } from "./commands/home";
|
import { home } from "./commands/home";
|
||||||
@@ -64,6 +67,7 @@ import { sudov } from "./commands/sudov";
|
|||||||
import { tail } from "./commands/tail";
|
import { tail } from "./commands/tail";
|
||||||
import { top } from "./commands/top";
|
import { top } from "./commands/top";
|
||||||
import { unalias } from "./commands/unalias";
|
import { unalias } from "./commands/unalias";
|
||||||
|
import { weaken } from "./commands/weaken";
|
||||||
import { wget } from "./commands/wget";
|
import { wget } from "./commands/wget";
|
||||||
|
|
||||||
export class Terminal implements ITerminal {
|
export class Terminal implements ITerminal {
|
||||||
@@ -115,6 +119,23 @@ export class Terminal implements ITerminal {
|
|||||||
this.startAction(calculateHackingTime(server, player) / 4, "h");
|
this.startAction(calculateHackingTime(server, player) / 4, "h");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startGrow(player: IPlayer): void {
|
||||||
|
const server = player.getCurrentServer();
|
||||||
|
if (server instanceof HacknetServer) {
|
||||||
|
this.error("Cannot hack this kind of server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.startAction(calculateGrowTime(server, player) / 16, "g");
|
||||||
|
}
|
||||||
|
startWeaken(player: IPlayer): void {
|
||||||
|
const server = player.getCurrentServer();
|
||||||
|
if (server instanceof HacknetServer) {
|
||||||
|
this.error("Cannot hack this kind of server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.startAction(calculateWeakenTime(server, player) / 16, "w");
|
||||||
|
}
|
||||||
|
|
||||||
startBackdoor(player: IPlayer): void {
|
startBackdoor(player: IPlayer): void {
|
||||||
// Backdoor should take the same amount of time as hack
|
// Backdoor should take the same amount of time as hack
|
||||||
const server = player.getCurrentServer();
|
const server = player.getCurrentServer();
|
||||||
@@ -130,7 +151,7 @@ export class Terminal implements ITerminal {
|
|||||||
this.startAction(1, "a");
|
this.startAction(1, "a");
|
||||||
}
|
}
|
||||||
|
|
||||||
startAction(n: number, action: "h" | "b" | "a"): void {
|
startAction(n: number, action: "h" | "b" | "a" | "g" | "w"): void {
|
||||||
this.action = new TTimer(n, action);
|
this.action = new TTimer(n, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +204,6 @@ export class Terminal implements ITerminal {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// Failure
|
// Failure
|
||||||
// player only gains 25% exp for failure? TODO Can change this later to balance
|
|
||||||
player.gainHackingExp(expGainedOnFailure);
|
player.gainHackingExp(expGainedOnFailure);
|
||||||
this.print(
|
this.print(
|
||||||
`Failed to hack ${server.hostname}. Gained ${numeralWrapper.formatExp(expGainedOnFailure)} hacking exp`,
|
`Failed to hack ${server.hostname}. Gained ${numeralWrapper.formatExp(expGainedOnFailure)} hacking exp`,
|
||||||
@@ -191,6 +211,39 @@ export class Terminal implements ITerminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finishGrow(player: IPlayer, cancelled = false): void {
|
||||||
|
if (cancelled) return;
|
||||||
|
const server = player.getCurrentServer();
|
||||||
|
if (server instanceof HacknetServer) {
|
||||||
|
this.error("Cannot hack this kind of server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const expGain = calculateHackingExpGain(server, player);
|
||||||
|
const growth = processSingleServerGrowth(server, 1, player, server.cpuCores) - 1;
|
||||||
|
this.print(
|
||||||
|
`Available money on '${server.hostname}' grown by ${numeralWrapper.formatPercentage(
|
||||||
|
growth,
|
||||||
|
6,
|
||||||
|
)}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
finishWeaken(player: IPlayer, cancelled = false): void {
|
||||||
|
if (cancelled) return;
|
||||||
|
const server = player.getCurrentServer();
|
||||||
|
if (server instanceof HacknetServer) {
|
||||||
|
this.error("Cannot hack this kind of server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const expGain = calculateHackingExpGain(server, player);
|
||||||
|
server.weaken(CONSTANTS.ServerWeakenAmount);
|
||||||
|
this.print(
|
||||||
|
`'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(
|
||||||
|
expGain,
|
||||||
|
)} hacking exp.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
finishBackdoor(router: IRouter, player: IPlayer, cancelled = false): void {
|
finishBackdoor(router: IRouter, player: IPlayer, cancelled = false): void {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
const server = player.getCurrentServer();
|
const server = player.getCurrentServer();
|
||||||
@@ -257,6 +310,10 @@ export class Terminal implements ITerminal {
|
|||||||
this.print(this.getProgressText());
|
this.print(this.getProgressText());
|
||||||
if (this.action.action === "h") {
|
if (this.action.action === "h") {
|
||||||
this.finishHack(router, player, cancelled);
|
this.finishHack(router, player, cancelled);
|
||||||
|
} else if (this.action.action === "g") {
|
||||||
|
this.finishGrow(player, cancelled);
|
||||||
|
} else if (this.action.action === "w") {
|
||||||
|
this.finishWeaken(player, cancelled);
|
||||||
} else if (this.action.action === "b") {
|
} else if (this.action.action === "b") {
|
||||||
this.finishBackdoor(router, player, cancelled);
|
this.finishBackdoor(router, player, cancelled);
|
||||||
} else if (this.action.action === "a") {
|
} else if (this.action.action === "a") {
|
||||||
@@ -657,6 +714,7 @@ export class Terminal implements ITerminal {
|
|||||||
args: (string | number)[],
|
args: (string | number)[],
|
||||||
) => void;
|
) => void;
|
||||||
} = {
|
} = {
|
||||||
|
"scan-analyze": scananalyze,
|
||||||
alias: alias,
|
alias: alias,
|
||||||
analyze: analyze,
|
analyze: analyze,
|
||||||
backdoor: backdoor,
|
backdoor: backdoor,
|
||||||
@@ -664,12 +722,13 @@ export class Terminal implements ITerminal {
|
|||||||
cat: cat,
|
cat: cat,
|
||||||
cd: cd,
|
cd: cd,
|
||||||
check: check,
|
check: check,
|
||||||
cls: () => this.clear(),
|
|
||||||
clear: () => this.clear(),
|
clear: () => this.clear(),
|
||||||
|
cls: () => this.clear(),
|
||||||
connect: connect,
|
connect: connect,
|
||||||
download: download,
|
download: download,
|
||||||
expr: expr,
|
expr: expr,
|
||||||
free: free,
|
free: free,
|
||||||
|
grow: grow,
|
||||||
hack: hack,
|
hack: hack,
|
||||||
help: help,
|
help: help,
|
||||||
home: home,
|
home: home,
|
||||||
@@ -686,12 +745,12 @@ export class Terminal implements ITerminal {
|
|||||||
rm: rm,
|
rm: rm,
|
||||||
run: run,
|
run: run,
|
||||||
scan: scan,
|
scan: scan,
|
||||||
"scan-analyze": scananalyze,
|
|
||||||
scp: scp,
|
scp: scp,
|
||||||
sudov: sudov,
|
sudov: sudov,
|
||||||
tail: tail,
|
tail: tail,
|
||||||
top: top,
|
top: top,
|
||||||
unalias: unalias,
|
unalias: unalias,
|
||||||
|
weaken: weaken,
|
||||||
wget: wget,
|
wget: wget,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { ITerminal } from "../ITerminal";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
import { Server } from "../../Server/Server";
|
||||||
|
|
||||||
|
export function grow(
|
||||||
|
terminal: ITerminal,
|
||||||
|
router: IRouter,
|
||||||
|
player: IPlayer,
|
||||||
|
server: BaseServer,
|
||||||
|
args: (string | number)[],
|
||||||
|
): void {
|
||||||
|
if (args.length !== 0) {
|
||||||
|
terminal.error("Incorrect usage of grow command. Usage: grow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(server instanceof Server)) {
|
||||||
|
terminal.error(
|
||||||
|
"Cannot grow your own machines! You are currently connected to your home PC or one of your purchased servers",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const normalServer = server as Server;
|
||||||
|
// Hack the current PC (usually for money)
|
||||||
|
// You can't grow your home pc or servers you purchased
|
||||||
|
if (normalServer.purchasedByPlayer) {
|
||||||
|
terminal.error(
|
||||||
|
"Cannot grow your own machines! You are currently connected to your home PC or one of your purchased servers",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!normalServer.hasAdminRights) {
|
||||||
|
terminal.error("You do not have admin rights for this machine! Cannot grow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (normalServer.requiredHackingSkill > player.hacking_skill) {
|
||||||
|
terminal.error(
|
||||||
|
"Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
terminal.startGrow(player);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { ITerminal } from "../ITerminal";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
import { Server } from "../../Server/Server";
|
||||||
|
|
||||||
|
export function weaken(
|
||||||
|
terminal: ITerminal,
|
||||||
|
router: IRouter,
|
||||||
|
player: IPlayer,
|
||||||
|
server: BaseServer,
|
||||||
|
args: (string | number)[],
|
||||||
|
): void {
|
||||||
|
if (args.length !== 0) {
|
||||||
|
terminal.error("Incorrect usage of weaken command. Usage: weaken");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(server instanceof Server)) {
|
||||||
|
terminal.error(
|
||||||
|
"Cannot weaken your own machines! You are currently connected to your home PC or one of your purchased servers",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const normalServer = server as Server;
|
||||||
|
// Hack the current PC (usually for money)
|
||||||
|
// You can't weaken your home pc or servers you purchased
|
||||||
|
if (normalServer.purchasedByPlayer) {
|
||||||
|
terminal.error(
|
||||||
|
"Cannot weaken your own machines! You are currently connected to your home PC or one of your purchased servers",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!normalServer.hasAdminRights) {
|
||||||
|
terminal.error("You do not have admin rights for this machine! Cannot weaken");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (normalServer.requiredHackingSkill > player.hacking_skill) {
|
||||||
|
terminal.error(
|
||||||
|
"Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill",
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
terminal.startWeaken(player);
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ const commands = [
|
|||||||
"download",
|
"download",
|
||||||
"expr",
|
"expr",
|
||||||
"free",
|
"free",
|
||||||
|
"grow",
|
||||||
"hack",
|
"hack",
|
||||||
"help",
|
"help",
|
||||||
"home",
|
"home",
|
||||||
@@ -36,13 +37,14 @@ const commands = [
|
|||||||
"ps",
|
"ps",
|
||||||
"rm",
|
"rm",
|
||||||
"run",
|
"run",
|
||||||
"scan",
|
|
||||||
"scan-analyze",
|
"scan-analyze",
|
||||||
|
"scan",
|
||||||
"scp",
|
"scp",
|
||||||
"sudov",
|
"sudov",
|
||||||
"tail",
|
"tail",
|
||||||
"theme",
|
"theme",
|
||||||
"top",
|
"top",
|
||||||
|
"weaken",
|
||||||
];
|
];
|
||||||
|
|
||||||
export function determineAllPossibilitiesForTabCompletion(
|
export function determineAllPossibilitiesForTabCompletion(
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Theme } from "@mui/material/styles";
|
|||||||
import makeStyles from "@mui/styles/makeStyles";
|
import makeStyles from "@mui/styles/makeStyles";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
import createStyles from "@mui/styles/createStyles";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import Paper from "@mui/material/Paper";
|
import Tooltip from "@mui/material/Tooltip";
|
||||||
|
|
||||||
import { KEY } from "../../utils/helpers/keyCodes";
|
import { KEY } from "../../utils/helpers/keyCodes";
|
||||||
import { ITerminal } from "../ITerminal";
|
import { ITerminal } from "../ITerminal";
|
||||||
@@ -18,7 +18,6 @@ const useStyles = makeStyles((theme: Theme) =>
|
|||||||
createStyles({
|
createStyles({
|
||||||
textfield: {
|
textfield: {
|
||||||
margin: theme.spacing(0),
|
margin: theme.spacing(0),
|
||||||
width: "100%",
|
|
||||||
},
|
},
|
||||||
input: {
|
input: {
|
||||||
backgroundColor: "#000",
|
backgroundColor: "#000",
|
||||||
@@ -330,40 +329,46 @@ export function TerminalInput({ terminal, router, player }: IProps): React.React
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{possibilities.length > 0 && (
|
<Tooltip
|
||||||
<Paper square>
|
title={
|
||||||
<Typography classes={{ root: classes.preformatted }} color={"primary"} paragraph={false}>
|
possibilities.length > 0 ? (
|
||||||
Possible autocomplete candidate:
|
|
||||||
</Typography>
|
|
||||||
<Typography classes={{ root: classes.preformatted }} color={"primary"} paragraph={false}>
|
|
||||||
{possibilities.join(" ")}
|
|
||||||
</Typography>
|
|
||||||
</Paper>
|
|
||||||
)}
|
|
||||||
<TextField
|
|
||||||
color={terminal.action === null ? "primary" : "secondary"}
|
|
||||||
autoFocus
|
|
||||||
disabled={terminal.action !== null}
|
|
||||||
autoComplete="off"
|
|
||||||
classes={{ root: classes.textfield }}
|
|
||||||
value={value}
|
|
||||||
onChange={handleValueChange}
|
|
||||||
inputRef={terminalInput}
|
|
||||||
InputProps={{
|
|
||||||
// for players to hook in
|
|
||||||
id: "terminal-input",
|
|
||||||
className: classes.input,
|
|
||||||
startAdornment: (
|
|
||||||
<>
|
<>
|
||||||
|
<Typography classes={{ root: classes.preformatted }} color={"primary"} paragraph={false}>
|
||||||
|
Possible autocomplete candidate:
|
||||||
|
</Typography>
|
||||||
|
<Typography classes={{ root: classes.preformatted }} color={"primary"} paragraph={false}>
|
||||||
|
{possibilities.join(" ")}
|
||||||
|
</Typography>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
color={terminal.action === null ? "primary" : "secondary"}
|
||||||
|
autoFocus
|
||||||
|
disabled={terminal.action !== null}
|
||||||
|
autoComplete="off"
|
||||||
|
value={value}
|
||||||
|
classes={{ root: classes.textfield }}
|
||||||
|
onChange={handleValueChange}
|
||||||
|
inputRef={terminalInput}
|
||||||
|
InputProps={{
|
||||||
|
// for players to hook in
|
||||||
|
id: "terminal-input",
|
||||||
|
className: classes.input,
|
||||||
|
startAdornment: (
|
||||||
<Typography color={terminal.action === null ? "primary" : "secondary"} flexShrink={0}>
|
<Typography color={terminal.action === null ? "primary" : "secondary"} flexShrink={0}>
|
||||||
[{player.getCurrentServer().hostname} ~{terminal.cwd()}]>
|
[{player.getCurrentServer().hostname} ~{terminal.cwd()}]>
|
||||||
</Typography>
|
</Typography>
|
||||||
</>
|
),
|
||||||
),
|
spellCheck: false,
|
||||||
spellCheck: false,
|
onKeyDown: onKeyDown,
|
||||||
onKeyDown: onKeyDown,
|
}}
|
||||||
}}
|
></TextField>
|
||||||
></TextField>
|
</Tooltip>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
import { setTimeoutRef } from "./utils/SetTimeoutRef";
|
|
||||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
||||||
import { BaseServer } from "./Server/BaseServer";
|
import { BaseServer } from "./Server/BaseServer";
|
||||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "./utils/JSONReviver";
|
import { Generic_fromJSON, Generic_toJSON, Reviver } from "./utils/JSONReviver";
|
||||||
@@ -47,7 +46,7 @@ export class TextFile {
|
|||||||
a.download = this.fn;
|
a.download = this.fn;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
a.click();
|
a.click();
|
||||||
setTimeoutRef(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|||||||
+2
-2
@@ -44,7 +44,7 @@ import { Reputation } from "./ui/React/Reputation";
|
|||||||
import { AlertEvents } from "./ui/React/AlertManager";
|
import { AlertEvents } from "./ui/React/AlertManager";
|
||||||
import { exceptionAlert } from "./utils/helpers/exceptionAlert";
|
import { exceptionAlert } from "./utils/helpers/exceptionAlert";
|
||||||
|
|
||||||
import { startTampering } from "./Exploits/tampering";
|
import { startExploits } from "./Exploits/loops";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
@@ -262,7 +262,7 @@ const Engine: {
|
|||||||
},
|
},
|
||||||
|
|
||||||
load: function (saveString) {
|
load: function (saveString) {
|
||||||
startTampering();
|
startExploits();
|
||||||
// Load game from save or create new game
|
// Load game from save or create new game
|
||||||
if (loadGame(saveString)) {
|
if (loadGame(saveString)) {
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
|
|||||||
@@ -285,7 +285,9 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
The amount of money on a server is not limitless. So, if you constantly hack a server and deplete its money,
|
The amount of money on a server is not limitless. So, if you constantly hack a server and deplete its money,
|
||||||
then you will encounter diminishing returns in your hacking.
|
then you will encounter diminishing returns in your hacking. You will need to use{" "}
|
||||||
|
<Typography classes={{ root: classes.textfield }}>{"[n00dles ~/]> grow"}</Typography>
|
||||||
|
and <Typography classes={{ root: classes.textfield }}>{"[n00dles ~/]> weaken"}</Typography>
|
||||||
</Typography>
|
</Typography>
|
||||||
),
|
),
|
||||||
canNext: true,
|
canNext: true,
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
// This is a reference to the native setTimeout() function
|
|
||||||
// setTimeout() is used in various places around the game's source code.
|
|
||||||
// This reference is used to make sure that if players alter window.setTimeout()
|
|
||||||
// through NetscriptJS, then the game will still function properly
|
|
||||||
export const setTimeoutRef = window.setTimeout.bind(window);
|
|
||||||
Reference in New Issue
Block a user