Initial version

This commit is contained in:
Zoë Hoekstra 2022-08-23 20:00:48 +02:00
parent 0b660d01bd
commit 7c571687bf
No known key found for this signature in database
GPG key ID: F9B7B7D8130F3323
8 changed files with 221 additions and 0 deletions

69
package-lock.json generated Normal file
View file

@ -0,0 +1,69 @@
{
"name": "bitburner-remote",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bitburner-remote",
"version": "1.0.0",
"license": "Unlicense",
"dependencies": {
"cheap-watch": "^1.0.4",
"signal-js": "^3.0.1",
"ws": "^8.8.1"
}
},
"node_modules/cheap-watch": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cheap-watch/-/cheap-watch-1.0.4.tgz",
"integrity": "sha512-QR/9FrtRL5fjfUJBhAKCdi0lSRQ3rVRRum3GF9wDKp2TJbEIMGhUEr2yU8lORzm9Isdjx7/k9S0DFDx+z5VGtw==",
"engines": {
"node": ">=8"
}
},
"node_modules/signal-js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/signal-js/-/signal-js-3.0.1.tgz",
"integrity": "sha512-etMzOR3k2GT8I2AoBUzYHuJ3QipKARXkuM1KxbcOGjgpuGyaXVXWPn61Aezsei9FL34DdfHISMbIu2wZYlIw9w=="
},
"node_modules/ws": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
},
"dependencies": {
"cheap-watch": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cheap-watch/-/cheap-watch-1.0.4.tgz",
"integrity": "sha512-QR/9FrtRL5fjfUJBhAKCdi0lSRQ3rVRRum3GF9wDKp2TJbEIMGhUEr2yU8lORzm9Isdjx7/k9S0DFDx+z5VGtw=="
},
"signal-js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/signal-js/-/signal-js-3.0.1.tgz",
"integrity": "sha512-etMzOR3k2GT8I2AoBUzYHuJ3QipKARXkuM1KxbcOGjgpuGyaXVXWPn61Aezsei9FL34DdfHISMbIu2wZYlIw9w=="
},
"ws": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz",
"integrity": "sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==",
"requires": {}
}
}
}

31
package.json Normal file
View file

@ -0,0 +1,31 @@
{
"name": "bitburner-remote",
"version": "1.0.0",
"description": "Official implementation of the Bitburner Remote Server",
"type": "module",
"main": "src/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node src/index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Hoekstraa/bitburner-remote.git"
},
"keywords": [
"bitburner",
"rfa",
"remote"
],
"author": "Zoë Hoekstra",
"license": "Unlicense",
"bugs": {
"url": "https://github.com/Hoekstraa/bitburner-remote/issues"
},
"homepage": "https://github.com/Hoekstraa/bitburner-remote#readme",
"dependencies": {
"cheap-watch": "^1.0.4",
"signal-js": "^3.0.1",
"ws": "^8.8.1"
}
}

23
src/fileWatch.js Normal file
View file

@ -0,0 +1,23 @@
import CheapWatch from "cheap-watch";
import * as settings from "./settings.js";
function fileFilter(event) {
if(settings.allowedFiletypes.some(extension => event.path.endsWith(extension)))
return true;
}
export async function setupWatch(signaller) {
const watch = new CheapWatch({
dir: settings.scriptsFolder,
filter: fileFilter
});
watch.on('+', fileEvent => signaller.emit(EventType.FileChanged, fileEvent));
watch.on('-', fileEvent => signaller.emit(EventType.FileDeleted, fileEvent));
// Wait 'till filewatcher is ready to go
await watch.init();
return watch;
}

29
src/index.js Normal file
View file

@ -0,0 +1,29 @@
"use strict"
import { setupWatch } from "./fileWatch.js";
import * as settings from "./settings.js";
import { setupSocket } from "./webSocket.js";
import signal from "signal-js";
import { fileChangeEventToMsg, fileRemovalEventToMsg, requestDefinitionFile } from "./messageGenerators.js";
const watch = await setupWatch(signal);
const socket = setupSocket(signal);
signal.on("fileChange", fileEvent => {
console.log(fileEvent.path + " changed");
signal.emit(EventType.SendMessage, fileChangeEventToMsg(fileEvent))
});
if(settings.allowDeletingFiles)
signal.on("fileDeletion", fileEvent =>
signal.emit(EventType.SendMessage, fileRemovalEventToMsg(fileEvent)));
console.log(`Server is ready, running on ${settings.port}!`)
process.on('SIGINT', function() {
console.log("Shutting down!");
watch.close();
socket.close();
process.exit();
});

38
src/messageGenerators.js Normal file
View file

@ -0,0 +1,38 @@
import * as fs from "fs";
let messageCounter = 0;
export function fileChangeEventToMsg({path}){
const message = {
"jsonrpc":"2.0",
"method":"pushFile",
"params":{
"server":"home",
"filename":path,
"content":fs.readFileSync(path).toString()
},
"id":messageCounter++
}
return JSON.stringify(message);
}
export function fileRemovalEventToMsg({path}){
const message = {
"jsonrpc":"2.0",
"method": "deleteFile",
"params":{
"filename": path,
},
"id":messageCounter++
}
return JSON.stringify(message);
}
export function requestDefinitionFile(){
const message = {
"jsonrpc": "2.0",
"method": "getDefinitionFile",
"id":messageCounter++
}
return JSON.stringify(message);
}

6
src/messages.js Normal file
View file

@ -0,0 +1,6 @@
class EventType {
static FileChanged = "FileChanged";
static FileDeleted = "FileDeleted";
static MessageReceived = "MessageReceived";
static SendMessage = "SendMessage";
}

8
src/settings.js Normal file
View file

@ -0,0 +1,8 @@
// Folder your scripts are located in.
export const scriptsFolder = "./";
// Allowed filetypes to synchronize.
export const allowedFiletypes = [".js", ".script", ".txt"];
export const allowDeletingFiles = false;
// Port the websocket is set up on.
export const port = 12525;

17
src/webSocket.js Normal file
View file

@ -0,0 +1,17 @@
import { WebSocketServer } from 'ws';
import * as settings from "./settings.js";
export function setupSocket(signaller){
const wss = new WebSocketServer({ port: settings.port });
wss.on('connection', function connection(ws) {
ws.on('message', function message(msg) {
signaller.emit(EventType.MessageReceived, msg);
});
signaller.on(EventType.SendMessage, data => ws.send(data));
});
return wss;
}