mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 20:25:45 +01:00
focus works
This commit is contained in:
parent
73ec97db87
commit
258716388e
1602
package-lock.json
generated
1602
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -35,6 +35,7 @@
|
|||||||
"loader-runner": "^2.3.0",
|
"loader-runner": "^2.3.0",
|
||||||
"loader-utils": "^1.1.0",
|
"loader-utils": "^1.1.0",
|
||||||
"memory-fs": "~0.4.1",
|
"memory-fs": "~0.4.1",
|
||||||
|
"monaco-editor": "^0.27.0",
|
||||||
"node-sass": "^6.0.1",
|
"node-sass": "^6.0.1",
|
||||||
"normalize.css": "^8.0.0",
|
"normalize.css": "^8.0.0",
|
||||||
"numeral": "2.0.6",
|
"numeral": "2.0.6",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
import Editor from "@monaco-editor/react";
|
import Editor from "@monaco-editor/react";
|
||||||
|
import * as monaco from "monaco-editor";
|
||||||
|
import IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
||||||
import { createPopup } from "../../ui/React/createPopup";
|
import { createPopup } from "../../ui/React/createPopup";
|
||||||
import { ConfigPopup } from "./ConfigPopup";
|
import { ConfigPopup } from "./ConfigPopup";
|
||||||
import { Config } from "./Config";
|
import { Config } from "./Config";
|
||||||
@ -16,6 +18,7 @@ import { TextFile } from "../../TextFile";
|
|||||||
import { calculateRamUsage } from "../../Script/RamCalculations";
|
import { calculateRamUsage } from "../../Script/RamCalculations";
|
||||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { CursorPositions } from "../../ScriptEditor/CursorPositions";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
filename: string;
|
filename: string;
|
||||||
@ -30,13 +33,22 @@ interface IProps {
|
|||||||
// https://www.npmjs.com/package/@monaco-editor/react#development-playground
|
// https://www.npmjs.com/package/@monaco-editor/react#development-playground
|
||||||
|
|
||||||
export function Root(props: IProps): React.ReactElement {
|
export function Root(props: IProps): React.ReactElement {
|
||||||
|
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
||||||
const [filename, setFilename] = useState(props.filename);
|
const [filename, setFilename] = useState(props.filename);
|
||||||
const [code, setCode] = useState<string>(props.code);
|
const [code, setCode] = useState<string>(props.code);
|
||||||
const [ram, setRAM] = useState('');
|
const [ram, setRAM] = useState('');
|
||||||
const [config, setConfig] = useState<Config>({theme: 'vs-dark'});
|
const [config, setConfig] = useState<Config>({theme: 'vs-dark'});
|
||||||
|
|
||||||
function save(): void {
|
function save(): void {
|
||||||
//CursorPositions.saveCursor(filename, cursor);
|
if(editorRef.current !== null) {
|
||||||
|
const position = editorRef.current.getPosition();
|
||||||
|
if(position !== null) {
|
||||||
|
CursorPositions.saveCursor(filename, {
|
||||||
|
row: position.lineNumber,
|
||||||
|
column: position.column,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -141,16 +153,13 @@ 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;
|
||||||
|
|
||||||
setCode(newCode);
|
setCode(newCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
async function updateRAM(): Promise<void> {
|
||||||
async function updateRAM() {
|
const codeCopy = code+"";
|
||||||
const codeCopy = code.repeat(1);
|
|
||||||
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
||||||
if (ramUsage > 0) {
|
if (ramUsage > 0) {
|
||||||
console.log(ramUsage);
|
|
||||||
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -171,12 +180,19 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
return new Promise<void>(() => undefined);
|
return new Promise<void>(() => undefined);
|
||||||
}
|
}
|
||||||
const id = setInterval(() => {
|
|
||||||
console.log(code);
|
useEffect(() => {
|
||||||
updateRAM();
|
const id = setInterval(updateRAM, 1000);
|
||||||
}, 10000);
|
|
||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, []);
|
}, [code]);
|
||||||
|
|
||||||
|
function onMount(editor: IStandaloneCodeEditor): void {
|
||||||
|
editorRef.current = editor;
|
||||||
|
if(editorRef.current === null) return;
|
||||||
|
const position = CursorPositions.getCursor(filename);
|
||||||
|
editorRef.current.setPosition({lineNumber: position.row, column: position.column});
|
||||||
|
editorRef.current.focus();
|
||||||
|
}
|
||||||
|
|
||||||
return (<div id="script-editor-wrapper">
|
return (<div id="script-editor-wrapper">
|
||||||
<div id="script-editor-filename-wrapper">
|
<div id="script-editor-filename-wrapper">
|
||||||
@ -185,6 +201,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
<StdButton text={"config"} onClick={openConfig} />
|
<StdButton text={"config"} onClick={openConfig} />
|
||||||
</div>
|
</div>
|
||||||
<Editor
|
<Editor
|
||||||
|
onMount={onMount}
|
||||||
loading={<p>Loading script editor!</p>}
|
loading={<p>Loading script editor!</p>}
|
||||||
height="80%"
|
height="80%"
|
||||||
defaultLanguage="javascript"
|
defaultLanguage="javascript"
|
||||||
|
@ -31,111 +31,6 @@ import { compareArrays } from "../../utils/helpers/compareArrays";
|
|||||||
import { createElement } from "../../utils/uiHelpers/createElement";
|
import { createElement } from "../../utils/uiHelpers/createElement";
|
||||||
|
|
||||||
var scriptEditorRamText = null;
|
var scriptEditorRamText = null;
|
||||||
export function scriptEditorInit() {
|
|
||||||
// Wrapper container that holds all the buttons below the script editor
|
|
||||||
const wrapper = document.getElementById("script-editor-buttons-wrapper");
|
|
||||||
if (wrapper == null) {
|
|
||||||
console.error("Could not find 'script-editor-buttons-wrapper'");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Beautify button
|
|
||||||
const beautifyButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "inline-block",
|
|
||||||
innerText: "Beautify",
|
|
||||||
clickListener:()=>{
|
|
||||||
let editor = getCurrentEditor();
|
|
||||||
if (editor != null) {
|
|
||||||
editor.beautifyScript();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Text that displays RAM calculation
|
|
||||||
scriptEditorRamText = createElement("p", {
|
|
||||||
display:"inline-block", margin:"10px", id:"script-editor-status-text",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Link to Netscript documentation
|
|
||||||
const documentationButton = createElement("a", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "inline-block",
|
|
||||||
href:"https://bitburner.readthedocs.io/en/latest/index.html",
|
|
||||||
innerText:"Netscript Documentation",
|
|
||||||
target:"_blank",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save and Close button
|
|
||||||
const closeButton = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
display: "inline-block",
|
|
||||||
innerText: "Save & Close (Ctrl/Cmd + b)",
|
|
||||||
clickListener:()=>{
|
|
||||||
saveAndCloseScriptEditor();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add all buttons to the UI
|
|
||||||
wrapper.appendChild(beautifyButton);
|
|
||||||
wrapper.appendChild(closeButton);
|
|
||||||
wrapper.appendChild(scriptEditorRamText);
|
|
||||||
wrapper.appendChild(documentationButton);
|
|
||||||
|
|
||||||
// Initialize editors
|
|
||||||
const initParams = {
|
|
||||||
saveAndCloseFn: saveAndCloseScriptEditor,
|
|
||||||
quitFn: Engine.loadTerminalContent,
|
|
||||||
}
|
|
||||||
|
|
||||||
AceEditor.init(initParams);
|
|
||||||
CodeMirrorEditor.init(initParams);
|
|
||||||
|
|
||||||
// Setup the selector for which Editor to use
|
|
||||||
const editorSelector = document.getElementById("script-editor-option-editor");
|
|
||||||
if (editorSelector == null) {
|
|
||||||
console.error(`Could not find DOM Element for editor selector (id=script-editor-option-editor)`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < editorSelector.options.length; ++i) {
|
|
||||||
if (editorSelector.options[i].value === Settings.Editor) {
|
|
||||||
editorSelector.selectedIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
editorSelector.onchange = () => {
|
|
||||||
const opt = editorSelector.value;
|
|
||||||
switch (opt) {
|
|
||||||
case EditorSetting.Ace: {
|
|
||||||
const codeMirrorCode = CodeMirrorEditor.getCode();
|
|
||||||
const codeMirrorFn = CodeMirrorEditor.getFilename();
|
|
||||||
AceEditor.create();
|
|
||||||
CodeMirrorEditor.setInvisible();
|
|
||||||
AceEditor.openScript(codeMirrorFn, codeMirrorCode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EditorSetting.CodeMirror: {
|
|
||||||
const aceCode = AceEditor.getCode();
|
|
||||||
const aceFn = AceEditor.getFilename();
|
|
||||||
CodeMirrorEditor.create();
|
|
||||||
AceEditor.setInvisible();
|
|
||||||
CodeMirrorEditor.openScript(aceFn, aceCode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
console.error(`Unrecognized Editor Setting: ${opt}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Editor = opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
editorSelector.onchange(); // Trigger the onchange event handler
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getCurrentEditor() {
|
export function getCurrentEditor() {
|
||||||
switch (Settings.Editor) {
|
switch (Settings.Editor) {
|
||||||
@ -149,43 +44,7 @@ export function getCurrentEditor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Updates RAM usage in script
|
// TODO(hydroflame): move to Monaco mount/unmount
|
||||||
export async function updateScriptEditorContent() {
|
|
||||||
var filename = document.getElementById("script-editor-filename").value;
|
|
||||||
if (!isScriptFilename(filename)) {
|
|
||||||
scriptEditorRamText.innerText = "RAM: N/A";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let code;
|
|
||||||
try {
|
|
||||||
code = getCurrentEditor().getCode();
|
|
||||||
} catch(e) {
|
|
||||||
scriptEditorRamText.innerText = "RAM: ERROR";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var codeCopy = code.repeat(1);
|
|
||||||
var ramUsage = await calculateRamUsage(codeCopy, Player.getCurrentServer().scripts);
|
|
||||||
if (ramUsage > 0) {
|
|
||||||
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.formatRAM(ramUsage);
|
|
||||||
} else {
|
|
||||||
switch (ramUsage) {
|
|
||||||
case RamCalculationErrorCode.ImportError:
|
|
||||||
scriptEditorRamText.innerText = "RAM: Import Error";
|
|
||||||
break;
|
|
||||||
case RamCalculationErrorCode.URLImportError:
|
|
||||||
scriptEditorRamText.innerText = "RAM: HTTP Import Error";
|
|
||||||
break;
|
|
||||||
case RamCalculationErrorCode.SyntaxError:
|
|
||||||
default:
|
|
||||||
scriptEditorRamText.innerText = "RAM: Syntax Error";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Define key commands in script editor (ctrl o to save + close, etc.)
|
//Define key commands in script editor (ctrl o to save + close, etc.)
|
||||||
$(document).keydown(function(e) {
|
$(document).keydown(function(e) {
|
||||||
if (Settings.DisableHotkeys === true) {return;}
|
if (Settings.DisableHotkeys === true) {return;}
|
||||||
@ -193,104 +52,11 @@ $(document).keydown(function(e) {
|
|||||||
//Ctrl + b
|
//Ctrl + b
|
||||||
if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
|
if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
saveAndCloseScriptEditor();
|
saveAndCloseScriptEditor(); // deleted function
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function saveAndCloseScriptEditor() {
|
|
||||||
var filename = document.getElementById("script-editor-filename").value;
|
|
||||||
|
|
||||||
let code, cursor;
|
|
||||||
try {
|
|
||||||
code = getCurrentEditor().getCode();
|
|
||||||
cursor = getCurrentEditor().getCursor();
|
|
||||||
CursorPositions.saveCursor(filename, cursor);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate("Something went wrong when trying to save (getCurrentEditor().getCode() or getCurrentEditor().getCursor()). Please report to game developer with details");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
|
||||||
//Make sure filename + code properly follow tutorial
|
|
||||||
if (filename !== "n00dles.script") {
|
|
||||||
dialogBoxCreate("Leave the script name as 'n00dles'!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
code = code.replace(/\s/g, "");
|
|
||||||
if (code.indexOf("while(true){hack('n00dles');}") == -1) {
|
|
||||||
dialogBoxCreate("Please copy and paste the code from the tutorial!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Save the script
|
|
||||||
let s = Player.getCurrentServer();
|
|
||||||
for (var i = 0; i < s.scripts.length; i++) {
|
|
||||||
if (filename == s.scripts[i].filename) {
|
|
||||||
s.scripts[i].saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
return iTutorialNextStep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the current script does NOT exist, create a new one
|
|
||||||
let script = new Script();
|
|
||||||
script.saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
|
||||||
s.scripts.push(script);
|
|
||||||
|
|
||||||
return iTutorialNextStep();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename == "") {
|
|
||||||
dialogBoxCreate("You must specify a filename!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filename !== ".fconf" && !isValidFilePath(filename)) {
|
|
||||||
dialogBoxCreate("Script filename can contain only alphanumerics, hyphens, and underscores, and must end with an extension.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var s = Player.getCurrentServer();
|
|
||||||
if (filename === ".fconf") {
|
|
||||||
try {
|
|
||||||
parseFconfSettings(code);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate(`Invalid .fconf file: ${e}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (isScriptFilename(filename)) {
|
|
||||||
//If the current script already exists on the server, overwrite it
|
|
||||||
for (let i = 0; i < s.scripts.length; i++) {
|
|
||||||
if (filename == s.scripts[i].filename) {
|
|
||||||
s.scripts[i].saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If the current script does NOT exist, create a new one
|
|
||||||
const script = new Script();
|
|
||||||
script.saveScript(getCurrentEditor().getCode(), Player.currentServer, Player.getCurrentServer().scripts);
|
|
||||||
s.scripts.push(script);
|
|
||||||
} else if (filename.endsWith(".txt")) {
|
|
||||||
for (let i = 0; i < s.textFiles.length; ++i) {
|
|
||||||
if (s.textFiles[i].fn === filename) {
|
|
||||||
s.textFiles[i].write(code);
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const textFile = new TextFile(filename, code);
|
|
||||||
s.textFiles.push(textFile);
|
|
||||||
} else {
|
|
||||||
dialogBoxCreate("Invalid filename. Must be either a script (.script) or " +
|
|
||||||
" or text file (.txt)")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Engine.loadTerminalContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function scriptCalculateOfflineProduction(runningScriptObj) {
|
export function scriptCalculateOfflineProduction(runningScriptObj) {
|
||||||
//The Player object stores the last update time from when we were online
|
//The Player object stores the last update time from when we were online
|
||||||
const thisUpdate = new Date().getTime();
|
const thisUpdate = new Date().getTime();
|
||||||
|
@ -66,11 +66,6 @@ import {
|
|||||||
} from "./Programs/ProgramHelpers";
|
} from "./Programs/ProgramHelpers";
|
||||||
import { redPillFlag } from "./RedPill";
|
import { redPillFlag } from "./RedPill";
|
||||||
import { saveObject, loadGame } from "./SaveObject";
|
import { saveObject, loadGame } from "./SaveObject";
|
||||||
import {
|
|
||||||
getCurrentEditor,
|
|
||||||
scriptEditorInit,
|
|
||||||
updateScriptEditorContent,
|
|
||||||
} from "./Script/ScriptHelpers";
|
|
||||||
import { Root as ScriptEditorRoot } from "./Monaco/ui/Root";
|
import { Root as ScriptEditorRoot } from "./Monaco/ui/Root";
|
||||||
import { initForeignServers, AllServers } from "./Server/AllServers";
|
import { initForeignServers, AllServers } from "./Server/AllServers";
|
||||||
import { Settings } from "./Settings/Settings";
|
import { Settings } from "./Settings/Settings";
|
||||||
@ -136,13 +131,6 @@ import ReactDOM from "react-dom";
|
|||||||
$(document).keydown(function(e) {
|
$(document).keydown(function(e) {
|
||||||
if (Settings.DisableHotkeys === true) {return;}
|
if (Settings.DisableHotkeys === true) {return;}
|
||||||
|
|
||||||
// These hotkeys should be disabled if the player is writing scripts
|
|
||||||
try {
|
|
||||||
if (getCurrentEditor().isFocused()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch(error) {}
|
|
||||||
|
|
||||||
if (!Player.isWorking && !redPillFlag && !inMission && !cinematicTextFlag) {
|
if (!Player.isWorking && !redPillFlag && !inMission && !cinematicTextFlag) {
|
||||||
if (e.keyCode == KEY.T && e.altKey) {
|
if (e.keyCode == KEY.T && e.altKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -797,13 +785,6 @@ const Engine = {
|
|||||||
Engine.Counters.updateDisplaysMed = 9;
|
Engine.Counters.updateDisplaysMed = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Engine.Counters.updateDisplaysLong <= 0) {
|
|
||||||
if (routing.isOn(Page.ScriptEditor)) {
|
|
||||||
updateScriptEditorContent();
|
|
||||||
}
|
|
||||||
Engine.Counters.updateDisplaysLong = 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Engine.Counters.createProgramNotifications <= 0) {
|
if (Engine.Counters.createProgramNotifications <= 0) {
|
||||||
var num = getNumAvailableCreateProgram();
|
var num = getNumAvailableCreateProgram();
|
||||||
var elem = document.getElementById("create-program-notification");
|
var elem = document.getElementById("create-program-notification");
|
||||||
@ -1207,7 +1188,6 @@ const Engine = {
|
|||||||
}
|
}
|
||||||
// Initialize labels on game settings
|
// Initialize labels on game settings
|
||||||
setSettingsLabels();
|
setSettingsLabels();
|
||||||
scriptEditorInit();
|
|
||||||
Terminal.resetTerminalInput();
|
Terminal.resetTerminalInput();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user