Automatic formatting pass
This commit is contained in:
parent
afb9ceccab
commit
b7c0761822
7 changed files with 131 additions and 131 deletions
118
src/config.js
118
src/config.js
|
@ -3,72 +3,72 @@ import { existsSync } from "fs";
|
||||||
|
|
||||||
// Define a schema
|
// Define a schema
|
||||||
export let config = convict({
|
export let config = convict({
|
||||||
allowedFiletypes: {
|
allowedFiletypes: {
|
||||||
doc: 'Filetypes that are synchronized to the game.',
|
doc: 'Filetypes that are synchronized to the game.',
|
||||||
format: 'Array',
|
format: 'Array',
|
||||||
default: [".js", ".script", ".txt"]
|
default: [".js", ".script", ".txt"]
|
||||||
},
|
|
||||||
allowDeletingFiles: {
|
|
||||||
doc: 'Allow deleting files in game if they get deleted off disk.',
|
|
||||||
format: 'Boolean',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
port: {
|
|
||||||
doc: 'The port to bind to.',
|
|
||||||
format: 'Number',
|
|
||||||
default: 12525,
|
|
||||||
env: 'BB_PORT',
|
|
||||||
arg: 'port'
|
|
||||||
},
|
|
||||||
scriptsFolder: {
|
|
||||||
doc: 'The to be synchronized folder.',
|
|
||||||
format: 'String',
|
|
||||||
default: '.',
|
|
||||||
env: 'BB_SCRIPTFOLDER',
|
|
||||||
arg: "folder"
|
|
||||||
},
|
|
||||||
quiet: {
|
|
||||||
doc: 'Log less internal events to stdout.',
|
|
||||||
format: 'Boolean',
|
|
||||||
env: 'BB_VERBOSE',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
dry: {
|
|
||||||
doc: 'Only print the files to be synchronised.',
|
|
||||||
format: 'Boolean',
|
|
||||||
env: 'BB_DRY',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
definitionFile: {
|
|
||||||
update: {
|
|
||||||
doc: 'Automatically pull the definition file from the game.',
|
|
||||||
format: 'Boolean',
|
|
||||||
env: 'BB_UPDATE_DEF',
|
|
||||||
default: false
|
|
||||||
},
|
},
|
||||||
location: {
|
allowDeletingFiles: {
|
||||||
doc: 'Location/name of where the definition file gets placed.',
|
doc: 'Allow deleting files in game if they get deleted off disk.',
|
||||||
format: 'String',
|
format: 'Boolean',
|
||||||
env: 'BB_LOCATION_DEF',
|
default: false
|
||||||
default: "./NetScriptDefinitions.d.ts"
|
},
|
||||||
|
port: {
|
||||||
|
doc: 'The port to bind to.',
|
||||||
|
format: 'Number',
|
||||||
|
default: 12525,
|
||||||
|
env: 'BB_PORT',
|
||||||
|
arg: 'port'
|
||||||
|
},
|
||||||
|
scriptsFolder: {
|
||||||
|
doc: 'The to be synchronized folder.',
|
||||||
|
format: 'String',
|
||||||
|
default: '.',
|
||||||
|
env: 'BB_SCRIPTFOLDER',
|
||||||
|
arg: "folder"
|
||||||
|
},
|
||||||
|
quiet: {
|
||||||
|
doc: 'Log less internal events to stdout.',
|
||||||
|
format: 'Boolean',
|
||||||
|
env: 'BB_VERBOSE',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
dry: {
|
||||||
|
doc: 'Only print the files to be synchronised.',
|
||||||
|
format: 'Boolean',
|
||||||
|
env: 'BB_DRY',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
definitionFile: {
|
||||||
|
update: {
|
||||||
|
doc: 'Automatically pull the definition file from the game.',
|
||||||
|
format: 'Boolean',
|
||||||
|
env: 'BB_UPDATE_DEF',
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
doc: 'Location/name of where the definition file gets placed.',
|
||||||
|
format: 'String',
|
||||||
|
env: 'BB_LOCATION_DEF',
|
||||||
|
default: "./NetScriptDefinitions.d.ts"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export function loadConfig() {
|
export function loadConfig() {
|
||||||
const configFile = "filesync.json";
|
const configFile = "filesync.json";
|
||||||
if (existsSync(configFile)) {
|
if (existsSync(configFile)) {
|
||||||
try {
|
try {
|
||||||
config.loadFile(configFile);
|
config.loadFile(configFile);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(`Unable to load configuration file at ${configFile}: ${e}`);
|
throw new Error(`Unable to load configuration file at ${configFile}: ${e}`);
|
||||||
|
}
|
||||||
|
} else if (!config.get("quiet")) {
|
||||||
|
console.log("No configuration file found.")
|
||||||
}
|
}
|
||||||
} else if (!config.get("quiet")) {
|
|
||||||
console.log("No configuration file found.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform validation
|
// Perform validation
|
||||||
config.validate({ allowed: 'strict' });
|
config.validate({ allowed: 'strict' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export class EventType {
|
export class EventType {
|
||||||
static ConnectionMade = "ConnectionMade";
|
static ConnectionMade = "ConnectionMade";
|
||||||
static FileChanged = "FileChanged";
|
static FileChanged = "FileChanged";
|
||||||
static FileDeleted = "FileDeleted";
|
static FileDeleted = "FileDeleted";
|
||||||
static MessageReceived = "MessageReceived";
|
static MessageReceived = "MessageReceived";
|
||||||
static MessageSend = "MessageSend";
|
static MessageSend = "MessageSend";
|
||||||
}
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
import CheapWatch from "cheap-watch";
|
import CheapWatch from "cheap-watch";
|
||||||
import {config} from "./config.js";
|
import { config } from "./config.js";
|
||||||
import {EventType} from "./eventTypes.js";
|
import { EventType } from "./eventTypes.js";
|
||||||
import {resolve } from "path";
|
import { resolve } from "path";
|
||||||
|
|
||||||
function fileFilter(file) {
|
function fileFilter(file) {
|
||||||
if(config.get("allowedFiletypes").some(extension => file.path.endsWith(extension)))
|
if (config.get("allowedFiletypes").some(extension => file.path.endsWith(extension)))
|
||||||
return true;
|
return true;
|
||||||
if(file.stats.isDirectory())
|
if (file.stats.isDirectory())
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,18 @@ const watch = new CheapWatch({
|
||||||
|
|
||||||
export async function setupWatch(signaller) {
|
export async function setupWatch(signaller) {
|
||||||
|
|
||||||
if(!config.get("quiet")) console.log("Watching folder", resolve(config.get("scriptsFolder")))
|
if (!config.get("quiet")) console.log("Watching folder", resolve(config.get("scriptsFolder")))
|
||||||
|
|
||||||
watch.on('+', fileEvent => {if (fileEvent.stats.isFile()) signaller.emit(EventType.FileChanged, fileEvent)});
|
watch.on('+', fileEvent => { if (fileEvent.stats.isFile()) signaller.emit(EventType.FileChanged, fileEvent) });
|
||||||
watch.on('-', fileEvent => {if (fileEvent.stats.isFile()) signaller.emit(EventType.FileDeleted, fileEvent)});
|
watch.on('-', fileEvent => { if (fileEvent.stats.isFile()) signaller.emit(EventType.FileDeleted, fileEvent) });
|
||||||
|
|
||||||
// Wait 'till filewatcher is ready to go
|
// Wait 'till filewatcher is ready to go
|
||||||
await watch.init();
|
await watch.init();
|
||||||
|
|
||||||
if(config.get("dry")) {
|
if (config.get("dry")) {
|
||||||
console.log("Watch would've synchronised:\n", watch.paths)
|
console.log("Watch would've synchronised:\n", watch.paths)
|
||||||
process.exit();
|
process.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return watch;
|
return watch;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,48 @@
|
||||||
import {readFileSync} from "fs";
|
import { readFileSync } from "fs";
|
||||||
import {config} from "../config.js";
|
import { config } from "../config.js";
|
||||||
import {join} from "path";
|
import { join } from "path";
|
||||||
|
|
||||||
let messageCounter = 0;
|
let messageCounter = 0;
|
||||||
|
|
||||||
export function fileChangeEventToMsg({path}){
|
export function fileChangeEventToMsg({ path }) {
|
||||||
return {
|
return {
|
||||||
"jsonrpc":"2.0",
|
"jsonrpc": "2.0",
|
||||||
"method":"pushFile",
|
"method": "pushFile",
|
||||||
"params":{
|
"params": {
|
||||||
"server":"home",
|
"server": "home",
|
||||||
"filename":"/"+path,
|
"filename": "/" + path,
|
||||||
"content":readFileSync(join(config.get("scriptsFolder"), path)).toString()
|
"content": readFileSync(join(config.get("scriptsFolder"), path)).toString()
|
||||||
},
|
},
|
||||||
"id":messageCounter++
|
"id": messageCounter++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fileRemovalEventToMsg({path}){
|
export function fileRemovalEventToMsg({ path }) {
|
||||||
return {
|
return {
|
||||||
"jsonrpc":"2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "deleteFile",
|
"method": "deleteFile",
|
||||||
"params":{
|
"params": {
|
||||||
"filename": path,
|
"filename": path,
|
||||||
},
|
},
|
||||||
"id":messageCounter++
|
"id": messageCounter++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestDefinitionFile(){
|
export function requestDefinitionFile() {
|
||||||
return {
|
return {
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "getDefinitionFile",
|
"method": "getDefinitionFile",
|
||||||
"id":messageCounter++
|
"id": messageCounter++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestFilenames(){
|
export function requestFilenames() {
|
||||||
return {
|
return {
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "getFileNames",
|
"method": "getFileNames",
|
||||||
"params": {
|
"params": {
|
||||||
"server": "home",
|
"server": "home",
|
||||||
},
|
},
|
||||||
"id":messageCounter++
|
"id": messageCounter++
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,8 +8,8 @@ import { fileChangeEventToMsg } from "./messageGenerators.js";
|
||||||
export function messageHandler(signaller, msg) {
|
export function messageHandler(signaller, msg) {
|
||||||
let incoming;
|
let incoming;
|
||||||
|
|
||||||
try {incoming = JSON.parse(msg.toString());}
|
try { incoming = JSON.parse(msg.toString()); }
|
||||||
catch (err) {return console.log(err);}
|
catch (err) { return console.log(err); }
|
||||||
console.log(incoming)
|
console.log(incoming)
|
||||||
if (incoming.id == undefined) return;
|
if (incoming.id == undefined) return;
|
||||||
|
|
||||||
|
@ -26,17 +26,17 @@ export function messageHandler(signaller, msg) {
|
||||||
if (request.method &&
|
if (request.method &&
|
||||||
request.method == "getFileNames"
|
request.method == "getFileNames"
|
||||||
&& incoming.result) {
|
&& incoming.result) {
|
||||||
const gameFiles = incoming.result.map(file => removeLeadingSlash(file));
|
const gameFiles = incoming.result.map(file => removeLeadingSlash(file));
|
||||||
|
|
||||||
watchedFiles().forEach((stats, fileName) => {
|
watchedFiles().forEach((stats, fileName) => {
|
||||||
if(!stats.isDirectory() && !gameFiles.includes(fileName))
|
if (!stats.isDirectory() && !gameFiles.includes(fileName))
|
||||||
signaller.emit(EventType.MessageSend, fileChangeEventToMsg({path:fileName}));
|
signaller.emit(EventType.MessageSend, fileChangeEventToMsg({ path: fileName }));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeLeadingSlash(path){
|
function removeLeadingSlash(path) {
|
||||||
const reg = /^\//;
|
const reg = /^\//;
|
||||||
return path.replace(reg, "")
|
return path.replace(reg, "")
|
||||||
}
|
}
|
|
@ -1,19 +1,19 @@
|
||||||
class MessageTracker {
|
class MessageTracker {
|
||||||
data = new Map()
|
data = new Map()
|
||||||
#maxLength = 200
|
#maxLength = 200
|
||||||
|
|
||||||
push(msg) {
|
push(msg) {
|
||||||
this.data.set(msg.id, msg);
|
this.data.set(msg.id, msg);
|
||||||
|
|
||||||
if (this.data.size > this.#maxLength){
|
if (this.data.size > this.#maxLength) {
|
||||||
const [firstKey] = map.keys();
|
const [firstKey] = map.keys();
|
||||||
this.data.delete(firstKey);
|
this.data.delete(firstKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
get(index) {
|
get(index) {
|
||||||
return this.data.get(index);
|
return this.data.get(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const messageTracker = new MessageTracker();
|
export const messageTracker = new MessageTracker();
|
|
@ -1,29 +1,29 @@
|
||||||
import { WebSocketServer } from 'ws';
|
import { WebSocketServer } from 'ws';
|
||||||
import {config} from "../config.js";
|
import { config } from "../config.js";
|
||||||
import {EventType} from "../eventTypes.js"
|
import { EventType } from "../eventTypes.js"
|
||||||
import { requestDefinitionFile } from './messageGenerators.js';
|
import { requestDefinitionFile } from './messageGenerators.js';
|
||||||
import {messageTracker} from "./messageTracker.js"
|
import { messageTracker } from "./messageTracker.js"
|
||||||
|
|
||||||
export function setupSocket(signaller){
|
export function setupSocket(signaller) {
|
||||||
|
|
||||||
const wss = new WebSocketServer({ port: config.get("port") });
|
const wss = new WebSocketServer({ port: config.get("port") });
|
||||||
|
|
||||||
wss.on('connection', function connection(ws) {
|
wss.on('connection', function connection(ws) {
|
||||||
|
|
||||||
function sendMessage(msg) {
|
function sendMessage(msg) {
|
||||||
messageTracker.push(msg);
|
messageTracker.push(msg);
|
||||||
ws.send(JSON.stringify(msg));
|
ws.send(JSON.stringify(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.on('message', (msg) => {
|
|
||||||
signaller.emit(EventType.MessageReceived, msg);
|
|
||||||
});
|
|
||||||
|
|
||||||
signaller.on(EventType.MessageSend, msg => {
|
ws.on('message', (msg) => {
|
||||||
sendMessage(msg);
|
signaller.emit(EventType.MessageReceived, msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
signaller.trigger(EventType.ConnectionMade);
|
signaller.on(EventType.MessageSend, msg => {
|
||||||
|
sendMessage(msg);
|
||||||
|
});
|
||||||
|
|
||||||
|
signaller.trigger(EventType.ConnectionMade);
|
||||||
});
|
});
|
||||||
|
|
||||||
return wss;
|
return wss;
|
||||||
|
|
Loading…
Add table
Reference in a new issue