Cleanup + lint/format

This commit is contained in:
Zoë Hoekstra 2022-08-10 23:22:03 +02:00
parent 2628dc1ae8
commit 88d8f13847
No known key found for this signature in database
GPG Key ID: F9B7B7D8130F3323
7 changed files with 235 additions and 237 deletions

@ -17,30 +17,25 @@ export class ConnectionBauble extends React.Component<baubleProps> {
super(props);
this.state = {
connection: props.callback(),
callback: props.callback
callback: props.callback,
};
}
componentDidMount() : void {
this.timerID = setInterval(
() => this.tick(),
1000
);
componentDidMount(): void {
this.timerID = setInterval(() => this.tick(), 1000);
}
componentWillUnmount() : void {
componentWillUnmount(): void {
clearInterval(this.timerID);
}
tick() : void {
tick(): void {
this.setState({
connection: this.state.callback()
connection: this.state.callback(),
});
}
render() : string {
return (
this.state.connection? "Connected" : "Disconnected"
);
render(): string {
return this.state.connection ? "Connected" : "Disconnected";
}
}

@ -370,27 +370,26 @@ export const CurrentOptionsPage = (props: IProps): React.ReactElement => {
</>
}
/>
<Tooltip title={
<Tooltip
title={
<Typography>
This port number is used to connect to a Remote File API port,
please ensure that it matches with the port the Remote File API server is publishing on (12525 by default).
Click the reconnect button to try and re-establish connection.
The little colored bauble shows whether the connection is live or not.
This port number is used to connect to a Remote File API port, please ensure that it matches with the port
the Remote File API server is publishing on (12525 by default). Click the reconnect button to try and
re-establish connection. The little colored bauble shows whether the connection is live or not.
</Typography>
}>
}
>
<TextField
InputProps={{
startAdornment: (
<Typography
color={remoteFileApiPort > 0 && remoteFileApiPort <= 65535? "success" : "error"}
>
<Typography color={remoteFileApiPort > 0 && remoteFileApiPort <= 65535 ? "success" : "error"}>
Remote File API port:
</Typography>
),
endAdornment: (
<Box>
<Button onClick={newRemoteFileApiConnection}>Reconnect</Button>
<ConnectionBauble callback={isRemoteFileApiConnectionLive}/>
<ConnectionBauble callback={isRemoteFileApiConnectionLive} />
</Box>
),
}}

@ -1,12 +1,12 @@
export class RFAMessage {
jsonrpc = "2.0"; // Transmits version of JSON-RPC. Compliance maybe allows some funky interaction with external tools?
public method?:string; // Is defined when it's a request/notification, otherwise undefined
public result?:string; // Is defined when it's a response, otherwise undefined
public params?:FileMetadata; // Optional parameters to method
public error? :string; // Only defined on error
public id? :number; // ID to keep track of request -> response interaction, undefined with notifications, defined with request/response
public method?: string; // Is defined when it's a request/notification, otherwise undefined
public result?: string; // Is defined when it's a response, otherwise undefined
public params?: FileMetadata; // Optional parameters to method
public error?: string; // Only defined on error
public id?: number; // ID to keep track of request -> response interaction, undefined with notifications, defined with request/response
constructor(obj: { method?: string; result?: string; params?: FileMetadata; error?: string; id?: number } = {}){
constructor(obj: { method?: string; result?: string; params?: FileMetadata; error?: string; id?: number } = {}) {
this.method = obj.method;
this.result = obj.result;
this.params = obj.params;
@ -15,10 +15,7 @@ export class RFAMessage {
}
}
type FileMetadata = FileData
| FileContent
| FileLocation
| FileServer;
type FileMetadata = FileData | FileContent | FileLocation | FileServer;
export interface FileData {
filename: string;
@ -41,25 +38,21 @@ export interface FileServer {
}
export function isFileData(p: unknown): p is FileData {
const pf = p as FileData
return typeof pf.server === 'string' &&
typeof pf.filename === 'string' &&
typeof pf.content === 'string'
const pf = p as FileData;
return typeof pf.server === "string" && typeof pf.filename === "string" && typeof pf.content === "string";
}
export function isFileLocation(p: unknown): p is FileLocation {
const pf = p as FileLocation
return typeof pf.server === 'string' &&
typeof pf.filename === 'string'
const pf = p as FileLocation;
return typeof pf.server === "string" && typeof pf.filename === "string";
}
export function isFileContent(p: unknown): p is FileContent {
const pf = p as FileContent
return typeof pf.filename === 'string' &&
typeof pf.content === 'string'
const pf = p as FileContent;
return typeof pf.filename === "string" && typeof pf.content === "string";
}
export function isFileServer(p: unknown): p is FileServer {
const pf = p as FileServer
return typeof pf.server === 'string'
const pf = p as FileServer;
return typeof pf.server === "string";
}

@ -3,35 +3,42 @@ import { isScriptFilename } from "../Script/isScriptFilename";
import { GetServer } from "../Server/AllServers";
import { isValidFilePath } from "../Terminal/DirectoryHelpers";
import { TextFile } from "../TextFile";
import { RFAMessage, FileData, FileContent, isFileServer, isFileLocation, FileLocation, isFileData } from "./MessageDefinitions";
import {
RFAMessage,
FileData,
FileContent,
isFileServer,
isFileLocation,
FileLocation,
isFileData,
} from "./MessageDefinitions";
//@ts-ignore: Complaint of import ending with .d.ts
import libSource from "!!raw-loader!../ScriptEditor/NetscriptDefinitions.d.ts";
import { RFALogger } from "./RFALogger";
function error(errorMsg: string, { id }: RFAMessage): RFAMessage {
console.error("[RFA-ERROR]" + (typeof (id) === "undefined" ? "" : `Request ${id}: `) + errorMsg);
RFALogger.error((typeof id === "undefined" ? "" : `Request ${id}: `) + errorMsg);
return new RFAMessage({ error: errorMsg, id: id });
}
export const RFARequestHandler: Record<string, (message: RFAMessage) => void | RFAMessage> = {
pushFile: function (msg: RFAMessage): RFAMessage {
if (!isFileData(msg.params)) return error("pushFile message misses parameters", msg);
if (!isFileData(msg.params)) return error("Misses parameters", msg);
const fileData: FileData = msg.params;
if (!isValidFilePath(fileData.filename)) return error("pushFile with an invalid filename", msg);
if (!isValidFilePath(fileData.filename)) return error("Invalid filename", msg);
const server = GetServer(fileData.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
if (isScriptFilename(fileData.filename))
server.writeToScriptFile(Player, fileData.filename, fileData.content);
else // Assume it's a text file
server.writeToTextFile(fileData.filename, fileData.content);
if (isScriptFilename(fileData.filename)) server.writeToScriptFile(Player, fileData.filename, fileData.content);
// Assume it's a text file
else server.writeToTextFile(fileData.filename, fileData.content);
// If and only if the content is actually changed correctly, send back an OK.
const savedCorrectly = server.getScript(fileData.filename)?.code === fileData.content
|| server.textFiles.filter((t: TextFile) => t.filename == fileData.filename).at(0)?.text === fileData.content;
const savedCorrectly =
server.getScript(fileData.filename)?.code === fileData.content ||
server.textFiles.filter((t: TextFile) => t.filename == fileData.filename).at(0)?.text === fileData.content;
if (!savedCorrectly) return error("File wasn't saved correctly", msg);
@ -39,91 +46,95 @@ export const RFARequestHandler: Record<string, (message: RFAMessage) => void | R
},
getFile: function (msg: RFAMessage): RFAMessage {
if (!isFileLocation(msg.params)) return error("getFile message misses parameters", msg);
if (!isFileLocation(msg.params)) return error("Message misses parameters", msg);
const fileData: FileLocation = msg.params;
if (!isValidFilePath(fileData.filename)) return error("getFile with an invalid filename", msg);
if (!isValidFilePath(fileData.filename)) return error("Invalid filename", msg);
const server = GetServer(fileData.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
if (isScriptFilename(fileData.filename)) {
const scriptContent = server.getScript(fileData.filename);
if (!scriptContent) return error("Requested script doesn't exist", msg);
if (!scriptContent) return error("File doesn't exist", msg);
return new RFAMessage({ result: scriptContent.code, id: msg.id });
}
else { // Assume it's a text file
} else {
// Assume it's a text file
const file = server.textFiles.filter((t: TextFile) => t.filename == fileData.filename).at(0);
if (file === undefined) return error("Requested textfile doesn't exist", msg);
if (!file) return error("File doesn't exist", msg);
return new RFAMessage({ result: file.text, id: msg.id });
}
},
deleteFile: function (msg: RFAMessage): RFAMessage {
if (!isFileLocation(msg.params)) return error("deleteFile message misses parameters", msg);
if (!isFileLocation(msg.params)) return error("Message misses parameters", msg);
const fileData: FileLocation = msg.params;
if (!isValidFilePath(fileData.filename)) return error("deleteFile with an invalid filename", msg);
if (!isValidFilePath(fileData.filename)) return error("Invalid filename", msg);
const server = GetServer(fileData.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
const fileExists = (): boolean => !!server.getScript(fileData.filename)
|| server.textFiles.some((t: TextFile) => t.filename === fileData.filename);
const fileExists = (): boolean =>
!!server.getScript(fileData.filename) || server.textFiles.some((t: TextFile) => t.filename === fileData.filename);
if (!fileExists()) return error("deleteFile file doesn't exist", msg);
if (!fileExists()) return error("File doesn't exist", msg);
server.removeFile(fileData.filename);
if (fileExists()) return error("deleteFile failed to delete the file", msg);
if (fileExists()) return error("Failed to delete the file", msg);
return new RFAMessage({ result: "OK", id: msg.id });
},
getFileNames: function (msg: RFAMessage): RFAMessage {
if (!isFileServer(msg.params)) return error("getFileNames message misses parameters", msg);
if (!isFileServer(msg.params)) return error("Message misses parameters", msg);
const server = GetServer(msg.params.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
const fileNameList: string[] = [
...server.textFiles.map((txt): string => txt.filename),
...server.scripts.map((scr): string => scr.filename)
...server.scripts.map((scr): string => scr.filename),
];
return new RFAMessage({ result: JSON.stringify(fileNameList), id: msg.id });
},
getAllFiles: function (msg: RFAMessage): RFAMessage {
if (!isFileServer(msg.params)) return error("getAllFiles message misses parameters", msg);
if (!isFileServer(msg.params)) return error("Message misses parameters", msg);
const server = GetServer(msg.params.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
const fileList: FileContent[] = [
...server.textFiles.map((txt): FileContent => { return { filename: txt.filename, content: txt.text } }),
...server.scripts.map((scr): FileContent => { return { filename: scr.filename, content: scr.code } })
...server.textFiles.map((txt): FileContent => {
return { filename: txt.filename, content: txt.text };
}),
...server.scripts.map((scr): FileContent => {
return { filename: scr.filename, content: scr.code };
}),
];
return new RFAMessage({ result: JSON.stringify(fileList), id: msg.id });
},
calculateRam: function (msg: RFAMessage): RFAMessage {
if (!isFileLocation(msg.params)) return error("calculateRam message misses parameters", msg);
if (!isFileLocation(msg.params)) return error("Message misses parameters", msg);
const fileData: FileLocation = msg.params;
if (!isValidFilePath(fileData.filename)) return error("deleteFile with an invalid filename", msg);
if (!isValidFilePath(fileData.filename)) return error("Invalid filename", msg);
const server = GetServer(fileData.server);
if (server == null) return error("Server hostname invalid", msg);
if (!server) return error("Server hostname invalid", msg);
if (!isScriptFilename(fileData.filename)) return error("Filename isn't a script filename", msg);
const script = server.getScript(fileData.filename);
if (!script) return error("File doesn't exist", msg);
const ramUsage = script.ramUsage;
return new RFAMessage({result: String(ramUsage), id: msg.id});
return new RFAMessage({ result: String(ramUsage), id: msg.id });
},
getDefinitionFile: function (msg: RFAMessage): RFAMessage {
const source = (libSource + "").replace(/export /g, "");
console.log(source);
return new RFAMessage({result: source, id: msg.id});
}
}
return new RFAMessage({ result: source, id: msg.id });
},
};

@ -3,23 +3,23 @@ class RemoteFileAPILogger {
_prefix = "[RFA]";
_error_prefix = "[RFA-ERROR]";
constructor(enabled: boolean){
constructor(enabled: boolean) {
this._enabled = enabled;
}
public error(...message: any[]) : void {
public error(...message: any[]): void {
if (this._enabled) console.error(this._error_prefix, ...message);
}
public log(...message: any[]) : void {
public log(...message: any[]): void {
if (this._enabled) console.log(this._prefix, ...message);
}
public disable() : void {
public disable(): void {
this._enabled = false;
}
public enable() : void {
public enable(): void {
this._enabled = true;
}
}

@ -1,47 +1,49 @@
import { RFALogger } from "./RFALogger";
import { RFAMessage } from "./MessageDefinitions"
import { RFAMessage } from "./MessageDefinitions";
import { RFARequestHandler } from "./MessageHandlers";
export class Remote {
connection? : WebSocket;
connection?: WebSocket;
protocol = "ws";
ipaddr: string;
port: number;
constructor(ip : string, port : number) {
constructor(ip: string, port: number) {
this.ipaddr = ip;
this.port = port;
}
public stopConnection() : void {
public stopConnection(): void {
this.connection?.close();
}
public startConnection() : void {
public startConnection(): void {
RFALogger.log("Trying to connect.");
this.connection = new WebSocket(this.protocol + "://" + this.ipaddr + ":" + this.port);
this.connection.addEventListener("error", (e:Event) => RFALogger.error(e));
this.connection.addEventListener("error", (e: Event) => RFALogger.error(e));
this.connection.addEventListener("message", handleMessageEvent);
this.connection.addEventListener("open", () => RFALogger.log("Connection established: ", this.ipaddr, ":", this.port));
this.connection.addEventListener("open", () =>
RFALogger.log("Connection established: ", this.ipaddr, ":", this.port),
);
this.connection.addEventListener("close", () => RFALogger.log("Connection closed"));
}
}
function handleMessageEvent(e: MessageEvent):void {
const msg : RFAMessage = JSON.parse(e.data);
function handleMessageEvent(this: WebSocket, e: MessageEvent): void {
const msg: RFAMessage = JSON.parse(e.data);
RFALogger.log("Message received:", msg);
//TODO: Needs more safety, send error on invalid input, send error when msg.method isn´t in handlers, ...
if (msg.method)
{
if (msg.method) {
if (!RFARequestHandler[msg.method]) {
const response = new RFAMessage({ error: "Unknown message received", id: msg.id });
this.send(JSON.stringify(response));
return;
}
const response = RFARequestHandler[msg.method](msg);
RFALogger.log("Sending response: ", response);
if(response) this.send(JSON.stringify(response));
}
else if (msg.result) RFALogger.error("Result handling not implemented yet.");
if (response) this.send(JSON.stringify(response));
} else if (msg.result) RFALogger.log("Somehow retrieved a result message.");
else if (msg.error) RFALogger.error("Received an error from server", msg);
else RFALogger.error("Incorrect Message", msg);
}

@ -1,21 +1,19 @@
import { Settings } from "../Settings/Settings";
import { Remote } from "./Remote";
let server: Remote;
export function newRemoteFileApiConnection() : void {
if(server == undefined) {
export function newRemoteFileApiConnection(): void {
if (server == undefined) {
server = new Remote("localhost", Settings.RemoteFileApiPort);
server.startConnection();
}
else {
} else {
server.stopConnection();
server = new Remote("localhost", Settings.RemoteFileApiPort);
server.startConnection();
}
}
export function isRemoteFileApiConnectionLive() : boolean {
export function isRemoteFileApiConnectionLive(): boolean {
return server.connection != undefined && server.connection.readyState == 1;
}