This commit is contained in:
Olivier Gagnon 2021-08-23 02:09:49 -04:00
parent b148b2f0b5
commit 6d2b8b4f6f
16 changed files with 106 additions and 80 deletions

File diff suppressed because one or more lines are too long

@ -2444,6 +2444,12 @@ input[type="checkbox"] {
border: 1px solid #fff; border: 1px solid #fff;
background-color: #000; } background-color: #000; }
.log-box-button:hover,
.log-box-button:focus {
color: var(--my-font-color);
text-decoration: none;
cursor: pointer; }
.dialog-box-content { .dialog-box-content {
z-index: 2; z-index: 2;
background-color: var(--my-background-color); background-color: var(--my-background-color);

@ -3,6 +3,26 @@
Changelog Changelog
========= =========
v0.52.8 - 2021-07-23 Fixing the previous patch tbh ROUND 2 (hydroflame)
-------------------------------------------
** Script editor **
* Correctly reloads old script when clicking "Script Editor"
* No longer jumps to the end of the text for no reason.
** Hash upgrades **
* Fixed an issue where the default option would say ecorp but was really
foodnstuff
** Misc. **
* The "Delete all active script" button under the options has a clearer
description.
* Removed some debug console.log
* nerf noodle bar
v0.52.7 - 2021-07-21 Fixing the previous patch tbh (hydroflame) v0.52.7 - 2021-07-21 Fixing the previous patch tbh (hydroflame)
------------------------------------------- -------------------------------------------

@ -66,7 +66,7 @@ documentation_title = '{0} Documentation'.format(project)
# The short X.Y version. # The short X.Y version.
version = '0.52' version = '0.52'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.52.7' release = '0.52.8'
# The language for content autogenerated by Sphinx. Refer to documentation # The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages. # for a list of supported languages.

@ -581,10 +581,12 @@
Copy Save data to Clipboard Copy Save data to Clipboard
</button> </button>
<button id="debug-delete-scripts-link" class="a-link-button tooltip"> <button id="debug-delete-scripts-link" class="a-link-button tooltip">
Delete all active scripts Force kill all active scripts
<span class="tooltiptextleft"> <span class="tooltiptextleft">
Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the game. After Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the game. After
using this, save the game and then reload the page. using this, save the game and then reload the page. This is different then normal kill in that normal kill
will tell the script to shut down while force kill just removes the references to it (and it should crash on it's own).
This will not remove the files on your computer. Just forcefully kill all running instance of all scripts.
</span> </span>
</button> </button>
<button id="debug-soft-reset" class="a-link-button tooltip"> <button id="debug-soft-reset" class="a-link-button tooltip">

@ -129,5 +129,5 @@
"watch": "webpack --watch --mode production", "watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development" "watch:dev": "webpack --watch --mode development"
}, },
"version": "0.52.7" "version": "0.52.8"
} }

