mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 15:04:52 +09:00
Merge pull request #227 from Hornwitser/config-part-2
Config Rewrite Part 2
This commit is contained in:
33 files changed
+165
-781
No files matched your search
@@ -10,3 +10,6 @@ Breaking Changes
|
||||
- Node.js versions below 10 are no longer supported.
|
||||
- lib/authenticate no longer requires config to be passed to it. Breaks
|
||||
playerManager.
|
||||
- The masterIP and masterPort config entries has been merged into masterURL.
|
||||
Breaks discordChat, playerManager, serverSelect, trainTeleports and
|
||||
clusterioModel.
|
||||
@@ -9,7 +9,6 @@ if(process.argv.length < 3){
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const masterIP = `${config.masterIP}:${config.masterPort}`;
|
||||
const token = config.masterAuthToken
|
||||
let commandArray = process.argv;
|
||||
commandArray.shift();
|
||||
@@ -24,14 +23,14 @@ let command = commandArray.join(" ");
|
||||
let killBiters = `/silent-command local surface=game.surfaces[1] for key, entity in pairs(surface.find_entities_filtered({force="enemy"})) do entity.destroy() end`;
|
||||
|
||||
(async ()=>{
|
||||
needle.post(masterIP+"/api/runCommand", {
|
||||
needle.post(config.masterURL+"/api/runCommand", {
|
||||
broadcast:true,
|
||||
command,
|
||||
}, needleOptionsWithTokenAuthHeader, (err, resp) => {
|
||||
console.log(resp.body)
|
||||
});
|
||||
// setInterval(()=>{
|
||||
// needle.post(masterIP+"/api/runCommand", {
|
||||
// needle.post(config.masterURL+"/api/runCommand", {
|
||||
// broadcast:true,
|
||||
// command: killBiters,
|
||||
// }, needleOptionsWithTokenAuthHeader, (err, resp) => {
|
||||
|
||||
@@ -11,7 +11,7 @@ if(!options.name){
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
needle.post(config.masterIP+":"+config.masterPort+"/api/playerManager/deletePlayer", {
|
||||
needle.post(config.masterURL+"/api/playerManager/deletePlayer", {
|
||||
name: options.name,
|
||||
token: options.token
|
||||
}, (err, resp) => {
|
||||
|
||||
@@ -203,9 +203,7 @@ reboot when you are done, then proceed to the next steps. *reboots matter*
|
||||
|
||||
To connect to a master server running on a remote machine, open config.json with your favourite text editor (notepad++). You can also set it up to use the official server browser.
|
||||
|
||||
Change `masterIP `to something like `31.152.123.14` (provided by master server owner)
|
||||
|
||||
Change `masterPort` to something like `8080` (provided by master server owner)
|
||||
Change `masterURL `to something like `http://203.0.113.33:8080` (provided by master server owner)
|
||||
|
||||
Change `masterAuthToken` to the value found in `secret-api-token.txt` on the master server
|
||||
|
||||
|
||||
@@ -21,12 +21,6 @@ const configManager = require("lib/manager/configManager.js");
|
||||
const pluginManager = require("lib/manager/pluginManager");
|
||||
const hashFile = require('lib/hash').hashFile;
|
||||
|
||||
console.warn(`
|
||||
+==========================================================+
|
||||
I WARNING: This is the development branch for the 2.0 I
|
||||
I version of clusterio. Expect things to break. I
|
||||
+==========================================================+
|
||||
`);
|
||||
|
||||
// argument parsing
|
||||
const args = require('minimist')(process.argv.slice(2));
|
||||
@@ -35,33 +29,10 @@ const args = require('minimist')(process.argv.slice(2));
|
||||
var config = require(args.config || './config');
|
||||
var global = {};
|
||||
|
||||
if (!fs.existsSync(config.instanceDirectory)) {
|
||||
fs.mkdirSync(config.instanceDirectory);
|
||||
}
|
||||
if (!fs.existsSync("./sharedPlugins/")) {
|
||||
fs.mkdirSync("sharedPlugins");
|
||||
}
|
||||
if (!fs.existsSync("./sharedMods/")) {
|
||||
fs.mkdirSync("sharedMods");
|
||||
}
|
||||
const instance = process.argv[3];
|
||||
const instancedirectory = config.instanceDirectory + '/' + instance;
|
||||
const command = process.argv[2];
|
||||
|
||||
// Set the process title, shows up as the title of the CMD window on windows
|
||||
// and as the process name in ps/top on linux.
|
||||
process.title = "clusterioClient "+instance;
|
||||
|
||||
// add better stack traces on promise rejection
|
||||
process.on('unhandledRejection', r => console.log(r));
|
||||
|
||||
// make sure we have the master access token (can't write to master without it since clusterio 2.0)
|
||||
if(!config.masterAuthToken || typeof config.masterAuthToken !== "string"){
|
||||
console.error("ERROR invalid config!");
|
||||
console.error("Master server now needs an access token for write operations. As clusterio slaves depends \
|
||||
upon this, please add your token to config.json in the field named masterAuthToken. \
|
||||
You can retrieve your auth token from the master in secret-api-token.txt after running it once.");
|
||||
}
|
||||
const needleOptionsWithTokenAuthHeader = {
|
||||
compressed:true,
|
||||
headers: {
|
||||
@@ -118,9 +89,7 @@ function messageInterface(command, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// handle commandline parameters
|
||||
if (!command || command == "help" || command == "--help") {
|
||||
function printUsage() {
|
||||
console.error("Usage: ");
|
||||
console.error("node client.js start [instance name]");
|
||||
console.error("node client.js list");
|
||||
@@ -131,8 +100,9 @@ if (!command || command == "help" || command == "--help") {
|
||||
console.error("node client.js manage shared plugins install https://github.com/Danielv123/playerManager");
|
||||
console.error("For more management options, do");
|
||||
console.error("node client.js manage");
|
||||
process.exit(1);
|
||||
} else if (command == "list") {
|
||||
}
|
||||
|
||||
async function listPlugins() {
|
||||
let instanceNames = fileOps.getDirectoriesSync(config.instanceDirectory);
|
||||
instanceNames.unshift("Name:");
|
||||
let longestInstanceName = 0;
|
||||
@@ -175,8 +145,9 @@ if (!command || command == "help" || command == "--help") {
|
||||
});
|
||||
|
||||
displayLines.forEach(line => console.log(line));
|
||||
process.exit(0);
|
||||
} else if (command == "manage"){
|
||||
}
|
||||
|
||||
async function manage() {
|
||||
// console.log("Launching mod manager");
|
||||
//const fullUsage = 'node client.js manage [instance, "shared"] ["mods", "config"] ...';
|
||||
function usage(instance, tool, action){
|
||||
@@ -262,8 +233,9 @@ if (!command || command == "help" || command == "--help") {
|
||||
console.log('Usage:');
|
||||
usage(instance);
|
||||
}
|
||||
// process.exit(0);
|
||||
} else if (command == "delete") {
|
||||
}
|
||||
|
||||
async function deleteInstance() {
|
||||
if (!process.argv[3]) {
|
||||
console.error("Usage: node client.js delete [instance]");
|
||||
process.exit(1);
|
||||
@@ -275,7 +247,9 @@ if (!command || command == "help" || command == "--help") {
|
||||
console.error("Instance not found: " + process.argv[3]);
|
||||
process.exit(0);
|
||||
}
|
||||
} else if (command == "download") {
|
||||
}
|
||||
|
||||
async function downloadMod() {
|
||||
console.log("Downloading mods...");
|
||||
// get JSON data about releases
|
||||
let res = syncRequest('GET', 'https://api.github.com/repos/Danielv123/factorioClusterioMod/releases', {"headers":{"User-Agent":"factorioClusterio"}});
|
||||
@@ -292,11 +266,9 @@ if (!command || command == "help" || command == "--help") {
|
||||
response.pipe(file);
|
||||
}).end();
|
||||
}
|
||||
} else if (command == "start" && instance === undefined) {
|
||||
console.error("ERROR: No instanceName provided!");
|
||||
console.error("Usage: node client.js start [instanceName]");
|
||||
process.exit(0);
|
||||
} else if (command == "start" && typeof instance == "string" && instance != "/" && !fs.existsSync(instancedirectory)) {
|
||||
}
|
||||
|
||||
async function createInstance() {
|
||||
// if instance does not exist, create it
|
||||
console.log("Creating instance...");
|
||||
fs.mkdirSync(instancedirectory);
|
||||
@@ -403,8 +375,10 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n
|
||||
|
||||
process.exit(0);
|
||||
}
|
||||
});
|
||||
} else if (command == "start" && typeof instance == "string" && instance != "/" && fs.existsSync(instancedirectory)){(async () => {
|
||||
});
|
||||
}
|
||||
|
||||
async function startInstance() {
|
||||
// Exit if no instance specified (it should be, just a safeguard);
|
||||
if(instancedirectory != config.instanceDirectory+"/undefined"){
|
||||
var instanceconfig = require(path.resolve(instancedirectory,'config'));
|
||||
@@ -563,9 +537,61 @@ write-data=${ path.resolve(config.instanceDirectory, instance) }\r\n
|
||||
confirmedOrders = [];
|
||||
lastSignalCheck = Date.now();
|
||||
});
|
||||
})()} else {
|
||||
console.error("Invalid arguments, quitting.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
async function startClient() {
|
||||
if (!fs.existsSync(config.instanceDirectory)) {
|
||||
fs.mkdirSync(config.instanceDirectory);
|
||||
}
|
||||
if (!fs.existsSync("./sharedPlugins/")) {
|
||||
fs.mkdirSync("sharedPlugins");
|
||||
}
|
||||
if (!fs.existsSync("./sharedMods/")) {
|
||||
fs.mkdirSync("sharedMods");
|
||||
}
|
||||
|
||||
// Set the process title, shows up as the title of the CMD window on windows
|
||||
// and as the process name in ps/top on linux.
|
||||
process.title = "clusterioClient "+instance;
|
||||
|
||||
// add better stack traces on promise rejection
|
||||
process.on('unhandledRejection', r => console.log(r));
|
||||
|
||||
// make sure we have the master access token (can't write to master without it since clusterio 2.0)
|
||||
if(!config.masterAuthToken || typeof config.masterAuthToken !== "string"){
|
||||
console.error("ERROR invalid config!");
|
||||
console.error("Master server now needs an access token for write operations. As clusterio slaves depends \
|
||||
upon this, please add your token to config.json in the field named masterAuthToken. \
|
||||
You can retrieve your auth token from the master in secret-api-token.txt after running it once.");
|
||||
}
|
||||
|
||||
|
||||
// handle commandline parameters
|
||||
if (!command || command == "help" || command == "--help") {
|
||||
printUsage();
|
||||
process.exit(1);
|
||||
} else if (command == "list") {
|
||||
await listPlugins();
|
||||
process.exit(0);
|
||||
} else if (command == "manage"){
|
||||
await manage();
|
||||
// process.exit(0);
|
||||
} else if (command == "delete") {
|
||||
await deleteInstance();
|
||||
} else if (command == "download") {
|
||||
await downloadMod();
|
||||
} else if (command == "start" && instance === undefined) {
|
||||
console.error("ERROR: No instanceName provided!");
|
||||
console.error("Usage: node client.js start [instanceName]");
|
||||
process.exit(0);
|
||||
} else if (command == "start" && typeof instance == "string" && instance != "/" && !fs.existsSync(instancedirectory)) {
|
||||
await createInstance();
|
||||
} else if (command == "start" && typeof instance == "string" && instance != "/" && fs.existsSync(instancedirectory)) {
|
||||
await startInstance();
|
||||
} else {
|
||||
console.error("Invalid arguments, quitting.");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// ensure instancemanagement only ever runs once
|
||||
@@ -577,7 +603,7 @@ async function instanceManagement(instanceconfig) {
|
||||
console.log("Started instanceManagement();");
|
||||
|
||||
/* Open websocket connection to master */
|
||||
var socket = ioClient("http://"+config.masterIP+":"+config.masterPort);
|
||||
var socket = ioClient(config.masterURL);
|
||||
socket.on("hello", data => {
|
||||
console.log("SOCKET | registering slave!");
|
||||
socket.emit("registerSlave", {
|
||||
@@ -710,15 +736,15 @@ async function instanceManagement(instanceconfig) {
|
||||
}
|
||||
global.mac = mac;
|
||||
payload.mac = mac;
|
||||
// console.log("Registered our presence with master "+config.masterIP+" at " + payload.time);
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/getID', payload, needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
// console.log("Registered our presence with master "+config.masterURL+" at " + payload.time);
|
||||
needle.post(config.masterURL + '/api/getID', payload, needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
if (err && err.code != "ECONNRESET"){
|
||||
console.error("We got problems, something went wrong when contacting master"+config.masterIP+" at " + payload.time);
|
||||
console.error("We got problems, something went wrong when contacting master "+config.masterURL+" at " + payload.time);
|
||||
console.error(err);
|
||||
} else if (response && response.body) {
|
||||
// In the future we might be interested in whether or not we actually manage to send it, but honestly I don't care.
|
||||
if(response.body !== "ok") {
|
||||
console.log("Got no \"ok\" while registering our precense with master "+config.masterIP+" at " + payload.time);
|
||||
console.log("Got no \"ok\" while registering our precense with master "+config.masterURL+" at " + payload.time);
|
||||
console.log(response.body);
|
||||
}
|
||||
}
|
||||
@@ -744,7 +770,7 @@ async function instanceManagement(instanceconfig) {
|
||||
modName: modHashes[i].modName,
|
||||
hash: modHashes[i].hash,
|
||||
};
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/checkMod', payload, needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
needle.post(config.masterURL + '/api/checkMod', payload, needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
if(err) console.error("Unable to contact master server /api/checkMod! Please check your config.json.");
|
||||
if(response && body && body == "found") {
|
||||
console.log("master has mod "+modHashes[i].modName);
|
||||
@@ -754,7 +780,7 @@ async function instanceManagement(instanceconfig) {
|
||||
console.log("Sending mod: " + mod);
|
||||
// Send mods master says it wants
|
||||
// response.body is a string which is a modName.zip
|
||||
var req = request.post({url: "http://"+config.masterIP + ":" + config.masterPort + '/api/uploadMod',
|
||||
var req = request.post({url: config.masterURL + '/api/uploadMod',
|
||||
headers: {
|
||||
"x-access-token": config.masterAuthToken,
|
||||
},
|
||||
@@ -801,3 +827,25 @@ function hashMods(instanceName, callback) {
|
||||
callback(hashes.filter(entry => entry !== null));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (module === require.main) {
|
||||
console.warn(`
|
||||
+==========================================================+
|
||||
I WARNING: This is the development branch for the 2.0 I
|
||||
I version of clusterio. Expect things to break. I
|
||||
+==========================================================+
|
||||
`
|
||||
);
|
||||
startClient().catch(err => {
|
||||
console.error(`
|
||||
+---------------------------------------------------------------+
|
||||
| Unexpected error occured while starting client, please report |
|
||||
| it to https://github.com/clusterio/factorioClusterio/issues |
|
||||
+---------------------------------------------------------------+`
|
||||
);
|
||||
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
"__comment1": "IP players should connect to to join your servers, should be portforwarded and stuff",
|
||||
"publicIP": "localhost",
|
||||
|
||||
"__comment2": "IP the master web server runs at, can be ignored on the master system",
|
||||
"masterIP": "localhost",
|
||||
"__comment2": "URL the master web server runs at, can be ignored on the master system. Must not end with a slash",
|
||||
"masterURL": "http://localhost:8080",
|
||||
|
||||
"__commentMasterPort": "HTTP port for the master to listen to",
|
||||
"masterPort": 8080,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const NodeInstance_1 = require("./NodeInstance");
|
||||
const Point_1 = require("./Point");
|
||||
const Grid_1 = require("./Grid");
|
||||
/**
|
||||
* Manages all nodes within the cluster
|
||||
*/
|
||||
class ClusterManager {
|
||||
constructor() {
|
||||
this.Grid = new Grid_1.Grid();
|
||||
}
|
||||
/**
|
||||
* Generates a x*y grid of 1x1 nodes
|
||||
* @param width How wide to make the node grid
|
||||
* @param height How high to make the node grid
|
||||
* @param nodeNamePrefix The prefix used for the initial node names. The name will be in the format <prefix>_x_y.
|
||||
*/
|
||||
GenerateBasicGridOfNodes(width, height, nodeNamePrefix) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
for (let y = 0; y < height; y++) {
|
||||
let newNode = new NodeInstance_1.NodeInstance(nodeNamePrefix + "-" + (x + 1) + "-" + (y + 1), new Point_1.Point(x, y), 1, 1);
|
||||
this.Grid.AddNodeToGrid(newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Assigns all nodes that currently do not have a server assigned to the given server
|
||||
* @param server Server to assign all unassigned nodes to
|
||||
*/
|
||||
AssignAllUnassignedNodesToServer(server) {
|
||||
this.CheckServerArray(server);
|
||||
this.Grid.GetNodes()
|
||||
.filter(node => { node.Server === null; })
|
||||
.forEach(node => {
|
||||
server.AddNodeInstance(node);
|
||||
node.Server = server;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Assigns a node to a server
|
||||
* @param x x co-ordinate of the node
|
||||
* @param y y co-ordinate of the node
|
||||
* @param serverName server name
|
||||
*/
|
||||
AssignNodeToServer(x, y, server) {
|
||||
this._nodeArray[x][y].Server = server;
|
||||
}
|
||||
CheckServerArray(server) {
|
||||
let s = this._servers[server.Name];
|
||||
if (s == null) {
|
||||
this._servers[server.Name] = server;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ClusterManager = ClusterManager;
|
||||
//# sourceMappingURL=ClusterManager.js.map
|
||||
@@ -1,112 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const child_process = require("child_process");
|
||||
const needle = require("needle");
|
||||
const Helpers_1 = require("./Helpers");
|
||||
const fs = require("fs");
|
||||
const util = require("util");
|
||||
/**
|
||||
* Contains all interactions between the cluster model, the
|
||||
* Clusterio master.js/client.js infrastructure and the operating system.
|
||||
*/
|
||||
class ClusterioMasterProxy {
|
||||
constructor(masterIP, masterPort, masterAuthToken, serviceHostType) {
|
||||
this._masterIP = `${masterIP}:${masterPort}`;
|
||||
this._needleOptionsWithTokenAuthHeader = {
|
||||
headers: {
|
||||
'x-access-token': masterAuthToken,
|
||||
},
|
||||
};
|
||||
}
|
||||
async RunRconCommand(instanceId, command, logDescription) {
|
||||
console.log("Running command: " + logDescription);
|
||||
let request = { instanceID: instanceId, command };
|
||||
let response = await needle("post", this._masterIP + "/api/runCommand", request, this._needleOptionsWithTokenAuthHeader);
|
||||
}
|
||||
async GetSlaves() {
|
||||
let response = await needle("get", this._masterIP + "/api/slaves", this._needleOptionsWithTokenAuthHeader);
|
||||
let body = response.body;
|
||||
let slaves = new Array();
|
||||
Object.entries(body).forEach((keyValuePair, index, array) => {
|
||||
let slave = keyValuePair[1];
|
||||
slave.id = keyValuePair[0];
|
||||
slaves.push(slave);
|
||||
});
|
||||
return slaves;
|
||||
}
|
||||
async CreateNodeInstancesOnLocalServer(nodes) {
|
||||
await Helpers_1.asyncForEach(nodes, async (node) => {
|
||||
await this.CreateNodeInstanceOnLocalServer(node);
|
||||
});
|
||||
await Helpers_1.asyncForEach(nodes, async (node) => {
|
||||
await this.CreateTeleportZonesForANodeInstance(node);
|
||||
});
|
||||
await this.sleep(1000);
|
||||
await Helpers_1.asyncForEach(nodes, async (node) => {
|
||||
await this.CreateTeleportRestrictionsForANodeInstance(node);
|
||||
await this.sleep(100);
|
||||
});
|
||||
}
|
||||
async CreateNodeInstanceOnLocalServer(node) {
|
||||
console.log(`Creating instance ${node.Name}...`);
|
||||
await this.CreateNodeInstanceOnLocalServerUsingPm2(node);
|
||||
console.log("Waiting for node to connect to cluster master...");
|
||||
while (true) {
|
||||
await this.sleep(1000);
|
||||
//TODO: Use /api/getSlaveMeta/
|
||||
let slaves = await this.GetSlaves();
|
||||
let slave = slaves.find((slave, index, array) => slave.instanceName === node.Name);
|
||||
if (slave != null) {
|
||||
node.ClusterioWorldId = slave.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
async CreateNodeInstanceOnLocalServerUsingPm2(node) {
|
||||
let proc = child_process.spawn("pm2", ['start', '--name', node.Name, 'client.js', '--', 'start', node.Name]);
|
||||
proc.stdout.on('data', (data) => { console.log(`stdout: ${data}`); });
|
||||
proc.stderr.on('data', data => { console.log(`stderr: ${data}`); });
|
||||
proc.on('error', error => { console.log(`error: ${error}`); });
|
||||
}
|
||||
async CreateNodeInstanceOnLocalServerUsingScreen(node) {
|
||||
// first call of client.js start for a new node creates map from HotPatch scenario then exits.
|
||||
let proc = child_process.spawn("screen", ['-dmS', node.Name, '-L', '-Logfile', node.Name + '.log', 'node', 'client.js', 'start', node.Name]);
|
||||
proc.stdout.on('data', (data) => { console.log(`stdout: ${data}`); });
|
||||
proc.stderr.on('data', data => { console.log(`stderr: ${data}`); });
|
||||
proc.on('error', error => { console.log(`error: ${error}`); });
|
||||
console.log("Waiting for creation of new map...");
|
||||
// create awaiter for fs.readFile
|
||||
const readFile = util.promisify(fs.readFile);
|
||||
while (true) {
|
||||
await this.sleep(1000);
|
||||
let fileData = await readFile(node.Name + '.log');
|
||||
if (fileData.includes('Instance created')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// start node
|
||||
proc = child_process.spawn("screen", ['-dmS', node.Name, '-L', '-Logfile', node.Name + '.log', 'node', 'client.js', 'start', node.Name]);
|
||||
proc.stdout.on('data', data => { console.log(`stdout: ${data}`); });
|
||||
proc.stderr.on('data', data => { console.log(`stderr: ${data}`); });
|
||||
proc.on('error', error => { console.log(`error: ${error}`); });
|
||||
}
|
||||
async CreateTeleportZonesForANodeInstance(nodeInstance) {
|
||||
await Helpers_1.asyncForEach(nodeInstance.TeleportZones.values(), async (zone) => {
|
||||
let o = zone.GenerateTeleportZoneInFactorioCoordinates();
|
||||
let cmd = `CreateZone('${o[0]}',${o[1]},${o[2]},${o[3]},${o[4]},${o[5]},true)`;
|
||||
await this.RunRconCommand(nodeInstance.ClusterioWorldId, `/c remote.call('trainTeleports','runCode',\"${cmd}\")`, cmd);
|
||||
});
|
||||
}
|
||||
async CreateTeleportRestrictionsForANodeInstance(nodeInstance) {
|
||||
await Helpers_1.asyncForEach(nodeInstance.TeleportZones.values(), async (zone) => {
|
||||
let o = zone.GenerateZoneRestriction();
|
||||
let cmd = `CreateZoneRestriction(${o[0]},'${o[1]}','${o[2]}')`;
|
||||
await this.RunRconCommand(nodeInstance.ClusterioWorldId, `/c remote.call('trainTeleports','runCode',\"${cmd}\")`, cmd);
|
||||
});
|
||||
}
|
||||
sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
}
|
||||
exports.ClusterioMasterProxy = ClusterioMasterProxy;
|
||||
//# sourceMappingURL=ClusterioMasterProxy.js.map
|
||||
@@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/** The multiplier used to convert from the grid's coordinate system to factorio's.
|
||||
* 1000 means a 1x1 grid node will have a factorio map size of 1000x1000. */
|
||||
exports.GridToFactorioCoordinateSystemMultiplier = 1000;
|
||||
/** The width of teleport zones when they get created. */
|
||||
exports.TeleportZoneWidth = 50;
|
||||
//# sourceMappingURL=Config.js.map
|
||||
@@ -1,177 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const typescript_collections_1 = require("typescript-collections");
|
||||
const Point_1 = require("./Point");
|
||||
const TeleportZone_1 = require("./TeleportZone");
|
||||
const TeleportZoneDirection_1 = require("./TeleportZoneDirection");
|
||||
class Grid {
|
||||
constructor() {
|
||||
this._nodes = new typescript_collections_1.Dictionary();
|
||||
this._minX = 0;
|
||||
this._minY = 0;
|
||||
this._maxX = 0;
|
||||
this._maxY = 0;
|
||||
}
|
||||
GetNodes() {
|
||||
return this._nodes.values();
|
||||
}
|
||||
/**
|
||||
* Adds a node to the grid
|
||||
* @param topLeftCoordinate The top left x,y coordinate of the node
|
||||
* @param nodeInstance
|
||||
*/
|
||||
AddNodeToGrid(nodeInstance) {
|
||||
let topLeftCoordinate = nodeInstance.TopLeftCoordinate;
|
||||
let pointsToSave = new Array();
|
||||
// check all points that make up nodeInstance for existing nodes
|
||||
for (let x = topLeftCoordinate.X; x < topLeftCoordinate.X + nodeInstance.Width; x++) {
|
||||
for (let y = topLeftCoordinate.Y; y < topLeftCoordinate.Y + nodeInstance.Height; y++) {
|
||||
let currentPoint = new Point_1.Point(x, y);
|
||||
let existingNode = this._nodes.getValue(currentPoint);
|
||||
if (existingNode != null) {
|
||||
throw new Error("Cannot add node to grid - collision detected with node '" + existingNode.Name + "'");
|
||||
}
|
||||
pointsToSave.push(currentPoint);
|
||||
}
|
||||
}
|
||||
// no existing nodes found to assign node to these points
|
||||
for (let i = 0; i < pointsToSave.length; i++) {
|
||||
this._nodes.setValue(pointsToSave[i], nodeInstance);
|
||||
}
|
||||
//TODO: Refactor
|
||||
//#region Set up teleport zones
|
||||
// check surrounding points for nodes
|
||||
// check north points
|
||||
let y = topLeftCoordinate.Y - 1;
|
||||
for (let x = topLeftCoordinate.X; x < topLeftCoordinate.X + nodeInstance.Width; x++) {
|
||||
let currentPoint = new Point_1.Point(x, y);
|
||||
let existingNode = this._nodes.getValue(currentPoint);
|
||||
// found a node - set up teleport zone
|
||||
if (existingNode != null) {
|
||||
// Create/Update teleport node in existing node to new node
|
||||
let teleportZoneFromExistingToNew = existingNode.TeleportZones.getValue(nodeInstance.Key);
|
||||
if (teleportZoneFromExistingToNew == null) {
|
||||
teleportZoneFromExistingToNew = new TeleportZone_1.TeleportZone(existingNode, TeleportZoneDirection_1.TeleportZoneDirection.South, currentPoint, currentPoint, existingNode.TeleportZones.size(), nodeInstance);
|
||||
existingNode.TeleportZones.setValue(nodeInstance.Key, teleportZoneFromExistingToNew);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromExistingToNew.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
// Create/Update teleport node in new node to existing node
|
||||
let teleportZoneFromNewToExisting = nodeInstance.TeleportZones.getValue(existingNode.Key);
|
||||
let pointInNewNode = new Point_1.Point(currentPoint.X, currentPoint.Y + 1);
|
||||
if (teleportZoneFromNewToExisting == null) {
|
||||
teleportZoneFromNewToExisting = new TeleportZone_1.TeleportZone(nodeInstance, TeleportZoneDirection_1.TeleportZoneDirection.North, pointInNewNode, pointInNewNode, nodeInstance.TeleportZones.size(), existingNode);
|
||||
nodeInstance.TeleportZones.setValue(existingNode.Key, teleportZoneFromNewToExisting);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromNewToExisting.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check south points
|
||||
y = topLeftCoordinate.Y + nodeInstance.Height + 1;
|
||||
for (let x = topLeftCoordinate.X; x < topLeftCoordinate.X + nodeInstance.Width; x++) {
|
||||
let currentPoint = new Point_1.Point(x, y);
|
||||
let existingNode = this._nodes.getValue(currentPoint);
|
||||
// found a node - set up teleport zone
|
||||
if (existingNode != null) {
|
||||
// Create/Update teleport node in existing node to new node
|
||||
let teleportZoneFromExistingToNew = existingNode.TeleportZones.getValue(nodeInstance.Key);
|
||||
if (teleportZoneFromExistingToNew == null) {
|
||||
teleportZoneFromExistingToNew = new TeleportZone_1.TeleportZone(existingNode, TeleportZoneDirection_1.TeleportZoneDirection.North, currentPoint, currentPoint, existingNode.TeleportZones.size(), nodeInstance);
|
||||
existingNode.TeleportZones.setValue(nodeInstance.Key, teleportZoneFromExistingToNew);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromExistingToNew.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
// Create/Update teleport node in new node to existing node
|
||||
let teleportZoneFromNewToExisting = nodeInstance.TeleportZones.getValue(existingNode.Key);
|
||||
let pointInNewNode = new Point_1.Point(currentPoint.X, currentPoint.Y - 1);
|
||||
if (teleportZoneFromNewToExisting == null) {
|
||||
teleportZoneFromNewToExisting = new TeleportZone_1.TeleportZone(nodeInstance, TeleportZoneDirection_1.TeleportZoneDirection.South, pointInNewNode, pointInNewNode, nodeInstance.TeleportZones.size(), existingNode);
|
||||
nodeInstance.TeleportZones.setValue(existingNode.Key, teleportZoneFromNewToExisting);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromNewToExisting.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check west points
|
||||
let x = topLeftCoordinate.X - 1;
|
||||
for (let y = topLeftCoordinate.Y; y < topLeftCoordinate.Y + nodeInstance.Height; y++) {
|
||||
let currentPoint = new Point_1.Point(x, y);
|
||||
let existingNode = this._nodes.getValue(currentPoint);
|
||||
// found a node - set up teleport zone
|
||||
if (existingNode != null) {
|
||||
// Create/Update teleport node in existing node to new node
|
||||
let teleportZoneFromExistingToNew = existingNode.TeleportZones.getValue(nodeInstance.Key);
|
||||
if (teleportZoneFromExistingToNew == null) {
|
||||
teleportZoneFromExistingToNew = new TeleportZone_1.TeleportZone(existingNode, TeleportZoneDirection_1.TeleportZoneDirection.East, currentPoint, currentPoint, existingNode.TeleportZones.size(), nodeInstance);
|
||||
existingNode.TeleportZones.setValue(nodeInstance.Key, teleportZoneFromExistingToNew);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromExistingToNew.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
// Create/Update teleport node in new node to existing node
|
||||
let teleportZoneFromNewToExisting = nodeInstance.TeleportZones.getValue(existingNode.Key);
|
||||
let pointInNewNode = new Point_1.Point(currentPoint.X + 1, currentPoint.Y);
|
||||
if (teleportZoneFromNewToExisting == null) {
|
||||
teleportZoneFromNewToExisting = new TeleportZone_1.TeleportZone(nodeInstance, TeleportZoneDirection_1.TeleportZoneDirection.West, pointInNewNode, pointInNewNode, nodeInstance.TeleportZones.size(), existingNode);
|
||||
nodeInstance.TeleportZones.setValue(existingNode.Key, teleportZoneFromNewToExisting);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromNewToExisting.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check east points
|
||||
x = topLeftCoordinate.X + nodeInstance.Width + 1;
|
||||
for (let y = topLeftCoordinate.Y; y < topLeftCoordinate.Y + nodeInstance.Height; y++) {
|
||||
let currentPoint = new Point_1.Point(x, y);
|
||||
let existingNode = this._nodes.getValue(currentPoint);
|
||||
// found a node - set up teleport zone
|
||||
if (existingNode != null) {
|
||||
// Create/Update teleport node in existing node to new node
|
||||
let teleportZoneFromExistingToNew = existingNode.TeleportZones.getValue(nodeInstance.Key);
|
||||
if (teleportZoneFromExistingToNew == null) {
|
||||
teleportZoneFromExistingToNew = new TeleportZone_1.TeleportZone(existingNode, TeleportZoneDirection_1.TeleportZoneDirection.West, currentPoint, currentPoint, existingNode.TeleportZones.size(), nodeInstance);
|
||||
existingNode.TeleportZones.setValue(nodeInstance.Key, teleportZoneFromExistingToNew);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromExistingToNew.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
// Create/Update teleport node in new node to existing node
|
||||
let teleportZoneFromNewToExisting = nodeInstance.TeleportZones.getValue(existingNode.Key);
|
||||
let pointInNewNode = new Point_1.Point(currentPoint.X - 1, currentPoint.Y);
|
||||
if (teleportZoneFromNewToExisting == null) {
|
||||
teleportZoneFromNewToExisting = new TeleportZone_1.TeleportZone(nodeInstance, TeleportZoneDirection_1.TeleportZoneDirection.East, pointInNewNode, pointInNewNode, nodeInstance.TeleportZones.size(), existingNode);
|
||||
nodeInstance.TeleportZones.setValue(existingNode.Key, teleportZoneFromNewToExisting);
|
||||
}
|
||||
else {
|
||||
teleportZoneFromNewToExisting.BottomRightCoordinate = currentPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
this._nodes.setValue(topLeftCoordinate, nodeInstance);
|
||||
this._minX = Math.min(this._minX, topLeftCoordinate.X);
|
||||
this._minY = Math.min(this._minY, topLeftCoordinate.Y);
|
||||
this._maxX = Math.max(this._maxX, topLeftCoordinate.X + nodeInstance.Width);
|
||||
this._maxY = Math.max(this._maxY, topLeftCoordinate.Y + nodeInstance.Height);
|
||||
}
|
||||
get Width() {
|
||||
return this._maxX - this._minX;
|
||||
}
|
||||
get Height() {
|
||||
return this._maxY - this._minY;
|
||||
}
|
||||
get TopLeftCoordinate() {
|
||||
return new Point_1.Point(this._minX, this._minY);
|
||||
}
|
||||
get BottomRightCoordinate() {
|
||||
return new Point_1.Point(this._maxX, this._maxY);
|
||||
}
|
||||
}
|
||||
exports.Grid = Grid;
|
||||
//# sourceMappingURL=Grid.js.map
|
||||
@@ -1,10 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//TODO: Make generic
|
||||
async function asyncForEach(array, callback) {
|
||||
for (let index = 0; index < array.length; index++) {
|
||||
await callback(array[index], index, array);
|
||||
}
|
||||
}
|
||||
exports.asyncForEach = asyncForEach;
|
||||
//# sourceMappingURL=Helpers.js.map
|
||||
@@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=IApiSlaves.js.map
|
||||
@@ -1,3 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=IClusterioMasterProxy.js.map
|
||||
@@ -1,27 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
console.log("started.");
|
||||
const ClusterioMasterProxy_1 = require("./ClusterioMasterProxy");
|
||||
const ClusterManager_1 = require("./ClusterManager");
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
let configPath = argv['configPath'];
|
||||
if (configPath === undefined || configPath === null || configPath === "") {
|
||||
throw new Error("configPath is null.");
|
||||
}
|
||||
;
|
||||
let config = require(configPath);
|
||||
let proxy = new ClusterioMasterProxy_1.ClusterioMasterProxy(config.masterIP, config.masterPort, config.masterAuthToken);
|
||||
let manager = new ClusterManager_1.ClusterManager();
|
||||
manager.GenerateBasicGridOfNodes(2, 2, 'GridLockTest_');
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
// async function test() {
|
||||
// await asyncForEach([1,2,3], async (v, i, a) => {
|
||||
// console.log("test" + i);
|
||||
// await sleep(5000);
|
||||
// });
|
||||
// }
|
||||
// test();
|
||||
proxy.CreateNodeInstancesOnLocalServer(manager.Grid.GetNodes());
|
||||
//# sourceMappingURL=ModelController.js.map
|
||||
@@ -1,24 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
console.log("started.");
|
||||
const ClusterioMasterProxy_1 = require("./ClusterioMasterProxy");
|
||||
const ClusterManager_1 = require("./ClusterManager");
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
let configPath = argv['configPath'];
|
||||
if (configPath === undefined || configPath === null || configPath === "") {
|
||||
throw new Error("configPath is null.");
|
||||
}
|
||||
;
|
||||
let config = require(configPath);
|
||||
let proxy = new ClusterioMasterProxy_1.ClusterioMasterProxy(config.masterIP, config.masterPort, config.masterAuthToken);
|
||||
function sleep(ms) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
// main
|
||||
(async () => {
|
||||
let manager = new ClusterManager_1.ClusterManager();
|
||||
manager.GenerateBasicGridOfNodes(2, 2, 'GridLockTest');
|
||||
await proxy.CreateNodeInstancesOnLocalServer(manager.Grid.GetNodes());
|
||||
return;
|
||||
})();
|
||||
//# sourceMappingURL=ModelDemo.js.map
|
||||
@@ -1,61 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
console.log("Started.");
|
||||
const ClusterioMasterProxy_1 = require("./ClusterioMasterProxy");
|
||||
const ClusterManager_1 = require("./ClusterManager");
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
// arg: configPath
|
||||
// description: should point to the clusterio config.json file.
|
||||
let configPath = argv['configPath'];
|
||||
if (configPath === undefined || configPath === null || configPath === "") {
|
||||
configPath = "../../config.json";
|
||||
}
|
||||
;
|
||||
let config = require(configPath);
|
||||
// arg: mode
|
||||
// description: should be GenerateBasicGridOfNodes for now. Can extend in future.
|
||||
let mode = argv['mode'];
|
||||
if (mode === undefined || mode === null || mode === "") {
|
||||
throw new Error("mode is null. mode must be 'GenerateBasicGridOfNodes' (for now).");
|
||||
}
|
||||
;
|
||||
// arg: serviceHostType
|
||||
// description: what program to use to host the client.js instances.
|
||||
let serviceHostType = argv['serviceHostType'];
|
||||
if (serviceHostType === undefined || serviceHostType === null || serviceHostType === "") {
|
||||
throw new Error("serviceHostType is null. serviceHostType must be either 'pm2' or 'screen'.");
|
||||
}
|
||||
;
|
||||
if (serviceHostType != "pm2" && serviceHostType != "screen") {
|
||||
throw new Error("serviceHostType must be either 'pm2' or 'screen'.");
|
||||
}
|
||||
// arg: width
|
||||
// description: width of node grid
|
||||
let width = argv['width'];
|
||||
if (width === undefined || width === null || width === "") {
|
||||
throw new Error("width is null. width must be an int > 0.");
|
||||
}
|
||||
;
|
||||
// arg: height
|
||||
// description: height of node grid
|
||||
let height = argv['height'];
|
||||
if (height === undefined || height === null || height === "") {
|
||||
throw new Error("height is null. height must be an int > 0.");
|
||||
}
|
||||
;
|
||||
// arg: namePrefix
|
||||
// description: namePrefix of node grid
|
||||
let namePrefix = argv['namePrefix'];
|
||||
if (namePrefix === undefined || namePrefix === null || namePrefix === "") {
|
||||
throw new Error("namePrefix is null.");
|
||||
}
|
||||
;
|
||||
let proxy = new ClusterioMasterProxy_1.ClusterioMasterProxy(config.masterIP, config.masterPort, config.masterAuthToken, serviceHostType);
|
||||
// main
|
||||
(async () => {
|
||||
let manager = new ClusterManager_1.ClusterManager();
|
||||
manager.GenerateBasicGridOfNodes(width, height, namePrefix);
|
||||
await proxy.CreateNodeInstancesOnLocalServer(manager.Grid.GetNodes());
|
||||
return;
|
||||
})();
|
||||
//# sourceMappingURL=ModelRunner.js.map
|
||||
@@ -1,29 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Point_1 = require("./Point");
|
||||
const typescript_collections_1 = require("typescript-collections");
|
||||
/**
|
||||
* An instance of a Factorio server. Multiple nodes can run on the same server.
|
||||
*/
|
||||
class NodeInstance {
|
||||
constructor(name, topLeftCoordinate, width, height) {
|
||||
this.TeleportZones = new typescript_collections_1.Dictionary();
|
||||
this.Name = name;
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
this.TopLeftCoordinate = topLeftCoordinate;
|
||||
}
|
||||
get BottomRightCoordinate() {
|
||||
return new Point_1.Point(this.TopLeftCoordinate.X + this.Width, this.TopLeftCoordinate.Y + this.Height);
|
||||
}
|
||||
// public AddTeleportZone(name: string, topLeftCoordinate: Point, bottomRightCoordinate: Point) {
|
||||
// this.TeleportZones.push(new TeleportZone(this, topLeftCoordinate, bottomRightCoordinate, name));
|
||||
// }
|
||||
AddTeleportZonePoint() {
|
||||
}
|
||||
get Key() {
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
exports.NodeInstance = NodeInstance;
|
||||
//# sourceMappingURL=NodeInstance.js.map
|
||||
@@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Point {
|
||||
/**
|
||||
* Constructs a Point. Will not accept NaNs.
|
||||
* @param x A number. Cannot be NaN.
|
||||
* @param y A number. Cannot be NaN.
|
||||
*/
|
||||
constructor(x, y) {
|
||||
this.toString = () => {
|
||||
return "(" + this.X + "," + this.Y + ")";
|
||||
};
|
||||
if (Number.isNaN(x)) {
|
||||
throw new Error("x is NaN. Will not construct Point.");
|
||||
}
|
||||
if (Number.isNaN(y)) {
|
||||
throw new Error("y is NaN. Will not construct Point.");
|
||||
}
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
/**
|
||||
* Constructs a Point from a string representation in the format (x,y). Will not accept NaNs.
|
||||
* @param vectorAsString A string in the format (x,y). Will not accept NaNs.
|
||||
*/
|
||||
static FromString(vectorAsString) {
|
||||
this.CheckChar('(', vectorAsString[0], vectorAsString);
|
||||
this.CheckChar(')', vectorAsString[vectorAsString.length - 1], vectorAsString);
|
||||
if (vectorAsString.indexOf(',') === -1) {
|
||||
throw new Error("vectorAsString is an invalid format. Cannot find ','. fullString: " + vectorAsString);
|
||||
}
|
||||
let splitStr = vectorAsString.substr(1, vectorAsString.length - 2).split(',');
|
||||
if (splitStr.length != 2) {
|
||||
throw new Error("vectorAsString is an invalid format. Expecting string in format (x,y). fullString: " + vectorAsString);
|
||||
}
|
||||
let x = parseInt(splitStr[0]);
|
||||
let y = parseInt(splitStr[1]);
|
||||
let v = new Point(x, y);
|
||||
return v;
|
||||
}
|
||||
static CheckChar(expectedChar, actualChar, fullString) {
|
||||
if (actualChar != expectedChar) {
|
||||
throw new Error("vectorAsString is an invalid format. Expecting: '" + expectedChar + "'. Actual: '" + actualChar + "'. fullString: " + fullString);
|
||||
}
|
||||
}
|
||||
equals(obj) {
|
||||
return this.X === obj.X && this.Y === obj.Y;
|
||||
}
|
||||
Add(p) {
|
||||
return new Point(this.X + p.X, this.Y + p.Y);
|
||||
}
|
||||
Subtract(p) {
|
||||
return new Point(this.X - p.X, this.Y - p.Y);
|
||||
}
|
||||
}
|
||||
exports.Point = Point;
|
||||
//# sourceMappingURL=Point.js.map
|
||||
@@ -1,16 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* A server. Can contain multiple nodes (Factorio server instances).
|
||||
*/
|
||||
class Server {
|
||||
constructor(name) {
|
||||
this.Nodes = new Array();
|
||||
this.Name = name;
|
||||
}
|
||||
AddNodeInstance(node) {
|
||||
this.Nodes.push(node);
|
||||
}
|
||||
}
|
||||
exports.Server = Server;
|
||||
//# sourceMappingURL=Server.js.map
|
||||
@@ -1,8 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ServiceHostType;
|
||||
(function (ServiceHostType) {
|
||||
ServiceHostType[ServiceHostType["pm2"] = 0] = "pm2";
|
||||
ServiceHostType[ServiceHostType["screen"] = 1] = "screen";
|
||||
})(ServiceHostType = exports.ServiceHostType || (exports.ServiceHostType = {}));
|
||||
//# sourceMappingURL=ServiceHostType.js.map
|
||||
@@ -1,64 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Point_1 = require("./Point");
|
||||
const TeleportZoneDirection_1 = require("./TeleportZoneDirection");
|
||||
const Config = require("./Config");
|
||||
class TeleportZone {
|
||||
constructor(parentNode, direction, topLeftCoordinate, bottomRightCoordinate, index, targetNode) {
|
||||
this.TopLeftCoordinate = topLeftCoordinate;
|
||||
this.BottomRightCoordinate = bottomRightCoordinate;
|
||||
this.ParentNode = parentNode;
|
||||
this.Direction = direction;
|
||||
this.Index = index;
|
||||
this.TargetNode = targetNode;
|
||||
}
|
||||
get Name() {
|
||||
return TeleportZoneDirection_1.TeleportZoneDirection[this.Direction] + " to " + this.TargetNode.Name;
|
||||
}
|
||||
// public AddRestriction(restrictingTeleportZone: TeleportZone) {
|
||||
// this.Restrictions.push(new TeleportZoneRestriction(this, restrictingTeleportZone));
|
||||
// }
|
||||
/**
|
||||
* Converts this teleport zone into Factorio map co-ordinates
|
||||
* @returns [name, topleft.x, topleft.y, width, height, zoneIndex]
|
||||
*/
|
||||
GenerateTeleportZoneInFactorioCoordinates() {
|
||||
// get where this zone is relative to the node itself
|
||||
let topLeftRelativeCoordinate = this.TopLeftCoordinate.Subtract(this.ParentNode.TopLeftCoordinate);
|
||||
// a grid coordinate point is equivalent to a 1x1 node, so bottomright = topleft.
|
||||
// add (1,1) to translate from area representation to coordinates representing actual points.
|
||||
let bottomRightRelativeCoordinate = this.BottomRightCoordinate
|
||||
.Subtract(this.ParentNode.TopLeftCoordinate)
|
||||
.Add(new Point_1.Point(1, 1));
|
||||
// Factorio map is e.g. (-500,-500) to (500, 500) for a 1000x1000 node.
|
||||
// We therefore need to offset our co-ordinates so that (0,0) is the center and not (width/2, height/2)
|
||||
let m = Config.GridToFactorioCoordinateSystemMultiplier;
|
||||
let factorioTeleportZoneTopLeft = new Point_1.Point(topLeftRelativeCoordinate.X * m - m / 2, topLeftRelativeCoordinate.Y * m - m / 2);
|
||||
let factorioTeleportZoneBottomRight = new Point_1.Point(bottomRightRelativeCoordinate.X * m - m / 2, bottomRightRelativeCoordinate.Y * m - m / 2);
|
||||
let zoneWidth = factorioTeleportZoneBottomRight.X - factorioTeleportZoneTopLeft.X;
|
||||
let zoneHeight = factorioTeleportZoneBottomRight.Y - factorioTeleportZoneTopLeft.Y;
|
||||
let tl = factorioTeleportZoneTopLeft;
|
||||
let br = factorioTeleportZoneBottomRight;
|
||||
let zw = Config.TeleportZoneWidth;
|
||||
switch (this.Direction) {
|
||||
case TeleportZoneDirection_1.TeleportZoneDirection.North:
|
||||
return [this.Name, tl.X, tl.Y, zoneWidth, zw, this.Index + 1];
|
||||
case TeleportZoneDirection_1.TeleportZoneDirection.West:
|
||||
return [this.Name, tl.X, tl.Y, zw, zoneHeight, this.Index + 1];
|
||||
case TeleportZoneDirection_1.TeleportZoneDirection.South:
|
||||
return [this.Name, tl.X, br.Y - zw, zoneWidth, zw, this.Index + 1];
|
||||
case TeleportZoneDirection_1.TeleportZoneDirection.East:
|
||||
return [this.Name, br.X - zw, tl.Y, zw, zoneHeight, this.Index + 1];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generates a zone restriction from this teleport zone to target zone
|
||||
* @returns [zoneIndex, targetNodeName, targetZoneName]
|
||||
*/
|
||||
GenerateZoneRestriction() {
|
||||
let targetZone = this.TargetNode.TeleportZones.getValue(this.ParentNode.Key);
|
||||
return [this.Index + 1, this.TargetNode.Name, targetZone.Name];
|
||||
}
|
||||
}
|
||||
exports.TeleportZone = TeleportZone;
|
||||
//# sourceMappingURL=TeleportZone.js.map
|
||||
@@ -1,10 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var TeleportZoneDirection;
|
||||
(function (TeleportZoneDirection) {
|
||||
TeleportZoneDirection[TeleportZoneDirection["North"] = 0] = "North";
|
||||
TeleportZoneDirection[TeleportZoneDirection["East"] = 1] = "East";
|
||||
TeleportZoneDirection[TeleportZoneDirection["South"] = 2] = "South";
|
||||
TeleportZoneDirection[TeleportZoneDirection["West"] = 3] = "West";
|
||||
})(TeleportZoneDirection = exports.TeleportZoneDirection || (exports.TeleportZoneDirection = {}));
|
||||
//# sourceMappingURL=TeleportZoneDirection.js.map
|
||||
@@ -1,10 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class TeleportZoneRestriction {
|
||||
constructor(parentTeleportZone, restrictingTeleportZone) {
|
||||
this.ParentTeleportZone = parentTeleportZone;
|
||||
this.RestrictingTeleportZone = restrictingTeleportZone;
|
||||
}
|
||||
}
|
||||
exports.TeleportZoneRestriction = TeleportZoneRestriction;
|
||||
//# sourceMappingURL=TeleportZoneRestriction.js.map
|
||||
@@ -1,13 +0,0 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("./ClusterManager"));
|
||||
__export(require("./NodeInstance"));
|
||||
__export(require("./Server"));
|
||||
__export(require("./TeleportZone"));
|
||||
__export(require("./TeleportZoneRestriction"));
|
||||
__export(require("./Point"));
|
||||
__export(require("./Grid"));
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -8,7 +8,7 @@ module.exports = function(config){
|
||||
return new Promise((resolve, reject) => {
|
||||
let instance = instances[instanceID];
|
||||
if(!instance){
|
||||
needle.get(config.masterIP+":"+config.masterPort+ '/api/slaves', (err, response) => {
|
||||
needle.get(config.masterURL + '/api/slaves', (err, response) => {
|
||||
if(err || response.statusCode != 200) {
|
||||
console.log("Unable to get JSON master/api/slaves, master might be unaccessible");
|
||||
} else if (response && response.body) {
|
||||
|
||||
@@ -25,9 +25,14 @@ class UPSdisplay {
|
||||
let UPS = Math.round(ticksInPeriod / (timePeriod/1000));
|
||||
// console.log("UPS: " + UPS);
|
||||
try{
|
||||
needle.post(this.config.masterIP+':'+this.config.masterPort+'/api/editSlaveMeta', {instanceID: this.config.unique, password: this.config.clientPassword, meta: {UPS:UPS, tick:this.tick}}, {headers: {'x-access-token': this.config.masterAuthToken}}, function(err, resp) {
|
||||
// success?
|
||||
});
|
||||
needle.post(
|
||||
this.config.masterURL+'/api/editSlaveMeta',
|
||||
{instanceID: this.config.unique, password: this.config.clientPassword, meta: {UPS:UPS, tick:this.tick}},
|
||||
{headers: {'x-access-token': this.config.masterAuthToken}},
|
||||
function(err, resp) {
|
||||
// success?
|
||||
}
|
||||
);
|
||||
} catch (err){
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
@@ -78,9 +78,14 @@ module.exports = class remoteCommands {
|
||||
}
|
||||
}
|
||||
console.log("Recorded flows, copper plate since last time: " + payload["copper-plate"]);
|
||||
needle.post(that.config.masterIP + ":" + that.config.masterPort + '/api/logStats', {timestamp: timestamp, instanceID: that.config.unique, data: payload}, needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
// we did it, keep going
|
||||
});
|
||||
needle.post(
|
||||
that.config.masterURL + '/api/logStats',
|
||||
{timestamp: timestamp, instanceID: that.config.unique, data: payload},
|
||||
needleOptionsWithTokenAuthHeader,
|
||||
function (err, response, body) {
|
||||
// we did it, keep going
|
||||
}
|
||||
);
|
||||
}
|
||||
oldTimestamp = timestamp;
|
||||
oldFlowStats = totalFlows;
|
||||
@@ -105,7 +110,7 @@ module.exports = class remoteCommands {
|
||||
g[0] = g[0].replace("\u0000", "");
|
||||
// console.log("exporting " + JSON.stringify(g));
|
||||
// send our entity and count to the master for him to keep track of
|
||||
needle.post(that.config.masterIP + ":" + that.config.masterPort + '/api/place', {
|
||||
needle.post(that.config.masterURL + '/api/place', {
|
||||
name: g[0],
|
||||
count: g[1],
|
||||
instanceName: instance, // name of instance
|
||||
@@ -168,7 +173,7 @@ module.exports = class remoteCommands {
|
||||
// request our items, one item at a time
|
||||
for (let i = 0; i < Object.keys(preparedPackage).length; i++) {
|
||||
// console.log(preparedPackage[Object.keys(preparedPackage)[i]]);
|
||||
needle.post(that.config.masterIP + ":" + that.config.masterPort + '/api/remove', preparedPackage[Object.keys(preparedPackage)[i]], needleOptionsWithTokenAuthHeader, function (err, response, body) {
|
||||
function callback(err, response, body) {
|
||||
if (response && response.body && typeof response.body == "object") {
|
||||
// buffer confirmed orders
|
||||
confirmedOrders[confirmedOrders.length] = {name:response.body.name,count:response.body.count}
|
||||
@@ -176,7 +181,13 @@ module.exports = class remoteCommands {
|
||||
console.log(`Imported ${response.body.count} ${response.body.name} from master`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
needle.post(
|
||||
that.config.masterURL + '/api/remove',
|
||||
preparedPackage[Object.keys(preparedPackage)[i]],
|
||||
needleOptionsWithTokenAuthHeader,
|
||||
callback
|
||||
);
|
||||
}
|
||||
// if we got some confirmed orders
|
||||
// console.log("Importing " + confirmedOrders.length + " items! " + JSON.stringify(confirmedOrders));
|
||||
@@ -195,7 +206,7 @@ module.exports = class remoteCommands {
|
||||
// COMBINATOR SIGNALS ---------------------------------------------------------
|
||||
// get inventory from Master and RCON it to our slave
|
||||
setInterval(() => {
|
||||
needle.get(that.config.masterIP + ":" + that.config.masterPort + '/api/inventory', function (err, response, body) {
|
||||
needle.get(that.config.masterURL + '/api/inventory', function (err, response, body) {
|
||||
if(err){
|
||||
console.error("Unable to get JSON master/api/inventory, master might be unaccessible");
|
||||
} else if (response && response.body) {
|
||||
@@ -307,7 +318,7 @@ module.exports = class remoteCommands {
|
||||
return new Promise((resolve, reject) => {
|
||||
let instance = this.instances[instanceID];
|
||||
if(!instance){
|
||||
needle.get(this.config.masterIP+":"+this.config.masterPort+ '/api/slaves', { compressed: true }, (err, response) => {
|
||||
needle.get(this.config.masterURL + '/api/slaves', { compressed: true }, (err, response) => {
|
||||
if(err || response.statusCode != 200) {
|
||||
console.log("Unable to get JSON master/api/slaves, master might be unaccessible");
|
||||
} else if (response && response.body) {
|
||||
|
||||
@@ -55,7 +55,7 @@ module.exports = class remoteCommands {
|
||||
return new Promise((resolve, reject) => {
|
||||
let instance = this.instances[instanceID];
|
||||
if(!instance){
|
||||
needle.get(this.config.masterIP+":"+this.config.masterPort+ '/api/slaves', { compressed: true }, (err, response) => {
|
||||
needle.get(this.config.masterURL + '/api/slaves', { compressed: true }, (err, response) => {
|
||||
if(err || response.statusCode != 200) {
|
||||
console.log("Unable to get JSON master/api/slaves, master might be unaccessible");
|
||||
} else if (response && response.body) {
|
||||
|
||||
@@ -60,7 +60,7 @@ function handleInventory(json, config, callback){
|
||||
}
|
||||
//console.log("Requesting: "+JSON.stringify(request));
|
||||
// request the difference from master
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/remove', request, {json:true,headers: {'x-access-token': config.masterAuthToken}}, function (err, response, body) {
|
||||
function callback(err, response, body) {
|
||||
if (!err && response && response.body && (typeof response.body == "object" || isJson(response.body))) {
|
||||
// confirmed orders, already removed from master inventory
|
||||
//response.body.name: response.body.count
|
||||
@@ -70,7 +70,13 @@ function handleInventory(json, config, callback){
|
||||
} else {
|
||||
collectStacks(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
needle.post(
|
||||
config.masterURL + '/api/remove',
|
||||
request,
|
||||
{json:true,headers: {'x-access-token': config.masterAuthToken}},
|
||||
callback
|
||||
);
|
||||
} else {
|
||||
collectStacks(false);
|
||||
}
|
||||
@@ -87,9 +93,14 @@ function handleInventory(json, config, callback){
|
||||
for(let i = 0; i < stackArray.length; i++){
|
||||
if(stackArray[i].count > 0){
|
||||
// console.log("Returning overflow: " + JSON.stringify(stackArray[i]));
|
||||
needle.post(config.masterIP + ":" + config.masterPort + '/api/place', stackArray[i], {headers: {'x-access-token': config.masterAuthToken}}, function (err, resp, body) {
|
||||
// console.log(body);
|
||||
});
|
||||
needle.post(
|
||||
config.masterURL + '/api/place',
|
||||
stackArray[i],
|
||||
{headers: {'x-access-token': config.masterAuthToken}},
|
||||
function (err, resp, body) {
|
||||
// console.log(body);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -127,7 +138,7 @@ function pollInventories(outputFile){
|
||||
//return "/silent-command "+'local a="{"for b,c in pairs(game.players)do if c.connected then local d=game.players[b].get_inventory(defines.inventory.player_main).get_contents()local e=game.players[b].get_quickbar().get_contents()local f={}for g=1,game.players[b].force.character_logistic_slot_count do f[g]=game.players[b].character.get_request_slot(g)end;a=a..b..":{inventory:{"for h,i in pairs(d)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;for h,i in pairs(e)do a=a.."['+"'"+'"..h.."'+"'"+']:"..i..","end;a=a.."},requestSlots:{"for h,i in pairs(f)do a=a.."['+"'"+'"..i["name"].."'+"'"+']:"..i["count"]..", "end;a=a.."}},"end end;a=a.."}"game.write_file("'+outputFile+'",a)'
|
||||
return '/silent-command '+'local a='+"'"+'{"players":{'+"'"+'local b=false;for c,d in pairs(game.players)do if d.connected and d.character then if b then a=a..'+"'"+','+"'"+'else b=true end;local e=game.players[c].get_inventory(defines.inventory.player_main).get_contents()local f=game.players[c].get_quickbar().get_contents()local g={}local z={}for j,k in pairs(e)do if z[j] ~= nil then z[j] = z[j] + k else z[j] = k end end for j,k in pairs(f)do if z[j] ~= nil then z[j] = z[j] + k else z[j] = k end end for h=1,game.players[c].force.character_logistic_slot_count do g[h]=game.players[c].character.get_request_slot(h)end;a=a..'+"'"+'"'+"'"+'..c..'+"'"+'":{"inventory":{'+"'"+'local i=false;for j,k in pairs(z)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..j..'+"'"+'":'+"'"+'..k end;a=a..'+"'"+'},"requestSlots":{'+"'"+'i=false;for j,k in pairs(g)do if i then a=a..'+"'"+','+"'"+'else i=true end;a=a..'+"'"+'"'+"'"+'..k['+"'"+'name'+"'"+']..'+"'"+'":'+"'"+'..k['+"'"+'count'+"'"+']end;a=a..'+"'"+'}}'+"'"+'end end;a=a.."}}"game.write_file("'+outputFile+'",a,true,0)'
|
||||
/*
|
||||
needle.post(config.masterIP+':'+config.masterPort+'/api/editSlaveMeta', {instanceID: config.unique, password: config.clientPassword, meta: {UPS:UPS}}, function(err, resp) {
|
||||
needle.post(config.masterURL+'/api/editSlaveMeta', {instanceID: config.unique, password: config.clientPassword, meta: {UPS:UPS}}, function(err, resp) {
|
||||
// success?
|
||||
});
|
||||
*/
|
||||
|
||||
@@ -12,8 +12,7 @@ const sinon = require("sinon");
|
||||
describe("inventoryImports/interfacingFunctions.js", function(){
|
||||
describe("handleInventory(inventory, config)", function(){
|
||||
let config = {
|
||||
masterIP:"localhost",
|
||||
masterPort:8080,
|
||||
masterURL:"http://localhost:8080",
|
||||
masterAuthToken:"",
|
||||
}
|
||||
it("returns false if given invalid input", function(){
|
||||
|
||||
@@ -50,7 +50,7 @@ class ResearchSync {
|
||||
}
|
||||
|
||||
initial_request_own_data(callback) {
|
||||
const url = `${this.config.masterIP}:${this.config.masterPort}/api/getSlaveMeta`
|
||||
const url = `${this.config.masterURL}/api/getSlaveMeta`
|
||||
const data = {
|
||||
instanceID: this.config.unique,
|
||||
password: this.config.clientPassword,
|
||||
@@ -102,7 +102,7 @@ class ResearchSync {
|
||||
}
|
||||
|
||||
request_cluster_data() {
|
||||
const slaves_data_url = `${this.config.masterIP}:${this.config.masterPort}/api/slaves`
|
||||
const slaves_data_url = `${this.config.masterURL}/api/slaves`
|
||||
needle.get(slaves_data_url, {compressed:true}, this.sync_researches.bind(this))
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ class ResearchSync {
|
||||
|
||||
this.print_own_contribution()
|
||||
|
||||
needle.post(this.config.masterIP + ':' + this.config.masterPort + '/api/editSlaveMeta', {
|
||||
needle.post(this.config.masterURL + '/api/editSlaveMeta', {
|
||||
instanceID: this.config.unique,
|
||||
password: this.config.clientPassword,
|
||||
meta: {research: this.research}
|
||||
|
||||
@@ -12,8 +12,7 @@ describe("researchSync/index.js", function() {
|
||||
|
||||
const config = {
|
||||
instanceName: "test",
|
||||
masterIP: "localhost",
|
||||
masterPort: 8080,
|
||||
masterURL: "http://localhost:8080",
|
||||
unique: 99,
|
||||
clientPassword: "password",
|
||||
masterAuthToken: "masterToken",
|
||||
|
||||
@@ -27,7 +27,7 @@ module.exports = class remoteCommands {
|
||||
force: force.forceName,
|
||||
forceData: JSON.stringify(force.data),
|
||||
};
|
||||
needle.post(`${mergedConfig.masterIP}:${mergedConfig.masterPort}/api/logStats`,
|
||||
needle.post(`${mergedConfig.masterURL}/api/logStats`,
|
||||
request,
|
||||
needleOptionsWithTokenAuthHeader, (err, resp) => {
|
||||
if(!err && resp.body && resp.body.ok == false) console.log("Error calling /api/logStats: " + resp.body);
|
||||
|
||||
Reference in new issue
Block a user