mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Move Factorio server implementation to host
Move Factorio related code in lib that's only used by the host into the host package.
This commit is contained in:
1 parent
bc574ee1cb
commit
6af25e085c
13 files changed
+95
-100
No files matched your search
@@ -20,8 +20,12 @@
|
||||
"dependencies": {
|
||||
"@clusterio/lib": "^2.0.0-alpha.13",
|
||||
"fs-extra": "^11.1.1",
|
||||
"jimp": "^0.22.8",
|
||||
"jszip": "^3.10.1",
|
||||
"phin": "^3.7.0",
|
||||
"pidusage": "^3.0.2",
|
||||
"rcon-client": "^4.2.3",
|
||||
"semver": "^7.5.4",
|
||||
"set-blocking": "^2.0.0",
|
||||
"winston": "^3.10.0",
|
||||
"winston-daily-rotate-file": "^4.7.1",
|
||||
|
||||
@@ -9,6 +9,10 @@ const util = require("util");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { PlayerStats } = lib;
|
||||
|
||||
const { FactorioServer } = require("./server");
|
||||
const { patch } = require("./patch");
|
||||
const { exportData } = require("./export");
|
||||
|
||||
|
||||
const instanceRconCommandDuration = new lib.Histogram(
|
||||
"clusterio_instance_rcon_command_duration_seconds",
|
||||
@@ -143,7 +147,7 @@ class Instance extends lib.Link {
|
||||
// Valid statuses are stopped, starting, running, stopping, creating_save and exporting_data.
|
||||
this._status = "stopped";
|
||||
this._loadedSave = null;
|
||||
this.server = new lib.FactorioServer(
|
||||
this.server = new FactorioServer(
|
||||
factorioDir, this._dir, serverOptions
|
||||
);
|
||||
|
||||
@@ -823,7 +827,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
}
|
||||
}
|
||||
|
||||
await lib.patch(this.path("saves", saveName), [...modules.values()]);
|
||||
await patch(this.path("saves", saveName), [...modules.values()]);
|
||||
return saveName;
|
||||
}
|
||||
|
||||
@@ -1082,7 +1086,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
this.logger.info("Exporting data .....");
|
||||
await this.syncMods();
|
||||
let zip = await lib.exportData(this.server);
|
||||
let zip = await exportData(this.server);
|
||||
|
||||
let content = await zip.generateAsync({ type: "nodebuffer" });
|
||||
let url = new URL(this._host.config.get("host.controller_url"));
|
||||
|
||||
@@ -5,9 +5,8 @@ const path = require("path");
|
||||
const Jimp = require("jimp");
|
||||
const JSZip = require("jszip");
|
||||
|
||||
const libIni = require("../ini");
|
||||
const libBuildMod = require("../../build_mod");
|
||||
const libZipOps = require("../zip_ops");
|
||||
const lib = require("@clusterio/lib");
|
||||
const libBuildMod = require("@clusterio/lib/build_mod");
|
||||
|
||||
/**
|
||||
* Generate the export mod needed for exportData
|
||||
@@ -16,7 +15,7 @@ const libZipOps = require("../zip_ops");
|
||||
* the server given, with dependencies generated for all the mods present in
|
||||
* the server's mods folder.
|
||||
*
|
||||
* @param {module:lib.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to generate the export mod for.
|
||||
* @memberof module:lib
|
||||
*/
|
||||
@@ -34,8 +33,7 @@ async function generateExportMod(server) {
|
||||
clean: false,
|
||||
build: true,
|
||||
pack: true,
|
||||
// XXX fix path when moving lib/factorio to host
|
||||
sourceDir: path.join(__dirname, "..", "..", "..", "host", "lua", "export"),
|
||||
sourceDir: path.join(__dirname, "..", "lua", "export"),
|
||||
outputDir: server.writePath("mods"),
|
||||
bumpPatch: false,
|
||||
factorioVersion: server.version.replace(/\.\d+$/, ""),
|
||||
@@ -57,13 +55,13 @@ async function loadZip(server, modVersions, mod) {
|
||||
zipCache.set(zipPath, zip);
|
||||
}
|
||||
|
||||
return zip.folder(libZipOps.findRoot(zip));
|
||||
return zip.folder(lib.findRoot(zip));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the given Factorio file path into a Buffer
|
||||
*
|
||||
* @param {module:lib.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to load the file from.
|
||||
* @param {Map<string, string>} modVersions - Mapping of mod to version used.
|
||||
* @param {string} modPath - Factorio style path to the file to load.
|
||||
@@ -250,7 +248,7 @@ function filterItems(prototypes) {
|
||||
* Assembles and packs the icons for the item prototypes given into a single
|
||||
* spritesheet and json file with meta data.
|
||||
*
|
||||
* @param {module:lib.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to generate the export mod for.
|
||||
* @param {Map<string, string>} modVersions -
|
||||
* Mapping of mod name to versions to get icons from.
|
||||
@@ -321,7 +319,7 @@ async function exportItems(server, modVersions, items) {
|
||||
* Parses and merges all the locales for the all the mods given through
|
||||
* `modVersions` and `modOrder`.
|
||||
*
|
||||
* @param {module:lib.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to export the locale from.
|
||||
* @param {Map<string, string>} modVersions -
|
||||
* Mapping of mod name to version to export locale from.
|
||||
@@ -349,7 +347,7 @@ async function exportLocale(server, modVersions, modOrder, languageCode) {
|
||||
}
|
||||
|
||||
let baseLocaleFilePath = server.dataPath("base", "locale", languageCode, "base.cfg");
|
||||
mergeLocale(libIni.parse(await fs.readFile(baseLocaleFilePath, "utf8")));
|
||||
mergeLocale(lib.parse(await fs.readFile(baseLocaleFilePath, "utf8")));
|
||||
|
||||
for (let mod of modOrder) {
|
||||
if (["core", "base", "export"].includes(mod)) {
|
||||
@@ -367,7 +365,7 @@ async function exportLocale(server, modVersions, modOrder, languageCode) {
|
||||
}
|
||||
for (let file of zip.file(new RegExp(`locale\\/${languageCode}\\/.*\\.cfg`))) {
|
||||
let content = await file.async("nodebuffer");
|
||||
mergeLocale(libIni.parse(content.toString("utf8")));
|
||||
mergeLocale(lib.parse(content.toString("utf8")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +375,7 @@ async function exportLocale(server, modVersions, modOrder, languageCode) {
|
||||
/**
|
||||
* Export the locale and item icons for the given factorio server
|
||||
*
|
||||
* @param {module:lib.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to export the data from.
|
||||
* @returns {Promise<JSZip>} zip file with exported data.
|
||||
* @memberof module:lib
|
||||
@@ -7,8 +7,7 @@ const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
const semver = require("semver");
|
||||
|
||||
const libHash = require("../hash");
|
||||
const { findRoot } = require("../zip_ops");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
|
||||
const knownScenarios = {
|
||||
@@ -179,7 +178,7 @@ function reorderDependencies(modules) {
|
||||
*/
|
||||
async function patch(savePath, modules) {
|
||||
let zip = await JSZip.loadAsync(await fs.readFile(savePath));
|
||||
let root = zip.folder(findRoot(zip));
|
||||
let root = zip.folder(lib.findRoot(zip));
|
||||
|
||||
let patchInfoFile = root.file("clusterio.json");
|
||||
let patchInfo;
|
||||
@@ -190,7 +189,7 @@ async function patch(savePath, modules) {
|
||||
// No info file present, try to detect if it's a known compatible scenario.
|
||||
} else {
|
||||
let controlStream = root.file("control.lua").nodeStream("nodebuffer");
|
||||
let controlHash = await libHash.hashStream(controlStream);
|
||||
let controlHash = await lib.hashStream(controlStream);
|
||||
|
||||
if (controlHash in knownScenarios) {
|
||||
patchInfo = {
|
||||
@@ -8,12 +8,7 @@ const util = require("util");
|
||||
const crypto = require("crypto");
|
||||
const rconClient = require("rcon-client");
|
||||
|
||||
const libErrors = require("../errors");
|
||||
const libFileOps = require("../file_ops");
|
||||
const libIni = require("../ini");
|
||||
const { logger } = require("../logging");
|
||||
const { escapeRegExp } = require("../helpers");
|
||||
const { LineSplitter } = require("../stream");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
|
||||
/**
|
||||
@@ -449,7 +444,7 @@ class FactorioServer extends events.EventEmitter {
|
||||
this._version = null;
|
||||
this._dataDir = null;
|
||||
|
||||
this._logger = options.logger || logger;
|
||||
this._logger = options.logger || lib.logger;
|
||||
this._targetVersion = options.version || "latest";
|
||||
/** UDP port used for hosting the Factorio game server on */
|
||||
this.gamePort = options.gamePort || randomDynamicPort();
|
||||
@@ -483,9 +478,9 @@ class FactorioServer extends events.EventEmitter {
|
||||
this._stripRegExp = new RegExp(
|
||||
// The script printer formats paths using / on both windows and linux.
|
||||
// But the save path is printed with \ on windows and / on linux.
|
||||
`(${escapeRegExp(tempPath.replace(/\\/g, "/"))})|` +
|
||||
`(${escapeRegExp(writePath)})|` +
|
||||
`(\\.\\.\\.[${escapeRegExp(chars)}/]*?currently-playing/)`,
|
||||
`(${lib.escapeRegExp(tempPath.replace(/\\/g, "/"))})|` +
|
||||
`(${lib.escapeRegExp(writePath)})|` +
|
||||
`(\\.\\.\\.[${lib.escapeRegExp(chars)}/]*?currently-playing/)`,
|
||||
"g"
|
||||
);
|
||||
}
|
||||
@@ -691,10 +686,10 @@ class FactorioServer extends events.EventEmitter {
|
||||
}
|
||||
|
||||
_attachStdio() {
|
||||
let stdout = new LineSplitter({ readableObjectMode: true });
|
||||
let stdout = new lib.LineSplitter({ readableObjectMode: true });
|
||||
stdout.on("data", line => { this._handleOutput(line, "stdout"); });
|
||||
this._server.stdout.pipe(stdout);
|
||||
let stderr = new LineSplitter({ readableObjectMode: true });
|
||||
let stderr = new lib.LineSplitter({ readableObjectMode: true });
|
||||
stderr.on("data", line => { this._handleOutput(line, "stderr"); });
|
||||
this._server.stderr.pipe(stderr);
|
||||
}
|
||||
@@ -714,9 +709,9 @@ class FactorioServer extends events.EventEmitter {
|
||||
if (this._state !== "stopping") {
|
||||
if (signal === "SIGKILL") {
|
||||
if (this._killed) {
|
||||
this.emit("error", new libErrors.EnvironmentError("Factorio server was killed"));
|
||||
this.emit("error", new lib.EnvironmentError("Factorio server was killed"));
|
||||
} else {
|
||||
this.emit("error", new libErrors.EnvironmentError(
|
||||
this.emit("error", new lib.EnvironmentError(
|
||||
"Factorio server was unexpectedly killed, is the system low on memory?"
|
||||
));
|
||||
}
|
||||
@@ -729,13 +724,13 @@ class FactorioServer extends events.EventEmitter {
|
||||
msg = `Factorio server was unexpectedly shut by down by signal ${signal}`;
|
||||
}
|
||||
|
||||
this.emit("error", new libErrors.EnvironmentError(msg));
|
||||
this.emit("error", new lib.EnvironmentError(msg));
|
||||
|
||||
} else if (this._unexpected.length === 1) {
|
||||
this.emit("error", new libErrors.EnvironmentError(this._unexpected[0]));
|
||||
this.emit("error", new lib.EnvironmentError(this._unexpected[0]));
|
||||
|
||||
} else {
|
||||
this.emit("error", new libErrors.EnvironmentError(
|
||||
this.emit("error", new lib.EnvironmentError(
|
||||
"Factorio server unexpectedly shut down. Possible causes:"+
|
||||
`\n- ${this._unexpected.join("\n- ")}`
|
||||
));
|
||||
@@ -751,9 +746,9 @@ class FactorioServer extends events.EventEmitter {
|
||||
});
|
||||
this._server.on("error", err => {
|
||||
if (err.code === "EACCES") {
|
||||
this.emit("error", new libErrors.EnvironmentError("Unable to run server: Permission denied"));
|
||||
this.emit("error", new lib.EnvironmentError("Unable to run server: Permission denied"));
|
||||
} else {
|
||||
this.emit("error", new libErrors.EnvironmentError(`Unexpected error:\n${err.stack}`));
|
||||
this.emit("error", new lib.EnvironmentError(`Unexpected error:\n${err.stack}`));
|
||||
}
|
||||
|
||||
if (this._rconClient) {
|
||||
@@ -823,7 +818,7 @@ class FactorioServer extends events.EventEmitter {
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code === "EACCES") {
|
||||
throw new libErrors.EnvironmentError("Unable to run server: Permission denied");
|
||||
throw new lib.EnvironmentError("Unable to run server: Permission denied");
|
||||
}
|
||||
throw err;
|
||||
} finally {
|
||||
@@ -1132,23 +1127,23 @@ class FactorioServer extends events.EventEmitter {
|
||||
}
|
||||
|
||||
async _writeConfigIni() {
|
||||
let content = libIni.stringify({
|
||||
let content = lib.stringify({
|
||||
path: {
|
||||
"read-data": this.dataPath(),
|
||||
"write-data": this.writePath(),
|
||||
},
|
||||
});
|
||||
await libFileOps.safeOutputFile(this.writePath("config.ini"), content);
|
||||
await lib.safeOutputFile(this.writePath("config.ini"), content);
|
||||
}
|
||||
|
||||
async _writeMapSettings(mapGenSettings, mapSettings) {
|
||||
if (mapGenSettings) {
|
||||
await libFileOps.safeOutputFile(
|
||||
await lib.safeOutputFile(
|
||||
this.writePath("map-gen-settings.json"), JSON.stringify(mapGenSettings, null, 4)
|
||||
);
|
||||
}
|
||||
if (mapSettings) {
|
||||
await libFileOps.safeOutputFile(
|
||||
await lib.safeOutputFile(
|
||||
this.writePath("map-settings.json"), JSON.stringify(mapSettings, null, 4)
|
||||
);
|
||||
}
|
||||
@@ -16,12 +16,9 @@
|
||||
"chalk": "^4.1.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fs-extra": "^11.1.1",
|
||||
"jimp": "^0.22.8",
|
||||
"jsonwebtoken": "^9.0.1",
|
||||
"jszip": "^3.10.1",
|
||||
"klaw": "^4.1.0",
|
||||
"rcon-client": "^4.2.3",
|
||||
"semver": "^7.5.4",
|
||||
"set-blocking": "^2.0.0",
|
||||
"triple-beam": "^1.4.1",
|
||||
"winston": "^3.10.0",
|
||||
|
||||
@@ -5,13 +5,7 @@
|
||||
*/
|
||||
"use strict";
|
||||
const exchange_string = require("./exchange_string");
|
||||
const export_ = require("./export");
|
||||
const patch = require("./patch");
|
||||
const server = require("./server");
|
||||
|
||||
module.exports = {
|
||||
...exchange_string,
|
||||
...export_,
|
||||
...patch,
|
||||
...server,
|
||||
};
|
||||
@@ -2,20 +2,21 @@
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { FactorioServer } = require("@clusterio/host/src/server");
|
||||
const { _exportLocale } = require("@clusterio/host/src/export");
|
||||
|
||||
|
||||
describe("lib/factorio/export", function() {
|
||||
describe("host/src/export", function() {
|
||||
describe("exportLocale()", function() {
|
||||
let testServer;
|
||||
before(async function() {
|
||||
let writePath = path.join("temp", "test", "server");
|
||||
testServer = new lib.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
|
||||
testServer = new FactorioServer(path.join("test", "file", "factorio"), writePath, {});
|
||||
await testServer.init();
|
||||
});
|
||||
|
||||
it("returns a flattened mapping with locale definitions", async function() {
|
||||
let locale = await lib._exportLocale(testServer, new Map(), ["base"], "en");
|
||||
let locale = await _exportLocale(testServer, new Map(), ["base"], "en");
|
||||
assert.deepEqual(locale, new Map([["test.key-a", "1"], ["test.key-b", "2"]]));
|
||||
});
|
||||
});
|
||||
@@ -4,10 +4,10 @@ const fs = require("fs-extra");
|
||||
const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const patch = require("@clusterio/host/src/patch");
|
||||
|
||||
|
||||
describe("lib/factorio", function() {
|
||||
describe("host/patch", function() {
|
||||
describe("generateLoader()", function() {
|
||||
let reference = [
|
||||
"-- Auto generated scenario module loader created by Clusterio",
|
||||
@@ -38,7 +38,7 @@ describe("lib/factorio", function() {
|
||||
};
|
||||
|
||||
it("should produce output matching the reference", function() {
|
||||
assert.equal(lib._generateLoader(patchInfo), reference);
|
||||
assert.equal(patch._generateLoader(patchInfo), reference);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
|
||||
{ name: "b", version: "1.0.0", dependencies: {} },
|
||||
];
|
||||
lib._reorderDependencies(modules);
|
||||
patch._reorderDependencies(modules);
|
||||
assert(modules[0].name === "b", "Dependency was not reorederd");
|
||||
});
|
||||
it("should throw on invalid version", function() {
|
||||
@@ -56,7 +56,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "a", version: "foo", dependencies: {} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Invalid version 'foo' for module a")
|
||||
);
|
||||
});
|
||||
@@ -65,7 +65,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "a", version: "1.0.0", dependencies: {"b": "invalid"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Invalid version range 'invalid' for dependency b on module a")
|
||||
);
|
||||
});
|
||||
@@ -74,7 +74,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Missing dependency b for module a")
|
||||
);
|
||||
modules = [
|
||||
@@ -83,7 +83,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "c", version: "1.0.0", dependencies: {"d": "*"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Missing dependency d for module c")
|
||||
);
|
||||
});
|
||||
@@ -93,7 +93,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "b", version: "1.0.0", dependencies: {"a": ">=2"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Module b requires a >=2")
|
||||
);
|
||||
});
|
||||
@@ -103,7 +103,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "b", version: "1.0.0", dependencies: {"a": "*"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Module dependency loop detected: a -> b -> a")
|
||||
);
|
||||
modules = [
|
||||
@@ -113,7 +113,7 @@ describe("lib/factorio", function() {
|
||||
{ name: "c", version: "1.0.0", dependencies: {"a": "*"} },
|
||||
];
|
||||
assert.throws(
|
||||
() => lib._reorderDependencies(modules),
|
||||
() => patch._reorderDependencies(modules),
|
||||
new Error("Module dependency loop detected: b -> c -> a -> b")
|
||||
);
|
||||
});
|
||||
@@ -153,7 +153,7 @@ describe("lib/factorio", function() {
|
||||
}
|
||||
let success = false;
|
||||
try {
|
||||
lib._reorderDependencies(modules);
|
||||
patch._reorderDependencies(modules);
|
||||
success = true;
|
||||
} catch (err) { }
|
||||
if (success) {
|
||||
@@ -176,7 +176,7 @@ describe("lib/factorio", function() {
|
||||
await fs.outputFile(zipPath, await zip.generateAsync({ type: "nodebuffer" }));
|
||||
|
||||
await assert.rejects(
|
||||
lib.patch(zipPath, []),
|
||||
patch.patch(zipPath, []),
|
||||
new Error("Unable to patch save, unknown scenario (3acc3be3861144e55604f5ac2f2555071885ebc4)")
|
||||
);
|
||||
});
|
||||
@@ -4,23 +4,24 @@ const events = require("events");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const hostServer = require("@clusterio/host/src/server");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { wait } = lib;
|
||||
const { testLines } = require("./lines");
|
||||
const { testLines } = require("../lib/factorio/lines");
|
||||
|
||||
|
||||
describe("lib/factorio/server", function() {
|
||||
describe("host/server", function() {
|
||||
describe("_getVersion()", function() {
|
||||
it("should get the version from a changelog", async function() {
|
||||
let version = await lib._getVersion(path.join("test", "file", "changelog-test.txt"));
|
||||
let version = await hostServer._getVersion(path.join("test", "file", "changelog-test.txt"));
|
||||
assert.equal(version, "0.1.1");
|
||||
});
|
||||
it("should return null if unable to find the version", async function() {
|
||||
let version = await lib._getVersion(path.join("test", "file", "changelog-bad.txt"));
|
||||
let version = await hostServer._getVersion(path.join("test", "file", "changelog-bad.txt"));
|
||||
assert.equal(version, null);
|
||||
});
|
||||
it("should return null if file does not exist", async function() {
|
||||
let version = await lib._getVersion(path.join("test", "file", "does-not-exist.txt"));
|
||||
let version = await hostServer._getVersion(path.join("test", "file", "does-not-exist.txt"));
|
||||
assert.equal(version, null);
|
||||
});
|
||||
});
|
||||
@@ -28,7 +29,7 @@ describe("lib/factorio/server", function() {
|
||||
describe("_versionOrder()", function() {
|
||||
it("should sort an array of versions", function() {
|
||||
let versions = ["1.2.3", "0.1.4", "0.1.2", "1.2.3", "0.1.5", "1.10.2"];
|
||||
versions.sort(lib._versionOrder);
|
||||
versions.sort(hostServer._versionOrder);
|
||||
assert.deepEqual(
|
||||
versions,
|
||||
["1.10.2", "1.2.3", "1.2.3", "0.1.5", "0.1.4", "0.1.2"]
|
||||
@@ -39,46 +40,46 @@ describe("lib/factorio/server", function() {
|
||||
describe("_findVersion()", function() {
|
||||
it("should find a given install dir with latest as target", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
let [dir, version] = await lib._findVersion(installDir, "latest");
|
||||
let [dir, version] = await hostServer._findVersion(installDir, "latest");
|
||||
assert.equal(dir, path.join(installDir, "data"));
|
||||
assert.equal(version, "0.1.1");
|
||||
});
|
||||
it("should find a given install dir with correct version as target", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
let [dir, version] = await lib._findVersion(installDir, "0.1.1");
|
||||
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
|
||||
assert.equal(dir, path.join(installDir, "data"));
|
||||
assert.equal(version, "0.1.1");
|
||||
});
|
||||
it("should reject if the install dir version does not match target version", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
await assert.rejects(
|
||||
lib._findVersion(installDir, "0.1.2"),
|
||||
hostServer._findVersion(installDir, "0.1.2"),
|
||||
new Error("Factorio version 0.1.2 was requested, but install directory contains 0.1.1")
|
||||
);
|
||||
});
|
||||
it("should search given directory for latest Factorio install", async function() {
|
||||
let installDir = path.join("test", "file");
|
||||
let [dir, version] = await lib._findVersion(installDir, "latest");
|
||||
let [dir, version] = await hostServer._findVersion(installDir, "latest");
|
||||
assert.equal(dir, path.join(installDir, "factorio", "data"));
|
||||
assert.equal(version, "0.1.1");
|
||||
});
|
||||
it("should search given directory for given Factorio install", async function() {
|
||||
let installDir = path.join("test", "file");
|
||||
let [dir, version] = await lib._findVersion(installDir, "0.1.1");
|
||||
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
|
||||
assert.equal(dir, path.join(installDir, "factorio", "data"));
|
||||
assert.equal(version, "0.1.1");
|
||||
});
|
||||
it("should reject if no factorio install with the given version was found", async function() {
|
||||
let installDir = path.join("test", "file");
|
||||
await assert.rejects(
|
||||
lib._findVersion(installDir, "0.1.2"),
|
||||
hostServer._findVersion(installDir, "0.1.2"),
|
||||
new Error("Unable to find Factorio version 0.1.2")
|
||||
);
|
||||
});
|
||||
it("should reject if no factorio install was found", async function() {
|
||||
let installDir = path.join("test", "file", "instances");
|
||||
await assert.rejects(
|
||||
lib._findVersion(installDir, "latest"),
|
||||
hostServer._findVersion(installDir, "latest"),
|
||||
new Error(`Unable to find any Factorio install in ${installDir}`)
|
||||
);
|
||||
});
|
||||
@@ -86,7 +87,7 @@ describe("lib/factorio/server", function() {
|
||||
|
||||
describe("randomDynamicPort()", function() {
|
||||
it("should return a port number", function() {
|
||||
let port = lib._randomDynamicPort();
|
||||
let port = hostServer._randomDynamicPort();
|
||||
assert.equal(typeof port, "number");
|
||||
assert(Number.isInteger(port));
|
||||
assert(0 <= port && port < 2**16);
|
||||
@@ -97,24 +98,24 @@ describe("lib/factorio/server", function() {
|
||||
return (49152 <= port && port <= 65535);
|
||||
}
|
||||
for (let i=0; i < 20; i++) {
|
||||
assert(validate(lib._randomDynamicPort()));
|
||||
assert(validate(hostServer._randomDynamicPort()));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("generatePassword()", function() {
|
||||
it("should return a string", async function() {
|
||||
let password = await lib._generatePassword(1);
|
||||
let password = await hostServer._generatePassword(1);
|
||||
assert.equal(typeof password, "string");
|
||||
});
|
||||
|
||||
it("should return a string of the given length", async function() {
|
||||
let password = await lib._generatePassword(10);
|
||||
let password = await hostServer._generatePassword(10);
|
||||
assert.equal(password.length, 10);
|
||||
});
|
||||
|
||||
it("should contain only a-z, A-Z, 0-9", async function() {
|
||||
let password = await lib._generatePassword(10);
|
||||
let password = await hostServer._generatePassword(10);
|
||||
assert(/^[a-zA-Z0-9]+$/.test(password), `${password} failed test`);
|
||||
});
|
||||
});
|
||||
@@ -123,7 +124,7 @@ describe("lib/factorio/server", function() {
|
||||
it("should parse the test lines", function() {
|
||||
for (let [line, reference] of testLines) {
|
||||
reference.source = "test";
|
||||
let output = lib._parseOutput(line, "test");
|
||||
let output = hostServer._parseOutput(line, "test");
|
||||
assert.deepEqual(output, reference);
|
||||
}
|
||||
});
|
||||
@@ -131,12 +132,12 @@ describe("lib/factorio/server", function() {
|
||||
|
||||
describe("class FactorioServer", function() {
|
||||
let writePath = path.join("temp", "test", "server");
|
||||
let server = new lib.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
|
||||
let server = new hostServer.FactorioServer(path.join("test", "file", "factorio"), writePath, {});
|
||||
|
||||
describe("constructor()", function() {
|
||||
it("should handle dashes in write path with strapPaths enabled", function() {
|
||||
// eslint-disable-next-line no-new
|
||||
new lib.FactorioServer(
|
||||
new hostServer.FactorioServer(
|
||||
path.join("test", "file", "factorio"),
|
||||
path.join("temp", "test", "server-1"),
|
||||
{ stripPaths: true }
|
||||
@@ -2,17 +2,18 @@
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { _exportLocale } = require("@clusterio/host/src/export");
|
||||
const { FactorioServer } = require("@clusterio/host/src/server");
|
||||
|
||||
|
||||
describe("Integration of lib/factorio/export", function() {
|
||||
describe("exportLocale()", function() {
|
||||
it("returns a nested Map with base game locale information", async function() {
|
||||
let writePath = path.join("temp", "test", "server");
|
||||
let testServer = new lib.FactorioServer("factorio", writePath, {});
|
||||
let testServer = new FactorioServer("factorio", writePath, {});
|
||||
await testServer.init();
|
||||
|
||||
let locale = await lib._exportLocale(testServer, new Map(), ["base"], "en");
|
||||
let locale = await _exportLocale(testServer, new Map(), ["base"], "en");
|
||||
|
||||
assert(locale instanceof Map, "locale is not a map");
|
||||
assert.equal(locale.get("entity-name.fish"), "Fish");
|
||||
|
||||
@@ -4,7 +4,7 @@ const fs = require("fs-extra");
|
||||
const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { patch } = require("@clusterio/host/src/patch");
|
||||
|
||||
const { slowTest } = require("./index");
|
||||
|
||||
@@ -17,7 +17,7 @@ describe("Integration of lib/factorio/patch", function() {
|
||||
let savePath = path.join("temp", "test", "integration", "saves", "test.zip");
|
||||
it("should patch a freeplay game", async function() {
|
||||
slowTest(this);
|
||||
await lib.patch(savePath, [{
|
||||
await patch(savePath, [{
|
||||
name: "test",
|
||||
version: "1.0.0",
|
||||
dependencies: {},
|
||||
@@ -39,7 +39,7 @@ describe("Integration of lib/factorio/patch", function() {
|
||||
});
|
||||
it("should remove old modules in a save", async function() {
|
||||
slowTest(this);
|
||||
await lib.patch(savePath, []);
|
||||
await patch(savePath, []);
|
||||
let zip = await JSZip.loadAsync(await fs.readFile(savePath));
|
||||
assert.equal(zip.file("test/modules/test/test.lua"), null);
|
||||
});
|
||||
|
||||
@@ -5,15 +5,16 @@ const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { FactorioServer, _getVersion } = require("@clusterio/host/src/server");
|
||||
const { logger } = lib;
|
||||
|
||||
const { slowTest } = require("./index");
|
||||
|
||||
|
||||
describe("Integration of lib/factorio/server", function() {
|
||||
describe("Integration of host/src/server", function() {
|
||||
describe("_getVersion()", function() {
|
||||
it("should get a version from factorio's changelog.txt", async function() {
|
||||
let version = await lib._getVersion(path.join("factorio", "data", "changelog.txt"));
|
||||
let version = await _getVersion(path.join("factorio", "data", "changelog.txt"));
|
||||
if (!/^\d+\.\d+\.\d+$/.test(version)) {
|
||||
assert.fail(`Detected version '${version}' does not followed the format x.y.z`);
|
||||
}
|
||||
@@ -22,7 +23,7 @@ describe("Integration of lib/factorio/server", function() {
|
||||
|
||||
describe("class FactorioServer", function() {
|
||||
let writePath = path.join("temp", "test", "integration");
|
||||
let server = new lib.FactorioServer("factorio", writePath, {});
|
||||
let server = new FactorioServer("factorio", writePath, {});
|
||||
let logFile;
|
||||
|
||||
before(async function() {
|
||||
|
||||
Reference in new issue
Block a user