mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 01:33:54 +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-utils": "^1.1.0",
|
||||
"memory-fs": "~0.4.1",
|
||||
"monaco-editor": "^0.27.0",
|
||||
"node-sass": "^6.0.1",
|
||||
"normalize.css": "^8.0.0",
|
||||
"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 Editor from "@monaco-editor/react";
|
||||
import * as monaco from "monaco-editor";
|
||||
import IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
import { ConfigPopup } from "./ConfigPopup";
|
||||
import { Config } from "./Config";
|
||||
@ -16,6 +18,7 @@ import { TextFile } from "../../TextFile";
|
||||
import { calculateRamUsage } from "../../Script/RamCalculations";
|
||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { CursorPositions } from "../../ScriptEditor/CursorPositions";
|
||||
|
||||
interface IProps {
|
||||
filename: string;
|
||||
@ -30,13 +33,22 @@ interface IProps {
|
||||
// https://www.npmjs.com/package/@monaco-editor/react#development-playground
|
||||
|
||||
export function Root(props: IProps): React.ReactElement {
|
||||
const editorRef = useRef<IStandaloneCodeEditor | null>(null);
|
||||
const [filename, setFilename] = useState(props.filename);
|
||||
const [code, setCode] = useState<string>(props.code);
|
||||
const [ram, setRAM] = useState('');
|
||||
const [config, setConfig] = useState<Config>({theme: 'vs-dark'});
|
||||
|
||||
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.
|
||||
// if (ITutorial.isRunning && ITutorial.currStep === iTutorialSteps.TerminalTypeScript) {
|
||||
@ -141,42 +153,46 @@ export function Root(props: IProps): React.ReactElement {
|
||||
|
||||
function updateCode(newCode?: string): void {
|
||||
if(newCode === undefined) return;
|
||||
|
||||
setCode(newCode);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
async function updateRAM() {
|
||||
const codeCopy = code.repeat(1);
|
||||
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
||||
if (ramUsage > 0) {
|
||||
console.log(ramUsage);
|
||||
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
||||
return;
|
||||
}
|
||||
switch (ramUsage) {
|
||||
case RamCalculationErrorCode.ImportError: {
|
||||
setRAM("RAM: Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.URLImportError: {
|
||||
setRAM("RAM: HTTP Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.SyntaxError:
|
||||
default: {
|
||||
setRAM("RAM: Syntax Error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Promise<void>(() => undefined);
|
||||
async function updateRAM(): Promise<void> {
|
||||
const codeCopy = code+"";
|
||||
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
||||
if (ramUsage > 0) {
|
||||
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
||||
return;
|
||||
}
|
||||
const id = setInterval(() => {
|
||||
console.log(code);
|
||||
updateRAM();
|
||||
}, 10000);
|
||||
switch (ramUsage) {
|
||||
case RamCalculationErrorCode.ImportError: {
|
||||
setRAM("RAM: Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.URLImportError: {
|
||||
setRAM("RAM: HTTP Import Error");
|
||||
break;
|
||||
}
|
||||
case RamCalculationErrorCode.SyntaxError:
|
||||
default: {
|
||||
setRAM("RAM: Syntax Error");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Promise<void>(() => undefined);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(updateRAM, 1000);
|
||||
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">
|
||||
<div id="script-editor-filename-wrapper">
|
||||
@ -185,6 +201,7 @@ export function Root(props: IProps): React.ReactElement {
|
||||
<StdButton text={"config"} onClick={openConfig} />
|
||||
</div>
|
||||
<Editor
|
||||
onMount={onMount}
|
||||
loading={<p>Loading script editor!</p>}
|
||||
height="80%"
|
||||
defaultLanguage="javascript"
|
||||
|
@ -31,111 +31,6 @@ import { compareArrays } from "../../utils/helpers/compareArrays";
|
||||
import { createElement } from "../../utils/uiHelpers/createElement";
|
||||
|
||||
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() {
|
||||
switch (Settings.Editor) {
|
||||
@ -149,43 +44,7 @@ export function getCurrentEditor() {
|
||||
}
|
||||
}
|
||||
|
||||
//Updates RAM usage in script
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(hydroflame): move to Monaco mount/unmount
|
||||
//Define key commands in script editor (ctrl o to save + close, etc.)
|
||||
$(document).keydown(function(e) {
|
||||
if (Settings.DisableHotkeys === true) {return;}
|
||||
@ -193,104 +52,11 @@ $(document).keydown(function(e) {
|
||||
//Ctrl + b
|
||||
if (e.keyCode == 66 && (e.ctrlKey || e.metaKey)) {
|
||||
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) {
|
||||
//The Player object stores the last update time from when we were online
|
||||
const thisUpdate = new Date().getTime();
|
||||
|
@ -66,11 +66,6 @@ import {
|
||||
} from "./Programs/ProgramHelpers";
|
||||
import { redPillFlag } from "./RedPill";
|
||||
import { saveObject, loadGame } from "./SaveObject";
|
||||
import {
|
||||
getCurrentEditor,
|
||||
scriptEditorInit,
|
||||
updateScriptEditorContent,
|
||||
} from "./Script/ScriptHelpers";
|
||||
import { Root as ScriptEditorRoot } from "./Monaco/ui/Root";
|
||||
import { initForeignServers, AllServers } from "./Server/AllServers";
|
||||
import { Settings } from "./Settings/Settings";
|
||||
@ -136,13 +131,6 @@ import ReactDOM from "react-dom";
|
||||
$(document).keydown(function(e) {
|
||||
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 (e.keyCode == KEY.T && e.altKey) {
|
||||
e.preventDefault();
|
||||
@ -797,13 +785,6 @@ const Engine = {
|
||||
Engine.Counters.updateDisplaysMed = 9;
|
||||
}
|
||||
|
||||
if (Engine.Counters.updateDisplaysLong <= 0) {
|
||||
if (routing.isOn(Page.ScriptEditor)) {
|
||||
updateScriptEditorContent();
|
||||
}
|
||||
Engine.Counters.updateDisplaysLong = 15;
|
||||
}
|
||||
|
||||
if (Engine.Counters.createProgramNotifications <= 0) {
|
||||
var num = getNumAvailableCreateProgram();
|
||||
var elem = document.getElementById("create-program-notification");
|
||||
@ -1207,7 +1188,6 @@ const Engine = {
|
||||
}
|
||||
// Initialize labels on game settings
|
||||
setSettingsLabels();
|
||||
scriptEditorInit();
|
||||
Terminal.resetTerminalInput();
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user