diff --git a/node_modules/_app/factorioServer/index.js b/node_modules/_app/factorioServer/index.js index 3eee566d..d5630bcb 100644 --- a/node_modules/_app/factorioServer/index.js +++ b/node_modules/_app/factorioServer/index.js @@ -11,14 +11,23 @@ This class has the responsiblity of : */ const fs = require("fs"); +const child_process = require("child_process"); -class factorioServer { +const mkdirp = require("mkdirp"); + +const fileOps = require("_app/fileOps"); + +module.exports = class factorioServer { constructor({ - factorioDirectory = "./../../factorio", - instanceDirectory = "./../../instances/data", + factorioDirectory = "factorio", + instanceDirectory = "instances/data", instanceName = "Default server name", factorioPort = Math.floor(Math.random() * 65535), - serversettings = {} + serversettings = {}, + onProgress = function(type, a, b, c){ + if(type == "progress") console.log("Progress: ",a," of ",b," unit: ",c); + if(type == "log") console.log(a); + }, } = {}){ this.factorioDirectory = factorioDirectory; this.instanceDirectory = instanceDirectory; @@ -40,18 +49,22 @@ class factorioServer { "autosave_slots": 5, "afk_autokick_interval": 0, "auto_pause": false, - }, serversettings) - - // ensure instance exists - initialize(); + }, serversettings); + this.onProgress = (type, a, b, c) => { + if(typeof onProgress == "function") onProgress(type, a, b, c); + }; } async initialize(){ - if(!isValidInstance()){ - await createInstance(); + if(!await this.isValidInstance()){ + await this.createInstance(); } - + return true; } async createInstance(path = this.instanceDirectory){ + if(await this.isValidInstance(path)){ + throw new Error("Instance already exists!"); + } + // create folders let folders = [ "/script-output/", @@ -59,7 +72,7 @@ class factorioServer { "/mods/", "/instanceMods/", ]; - fs.mkdirSync(path) + mkdirp.sync(path); folders.forEach(folder => fs.mkdirSync(path + folder)); // create files @@ -67,14 +80,17 @@ class factorioServer { {name: "/script-output/output.txt", content: ""}, {name: "/script-output/orders.txt", content: ""}, {name: "/script-output/txbuffer.txt", content: ""}, - {name: "/config.ini", content: "[path]\r\n\ read-data=__PATH__executable__/../../data\r\n\ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\ "}, + {name: "/config.ini", content: "[path]\r\n\ read-data=__PATH__executable__/../../data\r\n\ write-data=__PATH__executable__/../../../" + this.instanceDirectory + "\r\n\ "}, {name: "/config.json", content: JSON.stringify({ factorioPort: this.factorioPort, clientPassword: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 8), }, null, 4)}, - {name: "/server-settings.json", content: JSON.stringify(this.serversettings)}, + {name: "/server-settings.json", content: JSON.stringify(this.serversettings, null, 4)}, ]; - files.forEach(file => fs.writeFile(path + file.name, file.content, doneWritingHandler)); + files.forEach(file => { + fs.writeFile(path + file.name, file.content, doneWritingHandler); + // console.log("Created: ",path+file.name); + }); let filesToWrite = files.length; function doneWritingHandler(){ @@ -83,17 +99,38 @@ class factorioServer { } } } - isValidInstance(path = this.instanceDirectory){ - if(fs.existsSync(instancedirectory)){ + async deleteInstance(path = this.instanceDirectory){ + if(await this.isValidInstance(path)){ + await fileOps.deleteFolderRecursive(path); return true; } else { return false; } } + isValidInstance(path = this.instanceDirectory){ + return new Promise((resolve, reject) => { + fs.stat(path, (err, stat) => { + if(err){ + // console.log(err) + resolve(false); + } else { + // console.log(stat) + resolve(true); + } + }); + }); + } async createMap(name = "map.zip"){ - if(!this.isValidInstance()){ + if(!await this.isValidInstance()){ await createInstance(); } - + this.onProgress("log", "Starting map creation"); + child_process.spawnSync( + './'+this.factorioDirectory + '/bin/x64/factorio', [ + '-c', this.instanceDirectory + '/config.ini', + '--create', this.instanceDirectory + '/saves/'+name, + ] + ); + this.onProgress("log", "Map created"); } } \ No newline at end of file diff --git a/node_modules/_app/factorioServer/index.spec.js b/node_modules/_app/factorioServer/index.spec.js new file mode 100644 index 00000000..d885e362 --- /dev/null +++ b/node_modules/_app/factorioServer/index.spec.js @@ -0,0 +1,54 @@ +const assert = require("assert"); +const fs = require("fs"); +const path = require("path"); + +const factorioServer = require("./index.js"); + +describe("factorioServer/index.js", ()=>{ + it("is a class (or at least a function)", ()=>{ + assert.equal(typeof factorioServer, "function"); + }); + describe(".deleteInstance()", ()=>{ + it("deletes an instance, defaulting to the classes instanceDirectory", async () => { + let server = new factorioServer({ + instanceDirectory: path.resolve(__dirname, "_testData_deleteInstance"), + instanceName: "Unit testing instance", + }); + await server.initialize(); + await server.deleteInstance(); + assert.equal(await server.isValidInstance(), false); + return true; + }); + }); + describe(".isValidInstance()", ()=>{ + it("tells us whether an instance exists or not", async () => { + let server = new factorioServer({ + instanceDirectory: path.resolve(__dirname, "_testData_isValidInstance"), + instanceName: "Unit testing instance", + }); + await server.deleteInstance(); + let status = await server.isValidInstance(); + assert.equal(status, false); + let x = await server.initialize(); // creates our instance + let status2 = await server.isValidInstance(); + assert.equal(status2, true); + + // clean up folder + await server.deleteInstance(); + return true; + }); + }); + describe(".initialize()", ()=>{ + it("server.initialize creates an instance", done => { + let server = new factorioServer({ + instanceDirectory: path.resolve(__dirname, "_testData_initialize"), + instanceName: "Unit testing instance", + }); + server.initialize().then(()=>{ + return server.deleteInstance(); + }).then(() => { + done(); + }).catch(e => console.log(e)); + }); + }); +}); \ No newline at end of file