@ -26,18 +26,8 @@ export function Console(props: IProps): React.ReactElement {
// TODO: Figure out how to actually make the scrolling work correctly. // TODO: Figure out how to actually make the scrolling work correctly.
function scrollToBottom(): void { function scrollToBottom(): void {
function isMaxed(): boolean { if(!lastRef.current) return;
if(!lastRef.current) return false;
const oldTop = lastRef.current.scrollTop;
lastRef.current.scrollTop = lastRef.current.scrollHeight; lastRef.current.scrollTop = lastRef.current.scrollHeight;
const maxed = oldTop === lastRef.current.scrollTop;
lastRef.current.scrollTop = oldTop;
return maxed;
}
if(lastRef.current) {
if(isMaxed())
lastRef.current.scrollTop = lastRef.current.scrollHeight;
}
} }
function rerender(): void { function rerender(): void {

@ -6,7 +6,7 @@
import { IMap } from "./types"; import { IMap } from "./types";
export const CONSTANTS: IMap<any> = { export const CONSTANTS: IMap<any> = {
Version: "0.52.7", Version: "0.52.8",
// Speed (in ms) at which the main loop is updated // Speed (in ms) at which the main loop is updated
_idleSpeed: 200, _idleSpeed: 200,
@ -228,32 +228,24 @@ export const CONSTANTS: IMap<any> = {
TotalNumBitNodes: 24, TotalNumBitNodes: 24,
LatestUpdate: ` LatestUpdate: `
v0.52.7 - 2021-07-21 Fixing the previous patch tbh (hydroflame) v0.52.8 - 2021-07-23 Fixing the previous patch tbh ROUND 2 (hydroflame)
------------------------------------------- -------------------------------------------
** Netscript ** ** Script editor **
* API BREAKING CHANGE: getActionEstimatedSuccessChance now returns a pair of * Correctly reloads old script when clicking "Script Editor"
value to reflect the UI changes. I'm very sorry. * No longer jumps to the end of the text for no reason.
** Bladeburner ** ** Hash upgrades **
* General actions now display time required. * Fixed an issue where the default option would say ecorp but was really
* Recruitment now displays success chance. foodnstuff
* All other success chance now display a range instead of a single value
The real value is guaranteed to be within that range.
** Misc. ** ** Misc. **
* Fix tutorial not working after Monaco upate * The "Delete all active script" button under the options has a clearer
* Fix logbox logs not taking up the whole logbox description.
* Fix script editor shortcut (ctrl+b) * Removed some debug console.log
* Fix Corporation popup appearing in the wrong order, hiding one of them
* Fix error when loading Corp
* Fix logbox dragging (smoother now)
* Fix logbox name collision
* Fix logbox allowing to open the same box multiple times
* Fix netscript write.
* nerf noodle bar * nerf noodle bar
`, `,

@ -502,7 +502,7 @@ class DevMenuComponent extends Component {
modifyBladeburnerRank(modify) { modifyBladeburnerRank(modify) {
return function(rank) { return function(rank) {
if (Player.bladeburner) { if (Player.bladeburner) {
Player.bladeburner.changeRank(rank*modify); Player.bladeburner.changeRank(Player, rank*modify);
} }
} }
} }
@ -514,7 +514,7 @@ class DevMenuComponent extends Component {
addTonsBladeburnerRank() { addTonsBladeburnerRank() {
if (Player.bladeburner) { if (Player.bladeburner) {
Player.bladeburner.changeRank(tonsP); Player.bladeburner.changeRank(Player, tonsP);
} }
} }

@ -23,7 +23,7 @@ class HashUpgrade extends React.Component {
super(props); super(props);
this.state = { this.state = {
selectedServer: "foodnstuff", selectedServer: "ecorp",
} }
this.changeTargetServer = this.changeTargetServer.bind(this); this.changeTargetServer = this.changeTargetServer.bind(this);

@ -82,7 +82,6 @@ BitburnerSaveObject.prototype.getSaveString = function() {
this.GlobalAliasesSave = JSON.stringify(GlobalAliases); this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
this.MessagesSave = JSON.stringify(Messages); this.MessagesSave = JSON.stringify(Messages);
this.StockMarketSave = JSON.stringify(StockMarket); this.StockMarketSave = JSON.stringify(StockMarket);
console.log(JSON.stringify(Settings));
this.SettingsSave = JSON.stringify(Settings); this.SettingsSave = JSON.stringify(Settings);
this.FconfSettingsSave = JSON.stringify(FconfSettings); this.FconfSettingsSave = JSON.stringify(FconfSettings);
this.VersionSave = JSON.stringify(CONSTANTS.Version); this.VersionSave = JSON.stringify(CONSTANTS.Version);

@ -18,8 +18,8 @@ export class PositionTracker {
const position = this.positions.get(filename); const position = this.positions.get(filename);
if (!position) { if (!position) {
return { return {
row: 0, row: -1,
column: 0, column: -1,
}; };
} }
return position; return position;

@ -23,6 +23,7 @@ import { libSource } from "../NetscriptDefinitions";
import { NetscriptFunctions } from "../../NetscriptFunctions"; import { NetscriptFunctions } from "../../NetscriptFunctions";
import { WorkerScript } from "../../Netscript/WorkerScript"; import { WorkerScript } from "../../Netscript/WorkerScript";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { GetServerByHostname } from "../../Server/ServerHelpers";
import { import {
iTutorialNextStep, iTutorialNextStep,
ITutorial, ITutorial,
@ -69,16 +70,33 @@ interface IProps {
// https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages // https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-custom-languages
// https://github.com/threehams/typescript-error-guide/blob/master/stories/components/Editor.tsx#L11-L39 // https://github.com/threehams/typescript-error-guide/blob/master/stories/components/Editor.tsx#L11-L39
// These variables are used to reload a script when it's clicked on. Because we
// won't have references to the old script.
let lastFilename = "";
let lastServer = "";
let lastCode = "";
let lastPosition: monaco.Position | null = null;
export function Root(props: IProps): React.ReactElement { export function Root(props: IProps): React.ReactElement {
const editorRef = useRef<IStandaloneCodeEditor | null>(null); const editorRef = useRef<IStandaloneCodeEditor | null>(null);
const [filename, setFilename] = useState(props.filename); const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
const [code, setCode] = useState<string>(props.code); const [code, setCode] = useState<string>(props.code ? props.code : lastCode);
const [ram, setRAM] = useState(''); const [ram, setRAM] = useState('RAM: ???');
const [options, setOptions] = useState<Options>({ const [options, setOptions] = useState<Options>({
theme: Settings.MonacoTheme, theme: Settings.MonacoTheme,
insertSpaces: Settings.MonacoInsertSpaces, insertSpaces: Settings.MonacoInsertSpaces,
}); });
// store the last known state in case we need to restart without nano.
useEffect(() => {
if(props.filename === "") return;
if(lastFilename === "")
lastServer = props.player.getCurrentServer().hostname;
lastFilename = props.filename;
lastCode = props.code;
lastPosition = null;
}, []);
function save(): void { function save(): void {
if(editorRef.current !== null) { if(editorRef.current !== null) {
const position = editorRef.current.getPosition(); const position = editorRef.current.getPosition();
@ -89,6 +107,7 @@ export function Root(props: IProps): React.ReactElement {
}); });
} }
} }
lastPosition = null;
// TODO(hydroflame): re-enable the tutorial. // TODO(hydroflame): re-enable the tutorial.
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) { if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
@ -103,19 +122,20 @@ export function Root(props: IProps): React.ReactElement {
} }
//Save the script //Save the script
const s = props.player.getCurrentServer(); const server = GetServerByHostname(lastServer);
for (let i = 0; i < s.scripts.length; i++) { if(server === null) throw new Error('Server should not be null but it is.');
if (filename == s.scripts[i].filename) { for (let i = 0; i < server.scripts.length; i++) {
s.scripts[i].saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts); if (filename == server.scripts[i].filename) {
server.scripts[i].saveScript(code, lastServer, server.scripts);
props.engine.loadTerminalContent(); props.engine.loadTerminalContent();
return iTutorialNextStep(); return iTutorialNextStep();
} }
} }
// If the current script does NOT exist, create a new one // If the current script does NOT exist, create a new one
let script = new Script(); const script = new Script();
script.saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts); script.saveScript(code, lastServer, server.scripts);
s.scripts.push(script); server.scripts.push(script);
return iTutorialNextStep(); return iTutorialNextStep();
} }
@ -130,7 +150,8 @@ export function Root(props: IProps): React.ReactElement {
return; return;
} }
const s = props.player.getCurrentServer(); const server = GetServerByHostname(lastServer);
if(server === null) throw new Error('Server should not be null but it is.');
if (filename === ".fconf") { if (filename === ".fconf") {
try { try {
parseFconfSettings(code); parseFconfSettings(code);
@ -140,9 +161,9 @@ export function Root(props: IProps): React.ReactElement {
} }
} else if (isScriptFilename(filename)) { } else if (isScriptFilename(filename)) {
//If the current script already exists on the server, overwrite it //If the current script already exists on the server, overwrite it
for (let i = 0; i < s.scripts.length; i++) { for (let i = 0; i < server.scripts.length; i++) {
if (filename == s.scripts[i].filename) { if (filename == server.scripts[i].filename) {
s.scripts[i].saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts); server.scripts[i].saveScript(code, lastServer, server.scripts);
props.engine.loadTerminalContent(); props.engine.loadTerminalContent();
return; return;
} }
@ -150,18 +171,18 @@ export function Root(props: IProps): React.ReactElement {
//If the current script does NOT exist, create a new one //If the current script does NOT exist, create a new one
const script = new Script(); const script = new Script();
script.saveScript(code, props.player.currentServer, props.player.getCurrentServer().scripts); script.saveScript(code, lastServer, server.scripts);
s.scripts.push(script); server.scripts.push(script);
} else if (filename.endsWith(".txt")) { } else if (filename.endsWith(".txt")) {
for (let i = 0; i < s.textFiles.length; ++i) { for (let i = 0; i < server.textFiles.length; ++i) {
if (s.textFiles[i].fn === filename) { if (server.textFiles[i].fn === filename) {
s.textFiles[i].write(code); server.textFiles[i].write(code);
props.engine.loadTerminalContent(); props.engine.loadTerminalContent();
return; return;
} }
} }
const textFile = new TextFile(filename, code); const textFile = new TextFile(filename, code);
s.textFiles.push(textFile); server.textFiles.push(textFile);
} else { } else {
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " +
" or text file (.txt)") " or text file (.txt)")
@ -179,6 +200,7 @@ export function Root(props: IProps): React.ReactElement {
} }
function onFilenameChange(event: React.ChangeEvent<HTMLInputElement>): void { function onFilenameChange(event: React.ChangeEvent<HTMLInputElement>): void {
lastFilename = filename;
setFilename(event.target.value); setFilename(event.target.value);
} }
@ -202,6 +224,10 @@ export function Root(props: IProps): React.ReactElement {
function updateCode(newCode?: string): void { function updateCode(newCode?: string): void {
if(newCode === undefined) return; if(newCode === undefined) return;
lastCode = newCode;
if(editorRef.current !== null) {
lastPosition = editorRef.current.getPosition();
}
setCode(newCode); setCode(newCode);
} }
@ -252,7 +278,10 @@ export function Root(props: IProps): React.ReactElement {
editorRef.current = editor; editorRef.current = editor;
if(editorRef.current === null) return; if(editorRef.current === null) return;
const position = CursorPositions.getCursor(filename); const position = CursorPositions.getCursor(filename);
if(position.row !== -1)
editorRef.current.setPosition({lineNumber: position.row, column: position.column}); editorRef.current.setPosition({lineNumber: position.row, column: position.column});
else if(lastPosition !== null)
editorRef.current.setPosition({lineNumber: lastPosition.lineNumber, column: lastPosition.column+1});
editorRef.current.focus(); editorRef.current.focus();
} }

@ -227,8 +227,6 @@ const Engine = {
}, },
indexedDb: undefined, indexedDb: undefined,
lastFilename: '',
lastFilenameServer: '',
// Time variables (milliseconds unix epoch time) // Time variables (milliseconds unix epoch time)
_lastUpdate: new Date().getTime(), _lastUpdate: new Date().getTime(),
@ -254,17 +252,6 @@ const Engine = {
Engine.Display.scriptEditorContent.style.display = "block"; Engine.Display.scriptEditorContent.style.display = "block";
routing.navigateTo(Page.ScriptEditor); routing.navigateTo(Page.ScriptEditor);
if(filename !== "") {
this.lastFilename = filename;
this.lastFilenameServer = Player.getCurrentServer().hostname;
} else if(this.lastFilename !== '') {
const scripts = GetServerByHostname(this.lastFilenameServer).scripts.filter(x => x.filename === this.lastFilename);
if(scripts.length === 1) {
filename = this.lastFilename;
code = scripts[0].code;
}
}
ReactDOM.render( ReactDOM.render(
<ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />, <ScriptEditorRoot filename={filename} code={code} player={Player} engine={this} />,
Engine.Display.scriptEditorContent, Engine.Display.scriptEditorContent,

@ -594,10 +594,12 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
Copy Save data to Clipboard Copy Save data to Clipboard
</button> </button>
<button id="debug-delete-scripts-link" class="a-link-button tooltip"> <button id="debug-delete-scripts-link" class="a-link-button tooltip">
Delete all active scripts Force kill all active scripts
<span class="tooltiptextleft"> <span class="tooltiptextleft">
Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the game. After Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the game. After
using this, save the game and then reload the page. using this, save the game and then reload the page. This is different then normal kill in that normal kill
will tell the script to shut down while force kill just removes the references to it (and it should crash on it's own).
This will not remove the files on your computer. Just forcefully kill all running instance of all scripts.
</span> </span>
</button> </button>
<button id="debug-soft-reset" class="a-link-button tooltip"> <button id="debug-soft-reset" class="a-link-button tooltip">

@ -71,7 +71,6 @@ function ScriptLogPopup(props: IProps): React.ReactElement {
event.preventDefault(); event.preventDefault();
let x = event.clientX; let x = event.clientX;
let y = event.clientY; let y = event.clientY;
console.log(props.container.clientWidth);
let left = props.container.offsetLeft+props.container.clientWidth/2; let left = props.container.offsetLeft+props.container.clientWidth/2;
let top = props.container.offsetTop+props.container.clientWidth/5; let top = props.container.offsetTop+props.container.clientWidth/5;
function mouseMove(event: MouseEvent): void { function mouseMove(event: MouseEvent): void {