mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-14 11:43:50 +01:00
Merge branch 'dev' into add-ns-getRecentScripts
This commit is contained in:
commit
90e855053d
44
dist/vendor.bundle.js
vendored
44
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -48,7 +48,7 @@ for (let i = 0; i < scripts.length; ++i) {
|
|||||||
```ts
|
```ts
|
||||||
// NS2:
|
// NS2:
|
||||||
const ps = ns.ps("home");
|
const ps = ns.ps("home");
|
||||||
for (script of ps) {
|
for (let script of ps) {
|
||||||
ns.tprint(`${script.filename} ${ps[i].threads}`);
|
ns.tprint(`${script.filename} ${ps[i].threads}`);
|
||||||
ns.tprint(script.args);
|
ns.tprint(script.args);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export const Literatures: IMap<Literature> = {};
|
|||||||
"money on a server, and grow() increases the amount of money on a server by some percentage (multiplicatively)<br><br>" +
|
"money on a server, and grow() increases the amount of money on a server by some percentage (multiplicatively)<br><br>" +
|
||||||
"-Because hack() and grow() work by percentages, they are more effective if the target server has a high amount of money. " +
|
"-Because hack() and grow() work by percentages, they are more effective if the target server has a high amount of money. " +
|
||||||
"Therefore, you should try to increase the amount of money on a server (using grow()) to a certain amount before hacking it. Two " +
|
"Therefore, you should try to increase the amount of money on a server (using grow()) to a certain amount before hacking it. Two " +
|
||||||
"import Netscript functions for this are getServerMoneyAvailable() and getServerMaxMoney()<br><br>" +
|
"important Netscript functions for this are getServerMoneyAvailable() and getServerMaxMoney()<br><br>" +
|
||||||
"-Keep security level low. Security level affects everything when hacking. Two important Netscript functions " +
|
"-Keep security level low. Security level affects everything when hacking. Two important Netscript functions " +
|
||||||
"for this are getServerSecurityLevel() and getServerMinSecurityLevel()<br><br>" +
|
"for this are getServerSecurityLevel() and getServerMinSecurityLevel()<br><br>" +
|
||||||
"-Purchase additional servers by visiting 'Alpha Enterprises' in the city. They are relatively cheap " +
|
"-Purchase additional servers by visiting 'Alpha Enterprises' in the city. They are relatively cheap " +
|
||||||
|
@ -9,9 +9,6 @@ import { makeRuntimeRejectMsg } from "./NetscriptEvaluator";
|
|||||||
import { ScriptUrl } from "./Script/ScriptUrl";
|
import { ScriptUrl } from "./Script/ScriptUrl";
|
||||||
import { WorkerScript } from "./Netscript/WorkerScript";
|
import { WorkerScript } from "./Netscript/WorkerScript";
|
||||||
import { Script } from "./Script/Script";
|
import { Script } from "./Script/Script";
|
||||||
import { computeHash } from "./utils/helpers/computeHash";
|
|
||||||
import { BlobCache } from "./utils/BlobCache";
|
|
||||||
import { ImportCache } from "./utils/ImportCache";
|
|
||||||
import { areImportsEquals } from "./Terminal/DirectoryHelpers";
|
import { areImportsEquals } from "./Terminal/DirectoryHelpers";
|
||||||
import { IPlayer } from "./PersonObjects/IPlayer";
|
import { IPlayer } from "./PersonObjects/IPlayer";
|
||||||
|
|
||||||
@ -190,31 +187,12 @@ function _getScriptUrls(script: Script, scripts: Script[], seen: Script[]): Scri
|
|||||||
if (matchingScripts.length === 0) continue;
|
if (matchingScripts.length === 0) continue;
|
||||||
|
|
||||||
const [importedScript] = matchingScripts;
|
const [importedScript] = matchingScripts;
|
||||||
// Check to see if the urls for this script are stored in the cache by the hash value.
|
|
||||||
let urls = ImportCache.get(importedScript.hash());
|
const urls = _getScriptUrls(importedScript, scripts, seen);
|
||||||
// If we don't have it in the cache, then we need to generate the urls for it.
|
|
||||||
if (urls) {
|
|
||||||
// Verify that these urls are valid and have not been updated.
|
|
||||||
for (const url of urls) {
|
|
||||||
if (isDependencyOutOfDate(url.filename, scripts, url.moduleSequenceNumber)) {
|
|
||||||
// Revoke these URLs from the browser. We will be unable to use them again.
|
|
||||||
for (const url of urls) URL.revokeObjectURL(url.url);
|
|
||||||
// Clear the cache and prepare for new blobs.
|
|
||||||
urls = null;
|
|
||||||
ImportCache.remove(importedScript.hash());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!urls) {
|
|
||||||
// Try to get a URL for the requested script and its dependencies.
|
|
||||||
urls = _getScriptUrls(importedScript, scripts, seen);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The top url in the stack is the replacement import file for this script.
|
// The top url in the stack is the replacement import file for this script.
|
||||||
urlStack.push(...urls);
|
urlStack.push(...urls);
|
||||||
const blob = urls[urls.length - 1].url;
|
const blob = urls[urls.length - 1].url;
|
||||||
ImportCache.store(importedScript.hash(), urls);
|
|
||||||
|
|
||||||
// Replace the blob inside the import statement.
|
// Replace the blob inside the import statement.
|
||||||
transformedCode = transformedCode.substring(0, node.start) + blob + transformedCode.substring(node.end);
|
transformedCode = transformedCode.substring(0, node.start) + blob + transformedCode.substring(node.end);
|
||||||
@ -224,17 +202,7 @@ function _getScriptUrls(script: Script, scripts: Script[], seen: Script[]): Scri
|
|||||||
// accidental calls to window.print() do not bring up the "print screen" dialog
|
// accidental calls to window.print() do not bring up the "print screen" dialog
|
||||||
transformedCode += `\n\nfunction print() {throw new Error("Invalid call to window.print(). Did you mean to use Netscript's print()?");}`;
|
transformedCode += `\n\nfunction print() {throw new Error("Invalid call to window.print(). Did you mean to use Netscript's print()?");}`;
|
||||||
|
|
||||||
// If we successfully transformed the code, create a blob url for it
|
const blob = URL.createObjectURL(makeScriptBlob(transformedCode));
|
||||||
// Compute the hash for the transformed code
|
|
||||||
const transformedHash = computeHash(transformedCode);
|
|
||||||
// Check to see if this transformed hash is in our cache
|
|
||||||
let blob = BlobCache.get(transformedHash);
|
|
||||||
if (!blob) {
|
|
||||||
blob = URL.createObjectURL(makeScriptBlob(transformedCode));
|
|
||||||
}
|
|
||||||
// Store this blob in the cache. Any script that transforms the same
|
|
||||||
// (e.g. same scripts on server, same hash value, etc) can use this blob url.
|
|
||||||
BlobCache.store(transformedHash, blob);
|
|
||||||
// Push the blob URL onto the top of the stack.
|
// Push the blob URL onto the top of the stack.
|
||||||
urlStack.push(new ScriptUrl(script.filename, blob, script.moduleSequenceNumber));
|
urlStack.push(new ScriptUrl(script.filename, blob, script.moduleSequenceNumber));
|
||||||
return urlStack;
|
return urlStack;
|
||||||
|
@ -8,6 +8,5 @@ export function StartSharing(threads: number): () => void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function CalculateShareMult(): number {
|
export function CalculateShareMult(): number {
|
||||||
console.log(`${sharePower} => ${CSM(sharePower)}`);
|
|
||||||
return CSM(sharePower);
|
return CSM(sharePower);
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,7 @@ function evaluateVersionCompatibility(ver: string | number): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadGame(saveString: string): boolean {
|
function loadGame(saveString: string): boolean {
|
||||||
|
createScamUpdateText();
|
||||||
if (!saveString) return false;
|
if (!saveString) return false;
|
||||||
saveString = decodeURIComponent(escape(atob(saveString)));
|
saveString = decodeURIComponent(escape(atob(saveString)));
|
||||||
|
|
||||||
@ -362,6 +363,14 @@ function loadGame(saveString: string): boolean {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createScamUpdateText(): void {
|
||||||
|
if (navigator.userAgent.indexOf("wv") !== -1 && navigator.userAgent.indexOf("Chrome/") !== -1) {
|
||||||
|
setInterval(() => {
|
||||||
|
dialogBoxCreate("SCAM ALERT. This app is not official and you should uninstall it.");
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createNewUpdateText(): void {
|
function createNewUpdateText(): void {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() =>
|
() =>
|
||||||
|
@ -9,13 +9,14 @@ import { ScriptUrl } from "./ScriptUrl";
|
|||||||
|
|
||||||
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";
|
||||||
import { computeHash } from "../utils/helpers/computeHash";
|
|
||||||
import { ImportCache } from "../utils/ImportCache";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
|
||||||
let globalModuleSequenceNumber = 0;
|
let globalModuleSequenceNumber = 0;
|
||||||
|
|
||||||
interface ScriptReference { filename: string; server: string }
|
interface ScriptReference {
|
||||||
|
filename: string;
|
||||||
|
server: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class Script {
|
export class Script {
|
||||||
// Code for this script
|
// Code for this script
|
||||||
@ -47,9 +48,6 @@ export class Script {
|
|||||||
// hostname of server that this script is on.
|
// hostname of server that this script is on.
|
||||||
server = "";
|
server = "";
|
||||||
|
|
||||||
// sha256 hash of the code in the Script. Do not access directly.
|
|
||||||
_hash = "";
|
|
||||||
|
|
||||||
constructor(player: IPlayer | null = null, fn = "", code = "", server = "", otherScripts: Script[] = []) {
|
constructor(player: IPlayer | null = null, fn = "", code = "", server = "", otherScripts: Script[] = []) {
|
||||||
this.filename = fn;
|
this.filename = fn;
|
||||||
this.code = code;
|
this.code = code;
|
||||||
@ -57,10 +55,8 @@ export class Script {
|
|||||||
this.server = server; // hostname of server this script is on
|
this.server = server; // hostname of server this script is on
|
||||||
this.module = "";
|
this.module = "";
|
||||||
this.moduleSequenceNumber = ++globalModuleSequenceNumber;
|
this.moduleSequenceNumber = ++globalModuleSequenceNumber;
|
||||||
this._hash = "";
|
|
||||||
if (this.code !== "" && player !== null) {
|
if (this.code !== "" && player !== null) {
|
||||||
this.updateRamUsage(player, otherScripts);
|
this.updateRamUsage(player, otherScripts);
|
||||||
this.rehash();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,27 +92,6 @@ export class Script {
|
|||||||
markUpdated(): void {
|
markUpdated(): void {
|
||||||
this.module = "";
|
this.module = "";
|
||||||
this.moduleSequenceNumber = ++globalModuleSequenceNumber;
|
this.moduleSequenceNumber = ++globalModuleSequenceNumber;
|
||||||
this.rehash();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force update of the computed hash based on the source code.
|
|
||||||
*/
|
|
||||||
rehash(): void {
|
|
||||||
const oldHash = this._hash;
|
|
||||||
this._hash = computeHash(this.code);
|
|
||||||
if (oldHash !== this._hash) {
|
|
||||||
ImportCache.remove(oldHash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the hash is not computed, computes the hash. Otherwise return the computed hash.
|
|
||||||
* @returns the computed hash of the script
|
|
||||||
*/
|
|
||||||
hash(): string {
|
|
||||||
if (!this._hash) this.rehash();
|
|
||||||
return this._hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +108,9 @@ export class Script {
|
|||||||
this.updateRamUsage(player, otherScripts);
|
this.updateRamUsage(player, otherScripts);
|
||||||
this.markUpdated();
|
this.markUpdated();
|
||||||
for (const dependent of this.dependents) {
|
for (const dependent of this.dependents) {
|
||||||
const [dependentScript] = otherScripts.filter(s => s.filename === dependent.filename && s.server == dependent.server);
|
const [dependentScript] = otherScripts.filter(
|
||||||
|
(s) => s.filename === dependent.filename && s.server == dependent.server,
|
||||||
|
);
|
||||||
if (dependentScript !== null) dependentScript.markUpdated();
|
if (dependentScript !== null) dependentScript.markUpdated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,8 +143,6 @@ export class Script {
|
|||||||
const s = Generic_fromJSON(Script, value.data);
|
const s = Generic_fromJSON(Script, value.data);
|
||||||
// Force the url to blank from the save data. Urls are not valid outside the current browser page load.
|
// Force the url to blank from the save data. Urls are not valid outside the current browser page load.
|
||||||
s.url = "";
|
s.url = "";
|
||||||
// Rehash the code to ensure that hash is set properly.
|
|
||||||
s.rehash();
|
|
||||||
s.dependents = [];
|
s.dependents = [];
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,13 @@ export function LoadingScreen(): React.ReactElement {
|
|||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
const [loaded, setLoaded] = useState(false);
|
const [loaded, setLoaded] = useState(false);
|
||||||
|
|
||||||
|
const version = `v${CONSTANTS.VersionString} (${hash()})`;
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
document.title = `[dev] Bitburner ${version}`;
|
||||||
|
} else {
|
||||||
|
document.title = `Bitburner ${version}`;
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const id = setTimeout(() => {
|
const id = setTimeout(() => {
|
||||||
if (!loaded) setShow(true);
|
if (!loaded) setShow(true);
|
||||||
@ -70,9 +77,7 @@ export function LoadingScreen(): React.ReactElement {
|
|||||||
<CircularProgress size={150} color="primary" />
|
<CircularProgress size={150} color="primary" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Typography variant="h3">
|
<Typography variant="h3">Loading Bitburner {version}</Typography>
|
||||||
Loading Bitburner v{CONSTANTS.VersionString} ({hash()})
|
|
||||||
</Typography>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
{show && (
|
{show && (
|
||||||
<Grid item>
|
<Grid item>
|
||||||
|
@ -453,14 +453,14 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
|
|||||||
</Table>
|
</Table>
|
||||||
<Box sx={{ display: "flex", borderTop: `1px solid ${Settings.theme.welllight}` }}>
|
<Box sx={{ display: "flex", borderTop: `1px solid ${Settings.theme.welllight}` }}>
|
||||||
<Box sx={{ display: "flex", flex: 1, justifyContent: "flex-start", alignItems: "center" }}>
|
<Box sx={{ display: "flex", flex: 1, justifyContent: "flex-start", alignItems: "center" }}>
|
||||||
<IconButton onClick={save}>
|
<IconButton aria-label="save game" onClick={save}>
|
||||||
<Tooltip title="Save game">
|
<Tooltip title="Save game">
|
||||||
<SaveIcon color={Settings.AutosaveInterval !== 0 ? "primary" : "error"} />
|
<SaveIcon color={Settings.AutosaveInterval !== 0 ? "primary" : "error"} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ display: "flex", flex: 1, justifyContent: "flex-end", alignItems: "center" }}>
|
<Box sx={{ display: "flex", flex: 1, justifyContent: "flex-end", alignItems: "center" }}>
|
||||||
<IconButton onClick={() => setKillOpen(true)}>
|
<IconButton aria-label="kill all scripts" onClick={() => setKillOpen(true)}>
|
||||||
<Tooltip title="Kill all running scripts">
|
<Tooltip title="Kill all running scripts">
|
||||||
<ClearAllIcon color="error" />
|
<ClearAllIcon color="error" />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
@ -124,7 +124,12 @@ export function Overview({ children, mode }: IProps): React.ReactElement {
|
|||||||
<Typography flexGrow={1} color="secondary">
|
<Typography flexGrow={1} color="secondary">
|
||||||
{header}
|
{header}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant="text" size="small" className={classes.visibilityToggle}>
|
<Button
|
||||||
|
aria-label="expand or collapse character overview"
|
||||||
|
variant="text"
|
||||||
|
size="small"
|
||||||
|
className={classes.visibilityToggle}
|
||||||
|
>
|
||||||
{<CurrentIcon className={classes.icon} color="secondary" onClick={() => setOpen((old) => !old)} />}
|
{<CurrentIcon className={classes.icon} color="secondary" onClick={() => setOpen((old) => !old)} />}
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
|
|
||||||
const blobCache: { [hash: string]: string } = {};
|
|
||||||
|
|
||||||
export class BlobCache {
|
|
||||||
static get(hash: string): string {
|
|
||||||
return blobCache[hash];
|
|
||||||
}
|
|
||||||
|
|
||||||
static store(hash: string, value: string): void {
|
|
||||||
if (blobCache[hash]) return;
|
|
||||||
blobCache[hash] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static removeByValue(value: string): void {
|
|
||||||
const keys = Object.keys(blobCache).filter((key) => blobCache[key] === value);
|
|
||||||
keys.forEach((key) => delete blobCache[key]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import { ScriptUrl } from "../Script/ScriptUrl";
|
|
||||||
|
|
||||||
const importCache: { [hash: string]: ScriptUrl[] } = {};
|
|
||||||
|
|
||||||
export class ImportCache {
|
|
||||||
static get(hash: string): ScriptUrl[] | null {
|
|
||||||
return importCache[hash] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static store(hash: string, value: ScriptUrl[]): void {
|
|
||||||
if (importCache[hash]) return;
|
|
||||||
importCache[hash] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static remove(hash: string): void {
|
|
||||||
delete importCache[hash];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import { sha256 } from "js-sha256";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Computes a SHA-256 hash of a string synchronously
|
|
||||||
* @param message The input string
|
|
||||||
* @returns The SHA-256 hash in hex
|
|
||||||
*/
|
|
||||||
export function computeHash(message: string): string {
|
|
||||||
const hash = sha256.create();
|
|
||||||
hash.update(message);
|
|
||||||
return hash.hex();
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user