From 5f3a160b75e9709a597cba4506774148bedf1d01 Mon Sep 17 00:00:00 2001 From: Danielv123 Date: Sun, 21 May 2017 22:00:30 +0200 Subject: [PATCH] Moved file functions to internal lib with some tests as well --- client.js | 65 ++++----------------------- database/items.db | 94 +++++++++++++++++++++++++++++++++++++++ lib/fileOps.js | 65 +++++++++++++++++++++++++++ lib/fileOps.spec.js | 43 ++++++++++++++++++ lib/test/another file.txt | 0 lib/test/file.txt | 0 package.json | 11 +++-- 7 files changed, 218 insertions(+), 60 deletions(-) create mode 100644 lib/fileOps.js create mode 100644 lib/fileOps.spec.js create mode 100644 lib/test/another file.txt create mode 100644 lib/test/file.txt diff --git a/client.js b/client.js index deebed95..2292dc2a 100644 --- a/client.js +++ b/client.js @@ -10,7 +10,10 @@ var Rcon = require('simple-rcon'); var hashFiles = require('hash-files'); var _ = require('underscore'); +// internal libraries var libomega = require("./lib/libomega.js"); +var fileOps = require("./lib/fileOps.js"); + // require config.json var config = require('./config'); var global = {}; @@ -29,21 +32,6 @@ const instancedirectory = './instances/' + instance; const command = process.argv[2]; var instanceInfo = {}; -// Functions -function deleteFolderRecursive(path) { - if (fs.existsSync(path)) { - fs.readdirSync(path).forEach(function (file, index) { - var curPath = path + "/" + file; - if (fs.lstatSync(curPath).isDirectory()) { // recurse - deleteFolderRecursive(curPath); - } else { // delete file - fs.unlinkSync(curPath); - } - }); - fs.rmdirSync(path); - } -}; - // simple string hasher String.prototype.hashCode = function () { var hash = 0; @@ -94,14 +82,14 @@ if (!command || command == "help" || command == "--help") { console.error("node client.js download"); process.exit(1); } else if (command == "list") { - console.dir(getDirectories("./instances/")); + console.dir(fileOps.getDirectories("./instances/")); process.exit(1); } else if (command == "delete") { if (!process.argv[3]) { console.error("Usage: node client.js delete [instance]"); process.exit(1); } else if (typeof process.argv[3] == "string" && fs.existsSync("./instances/" + process.argv[3]) && process.argv[3] != "/" && process.argv[3] != "") { - deleteFolderRecursive("./instances/" + process.argv[3]); + fileOps.deleteFolderRecursive("./instances/" + process.argv[3]); console.log("Deleted instance " + process.argv[3]); process.exit(1); } else { @@ -228,7 +216,7 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\ // Spawn factorio server //var serverprocess = child_process.exec(commandline); - getNewestFile(instancedirectory + "/saves/", fs.readdirSync(instancedirectory + "/saves/"),function(latestSave) { + fileOps.getNewestFile(instancedirectory + "/saves/", fs.readdirSync(instancedirectory + "/saves/"),function(latestSave) { // implicit global serverprocess = child_process.spawn( './' + config.factorioDirectory + '/bin/x64/factorio', [ @@ -307,11 +295,13 @@ write-data=__PATH__executable__/../../../instances/" + instance + "\r\n\ lastSignalCheck = Date.now(); }); } + +// ensure instancemanagement only runs once _.once(instanceManagement); function instanceManagement() { console.log("Started instanceManagement();"); // load plugins and execute onLoad event - let pluginDirectories = getDirectories("./sharedPlugins/"); + let pluginDirectories = fileOps.getDirectories("./sharedPlugins/"); let plugins = []; for(i=0; i newest.mtime.getTime()) { - newest = { file : file, mtime : stats.mtime }; - } - if (checked == files.length) { - callback(newest); - } - }); - })(dir + file); - } - }); - } diff --git a/database/items.db b/database/items.db index e69de29b..4355854e 100644 --- a/database/items.db +++ b/database/items.db @@ -0,0 +1,94 @@ +{"name":"combat-shotgun","count":"1","_id":"01jLIbbQ2ZXo8xet"} +{"name":"crude-oil","count":3399414,"_id":"0z6ahVSklQcCuOmf"} +{"name":"sulfur","count":1032,"_id":"23SHYRpD6xVRNhaO"} +{"name":"science-pack-3","count":5002,"_id":"25wXED3PWYD9qk2r"} +{"name":"copper-plate","count":6144494,"_id":"2CawU9P5jgZHHiUU"} +{"name":"copper-ore","count":"102","_id":"2DYQES3PaVPuYyal"} +{"name":"stone","count":28,"_id":"2aCh9XADK403IjMu"} +{"name":"battery","count":53293,"_id":"4wzpuWq4UJGgGB0w"} +{"name":"substation","count":1035,"_id":"6EvWa5sr7aOfsOmh"} +{"name":"storage-tank","count":"4","_id":"6L8D2UUQGpqoeSyV"} +{"name":"small-pump","count":250,"_id":"6Y5Gdm7fANYWCK4S"} +{"name":"energy-shield-mk2-equipment","count":26,"_id":"7uV1wOd6YpP6YBg6"} +{"name":"pipe-to-ground","count":100,"_id":"9QP4hAy3sJkpDCrZ"} +{"name":"pipe","count":1004,"_id":"AHkpkp67PHoT2Ip8"} +{"name":"fast-inserter","count":"132","_id":"ALVxvbF1YpOzGQSI"} +{"name":"solid-fuel","count":70,"_id":"APqiAHT3a3sJRF7U"} +{"name":"chemical-plant","count":501,"_id":"CGwD3PkkPMqsCQBJ"} +{"name":"splitter","count":1008,"_id":"D6pu2w2C3tEpJSrY"} +{"name":"rail","count":2504,"_id":"DOIN6qxET53zLjAR"} +{"name":"small-electric-pole","count":55,"_id":"Dy4cKwfZtwB2pjeF"} +{"name":"battery-mk2-equipment","count":27,"_id":"E84qUcptl6eH4D14"} +{"name":"cargo-wagon","count":21,"_id":"EWkaGca01NYDnyrt"} +{"name":"steel-plate","count":1594404,"_id":"F5wIdk2J2O5Jfp64"} +{"name":"science-pack-2","count":108672,"_id":"HkKc8AFK9INvlxnD"} +{"name":"green-wire","count":"36","_id":"HoIHkVMIMSMXlfPW"} +{"name":"beacon","count":"10","_id":"ImP3SlS0bfO8kaip"} +{"name":"fusion-reactor-equipment","count":7,"_id":"JynGGRC3wgbjG1xK"} +{"name":"big-electric-pole","count":1005,"_id":"KvOb3foDB5Px2jCL"} +{"name":"solar-panel","count":1023,"_id":"LQ70r6rrvPQ1twsB"} +{"name":"productivity-module-2","count":254,"_id":"LWmYiJ4zAOcdEgRY"} +{"name":"science-pack-1","count":139816,"_id":"LXBJ6Ns3IvDtBq5Y"} +{"name":"advanced-circuit","count":645071,"_id":"LdCXjtKXYPpmmLJf"} +{"name":"electric-mining-drill","count":509,"_id":"MC0sUIbd4bNPyiWV"} +{"name":"iron-ore","count":"52","_id":"MQZOQJ132g92DlEg"} +{"name":"water","count":50058,"_id":"MTEnmbNGHKSE8Gy3"} +{"name":"destroyer-capsule","count":"100","_id":"MlXqRhCD4UZETrdK"} +{"name":"iron-gear-wheel","count":"180","_id":"NsPHgS3B2qaKmyap"} +{"name":"speed-module-2","count":254,"_id":"Nxz2ZKMbcyiqUWd1"} +{"name":"burner-inserter","count":94,"_id":"Ouwv7ZlKhaz00FAt"} +{"name":"logistic-chest-requester","count":257,"_id":"PNLjyvBGrb4Gci5G"} +{"name":"express-splitter","count":1010,"_id":"PT7b3VbWa47lJJNI"} +{"name":"piercing-shotgun-shell","count":"70","_id":"PfsRTwLQLwsnZK6F"} +{"name":"solar-panel-equipment","count":18,"_id":"S29hMsueEXwICCvp"} +{"name":"personal-roboport-equipment","count":26,"_id":"STElkhgN3HjQ9LKj"} +{"name":"logistic-chest-storage","count":250,"_id":"SscVzS8jf9xk6Eat"} +{"name":"stone-furnace","count":1001,"_id":"TIONNgEB1OcvuR4m"} +{"name":"iron-plate","count":25036,"_id":"TKUNsKLhzi9wbXLk"} +{"name":"assembling-machine-1","count":"50","_id":"VAjgjWvWSDLzJhcz"} +{"name":"rail-chain-signal","count":"97","_id":"W8KAv7VO9viuCuLO"} +{"name":"constant-combinator","count":"5","_id":"WnaALSqOZ6sHra99"} +{"name":"coal","count":853334,"_id":"WxJKZfXyX8c0rHWc"} +{"name":"red-wire","count":"13","_id":"XprwdphPUrihfASQ"} +{"name":"effectivity-module-2","count":286,"_id":"XwITKWqPlpxkAYxo"} +{"name":"logistic-chest-passive-provider","count":253,"_id":"Yr4v7SlUGXQWouxJ"} +{"name":"fast-splitter","count":1016,"_id":"YrzmqfD7u7fZp34C"} +{"name":"plastic-bar","count":50060,"_id":"Yw2qmHm6SH5dyTxs"} +{"name":"pumpjack","count":404,"_id":"Z0plqSsfLfAl9YYa"} +{"name":"small-lamp","count":"50","_id":"Zd3H118Nc2u7HmeP"} +{"name":"fast-transport-belt","count":1042,"_id":"ZmqzOJF4tVJEzgUW"} +{"name":"medium-electric-pole","count":500,"_id":"aPqWD0jxmTv8aac7"} +{"name":"electric-furnace","count":200,"_id":"bBvxS6tFmo4yCFEE"} +{"name":"raw-wood","count":22912,"_id":"d85jLuxP9EaWmHe9"} +{"name":"laser-turret","count":252,"_id":"f9MItTJWZYfsUc9f"} +{"name":"deconstruction-planner","count":10,"_id":"fmj6YZnuuinVPP4q"} +{"name":"roboport","count":25,"_id":"ijpo46GFEzZJdZDG"} +{"name":"construction-robot","count":1026,"_id":"ipGZYHapBK3gmsaV"} +{"name":"electronic-circuit","count":3768586,"_id":"iq5rntWyvPGJqWUr"} +{"name":"express-transport-belt","count":1017,"_id":"iyrTNKNZCap5CUfn"} +{"name":"boiler","count":1011,"_id":"j2UJIu2uH01RXpgo"} +{"name":"repair-pack","count":"14","_id":"jzlBCjlkSHXUwQaq"} +{"name":"blueprint","count":12,"_id":"k30PZakZ4PBVFB32"} +{"name":"stone-wall","count":551,"_id":"kjaR0wHDPqIwZNxN"} +{"name":"electric-engine-unit","count":252,"_id":"lSWfvV27887gKucW"} +{"name":"decider-combinator","count":"1","_id":"oRrRtX53cbXqkhJF"} +{"name":"petroleum-gas","count":7582906,"_id":"ovOahSJQhBOQf0sL"} +{"name":"transport-belt","count":1011,"_id":"pBF2CkAB1AFexcZE"} +{"name":"assembling-machine-3","count":293,"_id":"pevQK7kAM5v7ObfG"} +{"name":"alien-science-pack","count":"415","_id":"qlkibcDNC0OgBuy7"} +{"name":"assembling-machine-2","count":200,"_id":"rUdnyKLPhZvMoRJ8"} +{"name":"steam-engine","count":1000,"_id":"rmEFJ9OuEIn91mLx"} +{"name":"accumulator","count":1005,"_id":"tCrPS64NshuzFHtW"} +{"name":"raw-fish","count":"11","_id":"uVQshHGwOWGwIMux"} +{"name":"underground-belt","count":1008,"_id":"v1qaz21iokoxERyl"} +{"name":"diesel-locomotive","count":20,"_id":"vmyqu0WI3k1XIdlu"} +{"name":"express-underground-belt","count":1012,"_id":"vpm5zw4BlnfErJAo"} +{"name":"piercing-rounds-magazine","count":5030,"_id":"wJpfX5g4HgCyRiAa"} +{"name":"processing-unit","count":108,"_id":"wXjUBq0KIksTJcwy"} +{"name":"power-armor-mk2","count":5,"_id":"wmItTXh1bEcysw86"} +{"name":"logistic-robot","count":1048,"_id":"x2cRxrpdC7BHJFpx"} +{"name":"fast-underground-belt","count":1010,"_id":"xONgtmV0OoxKmzVv"} +{"name":"engine-unit","count":254,"_id":"y9XyUryrxgsucFJc"} +{"name":"grenade","count":"30","_id":"ygLIdsWl9JFV2aZ6"} +{"name":"concrete","count":1039,"_id":"ym8LemdTCsDO52s8"} +{"name":"logistic-chest-active-provider","count":252,"_id":"zQZ9UP3qyg6Hx9jO"} diff --git a/lib/fileOps.js b/lib/fileOps.js new file mode 100644 index 00000000..55b9f066 --- /dev/null +++ b/lib/fileOps.js @@ -0,0 +1,65 @@ +var fs = require("fs"); +var path = require("path"); + +// gets newest file in a directory +// dir is directory +// files is array of filenames +// callback(filename string); +var getNewestFile = function(dir, files, callback) { + if (!callback) return; + if (!files || (files && files.length === 0)) { + callback(); + } + var newest = { file: files[0] }; + var checked = 0; + fs.stat(dir + newest.file, function(err, stats) { + newest.mtime = stats.mtime; + for (var i = 0; i < files.length; i++) { + var file = files[i]; + (function(file) { + fs.stat(file, function(err, stats) { + ++checked; + if (stats.mtime.getTime() > newest.mtime.getTime()) { + newest = { file : file, mtime : stats.mtime }; + } + if (checked == files.length) { + callback(newest); + } + }); + })(dir + file); + } + }); +} + +// get all directories in folder +var getDirectories = function(srcpath) { + return fs.readdirSync(srcpath).filter(function (file) { + return fs.statSync(path.join(srcpath, file)).isDirectory(); + }); +} +var getFileNamesSync = function(srcpath) { + return fs.readdirSync(srcpath).filter(function (file) { + return !fs.statSync(path.join(srcpath, file)).isDirectory(); + }); +} +// does what it says on the tin +var deleteFolderRecursive = function(path) { + if (fs.existsSync(path)) { + fs.readdirSync(path).forEach(function (file, index) { + var curPath = path + "/" + file; + if (fs.lstatSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(path); + } +}; + +module.exports = { + getNewestFile:getNewestFile, + getDirectories:getDirectories, + deleteFolderRecursive:deleteFolderRecursive, + getFileNamesSync:getFileNamesSync, +} \ No newline at end of file diff --git a/lib/fileOps.spec.js b/lib/fileOps.spec.js new file mode 100644 index 00000000..7297f11c --- /dev/null +++ b/lib/fileOps.spec.js @@ -0,0 +1,43 @@ +var assert = require('assert'); +var fileOps = require('./fileOps'); + +describe("fileOps.js", function(){ + describe("fileOps.getDirectories()", function(){ + it("gets an array of directory names from a path", function(){ + let directories = fileOps.getDirectories("lib/test"); + + // because there are no arrays for some reason + assert(typeof directories == "object"); + + // they are sorted alphabetically because thats the way it is + assert(directories[0] == "another folder" && directories[1] == "folder"); + }); + it("does not return any filenames", function(){ + let directories = fileOps.getDirectories("lib/test"); + + // this is a function to return directories, not files. So yeah. + assert(!directories.includes("file.txt") && !directories.includes("another file.txt")); + }); + }); + describe("fileOps.getFileNamesSync(path)", function(){ + it("gets names of files in directory", function(){ + let files = fileOps.getFileNamesSync("lib/test"); + assert(files.length > 0); + assert(files.includes("file.txt") && files.includes("another file.txt")); + }); + it("throws when lacking first argument", function(){ + assert.throws(function(){ + let files = fileOps.getFileNamesSync(); + }, Error); + }); + }); + /*describe("fileOps.getNewestFile()", function(){ + it("gets the newest file in a directory async", function(done){ + fileOps.getNewestFile("lib/test", fileOps.getFileNames("lib/test"), function(newest){ + assert(newest); + done(); + }) + + }); + });*/ +}); diff --git a/lib/test/another file.txt b/lib/test/another file.txt new file mode 100644 index 00000000..e69de29b diff --git a/lib/test/file.txt b/lib/test/file.txt new file mode 100644 index 00000000..e69de29b diff --git a/package.json b/package.json index 6c076c1a..b08f032f 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "factorio-clusterio", + "name": "clusterio", "version": "1.0.0", - "description": "Factorio cluster???", + "description": "Interserver communication for factorio", "main": "master.js", "scripts": { "test": "npm run test-unit", - "test-unit": "SET NODE_ENV=test && mocha --recursive ./**/*.spec.js", + "test-unit": "SET NODE_ENV=test && mocha --recursive \"./{,!(node_modules)/**/}*.spec.js\"", "start": "echo Run node client.js start [instance] to start slaves && node master.js" }, "keywords": [ @@ -33,11 +33,14 @@ "needle": "^1.1.0", "portfinder": "^1.0.9", "request": "^2.79.0", + "semver": "^5.3.0", "simple-rcon": "^0.3.1", "sync-request": "^4.0.1", "underscore": "^1.8.3" }, "devDependencies": { - "mocha": "^3.4.1" + "chai": "^3.5.0", + "mocha": "^3.4.1", + "mock-fs": "^4.3.0" } }