mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
159 files changed
+1887
-2013
No files matched your search
@@ -205,12 +205,13 @@ Fields in configs and messages sent over links uses lowercase_underscore.
|
||||
JavaScript files are named using lowercase_underscore for files that export multiple items.
|
||||
Files containing and exporting a single class should be named the same as the class in PascalCase.
|
||||
|
||||
Imported modules from the lib package are prefixed with lib to make them easier to distinguish, as the names tend to be very generic.
|
||||
Relative imports in lib package are prefixed with lib to make them easier to distinguish, as the names tend to be very generic.
|
||||
E.g.:
|
||||
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libLuaTools = require("@clusterio/lib/lua_tools");
|
||||
const libLink = require("./link");
|
||||
const libLuaTools = require("./lua_tools");
|
||||
|
||||
Note that no sub-modules of the lib package is imported directly from the outside of it with the exception of `build_mod`.
|
||||
|
||||
For lua code lowercase_underscore is used for everything.
|
||||
|
||||
|
||||
+12
-12
@@ -49,7 +49,7 @@ Without it the plugin will not recognized by Clusterio.
|
||||
Here's an example of it:
|
||||
|
||||
```js
|
||||
const { libLink } = require("@clusterio/lib"); // For messages
|
||||
const lib = require("@clusterio/lib"); // For messages
|
||||
|
||||
module.exports = {
|
||||
name: "foo_frobber",
|
||||
@@ -120,9 +120,9 @@ The plugin class should derive from its respective base class defined in `lib/pl
|
||||
For example, to define a ControllerPlugin class the following code can be used:
|
||||
|
||||
```js
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
class ControllerPlugin extends libPlugin.BaseControllerPlugin {
|
||||
class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
async init() {
|
||||
this.foo = 42;
|
||||
await this.startFrobnication();
|
||||
@@ -206,9 +206,9 @@ You can take advantage of it by subclassing `PluginConfigGroup`, setting `defaul
|
||||
For example in info.js:
|
||||
|
||||
```js
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
class ControllerConfigGroup extends libConfig.PluginConfigGroup { }
|
||||
class ControllerConfigGroup extends lib.PluginConfigGroup { }
|
||||
ControllerConfigGroup.defaultAccess = ["controller", "host", "control"];
|
||||
ControllerConfigGroup.groupName = "foo_frobber";
|
||||
ControllerConfigGroup.define({
|
||||
@@ -333,7 +333,7 @@ The Event constructor takes an object of properties that define the event, for e
|
||||
|
||||
```js
|
||||
messages: {
|
||||
startFrobnication: new libLink.Event({
|
||||
startFrobnication: new lib.Event({
|
||||
type: "foo_frobber:start_frobnication",
|
||||
links: ["controller-host", "host-instance"],
|
||||
forwardTo: "instance",
|
||||
@@ -408,7 +408,7 @@ For example, the following could be defined in `info.js`:
|
||||
|
||||
```js
|
||||
messages: {
|
||||
reportFrobnication: new libLink.Request({
|
||||
reportFrobnication: new lib.Request({
|
||||
type: "foo_frobber:report_frobnication",
|
||||
links: ["controller-host", "host-instance"],
|
||||
forwardTo: "instance",
|
||||
@@ -530,7 +530,7 @@ In its simplest form collecting data from plugins consists of defining the metri
|
||||
For example:
|
||||
|
||||
```js
|
||||
const { Counter } = require("@clusterio/lib/prometheus");
|
||||
const { Counter } = require("@clusterio/lib");
|
||||
|
||||
const fooMetric = new Counter(
|
||||
"clusterio_foo_frobber_foo_metric", "Measures the level of foo",
|
||||
@@ -546,7 +546,7 @@ It's recommended that plugin metrics follow `clusterio_<plugin_name>_<metric_nam
|
||||
For metrics that are per-instance, you must define an `instance_id` label and set it accordingly, for example:
|
||||
|
||||
```js
|
||||
const { Counter } = require("@clusterio/lib/prometheus");
|
||||
const { Counter } = require("@clusterio/lib");
|
||||
|
||||
const barMetric = new Gauge(
|
||||
"clusterio_foo_frobber_bar_metric", "Bar instance level",
|
||||
@@ -570,7 +570,7 @@ The control entrypoint for plugins allows you to extend clustectl with your own
|
||||
The creation of custom commands typically starts with defining a command tree for the plugin:
|
||||
|
||||
```js
|
||||
const { Command, CommandTree } = require("@clusterio/lib/command");
|
||||
const { Command, CommandTree } = require("@clusterio/lib");
|
||||
const fooFrobberCommands = new CommandTree({
|
||||
name: "foo-frobber", description: "Foo Frobber Plugin commands"
|
||||
});
|
||||
@@ -605,9 +605,9 @@ Note that messages sent from clusterioctl needs to have `"control-controller"` a
|
||||
To have the command tree become part of clusterioctl it needs to be added to the rootCommand tree in `addCommands` callback of the Control plugin:
|
||||
|
||||
```js
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
class ControlPlugin extends libPlugin.BaseControlPlugin {
|
||||
class ControlPlugin extends lib.BaseControlPlugin {
|
||||
async addCommands(rootCommand) {
|
||||
rootCommand.add(fooFrobberCommands);
|
||||
}
|
||||
|
||||
@@ -26,16 +26,8 @@ require("winston-daily-rotate-file");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
// homebrew modules
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libPluginLoader = require("@clusterio/lib/plugin_loader");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libUsers = require("@clusterio/lib/users");
|
||||
const libSharedCommands = require("@clusterio/lib/shared_commands");
|
||||
const { ConsoleTransport, levels, logger } = require("@clusterio/lib/logging");
|
||||
const libLoggingUtils = require("@clusterio/lib/logging_utils");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ConsoleTransport, levels, logger } = lib;
|
||||
|
||||
const Controller = require("./src/Controller");
|
||||
const UserManager = require("./src/UserManager");
|
||||
@@ -45,7 +37,7 @@ const version = require("./package").version;
|
||||
let controller;
|
||||
|
||||
|
||||
void new libPrometheus.Gauge(
|
||||
void new lib.Gauge(
|
||||
"clusterio_controller_host_mapping",
|
||||
"Mapping of Host ID to name",
|
||||
{
|
||||
@@ -65,7 +57,7 @@ void new libPrometheus.Gauge(
|
||||
}
|
||||
);
|
||||
|
||||
void new libPrometheus.Gauge(
|
||||
void new lib.Gauge(
|
||||
"clusterio_controller_instance_mapping",
|
||||
"Mapping of Instance ID to name and host",
|
||||
{
|
||||
@@ -86,19 +78,19 @@ void new libPrometheus.Gauge(
|
||||
}
|
||||
);
|
||||
|
||||
void new libPrometheus.Gauge(
|
||||
void new lib.Gauge(
|
||||
"clusterio_controller_websocket_active_connections",
|
||||
"How many WebSocket connections are currently open to the controller",
|
||||
{ callback: function(gauge) { gauge.set(controller.wsServer.activeConnectors.size); }}
|
||||
);
|
||||
|
||||
void new libPrometheus.Gauge(
|
||||
void new lib.Gauge(
|
||||
"clusterio_controller_active_hosts",
|
||||
"How many hosts are currently connected to the controller",
|
||||
{ callback: function(gauge) { gauge.set(controller.wsServer.hostConnections.size); }}
|
||||
);
|
||||
|
||||
void new libPrometheus.Gauge(
|
||||
void new lib.Gauge(
|
||||
"clusterio_controller_connected_clients_count", "How many clients are currently connected to this controller",
|
||||
{
|
||||
labels: ["type"], callback: async function(gauge) {
|
||||
@@ -125,7 +117,7 @@ async function handleBootstrapCommand(args, controllerConfig) {
|
||||
admin = userManager.createUser(args.name);
|
||||
}
|
||||
|
||||
let adminRole = libUsers.ensureDefaultAdminRole(userManager.roles);
|
||||
let adminRole = lib.ensureDefaultAdminRole(userManager.roles);
|
||||
admin.roles.add(adminRole);
|
||||
admin.isAdmin = true;
|
||||
await userManager.save(path.join(controllerConfig.get("controller.database_directory"), "users.json"));
|
||||
@@ -138,7 +130,7 @@ async function handleBootstrapCommand(args, controllerConfig) {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(user.createToken(controllerConfig.get("controller.auth_secret")));
|
||||
console.log(userManager.signUserToken(user.name));
|
||||
|
||||
} else if (subCommand === "generate-host-token") {
|
||||
// eslint-disable-next-line no-console
|
||||
@@ -154,12 +146,13 @@ async function handleBootstrapCommand(args, controllerConfig) {
|
||||
process.exitCode = 1;
|
||||
return;
|
||||
}
|
||||
let controlConfig = new libConfig.ControlConfig("control");
|
||||
let controlConfig = new lib.ControlConfig("control");
|
||||
await controlConfig.init();
|
||||
|
||||
controlConfig.set("control.controller_url", Controller.calculateControllerUrl(controllerConfig));
|
||||
controlConfig.set(
|
||||
"control.controller_token", admin.createToken(controllerConfig.get("controller.auth_secret"))
|
||||
"control.controller_token",
|
||||
userManager.signUserToken(admin.name),
|
||||
);
|
||||
|
||||
let content = JSON.stringify(controlConfig.serialize(), null, 4);
|
||||
@@ -168,7 +161,7 @@ async function handleBootstrapCommand(args, controllerConfig) {
|
||||
console.log(content);
|
||||
} else {
|
||||
logger.info(`Writing ${args.output}`);
|
||||
await libFileOps.safeOutputFile(args.output, content);
|
||||
await lib.safeOutputFile(args.output, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,8 +205,8 @@ async function initialize() {
|
||||
default: "plugin-list.json",
|
||||
type: "string",
|
||||
})
|
||||
.command("plugin", "Manage available plugins", libSharedCommands.pluginCommand)
|
||||
.command("config", "Manage Controller config", libSharedCommands.configCommand)
|
||||
.command("plugin", "Manage available plugins", lib.pluginCommand)
|
||||
.command("config", "Manage Controller config", lib.configCommand)
|
||||
.command("bootstrap", "Bootstrap access to cluster", yargs => {
|
||||
yargs
|
||||
.command("create-admin <name>", "Create a cluster admin")
|
||||
@@ -262,10 +255,10 @@ async function initialize() {
|
||||
if (parameters.args.logLevel !== "none") {
|
||||
logger.add(new ConsoleTransport({
|
||||
level: parameters.args.logLevel,
|
||||
format: new libLoggingUtils.TerminalFormat(),
|
||||
format: new lib.TerminalFormat(),
|
||||
}));
|
||||
}
|
||||
libLoggingUtils.handleUnhandledErrors(logger);
|
||||
lib.handleUnhandledErrors(logger);
|
||||
|
||||
let command = parameters.args._[0];
|
||||
if (command === "run") {
|
||||
@@ -285,19 +278,19 @@ async function initialize() {
|
||||
|
||||
// If the command is plugin management we don't try to load plugins
|
||||
if (command === "plugin") {
|
||||
await libSharedCommands.handlePluginCommand(parameters.args, pluginList, parameters.args.pluginList);
|
||||
await lib.handlePluginCommand(parameters.args, pluginList, parameters.args.pluginList);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
logger.info("Loading Plugin info");
|
||||
parameters.pluginInfos = await libPluginLoader.loadPluginInfos(pluginList);
|
||||
libLink.registerPluginMessages(parameters.pluginInfos);
|
||||
libConfig.registerPluginConfigGroups(parameters.pluginInfos);
|
||||
libConfig.finalizeConfigs();
|
||||
parameters.pluginInfos = await lib.loadPluginInfos(pluginList);
|
||||
lib.registerPluginMessages(parameters.pluginInfos);
|
||||
lib.registerPluginConfigGroups(parameters.pluginInfos);
|
||||
lib.finalizeConfigs();
|
||||
|
||||
parameters.controllerConfigPath = parameters.args.config;
|
||||
logger.info(`Loading config from ${parameters.controllerConfigPath}`);
|
||||
parameters.controllerConfig = new libConfig.ControllerConfig("controller");
|
||||
parameters.controllerConfig = new lib.ControllerConfig("controller");
|
||||
try {
|
||||
await parameters.controllerConfig.load(JSON.parse(await fs.readFile(parameters.controllerConfigPath)));
|
||||
|
||||
@@ -307,7 +300,7 @@ async function initialize() {
|
||||
await parameters.controllerConfig.init();
|
||||
|
||||
} else {
|
||||
throw new libErrors.StartupError(`Failed to load ${parameters.controllerConfigPath}: ${err.message}`);
|
||||
throw new lib.StartupError(`Failed to load ${parameters.controllerConfigPath}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,13 +309,13 @@ async function initialize() {
|
||||
let asyncRandomBytes = util.promisify(crypto.randomBytes);
|
||||
let bytes = await asyncRandomBytes(256);
|
||||
parameters.controllerConfig.set("controller.auth_secret", bytes.toString("base64"));
|
||||
await libFileOps.safeOutputFile(
|
||||
await lib.safeOutputFile(
|
||||
parameters.controllerConfigPath, JSON.stringify(parameters.controllerConfig.serialize(), null, 4)
|
||||
);
|
||||
}
|
||||
|
||||
if (command === "config") {
|
||||
await libSharedCommands.handleConfigCommand(
|
||||
await lib.handleConfigCommand(
|
||||
parameters.args, parameters.controllerConfig, parameters.controllerConfigPath
|
||||
);
|
||||
|
||||
@@ -393,14 +386,14 @@ I version of clusterio. Expect things to break. I
|
||||
`
|
||||
);
|
||||
startup().catch(err => {
|
||||
if (err instanceof libErrors.StartupError) {
|
||||
if (err instanceof lib.StartupError) {
|
||||
logger.fatal(`
|
||||
+-------------------------------+
|
||||
| Unable to to start controller |
|
||||
+-------------------------------+
|
||||
${err.stack}`
|
||||
);
|
||||
} else if (err instanceof libErrors.PluginError) {
|
||||
} else if (err instanceof lib.PluginError) {
|
||||
logger.fatal(`
|
||||
${err.pluginName} plugin threw an unexpected error
|
||||
during startup, please report it to the plugin author.
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
"use strict";
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
const ControllerRouter = require("./ControllerRouter");
|
||||
|
||||
|
||||
/**
|
||||
* Base class for controller connections
|
||||
*
|
||||
* @extends module:lib/link.Link
|
||||
* @extends module:lib.Link
|
||||
* @alias module:controller/src/BaseConnection
|
||||
*/
|
||||
class BaseConnection extends libLink.Link {
|
||||
class BaseConnection extends lib.Link {
|
||||
constructor(connector, controller) {
|
||||
/** @member {module:controller/src/WsServerConnector} module:controller/src/BaseConnection#connector */
|
||||
super(connector);
|
||||
@@ -24,15 +21,15 @@ class BaseConnection extends libLink.Link {
|
||||
for (let [Event, handler] of controller._registeredEvents) { this.handle(Event, handler); }
|
||||
for (let [Event, handler] of controller._snoopedEvents) { this.snoopEvent(Event, handler); }
|
||||
|
||||
this.handle(libData.ModPackGetRequest, this.handleModPackGetRequest.bind(this));
|
||||
this.handle(libData.ModPackGetDefaultRequest, this.handleModPackGetDefaultRequest.bind(this));
|
||||
this.handle(lib.ModPackGetRequest, this.handleModPackGetRequest.bind(this));
|
||||
this.handle(lib.ModPackGetDefaultRequest, this.handleModPackGetDefaultRequest.bind(this));
|
||||
}
|
||||
|
||||
async disconnect(code, reason) {
|
||||
try {
|
||||
await this.connector.disconnect();
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
logger.error(`"Unexpected error preparing disconnect:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
@@ -51,7 +48,7 @@ class BaseConnection extends libLink.Link {
|
||||
let { id } = request;
|
||||
let modPack = this._controller.modPacks.get(id);
|
||||
if (!modPack) {
|
||||
throw new libErrors.RequestError(`Mod pack with ID ${id} does not exist`);
|
||||
throw new lib.RequestError(`Mod pack with ID ${id} does not exist`);
|
||||
}
|
||||
return modPack;
|
||||
}
|
||||
@@ -59,11 +56,11 @@ class BaseConnection extends libLink.Link {
|
||||
async handleModPackGetDefaultRequest() {
|
||||
let id = this._controller.config.get("controller.default_mod_pack_id");
|
||||
if (id === null) {
|
||||
throw new libErrors.RequestError("Default mod pack not set on controller");
|
||||
throw new lib.RequestError("Default mod pack not set on controller");
|
||||
}
|
||||
let modPack = this._controller.modPacks.get(id);
|
||||
if (!modPack) {
|
||||
throw new libErrors.RequestError(`Default mod pack configured (${id}) does not exist`);
|
||||
throw new lib.RequestError(`Default mod pack configured (${id}) does not exist`);
|
||||
}
|
||||
return modPack;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,15 @@ const events = require("events");
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libHelpers = require("@clusterio/lib/helpers");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const { logFilter, logger } = require("@clusterio/lib/logging");
|
||||
const libLoggingUtils = require("@clusterio/lib/logging_utils");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const libUsers = require("@clusterio/lib/users");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logFilter, logger } = lib;
|
||||
|
||||
const BaseConnection = require("./BaseConnection");
|
||||
const routes = require("./routes");
|
||||
|
||||
const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare;
|
||||
|
||||
const queryLogTime = new libPrometheus.Summary(
|
||||
const queryLogTime = new lib.Summary(
|
||||
"clusterio_controller_query_log_duration_seconds",
|
||||
"Time in seconds log queries took to execute."
|
||||
);
|
||||
@@ -39,7 +32,7 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
/**
|
||||
* The user making this connection.
|
||||
* @type {module:lib/users.User}
|
||||
* @type {module:lib.User}
|
||||
*/
|
||||
this.user = user;
|
||||
|
||||
@@ -103,75 +96,75 @@ class ControlConnection extends BaseConnection {
|
||||
});
|
||||
}
|
||||
|
||||
this.handle(libData.ControllerConfigGetRequest, this.handleControllerConfigGetRequest.bind(this));
|
||||
this.handle(libData.ControllerConfigSetFieldRequest, this.handleControllerConfigSetFieldRequest.bind(this));
|
||||
this.handle(libData.ControllerConfigSetPropRequest, this.handleControllerConfigSetPropRequest.bind(this));
|
||||
this.handle(libData.HostListRequest, this.handleHostListRequest.bind(this));
|
||||
this.handle(libData.HostSetSubscriptionsRequest, this.handleHostSetSubscriptionsRequest.bind(this));
|
||||
this.handle(libData.HostGenerateTokenRequest, this.handleHostGenerateTokenRequest.bind(this));
|
||||
this.handle(libData.HostConfigCreateRequest, this.handleHostConfigCreateRequest.bind(this));
|
||||
this.handle(libData.InstanceDetailsGetRequest, this.handleInstanceDetailsGetRequest.bind(this));
|
||||
this.handle(libData.InstanceDetailsListRequest, this.handleInstanceDetailsListRequest.bind(this));
|
||||
this.handle(lib.ControllerConfigGetRequest, this.handleControllerConfigGetRequest.bind(this));
|
||||
this.handle(lib.ControllerConfigSetFieldRequest, this.handleControllerConfigSetFieldRequest.bind(this));
|
||||
this.handle(lib.ControllerConfigSetPropRequest, this.handleControllerConfigSetPropRequest.bind(this));
|
||||
this.handle(lib.HostListRequest, this.handleHostListRequest.bind(this));
|
||||
this.handle(lib.HostSetSubscriptionsRequest, this.handleHostSetSubscriptionsRequest.bind(this));
|
||||
this.handle(lib.HostGenerateTokenRequest, this.handleHostGenerateTokenRequest.bind(this));
|
||||
this.handle(lib.HostConfigCreateRequest, this.handleHostConfigCreateRequest.bind(this));
|
||||
this.handle(lib.InstanceDetailsGetRequest, this.handleInstanceDetailsGetRequest.bind(this));
|
||||
this.handle(lib.InstanceDetailsListRequest, this.handleInstanceDetailsListRequest.bind(this));
|
||||
this.handle(
|
||||
libData.InstanceDetailsSetSubscriptionsRequest, this.handleInstanceDetailsSetSubscriptionsRequest.bind(this)
|
||||
lib.InstanceDetailsSetSubscriptionsRequest, this.handleInstanceDetailsSetSubscriptionsRequest.bind(this)
|
||||
);
|
||||
this.handle(libData.InstanceCreateRequest, this.handleInstanceCreateRequest.bind(this));
|
||||
this.handle(libData.InstanceDeleteRequest, this.handleInstanceDeleteRequest.bind(this));
|
||||
this.handle(libData.InstanceConfigGetRequest, this.handleInstanceConfigGetRequest.bind(this));
|
||||
this.handle(libData.InstanceConfigSetFieldRequest, this.handleInstanceConfigSetFieldRequest.bind(this));
|
||||
this.handle(libData.InstanceConfigSetPropRequest, this.handleInstanceConfigSetPropRequest.bind(this));
|
||||
this.handle(libData.InstanceAssignRequest, this.handleInstanceAssignRequest.bind(this));
|
||||
this.handle(lib.InstanceCreateRequest, this.handleInstanceCreateRequest.bind(this));
|
||||
this.handle(lib.InstanceDeleteRequest, this.handleInstanceDeleteRequest.bind(this));
|
||||
this.handle(lib.InstanceConfigGetRequest, this.handleInstanceConfigGetRequest.bind(this));
|
||||
this.handle(lib.InstanceConfigSetFieldRequest, this.handleInstanceConfigSetFieldRequest.bind(this));
|
||||
this.handle(lib.InstanceConfigSetPropRequest, this.handleInstanceConfigSetPropRequest.bind(this));
|
||||
this.handle(lib.InstanceAssignRequest, this.handleInstanceAssignRequest.bind(this));
|
||||
this.handle(
|
||||
libData.InstanceSetSaveListSubscriptionsRequest,
|
||||
lib.InstanceSetSaveListSubscriptionsRequest,
|
||||
this.handleInstanceSetSaveListSubscriptionsRequest.bind(this)
|
||||
);
|
||||
this.handle(
|
||||
libData.InstanceRenameSaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller)
|
||||
lib.InstanceRenameSaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller)
|
||||
);
|
||||
this.handle(libData.InstanceCopySaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller));
|
||||
this.handle(lib.InstanceCopySaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller));
|
||||
this.handle(
|
||||
libData.InstanceDeleteSaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller)
|
||||
lib.InstanceDeleteSaveRequest, this._controller.sendToHostByInstanceId.bind(this._controller)
|
||||
);
|
||||
this.handle(libData.InstanceDownloadSaveRequest, this.handleInstanceDownloadSaveRequest.bind(this));
|
||||
this.handle(libData.InstanceTransferSaveRequest, this.handleInstanceTransferSaveRequest.bind(this));
|
||||
this.handle(libData.ModPackListRequest, this.handleModPackListRequest.bind(this));
|
||||
this.handle(libData.ModPackSetSubscriptionsRequest, this.handleModPackSetSubscriptionsRequest.bind(this));
|
||||
this.handle(libData.ModPackCreateRequest, this.handleModPackCreateRequest.bind(this));
|
||||
this.handle(libData.ModPackUpdateRequest, this.handleModPackUpdateRequest.bind(this));
|
||||
this.handle(libData.ModPackDeleteRequest, this.handleModPackDeleteRequest.bind(this));
|
||||
this.handle(libData.ModGetRequest, this.handleModGetRequest.bind(this));
|
||||
this.handle(libData.ModListRequest, this.handleModListRequest.bind(this));
|
||||
this.handle(libData.ModSearchRequest, this.handleModSearchRequest.bind(this));
|
||||
this.handle(libData.ModSetSubscriptionsRequest, this.handleModSetSubscriptionsRequest.bind(this));
|
||||
this.handle(libData.ModDownloadRequest, this.handleModDownloadRequest.bind(this));
|
||||
this.handle(libData.ModDeleteRequest, this.handleModDeleteRequest.bind(this));
|
||||
this.handle(libData.LogSetSubscriptionsRequest, this.handleLogSetSubscriptionsRequest.bind(this));
|
||||
this.handle(libData.LogQueryRequest, this.handleLogQueryRequest.bind(this));
|
||||
this.handle(libData.PermissionListRequest, this.handlePermissionListRequest.bind(this));
|
||||
this.handle(libData.RoleListRequest, this.handleRoleListRequest.bind(this));
|
||||
this.handle(libData.RoleCreateRequest, this.handleRoleCreateRequest.bind(this));
|
||||
this.handle(libData.RoleUpdateRequest, this.handleRoleUpdateRequest.bind(this));
|
||||
this.handle(lib.InstanceDownloadSaveRequest, this.handleInstanceDownloadSaveRequest.bind(this));
|
||||
this.handle(lib.InstanceTransferSaveRequest, this.handleInstanceTransferSaveRequest.bind(this));
|
||||
this.handle(lib.ModPackListRequest, this.handleModPackListRequest.bind(this));
|
||||
this.handle(lib.ModPackSetSubscriptionsRequest, this.handleModPackSetSubscriptionsRequest.bind(this));
|
||||
this.handle(lib.ModPackCreateRequest, this.handleModPackCreateRequest.bind(this));
|
||||
this.handle(lib.ModPackUpdateRequest, this.handleModPackUpdateRequest.bind(this));
|
||||
this.handle(lib.ModPackDeleteRequest, this.handleModPackDeleteRequest.bind(this));
|
||||
this.handle(lib.ModGetRequest, this.handleModGetRequest.bind(this));
|
||||
this.handle(lib.ModListRequest, this.handleModListRequest.bind(this));
|
||||
this.handle(lib.ModSearchRequest, this.handleModSearchRequest.bind(this));
|
||||
this.handle(lib.ModSetSubscriptionsRequest, this.handleModSetSubscriptionsRequest.bind(this));
|
||||
this.handle(lib.ModDownloadRequest, this.handleModDownloadRequest.bind(this));
|
||||
this.handle(lib.ModDeleteRequest, this.handleModDeleteRequest.bind(this));
|
||||
this.handle(lib.LogSetSubscriptionsRequest, this.handleLogSetSubscriptionsRequest.bind(this));
|
||||
this.handle(lib.LogQueryRequest, this.handleLogQueryRequest.bind(this));
|
||||
this.handle(lib.PermissionListRequest, this.handlePermissionListRequest.bind(this));
|
||||
this.handle(lib.RoleListRequest, this.handleRoleListRequest.bind(this));
|
||||
this.handle(lib.RoleCreateRequest, this.handleRoleCreateRequest.bind(this));
|
||||
this.handle(lib.RoleUpdateRequest, this.handleRoleUpdateRequest.bind(this));
|
||||
this.handle(
|
||||
libData.RoleGrantDefaultPermissionsRequest, this.handleRoleGrantDefaultPermissionsRequest.bind(this)
|
||||
lib.RoleGrantDefaultPermissionsRequest, this.handleRoleGrantDefaultPermissionsRequest.bind(this)
|
||||
);
|
||||
this.handle(libData.RoleDeleteRequest, this.handleRoleDeleteRequest.bind(this));
|
||||
this.handle(libData.UserGetRequest, this.handleUserGetRequest.bind(this));
|
||||
this.handle(libData.UserListRequest, this.handleUserListRequest.bind(this));
|
||||
this.handle(libData.UserSetSubscriptionsRequest, this.handleUserSetSubscriptionsRequest.bind(this));
|
||||
this.handle(libData.UserCreateRequest, this.handleUserCreateRequest.bind(this));
|
||||
this.handle(libData.UserRevokeTokenRequest, this.handleUserRevokeTokenRequest.bind(this));
|
||||
this.handle(libData.UserUpdateRolesRequest, this.handleUserUpdateRolesRequest.bind(this));
|
||||
this.handle(libData.UserSetAdminRequest, this.handleUserSetAdminRequest.bind(this));
|
||||
this.handle(libData.UserSetBannedRequest, this.handleUserSetBannedRequest.bind(this));
|
||||
this.handle(libData.UserSetWhitelistedRequest, this.handleUserSetWhitelistedRequest.bind(this));
|
||||
this.handle(libData.UserDeleteRequest, this.handleUserDeleteRequest.bind(this));
|
||||
this.handle(libData.DebugDumpWsRequest, this.handleDebugDumpWsRequest.bind(this));
|
||||
this.handle(lib.RoleDeleteRequest, this.handleRoleDeleteRequest.bind(this));
|
||||
this.handle(lib.UserGetRequest, this.handleUserGetRequest.bind(this));
|
||||
this.handle(lib.UserListRequest, this.handleUserListRequest.bind(this));
|
||||
this.handle(lib.UserSetSubscriptionsRequest, this.handleUserSetSubscriptionsRequest.bind(this));
|
||||
this.handle(lib.UserCreateRequest, this.handleUserCreateRequest.bind(this));
|
||||
this.handle(lib.UserRevokeTokenRequest, this.handleUserRevokeTokenRequest.bind(this));
|
||||
this.handle(lib.UserUpdateRolesRequest, this.handleUserUpdateRolesRequest.bind(this));
|
||||
this.handle(lib.UserSetAdminRequest, this.handleUserSetAdminRequest.bind(this));
|
||||
this.handle(lib.UserSetBannedRequest, this.handleUserSetBannedRequest.bind(this));
|
||||
this.handle(lib.UserSetWhitelistedRequest, this.handleUserSetWhitelistedRequest.bind(this));
|
||||
this.handle(lib.UserDeleteRequest, this.handleUserDeleteRequest.bind(this));
|
||||
this.handle(lib.DebugDumpWsRequest, this.handleDebugDumpWsRequest.bind(this));
|
||||
}
|
||||
|
||||
validateIngress(message) {
|
||||
let origin = this.connector.dst;
|
||||
if (origin.type !== message.src.type || origin.id !== message.src.id) {
|
||||
throw new libErrors.InvalidMessage(`Received message with invalid src ${message.src} from ${origin}`);
|
||||
throw new lib.InvalidMessage(`Received message with invalid src ${message.src} from ${origin}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +172,7 @@ class ControlConnection extends BaseConnection {
|
||||
try {
|
||||
this.checkPermission(message, entry);
|
||||
} catch (err) {
|
||||
this.connector.sendResponseError(new libData.ResponseError(err.message, err.code), message.src);
|
||||
this.connector.sendResponseError(new lib.ResponseError(err.message, err.code), message.src);
|
||||
logger.audit(`Permission denied for ${message.name} by ${this.user.name} from ${this.connector.dst}`);
|
||||
throw err;
|
||||
}
|
||||
@@ -213,7 +206,7 @@ class ControlConnection extends BaseConnection {
|
||||
}
|
||||
|
||||
async handleControllerConfigGetRequest() {
|
||||
return new libData.RawConfig(this._controller.config.serialize("control"));
|
||||
return new lib.RawConfig(this._controller.config.serialize("control"));
|
||||
}
|
||||
|
||||
async handleControllerConfigSetFieldRequest(request) {
|
||||
@@ -228,7 +221,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleHostListRequest() {
|
||||
let list = [];
|
||||
for (let host of this._controller.hosts.values()) {
|
||||
list.push(new libData.HostDetails(
|
||||
list.push(new lib.HostDetails(
|
||||
host.agent,
|
||||
host.version,
|
||||
host.name,
|
||||
@@ -249,7 +242,7 @@ class ControlConnection extends BaseConnection {
|
||||
this.hostSubscriptions.all
|
||||
|| this.hostSubscriptions.hostIds.includes(host.id)
|
||||
) {
|
||||
this.send(new libData.HostUpdateEvent(update));
|
||||
this.send(new lib.HostUpdateEvent(update));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +255,7 @@ class ControlConnection extends BaseConnection {
|
||||
}
|
||||
|
||||
async handleHostConfigCreateRequest(request) {
|
||||
let hostConfig = new libConfig.HostConfig("control");
|
||||
let hostConfig = new lib.HostConfig("control");
|
||||
await hostConfig.init();
|
||||
|
||||
hostConfig.set("host.controller_url", this._controller.getControllerUrl());
|
||||
@@ -276,13 +269,13 @@ class ControlConnection extends BaseConnection {
|
||||
this.user.checkPermission("core.host.generate_token");
|
||||
hostConfig.set("host.controller_token", this._controller.generateHostToken(hostConfig.get("host.id")));
|
||||
}
|
||||
return new libData.RawConfig(hostConfig.serialize());
|
||||
return new lib.RawConfig(hostConfig.serialize());
|
||||
}
|
||||
|
||||
async handleInstanceDetailsGetRequest(request) {
|
||||
let instance = this._controller.getRequestInstance(request.instanceId);
|
||||
|
||||
return new libData.InstanceDetails(
|
||||
return new lib.InstanceDetails(
|
||||
instance.config.get("instance.name"),
|
||||
instance.id,
|
||||
instance.config.get("instance.assigned_host"),
|
||||
@@ -294,7 +287,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleInstanceDetailsListRequest() {
|
||||
let list = [];
|
||||
for (let instance of this._controller.instances.values()) {
|
||||
list.push(new libData.InstanceDetails(
|
||||
list.push(new lib.InstanceDetails(
|
||||
instance.config.get("instance.name"),
|
||||
instance.id,
|
||||
instance.config.get("instance.assigned_host"),
|
||||
@@ -314,8 +307,8 @@ class ControlConnection extends BaseConnection {
|
||||
this.instanceSubscriptions.all
|
||||
|| this.instanceSubscriptions.instanceIds.includes(instance.id)
|
||||
) {
|
||||
this.send(new libData.InstanceDetailsUpdateEvent(
|
||||
new libData.InstanceDetails(
|
||||
this.send(new lib.InstanceDetailsUpdateEvent(
|
||||
new lib.InstanceDetails(
|
||||
instance.config.get("instance.name"),
|
||||
instance.id,
|
||||
instance.config.get("instance.assigned_host"),
|
||||
@@ -328,7 +321,7 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
// XXX should probably add a hook for host reuqests?
|
||||
async handleInstanceCreateRequest(request) {
|
||||
let instanceConfig = new libConfig.InstanceConfig("controller");
|
||||
let instanceConfig = new lib.InstanceConfig("controller");
|
||||
await instanceConfig.load(request.config);
|
||||
await this._controller.instanceCreate(instanceConfig);
|
||||
}
|
||||
@@ -339,18 +332,18 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
async handleInstanceConfigGetRequest(request) {
|
||||
let instance = this._controller.getRequestInstance(request.instanceId);
|
||||
return new libData.InstanceConfigGetRequest.Response(instance.config.serialize("control"));
|
||||
return new lib.InstanceConfigGetRequest.Response(instance.config.serialize("control"));
|
||||
}
|
||||
|
||||
async handleInstanceConfigSetFieldRequest(request) {
|
||||
let instance = this._controller.getRequestInstance(request.instanceId);
|
||||
if (request.field === "instance.assigned_host") {
|
||||
throw new libErrors.RequestError("instance.assigned_host must be set through the assign-host interface");
|
||||
throw new lib.RequestError("instance.assigned_host must be set through the assign-host interface");
|
||||
}
|
||||
|
||||
if (request.field === "instance.id") {
|
||||
// XXX is this worth implementing? It's race condition galore.
|
||||
throw new libErrors.RequestError("Setting instance.id is not supported");
|
||||
throw new lib.RequestError("Setting instance.id is not supported");
|
||||
}
|
||||
|
||||
instance.config.set(request.field, request.value, "control");
|
||||
@@ -377,7 +370,7 @@ class ControlConnection extends BaseConnection {
|
||||
this.saveListSubscriptions.all
|
||||
|| this.saveListSubscriptions.instanceIds.includes(instanceId)
|
||||
) {
|
||||
this.send(new libData.InstanceSaveListUpdateEvent(instanceId, saves));
|
||||
this.send(new lib.InstanceSaveListUpdateEvent(instanceId, saves));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,12 +382,12 @@ class ControlConnection extends BaseConnection {
|
||||
let ready = new Promise((resolve, reject) => {
|
||||
stream.events.on("source", resolve);
|
||||
stream.events.on("timeout", () => reject(
|
||||
new libErrors.RequestError("Timed out establishing stream from host")
|
||||
new lib.RequestError("Timed out establishing stream from host")
|
||||
));
|
||||
});
|
||||
ready.catch(() => {});
|
||||
|
||||
await this._controller.sendToHostByInstanceId(new libData.InstancePushSaveRequest(
|
||||
await this._controller.sendToHostByInstanceId(new lib.InstancePushSaveRequest(
|
||||
instanceId,
|
||||
stream.id,
|
||||
name,
|
||||
@@ -406,17 +399,17 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
async handleInstanceTransferSaveRequest(request) {
|
||||
if (request.sourceInstanceId === request.targetInstanceId) {
|
||||
throw new libErrors.RequestError("Source and target instance may not be the same");
|
||||
throw new lib.RequestError("Source and target instance may not be the same");
|
||||
}
|
||||
let sourceInstance = this._controller.getRequestInstance(request.sourceInstanceId);
|
||||
let targetInstance = this._controller.getRequestInstance(request.targetInstanceId);
|
||||
let sourceHostId = sourceInstance.config.get("instance.assigned_host");
|
||||
let targetHostId = targetInstance.config.get("instance.assigned_host");
|
||||
if (sourceHostId === null) {
|
||||
throw new libErrors.RequestError("Source instance is not assigned a host");
|
||||
throw new lib.RequestError("Source instance is not assigned a host");
|
||||
}
|
||||
if (targetHostId === null) {
|
||||
throw new libErrors.RequestError("Target instance is not assigned a host");
|
||||
throw new lib.RequestError("Target instance is not assigned a host");
|
||||
}
|
||||
|
||||
// Let host handle request if source and target is on the same host.
|
||||
@@ -427,12 +420,12 @@ class ControlConnection extends BaseConnection {
|
||||
// Check connectivity
|
||||
let sourceHostConnection = this._controller.wsServer.hostConnections.get(sourceHostId);
|
||||
if (!sourceHostConnection || sourceHostConnection.closing) {
|
||||
throw new libErrors.RequestError("Source host is not connected to the controller");
|
||||
throw new lib.RequestError("Source host is not connected to the controller");
|
||||
}
|
||||
|
||||
let targetHostConnection = this._controller.wsServer.hostConnections.get(targetHostId);
|
||||
if (!targetHostConnection || targetHostConnection.closing) {
|
||||
throw new libErrors.RequestError("Target host is not connected to the controller");
|
||||
throw new lib.RequestError("Target host is not connected to the controller");
|
||||
}
|
||||
|
||||
// Create stream to proxy from target to source
|
||||
@@ -441,7 +434,7 @@ class ControlConnection extends BaseConnection {
|
||||
if (stream.source) {
|
||||
stream.source.destroy();
|
||||
}
|
||||
stream.events.emit("error", new libErrors.RequestError("Timed out establishing transfer stream"));
|
||||
stream.events.emit("error", new lib.RequestError("Timed out establishing transfer stream"));
|
||||
});
|
||||
|
||||
// Ignore errors if not listening for them to avoid crash.
|
||||
@@ -452,7 +445,7 @@ class ControlConnection extends BaseConnection {
|
||||
await Promise.all([
|
||||
this._controller.sendTo(
|
||||
{ hostId: sourceHostId },
|
||||
new libData.InstancePushSaveRequest(request.sourceInstanceId, stream.id, request.sourceName),
|
||||
new lib.InstancePushSaveRequest(request.sourceInstanceId, stream.id, request.sourceName),
|
||||
),
|
||||
events.once(stream.events, "source"),
|
||||
]);
|
||||
@@ -460,14 +453,14 @@ class ControlConnection extends BaseConnection {
|
||||
// Establish pull from target host to stream and wait for completion.
|
||||
let storedName = await this._controller.sendTo(
|
||||
{ hostId: targetHostId },
|
||||
new libData.InstancePullSaveRequest(request.targetInstanceId, stream.id, request.targetName),
|
||||
new lib.InstancePullSaveRequest(request.targetInstanceId, stream.id, request.targetName),
|
||||
);
|
||||
|
||||
// Delete source save if this is not a copy
|
||||
if (!request.copy) {
|
||||
await this._controller.sendTo(
|
||||
{ hostId: sourceHostId },
|
||||
new libData.InstanceDeleteSaveRequest(request.sourceInstanceId, request.sourceName),
|
||||
new lib.InstanceDeleteSaveRequest(request.sourceInstanceId, request.sourceName),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -485,7 +478,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleModPackCreateRequest(request) {
|
||||
let modPack = request.modPack;
|
||||
if (this._controller.modPacks.has(modPack.id)) {
|
||||
throw new libErrors.RequestError(`Mod pack with ID ${modPack.id} already exist`);
|
||||
throw new lib.RequestError(`Mod pack with ID ${modPack.id} already exist`);
|
||||
}
|
||||
this._controller.modPacks.set(modPack.id, modPack);
|
||||
this._controller.modPackUpdated(modPack);
|
||||
@@ -494,7 +487,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleModPackUpdateRequest(request) {
|
||||
let modPack = request.modPack;
|
||||
if (!this._controller.modPacks.has(modPack.id)) {
|
||||
throw new libErrors.RequestError(`Mod pack with ID ${modPack.id} does not exist`);
|
||||
throw new lib.RequestError(`Mod pack with ID ${modPack.id} does not exist`);
|
||||
}
|
||||
this._controller.modPacks.set(modPack.id, modPack);
|
||||
this._controller.modPackUpdated(modPack);
|
||||
@@ -504,7 +497,7 @@ class ControlConnection extends BaseConnection {
|
||||
let { id } = request;
|
||||
let modPack = this._controller.modPacks.get(id);
|
||||
if (!modPack) {
|
||||
throw new libErrors.RequestError(`Mod pack with ID ${id} does not exist`);
|
||||
throw new lib.RequestError(`Mod pack with ID ${id} does not exist`);
|
||||
}
|
||||
modPack.isDeleted = true;
|
||||
this._controller.modPacks.delete(id);
|
||||
@@ -516,7 +509,7 @@ class ControlConnection extends BaseConnection {
|
||||
this.modPackSubscriptions.all
|
||||
|| this.modPackSubscriptions.modPackIds.includes(modPack.id)
|
||||
) {
|
||||
this.send(new libData.ModPackUpdateEvent(modPack));
|
||||
this.send(new lib.ModPackUpdateEvent(modPack));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,7 +518,7 @@ class ControlConnection extends BaseConnection {
|
||||
let filename = `${name}_${version}.zip`;
|
||||
let mod = this._controller.mods.get(filename);
|
||||
if (!mod) {
|
||||
throw new libErrors.RequestError(`Mod ${filename} does not exist`);
|
||||
throw new lib.RequestError(`Mod ${filename} does not exist`);
|
||||
}
|
||||
return mod;
|
||||
}
|
||||
@@ -537,14 +530,14 @@ class ControlConnection extends BaseConnection {
|
||||
static termsMatchesMod(terms, mod) {
|
||||
for (let term of terms) {
|
||||
if (term.type === "word") {
|
||||
if (!libHelpers.wordMatches(term,
|
||||
if (!lib.wordMatches(term,
|
||||
mod.name, mod.version, mod.title, mod.author, mod.contact,
|
||||
mod.homepage, mod.description, mod.filename
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
} else if (term.type === "attribute") {
|
||||
if (!libHelpers.wordMatches(term.value, mod[term.name])) {
|
||||
if (!lib.wordMatches(term.value, mod[term.name])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -553,7 +546,7 @@ class ControlConnection extends BaseConnection {
|
||||
}
|
||||
|
||||
async handleModSearchRequest(request) {
|
||||
let query = libHelpers.parseSearchString(request.query, {
|
||||
let query = lib.parseSearchString(request.query, {
|
||||
name: "word",
|
||||
// version
|
||||
title: "word",
|
||||
@@ -601,7 +594,7 @@ class ControlConnection extends BaseConnection {
|
||||
author: (a, b) => strcmp(a.versions[0].author, b.versions[0].author),
|
||||
};
|
||||
if (!Object.prototype.hasOwnProperty.call(sorters, sort)) {
|
||||
throw new libErrors.RequestError(`Invalid value for sort: ${sort}`);
|
||||
throw new lib.RequestError(`Invalid value for sort: ${sort}`);
|
||||
}
|
||||
resultList.sort(sorters[sort]);
|
||||
let order = request.sortOrder;
|
||||
@@ -631,7 +624,7 @@ class ControlConnection extends BaseConnection {
|
||||
let filename = `${name}_${version}.zip`;
|
||||
let mod = this._controller.mods.get(filename);
|
||||
if (!mod) {
|
||||
throw new libErrors.RequestError(`Mod ${filename} does not exist`);
|
||||
throw new lib.RequestError(`Mod ${filename} does not exist`);
|
||||
}
|
||||
let modPath = path.join(this._controller.config.get("controller.mods_directory"), mod.filename);
|
||||
|
||||
@@ -658,7 +651,7 @@ class ControlConnection extends BaseConnection {
|
||||
this.modSubscriptions.all
|
||||
|| this.modSubscriptions.modNames.includes(mod.name)
|
||||
) {
|
||||
this.send(new libData.ModUpdateEvent(mod));
|
||||
this.send(new lib.ModUpdateEvent(mod));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,7 +659,7 @@ class ControlConnection extends BaseConnection {
|
||||
let { all, controller, hostIds, instanceIds } = this.logSubscriptions;
|
||||
if (all || controller || hostIds.length || instanceIds.length) {
|
||||
if (!this.logTransport) {
|
||||
this.logTransport = new libLoggingUtils.LinkTransport({ link: this });
|
||||
this.logTransport = new lib.LinkTransport({ link: this });
|
||||
this._controller.clusterLogger.add(this.logTransport);
|
||||
}
|
||||
this.logTransport.filter = logFilter(this.logSubscriptions);
|
||||
@@ -694,8 +687,8 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
async handlePermissionListRequest() {
|
||||
let list = [];
|
||||
for (let permission of libUsers.permissions.values()) {
|
||||
list.push(new libData.RawPermission(
|
||||
for (let permission of lib.permissions.values()) {
|
||||
list.push(new lib.RawPermission(
|
||||
permission.name,
|
||||
permission.title,
|
||||
permission.description,
|
||||
@@ -707,7 +700,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleRoleListRequest() {
|
||||
let list = [];
|
||||
for (let role of this._controller.userManager.roles.values()) {
|
||||
list.push(new libData.RawRole(
|
||||
list.push(new lib.RawRole(
|
||||
role.id,
|
||||
role.name,
|
||||
role.description,
|
||||
@@ -722,7 +715,7 @@ class ControlConnection extends BaseConnection {
|
||||
|
||||
// Start at 5 to leave space for future default roles
|
||||
let id = Math.max(5, lastId+1);
|
||||
this._controller.userManager.roles.set(id, new libUsers.Role({ id, ...request }));
|
||||
this._controller.userManager.roles.set(id, new lib.Role({ id, ...request }));
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -730,7 +723,7 @@ class ControlConnection extends BaseConnection {
|
||||
let { id, name, description, permissions } = request;
|
||||
let role = this._controller.userManager.roles.get(id);
|
||||
if (!role) {
|
||||
throw new libErrors.RequestError(`Role with ID ${id} does not exist`);
|
||||
throw new lib.RequestError(`Role with ID ${id} does not exist`);
|
||||
}
|
||||
|
||||
role.name = name;
|
||||
@@ -742,7 +735,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleRoleGrantDefaultPermissionsRequest(request) {
|
||||
let role = this._controller.userManager.roles.get(request.id);
|
||||
if (!role) {
|
||||
throw new libErrors.RequestError(`Role with ID ${request.id} does not exist`);
|
||||
throw new lib.RequestError(`Role with ID ${request.id} does not exist`);
|
||||
}
|
||||
|
||||
role.grantDefaultPermissions();
|
||||
@@ -753,7 +746,7 @@ class ControlConnection extends BaseConnection {
|
||||
let id = request.id;
|
||||
let role = this._controller.userManager.roles.get(id);
|
||||
if (!role) {
|
||||
throw new libErrors.RequestError(`Role with ID ${id} does not exist`);
|
||||
throw new lib.RequestError(`Role with ID ${id} does not exist`);
|
||||
}
|
||||
|
||||
this._controller.userManager.roles.delete(id);
|
||||
@@ -767,10 +760,10 @@ class ControlConnection extends BaseConnection {
|
||||
let name = request.name;
|
||||
let user = this._controller.userManager.users.get(name);
|
||||
if (!user) {
|
||||
throw new libErrors.RequestError(`User ${name} does not exist`);
|
||||
throw new lib.RequestError(`User ${name} does not exist`);
|
||||
}
|
||||
|
||||
return new libData.RawUser(
|
||||
return new lib.RawUser(
|
||||
user.name,
|
||||
[...user.roles].map(role => role.id),
|
||||
[...user.instances],
|
||||
@@ -787,7 +780,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleUserListRequest() {
|
||||
let list = [];
|
||||
for (let user of this._controller.userManager.users.values()) {
|
||||
list.push(new libData.RawUser(
|
||||
list.push(new lib.RawUser(
|
||||
user.name,
|
||||
[...user.roles].map(role => role.id),
|
||||
[...user.instances],
|
||||
@@ -812,8 +805,8 @@ class ControlConnection extends BaseConnection {
|
||||
this.userSubscriptions.all
|
||||
|| this.userSubscriptions.names.includes(user.name)
|
||||
) {
|
||||
this.send(new libData.UserUpdateEvent(
|
||||
new libData.RawUser(
|
||||
this.send(new lib.UserUpdateEvent(
|
||||
new lib.RawUser(
|
||||
user.name,
|
||||
[...user.roles].map(role => role.id),
|
||||
[...user.instances],
|
||||
@@ -837,7 +830,7 @@ class ControlConnection extends BaseConnection {
|
||||
async handleUserRevokeTokenRequest(request) {
|
||||
let user = this._controller.userManager.users.get(request.name);
|
||||
if (!user) {
|
||||
throw new libErrors.RequestError(`User '${request.name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${request.name}' does not exist`);
|
||||
}
|
||||
if (user.name !== this.user.name) {
|
||||
this.user.checkPermission("core.user.revoke_other_token");
|
||||
@@ -855,14 +848,14 @@ class ControlConnection extends BaseConnection {
|
||||
async handleUserUpdateRolesRequest(request) {
|
||||
let user = this._controller.userManager.users.get(request.name);
|
||||
if (!user) {
|
||||
throw new libErrors.RequestError(`User '${request.name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${request.name}' does not exist`);
|
||||
}
|
||||
|
||||
let resolvedRoles = new Set();
|
||||
for (let roleId of request.roles) {
|
||||
let role = this._controller.userManager.roles.get(roleId);
|
||||
if (!role) {
|
||||
throw new libErrors.RequestError(`Role with ID ${roleId} does not exist`);
|
||||
throw new lib.RequestError(`Role with ID ${roleId} does not exist`);
|
||||
}
|
||||
|
||||
resolvedRoles.add(role);
|
||||
@@ -881,13 +874,13 @@ class ControlConnection extends BaseConnection {
|
||||
this.user.checkPermission("core.user.create");
|
||||
user = this._controller.userManager.createUser(name);
|
||||
} else {
|
||||
throw new libErrors.RequestError(`User '${name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${name}' does not exist`);
|
||||
}
|
||||
}
|
||||
|
||||
user.isAdmin = admin;
|
||||
this._controller.userUpdated(user);
|
||||
this._controller.sendTo("allInstances", new libData.InstanceAdminlistUpdateEvent(name, admin));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceAdminlistUpdateEvent(name, admin));
|
||||
}
|
||||
|
||||
async handleUserSetBannedRequest(request) {
|
||||
@@ -898,14 +891,14 @@ class ControlConnection extends BaseConnection {
|
||||
this.user.checkPermission("core.user.create");
|
||||
user = this._controller.userManager.createUser(name);
|
||||
} else {
|
||||
throw new libErrors.RequestError(`User '${name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${name}' does not exist`);
|
||||
}
|
||||
}
|
||||
|
||||
user.isBanned = banned;
|
||||
user.banReason = reason;
|
||||
this._controller.userUpdated(user);
|
||||
this._controller.sendTo("allInstances", new libData.InstanceBanlistUpdateEvent(name, banned, reason));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceBanlistUpdateEvent(name, banned, reason));
|
||||
}
|
||||
|
||||
async handleUserSetWhitelistedRequest(request) {
|
||||
@@ -916,20 +909,20 @@ class ControlConnection extends BaseConnection {
|
||||
this.user.checkPermission("core.user.create");
|
||||
user = this._controller.userManager.createUser(name);
|
||||
} else {
|
||||
throw new libErrors.RequestError(`User '${name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${name}' does not exist`);
|
||||
}
|
||||
}
|
||||
|
||||
user.isWhitelisted = whitelisted;
|
||||
this._controller.userUpdated(user);
|
||||
this._controller.sendTo("allInstances", new libData.InstanceWhitelistUpdateEvent(name, whitelisted));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceWhitelistUpdateEvent(name, whitelisted));
|
||||
}
|
||||
|
||||
async handleUserDeleteRequest(request) {
|
||||
let name = request.name;
|
||||
let user = this._controller.userManager.users.get(name);
|
||||
if (!user) {
|
||||
throw new libErrors.RequestError(`User '${name}' does not exist`);
|
||||
throw new lib.RequestError(`User '${name}' does not exist`);
|
||||
}
|
||||
|
||||
user.isDeleted = true;
|
||||
@@ -937,20 +930,20 @@ class ControlConnection extends BaseConnection {
|
||||
this._controller.userUpdated(user);
|
||||
|
||||
if (user.is_admin) {
|
||||
this._controller.sendTo("allInstances", new libData.InstanceAdminlistUpdateEvent(name, false));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceAdminlistUpdateEvent(name, false));
|
||||
}
|
||||
if (user.is_whitelisted) {
|
||||
this._controller.sendTo("allInstances", new libData.InstanceWhitelistUpdateEvent(name, false));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceWhitelistUpdateEvent(name, false));
|
||||
}
|
||||
if (user.is_banned) {
|
||||
this._controller.sendTo("allInstances", new libData.InstanceBanlistUpdateEvent(name, false, ""));
|
||||
this._controller.sendTo("allInstances", new lib.InstanceBanlistUpdateEvent(name, false, ""));
|
||||
}
|
||||
}
|
||||
|
||||
async handleDebugDumpWsRequest(request) {
|
||||
this.ws_dumper = data => {
|
||||
if (this.connector.connected) {
|
||||
this.send(new libData.DebugWsMessageEvent(data.direction, data.content));
|
||||
this.send(new lib.DebugWsMessageEvent(data.direction, data.content));
|
||||
}
|
||||
};
|
||||
this.connector._socket.clusterio_ignore_dump = true;
|
||||
|
||||
@@ -9,16 +9,8 @@ const jwt = require("jsonwebtoken");
|
||||
const path = require("path");
|
||||
const stream = require("stream");
|
||||
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libLoggingUtils = require("@clusterio/lib/logging_utils");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libPluginLoader = require("@clusterio/lib/plugin_loader");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
|
||||
const HttpCloser = require("./HttpCloser");
|
||||
const InstanceInfo = require("./InstanceInfo");
|
||||
@@ -28,13 +20,13 @@ const UserManager = require("./UserManager");
|
||||
const WsServer = require("./WsServer");
|
||||
|
||||
|
||||
const endpointDurationSummary = new libPrometheus.Summary(
|
||||
const endpointDurationSummary = new lib.Summary(
|
||||
"clusterio_controller_http_endpoint_duration_seconds",
|
||||
"Time it took to respond to a an HTTP request",
|
||||
{ labels: ["route"] }
|
||||
);
|
||||
|
||||
const logSizeGauge = new libPrometheus.Gauge(
|
||||
const logSizeGauge = new lib.Gauge(
|
||||
"clusterio_controller_log_bytes",
|
||||
"Size of all log files currently stored on the controller."
|
||||
);
|
||||
@@ -54,7 +46,7 @@ class Controller {
|
||||
this.configPath = configPath;
|
||||
/**
|
||||
* Controller config.
|
||||
* @type {module:lib/config.ControllerConfig}
|
||||
* @type {module:lib.ControllerConfig}
|
||||
*/
|
||||
this.config = config;
|
||||
|
||||
@@ -76,13 +68,13 @@ class Controller {
|
||||
|
||||
/**
|
||||
* Mapping of mod pack id to mod pack
|
||||
* @type {Map<number, module:lib/data.ModPack>}
|
||||
* @type {Map<number, module:lib.ModPack>}
|
||||
*/
|
||||
this.modPacks = null;
|
||||
|
||||
/**
|
||||
* Mapping of mod names to mod infos
|
||||
* @type {Map<string, module:lib/data.ModInfo>}
|
||||
* @type {Map<string, module:lib.ModInfo>}
|
||||
*/
|
||||
this.mods = null;
|
||||
|
||||
@@ -98,7 +90,7 @@ class Controller {
|
||||
|
||||
/**
|
||||
* Mapping of plugin name to loaded plugin
|
||||
* @type {Map<string, module:lib/plugin.BaseControllerPlugin>}
|
||||
* @type {Map<string, module:lib.BaseControllerPlugin>}
|
||||
*/
|
||||
this.plugins = new Map();
|
||||
|
||||
@@ -150,15 +142,15 @@ class Controller {
|
||||
*/
|
||||
async logSize() {
|
||||
return (await Promise.all([
|
||||
libFileOps.directorySize(path.join(this.logDirectory, "cluster")),
|
||||
libFileOps.directorySize(path.join(this.logDirectory, "controller")),
|
||||
libFileOps.directorySize(path.join(this.logDirectory, "host")),
|
||||
lib.directorySize(path.join(this.logDirectory, "cluster")),
|
||||
lib.directorySize(path.join(this.logDirectory, "controller")),
|
||||
lib.directorySize(path.join(this.logDirectory, "host")),
|
||||
])).reduce((a, v) => a + v, 0);
|
||||
}
|
||||
|
||||
async _startInternal(args) {
|
||||
this.logDirectory = args.logDirectory;
|
||||
this.clusterLogIndex = await libLoggingUtils.LogIndex.load(path.join(this.logDirectory, "cluster"));
|
||||
this.clusterLogIndex = await lib.LogIndex.load(path.join(this.logDirectory, "cluster"));
|
||||
this.clusterLogBuildInterval = setInterval(() => {
|
||||
this.clusterLogIndex.buildIndex().catch(
|
||||
err => logger.error(`Error building cluster log index:\n${err.stack}`)
|
||||
@@ -181,7 +173,7 @@ class Controller {
|
||||
for (let name of args.devPlugin) {
|
||||
let info = this.pluginInfos.find(i => i.name === name);
|
||||
if (!info) {
|
||||
throw new libErrors.StartupError(`No plugin named ${name}`);
|
||||
throw new lib.StartupError(`No plugin named ${name}`);
|
||||
}
|
||||
let config = require(path.posix.join(info.requirePath, "webpack.config"))({});
|
||||
devPlugins.set(name, webpackConfigs.length);
|
||||
@@ -210,7 +202,7 @@ class Controller {
|
||||
this.mods = await Controller.loadModInfos(modsDirectory);
|
||||
|
||||
this.config.on("fieldChanged", (group, field, prev) => {
|
||||
libPlugin.invokeHook(this.plugins, "onControllerConfigFieldChanged", group, field, prev);
|
||||
lib.invokeHook(this.plugins, "onControllerConfigFieldChanged", group, field, prev);
|
||||
});
|
||||
for (let instance of this.instances.values()) {
|
||||
this.addInstanceHooks(instance);
|
||||
@@ -230,7 +222,7 @@ class Controller {
|
||||
let tls_key = this.config.get("controller.tls_private_key");
|
||||
|
||||
if (httpsPort && (!tls_cert || !tls_key)) {
|
||||
throw new libErrors.StartupError(
|
||||
throw new lib.StartupError(
|
||||
"tls_certificate and tls_private_key must be configure in order to use https_port"
|
||||
);
|
||||
}
|
||||
@@ -265,7 +257,7 @@ class Controller {
|
||||
privateKey = await fs.readFile(tls_key);
|
||||
|
||||
} catch (err) {
|
||||
throw new libErrors.StartupError(
|
||||
throw new lib.StartupError(
|
||||
`Error loading ssl certificate: ${err.message}`
|
||||
);
|
||||
}
|
||||
@@ -313,7 +305,7 @@ class Controller {
|
||||
}
|
||||
|
||||
logger.info("Saving config");
|
||||
await libFileOps.safeOutputFile(this.configPath, JSON.stringify(this.config.serialize(), null, 4));
|
||||
await lib.safeOutputFile(this.configPath, JSON.stringify(this.config.serialize(), null, 4));
|
||||
|
||||
if (this.devMiddleware) {
|
||||
await new Promise((resolve, reject) => { this.devMiddleware.close(resolve); });
|
||||
@@ -336,7 +328,7 @@ class Controller {
|
||||
await this.userManager.save(path.join(databaseDirectory, "users.json"));
|
||||
}
|
||||
|
||||
await libPlugin.invokeHook(this.plugins, "onShutdown");
|
||||
await lib.invokeHook(this.plugins, "onShutdown");
|
||||
|
||||
if (this.wsServer) {
|
||||
await this.wsServer.stop();
|
||||
@@ -373,7 +365,7 @@ class Controller {
|
||||
}
|
||||
|
||||
static async saveHosts(filePath, hosts) {
|
||||
await libFileOps.safeOutputFile(filePath, JSON.stringify([...hosts.entries()], null, 4));
|
||||
await lib.safeOutputFile(filePath, JSON.stringify([...hosts.entries()], null, 4));
|
||||
}
|
||||
|
||||
static async loadInstances(filePath) {
|
||||
@@ -383,7 +375,7 @@ class Controller {
|
||||
try {
|
||||
let serialized = JSON.parse(await fs.readFile(filePath));
|
||||
for (let serializedConfig of serialized) {
|
||||
let instanceConfig = new libConfig.InstanceConfig("controller");
|
||||
let instanceConfig = new lib.InstanceConfig("controller");
|
||||
await instanceConfig.load(serializedConfig);
|
||||
let status = instanceConfig.get("instance.assigned_host") === null ? "unassigned" : "unknown";
|
||||
let instance = new InstanceInfo({ config: instanceConfig, status });
|
||||
@@ -405,7 +397,7 @@ class Controller {
|
||||
serialized.push(instance.config.serialize());
|
||||
}
|
||||
|
||||
await libFileOps.safeOutputFile(filePath, JSON.stringify(serialized, null, 4));
|
||||
await lib.safeOutputFile(filePath, JSON.stringify(serialized, null, 4));
|
||||
}
|
||||
|
||||
static async loadModPacks(filePath) {
|
||||
@@ -418,11 +410,11 @@ class Controller {
|
||||
}
|
||||
return new Map();
|
||||
}
|
||||
return new Map(json.map(e => [e.id, libData.ModPack.fromJSON(e)]));
|
||||
return new Map(json.map(e => [e.id, lib.ModPack.fromJSON(e)]));
|
||||
}
|
||||
|
||||
static async saveModPacks(filePath, modPacks) {
|
||||
await libFileOps.safeOutputFile(filePath, JSON.stringify([...modPacks.values()], null, 4));
|
||||
await lib.safeOutputFile(filePath, JSON.stringify([...modPacks.values()], null, 4));
|
||||
}
|
||||
|
||||
static async loadModInfos(modsDirectory) {
|
||||
@@ -440,7 +432,7 @@ class Controller {
|
||||
logger.info(`Loading info for Mod ${entry.name}`);
|
||||
let modInfo;
|
||||
try {
|
||||
modInfo = await libData.ModInfo.fromModFile(path.join(modsDirectory, entry.name));
|
||||
modInfo = await lib.ModInfo.fromModFile(path.join(modsDirectory, entry.name));
|
||||
} catch (err) {
|
||||
logger.error(`Error loading mod ${entry.name}: ${err.message}`);
|
||||
continue;
|
||||
@@ -488,13 +480,13 @@ class Controller {
|
||||
/**
|
||||
* Query controller log
|
||||
*
|
||||
* @param {module:lib/logging_utils~QueryLogFilter} filter -
|
||||
* @param {module:lib~QueryLogFilter} filter -
|
||||
* Filter to limit entries with. Note that only the controller log can
|
||||
* be queried from this function.
|
||||
* @returns {Promise<Array<Object>>} log entries matching the filter
|
||||
*/
|
||||
async queryControllerLog(filter) {
|
||||
return await libLoggingUtils.queryLog(
|
||||
return await lib.queryLog(
|
||||
path.join(this.logDirectory, "controller"), filter,
|
||||
);
|
||||
}
|
||||
@@ -502,12 +494,12 @@ class Controller {
|
||||
/**
|
||||
* Query cluster log
|
||||
*
|
||||
* @param {module:lib/logging_utils~QueryLogFilter} filter -
|
||||
* @param {module:lib~QueryLogFilter} filter -
|
||||
* Filter to limit entries with.
|
||||
* @returns {Promise<Array<Object>>} log entries matching the filter
|
||||
*/
|
||||
async queryClusterLog(filter) {
|
||||
return await libLoggingUtils.queryLog(
|
||||
return await lib.queryLog(
|
||||
path.join(this.logDirectory, "cluster"), filter, this.clusterLogIndex,
|
||||
);
|
||||
}
|
||||
@@ -564,7 +556,7 @@ class Controller {
|
||||
}
|
||||
|
||||
hostUpdated(host) {
|
||||
let update = new libData.HostDetails(
|
||||
let update = new lib.HostDetails(
|
||||
host.agent,
|
||||
host.version,
|
||||
host.name,
|
||||
@@ -587,12 +579,12 @@ class Controller {
|
||||
*
|
||||
* @param {number} instanceId - ID of instance to get.
|
||||
* @returns {object} instance
|
||||
* @throws {module:lib/errors.RequestError} if the instance does not exist.
|
||||
* @throws {module:lib.RequestError} if the instance does not exist.
|
||||
*/
|
||||
getRequestInstance(instanceId) {
|
||||
let instance = this.instances.get(instanceId);
|
||||
if (!instance) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@@ -604,20 +596,20 @@ class Controller {
|
||||
* creates an instance using that config in the cluster.
|
||||
*
|
||||
* @example
|
||||
* let instanceConfig = new libConfig.InstanceConfig("controller");
|
||||
* let instanceConfig = new lib.InstanceConfig("controller");
|
||||
* await instanceConfig.init();
|
||||
* instanceConfig.set("instance.name", "My instance");
|
||||
* let instance = await controller.instanceAssign(instanceConfig);
|
||||
* await controller.instanceAssign(instance.id, hostId);
|
||||
*
|
||||
* @param {module:lib/config.InstanceConfig} instanceConfig -
|
||||
* @param {module:lib.InstanceConfig} instanceConfig -
|
||||
* Config to base newly created instance on.
|
||||
* @returns {module:controller/src/InstanceInfo} The created instance
|
||||
*/
|
||||
async instanceCreate(instanceConfig) {
|
||||
let instanceId = instanceConfig.get("instance.id");
|
||||
if (this.instances.has(instanceId)) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} already exists`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} already exists`);
|
||||
}
|
||||
|
||||
// Add common settings for the Factorio server
|
||||
@@ -648,7 +640,7 @@ class Controller {
|
||||
|
||||
let instance = new InstanceInfo({ config: instanceConfig, status: "unassigned" });
|
||||
this.instances.set(instanceId, instance);
|
||||
await libPlugin.invokeHook(this.plugins, "onInstanceStatusChanged", instance, null);
|
||||
await lib.invokeHook(this.plugins, "onInstanceStatusChanged", instance, null);
|
||||
this.addInstanceHooks(instance);
|
||||
}
|
||||
|
||||
@@ -678,7 +670,7 @@ class Controller {
|
||||
// target host be connected to the controller while doing the
|
||||
// assignment, but it is IMHO a better user experience if this
|
||||
// is the case.
|
||||
throw new libErrors.RequestError("Target host is not connected to the controller");
|
||||
throw new lib.RequestError("Target host is not connected to the controller");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -687,7 +679,7 @@ class Controller {
|
||||
if (currentAssignedHost !== null && hostId !== currentAssignedHost) {
|
||||
let oldHostConnection = this.wsServer.hostConnections.get(currentAssignedHost);
|
||||
if (oldHostConnection && !oldHostConnection.connector.closing) {
|
||||
await oldHostConnection.send(new libData.InstanceUnassignInternalRequest(instanceId));
|
||||
await oldHostConnection.send(new lib.InstanceUnassignInternalRequest(instanceId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,7 +687,7 @@ class Controller {
|
||||
instance.config.set("instance.assigned_host", hostId);
|
||||
if (hostId !== null) {
|
||||
await newHostConnection.send(
|
||||
new libData.InstanceAssignInternalRequest(instanceId, instance.config.serialize("host"))
|
||||
new lib.InstanceAssignInternalRequest(instanceId, instance.config.serialize("host"))
|
||||
);
|
||||
} else {
|
||||
instance.status = "unassigned";
|
||||
@@ -715,14 +707,14 @@ class Controller {
|
||||
let instance = this.getRequestInstance(instanceId);
|
||||
let hostId = instance.config.get("instance.assigned_host");
|
||||
if (hostId !== null) {
|
||||
await this.sendTo({ hostId }, new libData.InstanceDeleteInternalRequest(instanceId));
|
||||
await this.sendTo({ hostId }, new lib.InstanceDeleteInternalRequest(instanceId));
|
||||
}
|
||||
this.instances.delete(instanceId);
|
||||
|
||||
let prev = instance.status;
|
||||
instance.status = "deleted";
|
||||
this.instanceUpdated(instance);
|
||||
await libPlugin.invokeHook(this.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
await lib.invokeHook(this.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -740,7 +732,7 @@ class Controller {
|
||||
let connection = this.wsServer.hostConnections.get(hostId);
|
||||
if (connection) {
|
||||
await connection.send(
|
||||
new libData.InstanceAssignInternalRequest(instance.id, instance.config.serialize("host"))
|
||||
new lib.InstanceAssignInternalRequest(instance.id, instance.config.serialize("host"))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -752,7 +744,7 @@ class Controller {
|
||||
this.instanceUpdated(instance);
|
||||
}
|
||||
|
||||
libPlugin.invokeHook(this.plugins, "onInstanceConfigFieldChanged", instance, group, field, prev);
|
||||
lib.invokeHook(this.plugins, "onInstanceConfigFieldChanged", instance, group, field, prev);
|
||||
});
|
||||
|
||||
this.instanceUpdated(instance);
|
||||
@@ -786,7 +778,7 @@ class Controller {
|
||||
controlConnection.modPackUpdated(modPack);
|
||||
}
|
||||
|
||||
libPlugin.invokeHook(this.plugins, "onModPackUpdated", modPack);
|
||||
lib.invokeHook(this.plugins, "onModPackUpdated", modPack);
|
||||
}
|
||||
|
||||
modUpdated(mod) {
|
||||
@@ -798,7 +790,7 @@ class Controller {
|
||||
controlConnection.modUpdated(mod);
|
||||
}
|
||||
|
||||
libPlugin.invokeHook(this.plugins, "onModUpdated", mod);
|
||||
lib.invokeHook(this.plugins, "onModUpdated", mod);
|
||||
}
|
||||
|
||||
userUpdated(user) {
|
||||
@@ -814,13 +806,13 @@ class Controller {
|
||||
/**
|
||||
* Notify connected control clients under the given user that the
|
||||
* permissions for this user may have changed.
|
||||
* @param {module:lib/users.User} user - User permisions updated for.
|
||||
* @param {module:lib.User} user - User permisions updated for.
|
||||
*/
|
||||
userPermissionsUpdated(user) {
|
||||
for (let controlConnection of this.wsServer.controlConnections.values()) {
|
||||
if (controlConnection.user === user) {
|
||||
controlConnection.send(
|
||||
new libData.AccountUpdateEvent([...user.roles].map(r => ({
|
||||
new lib.AccountUpdateEvent([...user.roles].map(r => ({
|
||||
name: r.name,
|
||||
id: r.id,
|
||||
permissions: [...r.permissions],
|
||||
@@ -833,13 +825,13 @@ class Controller {
|
||||
/**
|
||||
* Notify connected control clients with the given role that the
|
||||
* permissions may have changed.
|
||||
* @param {module:lib/users.Role} role - Role permisions updated for.
|
||||
* @param {module:lib.Role} role - Role permisions updated for.
|
||||
*/
|
||||
rolePermissionsUpdated(role) {
|
||||
for (let controlConnection of this.wsServer.controlConnections.values()) {
|
||||
if (controlConnection.user.roles.has(role)) {
|
||||
controlConnection.send(
|
||||
new libData.AccountUpdateEvent(
|
||||
new lib.AccountUpdateEvent(
|
||||
[...controlConnection.user.roles].map(r => ({
|
||||
name: r.name,
|
||||
id: r.id,
|
||||
@@ -864,10 +856,10 @@ class Controller {
|
||||
continue;
|
||||
}
|
||||
|
||||
let ControllerPluginClass = libPlugin.BaseControllerPlugin;
|
||||
let ControllerPluginClass = lib.BaseControllerPlugin;
|
||||
try {
|
||||
if (pluginInfo.controllerEntrypoint) {
|
||||
ControllerPluginClass = await libPluginLoader.loadControllerPluginClass(pluginInfo);
|
||||
ControllerPluginClass = await lib.loadControllerPluginClass(pluginInfo);
|
||||
}
|
||||
|
||||
let controllerPlugin = new ControllerPluginClass(pluginInfo, this, metrics, logger);
|
||||
@@ -875,7 +867,7 @@ class Controller {
|
||||
this.plugins.set(pluginInfo.name, controllerPlugin);
|
||||
|
||||
} catch (err) {
|
||||
throw new libErrors.PluginError(pluginInfo.name, err);
|
||||
throw new lib.PluginError(pluginInfo.name, err);
|
||||
}
|
||||
|
||||
logger.info(`Loaded plugin ${pluginInfo.name}`);
|
||||
@@ -899,7 +891,7 @@ class Controller {
|
||||
});
|
||||
|
||||
function wrapError(err) {
|
||||
reject(new libErrors.StartupError(
|
||||
reject(new lib.StartupError(
|
||||
`Server listening failed: ${err.message}`
|
||||
));
|
||||
}
|
||||
@@ -982,7 +974,7 @@ class Controller {
|
||||
}
|
||||
|
||||
handleRequest(Request, handler) {
|
||||
if (!libLink.Link._requestsByClass.has(Request)) {
|
||||
if (!lib.Link._requestsByClass.has(Request)) {
|
||||
throw new Error(`Unregistered Request class ${Request.name}`);
|
||||
}
|
||||
if (this._registeredRequests.has(Request)) {
|
||||
@@ -992,7 +984,7 @@ class Controller {
|
||||
}
|
||||
|
||||
fallbackRequest(Request, handler) {
|
||||
if (!libLink.Link._requestsByClass.has(Request)) {
|
||||
if (!lib.Link._requestsByClass.has(Request)) {
|
||||
throw new Error(`Unregistered Request class ${Request.name}`);
|
||||
}
|
||||
if (this._fallbackedRequests.has(Request)) {
|
||||
@@ -1002,7 +994,7 @@ class Controller {
|
||||
}
|
||||
|
||||
handleEvent(Event, handler) {
|
||||
if (!libLink.Link._eventsByClass.has(Event)) {
|
||||
if (!lib.Link._eventsByClass.has(Event)) {
|
||||
throw new Error(`Unregistered Event class ${Event.name}`);
|
||||
}
|
||||
if (this._registeredEvents.has(Event)) {
|
||||
@@ -1012,7 +1004,7 @@ class Controller {
|
||||
}
|
||||
|
||||
snoopEvent(Event, handler) {
|
||||
if (!libLink.Link._eventsByClass.has(Event)) {
|
||||
if (!lib.Link._eventsByClass.has(Event)) {
|
||||
throw new Error(`Unregistered Event class ${Event.name}`);
|
||||
}
|
||||
if (this._snoopedEvents.has(Event)) {
|
||||
@@ -1026,16 +1018,16 @@ class Controller {
|
||||
*
|
||||
* Routes the given request or event to the given destination. The
|
||||
* destination argument supports address shorthands, see {@link
|
||||
* module:lib/data.Address.fromShorthand}
|
||||
* module:lib.Address.fromShorthand}
|
||||
*
|
||||
* @param {*|module:lib/data.Address} address - Where to send it.
|
||||
* @param {*|module:lib.Address} address - Where to send it.
|
||||
* @param {*} requestOrEvent - The request or event to send.
|
||||
* @returns {Promise<*>|undefined}
|
||||
* Promise that resolves to the response if a request was sent or
|
||||
* undefined if it was an event.
|
||||
*/
|
||||
sendTo(address, requestOrEvent) {
|
||||
let dst = libData.Address.fromShorthand(address);
|
||||
let dst = lib.Address.fromShorthand(address);
|
||||
if (requestOrEvent.constructor.type === "request") {
|
||||
return this.sendRequest(requestOrEvent, dst);
|
||||
}
|
||||
@@ -1047,30 +1039,30 @@ class Controller {
|
||||
|
||||
async sendRequest(request, dst) {
|
||||
let connection;
|
||||
if (dst.type === libData.Address.controller) {
|
||||
if (dst.type === lib.Address.controller) {
|
||||
throw new Error("controller as dst is not supported.");
|
||||
|
||||
} else if (dst.type === libData.Address.control) {
|
||||
} else if (dst.type === lib.Address.control) {
|
||||
connection = this.wsServer.controlConnections.get(dst.id);
|
||||
if (!connection) {
|
||||
throw new libErrors.RequestError("Target control connection does not exist.");
|
||||
throw new lib.RequestError("Target control connection does not exist.");
|
||||
}
|
||||
|
||||
} else if (dst.type === libData.Address.instance) {
|
||||
} else if (dst.type === lib.Address.instance) {
|
||||
let instance = this.getRequestInstance(dst.id);
|
||||
let hostId = instance.config.get("instance.assigned_host");
|
||||
if (hostId === null) {
|
||||
throw new libErrors.RequestError("Instance is not assigned to a host");
|
||||
throw new lib.RequestError("Instance is not assigned to a host");
|
||||
}
|
||||
connection = this.wsServer.hostConnections.get(hostId);
|
||||
if (!connection) {
|
||||
throw new libErrors.RequestError("Host containing instance is not connected");
|
||||
throw new lib.RequestError("Host containing instance is not connected");
|
||||
}
|
||||
|
||||
} else if (dst.type === libData.Address.host) {
|
||||
} else if (dst.type === lib.Address.host) {
|
||||
connection = this.wsServer.hostConnections.get(dst.id);
|
||||
if (!connection) {
|
||||
throw new libErrors.RequestError("Host is not connected");
|
||||
throw new lib.RequestError("Host is not connected");
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1082,13 +1074,13 @@ class Controller {
|
||||
|
||||
sendEvent(event, dst) {
|
||||
let connection;
|
||||
if (dst.type === libData.Address.controller) {
|
||||
if (dst.type === lib.Address.controller) {
|
||||
throw new Error("controller as dst is not supported.");
|
||||
|
||||
} else if (dst.type === libData.Address.control) {
|
||||
} else if (dst.type === lib.Address.control) {
|
||||
connection = this.wsServer.controlConnections.get(dst.id);
|
||||
|
||||
} else if (dst.type === libData.Address.instance) {
|
||||
} else if (dst.type === lib.Address.instance) {
|
||||
let instance = this.instances.get(dst.id);
|
||||
if (!instance) {
|
||||
return;
|
||||
@@ -1099,16 +1091,16 @@ class Controller {
|
||||
}
|
||||
connection = this.wsServer.hostConnections.get(hostId);
|
||||
|
||||
} else if (dst.type === libData.Address.host) {
|
||||
} else if (dst.type === lib.Address.host) {
|
||||
connection = this.wsServer.hostConnections.get(dst.id);
|
||||
|
||||
} else if (dst.type === libData.Address.broadcast) {
|
||||
if (dst.id === libData.Address.control) {
|
||||
} else if (dst.type === lib.Address.broadcast) {
|
||||
if (dst.id === lib.Address.control) {
|
||||
for (let controlConnection of this.wsServer.controlConnections.values()) {
|
||||
controlConnection.sendEvent(event, dst);
|
||||
}
|
||||
|
||||
} else if (dst.id === libData.Address.instance || dst.id === libData.Address.host) {
|
||||
} else if (dst.id === lib.Address.instance || dst.id === lib.Address.host) {
|
||||
for (let hostConnection of this.wsServer.hostConnections.values()) {
|
||||
hostConnection.sendEvent(event, dst);
|
||||
}
|
||||
@@ -1141,11 +1133,11 @@ class Controller {
|
||||
let instance = this.getRequestInstance(request.instanceId);
|
||||
let hostId = instance.config.get("instance.assigned_host");
|
||||
if (hostId === null) {
|
||||
throw new libErrors.RequestError("Instance is not assigned to a host");
|
||||
throw new lib.RequestError("Instance is not assigned to a host");
|
||||
}
|
||||
let connection = this.wsServer.hostConnections.get(hostId);
|
||||
if (!connection) {
|
||||
throw new libErrors.RequestError("Host containing instance is not connected");
|
||||
throw new lib.RequestError("Host containing instance is not connected");
|
||||
}
|
||||
return await connection.send(request);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
class ControllerRouter {
|
||||
/** @type {module:controller/src/Controller} */
|
||||
@@ -20,8 +20,8 @@ class ControllerRouter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {module:lib/link.Link} origin - Source link of the message.
|
||||
* @param {module:lib/data.Message} message
|
||||
* @param {module:lib.Link} origin - Source link of the message.
|
||||
* @param {module:lib.Message} message
|
||||
* Link the message originated from.
|
||||
* @param {boolean} hasFallback - true if fallback handling is available.
|
||||
* @returns {boolean} true if the message was handled
|
||||
@@ -34,15 +34,15 @@ class ControllerRouter {
|
||||
let dst = message.dst;
|
||||
let nextHop;
|
||||
let msg;
|
||||
if (dst.type === libData.Address.broadcast) {
|
||||
if (dst.type === lib.Address.broadcast) {
|
||||
this.broadcastMessage(origin, message);
|
||||
return true;
|
||||
} else if (dst.type === libData.Address.host) {
|
||||
} else if (dst.type === lib.Address.host) {
|
||||
nextHop = this.controller.wsServer.hostConnections.get(dst.id);
|
||||
if (!nextHop) {
|
||||
msg = `Host ${dst.id} is offline`;
|
||||
}
|
||||
} else if (dst.type === libData.Address.instance) {
|
||||
} else if (dst.type === lib.Address.instance) {
|
||||
let instance = this.controller.instances.get(dst.id);
|
||||
if (!instance) {
|
||||
msg = `Instance ${dst.id} does not exist`;
|
||||
@@ -57,12 +57,12 @@ class ControllerRouter {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dst.type === libData.Address.control) {
|
||||
} else if (dst.type === lib.Address.control) {
|
||||
nextHop = this.controller.wsServer.controlConnections.get(dst.id);
|
||||
if (!nextHop) {
|
||||
msg = "Control connection does not exist";
|
||||
}
|
||||
} else if (dst.type === libData.Address.controller) {
|
||||
} else if (dst.type === lib.Address.controller) {
|
||||
msg = `Unexpected message forwarded to ${dst}`;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class ControllerRouter {
|
||||
return false;
|
||||
}
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError(msg || "Unroutable destination"), message.src
|
||||
new lib.ResponseError(msg || "Unroutable destination"), message.src
|
||||
);
|
||||
return true;
|
||||
}
|
||||
@@ -100,13 +100,13 @@ class ControllerRouter {
|
||||
let dst = message.dst;
|
||||
if (message.type !== "event") {
|
||||
this.warnUnrouted(message, `Unexpected broadcast of ${message.type}`);
|
||||
} else if (dst.id === libData.Address.host || dst.id === libData.Address.instance) {
|
||||
} else if (dst.id === lib.Address.host || dst.id === lib.Address.instance) {
|
||||
for (let hostConnection of this.controller.wsServer.hostConnections.values()) {
|
||||
if (hostConnection !== origin) {
|
||||
hostConnection.connector.send(message);
|
||||
}
|
||||
}
|
||||
} else if (dst.id === libData.Address.control) {
|
||||
} else if (dst.id === lib.Address.control) {
|
||||
for (let controlConnection of this.controller.wsServer.controlConnections.values()) {
|
||||
if (controlConnection !== origin) {
|
||||
controlConnection.connector.send(message);
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
"use strict";
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const PlayerStats = require("@clusterio/lib/PlayerStats");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger, PlayerStats } = lib;
|
||||
|
||||
const BaseConnection = require("./BaseConnection");
|
||||
const InstanceInfo = require("./InstanceInfo");
|
||||
@@ -55,36 +51,36 @@ class HostConnection extends BaseConnection {
|
||||
let prev = instance.status;
|
||||
instance.status = "unknown";
|
||||
this._controller.instanceUpdated(instance);
|
||||
libPlugin.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
lib.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
}
|
||||
});
|
||||
|
||||
this.handle(libData.InstanceStatusChangedEvent, this.handleInstanceStatusChangedEvent.bind(this));
|
||||
this.handle(libData.InstancesUpdateRequest, this.handleInstancesUpdateRequest.bind(this));
|
||||
this.handle(libData.InstanceSaveListUpdateEvent, this.handleInstanceSaveListUpdateEvent.bind(this));
|
||||
this.handle(libData.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(libData.InstancePlayerUpdateEvent, this.handleInstancePlayerUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceStatusChangedEvent, this.handleInstanceStatusChangedEvent.bind(this));
|
||||
this.handle(lib.InstancesUpdateRequest, this.handleInstancesUpdateRequest.bind(this));
|
||||
this.handle(lib.InstanceSaveListUpdateEvent, this.handleInstanceSaveListUpdateEvent.bind(this));
|
||||
this.handle(lib.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(lib.InstancePlayerUpdateEvent, this.handleInstancePlayerUpdateEvent.bind(this));
|
||||
}
|
||||
|
||||
validateIngress(message) {
|
||||
let origin = this.connector.dst;
|
||||
switch (message.src.type) {
|
||||
case libData.Address.control:
|
||||
case libData.Address.controller:
|
||||
throw new libErrors.InvalidMessage(`Received message with invalid src ${message.src} from ${origin}`);
|
||||
case lib.Address.control:
|
||||
case lib.Address.controller:
|
||||
throw new lib.InvalidMessage(`Received message with invalid src ${message.src} from ${origin}`);
|
||||
|
||||
case libData.Address.host:
|
||||
case lib.Address.host:
|
||||
if (message.src.id !== origin.id) {
|
||||
throw new libErrors.InvalidMessage(
|
||||
throw new lib.InvalidMessage(
|
||||
`Received message with invalid src ${message.src} from ${origin}`
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case libData.Address.instance:
|
||||
case lib.Address.instance:
|
||||
let instance = this._controller.instances.get(message.src.id);
|
||||
if (!instance || instance.config.get("instance.assigned_host") !== this._id) {
|
||||
throw new libErrors.InvalidMessage(
|
||||
throw new lib.InvalidMessage(
|
||||
`Received message with invalid src ${message.src} from ${origin}`
|
||||
);
|
||||
}
|
||||
@@ -120,7 +116,7 @@ class HostConnection extends BaseConnection {
|
||||
}
|
||||
|
||||
async prepareDisconnect() {
|
||||
await libPlugin.invokeHook(this._controller.plugins, "onPrepareHostDisconnect", this);
|
||||
await lib.invokeHook(this._controller.plugins, "onPrepareHostDisconnect", this);
|
||||
return await super.prepareDisconnect();
|
||||
}
|
||||
|
||||
@@ -159,7 +155,7 @@ class HostConnection extends BaseConnection {
|
||||
instance.game_port = request.gamePort;
|
||||
logger.verbose(`Instance ${instance.config.get("instance.name")} State: ${instance.status}`);
|
||||
this._controller.instanceUpdated(instance);
|
||||
await libPlugin.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
await lib.invokeHook(this._controller.plugins, "onInstanceStatusChanged", instance, prev);
|
||||
}
|
||||
|
||||
async handleInstancesUpdateRequest(request) {
|
||||
@@ -167,14 +163,14 @@ class HostConnection extends BaseConnection {
|
||||
for (let instance of this._controller.instances.values()) {
|
||||
if (instance.config.get("instance.assigned_host") === this._id) {
|
||||
await this.send(
|
||||
new libData.InstanceAssignInternalRequest(instance.id, instance.config.serialize("host"))
|
||||
new lib.InstanceAssignInternalRequest(instance.id, instance.config.serialize("host"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Assign instances the host has but controller does not
|
||||
for (let instanceData of request.instances) {
|
||||
let instanceConfig = new libConfig.InstanceConfig("controller");
|
||||
let instanceConfig = new lib.InstanceConfig("controller");
|
||||
await instanceConfig.load(instanceData.config, "host");
|
||||
|
||||
let controllerInstance = this._controller.instances.get(instanceConfig.get("instance.id"));
|
||||
@@ -182,7 +178,7 @@ class HostConnection extends BaseConnection {
|
||||
// Check if this instance is assigned somewhere else.
|
||||
if (controllerInstance.config.get("instance.assigned_host") !== this._id) {
|
||||
await this.send(
|
||||
new libData.InstanceUnassignInternalRequest(instanceConfig.get("instance.id"))
|
||||
new lib.InstanceUnassignInternalRequest(instanceConfig.get("instance.id"))
|
||||
);
|
||||
continue;
|
||||
}
|
||||
@@ -193,7 +189,7 @@ class HostConnection extends BaseConnection {
|
||||
controllerInstance.status = instanceData.status;
|
||||
logger.verbose(`Instance ${instanceConfig.get("instance.name")} State: ${instanceData.status}`);
|
||||
this._controller.instanceUpdated(controllerInstance);
|
||||
await libPlugin.invokeHook(
|
||||
await lib.invokeHook(
|
||||
this._controller.plugins, "onInstanceStatusChanged", controllerInstance, prev
|
||||
);
|
||||
}
|
||||
@@ -205,11 +201,11 @@ class HostConnection extends BaseConnection {
|
||||
this._controller.instances.set(instanceConfig.get("instance.id"), newInstance);
|
||||
this._controller.addInstanceHooks(newInstance);
|
||||
await this.send(
|
||||
new libData.InstanceAssignInternalRequest(
|
||||
new lib.InstanceAssignInternalRequest(
|
||||
instanceConfig.get("instance.id"), instanceConfig.serialize("host")
|
||||
)
|
||||
);
|
||||
await libPlugin.invokeHook(this._controller.plugins, "onInstanceStatusChanged", newInstance, null);
|
||||
await lib.invokeHook(this._controller.plugins, "onInstanceStatusChanged", newInstance, null);
|
||||
}
|
||||
|
||||
// Push lists to make sure they are in sync.
|
||||
@@ -229,7 +225,7 @@ class HostConnection extends BaseConnection {
|
||||
}
|
||||
}
|
||||
|
||||
await this.send(new libData.SyncUserListsEvent(adminlist, banlist, whitelist));
|
||||
await this.send(new lib.SyncUserListsEvent(adminlist, banlist, whitelist));
|
||||
}
|
||||
|
||||
async handleInstanceSaveListUpdateEvent(event) {
|
||||
@@ -261,7 +257,7 @@ class HostConnection extends BaseConnection {
|
||||
this._controller.userUpdated(user);
|
||||
|
||||
let instance = this._controller.instances.get(instanceId);
|
||||
await libPlugin.invokeHook(this._controller.plugins, "onPlayerEvent", instance, {
|
||||
await lib.invokeHook(this._controller.plugins, "onPlayerEvent", instance, {
|
||||
type: event.type,
|
||||
name: event.name,
|
||||
reason: event.reason,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* @alias module:controller/src/InstanceInfo
|
||||
*/
|
||||
class InstanceInfo {
|
||||
/** @type {module:lib/config.InstanceConfig} */
|
||||
/** @type {module:lib.InstanceConfig} */
|
||||
config;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
const fs = require("fs-extra");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libUsers = require("@clusterio/lib/users");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
/**
|
||||
* Manages users and roles
|
||||
@@ -21,12 +21,12 @@ class UserManager {
|
||||
try {
|
||||
let content = JSON.parse(await fs.readFile(filePath));
|
||||
for (let serializedRole of content.roles) {
|
||||
let role = new libUsers.Role(serializedRole);
|
||||
let role = new lib.Role(serializedRole);
|
||||
loadedRoles.set(role.id, role);
|
||||
}
|
||||
|
||||
for (let serializedUser of content.users) {
|
||||
let user = new libUsers.User(serializedUser, loadedRoles);
|
||||
let user = new lib.User(serializedUser, loadedRoles);
|
||||
loadedUsers.set(user.name, user);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ class UserManager {
|
||||
}
|
||||
|
||||
// Create default roles if loading failed
|
||||
libUsers.ensureDefaultAdminRole(loadedRoles);
|
||||
libUsers.ensureDefaultPlayerRole(loadedRoles);
|
||||
lib.ensureDefaultAdminRole(loadedRoles);
|
||||
lib.ensureDefaultPlayerRole(loadedRoles);
|
||||
}
|
||||
|
||||
this.roles = loadedRoles;
|
||||
@@ -63,7 +63,7 @@ class UserManager {
|
||||
users: serializedUsers,
|
||||
roles: serializedRoles,
|
||||
};
|
||||
await libFileOps.safeOutputFile(filePath, JSON.stringify(serialized, null, 4));
|
||||
await lib.safeOutputFile(filePath, JSON.stringify(serialized, null, 4));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ class UserManager {
|
||||
* Creates a new user and add it to the user database.
|
||||
*
|
||||
* @param {string} name - Name of the user to create.
|
||||
* @returns {module:lib/users.User} newly created user.
|
||||
* @returns {module:lib.User} newly created user.
|
||||
*/
|
||||
createUser(name) {
|
||||
if (this.users.has(name)) {
|
||||
@@ -80,10 +80,24 @@ class UserManager {
|
||||
}
|
||||
|
||||
let defaultRoleId = this._config.get("controller.default_role_id");
|
||||
let user = new libUsers.User({ name, roles: [defaultRoleId] }, this.roles);
|
||||
let user = new lib.User({ name, roles: [defaultRoleId] }, this.roles);
|
||||
this.users.set(name, user);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign access token for the given user name
|
||||
*
|
||||
* @param {string} name - user name to sign token for
|
||||
* @returns {string} JWT access token for the user.
|
||||
*/
|
||||
signUserToken(name) {
|
||||
return jwt.sign(
|
||||
{ aud: "user", user: name },
|
||||
Buffer.from(this._config.get("controller.auth_secret"), "base64")
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = UserManager;
|
||||
@@ -2,10 +2,8 @@
|
||||
const jwt = require("jsonwebtoken");
|
||||
const WebSocket = require("ws");
|
||||
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
|
||||
const ControlConnection = require("./ControlConnection");
|
||||
const packageVersion = require("../package").version;
|
||||
@@ -13,18 +11,18 @@ const HostConnection = require("./HostConnection");
|
||||
const WsServerConnector = require("./WsServerConnector");
|
||||
|
||||
|
||||
const wsMessageCounter = new libPrometheus.Counter(
|
||||
const wsMessageCounter = new lib.Counter(
|
||||
"clusterio_controller_websocket_message_total",
|
||||
"How many messages have been received over WebSocket on the controller",
|
||||
{ labels: ["direction"] }
|
||||
);
|
||||
|
||||
const wsConnectionsCounter = new libPrometheus.Counter(
|
||||
const wsConnectionsCounter = new lib.Counter(
|
||||
"clusterio_controller_websocket_connections_total",
|
||||
"How many WebSocket connections have been initiated on the controller"
|
||||
);
|
||||
|
||||
const wsRejectedConnectionsCounter = new libPrometheus.Counter(
|
||||
const wsRejectedConnectionsCounter = new lib.Counter(
|
||||
"clusterio_controller_websocket_rejected_connections_total",
|
||||
"How many WebSocket connections have been rejected during the handshake on the controller"
|
||||
);
|
||||
@@ -78,7 +76,7 @@ class WsServer {
|
||||
try {
|
||||
await task;
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
logger.warn(`Unexpected error disconnecting connector:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +121,7 @@ class WsServer {
|
||||
loadedPlugins[name] = plugin.info.version;
|
||||
}
|
||||
|
||||
socket.send(JSON.stringify(new libData.MessageHello(new libData.HelloData(packageVersion, loadedPlugins))));
|
||||
socket.send(JSON.stringify(new lib.MessageHello(new lib.HelloData(packageVersion, loadedPlugins))));
|
||||
this.attachHandler(socket, req);
|
||||
}
|
||||
|
||||
@@ -160,8 +158,8 @@ ${err.stack}`
|
||||
let message;
|
||||
try {
|
||||
const json = JSON.parse(rawMessage);
|
||||
libData.Message.validate(json);
|
||||
message = libData.Message.fromJSON(json);
|
||||
lib.Message.validate(json);
|
||||
message = lib.Message.fromJSON(json);
|
||||
} catch (err) {
|
||||
logger.verbose(`WsServer | closing ${req.socket.remoteAddress} after receiving invalid message`);
|
||||
wsRejectedConnectionsCounter.inc();
|
||||
@@ -239,7 +237,7 @@ ${err.stack}`
|
||||
return;
|
||||
}
|
||||
|
||||
let [connector, sessionToken] = this.createSession(new libData.Address(libData.Address.host, data.id));
|
||||
let [connector, sessionToken] = this.createSession(new lib.Address(lib.Address.host, data.id));
|
||||
let connection = this.hostConnections.get(data.id);
|
||||
if (connection) {
|
||||
logger.verbose(`WsServer | disconnecting existing connection for host ${data.id}`);
|
||||
@@ -267,7 +265,7 @@ ${err.stack}`
|
||||
});
|
||||
this.hostConnections.set(data.id, connection);
|
||||
this.controller.hostUpdated(this.controller.hosts.get(data.id));
|
||||
let src = new libData.Address(libData.Address.host, data.id);
|
||||
let src = new lib.Address(lib.Address.host, data.id);
|
||||
connector.ready(socket, src, sessionToken);
|
||||
}
|
||||
|
||||
@@ -298,7 +296,7 @@ ${err.stack}`
|
||||
|
||||
let id = this.nextControlId;
|
||||
this.nextControlId += 1;
|
||||
let [connector, sessionToken] = this.createSession(new libData.Address(libData.Address.control, id));
|
||||
let [connector, sessionToken] = this.createSession(new lib.Address(lib.Address.control, id));
|
||||
|
||||
logger.verbose(`WsServer | registered control ${id} from ${req.socket.remoteAddress}`);
|
||||
let connection = new ControlConnection(data, connector, this.controller, user, id);
|
||||
@@ -306,7 +304,7 @@ ${err.stack}`
|
||||
this.controlConnections.delete(id);
|
||||
});
|
||||
this.controlConnections.set(id, connection);
|
||||
let account = new libData.AccountDetails(
|
||||
let account = new lib.AccountDetails(
|
||||
user.name,
|
||||
[...user.roles].map(r => ({
|
||||
name: r.name,
|
||||
@@ -315,7 +313,7 @@ ${err.stack}`
|
||||
}))
|
||||
);
|
||||
|
||||
let src = new libData.Address(libData.Address.control, id);
|
||||
let src = new lib.Address(lib.Address.control, id);
|
||||
connector.ready(socket, src, sessionToken, account);
|
||||
}
|
||||
|
||||
@@ -334,7 +332,7 @@ ${err.stack}`
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
socket.send(JSON.stringify(new libData.MessageInvalidate()));
|
||||
socket.send(JSON.stringify(new lib.MessageInvalidate()));
|
||||
this.attachHandler(socket, req);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
"use strict";
|
||||
const events = require("events");
|
||||
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
|
||||
|
||||
/**
|
||||
* Connector for controller connections
|
||||
*
|
||||
* @extends module:lib/link.WebSocketBaseConnector
|
||||
* @extends module:lib.WebSocketBaseConnector
|
||||
* @alias module:controller/src/WsServerConnector
|
||||
*/
|
||||
class WsServerConnector extends libLink.WebSocketBaseConnector {
|
||||
class WsServerConnector extends lib.WebSocketBaseConnector {
|
||||
constructor(dst, sessionId, sessionTimeout, heartbeatInterval) {
|
||||
super(new libData.Address(libData.Address.controller, 0), dst);
|
||||
super(new lib.Address(lib.Address.controller, 0), dst);
|
||||
|
||||
this._sessionTimeout = sessionTimeout;
|
||||
this._socket = null;
|
||||
@@ -40,16 +39,16 @@ class WsServerConnector extends libLink.WebSocketBaseConnector {
|
||||
* Sends the ready message over the socket to initiate the session.
|
||||
*
|
||||
* @param {Object} socket - WebSocket connection to client.
|
||||
* @param {module:lib/data.Address} src - Source address for this link.
|
||||
* @param {module:lib.Address} src - Source address for this link.
|
||||
* @param {string} sessionToken -
|
||||
* the session token to send to the client.
|
||||
* @param {module:lib/data.AccountDetails=} account -
|
||||
* @param {module:lib.AccountDetails=} account -
|
||||
* account data to provide to control connection
|
||||
*/
|
||||
ready(socket, src, sessionToken, account) {
|
||||
this._socket = socket;
|
||||
this._sendInternal(new libData.MessageReady(
|
||||
new libData.ReadyData(
|
||||
this._sendInternal(new lib.MessageReady(
|
||||
new lib.ReadyData(
|
||||
src,
|
||||
sessionToken,
|
||||
this._sessionTimeout,
|
||||
@@ -89,8 +88,8 @@ class WsServerConnector extends libLink.WebSocketBaseConnector {
|
||||
this._timeoutId = null;
|
||||
}
|
||||
|
||||
this._sendInternal(new libData.MessageContinue(
|
||||
new libData.ContinueData(this._sessionTimeout, this._heartbeatInterval, this._lastReceivedSeq)
|
||||
this._sendInternal(new lib.MessageContinue(
|
||||
new lib.ContinueData(this._sessionTimeout, this._heartbeatInterval, this._lastReceivedSeq)
|
||||
));
|
||||
|
||||
this._state = "connected";
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Shared metrics
|
||||
"use strict";
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const lib = require("@clusterio/lib");
|
||||
const util = require("util");
|
||||
|
||||
exports.endpointHitCounter = new libPrometheus.Counter(
|
||||
exports.endpointHitCounter = new lib.Counter(
|
||||
"clusterio_controller_http_endpoint_hits_total",
|
||||
"How many requests a particular HTTP endpoint has gotten",
|
||||
{ labels: ["route"], register: false }
|
||||
|
||||
@@ -9,15 +9,8 @@ const path = require("path");
|
||||
const nodeStream = require("stream");
|
||||
const util = require("util");
|
||||
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libHash = require("@clusterio/lib/hash");
|
||||
const libHelpers = require("@clusterio/lib/helpers");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
|
||||
const finished = util.promisify(nodeStream.finished);
|
||||
|
||||
@@ -40,7 +33,7 @@ function mergeSamples(destinationResult, sourceResult) {
|
||||
// Prometheus polling endpoint
|
||||
async function getMetrics(req, res, next) {
|
||||
let results = [];
|
||||
let pluginResults = await libPlugin.invokeHook(req.app.locals.controller.plugins, "onMetrics");
|
||||
let pluginResults = await lib.invokeHook(req.app.locals.controller.plugins, "onMetrics");
|
||||
for (let metricIterator of pluginResults) {
|
||||
for await (let metric of metricIterator) {
|
||||
results.push(metric);
|
||||
@@ -53,9 +46,9 @@ async function getMetrics(req, res, next) {
|
||||
if (!hostConnection.connected) {
|
||||
continue;
|
||||
}
|
||||
requests.push(libHelpers.timeout(
|
||||
hostConnection.send(new libData.HostMetricsRequest()).catch(err => {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
requests.push(lib.timeout(
|
||||
hostConnection.send(new lib.HostMetricsRequest()).catch(err => {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
logger.error(`Unexpected error gathering metrics from host:\n${err.stack}`);
|
||||
}
|
||||
return null;
|
||||
@@ -64,7 +57,7 @@ async function getMetrics(req, res, next) {
|
||||
));
|
||||
}
|
||||
|
||||
for await (let result of await libPrometheus.defaultRegistry.collect()) {
|
||||
for await (let result of await lib.defaultRegistry.collect()) {
|
||||
results.push(result);
|
||||
}
|
||||
|
||||
@@ -87,12 +80,12 @@ async function getMetrics(req, res, next) {
|
||||
}
|
||||
|
||||
for (let result of resultMap.values()) {
|
||||
results.push(libPrometheus.deserializeResult(result));
|
||||
results.push(lib.deserializeResult(result));
|
||||
}
|
||||
|
||||
|
||||
let text = await libPrometheus.exposition(results);
|
||||
res.set("Content-Type", libPrometheus.exposition.contentType);
|
||||
let text = await lib.exposition(results);
|
||||
res.set("Content-Type", lib.exposition.contentType);
|
||||
res.send(text);
|
||||
}
|
||||
|
||||
@@ -227,12 +220,12 @@ async function uploadExport(req, res) {
|
||||
}
|
||||
|
||||
let { name, ext } = path.posix.parse(filePath);
|
||||
let hash = await libHash.hashStream(file.nodeStream());
|
||||
let hash = await lib.hashStream(file.nodeStream());
|
||||
assets[name] = `${name}.${hash}${ext}`;
|
||||
await libFileOps.safeOutputFile(path.join("static", `${name}.${hash}${ext}`), await file.async("nodebuffer"));
|
||||
await lib.safeOutputFile(path.join("static", `${name}.${hash}${ext}`), await file.async("nodebuffer"));
|
||||
}
|
||||
|
||||
modPack.exportManifest = new libData.ExportManifest(assets);
|
||||
modPack.exportManifest = new lib.ExportManifest(assets);
|
||||
modPack.fillDefaultSettings(settingPrototypes, logger);
|
||||
res.app.locals.controller.modPackUpdated(modPack);
|
||||
|
||||
@@ -363,7 +356,7 @@ async function uploadSave(req, res) {
|
||||
try {
|
||||
let storedName = await Promise.race([
|
||||
req.app.locals.controller.sendToHostByInstanceId(
|
||||
new libData.InstancePullSaveRequest(
|
||||
new lib.InstancePullSaveRequest(
|
||||
instanceId,
|
||||
proxyStream.id,
|
||||
filename,
|
||||
@@ -462,9 +455,9 @@ async function uploadSave(req, res) {
|
||||
|
||||
function checkModName(name) {
|
||||
try {
|
||||
libFileOps.checkFilename(name);
|
||||
lib.checkFilename(name);
|
||||
} catch (err) {
|
||||
throw new libErrors.RequestError(`Mod name ${err.message}`);
|
||||
throw new lib.RequestError(`Mod name ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,7 +505,7 @@ async function uploadMod(req, res) {
|
||||
break;
|
||||
} catch (err) {
|
||||
if (err.code === "EEXIST") {
|
||||
tempFilename = await libFileOps.findUnusedName(modsDirectory, tempFilename, ".tmp.zip");
|
||||
tempFilename = await lib.findUnusedName(modsDirectory, tempFilename, ".tmp.zip");
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
@@ -521,7 +514,7 @@ async function uploadMod(req, res) {
|
||||
stream.pipe(writeStream);
|
||||
await finished(writeStream);
|
||||
|
||||
const modInfo = await libData.ModInfo.fromModFile(path.join(modsDirectory, tempFilename));
|
||||
const modInfo = await lib.ModInfo.fromModFile(path.join(modsDirectory, tempFilename));
|
||||
await fs.rename(path.join(modsDirectory, tempFilename), path.join(modsDirectory, modInfo.filename));
|
||||
req.app.locals.controller.mods.set(modInfo.filename, modInfo);
|
||||
req.app.locals.controller.modUpdated(modInfo);
|
||||
|
||||
+31
-39
@@ -10,16 +10,8 @@ const yargs = require("yargs");
|
||||
const version = require("./package").version;
|
||||
const setBlocking = require("set-blocking");
|
||||
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libPluginLoader = require("@clusterio/lib/plugin_loader");
|
||||
const libCommand = require("@clusterio/lib/command");
|
||||
const libSharedCommands = require("@clusterio/lib/shared_commands");
|
||||
const { ConsoleTransport, levels, logger } = require("@clusterio/lib/logging");
|
||||
const libLoggingUtils = require("@clusterio/lib/logging_utils");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ConsoleTransport, levels, logger } = lib;
|
||||
|
||||
const commands = require("./src/commands");
|
||||
|
||||
@@ -28,7 +20,7 @@ const commands = require("./src/commands");
|
||||
* Connector for control connection to controller
|
||||
* @private
|
||||
*/
|
||||
class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
class ControlConnector extends lib.WebSocketClientConnector {
|
||||
constructor(url, maxReconnectDelay, tlsCa, token) {
|
||||
super(url, maxReconnectDelay, tlsCa);
|
||||
this._token = token;
|
||||
@@ -37,8 +29,8 @@ class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
register() {
|
||||
logger.verbose("Connector | registering control");
|
||||
this.sendHandshake(
|
||||
new libData.MessageRegisterControl(
|
||||
new libData.RegisterControlData(
|
||||
new lib.MessageRegisterControl(
|
||||
new lib.RegisterControlData(
|
||||
this._token,
|
||||
"clusterioctl",
|
||||
version,
|
||||
@@ -54,13 +46,13 @@ class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
* Connects to the controller over WebSocket and sends commands to it.
|
||||
* @static
|
||||
*/
|
||||
class Control extends libLink.Link {
|
||||
class Control extends lib.Link {
|
||||
constructor(connector, controlConfig, tlsCa, controlPlugins) {
|
||||
super(connector);
|
||||
|
||||
/**
|
||||
* Control config used for connecting to the controller.
|
||||
* @type {module:lib/config.ControlConfig}
|
||||
* @type {module:lib.ControlConfig}
|
||||
*/
|
||||
this.config = controlConfig;
|
||||
/**
|
||||
@@ -70,7 +62,7 @@ class Control extends libLink.Link {
|
||||
this.tlsCa = tlsCa;
|
||||
/**
|
||||
* Mapping of plugin names to their instance for loaded plugins.
|
||||
* @type {Map<string, module:lib/plugin.BaseControlPlugin>}
|
||||
* @type {Map<string, module:lib.BaseControlPlugin>}
|
||||
*/
|
||||
this.plugins = controlPlugins;
|
||||
|
||||
@@ -80,8 +72,8 @@ class Control extends libLink.Link {
|
||||
*/
|
||||
this.keepOpen = false;
|
||||
|
||||
this.handle(libData.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(libData.DebugWsMessageEvent, this.handleDebugWsMessageEvent.bind(this));
|
||||
this.handle(lib.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(lib.DebugWsMessageEvent, this.handleDebugWsMessageEvent.bind(this));
|
||||
}
|
||||
|
||||
async setLogSubscriptions({
|
||||
@@ -92,7 +84,7 @@ class Control extends libLink.Link {
|
||||
maxLevel = null,
|
||||
}) {
|
||||
await this.send(
|
||||
new libData.LogSetSubscriptionsRequest(
|
||||
new lib.LogSetSubscriptionsRequest(
|
||||
all, controller, hostIds, instanceIds, maxLevel,
|
||||
)
|
||||
);
|
||||
@@ -111,7 +103,7 @@ class Control extends libLink.Link {
|
||||
try {
|
||||
await this.connector.disconnect();
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -119,10 +111,10 @@ class Control extends libLink.Link {
|
||||
}
|
||||
|
||||
async function loadPlugins(pluginList) {
|
||||
let pluginInfos = await libPluginLoader.loadPluginInfos(pluginList);
|
||||
libLink.registerPluginMessages(pluginInfos);
|
||||
libConfig.registerPluginConfigGroups(pluginInfos);
|
||||
libConfig.finalizeConfigs();
|
||||
let pluginInfos = await lib.loadPluginInfos(pluginList);
|
||||
lib.registerPluginMessages(pluginInfos);
|
||||
lib.registerPluginConfigGroups(pluginInfos);
|
||||
lib.finalizeConfigs();
|
||||
|
||||
let controlPlugins = new Map();
|
||||
for (let pluginInfo of pluginInfos) {
|
||||
@@ -130,7 +122,7 @@ async function loadPlugins(pluginList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let ControlPluginClass = await libPluginLoader.loadControlPluginClass(pluginInfo);
|
||||
let ControlPluginClass = await lib.loadControlPluginClass(pluginInfo);
|
||||
let controlPlugin = new ControlPluginClass(pluginInfo, logger);
|
||||
controlPlugins.set(pluginInfo.name, controlPlugin);
|
||||
await controlPlugin.init();
|
||||
@@ -162,8 +154,8 @@ async function startControl() {
|
||||
default: "plugin-list.json",
|
||||
type: "string",
|
||||
})
|
||||
.command("plugin", "Manage available plugins", libSharedCommands.pluginCommand)
|
||||
.command("control-config", "Manage Control config", libSharedCommands.configCommand)
|
||||
.command("plugin", "Manage available plugins", lib.pluginCommand)
|
||||
.command("control-config", "Manage Control config", lib.configCommand)
|
||||
.wrap(yargs.terminalWidth())
|
||||
.help(false) // Disable help to avoid triggering it on the first parse.
|
||||
;
|
||||
@@ -176,10 +168,10 @@ async function startControl() {
|
||||
new ConsoleTransport({
|
||||
errorLevels: Object.keys(levels),
|
||||
level: args.logLevel,
|
||||
format: new libLoggingUtils.TerminalFormat(),
|
||||
format: new lib.TerminalFormat(),
|
||||
})
|
||||
);
|
||||
libLoggingUtils.handleUnhandledErrors(logger);
|
||||
lib.handleUnhandledErrors(logger);
|
||||
|
||||
logger.verbose(`Loading available plugins from ${args.pluginList}`);
|
||||
let pluginList = new Map();
|
||||
@@ -193,7 +185,7 @@ async function startControl() {
|
||||
|
||||
// If the command is plugin management we don't try to load plugins
|
||||
if (args._[0] === "plugin") {
|
||||
await libSharedCommands.handlePluginCommand(args, pluginList, args.pluginList);
|
||||
await lib.handlePluginCommand(args, pluginList, args.pluginList);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,7 +203,7 @@ async function startControl() {
|
||||
;
|
||||
|
||||
logger.verbose(`Loading config from ${args.config}`);
|
||||
let controlConfig = new libConfig.ControlConfig("control");
|
||||
let controlConfig = new lib.ControlConfig("control");
|
||||
try {
|
||||
await controlConfig.load(JSON.parse(await fs.readFile(args.config)));
|
||||
|
||||
@@ -221,7 +213,7 @@ async function startControl() {
|
||||
await controlConfig.init();
|
||||
|
||||
} else {
|
||||
throw new libErrors.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,14 +224,14 @@ async function startControl() {
|
||||
|
||||
// Handle the control-config command before trying to connect.
|
||||
if (args._[0] === "control-config") {
|
||||
await libSharedCommands.handleConfigCommand(args, controlConfig, args.config);
|
||||
await lib.handleConfigCommand(args, controlConfig, args.config);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine which command is being executed.
|
||||
let commandPath = [...args._];
|
||||
let targetCommand = rootCommands;
|
||||
while (commandPath.length && targetCommand instanceof libCommand.CommandTree) {
|
||||
while (commandPath.length && targetCommand instanceof lib.CommandTree) {
|
||||
targetCommand = targetCommand.get(commandPath.shift());
|
||||
}
|
||||
|
||||
@@ -266,8 +258,8 @@ async function startControl() {
|
||||
try {
|
||||
await controlConnector.connect();
|
||||
} catch (err) {
|
||||
if (err instanceof libErrors.AuthenticationFailed) {
|
||||
throw new libErrors.StartupError(err.message);
|
||||
if (err instanceof lib.AuthenticationFailed) {
|
||||
throw new lib.StartupError(err.message);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -287,11 +279,11 @@ async function startControl() {
|
||||
|
||||
} catch (err) {
|
||||
control.keepOpen = false;
|
||||
if (err instanceof libErrors.CommandError) {
|
||||
if (err instanceof lib.CommandError) {
|
||||
logger.error(`Error running command: ${err.message}`);
|
||||
process.exitCode = 1;
|
||||
|
||||
} else if (err instanceof libErrors.RequestError) {
|
||||
} else if (err instanceof lib.RequestError) {
|
||||
logger.error(`Error sending request:\n${err.stack}`);
|
||||
process.exitCode = 1;
|
||||
|
||||
@@ -321,7 +313,7 @@ I version of clusterio. Expect things to break. I
|
||||
`
|
||||
);
|
||||
startControl().catch(err => {
|
||||
if (!(err instanceof libErrors.StartupError)) {
|
||||
if (!(err instanceof lib.StartupError)) {
|
||||
logger.fatal(`
|
||||
+------------------------------------------------------------+
|
||||
| Unexpected error occured while starting control, please |
|
||||
|
||||
+208
-215
File diff suppressed because it is too large.
Load diff
+21
-27
@@ -22,19 +22,13 @@ const winston = require("winston");
|
||||
require("winston-daily-rotate-file");
|
||||
|
||||
// internal libraries
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libPluginLoader = require("@clusterio/lib/plugin_loader");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libSharedCommands = require("@clusterio/lib/shared_commands");
|
||||
const { ConsoleTransport, FilteredTransport, levels, logger } = require("@clusterio/lib/logging");
|
||||
const libLoggingUtils = require("@clusterio/lib/logging_utils");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ConsoleTransport, levels, logger } = lib;
|
||||
|
||||
const Host = require("./src/Host");
|
||||
|
||||
|
||||
class HostConnector extends libLink.WebSocketClientConnector {
|
||||
class HostConnector extends lib.WebSocketClientConnector {
|
||||
constructor(hostConfig, tlsCa, pluginInfos) {
|
||||
super(
|
||||
hostConfig.get("host.controller_url"),
|
||||
@@ -53,8 +47,8 @@ class HostConnector extends libLink.WebSocketClientConnector {
|
||||
}
|
||||
|
||||
this.sendHandshake(
|
||||
new libData.MessageRegisterHost(
|
||||
new libData.RegisterHostData(
|
||||
new lib.MessageRegisterHost(
|
||||
new lib.RegisterHostData(
|
||||
this.hostConfig.get("host.controller_token"),
|
||||
"Clusterio Host",
|
||||
version,
|
||||
@@ -99,8 +93,8 @@ async function startHost() {
|
||||
default: "plugin-list.json",
|
||||
type: "string",
|
||||
})
|
||||
.command("plugin", "Manage available plugins", libSharedCommands.pluginCommand)
|
||||
.command("config", "Manage Host config", libSharedCommands.configCommand)
|
||||
.command("plugin", "Manage available plugins", lib.pluginCommand)
|
||||
.command("config", "Manage Host config", lib.configCommand)
|
||||
.command("run", "Run host")
|
||||
.demandCommand(1, "You need to specify a command to run")
|
||||
.strict()
|
||||
@@ -116,11 +110,11 @@ async function startHost() {
|
||||
if (args.logLevel !== "none") {
|
||||
logger.add(new ConsoleTransport({
|
||||
level: args.logLevel,
|
||||
format: new libLoggingUtils.TerminalFormat(),
|
||||
format: new lib.TerminalFormat(),
|
||||
filter: info => info.instance_id === undefined,
|
||||
}));
|
||||
}
|
||||
libLoggingUtils.handleUnhandledErrors(logger);
|
||||
lib.handleUnhandledErrors(logger);
|
||||
|
||||
let command = args._[0];
|
||||
if (command === "run") {
|
||||
@@ -139,18 +133,18 @@ async function startHost() {
|
||||
|
||||
// If the command is plugin management we don't try to load plugins
|
||||
if (command === "plugin") {
|
||||
await libSharedCommands.handlePluginCommand(args, pluginList, args.pluginList);
|
||||
await lib.handlePluginCommand(args, pluginList, args.pluginList);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Loading Plugin info");
|
||||
let pluginInfos = await libPluginLoader.loadPluginInfos(pluginList);
|
||||
libLink.registerPluginMessages(pluginInfos);
|
||||
libConfig.registerPluginConfigGroups(pluginInfos);
|
||||
libConfig.finalizeConfigs();
|
||||
let pluginInfos = await lib.loadPluginInfos(pluginList);
|
||||
lib.registerPluginMessages(pluginInfos);
|
||||
lib.registerPluginConfigGroups(pluginInfos);
|
||||
lib.finalizeConfigs();
|
||||
|
||||
logger.info(`Loading config from ${args.config}`);
|
||||
let hostConfig = new libConfig.HostConfig("host");
|
||||
let hostConfig = new lib.HostConfig("host");
|
||||
try {
|
||||
await hostConfig.load(JSON.parse(await fs.readFile(args.config)));
|
||||
|
||||
@@ -160,12 +154,12 @@ async function startHost() {
|
||||
await hostConfig.init();
|
||||
|
||||
} else {
|
||||
throw new libErrors.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
throw new lib.StartupError(`Failed to load ${args.config}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (command === "config") {
|
||||
await libSharedCommands.handleConfigCommand(args, hostConfig, args.config);
|
||||
await lib.handleConfigCommand(args, hostConfig, args.config);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -242,7 +236,7 @@ async function startHost() {
|
||||
});
|
||||
|
||||
hostConnector.once("connect", () => {
|
||||
logger.add(new libLoggingUtils.LinkTransport({ link: host }));
|
||||
logger.add(new lib.LinkTransport({ link: host }));
|
||||
});
|
||||
|
||||
await hostConnector.connect();
|
||||
@@ -259,10 +253,10 @@ I version of clusterio. Expect things to break. I
|
||||
`
|
||||
);
|
||||
startHost().catch(err => {
|
||||
if (err instanceof libErrors.AuthenticationFailed) {
|
||||
if (err instanceof lib.AuthenticationFailed) {
|
||||
logger.fatal(err.message);
|
||||
|
||||
} else if (err instanceof libErrors.StartupError) {
|
||||
} else if (err instanceof lib.StartupError) {
|
||||
logger.fatal(`
|
||||
+----------------------------------+
|
||||
| Unable to to start clusteriohost |
|
||||
@@ -270,7 +264,7 @@ I version of clusterio. Expect things to break. I
|
||||
${err.stack}`
|
||||
);
|
||||
|
||||
} else if (err instanceof libErrors.PluginError) {
|
||||
} else if (err instanceof lib.PluginError) {
|
||||
logger.fatal(`
|
||||
${err.pluginName} plugin threw an unexpected error
|
||||
during startup, please report it to the plugin author.
|
||||
|
||||
@@ -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",
|
||||
|
||||
+85
-93
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
const yargs = require("yargs");
|
||||
const events = require("events");
|
||||
const pidusage = require("pidusage");
|
||||
const setBlocking = require("set-blocking");
|
||||
@@ -10,15 +9,8 @@ const stream = require("stream");
|
||||
const util = require("util");
|
||||
|
||||
// internal libraries
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
const libHelpers = require("@clusterio/lib/helpers");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { logger } = lib;
|
||||
|
||||
const Instance = require("./Instance");
|
||||
const InstanceConnection = require("./InstanceConnection");
|
||||
@@ -28,9 +20,9 @@ const finished = util.promisify(stream.finished);
|
||||
|
||||
function checkRequestSaveName(name) {
|
||||
try {
|
||||
libFileOps.checkFilename(name);
|
||||
lib.checkFilename(name);
|
||||
} catch (err) {
|
||||
throw new libErrors.RequestError(`Save name ${err.message}`);
|
||||
throw new lib.RequestError(`Save name ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +42,7 @@ async function discoverInstances(instancesDir) {
|
||||
let instanceInfos = new Map();
|
||||
for (let entry of await fs.readdir(instancesDir, { withFileTypes: true })) {
|
||||
if (entry.isDirectory()) {
|
||||
let instanceConfig = new libConfig.InstanceConfig("host");
|
||||
let instanceConfig = new lib.InstanceConfig("host");
|
||||
let configPath = path.join(instancesDir, entry.name, "instance.json");
|
||||
|
||||
try {
|
||||
@@ -82,14 +74,14 @@ async function discoverInstances(instancesDir) {
|
||||
}
|
||||
|
||||
const instanceStartingMessages = new Set([
|
||||
libData.InstanceStartRequest.name,
|
||||
libData.InstanceLoadScenarioRequest.name,
|
||||
libData.InstanceCreateSaveRequest.name,
|
||||
libData.InstanceExportDataRequest.name,
|
||||
lib.InstanceStartRequest.name,
|
||||
lib.InstanceLoadScenarioRequest.name,
|
||||
lib.InstanceCreateSaveRequest.name,
|
||||
lib.InstanceExportDataRequest.name,
|
||||
]);
|
||||
|
||||
class HostRouter {
|
||||
/** @type {module:lib/host/src/Host} */
|
||||
/** @type {module:host/src/Host} */
|
||||
host;
|
||||
|
||||
constructor(host) {
|
||||
@@ -99,9 +91,9 @@ class HostRouter {
|
||||
/**
|
||||
* Forward a message to the next hop towards its destination.
|
||||
*
|
||||
* @param {module:lib/link.Link} origin -
|
||||
* @param {module:lib.Link} origin -
|
||||
* Link the message originated from.
|
||||
* @param {module:lib/data.Message} message - Message to process.
|
||||
* @param {module:lib.Message} message - Message to process.
|
||||
* @param {boolean} hasFallback - is fallback available
|
||||
* @returns {boolean} true if the message was handled, false if fallback
|
||||
* is requested
|
||||
@@ -110,17 +102,17 @@ class HostRouter {
|
||||
let dst = message.dst;
|
||||
let nextHop;
|
||||
let msg;
|
||||
if (dst.type === libData.Address.broadcast) {
|
||||
if (dst.type === lib.Address.broadcast) {
|
||||
this.broadcastMessage(origin, message);
|
||||
return true;
|
||||
} else if (
|
||||
dst.type === libData.Address.controller
|
||||
|| dst.type === libData.Address.control
|
||||
|| dst.type === libData.Address.host && dst.id !== this.host.config.get("host.id")
|
||||
|| dst.type === libData.Address.instance && !this.host.instanceInfos.has(dst.id)
|
||||
dst.type === lib.Address.controller
|
||||
|| dst.type === lib.Address.control
|
||||
|| dst.type === lib.Address.host && dst.id !== this.host.config.get("host.id")
|
||||
|| dst.type === lib.Address.instance && !this.host.instanceInfos.has(dst.id)
|
||||
) {
|
||||
nextHop = this.host;
|
||||
} else if (dst.type === libData.Address.instance && this.host.instanceInfos.has(dst.id)) {
|
||||
} else if (dst.type === lib.Address.instance && this.host.instanceInfos.has(dst.id)) {
|
||||
nextHop = this.host.instanceConnections.get(dst.id);
|
||||
}
|
||||
|
||||
@@ -130,17 +122,17 @@ class HostRouter {
|
||||
}
|
||||
|
||||
if (message.type === "request") {
|
||||
if (dst.type === libData.Address.instance && instanceStartingMessages.has(message.name)) {
|
||||
if (dst.type === lib.Address.instance && instanceStartingMessages.has(message.name)) {
|
||||
this.wakeInstance(origin, message, nextHop);
|
||||
return true;
|
||||
|
||||
} else if (!nextHop) {
|
||||
if (dst.type === libData.Address.instance) {
|
||||
if (dst.type === lib.Address.instance) {
|
||||
if (hasFallback) {
|
||||
return false;
|
||||
}
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError("Instance is not running."), message.src
|
||||
new lib.ResponseError("Instance is not running."), message.src
|
||||
);
|
||||
}
|
||||
return true;
|
||||
@@ -163,7 +155,7 @@ class HostRouter {
|
||||
let dst = message.dst;
|
||||
if (message.type !== "event") {
|
||||
this.warnUnrouted(message, `Unexpected broadcast of ${message.type}`);
|
||||
} else if (dst.id === libData.Address.host || dst.id === libData.Address.instance) {
|
||||
} else if (dst.id === lib.Address.host || dst.id === lib.Address.instance) {
|
||||
for (let instanceConnection of this.host.instanceConnections.values()) {
|
||||
if (instanceConnection !== origin) {
|
||||
instanceConnection.connector.send(message);
|
||||
@@ -172,7 +164,7 @@ class HostRouter {
|
||||
if (this.host !== origin) {
|
||||
this.host.connector.send(message);
|
||||
}
|
||||
} else if (dst.id === libData.Address.control) {
|
||||
} else if (dst.id === lib.Address.control) {
|
||||
if (this.host !== origin) {
|
||||
this.host.connector.send(message);
|
||||
} else {
|
||||
@@ -187,13 +179,13 @@ class HostRouter {
|
||||
let dst = message.dst;
|
||||
if (nextHop) {
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError("Instance is already running."), message.src
|
||||
new lib.ResponseError("Instance is already running."), message.src
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (this.host._shuttingDown) {
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError("Host is shutting down."), message.src
|
||||
new lib.ResponseError("Host is shutting down."), message.src
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -203,7 +195,7 @@ class HostRouter {
|
||||
}).catch(err => {
|
||||
logger.error(`Error starting instance:\n${err.stack}`, this.host.instanceLogMeta(dst.id));
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError(err.message, err.code, err.stack), message.src
|
||||
new lib.ResponseError(err.message, err.code, err.stack), message.src
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -218,7 +210,7 @@ class HostRouter {
|
||||
} catch (err) {
|
||||
if (message.type === "request") {
|
||||
origin.connector.sendResponseError(
|
||||
new libData.ResponseError(err.message, err.code, err.stack), message.src
|
||||
new lib.ResponseError(err.message, err.code, err.stack), message.src
|
||||
);
|
||||
}
|
||||
logger.warn(`Failed to deliver ${message.name || "message"} (${message.type}): ${err.message}`);
|
||||
@@ -238,7 +230,7 @@ class HostRouter {
|
||||
* Connects to the controller over the WebSocket and manages intsances.
|
||||
* @alias module:host/src/Host
|
||||
*/
|
||||
class Host extends libLink.Link {
|
||||
class Host extends lib.Link {
|
||||
constructor(connector, hostConfig, tlsCa, pluginInfos) {
|
||||
super(connector);
|
||||
|
||||
@@ -275,7 +267,7 @@ class Host extends libLink.Link {
|
||||
}
|
||||
|
||||
this.updateInstances().catch((err) => {
|
||||
if (err instanceof libErrors.SessionLost) {
|
||||
if (err instanceof lib.SessionLost) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -304,41 +296,41 @@ class Host extends libLink.Link {
|
||||
|
||||
for (let event of ["connect", "drop", "resume", "close"]) {
|
||||
this.connector.on(event, () => {
|
||||
let message = new libData.ControllerConnectionEvent(event);
|
||||
let message = new lib.ControllerConnectionEvent(event);
|
||||
for (let instanceConnection of this.instanceConnections.values()) {
|
||||
instanceConnection.send(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.handle(libData.SyncUserListsEvent, this.handleSyncUserListsEvent.bind(this));
|
||||
this.snoopEvent(libData.InstanceAdminlistUpdateEvent, this.handleAdminlistUpdateEvent.bind(this));
|
||||
this.snoopEvent(libData.InstanceBanlistUpdateEvent, this.handleBanlistUpdateEvent.bind(this));
|
||||
this.snoopEvent(libData.InstanceWhitelistUpdateEvent, this.handleWhitelistUpdateEvent.bind(this));
|
||||
this.handle(libData.InstanceAssignInternalRequest, this.handleInstanceAssignInternalRequest.bind(this));
|
||||
this.handle(libData.InstanceUnassignInternalRequest, this.handleInstanceUnassignInternalRequest.bind(this));
|
||||
this.handle(libData.HostMetricsRequest, this.handleHostMetricsRequest.bind(this));
|
||||
this.fallbackRequest(libData.InstanceListSavesRequest, this.fallbackInstanceListSavesRequest.bind(this));
|
||||
this.handle(libData.InstanceRenameSaveRequest, this.handleInstanceRenameSaveRequest.bind(this));
|
||||
this.handle(libData.InstanceCopySaveRequest, this.handleInstanceCopySaveRequest.bind(this));
|
||||
this.handle(libData.InstanceTransferSaveRequest, this.handleInstanceTransferSaveRequest.bind(this));
|
||||
this.handle(libData.InstanceDeleteSaveRequest, this.handleInstanceDeleteSaveRequest.bind(this));
|
||||
this.handle(libData.InstancePullSaveRequest, this.handleInstancePullSaveRequest.bind(this));
|
||||
this.handle(libData.InstancePushSaveRequest, this.handleInstancePushSaveRequest.bind(this));
|
||||
this.handle(libData.InstanceDeleteInternalRequest, this.handleInstanceDeleteInternalRequest.bind(this));
|
||||
this.handle(lib.SyncUserListsEvent, this.handleSyncUserListsEvent.bind(this));
|
||||
this.snoopEvent(lib.InstanceAdminlistUpdateEvent, this.handleAdminlistUpdateEvent.bind(this));
|
||||
this.snoopEvent(lib.InstanceBanlistUpdateEvent, this.handleBanlistUpdateEvent.bind(this));
|
||||
this.snoopEvent(lib.InstanceWhitelistUpdateEvent, this.handleWhitelistUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceAssignInternalRequest, this.handleInstanceAssignInternalRequest.bind(this));
|
||||
this.handle(lib.InstanceUnassignInternalRequest, this.handleInstanceUnassignInternalRequest.bind(this));
|
||||
this.handle(lib.HostMetricsRequest, this.handleHostMetricsRequest.bind(this));
|
||||
this.fallbackRequest(lib.InstanceListSavesRequest, this.fallbackInstanceListSavesRequest.bind(this));
|
||||
this.handle(lib.InstanceRenameSaveRequest, this.handleInstanceRenameSaveRequest.bind(this));
|
||||
this.handle(lib.InstanceCopySaveRequest, this.handleInstanceCopySaveRequest.bind(this));
|
||||
this.handle(lib.InstanceTransferSaveRequest, this.handleInstanceTransferSaveRequest.bind(this));
|
||||
this.handle(lib.InstanceDeleteSaveRequest, this.handleInstanceDeleteSaveRequest.bind(this));
|
||||
this.handle(lib.InstancePullSaveRequest, this.handleInstancePullSaveRequest.bind(this));
|
||||
this.handle(lib.InstancePushSaveRequest, this.handleInstancePushSaveRequest.bind(this));
|
||||
this.handle(lib.InstanceDeleteInternalRequest, this.handleInstanceDeleteInternalRequest.bind(this));
|
||||
}
|
||||
|
||||
async _createNewInstanceDir(name) {
|
||||
name = libFileOps.cleanFilename(name);
|
||||
name = lib.cleanFilename(name);
|
||||
try {
|
||||
libFileOps.checkFilename(name);
|
||||
lib.checkFilename(name);
|
||||
} catch (err) {
|
||||
throw new Error(`Instance folder was unepectedly invalid: name ${err.message}`);
|
||||
}
|
||||
|
||||
let instancesDir = this.config.get("host.instances_directory");
|
||||
for (let i = 0; i < 10; i++) { // Limit attempts in case this is somehow an infinite loop
|
||||
let candidateDir = path.join(instancesDir, await libFileOps.findUnusedName(instancesDir, name));
|
||||
let candidateDir = path.join(instancesDir, await lib.findUnusedName(instancesDir, name));
|
||||
try {
|
||||
await fs.mkdir(candidateDir);
|
||||
} catch (err) {
|
||||
@@ -377,8 +369,8 @@ class Host extends libLink.Link {
|
||||
}
|
||||
};
|
||||
|
||||
updateList(this.adminlist, request.adminlist, libData.InstanceAdminlistUpdateEvent);
|
||||
updateList(this.whitelist, request.whitelist, libData.InstanceWhitelistUpdateEvent);
|
||||
updateList(this.adminlist, request.adminlist, lib.InstanceAdminlistUpdateEvent);
|
||||
updateList(this.whitelist, request.whitelist, lib.InstanceWhitelistUpdateEvent);
|
||||
|
||||
let addedOrChanged = new Map(request.banlist);
|
||||
let removed = new Set(this.banlist.keys());
|
||||
@@ -391,12 +383,12 @@ class Host extends libLink.Link {
|
||||
|
||||
for (let [name, reason] of addedOrChanged) {
|
||||
this.banlist.set(name, reason);
|
||||
this.broadcastEventToInstance(new libData.InstanceBanlistUpdateEvent(name, true, reason));
|
||||
this.broadcastEventToInstance(new lib.InstanceBanlistUpdateEvent(name, true, reason));
|
||||
}
|
||||
|
||||
for (let name of removed) {
|
||||
this.banlist.delete(name);
|
||||
this.broadcastEventToInstance(new libData.InstanceBanlistUpdateEvent(name, false, ""));
|
||||
this.broadcastEventToInstance(new lib.InstanceBanlistUpdateEvent(name, false, ""));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,7 +432,7 @@ class Host extends libLink.Link {
|
||||
instanceInfo.config.update(config, true, "controller");
|
||||
|
||||
} else {
|
||||
let instanceConfig = new libConfig.InstanceConfig("host");
|
||||
let instanceConfig = new lib.InstanceConfig("host");
|
||||
await instanceConfig.load(config, "controller");
|
||||
|
||||
let instanceDir = await this._createNewInstanceDir(instanceConfig.get("instance.name"));
|
||||
@@ -464,7 +456,7 @@ class Host extends libLink.Link {
|
||||
// request for all the instances it knows should be on this host.
|
||||
let instanceConnection = this.instanceConnections.get(instanceId);
|
||||
this.send(
|
||||
new libData.InstanceStatusChangedEvent(
|
||||
new lib.InstanceStatusChangedEvent(
|
||||
instanceId, instanceConnection ? instanceConnection.status : "stopped", null
|
||||
)
|
||||
);
|
||||
@@ -474,7 +466,7 @@ class Host extends libLink.Link {
|
||||
_warning: "Changes to this file will be overwritten by the controller's copy.",
|
||||
...instanceInfo.config.serialize(),
|
||||
};
|
||||
await libFileOps.safeOutputFile(
|
||||
await lib.safeOutputFile(
|
||||
path.join(instanceInfo.path, "instance.json"),
|
||||
JSON.stringify(warnedOutput, null, 4)
|
||||
);
|
||||
@@ -486,7 +478,7 @@ class Host extends libLink.Link {
|
||||
if (instanceInfo) {
|
||||
let instanceConnection = this.instanceConnections.get(instanceId);
|
||||
if (instanceConnection && ["starting", "running"].includes(instanceConnection.status)) {
|
||||
await instanceConnection.send(new libData.InstanceStopRequest());
|
||||
await instanceConnection.send(new lib.InstanceStopRequest());
|
||||
}
|
||||
|
||||
this.instanceInfos.delete(instanceId);
|
||||
@@ -505,7 +497,7 @@ class Host extends libLink.Link {
|
||||
getRequestInstanceInfo(instanceId) {
|
||||
let instanceInfo = this.instanceInfos.get(instanceId);
|
||||
if (!instanceInfo) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
}
|
||||
return instanceInfo;
|
||||
}
|
||||
@@ -519,12 +511,12 @@ class Host extends libLink.Link {
|
||||
async _connectInstance(instanceId) {
|
||||
let instanceInfo = this.getRequestInstanceInfo(instanceId);
|
||||
if (this.instanceConnections.has(instanceId)) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} is running`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} is running`);
|
||||
}
|
||||
|
||||
let hostAddress = new libData.Address(libData.Address.host, this.id);
|
||||
let instanceAddress = new libData.Address(libData.Address.instance, instanceId);
|
||||
let [connectionClient, connectionServer] = libLink.VirtualConnector.makePair(instanceAddress, hostAddress);
|
||||
let hostAddress = new lib.Address(lib.Address.host, this.id);
|
||||
let instanceAddress = new lib.Address(lib.Address.instance, instanceId);
|
||||
let [connectionClient, connectionServer] = lib.VirtualConnector.makePair(instanceAddress, hostAddress);
|
||||
let instanceConnection = new InstanceConnection(connectionServer, this, instanceId);
|
||||
let instance = new Instance(
|
||||
this, connectionClient, instanceInfo.path, this.config.get("host.factorio_directory"), instanceInfo.config
|
||||
@@ -539,7 +531,7 @@ class Host extends libLink.Link {
|
||||
async handleHostMetricsRequest() {
|
||||
let requests = [];
|
||||
for (let instanceConnection of this.instanceConnections.values()) {
|
||||
requests.push(instanceConnection.send(new libData.InstanceMetricsRequest()));
|
||||
requests.push(instanceConnection.send(new lib.InstanceMetricsRequest()));
|
||||
}
|
||||
|
||||
let results = [];
|
||||
@@ -547,15 +539,15 @@ class Host extends libLink.Link {
|
||||
results.push(...response.results);
|
||||
}
|
||||
|
||||
for await (let result of libPrometheus.defaultRegistry.collect()) {
|
||||
for await (let result of lib.defaultRegistry.collect()) {
|
||||
if (result.metric.name.startsWith("process_")) {
|
||||
results.push(libPrometheus.serializeResult(result, {
|
||||
results.push(lib.serializeResult(result, {
|
||||
addLabels: { "host_id": String(this.config.get("host.id")) },
|
||||
metricName: result.metric.name.replace("process_", "clusterio_host_"),
|
||||
}));
|
||||
|
||||
} else {
|
||||
results.push(libPrometheus.serializeResult(result));
|
||||
results.push(lib.serializeResult(result));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,7 +572,7 @@ class Host extends libLink.Link {
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
throw new libErrors.RequestError(`${oldName} does not exist`);
|
||||
throw new lib.RequestError(`${oldName} does not exist`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -600,7 +592,7 @@ class Host extends libLink.Link {
|
||||
);
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
throw new libErrors.RequestError(`${source} does not exist`);
|
||||
throw new lib.RequestError(`${source} does not exist`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -616,7 +608,7 @@ class Host extends libLink.Link {
|
||||
|
||||
// For consistency with remote transfer initiated through pullSave the
|
||||
// target is renamed if it already exists.
|
||||
targetName = await libFileOps.findUnusedName(
|
||||
targetName = await lib.findUnusedName(
|
||||
path.join(targetInstanceInfo.path, "saves"), targetName, ".zip"
|
||||
);
|
||||
|
||||
@@ -636,7 +628,7 @@ class Host extends libLink.Link {
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
throw new libErrors.RequestError(`${sourceName} does not exist`);
|
||||
throw new lib.RequestError(`${sourceName} does not exist`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -650,12 +642,12 @@ class Host extends libLink.Link {
|
||||
let instanceConnection = this.instanceConnections.get(instanceId);
|
||||
let saveList;
|
||||
if (instanceConnection) {
|
||||
saveList = await instanceConnection.send(new libData.InstanceListSavesRequest());
|
||||
saveList = await instanceConnection.send(new lib.InstanceListSavesRequest());
|
||||
} else {
|
||||
saveList = await Instance.listSaves(savesDir, null);
|
||||
}
|
||||
|
||||
this.send(new libData.InstanceSaveListUpdateEvent(instanceId, saveList));
|
||||
this.send(new lib.InstanceSaveListUpdateEvent(instanceId, saveList));
|
||||
}
|
||||
|
||||
async handleInstanceDeleteSaveRequest(request) {
|
||||
@@ -667,7 +659,7 @@ class Host extends libLink.Link {
|
||||
await fs.unlink(path.join(instanceInfo.path, "saves", name));
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
throw new libErrors.RequestError(`${name} does not exist`);
|
||||
throw new lib.RequestError(`${name} does not exist`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -688,8 +680,8 @@ class Host extends libLink.Link {
|
||||
});
|
||||
|
||||
if (response.statusCode !== 200) {
|
||||
let content = await libHelpers.readStream(response);
|
||||
throw new libErrors.RequestError(`Stream returned ${response.statusCode}: ${content.toString()}`);
|
||||
let content = await lib.readStream(response);
|
||||
throw new lib.RequestError(`Stream returned ${response.statusCode}: ${content.toString()}`);
|
||||
}
|
||||
|
||||
let savesDir = path.join(instanceInfo.path, "saves");
|
||||
@@ -702,7 +694,7 @@ class Host extends libLink.Link {
|
||||
break;
|
||||
} catch (err) {
|
||||
if (err.code === "EEXIST") {
|
||||
tempFilename = await libFileOps.findUnusedName(savesDir, tempFilename, ".tmp.zip");
|
||||
tempFilename = await lib.findUnusedName(savesDir, tempFilename, ".tmp.zip");
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
@@ -711,7 +703,7 @@ class Host extends libLink.Link {
|
||||
response.pipe(writeStream);
|
||||
await finished(writeStream);
|
||||
|
||||
name = await libFileOps.findUnusedName(savesDir, name, ".zip");
|
||||
name = await lib.findUnusedName(savesDir, name, ".zip");
|
||||
await fs.rename(path.join(savesDir, tempFilename), path.join(savesDir, name));
|
||||
|
||||
await this.sendSaveListUpdate(instanceId, savesDir);
|
||||
@@ -729,7 +721,7 @@ class Host extends libLink.Link {
|
||||
content = await fs.readFile(path.join(instanceInfo.path, "saves", name));
|
||||
} catch (err) {
|
||||
if (err.code === "ENOENT") {
|
||||
throw new libErrors.RequestError(`${name} does not exist`);
|
||||
throw new lib.RequestError(`${name} does not exist`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
@@ -747,18 +739,18 @@ class Host extends libLink.Link {
|
||||
|
||||
async stopInstance(instanceId) {
|
||||
let instanceConnection = this.instanceConnections.get(instanceId);
|
||||
await instanceConnection.send(new libData.InstanceStopRequest());
|
||||
await instanceConnection.send(new lib.InstanceStopRequest());
|
||||
}
|
||||
|
||||
async handleInstanceDeleteInternalRequest(request) {
|
||||
let instanceId = request.instanceId;
|
||||
if (this.instanceConnections.has(instanceId)) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} is running`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} is running`);
|
||||
}
|
||||
|
||||
let instanceInfo = this.discoveredInstanceInfos.get(instanceId);
|
||||
if (!instanceInfo) {
|
||||
throw new libErrors.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
throw new lib.RequestError(`Instance with ID ${instanceId} does not exist`);
|
||||
}
|
||||
|
||||
this.discoveredInstanceInfos.delete(instanceId);
|
||||
@@ -777,12 +769,12 @@ class Host extends libLink.Link {
|
||||
let list = [];
|
||||
for (let [instanceId, instanceInfo] of this.discoveredInstanceInfos) {
|
||||
let instanceConnection = this.instanceConnections.get(instanceId);
|
||||
list.push(new libData.RawInstanceInfo(
|
||||
list.push(new lib.RawInstanceInfo(
|
||||
instanceInfo.config.serialize("controller"),
|
||||
instanceConnection ? instanceConnection.status : "stopped",
|
||||
));
|
||||
}
|
||||
await this.send(new libData.InstancesUpdateRequest(list));
|
||||
await this.send(new lib.InstancesUpdateRequest(list));
|
||||
|
||||
// Handle configured auto startup instances
|
||||
if (this._startup) {
|
||||
@@ -792,7 +784,7 @@ class Host extends libLink.Link {
|
||||
if (instanceInfo.config.get("instance.auto_start")) {
|
||||
try {
|
||||
let instanceConnection = await this._connectInstance(instanceId);
|
||||
await instanceConnection.send(new libData.InstanceStartRequest(null));
|
||||
await instanceConnection.send(new lib.InstanceStartRequest(null));
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`Error during auto startup for ${instanceInfo.config.get("instance.name")}:\n${err.stack}`,
|
||||
@@ -806,7 +798,7 @@ class Host extends libLink.Link {
|
||||
|
||||
async prepareDisconnect() {
|
||||
for (let instanceConnection of this.instanceConnections.values()) {
|
||||
await instanceConnection.send(new libData.PrepareControllerDisconnectRequest());
|
||||
await instanceConnection.send(new lib.PrepareControllerDisconnectRequest());
|
||||
}
|
||||
this._disconnecting = true;
|
||||
return await super.prepareDisconnect();
|
||||
@@ -832,7 +824,7 @@ class Host extends libLink.Link {
|
||||
try {
|
||||
await this.connector.disconnect();
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
logger.error(`Unexpected error preparing disconnect:\n${err.stack}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,47 +6,42 @@ const phin = require("phin");
|
||||
const util = require("util");
|
||||
|
||||
// internal libraries
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libFactorio = require("@clusterio/lib/factorio");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const PlayerStats = require("@clusterio/lib/PlayerStats");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libPluginLoader = require("@clusterio/lib/plugin_loader");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const libLuaTools = require("@clusterio/lib/lua_tools");
|
||||
const libLogging = require("@clusterio/lib/logging");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { PlayerStats } = lib;
|
||||
|
||||
const { FactorioServer } = require("./server");
|
||||
const { patch } = require("./patch");
|
||||
const { exportData } = require("./export");
|
||||
|
||||
|
||||
const instanceRconCommandDuration = new libPrometheus.Histogram(
|
||||
const instanceRconCommandDuration = new lib.Histogram(
|
||||
"clusterio_instance_rcon_command_duration_seconds",
|
||||
"Histogram of the RCON command duration from request to response.",
|
||||
{ labels: ["instance_id"] }
|
||||
);
|
||||
|
||||
const instanceRconCommandSize = new libPrometheus.Histogram(
|
||||
const instanceRconCommandSize = new lib.Histogram(
|
||||
"clusterio_instance_rcon_command_size_bytes",
|
||||
"Histogram of the RCON command sizes that are sent.",
|
||||
{
|
||||
labels: ["instance_id", "plugin"],
|
||||
buckets: libPrometheus.Histogram.exponential(16, 2, 12),
|
||||
buckets: lib.Histogram.exponential(16, 2, 12),
|
||||
}
|
||||
);
|
||||
|
||||
const instanceFactorioCpuTime = new libPrometheus.Gauge(
|
||||
const instanceFactorioCpuTime = new lib.Gauge(
|
||||
"clusterio_instance_factorio_cpu_time_total",
|
||||
"Factorio CPU time spent in seconds.",
|
||||
{ labels: ["instance_id"] }
|
||||
);
|
||||
|
||||
const instanceFactorioMemoryUsage = new libPrometheus.Gauge(
|
||||
const instanceFactorioMemoryUsage = new lib.Gauge(
|
||||
"clusterio_instance_factorio_resident_memory_bytes",
|
||||
"Factorio resident memory size in bytes.",
|
||||
{ labels: ["instance_id"] }
|
||||
);
|
||||
|
||||
const instanceFactorioAutosaveSize = new libPrometheus.Gauge(
|
||||
const instanceFactorioAutosaveSize = new lib.Gauge(
|
||||
"clusterio_instance_factorio_autosave_bytes",
|
||||
"Size of Factorio server autosave in bytes.",
|
||||
{ labels: ["instance_id"] }
|
||||
@@ -100,7 +95,7 @@ const serverSettingsActions = {
|
||||
* Keeps track of the runtime parameters of an instance
|
||||
* @alias module:host/src/Instance
|
||||
*/
|
||||
class Instance extends libLink.Link {
|
||||
class Instance extends lib.Link {
|
||||
constructor(host, connector, dir, factorioDir, instanceConfig) {
|
||||
super(connector);
|
||||
this._host = host;
|
||||
@@ -115,13 +110,13 @@ class Instance extends libLink.Link {
|
||||
*/
|
||||
this.id = this.config.get("instance.id");
|
||||
|
||||
this.logger = libLogging.logger.child({
|
||||
this.logger = lib.logger.child({
|
||||
instance_id: this.id,
|
||||
instance_name: this.name,
|
||||
});
|
||||
|
||||
this._configFieldChanged = (group, field, prev) => {
|
||||
let hook = () => libPlugin.invokeHook(this.plugins, "onInstanceConfigFieldChanged", group, field, prev);
|
||||
let hook = () => lib.invokeHook(this.plugins, "onInstanceConfigFieldChanged", group, field, prev);
|
||||
|
||||
if (group.name === "factorio" && field === "settings") {
|
||||
this.updateFactorioSettings(group.get(field), prev).finally(hook);
|
||||
@@ -152,18 +147,18 @@ class Instance extends libLink.Link {
|
||||
// Valid statuses are stopped, starting, running, stopping, creating_save and exporting_data.
|
||||
this._status = "stopped";
|
||||
this._loadedSave = null;
|
||||
this.server = new libFactorio.FactorioServer(
|
||||
this.server = new FactorioServer(
|
||||
factorioDir, this._dir, serverOptions
|
||||
);
|
||||
|
||||
this.server.on("output", (parsed, line) => {
|
||||
this.logger.log("server", { message: line, instance_id: this.id, parsed });
|
||||
|
||||
libPlugin.invokeHook(this.plugins, "onOutput", parsed, line);
|
||||
lib.invokeHook(this.plugins, "onOutput", parsed, line);
|
||||
});
|
||||
|
||||
this.server.on("error", err => {
|
||||
if (err instanceof libErrors.EnvironmentError) {
|
||||
if (err instanceof lib.EnvironmentError) {
|
||||
this.logger.error(err.message);
|
||||
} else {
|
||||
this.logger.error(`${this.name}:\n${err.stack}`);
|
||||
@@ -192,13 +187,13 @@ class Instance extends libLink.Link {
|
||||
|
||||
/**
|
||||
* Mod pack currently running on this instance
|
||||
* @type {module:lib/data.ModPack}
|
||||
* @type {module:lib.ModPack}
|
||||
*/
|
||||
this.activeModPack = undefined;
|
||||
|
||||
/**
|
||||
* Per player statistics recorded by this instance.
|
||||
* @type {Map<string, module:lib/PlayerStats>}
|
||||
* @type {Map<string, module:lib.PlayerStats>}
|
||||
*/
|
||||
this.playerStats = new Map();
|
||||
|
||||
@@ -211,23 +206,23 @@ class Instance extends libLink.Link {
|
||||
this._hadPlayersOnline = false;
|
||||
this._playerAutosaveSlot = 1;
|
||||
|
||||
this.handle(libData.InstanceExtractPlayersRequest, this.handleInstanceExtractPlayersRequest.bind(this));
|
||||
this.handle(libData.InstanceAdminlistUpdateEvent, this.handleInstanceAdminlistUpdateEvent.bind(this));
|
||||
this.handle(libData.InstanceBanlistUpdateEvent, this.handleInstanceBanlistUpdateEvent.bind(this));
|
||||
this.handle(libData.InstanceWhitelistUpdateEvent, this.handleInstanceWhitelistUpdateEvent.bind(this));
|
||||
this.handle(libData.ControllerConnectionEvent, this.handleControllerConnectionEvent.bind(this));
|
||||
this.handle(lib.InstanceExtractPlayersRequest, this.handleInstanceExtractPlayersRequest.bind(this));
|
||||
this.handle(lib.InstanceAdminlistUpdateEvent, this.handleInstanceAdminlistUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceBanlistUpdateEvent, this.handleInstanceBanlistUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceWhitelistUpdateEvent, this.handleInstanceWhitelistUpdateEvent.bind(this));
|
||||
this.handle(lib.ControllerConnectionEvent, this.handleControllerConnectionEvent.bind(this));
|
||||
this.handle(
|
||||
libData.PrepareControllerDisconnectRequest, this.handlePrepareControllerDisconnectRequest.bind(this)
|
||||
lib.PrepareControllerDisconnectRequest, this.handlePrepareControllerDisconnectRequest.bind(this)
|
||||
);
|
||||
this.handle(libData.InstanceMetricsRequest, this.handleInstanceMetricsRequest.bind(this));
|
||||
this.handle(libData.InstanceStartRequest, this.handleInstanceStartRequest.bind(this));
|
||||
this.handle(libData.InstanceLoadScenarioRequest, this.handleInstanceLoadScenarioRequest.bind(this));
|
||||
this.handle(libData.InstanceListSavesRequest, this.handleInstanceListSavesRequest.bind(this));
|
||||
this.handle(libData.InstanceCreateSaveRequest, this.handleInstanceCreateSaveRequest.bind(this));
|
||||
this.handle(libData.InstanceExportDataRequest, this.handleInstanceExportDataRequest.bind(this));
|
||||
this.handle(libData.InstanceStopRequest, this.handleInstanceStopRequest.bind(this));
|
||||
this.handle(libData.InstanceKillRequest, this.handleInstanceKillRequest.bind(this));
|
||||
this.handle(libData.InstanceSendRconRequest, this.handleInstanceSendRconRequest.bind(this));
|
||||
this.handle(lib.InstanceMetricsRequest, this.handleInstanceMetricsRequest.bind(this));
|
||||
this.handle(lib.InstanceStartRequest, this.handleInstanceStartRequest.bind(this));
|
||||
this.handle(lib.InstanceLoadScenarioRequest, this.handleInstanceLoadScenarioRequest.bind(this));
|
||||
this.handle(lib.InstanceListSavesRequest, this.handleInstanceListSavesRequest.bind(this));
|
||||
this.handle(lib.InstanceCreateSaveRequest, this.handleInstanceCreateSaveRequest.bind(this));
|
||||
this.handle(lib.InstanceExportDataRequest, this.handleInstanceExportDataRequest.bind(this));
|
||||
this.handle(lib.InstanceStopRequest, this.handleInstanceStopRequest.bind(this));
|
||||
this.handle(lib.InstanceKillRequest, this.handleInstanceKillRequest.bind(this));
|
||||
this.handle(lib.InstanceSendRconRequest, this.handleInstanceSendRconRequest.bind(this));
|
||||
}
|
||||
|
||||
_watchPlayerJoinsByChat() {
|
||||
@@ -303,8 +298,8 @@ class Instance extends libLink.Link {
|
||||
name,
|
||||
stats,
|
||||
};
|
||||
this.sendTo("controller", new libData.InstancePlayerUpdateEvent("join", name, undefined, stats));
|
||||
libPlugin.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
this.sendTo("controller", new lib.InstancePlayerUpdateEvent("join", name, undefined, stats));
|
||||
lib.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
}
|
||||
|
||||
_recordPlayerLeave(name, reason) {
|
||||
@@ -325,8 +320,8 @@ class Instance extends libLink.Link {
|
||||
reason,
|
||||
stats,
|
||||
};
|
||||
this.sendTo("controller", new libData.InstancePlayerUpdateEvent("leave", name, reason, stats));
|
||||
libPlugin.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
this.sendTo("controller", new lib.InstancePlayerUpdateEvent("leave", name, reason, stats));
|
||||
lib.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
}
|
||||
|
||||
async handleInstanceExtractPlayersRequest() {
|
||||
@@ -353,8 +348,8 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
name,
|
||||
stats: stats.toJSON(),
|
||||
};
|
||||
this.sendTo("controller", new libData.InstancePlayerUpdateEvent("import", name, undefined, stats));
|
||||
libPlugin.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
this.sendTo("controller", new lib.InstancePlayerUpdateEvent("import", name, undefined, stats));
|
||||
lib.invokeHook(this.plugins, "onPlayerEvent", event);
|
||||
count += 1;
|
||||
}
|
||||
this.logger.info(`Extracted data for ${count} player(s)`);
|
||||
@@ -374,7 +369,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
static async listSaves(savesDir, loadedSave) {
|
||||
let defaultSave = null;
|
||||
if (loadedSave === null) {
|
||||
defaultSave = await libFileOps.getNewestFile(
|
||||
defaultSave = await lib.getNewestFile(
|
||||
savesDir, (name) => !name.endsWith(".tmp.zip")
|
||||
);
|
||||
}
|
||||
@@ -391,7 +386,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
type = "special";
|
||||
}
|
||||
|
||||
list.push(new libData.SaveDetails(
|
||||
list.push(new lib.SaveDetails(
|
||||
type,
|
||||
name,
|
||||
stat.size,
|
||||
@@ -407,7 +402,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
async sendSaveListUpdate() {
|
||||
this.sendTo(
|
||||
"controller",
|
||||
new libData.InstanceSaveListUpdateEvent(
|
||||
new lib.InstanceSaveListUpdateEvent(
|
||||
this.id,
|
||||
await Instance.listSaves(this.path("saves"), this._loadedSave),
|
||||
),
|
||||
@@ -440,7 +435,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
this._status = status;
|
||||
this.sendTo(
|
||||
"controller",
|
||||
new libData.InstanceStatusChangedEvent(
|
||||
new lib.InstanceStatusChangedEvent(
|
||||
this.id,
|
||||
status,
|
||||
this.server && this.server.gamePort || this.config.get("factorio.game_port") || null,
|
||||
@@ -467,9 +462,9 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
clearTimeout(this._playerCheckInterval);
|
||||
|
||||
// Clear metrics this instance is exporting
|
||||
for (let collector of libPrometheus.defaultRegistry.collectors) {
|
||||
for (let collector of lib.defaultRegistry.collectors) {
|
||||
if (
|
||||
collector instanceof libPrometheus.ValueCollector
|
||||
collector instanceof lib.ValueCollector
|
||||
&& collector.metric.labels.includes("instance_id")
|
||||
) {
|
||||
collector.removeAll({ instance_id: String(this.id) });
|
||||
@@ -489,7 +484,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
async _loadPlugin(pluginInfo, host) {
|
||||
let pluginLoadStarted = Date.now();
|
||||
let InstancePluginClass = await libPluginLoader.loadInstancePluginClass(pluginInfo);
|
||||
let InstancePluginClass = await lib.loadInstancePluginClass(pluginInfo);
|
||||
let instancePlugin = new InstancePluginClass(pluginInfo, this, host);
|
||||
this.plugins.set(pluginInfo.name, instancePlugin);
|
||||
await instancePlugin.init();
|
||||
@@ -516,7 +511,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
players: [...this.playerStats],
|
||||
player_autosave_slot: this._playerAutosaveSlot,
|
||||
}, null, 4);
|
||||
await libFileOps.safeOutputFile(this.path("instance-stats.json"), content);
|
||||
await lib.safeOutputFile(this.path("instance-stats.json"), content);
|
||||
}
|
||||
|
||||
async init(pluginInfos) {
|
||||
@@ -553,7 +548,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
for (let [name, plugin] of this.plugins) {
|
||||
plugins[name] = plugin.info.version;
|
||||
}
|
||||
this.send(new libData.InstanceInitialisedEvent(plugins));
|
||||
this.send(new lib.InstanceInitialisedEvent(plugins));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -588,7 +583,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
*/
|
||||
async writeServerSettings() {
|
||||
let serverSettings = await this.resolveServerSettings(this.config.get("factorio.settings"));
|
||||
await libFileOps.safeOutputFile(
|
||||
await lib.safeOutputFile(
|
||||
this.server.writePath("server-settings.json"),
|
||||
JSON.stringify(serverSettings, null, 4)
|
||||
);
|
||||
@@ -625,9 +620,9 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
const modPackId = this.config.get("factorio.mod_pack");
|
||||
let modPack;
|
||||
if (modPackId === null) {
|
||||
modPack = await this.sendTo("controller", new libData.ModPackGetDefaultRequest());
|
||||
modPack = await this.sendTo("controller", new lib.ModPackGetDefaultRequest());
|
||||
} else {
|
||||
modPack = await this.sendTo("controller", new libData.ModPackGetRequest(modPackId));
|
||||
modPack = await this.sendTo("controller", new lib.ModPackGetRequest(modPackId));
|
||||
}
|
||||
this.activeModPack = modPack;
|
||||
|
||||
@@ -691,7 +686,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
if (this.config.get("factorio.sync_adminlist")) {
|
||||
this.logger.verbose("Writing server-adminlist.json");
|
||||
libFileOps.safeOutputFile(
|
||||
lib.safeOutputFile(
|
||||
this.server.writePath("server-adminlist.json"),
|
||||
JSON.stringify([...this._host.adminlist], null, 4)
|
||||
);
|
||||
@@ -699,7 +694,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
if (this.config.get("factorio.sync_banlist")) {
|
||||
this.logger.verbose("Writing server-banlist.json");
|
||||
libFileOps.safeOutputFile(
|
||||
lib.safeOutputFile(
|
||||
this.server.writePath("server-banlist.json"),
|
||||
JSON.stringify([...this._host.banlist].map(
|
||||
([username, reason]) => ({ username, reason })
|
||||
@@ -709,7 +704,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
if (this.config.get("factorio.sync_whitelist")) {
|
||||
this.logger.verbose("Writing server-whitelist.json");
|
||||
libFileOps.safeOutputFile(
|
||||
lib.safeOutputFile(
|
||||
this.server.writePath("server-whitelist.json"),
|
||||
JSON.stringify([...this._host.whitelist], null, 4)
|
||||
);
|
||||
@@ -731,7 +726,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
async prepareSave(saveName) {
|
||||
// Use latest save if no save was specified
|
||||
if (saveName === undefined) {
|
||||
saveName = await libFileOps.getNewestFile(
|
||||
saveName = await lib.getNewestFile(
|
||||
this.path("saves"), (name) => !name.endsWith(".tmp.zip")
|
||||
);
|
||||
}
|
||||
@@ -832,7 +827,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
}
|
||||
}
|
||||
|
||||
await libFactorio.patch(this.path("saves", saveName), [...modules.values()]);
|
||||
await patch(this.path("saves", saveName), [...modules.values()]);
|
||||
return saveName;
|
||||
}
|
||||
|
||||
@@ -860,7 +855,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
}
|
||||
|
||||
await this.sendSaveListUpdate();
|
||||
await libPlugin.invokeHook(this.plugins, "onStart");
|
||||
await lib.invokeHook(this.plugins, "onStart");
|
||||
|
||||
this.notifyStatus("running");
|
||||
}
|
||||
@@ -885,7 +880,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
await this.server.startScenario(scenario, seed, mapGenSettings, mapSettings);
|
||||
this._watchPlayerJoinsByChat();
|
||||
|
||||
await libPlugin.invokeHook(this.plugins, "onStart");
|
||||
await lib.invokeHook(this.plugins, "onStart");
|
||||
|
||||
this.notifyStatus("running");
|
||||
}
|
||||
@@ -894,7 +889,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
* Update instance information on the Factorio side
|
||||
*/
|
||||
async updateInstanceData() {
|
||||
let name = libLuaTools.escapeString(this.name);
|
||||
let name = lib.escapeString(this.name);
|
||||
await this.sendRcon(`/sc clusterio_private.update_instance(${this.id}, "${name}")`, true);
|
||||
}
|
||||
|
||||
@@ -973,7 +968,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
|
||||
// XXX this needs more thought to it
|
||||
if (this.server._state === "running") {
|
||||
await libPlugin.invokeHook(this.plugins, "onStop");
|
||||
await lib.invokeHook(this.plugins, "onStop");
|
||||
await this.server.stop();
|
||||
await this.sendSaveListUpdate();
|
||||
}
|
||||
@@ -987,20 +982,20 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
}
|
||||
|
||||
async handleControllerConnectionEvent(event) {
|
||||
await libPlugin.invokeHook(this.plugins, "onControllerConnectionEvent", event.event);
|
||||
await lib.invokeHook(this.plugins, "onControllerConnectionEvent", event.event);
|
||||
}
|
||||
|
||||
async handlePrepareControllerDisconnectRequest() {
|
||||
await libPlugin.invokeHook(this.plugins, "onPrepareControllerDisconnect");
|
||||
await lib.invokeHook(this.plugins, "onPrepareControllerDisconnect");
|
||||
}
|
||||
|
||||
async handleInstanceMetricsRequest() {
|
||||
let results = [];
|
||||
if (!["stopped", "stopping"].includes(this._status)) {
|
||||
let pluginResults = await libPlugin.invokeHook(this.plugins, "onMetrics");
|
||||
let pluginResults = await lib.invokeHook(this.plugins, "onMetrics");
|
||||
for (let metricIterator of pluginResults) {
|
||||
for await (let metric of metricIterator) {
|
||||
results.push(libPrometheus.serializeResult(metric));
|
||||
results.push(lib.serializeResult(metric));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1012,7 +1007,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
instanceFactorioMemoryUsage.labels(String(this.id)).set(stats.memory);
|
||||
}
|
||||
|
||||
return new libData.InstanceMetricsRequest.Response(results);
|
||||
return new lib.InstanceMetricsRequest.Response(results);
|
||||
}
|
||||
|
||||
async handleInstanceStartRequest(request) {
|
||||
@@ -1037,7 +1032,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
async handleInstanceLoadScenarioRequest(request) {
|
||||
if (this.config.get("factorio.enable_save_patching")) {
|
||||
this.notifyExit();
|
||||
throw new libErrors.RequestError("Load scenario cannot be used with save patching enabled");
|
||||
throw new lib.RequestError("Load scenario cannot be used with save patching enabled");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -1091,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 libFactorio.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"));
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
"use strict";
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
|
||||
class InstanceConnection extends libLink.Link {
|
||||
class InstanceConnection extends lib.Link {
|
||||
constructor(connector, host, instanceId) {
|
||||
super(connector);
|
||||
this.host = host;
|
||||
@@ -14,8 +11,8 @@ class InstanceConnection extends libLink.Link {
|
||||
this.plugins = new Map();
|
||||
this.status = "stopped";
|
||||
|
||||
this.handle(libData.InstanceInitialisedEvent, this.handleInstanceInitialisedEvent.bind(this));
|
||||
this.snoopEvent(libData.InstanceStatusChangedEvent, this.snoopInstanceStatusChangedEvent.bind(this));
|
||||
this.handle(lib.InstanceInitialisedEvent, this.handleInstanceInitialisedEvent.bind(this));
|
||||
this.snoopEvent(lib.InstanceStatusChangedEvent, this.snoopInstanceStatusChangedEvent.bind(this));
|
||||
}
|
||||
|
||||
async broadcastEventToInstance(message, event) {
|
||||
|
||||
@@ -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,9 +15,9 @@ 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/factorio.FactorioServer} server -
|
||||
* @param {module:host/src/server.FactorioServer} server -
|
||||
* The server to generate the export mod for.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
*/
|
||||
async function generateExportMod(server) {
|
||||
let dependencies = [];
|
||||
@@ -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,18 +55,18 @@ 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/factorio.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.
|
||||
* @returns {Promise<?Buffer>} The content of the file or null if not found.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -250,14 +248,14 @@ 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/factorio.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.
|
||||
* @param {Array<Object>} items - Array of item prototypes.
|
||||
* @return {Promise<{itemSheet: Jimp, itemData: Map<string,Object>}>}
|
||||
* Item spritesheet and metadata.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -321,14 +319,14 @@ 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/factorio.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.
|
||||
* @param {Array<string>} modOrder - Load order of the mods.
|
||||
* @param {string} languageCode - Language to export locale for.
|
||||
* @returns {Promise<Map<string, string>>} merged locale information
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -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,10 +375,10 @@ async function exportLocale(server, modVersions, modOrder, languageCode) {
|
||||
/**
|
||||
* Export the locale and item icons for the given factorio server
|
||||
*
|
||||
* @param {module:lib/factorio.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/factorio
|
||||
* @memberof module:lib
|
||||
*/
|
||||
async function exportData(server) {
|
||||
await generateExportMod(server);
|
||||
@@ -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 = {
|
||||
@@ -27,7 +26,7 @@ const knownScenarios = {
|
||||
*
|
||||
* @param {Object} patchInfo - The patch info files's json content
|
||||
* @returns {string} Generated control.lua code.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -77,7 +76,7 @@ function generateLoader(patchInfo) {
|
||||
* their dependents. Throws an error if this is not possible.
|
||||
*
|
||||
* @param {Array<Object>} modules - Array of modules to reorder
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -175,11 +174,11 @@ function reorderDependencies(modules) {
|
||||
*
|
||||
* @param {string} savePath - Path to the Factorio save to patch.
|
||||
* @param {Array<Object>} modules - Description of the modules to patch.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
*/
|
||||
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");
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,7 +16,7 @@ const { LineSplitter } = require("../stream");
|
||||
* reading the changelog.txt in it.
|
||||
*
|
||||
* @param {string} changelogPath - Path to changelog.txt.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -55,7 +50,7 @@ async function getVersion(changelogPath) {
|
||||
* @param {string} a - Version to compare.
|
||||
* @param {string} b - Version to compare.
|
||||
* @returns {number} 1 if a < b, 0 if a = b and -1 if a > b.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -87,7 +82,7 @@ function versionOrder(a, b) {
|
||||
* Version to look for, supports the special value "latest" for the
|
||||
* latest version available.
|
||||
* @returns {Promise<Array>} Array with path to data dir and version found.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -145,7 +140,7 @@ async function findVersion(factorioDir, targetVersion) {
|
||||
* RFC 6335.
|
||||
*
|
||||
* @return {number} a number in the range 49152 to 65535.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -164,7 +159,7 @@ function randomDynamicPort() {
|
||||
*
|
||||
* @param {number} length - the length of the password to generate.
|
||||
* @return {Promise<string>} password of the given length
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -207,7 +202,7 @@ async function generatePassword(length) {
|
||||
* @param {string} source - Passed into the output structure as source
|
||||
*
|
||||
* @returns {object} - An object with interpeted data.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -412,7 +407,7 @@ const outputHeuristics = [
|
||||
* - save-finished - invoked when the server has finished a manual save
|
||||
* - exit - invoked when the sterver has exited
|
||||
* @extends events.EventEmitter
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class FactorioServer extends events.EventEmitter {
|
||||
/**
|
||||
@@ -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)
|
||||
);
|
||||
}
|
||||
+14
-12
@@ -1,13 +1,15 @@
|
||||
export { default as libConfig } from "./config";
|
||||
export { default as libData } from "./data";
|
||||
export { default as libErrors } from "./errors";
|
||||
export { default as libFactorio } from "./factorio/exchange_string";
|
||||
export { default as libHelpers } from "./helpers";
|
||||
export { default as libLink } from "./link";
|
||||
export { default as libLogging } from "./logging";
|
||||
export { default as libPlugin } from "./plugin";
|
||||
export { default as libSchema } from "./schema";
|
||||
export { default as libUsers } from "./users";
|
||||
export * from "./src/config";
|
||||
export * from "./src/data";
|
||||
export * from "./src/errors";
|
||||
export * from "./src/factorio/exchange_string";
|
||||
export * from "./src/helpers";
|
||||
export * from "./src/ini";
|
||||
export * from "./src/link";
|
||||
export * from "./src/logging";
|
||||
export * from "./src/plugin";
|
||||
export * from "./src/schema";
|
||||
export * from "./src/users";
|
||||
|
||||
export { default as ExponentialBackoff } from "./ExponentialBackoff";
|
||||
export { default as RateLimiter } from "./RateLimiter";
|
||||
export { default as ExponentialBackoff } from "./src/ExponentialBackoff";
|
||||
export { default as PlayerStats } from "./src/PlayerStats";
|
||||
export { default as RateLimiter } from "./src/RateLimiter";
|
||||
+53
-43
@@ -1,53 +1,63 @@
|
||||
/**
|
||||
* Shared library for Clusterio
|
||||
* @module lib
|
||||
*/
|
||||
"use strict";
|
||||
const libBuildMod = require("./build_mod");
|
||||
const libCommand = require("./command");
|
||||
const libConfig = require("./config");
|
||||
const libData = require("./data");
|
||||
const libDatabase = require("./database");
|
||||
const libErrors = require("./errors");
|
||||
const libFactorio = require("./factorio");
|
||||
const libFileOps = require("./file_ops");
|
||||
const libHash = require("./hash");
|
||||
const libHelpers = require("./helpers");
|
||||
const libLink = require("./link");
|
||||
const libLogging = require("./logging");
|
||||
const libLoggingUtils = require("./logging_utils");
|
||||
const libLuaTools = require("./lua_tools");
|
||||
const libPlugin = require("./plugin");
|
||||
const libPluginLoader = require("./plugin_loader");
|
||||
const libPrometheus = require("./prometheus");
|
||||
const libSchema = require("./schema");
|
||||
const libSharedCommands = require("./shared_commands");
|
||||
const libUsers = require("./users");
|
||||
const libZipOps = require("./zip_ops");
|
||||
const libCommand = require("./src/command");
|
||||
const libConfig = require("./src/config");
|
||||
const libData = require("./src/data");
|
||||
const libDatabase = require("./src/database");
|
||||
const libErrors = require("./src/errors");
|
||||
const libFactorio = require("./src/factorio");
|
||||
const libFileOps = require("./src/file_ops");
|
||||
const libHash = require("./src/hash");
|
||||
const libHelpers = require("./src/helpers");
|
||||
const libIni = require("./src/ini");
|
||||
const libLink = require("./src/link");
|
||||
const libLogging = require("./src/logging");
|
||||
const libLoggingUtils = require("./src/logging_utils");
|
||||
const libLuaTools = require("./src/lua_tools");
|
||||
const libPlugin = require("./src/plugin");
|
||||
const libPluginLoader = require("./src/plugin_loader");
|
||||
const libPrometheus = require("./src/prometheus");
|
||||
const libSchema = require("./src/schema");
|
||||
const libSharedCommands = require("./src/shared_commands");
|
||||
const libStream = require("./src/stream");
|
||||
const libUsers = require("./src/users");
|
||||
const libZipOps = require("./src/zip_ops");
|
||||
|
||||
const ExponentialBackoff = require("./ExponentialBackoff");
|
||||
const RateLimiter = require("./RateLimiter");
|
||||
const ExponentialBackoff = require("./src/ExponentialBackoff");
|
||||
const PlayerStats = require("./src/PlayerStats");
|
||||
const RateLimiter = require("./src/RateLimiter");
|
||||
|
||||
|
||||
module.exports = {
|
||||
libBuildMod,
|
||||
libCommand,
|
||||
libConfig,
|
||||
libData,
|
||||
libDatabase,
|
||||
libErrors,
|
||||
libFactorio,
|
||||
libFileOps,
|
||||
libHash,
|
||||
libHelpers,
|
||||
libLink,
|
||||
libLogging,
|
||||
libLoggingUtils,
|
||||
libLuaTools,
|
||||
libPlugin,
|
||||
libPluginLoader,
|
||||
libPrometheus,
|
||||
libSchema,
|
||||
libSharedCommands,
|
||||
libUsers,
|
||||
libZipOps,
|
||||
...libBuildMod,
|
||||
...libCommand,
|
||||
...libConfig,
|
||||
...libData,
|
||||
...libDatabase,
|
||||
...libErrors,
|
||||
...libFactorio,
|
||||
...libFileOps,
|
||||
...libHash,
|
||||
...libHelpers,
|
||||
...libIni,
|
||||
...libLink,
|
||||
...libLogging,
|
||||
...libLoggingUtils,
|
||||
...libLuaTools,
|
||||
...libPlugin,
|
||||
...libPluginLoader,
|
||||
...libPrometheus,
|
||||
...libSchema,
|
||||
...libSharedCommands,
|
||||
...libStream,
|
||||
...libUsers,
|
||||
...libZipOps,
|
||||
|
||||
ExponentialBackoff,
|
||||
PlayerStats,
|
||||
RateLimiter,
|
||||
};
|
||||
@@ -16,12 +16,8 @@
|
||||
"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",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* `base` if more time than the value for `reset` has passed between two
|
||||
* invocations of delay.
|
||||
*
|
||||
* @alias module:lib/ExponentialBackoff
|
||||
* @alias module:lib.ExponentialBackoff
|
||||
*/
|
||||
class ExponentialBackoff {
|
||||
/**
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* Stastics collected about a player.
|
||||
* @alias module:lib/PlayerStats
|
||||
* @alias module:lib.PlayerStats
|
||||
*/
|
||||
class PlayerStats {
|
||||
/**
|
||||
@@ -19,7 +19,7 @@
|
||||
* // and one more time 1 second later for 99 other activations that were
|
||||
* // exceeding the rate limit.
|
||||
* }
|
||||
* @alias module:lib/RateLimiter
|
||||
* @alias module:lib.RateLimiter
|
||||
*/
|
||||
class RateLimiter {
|
||||
/**
|
||||
@@ -52,10 +52,10 @@ class Command {
|
||||
/**
|
||||
* A node in the command tree that can hold commands and sub trees
|
||||
*
|
||||
* Container which can contain {@link module:lib/command.Command}s and other
|
||||
* Container which can contain {@link module:lib.Command}s and other
|
||||
* CommandTrees. This is used by clusterioctl to hold the full tree of
|
||||
* available commands, you may extend this tree by using a control plugin,
|
||||
* see {@link module:lib/plugin.BaseControlPlugin#addCommands}
|
||||
* see {@link module:lib.BaseControlPlugin#addCommands}
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
@@ -83,7 +83,7 @@ class CommandTree {
|
||||
/**
|
||||
* Add a command or command tree to this tree
|
||||
*
|
||||
* @param {module:lib/command.Command|module:lib/command.CommandTree} command -
|
||||
* @param {module:lib.Command|module:lib.CommandTree} command -
|
||||
* The command to add to this command tree.
|
||||
*/
|
||||
add(command) {
|
||||
@@ -104,7 +104,7 @@ class CommandTree {
|
||||
*
|
||||
* @param {string} name -
|
||||
* The name of the command or command tree to retrieve.
|
||||
* @return {?module:lib/command.Command|module:lib/command.CommandTree}
|
||||
* @return {?module:lib.Command|module:lib.CommandTree}
|
||||
* The command to add to this command tree.
|
||||
*/
|
||||
get(name) {
|
||||
@@ -141,7 +141,7 @@ class CommandTree {
|
||||
* Resolves a string with either an host name or an id into an integer with
|
||||
* the host ID.
|
||||
*
|
||||
* @param {module:lib/link.Link} client - link to controller to query host on.
|
||||
* @param {module:lib.Link} client - link to controller to query host on.
|
||||
* @param {string} hostName - string with name or id of host.
|
||||
* @returns {Promise<number>} host ID.
|
||||
* @static
|
||||
@@ -173,7 +173,7 @@ async function resolveHost(client, hostName) {
|
||||
* Resolves a string with either an instance name or an id into an integer
|
||||
* with the instance ID.
|
||||
*
|
||||
* @param {module:lib/link.Link} client - link to controller to query instance on.
|
||||
* @param {module:lib.Link} client - link to controller to query instance on.
|
||||
* @param {string} instanceName - string with name or id of instance.
|
||||
* @returns {Promise<number>} instance ID.
|
||||
* @static
|
||||
@@ -205,7 +205,7 @@ async function resolveInstance(client, instanceName) {
|
||||
* Resolevs a string with either a mod pack name or an id into an integer
|
||||
* with the mod pack ID.
|
||||
*
|
||||
* @param {module:lib/link.Link} client -
|
||||
* @param {module:lib.Link} client -
|
||||
* link to controller to query mod pack on.
|
||||
* @param {string} modPackName - string with name or id of mod pack.
|
||||
* @returns {Promise<number>} mod pack ID.
|
||||
@@ -238,7 +238,7 @@ async function resolveModPack(client, modPackName) {
|
||||
* Resolves a string with either a role name or an id into an object
|
||||
* representing the role.
|
||||
*
|
||||
* @param {module:lib/link.Link} client - link to controller to query role on.
|
||||
* @param {module:lib.Link} client - link to controller to query role on.
|
||||
* @param {string} roleName - string with name or id of role.
|
||||
* @returns {Promise<object>} Role info.
|
||||
* @static
|
||||
@@ -14,7 +14,7 @@ const { basicType } = require("../helpers");
|
||||
* does not permitt this access is done.
|
||||
*
|
||||
* @extends Error
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class InvalidAccess extends Error { };
|
||||
|
||||
@@ -25,7 +25,7 @@ class InvalidAccess extends Error { };
|
||||
* field.
|
||||
*
|
||||
* @extends Error
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class InvalidValue extends Error { };
|
||||
|
||||
@@ -36,7 +36,7 @@ class InvalidValue extends Error { };
|
||||
* attempted to be accessed.
|
||||
*
|
||||
* @extends Error
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class InvalidField extends Error { };
|
||||
|
||||
@@ -51,7 +51,7 @@ class InvalidField extends Error { };
|
||||
* @param {string} separator - Separator to split string by.
|
||||
* @param {string} string - String to split
|
||||
* @returns {Array} string split on separator.
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -77,7 +77,7 @@ function splitOn(separator, string) {
|
||||
*
|
||||
* @extends events.EventEmitter
|
||||
*
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class Config extends events.EventEmitter {
|
||||
/**
|
||||
@@ -236,7 +236,7 @@ class Config extends events.EventEmitter {
|
||||
* Get the config group instance with the given name
|
||||
*
|
||||
* @param {string} name - Name of group to get.
|
||||
* @returns {module:lib/config.ConfigGroup} config group.
|
||||
* @returns {module:lib.ConfigGroup} config group.
|
||||
*/
|
||||
group(name) {
|
||||
if (!this._initialized) {
|
||||
@@ -287,7 +287,7 @@ class Config extends events.EventEmitter {
|
||||
* Adds the ConfigGroup to this config as a group that will get
|
||||
* initialized, loaded and serialized with this config class.
|
||||
*
|
||||
* @param {module:lib/config.ConfigGroup} group - class to register.
|
||||
* @param {module:lib.ConfigGroup} group - class to register.
|
||||
*/
|
||||
static registerGroup(group) {
|
||||
this._initSubclass();
|
||||
@@ -317,7 +317,7 @@ class Config extends events.EventEmitter {
|
||||
* loading a config with invalid values will result in those being replaced
|
||||
* by the innitial value for those fields.
|
||||
*
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ConfigGroup {
|
||||
/**
|
||||
@@ -326,7 +326,7 @@ class ConfigGroup {
|
||||
* After the creation of the new config group you have to call
|
||||
* either .init() or .load() on it in order to fully initialize it.
|
||||
*
|
||||
* @param {module:lib/config.Config} config -
|
||||
* @param {module:lib.Config} config -
|
||||
* Parent config for this group instance.
|
||||
*/
|
||||
constructor(config) {
|
||||
@@ -345,7 +345,7 @@ class ConfigGroup {
|
||||
* @param {object} def - definition for for the field to check.
|
||||
* @param {string} remote - location of remote access to check for.
|
||||
* @param {boolean} error - throw on failure to pass check.
|
||||
* @throws {module:lib/config.InvalidAccess}
|
||||
* @throws {module:lib.InvalidAccess}
|
||||
* if access is not granted and error is true.
|
||||
* @returns {boolean} true if access is granted
|
||||
* @private
|
||||
@@ -456,8 +456,8 @@ class ConfigGroup {
|
||||
* @param {string} name - Name of field to set.
|
||||
* @param {*} value - Value to set for field.
|
||||
* @param {string=} location - Location used for access control.
|
||||
* @throws {module:lib/config.InvalidField} if field is not defined.
|
||||
* @throws {module:lib/config.InvalidValue} if value is not allowed for the field.
|
||||
* @throws {module:lib.InvalidField} if field is not defined.
|
||||
* @throws {module:lib.InvalidValue} if value is not allowed for the field.
|
||||
*/
|
||||
set(name, value, location = this.config.location) {
|
||||
let def = this.constructor._definitions.get(name);
|
||||
@@ -524,8 +524,8 @@ class ConfigGroup {
|
||||
* @param {string} prop - Name of property to set on field.
|
||||
* @param {*} value - the value to set the property to.
|
||||
* @param {string=} location - Location used for access control.
|
||||
* @throws {module:lib/config.InvalidField} if field is not defined.
|
||||
* @throws {module:lib/config.InvalidValue} if field is not an object.
|
||||
* @throws {module:lib.InvalidField} if field is not defined.
|
||||
* @throws {module:lib.InvalidValue} if field is not an object.
|
||||
*/
|
||||
setProp(name, prop, value, location = this.config.location) {
|
||||
let def = this.constructor._definitions.get(name);
|
||||
@@ -829,8 +829,8 @@ class ConfigGroup {
|
||||
* plugins. This is currently only the enabled field. It is otherwise
|
||||
* identical to the ConfigGroup class.
|
||||
*
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class PluginConfigGroup extends ConfigGroup {
|
||||
static _initSubclass() {
|
||||
@@ -5,9 +5,9 @@ const classes = require("./classes");
|
||||
|
||||
|
||||
/**
|
||||
* Controller config group for {@link module:lib/config.ControllerConfig}
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* Controller config group for {@link module:lib.ControllerConfig}
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ControllerGroup extends classes.ConfigGroup { }
|
||||
ControllerGroup.defaultAccess = ["controller", "host", "control"];
|
||||
@@ -140,17 +140,17 @@ ControllerGroup.finalize();
|
||||
|
||||
/**
|
||||
* Controller Config class
|
||||
* @extends module:lib/config.Config
|
||||
* @memberof module:lib/config
|
||||
* @extends module:lib.Config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ControllerConfig extends classes.Config { }
|
||||
ControllerConfig.registerGroup(ControllerGroup);
|
||||
|
||||
|
||||
/**
|
||||
* Host config group for {@link module:lib/config.HostConfig}
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* Host config group for {@link module:lib.HostConfig}
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class HostGroup extends classes.ConfigGroup {}
|
||||
HostGroup.defaultAccess = ["controller", "host", "control"];
|
||||
@@ -232,17 +232,17 @@ HostGroup.finalize();
|
||||
|
||||
/**
|
||||
* Host Config class
|
||||
* @extends module:lib/config.Config
|
||||
* @memberof module:lib/config
|
||||
* @extends module:lib.Config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class HostConfig extends classes.Config { }
|
||||
HostConfig.registerGroup(HostGroup);
|
||||
|
||||
|
||||
/**
|
||||
* Instance config group for {@link module:lib/config.InstanceConfig}
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* Instance config group for {@link module:lib.InstanceConfig}
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class InstanceGroup extends classes.ConfigGroup { }
|
||||
InstanceGroup.defaultAccess = ["controller", "host", "control"];
|
||||
@@ -272,9 +272,9 @@ InstanceGroup.define({
|
||||
InstanceGroup.finalize();
|
||||
|
||||
/**
|
||||
* Factorio config group for {@link module:lib/config.InstanceConfig}
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* Factorio config group for {@link module:lib.InstanceConfig}
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class FactorioGroup extends classes.ConfigGroup { }
|
||||
FactorioGroup.defaultAccess = ["controller", "host", "control"];
|
||||
@@ -398,8 +398,8 @@ FactorioGroup.finalize();
|
||||
|
||||
/**
|
||||
* Instance config class
|
||||
* @extends module:lib/config.Config
|
||||
* @memberof module:lib/config
|
||||
* @extends module:lib.Config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class InstanceConfig extends classes.Config { }
|
||||
InstanceConfig.registerGroup(InstanceGroup);
|
||||
@@ -407,9 +407,9 @@ InstanceConfig.registerGroup(FactorioGroup);
|
||||
|
||||
|
||||
/**
|
||||
* Control config group for {@link module:lib/config.ControlConfig}
|
||||
* @extends module:lib/config.ConfigGroup
|
||||
* @memberof module:lib/config
|
||||
* Control config group for {@link module:lib.ControlConfig}
|
||||
* @extends module:lib.ConfigGroup
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ControlGroup extends classes.ConfigGroup {}
|
||||
ControlGroup.defaultAccess = ["control"];
|
||||
@@ -443,8 +443,8 @@ ControlGroup.finalize();
|
||||
|
||||
/**
|
||||
* Control config class
|
||||
* @extends module:lib/config.Config
|
||||
* @memberof module:lib/config
|
||||
* @extends module:lib.Config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ControlConfig extends classes.Config { }
|
||||
ControlConfig.registerGroup(ControlGroup);
|
||||
@@ -468,7 +468,7 @@ function validateGroup(pluginInfo, groupName) {
|
||||
* Registers the config groups for the provided plugin infos
|
||||
*
|
||||
* @param {Array<Object>} pluginInfos - Array of plugin info objects.
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
function registerPluginConfigGroups(pluginInfos) {
|
||||
for (let pluginInfo of pluginInfos) {
|
||||
@@ -503,7 +503,7 @@ function registerPluginConfigGroups(pluginInfos) {
|
||||
/**
|
||||
* Lock configs from adding more groups and make them usable
|
||||
*
|
||||
* @memberof module:lib/config
|
||||
* @memberof module:lib
|
||||
*/
|
||||
function finalizeConfigs() {
|
||||
ControllerConfig.finalize();
|
||||
File renamed without changes.
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Tracks files stored on disk for data that extracted from Factorio using a
|
||||
* given mod pack.
|
||||
* @alias module:lib/data.ExportManifest
|
||||
* @alias module:lib.ExportManifest
|
||||
*/
|
||||
class ExportManifest {
|
||||
|
||||
@@ -15,7 +15,7 @@ const { integerModVersion, integerFactorioVersion, modVersionRegExp } = require(
|
||||
*
|
||||
* See https://wiki.factorio.com/Tutorial:Mod_structure#info.json for
|
||||
* details of the invidiual fields sourced from info.json.
|
||||
* @alias module:lib/data.ModInfo
|
||||
* @alias module:lib.ModInfo
|
||||
*/
|
||||
class ModInfo {
|
||||
/**
|
||||
@@ -9,7 +9,7 @@ const { integerFactorioVersion } = require("./version");
|
||||
|
||||
/**
|
||||
* A setting for a mod.
|
||||
* @typedef {object} module:lib/data.ModPack~ModSetting
|
||||
* @typedef {object} module:lib.ModPack~ModSetting
|
||||
* @property {boolean|number|string} value - Value of the given mod setting.
|
||||
*/
|
||||
const ModSettingJsonSchema = {
|
||||
@@ -28,7 +28,7 @@ const ModSettingsJsonSchema = {
|
||||
|
||||
/**
|
||||
* A mod in a mod pack
|
||||
* @typedef {object} module:lib/data.ModPack~ModRecord
|
||||
* @typedef {object} module:lib.ModPack~ModRecord
|
||||
* @property {string} name - name of the mod.
|
||||
* @property {boolean} enabled - if mod is to be loaded.
|
||||
* @property {string} version - version of the mod.
|
||||
@@ -49,7 +49,7 @@ const ModRecordJsonSchema = {
|
||||
* Factorio Mod Pack
|
||||
*
|
||||
* Tracks mods and settings for a collection of Factorio mods.
|
||||
* @alias module:lib/data.ModPack
|
||||
* @alias module:lib.ModPack
|
||||
*/
|
||||
class ModPack {
|
||||
/**
|
||||
@@ -86,13 +86,13 @@ class ModPack {
|
||||
|
||||
/**
|
||||
* Mods included in this mod pack
|
||||
* @type {Map<string, module:lib/data.ModPack~ModRecord>}
|
||||
* @type {Map<string, module:lib.ModPack~ModRecord>}
|
||||
*/
|
||||
mods = new Map();
|
||||
|
||||
/**
|
||||
* Mod settings for this mod pack
|
||||
* @type {Object<string, Map<string, module:lib/data.ModPack~ModSetting>>=}
|
||||
* @type {Object<string, Map<string, module:lib.ModPack~ModSetting>>=}
|
||||
*/
|
||||
settings = {
|
||||
"startup": new Map(),
|
||||
@@ -102,7 +102,7 @@ class ModPack {
|
||||
|
||||
/**
|
||||
* Mapping to files containing exported data for this modpack
|
||||
* @type {module:lib/data.ExportManifest|undefined}
|
||||
* @type {module:lib.ExportManifest|undefined}
|
||||
*/
|
||||
exportManifest;
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+11
-11
@@ -2,7 +2,7 @@
|
||||
const { JsonString } = require("./composites");
|
||||
|
||||
// TODO: remove after config refactor
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class RawConfig {
|
||||
/** @type {object} */
|
||||
serializedConfig;
|
||||
@@ -24,7 +24,7 @@ class RawConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ControllerConfigGetRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -33,7 +33,7 @@ class ControllerConfigGetRequest {
|
||||
static Response = RawConfig;
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ControllerConfigSetFieldRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -64,7 +64,7 @@ class ControllerConfigSetFieldRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ControllerConfigSetPropRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -99,7 +99,7 @@ class ControllerConfigSetPropRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class HostGenerateTokenRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -128,7 +128,7 @@ class HostGenerateTokenRequest {
|
||||
static Response = JsonString;
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class HostConfigCreateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -165,7 +165,7 @@ class HostConfigCreateRequest {
|
||||
static Response = RawConfig;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class LogSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -214,7 +214,7 @@ class LogSetSubscriptionsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class LogQueryRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -298,7 +298,7 @@ LogQueryRequest.Response = class Response {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class LogMessageEvent {
|
||||
static type = "event";
|
||||
static src = ["host", "controller"];
|
||||
@@ -331,7 +331,7 @@ class LogMessageEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class DebugDumpWsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -339,7 +339,7 @@ class DebugDumpWsRequest {
|
||||
static permission = "core.debug.dump_ws";
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class DebugWsMessageEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
@@ -2,7 +2,7 @@
|
||||
const libSchema = require("../schema");
|
||||
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class Address {
|
||||
/** Controller address */
|
||||
static controller = 0;
|
||||
@@ -44,9 +44,9 @@ class Address {
|
||||
* `"allHosts"`: new Address(Address.broadcast, Address.host)
|
||||
* `"allInstances"`: new Address(Address.broadcast, Address.instance)
|
||||
* `"allControls"`: new Address(Address.broadcast, Address.control)
|
||||
* @param {module:lib/data.Address|string|object} shorthand -
|
||||
* @param {module:lib.Address|string|object} shorthand -
|
||||
* Shorthand to translate with.
|
||||
* @returns {module:lib/data.Address} Translated address.
|
||||
* @returns {module:lib.Address} Translated address.
|
||||
*/
|
||||
static fromShorthand(shorthand) {
|
||||
if (shorthand instanceof Address) { return shorthand; }
|
||||
@@ -107,7 +107,7 @@ class Address {
|
||||
|
||||
/**
|
||||
* Returns true if this address targets the given destination
|
||||
* @param {module:lib/Data.Address} dst - Destination to check
|
||||
* @param {module:lib.Address} dst - Destination to check
|
||||
* @returns {boolean} true if this address is addressed to the given destination
|
||||
*/
|
||||
addressedTo(dst) {
|
||||
@@ -129,7 +129,7 @@ class Address {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class Message {
|
||||
/** @type {string} */
|
||||
type;
|
||||
@@ -161,7 +161,7 @@ class Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class HelloData {
|
||||
/** @type {string} */
|
||||
version;
|
||||
@@ -190,9 +190,9 @@ class HelloData {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageHello extends Message {
|
||||
/** @type {module:lib/data.HelloData} */
|
||||
/** @type {module:lib.HelloData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -214,7 +214,7 @@ class MessageHello extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class RegisterHostData {
|
||||
/** @type {string} */
|
||||
token;
|
||||
@@ -263,9 +263,9 @@ class RegisterHostData {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageRegisterHost extends Message {
|
||||
/** @type {module:lib/data.RegisterHostData} */
|
||||
/** @type {module:lib.RegisterHostData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -287,7 +287,7 @@ class MessageRegisterHost extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class RegisterControlData {
|
||||
/** @type {string} */
|
||||
token;
|
||||
@@ -317,9 +317,9 @@ class RegisterControlData {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageRegisterControl extends Message {
|
||||
/** @type {module:lib/data.RegisterControlData} */
|
||||
/** @type {module:lib.RegisterControlData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -341,7 +341,7 @@ class MessageRegisterControl extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class AccountDetails {
|
||||
/** @type {string} */
|
||||
name;
|
||||
@@ -381,9 +381,9 @@ class AccountDetails {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ReadyData {
|
||||
/** @type {module:lib/data.Address} */
|
||||
/** @type {module:lib.Address} */
|
||||
src;
|
||||
/** @type {string} */
|
||||
sessionToken;
|
||||
@@ -427,9 +427,9 @@ class ReadyData {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageReady extends Message {
|
||||
/** @type {module:lib/data.ReadyData} */
|
||||
/** @type {module:lib.ReadyData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -451,7 +451,7 @@ class MessageReady extends Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ResumeData {
|
||||
/** @type {string} */
|
||||
sessionToken;
|
||||
@@ -478,9 +478,9 @@ class ResumeData {
|
||||
}
|
||||
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageResume extends Message {
|
||||
/** @type {module:lib/data.ResumeData} */
|
||||
/** @type {module:lib.ResumeData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -502,7 +502,7 @@ class MessageResume extends Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ContinueData {
|
||||
/** @type {number} */
|
||||
sessionTimeout;
|
||||
@@ -532,9 +532,9 @@ class ContinueData {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageContinue extends Message {
|
||||
/** @type {module:lib/data.ContinueData} */
|
||||
/** @type {module:lib.ContinueData} */
|
||||
data;
|
||||
|
||||
constructor(data) {
|
||||
@@ -556,7 +556,7 @@ class MessageContinue extends Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageInvalidate extends Message {
|
||||
constructor() {
|
||||
super("invalidate");
|
||||
@@ -574,7 +574,7 @@ class MessageInvalidate extends Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageHeartbeat extends Message {
|
||||
/** @type {integer|undefined} */
|
||||
seq;
|
||||
@@ -598,7 +598,7 @@ class MessageHeartbeat extends Message {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageRequest extends Message {
|
||||
/** @type {number} */
|
||||
seq;
|
||||
@@ -644,7 +644,7 @@ class MessageRequest extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageResponse extends Message {
|
||||
/** @type {number} */
|
||||
seq;
|
||||
@@ -685,7 +685,7 @@ class MessageResponse extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ResponseError {
|
||||
/** @type {string} */
|
||||
message;
|
||||
@@ -715,7 +715,7 @@ class ResponseError {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageResponseError extends Message {
|
||||
/** @type {number} */
|
||||
seq;
|
||||
@@ -723,7 +723,7 @@ class MessageResponseError extends Message {
|
||||
src;
|
||||
/** @type {Address} */
|
||||
dst;
|
||||
/** @type {module:lib/data.ResponseError} */
|
||||
/** @type {module:lib.ResponseError} */
|
||||
data;
|
||||
|
||||
constructor(seq, src, dst, data) {
|
||||
@@ -756,7 +756,7 @@ class MessageResponseError extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageEvent extends Message {
|
||||
/** @type {number} */
|
||||
seq;
|
||||
@@ -802,7 +802,7 @@ class MessageEvent extends Message {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class MessageDisconnect extends Message {
|
||||
/** @type {string} */
|
||||
data;
|
||||
@@ -853,7 +853,7 @@ Message.jsonSchema = {
|
||||
};
|
||||
Message.validate = libSchema.compile(Message.jsonSchema);
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class PingRequest {
|
||||
static type = "request";
|
||||
static src = ["controller", "host", "control"];
|
||||
@@ -2,7 +2,7 @@
|
||||
const { jsonArray } = require("./composites");
|
||||
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class HostDetails {
|
||||
/** @type {string} */
|
||||
agent;
|
||||
@@ -44,7 +44,7 @@ class HostDetails {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class HostListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -53,7 +53,7 @@ class HostListRequest {
|
||||
static Response = jsonArray(HostDetails);
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class HostSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -88,13 +88,13 @@ class HostSetSubscriptionsRequest {
|
||||
}
|
||||
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class HostUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
|
||||
/** @type {module:lib/data.HostDetails} */
|
||||
/** @type {module:lib.HostDetails} */
|
||||
update;
|
||||
|
||||
constructor(update) {
|
||||
@@ -114,7 +114,7 @@ class HostUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class HostMetricsRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -143,7 +143,7 @@ HostMetricsRequest.Response = class Response { // TODO: Use JSON class pattern i
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ControllerConnectionEvent {
|
||||
static type = "event";
|
||||
static src = "host";
|
||||
@@ -169,14 +169,14 @@ class ControllerConnectionEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class PrepareControllerDisconnectRequest {
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
static dst = "instance";
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class SyncUserListsEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
+47
-47
@@ -2,7 +2,7 @@
|
||||
const PlayerStats = require("../PlayerStats");
|
||||
const { JsonString, jsonArray } = require("./composites");
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetails {
|
||||
/** @type {string} */
|
||||
name;
|
||||
@@ -43,7 +43,7 @@ class InstanceDetails {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetailsGetRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -72,7 +72,7 @@ class InstanceDetailsGetRequest {
|
||||
static Response = InstanceDetails;
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetailsListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -81,7 +81,7 @@ class InstanceDetailsListRequest {
|
||||
static Response = jsonArray(InstanceDetails);
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetailsSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -115,13 +115,13 @@ class InstanceDetailsSetSubscriptionsRequest {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetailsUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
|
||||
/** @type {module:lib/data.InstanceDetails} */
|
||||
/** @type {module:lib.InstanceDetails} */
|
||||
details;
|
||||
|
||||
constructor(details) {
|
||||
@@ -139,7 +139,7 @@ class InstanceDetailsUpdateEvent {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceCreateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -167,7 +167,7 @@ class InstanceCreateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceConfigGetRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -215,7 +215,7 @@ InstanceConfigGetRequest.Response = class Response {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceConfigSetFieldRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -250,7 +250,7 @@ class InstanceConfigSetFieldRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceConfigSetPropRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -291,7 +291,7 @@ class InstanceConfigSetPropRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceAssignRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -322,7 +322,7 @@ class InstanceAssignRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceMetricsRequest {
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
@@ -351,7 +351,7 @@ InstanceMetricsRequest.Response = class Response { // TODO: Use JSON class patte
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceStartRequest {
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
@@ -377,7 +377,7 @@ class InstanceStartRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class SaveDetails {
|
||||
/** @type {string} */
|
||||
type;
|
||||
@@ -419,7 +419,7 @@ class SaveDetails {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceListSavesRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -428,7 +428,7 @@ class InstanceListSavesRequest {
|
||||
static Response = jsonArray(SaveDetails);
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceSetSaveListSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -462,7 +462,7 @@ class InstanceSetSaveListSubscriptionsRequest {
|
||||
}
|
||||
};
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceSaveListUpdateEvent {
|
||||
static type = "event";
|
||||
static src = ["instance", "host", "controller"];
|
||||
@@ -470,7 +470,7 @@ class InstanceSaveListUpdateEvent {
|
||||
|
||||
/** @type {number} */
|
||||
instanceId;
|
||||
/** @type {module:lib/data.SaveDetails} */
|
||||
/** @type {module:lib.SaveDetails} */
|
||||
saves;
|
||||
|
||||
constructor(instanceId, saves) {
|
||||
@@ -495,7 +495,7 @@ class InstanceSaveListUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceCreateSaveRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -534,7 +534,7 @@ class InstanceCreateSaveRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceRenameSaveRequest {
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
@@ -569,7 +569,7 @@ class InstanceRenameSaveRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceCopySaveRequest {
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
@@ -604,7 +604,7 @@ class InstanceCopySaveRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDeleteSaveRequest {
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
@@ -635,7 +635,7 @@ class InstanceDeleteSaveRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDownloadSaveRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -668,7 +668,7 @@ class InstanceDownloadSaveRequest {
|
||||
static Response = JsonString;
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceTransferSaveRequest {
|
||||
static type = "request";
|
||||
static src = ["control", "controller"];
|
||||
@@ -724,7 +724,7 @@ class InstanceTransferSaveRequest {
|
||||
}
|
||||
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstancePullSaveRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -760,7 +760,7 @@ class InstancePullSaveRequest {
|
||||
static Response = JsonString;
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstancePushSaveRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -794,7 +794,7 @@ class InstancePushSaveRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceLoadScenarioRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -833,7 +833,7 @@ class InstanceLoadScenarioRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceExportDataRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -841,7 +841,7 @@ class InstanceExportDataRequest {
|
||||
static permission = "core.instance.export_data";
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceExtractPlayersRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -849,7 +849,7 @@ class InstanceExtractPlayersRequest {
|
||||
static permission = "core.instance.extract_players";
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceStopRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -857,7 +857,7 @@ class InstanceStopRequest {
|
||||
static permission = "core.instance.stop";
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceKillRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -865,7 +865,7 @@ class InstanceKillRequest {
|
||||
static permission = "core.instance.kill";
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDeleteRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -892,7 +892,7 @@ class InstanceDeleteRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDeleteInternalRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -918,7 +918,7 @@ class InstanceDeleteInternalRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceSendRconRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -948,7 +948,7 @@ class InstanceSendRconRequest {
|
||||
}
|
||||
|
||||
// TODO remove this after config refactor
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class RawInstanceInfo {
|
||||
/** @type {object} */
|
||||
config;
|
||||
@@ -977,13 +977,13 @@ class RawInstanceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstancesUpdateRequest {
|
||||
static type = "request";
|
||||
static src = "host";
|
||||
static dst = "controller";
|
||||
|
||||
/** @type {Array<module:lib/data.RawInstanceInfo>} */
|
||||
/** @type {Array<module:lib.RawInstanceInfo>} */
|
||||
instances;
|
||||
|
||||
constructor(instances) {
|
||||
@@ -1004,7 +1004,7 @@ class InstancesUpdateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceAssignInternalRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -1035,7 +1035,7 @@ class InstanceAssignInternalRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceUnassignInternalRequest {
|
||||
static type = "request";
|
||||
static src = "controller";
|
||||
@@ -1061,7 +1061,7 @@ class InstanceUnassignInternalRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceInitialisedEvent {
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
@@ -1090,7 +1090,7 @@ class InstanceInitialisedEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceStatusChangedEvent {
|
||||
static type = "event";
|
||||
static src = ["instance", "host"];
|
||||
@@ -1129,13 +1129,13 @@ class InstanceStatusChangedEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceDetailsChangedEvent {
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
static dst = "controller";
|
||||
|
||||
/** @type {module:lib/data.InstanceDetails} */
|
||||
/** @type {module:lib.InstanceDetails} */
|
||||
details;
|
||||
|
||||
constructor(details) {
|
||||
@@ -1149,7 +1149,7 @@ class InstanceDetailsChangedEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceBanlistUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
@@ -1185,7 +1185,7 @@ class InstanceBanlistUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceAdminlistUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
@@ -1216,7 +1216,7 @@ class InstanceAdminlistUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstanceWhitelistUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
@@ -1247,7 +1247,7 @@ class InstanceWhitelistUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class InstancePlayerUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "instance";
|
||||
@@ -4,7 +4,7 @@ const ModInfo = require("./ModInfo");
|
||||
const { jsonArray, JsonString } = require("./composites");
|
||||
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackGetRequest {
|
||||
static type = "request";
|
||||
static src = ["instance", "control"];
|
||||
@@ -33,7 +33,7 @@ class ModPackGetRequest {
|
||||
static Response = ModPack;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackGetDefaultRequest {
|
||||
static type = "request";
|
||||
static src = ["instance", "control"];
|
||||
@@ -42,7 +42,7 @@ class ModPackGetDefaultRequest {
|
||||
static Response = ModPack;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -51,14 +51,14 @@ class ModPackListRequest {
|
||||
static Response = jsonArray(ModPack);
|
||||
}
|
||||
|
||||
/** @memberof module:lib/data */
|
||||
/** @memberof module:lib */
|
||||
class ModPackCreateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.create";
|
||||
|
||||
/** @type {module:lib/data.ModPack} */
|
||||
/** @type {module:lib.ModPack} */
|
||||
modPack;
|
||||
|
||||
constructor(modPack) {
|
||||
@@ -78,14 +78,14 @@ class ModPackCreateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackUpdateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
static permission = "core.mod_pack.update";
|
||||
|
||||
/** @type {module:lib/data.ModPack} */
|
||||
/** @type {module:lib.ModPack} */
|
||||
modPack;
|
||||
|
||||
constructor(modPack) {
|
||||
@@ -105,7 +105,7 @@ class ModPackUpdateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackDeleteRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -132,7 +132,7 @@ class ModPackDeleteRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -166,7 +166,7 @@ class ModPackSetSubscriptionsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModGetRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -199,7 +199,7 @@ class ModGetRequest {
|
||||
static Response = ModInfo;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -208,7 +208,7 @@ class ModListRequest {
|
||||
static Response = jsonArray(ModInfo);
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModSearchRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -305,7 +305,7 @@ ModSearchRequest.Response = class Response {
|
||||
}
|
||||
};
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -339,7 +339,7 @@ class ModSetSubscriptionsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModDownloadRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -372,7 +372,7 @@ class ModDownloadRequest {
|
||||
static Response = JsonString;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModDeleteRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -403,13 +403,13 @@ class ModDeleteRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModPackUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
|
||||
/** @type {module:lib/data.ModPack} */
|
||||
/** @type {module:lib.ModPack} */
|
||||
modPack;
|
||||
|
||||
constructor(modPack) {
|
||||
@@ -429,13 +429,13 @@ class ModPackUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class ModUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
|
||||
/** @type {module:lib/data.ModInfo} */
|
||||
/** @type {module:lib.ModInfo} */
|
||||
mod;
|
||||
|
||||
constructor(mod) {
|
||||
@@ -2,7 +2,7 @@
|
||||
const PlayerStats = require("../PlayerStats");
|
||||
const { jsonArray, JsonNumber } = require("./composites");
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RawPermission { // TODO refactor into lib/user.Permission
|
||||
/** @type {string} */
|
||||
name;
|
||||
@@ -32,7 +32,7 @@ class RawPermission { // TODO refactor into lib/user.Permission
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class PermissionListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -77,7 +77,7 @@ class RawRole { // TODO refactor into lib/user.Role
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RoleListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -86,7 +86,7 @@ class RoleListRequest {
|
||||
static Response = jsonArray(RawRole);
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RoleCreateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -126,7 +126,7 @@ class RoleCreateRequest {
|
||||
static Response = JsonNumber;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RoleUpdateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -168,7 +168,7 @@ class RoleUpdateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RoleGrantDefaultPermissionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -195,7 +195,7 @@ class RoleGrantDefaultPermissionsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RoleDeleteRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -222,7 +222,7 @@ class RoleDeleteRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class RawUser { // TODO refactor into lib/user.User
|
||||
/** @type {string} */
|
||||
name;
|
||||
@@ -240,9 +240,9 @@ class RawUser { // TODO refactor into lib/user.User
|
||||
banReason;
|
||||
/** @type {boolean|undefined} */
|
||||
isDeleted;
|
||||
/** @type {module:lib/PlayerStats} */
|
||||
/** @type {module:lib.PlayerStats} */
|
||||
playerStats;
|
||||
/** @type {Map<number, module:lib/PlayerStats>|undefined} */
|
||||
/** @type {Map<number, module:lib.PlayerStats>|undefined} */
|
||||
instanceStats;
|
||||
|
||||
constructor(
|
||||
@@ -321,7 +321,7 @@ class RawUser { // TODO refactor into lib/user.User
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserGetRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -350,7 +350,7 @@ class UserGetRequest {
|
||||
static Response = RawUser;
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserListRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -359,7 +359,7 @@ class UserListRequest {
|
||||
static Response = jsonArray(RawUser);
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserSetSubscriptionsRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -393,7 +393,7 @@ class UserSetSubscriptionsRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserCreateRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -420,7 +420,7 @@ class UserCreateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserRevokeTokenRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -447,7 +447,7 @@ class UserRevokeTokenRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserUpdateRolesRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -481,7 +481,7 @@ class UserUpdateRolesRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserSetAdminRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -516,7 +516,7 @@ class UserSetAdminRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserSetWhitelistedRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -551,7 +551,7 @@ class UserSetWhitelistedRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserSetBannedRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -590,7 +590,7 @@ class UserSetBannedRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserDeleteRequest {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
@@ -618,7 +618,7 @@ class UserDeleteRequest {
|
||||
}
|
||||
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class AccountUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
@@ -657,13 +657,13 @@ class AccountUpdateEvent {
|
||||
}
|
||||
}
|
||||
|
||||
/* @memberof module:lib/data */
|
||||
/* @memberof module:lib */
|
||||
class UserUpdateEvent {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "control";
|
||||
|
||||
/** @type {module:lib/data.RawUser} */
|
||||
/** @type {module:lib.RawUser} */
|
||||
user;
|
||||
|
||||
constructor(user) {
|
||||
@@ -9,7 +9,7 @@
|
||||
* number of leading zeros in them.
|
||||
* @param {string} version - string representation of version.
|
||||
* @returns {number} numeric representation.
|
||||
* @alias module:lib/data.integerModVersion
|
||||
* @alias module:lib.integerModVersion
|
||||
*/
|
||||
function integerModVersion(version) {
|
||||
const [major, minor, sub] = version.split(".").map(n => Number.parseInt(n, 10));
|
||||
@@ -23,7 +23,7 @@ function integerModVersion(version) {
|
||||
* number of leading zeros in them.
|
||||
* @param {string} version - string representation of version.
|
||||
* @returns {number} numeric representation.
|
||||
* @alias module:lib/data.integerFactorioVersion
|
||||
* @alias module:lib.integerFactorioVersion
|
||||
*/
|
||||
function integerFactorioVersion(version) {
|
||||
const [main, major, minor] = version.split(".").map(n => Number.parseInt(n, 10));
|
||||
@@ -33,7 +33,7 @@ function integerFactorioVersion(version) {
|
||||
/**
|
||||
* Matches valid mod versions.
|
||||
* @type {RegExp}
|
||||
* @alias module:lib/data.modVersionRegExp
|
||||
* @alias module:lib.modVersionRegExp
|
||||
*/
|
||||
const modVersionRegExp = /^\d+\.\d+\.\d+$/;
|
||||
|
||||
@@ -170,7 +170,7 @@ class ItemDatabase {
|
||||
* Create a new item database
|
||||
*
|
||||
* @param {object|undefined} serialized - An object from a previous call to
|
||||
* {@link module:lib/database~ItemDatabase#serialize} to restore the
|
||||
* {@link module:libbase~ItemDatabase#serialize} to restore the
|
||||
* database from. An empty database will be created if this parameter
|
||||
* is left undefined.
|
||||
*/
|
||||
File renamed without changes.
+3
-3
@@ -324,7 +324,7 @@ function readMapSettings(state) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} module:lib/factorio.MapExchangeResult
|
||||
* @typedef {object} module:lib.MapExchangeResult
|
||||
* @property {array} version -
|
||||
* Version of Factorio the string was created with.
|
||||
* @property {object} map_gen_settings -
|
||||
@@ -344,8 +344,8 @@ function readMapSettings(state) {
|
||||
* save to set the map gen settings and the map settings for the save.
|
||||
*
|
||||
* @param {string} exchangeString - Max Exchange String to parse.
|
||||
* @returns {module:lib/factorio.MapExchangeResult} Parsed result.
|
||||
* @memberof module:lib/factorio
|
||||
* @returns {module:lib.MapExchangeResult} Parsed result.
|
||||
* @memberof module:lib
|
||||
*/
|
||||
function readMapExchangeString(exchangeString) {
|
||||
exchangeString = exchangeString.replace(/[ \t\n\r]+/g, "");
|
||||
@@ -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,
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
@@ -210,18 +210,18 @@ function wordMatches(word, ...texts) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} module:lib/helpers~ParsedTerm
|
||||
* @typedef {object} module:lib~ParsedTerm
|
||||
* @property {string} type - Type of term, either attribute or word.
|
||||
* @property {string=} name - attribute only: Name of attribute.
|
||||
* @property {boolean=} exclude - word only: exclude results with this word.
|
||||
* @property {string | module:lib/helpers.ParsedTerm} value -
|
||||
* @property {string | module:lib.ParsedTerm} value -
|
||||
* Parsed value of this term. Is a string if type is word, and a
|
||||
* ParsedTerm if type is attribute.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} module:lib/helpers~ParsedSearch
|
||||
* @property {Array<module:lib/helpers~ParsedTerm>} terms -
|
||||
* @typedef {object} module:lib~ParsedSearch
|
||||
* @property {Array<module:lib~ParsedTerm>} terms -
|
||||
* Parsed result of search terms.
|
||||
* @property {Array<string>} issues -
|
||||
* Issues detected while parsing the seach string.
|
||||
@@ -248,7 +248,7 @@ function wordMatches(word, ...texts) {
|
||||
* @param {Object<string, string>} attributes -
|
||||
* Recognized attributes and their format. Currently only word is
|
||||
* supported.
|
||||
* @returns {module:lib/helpers~ParsedSearch} parsed terms of the search.
|
||||
* @returns {module:lib~ParsedSearch} parsed terms of the search.
|
||||
* @static
|
||||
*/
|
||||
function parseSearchString(input, attributes = {}) {
|
||||
File renamed without changes.
File renamed without changes.
@@ -15,7 +15,7 @@ const ExponentialBackoff = require("../ExponentialBackoff");
|
||||
* Base connector for links
|
||||
*
|
||||
* @extends events.EventEmitter
|
||||
* @memberof module:lib/link
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class BaseConnector extends events.EventEmitter {
|
||||
constructor(src, dst) {
|
||||
@@ -76,8 +76,8 @@ class BaseConnector extends events.EventEmitter {
|
||||
/**
|
||||
* Base connector for links
|
||||
*
|
||||
* @extends module:lib/link.BaseConnector
|
||||
* @memberof module:lib/link
|
||||
* @extends module:lib.BaseConnector
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class WebSocketBaseConnector extends BaseConnector {
|
||||
constructor(src, dst) {
|
||||
@@ -231,7 +231,7 @@ class WebSocketBaseConnector extends BaseConnector {
|
||||
* This is a low level method that should only be used for implementing
|
||||
* links. See sendTo for sending requests and events.
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message to send.
|
||||
* @param {module:lib.Message} message - Message to send.
|
||||
*/
|
||||
send(message) {
|
||||
if (!["connected", "resuming"].includes(this._state)) {
|
||||
@@ -313,8 +313,8 @@ class WebSocketBaseConnector extends BaseConnector {
|
||||
/**
|
||||
* Connector for controller clients
|
||||
*
|
||||
* @extends module:lib/link.WebSocketBaseConnector
|
||||
* @memberof module:lib/link
|
||||
* @extends module:lib.WebSocketBaseConnector
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
constructor(url, maxReconnectDelay, tlsCa = null) {
|
||||
@@ -360,7 +360,7 @@ class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
* Used in the register function in order to send the handshake messages
|
||||
* over the WebSocket.
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message to send.
|
||||
* @param {module:lib.Message} message - Message to send.
|
||||
*/
|
||||
sendHandshake(message) {
|
||||
this._check("connecting", "resuming");
|
||||
@@ -647,7 +647,7 @@ class WebSocketClientConnector extends WebSocketBaseConnector {
|
||||
* Connector for in-memory local links
|
||||
*
|
||||
* @extends events.EventEmitter
|
||||
* @memberof module:lib/link
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class VirtualConnector extends BaseConnector {
|
||||
constructor(src, dst) {
|
||||
@@ -662,8 +662,8 @@ class VirtualConnector extends BaseConnector {
|
||||
* Creates two virtual connectors that are liked to each othes such that
|
||||
* a message sent on one is received by the other.
|
||||
*
|
||||
* @param {module:lib/data.Address} src - Source for obverse connector
|
||||
* @param {module:lib/data.Address} dst - destination for obverse connector
|
||||
* @param {module:lib.Address} src - Source for obverse connector
|
||||
* @param {module:lib.Address} dst - destination for obverse connector
|
||||
* @returns {Array} two virtuarl connectors.
|
||||
*/
|
||||
static makePair(src, dst) {
|
||||
@@ -677,7 +677,7 @@ class VirtualConnector extends BaseConnector {
|
||||
/**
|
||||
* Send a message to the other end of the connector
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message type to send.
|
||||
* @param {module:lib.Message} message - Message type to send.
|
||||
*/
|
||||
send(message) {
|
||||
this.other.emit("message", message);
|
||||
File renamed without changes.
@@ -17,7 +17,7 @@ const { dataClasses } = require("./messages");
|
||||
/**
|
||||
* Common interface for server and client connections
|
||||
*
|
||||
* @memberof module:lib/link
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class Link {
|
||||
constructor(connector) {
|
||||
@@ -95,8 +95,8 @@ class Link {
|
||||
* Validates and invokes the handler and/or waiters for a message that has
|
||||
* been received. An unhandled message is considered to be an error.
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message to process.
|
||||
* @throws {module:lib/errors.InvalidMessage} if the message is invalid or not handled.
|
||||
* @param {module:lib.Message} message - Message to process.
|
||||
* @throws {module:lib.InvalidMessage} if the message is invalid or not handled.
|
||||
*/
|
||||
_processMessage(message) {
|
||||
if (!["request", "response", "responseError", "event"].includes(message.type)) {
|
||||
@@ -149,8 +149,8 @@ class Link {
|
||||
*
|
||||
* Should be overridden by sub-classes to validate messages received.
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message to check.
|
||||
* @throws {module:lib/errors.InvalidMessage} if the message is invalid.
|
||||
* @param {module:lib.Message} message - Message to check.
|
||||
* @throws {module:lib.InvalidMessage} if the message is invalid.
|
||||
*/
|
||||
validateIngress(message) { }
|
||||
|
||||
@@ -222,9 +222,9 @@ class Link {
|
||||
* Called when an request or event is received by a control connector.
|
||||
* Should be overridden by sub-classes to validate messages received.
|
||||
*
|
||||
* @param {module:lib/data.Message} message - Message to check.
|
||||
* @param {module:lib.Message} message - Message to check.
|
||||
* @param {object} entry - Request or Event entry for this Message.
|
||||
* @throws {module:lib/errors.PermissionError} if unauthorized.
|
||||
* @throws {module:lib.PermissionError} if unauthorized.
|
||||
*/
|
||||
validatePermission(message, entry) { }
|
||||
|
||||
@@ -380,7 +380,7 @@ class Link {
|
||||
/**
|
||||
* Send a request or event to the given address
|
||||
*
|
||||
* @param {*|module:lib/data.Address} destination - Where to send it
|
||||
* @param {*|module:lib.Address} destination - Where to send it
|
||||
* @param {*} requestOrEvent - Request or event to send
|
||||
* @returns {Promise<*>|undefined}
|
||||
* Promise that resolves to the response if a request was sent or
|
||||
File renamed without changes.
@@ -84,7 +84,7 @@ class WebConsoleFormat {
|
||||
|
||||
/**
|
||||
* Filter object for logs
|
||||
* @typedef {Object} module:lib/logging~LogFilter
|
||||
* @typedef {Object} module:lib~LogFilter
|
||||
* @property {string} [maxLevel] -
|
||||
* Maximum log level to include. Higher levels are more verbose.
|
||||
* @property {boolean} [all] -
|
||||
@@ -101,7 +101,7 @@ class WebConsoleFormat {
|
||||
/**
|
||||
* Create log filter by level and source.
|
||||
*
|
||||
* @param {module:lib/logging~LogFilter} filter -
|
||||
* @param {module:lib~LogFilter} filter -
|
||||
* Filter to filter log entries by.
|
||||
* @returns {function(object): boolean}
|
||||
* filter returning true for log entries that match it.
|
||||
@@ -188,10 +188,10 @@ class LogIndex {
|
||||
*
|
||||
* Loads index.json from the given log directy expecting it to contain
|
||||
* data about previously indexed files saved with {@link
|
||||
* module:lib/logging_utils.LogIndex#save}.
|
||||
* module:lib.LogIndex#save}.
|
||||
*
|
||||
* @param {string} logDirectory - Path to directory to load from.
|
||||
* @returns {Promise<module:lib/logging_utils.LogIndex>} loaded or created log index.
|
||||
* @returns {Promise<module:lib.LogIndex>} loaded or created log index.
|
||||
*/
|
||||
static async load(logDirectory) {
|
||||
try {
|
||||
@@ -275,7 +275,7 @@ class LogIndex {
|
||||
*
|
||||
* @param {string} file -
|
||||
* Name of file in the log directory to check for.
|
||||
* @param {module:lib/logging~LogFilter} filter -
|
||||
* @param {module:lib~LogFilter} filter -
|
||||
* Filter to check index if file contains entries for.
|
||||
* @returns {boolean}
|
||||
* true if the file may contain entries included by the filter.
|
||||
@@ -314,7 +314,7 @@ class LogIndex {
|
||||
|
||||
/**
|
||||
* Filter object for querying logs
|
||||
* @typedef {Object} module:lib/logging_utils~QueryLogFilter
|
||||
* @typedef {Object} module:lib~QueryLogFilter
|
||||
* @property {number} [limit=100] - Maximum number of entries to return.
|
||||
* @property {string} [order="asc"] -
|
||||
* Return entries in ascending ("asc") date order or desceding ("desc")
|
||||
@@ -336,9 +336,9 @@ class LogIndex {
|
||||
* Query log directory
|
||||
*
|
||||
* @param {string} logDirectory - path to directory with logs.
|
||||
* @param {module:lib/logging_utils~QueryLogFilter} filter -
|
||||
* @param {module:lib~QueryLogFilter} filter -
|
||||
* Filter to limit logs by.
|
||||
* @param {module:lib/logging_utils.LogIndex=} index -
|
||||
* @param {module:lib.LogIndex=} index -
|
||||
* Index to speed up query with.
|
||||
* @returns {Promise<Array<Object>>} log entries matching the filter
|
||||
*/
|
||||
File renamed without changes.
@@ -9,10 +9,10 @@ const helpers = require("./helpers");
|
||||
/**
|
||||
* Conceptual base for controller and instance plugins.
|
||||
* @typedef {
|
||||
* module:lib/plugin.BaseControllerPlugin
|
||||
* |module:lib/plugin.BaseInstancePlugin
|
||||
* |module:lib/plugin.BaseControlPlugin
|
||||
* } module:lib/plugin.BasePlugin
|
||||
* module:lib.BaseControllerPlugin
|
||||
* |module:lib.BaseInstancePlugin
|
||||
* |module:lib.BaseControlPlugin
|
||||
* } module:lib.BasePlugin
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ class BaseInstancePlugin {
|
||||
* Invoked after the value of the config field given by `field` has
|
||||
* changed.
|
||||
*
|
||||
* @param {module:lib/config.ConfigGroup} group -
|
||||
* @param {module:lib.ConfigGroup} group -
|
||||
* The group who's field got changed.
|
||||
* @param {string} field - Name of the field that changed.
|
||||
* @param {*} prev - The previous value of the field.
|
||||
@@ -366,7 +366,7 @@ class BaseControllerPlugin {
|
||||
* Invoked after the value of the config field given by `field` has
|
||||
* changed on the controller.
|
||||
*
|
||||
* @param {module:lib/config.ConfigGroup} group -
|
||||
* @param {module:lib.ConfigGroup} group -
|
||||
* The group who's field got changed.
|
||||
* @param {string} field - Name of the field that changed.
|
||||
* @param {*} prev - The previous value of the field.
|
||||
@@ -381,7 +381,7 @@ class BaseControllerPlugin {
|
||||
*
|
||||
* @param {module:controller/src/InstanceInfo} instance -
|
||||
* The instance the config changed on.
|
||||
* @param {module:lib/config.ConfigGroup} group -
|
||||
* @param {module:lib.ConfigGroup} group -
|
||||
* The group who's field got changed.
|
||||
* @param {string} field - Name of the field that changed.
|
||||
* @param {*} prev - The previous value of the field.
|
||||
@@ -504,7 +504,7 @@ class BaseControllerPlugin {
|
||||
* If the mod pack has been deleted its `.isDeleted` property will be
|
||||
* true.
|
||||
*
|
||||
* @param {module:lib/data.ModPack} modPack - Mod pack that updated.
|
||||
* @param {module:lib.ModPack} modPack - Mod pack that updated.
|
||||
*/
|
||||
async onModPackUpdated(modPack) { }
|
||||
|
||||
@@ -516,7 +516,7 @@ class BaseControllerPlugin {
|
||||
*
|
||||
* If a mod has been deleted its `.isDeleted` property will be true.
|
||||
*
|
||||
* @param {module:lib/data.ModInfo} mod - Mod that updated.
|
||||
* @param {module:lib.ModInfo} mod - Mod that updated.
|
||||
*/
|
||||
async onModUpdated(mod) { }
|
||||
|
||||
@@ -601,9 +601,9 @@ class BaseControlPlugin {
|
||||
*
|
||||
* Invoked by clusterioctl to let plugins add commands. `rootCommand` is
|
||||
* the top level command node which the plugin should add its own {@link
|
||||
* module:lib/command.CommandTree} to.
|
||||
* module:lib.CommandTree} to.
|
||||
*
|
||||
* @param {module:lib/command.CommandTree} rootCommand -
|
||||
* @param {module:lib.CommandTree} rootCommand -
|
||||
* Root of the clusterioctl command tree.
|
||||
*/
|
||||
async addCommands(rootCommand) { }
|
||||
@@ -612,7 +612,7 @@ class BaseControlPlugin {
|
||||
|
||||
/**
|
||||
* Plugin supplied login form
|
||||
* @typedef {Object} module:lib/plugin~LoginForm
|
||||
* @typedef {Object} module:lib~LoginForm
|
||||
* @property {string} name -
|
||||
* Internal name of the login form, this should start with the
|
||||
* plugin name followed by a dot.
|
||||
@@ -627,7 +627,7 @@ class BaseControlPlugin {
|
||||
|
||||
/**
|
||||
* Plugin supplied pages
|
||||
* @typedef {Object} module:lib/plugin~Page
|
||||
* @typedef {Object} module:lib~Page
|
||||
* @property {string} path - URL path to this page.
|
||||
* @property {string=} sidebarPath -
|
||||
* If present and this path matches one of the pages in the sidebar it
|
||||
@@ -669,7 +669,7 @@ class BaseWebPlugin {
|
||||
/**
|
||||
* Control link to the controller, not available until the
|
||||
* connect event in onControllerConnectionEvent is signaled.
|
||||
* @type {?module:lib/link.Link}
|
||||
* @type {?module:lib.Link}
|
||||
*/
|
||||
this.control = null;
|
||||
|
||||
@@ -685,14 +685,14 @@ class BaseWebPlugin {
|
||||
/**
|
||||
* List of login forms provided by this plugin
|
||||
*
|
||||
* @type {Array<module:lib/plugin~LoginForm>}
|
||||
* @type {Array<module:lib~LoginForm>}
|
||||
*/
|
||||
this.loginForms = [];
|
||||
|
||||
/**
|
||||
* List of pages provided by this plugin
|
||||
*
|
||||
* @type {Array<module:lib/plugin~Page>}
|
||||
* @type {Array<module:lib~Page>}
|
||||
*/
|
||||
this.pages = [];
|
||||
|
||||
@@ -77,7 +77,7 @@ function loadPluginClass(entrypointName, className, pluginClass, pluginInfo) {
|
||||
*
|
||||
* @param {Object} pluginInfo -
|
||||
* Plugin info object returned from {@link
|
||||
* module:lib/plugin_loader.loadPluginInfos} to load class from.
|
||||
* module:lib.loadPluginInfos} to load class from.
|
||||
* @returns {Promise<function>} plugin class
|
||||
* @static
|
||||
*/
|
||||
@@ -90,7 +90,7 @@ async function loadControllerPluginClass(pluginInfo) {
|
||||
*
|
||||
* @param {Object} pluginInfo -
|
||||
* Plugin info object returned from {@link
|
||||
* module:lib/plugin_loader.loadPluginInfos} to load class from.
|
||||
* module:lib.loadPluginInfos} to load class from.
|
||||
* @returns {Promise<function>} plugin class
|
||||
* @static
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ async function loadInstancePluginClass(pluginInfo) {
|
||||
*
|
||||
* @param {Object} pluginInfo -
|
||||
* Plugin info object returned from {@link
|
||||
* module:lib/plugin_loader.loadPluginInfos} to load class from.
|
||||
* module:lib.loadPluginInfos} to load class from.
|
||||
* @returns {Promise<function>} plugin class
|
||||
* @static
|
||||
*/
|
||||
@@ -7,13 +7,13 @@
|
||||
* metric collections in prom-client.
|
||||
*
|
||||
* The ordinary use case of instrumenting a code base should be covered by
|
||||
* {@link module:lib/prometheus.Counter}, {@link
|
||||
* module:lib/prometheus.Gauge}, {@link module:lib/prometheus.Histogram} and
|
||||
* {@link module:lib/prometheus.exposition}. See documentation for each of
|
||||
* {@link module:lib.Counter}, {@link
|
||||
* module:lib.Gauge}, {@link module:lib.Histogram} and
|
||||
* {@link module:lib.exposition}. See documentation for each of
|
||||
* the listed interfaces for more information.
|
||||
*
|
||||
* @example
|
||||
* const { Counter, exposition } = require("@clusterio/lib/prometheus");
|
||||
* const { Counter, exposition } = require("@clusterio/lib");
|
||||
*
|
||||
* // Collectors are by default registered to the default collector regitry.
|
||||
* const totalRequests = new Counter(
|
||||
@@ -42,9 +42,9 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Result from collecting a {@link module:lib/prometheus.Collector}
|
||||
* Result from collecting a {@link module:lib.Collector}
|
||||
* @typedef {Object} CollectorResult
|
||||
* @property {module:lib/prometheus.Metric} metric -
|
||||
* @property {module:lib.Metric} metric -
|
||||
* Metric collected.
|
||||
* @property {Map<string, Map<string, number>>} samples -
|
||||
* Mapping of metric suffix to mapping of label keys to values
|
||||
@@ -165,7 +165,7 @@ class Metric {
|
||||
|
||||
/**
|
||||
* The default registry which collectors are regististered to.
|
||||
* @type {module:lib/prometheus.CollectorRegistry}
|
||||
* @type {module:lib.CollectorRegistry}
|
||||
* @static
|
||||
*/
|
||||
let defaultRegistry;
|
||||
@@ -176,7 +176,7 @@ let defaultRegistry;
|
||||
* This servers mostly as a conceptual base for all collectors, the only
|
||||
* feature implemented here is registring to the default registry on
|
||||
* construction. If you want to implement a custom collector you most
|
||||
* likely want to base it on {@link module:lib/prometheus.LabeledCollector}
|
||||
* likely want to base it on {@link module:lib.LabeledCollector}
|
||||
* instead.
|
||||
*
|
||||
* @static
|
||||
@@ -197,7 +197,7 @@ class Collector {
|
||||
/**
|
||||
* Retrieve metric data from this collctor.
|
||||
*
|
||||
* Called by {@link module:lib/prometheus.CollectorRegistry} to gather
|
||||
* Called by {@link module:lib.CollectorRegistry} to gather
|
||||
* the metric data this Collector exports.
|
||||
*
|
||||
* @returns {*} Async iterator of {@link CollectorResult}.
|
||||
@@ -318,7 +318,7 @@ function removeMatchingLabels(mapping, labels) {
|
||||
* set is a child to the collector that can be retrieved with the .labels()
|
||||
* method.
|
||||
*
|
||||
* @extends module:lib/prometheus.Collector
|
||||
* @extends module:lib.Collector
|
||||
* @static
|
||||
*/
|
||||
class LabeledCollector extends Collector {
|
||||
@@ -341,7 +341,7 @@ class LabeledCollector extends Collector {
|
||||
* collected. The collector being collected is passed as the
|
||||
* argument.
|
||||
* @param {
|
||||
* function(module:lib/prometheus.LabeledCollector,string)
|
||||
* function(module:lib.LabeledCollector,string)
|
||||
* } childClass -
|
||||
* Constructor taking instance of collector and label key as
|
||||
* arguments and returns a child instance.
|
||||
@@ -461,7 +461,7 @@ class LabeledCollector extends Collector {
|
||||
/**
|
||||
* Base class for implementing single value per label collectors
|
||||
*
|
||||
* @extends module:lib/prometheus.LabeledCollector
|
||||
* @extends module:lib.LabeledCollector
|
||||
* @static
|
||||
*/
|
||||
class ValueCollector extends LabeledCollector {
|
||||
@@ -485,8 +485,8 @@ class ValueCollector extends LabeledCollector {
|
||||
* argument.
|
||||
* @param {
|
||||
* function(
|
||||
* new:module:lib/prometheus.ValueCollectorChild,
|
||||
* module:lib/prometheus.LabeledCollector,
|
||||
* new:module:lib.ValueCollectorChild,
|
||||
* module:lib.LabeledCollector,
|
||||
* string
|
||||
* )
|
||||
* } childClass -
|
||||
@@ -555,7 +555,7 @@ class ValueCollectorChild {
|
||||
|
||||
/**
|
||||
* Child counter holding the value for a single label set.
|
||||
* @extends module:lib/prometheus~ValueCollectorChild
|
||||
* @extends module:lib~ValueCollectorChild
|
||||
*/
|
||||
class CounterChild extends ValueCollectorChild {
|
||||
/**
|
||||
@@ -597,7 +597,7 @@ class CounterChild extends ValueCollectorChild {
|
||||
*
|
||||
* The `totalRequests` counter will register with the default registry and
|
||||
* provided exposition is set up (see {@link
|
||||
* module:lib/prometheus.exposition}) the counter will be exported to
|
||||
* module:lib.exposition}) the counter will be exported to
|
||||
* Prometheus starting out with a value of 0. And that is all there is to
|
||||
* it.
|
||||
*
|
||||
@@ -652,7 +652,7 @@ class CounterChild extends ValueCollectorChild {
|
||||
* labels you actually need as resource usage for a metric increases
|
||||
* exponentially with the number of labels used.
|
||||
*
|
||||
* @extends module:lib/prometheus.ValueCollector
|
||||
* @extends module:lib.ValueCollector
|
||||
* @static
|
||||
*/
|
||||
class Counter extends ValueCollector {
|
||||
@@ -689,7 +689,7 @@ class Counter extends ValueCollector {
|
||||
|
||||
/**
|
||||
* Child gauge holding the value for a single label set.
|
||||
* @extends module:lib/prometheus~ValueCollectorChild
|
||||
* @extends module:lib~ValueCollectorChild
|
||||
*/
|
||||
class GaugeChild extends ValueCollectorChild {
|
||||
/**
|
||||
@@ -771,7 +771,7 @@ class GaugeChild extends ValueCollectorChild {
|
||||
*
|
||||
* The `activeRequests` gauge will register with the default registry and
|
||||
* provided exposition is set up (see {@link
|
||||
* module:lib/prometheus.exposition}) the gauge will be exported to
|
||||
* module:lib.exposition}) the gauge will be exported to
|
||||
* Prometheus starting out with a value of 0.
|
||||
*
|
||||
* Sometimes keeping track of the value measured is impractical or
|
||||
@@ -842,7 +842,7 @@ class GaugeChild extends ValueCollectorChild {
|
||||
* labels you actually need as resource usage for a metric increases
|
||||
* exponentially with the number of labels used.
|
||||
*
|
||||
* @extends module:lib/prometheus.ValueCollector
|
||||
* @extends module:lib.ValueCollector
|
||||
* @static
|
||||
*/
|
||||
class Gauge extends ValueCollector {
|
||||
@@ -1637,7 +1637,7 @@ async function* expositionLines(resultsIterator) {
|
||||
* @param {*} resultsIterator -
|
||||
* Asynchronously itreable of {@link CollectorResult} results to create
|
||||
* exposition for. Defaults to collecting results from {@link
|
||||
* module:lib/prometheus.defaultRegistry}.
|
||||
* module:lib.defaultRegistry}.
|
||||
* @returns {string} Prometheus exposition.
|
||||
*
|
||||
* @property {string} exposition.contentType
|
||||
@@ -1658,10 +1658,10 @@ exposition.contentType = "text/plain; version=0.0.4";
|
||||
/**
|
||||
* Serialize CollectorResult into a plain object
|
||||
*
|
||||
* Converts a {@link module:lib/prometheus~CollectorResult} into a plain
|
||||
* Converts a {@link module:lib~CollectorResult} into a plain
|
||||
* object form that can be stringified to JSON.
|
||||
*
|
||||
* @param {module:lib/prometheus~CollectorResult} result -
|
||||
* @param {module:lib~CollectorResult} result -
|
||||
* Result to serialize into plain object form.
|
||||
* @param {Object} options - Options for controlling the serialization.
|
||||
* @param {string} options.addLabels -
|
||||
@@ -1724,10 +1724,10 @@ function serializeResult(result, options = {}) {
|
||||
/**
|
||||
* Deserialize CollectorResult from plain object
|
||||
*
|
||||
* Reverse counterpart to {@link module:lib/prometheus.serializeResult}.
|
||||
* Reverse counterpart to {@link module:lib.serializeResult}.
|
||||
*
|
||||
* @param {Object} serializedResult - Previously serialized result object.
|
||||
* @returns {module:lib/prometheus~CollectorResult} deserialized result.
|
||||
* @returns {module:lib~CollectorResult} deserialized result.
|
||||
* @static
|
||||
*/
|
||||
function deserializeResult(serializedResult) {
|
||||
@@ -1748,7 +1748,7 @@ function deserializeResult(serializedResult) {
|
||||
|
||||
/**
|
||||
* Default collectors provided by this library
|
||||
* @type {Object<string, module:lib/prometheus.Collector>}
|
||||
* @type {Object<string, module:lib.Collector>}
|
||||
*/
|
||||
let defaultCollectors = {};
|
||||
defaultCollectors.processCpuSecondsTotal = new Gauge(
|
||||
File renamed without changes.
@@ -120,7 +120,7 @@ function configCommand(yargs) {
|
||||
* Handle the actions that are made available by configCommand.
|
||||
*
|
||||
* @param {Object} args - yargs args object.
|
||||
* @param {module:lib/config.Config} instance - Config instance.
|
||||
* @param {module:lib.Config} instance - Config instance.
|
||||
* @param {string} configPath - Path to configuration file.
|
||||
*/
|
||||
async function handleConfigCommand(args, instance, configPath) {
|
||||
@@ -16,7 +16,7 @@ const stream = require("stream");
|
||||
* let fileStream = fs.createReadStream(path);
|
||||
* fileStream.pipe(lineStream);
|
||||
*
|
||||
* @memberof module:lib/stream
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class LineSplitter extends stream.Transform {
|
||||
constructor(options) {
|
||||
@@ -63,7 +63,7 @@ class LineSplitter extends stream.Transform {
|
||||
* Transform splitting a reverse stream into lines
|
||||
*
|
||||
* Splits up a reverse stream of chunks created by {@link
|
||||
* module:lib/stream.createReverseReadStream} by newlines and passes on the
|
||||
* module:lib.createReverseReadStream} by newlines and passes on the
|
||||
* lines one by one in reverse order removing the line feed and optional
|
||||
* carriage return from the lines.
|
||||
*
|
||||
@@ -73,7 +73,7 @@ class LineSplitter extends stream.Transform {
|
||||
* let revFileStream = await libStream.createReverseReadStream(path);
|
||||
* revFileStream.pipe(revLineStream);
|
||||
*
|
||||
* @memberof module:lib/stream
|
||||
* @memberof module:lib
|
||||
*/
|
||||
class ReverseLineSplitter extends stream.Transform {
|
||||
constructor(options) {
|
||||
@@ -141,7 +141,7 @@ class ReverseLineSplitter extends stream.Transform {
|
||||
* @param {object} options -
|
||||
* Options to pass to fs.createReadStream. Values passed for `fd` and
|
||||
* `fs` will be ignored.
|
||||
* @memberof module:lib/stream
|
||||
* @memberof module:lib
|
||||
*/
|
||||
async function createReverseReadStream(path, options) {
|
||||
const fileFd = await fs.open(path, "r");
|
||||
@@ -7,8 +7,6 @@
|
||||
* @module lib/users
|
||||
*/
|
||||
"use strict";
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const libErrors = require("./errors");
|
||||
|
||||
const PlayerStats = require("./PlayerStats");
|
||||
@@ -100,8 +98,8 @@ class Role {
|
||||
*
|
||||
* Ensures the role with id 0 exisits and has the core.admin permission.
|
||||
*
|
||||
* @param {Map<number, module:lib/user.Role>} roles - role storage to modify.
|
||||
* @returns {module:lib/permission.Role} the default admin role
|
||||
* @param {Map<number, module:lib.Role>} roles - role storage to modify.
|
||||
* @returns {module:lib.Role} the default admin role
|
||||
* @static
|
||||
*/
|
||||
function ensureDefaultAdminRole(roles) {
|
||||
@@ -121,7 +119,7 @@ function ensureDefaultAdminRole(roles) {
|
||||
* assigned by default. Note that this may not be the same role as the one
|
||||
* that is assigned to new users by default.
|
||||
*
|
||||
* @param {Map<number, module:lib/user.Role>} roles - role storage to modify.
|
||||
* @param {Map<number, module:lib.Role>} roles - role storage to modify.
|
||||
* @static
|
||||
*/
|
||||
function ensureDefaultPlayerRole(roles) {
|
||||
@@ -186,7 +184,7 @@ class User {
|
||||
|
||||
/**
|
||||
* Roles this user has
|
||||
* @type {Set<module:lib/permissions.Role>}
|
||||
* @type {Set<module:lib.Role>}
|
||||
*/
|
||||
this.roles = new Set();
|
||||
if (serializedUser.roles) {
|
||||
@@ -200,7 +198,7 @@ class User {
|
||||
|
||||
/**
|
||||
* Per instance statistics for the player this user account is tied to.
|
||||
* @type {Map<number, module:lib/PlayerStats>}
|
||||
* @type {Map<number, module:lib.PlayerStats>}
|
||||
*/
|
||||
this.instanceStats = new Map(
|
||||
(serializedUser.instance_stats ? serializedUser.instance_stats : []).map(
|
||||
@@ -210,7 +208,7 @@ class User {
|
||||
|
||||
/**
|
||||
* Combined statistics for the player this user account is tied to.
|
||||
* @type {module:lib/PlayerStats}
|
||||
* @type {module:lib.PlayerStats}
|
||||
*/
|
||||
this.playerStats = this._calculatePlayerStats();
|
||||
|
||||
@@ -257,16 +255,6 @@ class User {
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate access token for this user
|
||||
*
|
||||
* @param {string} secret - Secret to sign token with.
|
||||
* @returns {string} JWT access token for the user.
|
||||
*/
|
||||
createToken(secret) {
|
||||
return jwt.sign({ aud: "user", user: this.name }, Buffer.from(secret, "base64"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate current tokens for the user
|
||||
*
|
||||
@@ -286,7 +274,7 @@ class User {
|
||||
*
|
||||
* @param {string} permission - The permission to check for.
|
||||
* @throws {Error} If the given permission does not exist.
|
||||
* @throws {module:lib/errors.PermissionError} if the user does noh have the given permission.
|
||||
* @throws {module:lib.PermissionError} if the user does noh have the given permission.
|
||||
*/
|
||||
checkPermission(permission) {
|
||||
if (!permissions.has(permission)) {
|
||||
@@ -336,7 +324,7 @@ class User {
|
||||
}
|
||||
/**
|
||||
* Set of users currently online in the cluster.
|
||||
* @type {module:lib/users.User}
|
||||
* @type {module:lib.User}
|
||||
*/
|
||||
User.onlineUsers = new Set();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* @param {JSZip} zip - Zip to search through.
|
||||
* @returns {string} name of the root folder.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
* @private
|
||||
* @inner
|
||||
*/
|
||||
@@ -3,12 +3,12 @@ import "./index.css";
|
||||
import React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
|
||||
import { libConfig, libLink, libLogging, libPlugin } from "@clusterio/lib";
|
||||
const { ConsoleTransport, WebConsoleFormat, logger } = libLogging;
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import App from "./components/App";
|
||||
import { Control, ControlConnector } from "./util/websocket";
|
||||
|
||||
const { ConsoleTransport, WebConsoleFormat, logger } = lib;
|
||||
|
||||
async function loadScript(url) {
|
||||
let script = document.createElement("script");
|
||||
@@ -73,7 +73,7 @@ async function loadPlugins(pluginInfos) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
let WebPluginClass = libPlugin.BaseWebPlugin;
|
||||
let WebPluginClass = lib.BaseWebPlugin;
|
||||
if (pluginInfo.webEntrypoint) {
|
||||
let webModule = (await pluginInfo.container.get(pluginInfo.webEntrypoint))();
|
||||
if (!webModule.WebPlugin) {
|
||||
@@ -102,9 +102,9 @@ export default async function bootstrap() {
|
||||
format: new WebConsoleFormat(),
|
||||
}));
|
||||
let pluginInfos = await loadPluginInfos();
|
||||
libLink.registerPluginMessages(pluginInfos);
|
||||
libConfig.registerPluginConfigGroups(pluginInfos);
|
||||
libConfig.finalizeConfigs();
|
||||
lib.registerPluginMessages(pluginInfos);
|
||||
lib.registerPluginConfigGroups(pluginInfos);
|
||||
lib.finalizeConfigs();
|
||||
let plugins = await loadPlugins(pluginInfos);
|
||||
|
||||
let wsUrl = new URL(window.webRoot, document.location);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
import { libLogging } from "@clusterio/lib";
|
||||
import { logger } from "@clusterio/lib";
|
||||
|
||||
import ErrorBoundary from "./ErrorBoundary";
|
||||
import SiteLayout from "./SiteLayout";
|
||||
@@ -11,7 +11,6 @@ import LoginForm from "./LoginForm";
|
||||
import { Card, ConfigProvider, Spin, Typography, theme } from "antd";
|
||||
|
||||
const { Paragraph } = Typography;
|
||||
const { logger } = libLogging;
|
||||
|
||||
|
||||
function ErrorCard(props) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button, Form, Modal, Select, Typography } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
@@ -30,7 +30,7 @@ export default function AssignInstanceModal(props) {
|
||||
|
||||
setApplying(true);
|
||||
control.send(
|
||||
new libData.InstanceAssignRequest(props.id, hostId)
|
||||
new lib.InstanceAssignRequest(props.id, hostId)
|
||||
).then(() => {
|
||||
setOpen(false);
|
||||
if (props.onFinish) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext } from "react";
|
||||
|
||||
import { libConfig, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import BaseConfigTree from "./BaseConfigTree";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -10,12 +10,12 @@ export default function ControllerConfigTree(props) {
|
||||
let control = useContext(ControlContext);
|
||||
|
||||
async function retrieveConfig() {
|
||||
let result = await control.send(new libData.ControllerConfigGetRequest());
|
||||
let result = await control.send(new lib.ControllerConfigGetRequest());
|
||||
return result.serializedConfig;
|
||||
}
|
||||
|
||||
async function setField(field, value) {
|
||||
await control.send(new libData.ControllerConfigSetFieldRequest(
|
||||
await control.send(new lib.ControllerConfigSetFieldRequest(
|
||||
field,
|
||||
String(value),
|
||||
));
|
||||
@@ -29,11 +29,11 @@ export default function ControllerConfigTree(props) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
await control.send(new libData.ControllerConfigSetPropRequest(field, prop, value));
|
||||
await control.send(new lib.ControllerConfigSetPropRequest(field, prop, value));
|
||||
}
|
||||
|
||||
return <BaseConfigTree
|
||||
ConfigClass={libConfig.ControllerConfig}
|
||||
ConfigClass={lib.ControllerConfig}
|
||||
retrieveConfig={retrieveConfig}
|
||||
setField={setField}
|
||||
setProp={setProp}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button, Form, Input, Modal } from "antd";
|
||||
|
||||
import { libFactorio, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
@@ -22,7 +22,7 @@ export default function CreateSaveModal(props) {
|
||||
if (values.exchangeString && values.exchangeString.trim()) {
|
||||
let result;
|
||||
try {
|
||||
result = libFactorio.readMapExchangeString(values.exchangeString);
|
||||
result = lib.readMapExchangeString(values.exchangeString);
|
||||
} catch (err) {
|
||||
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ export default function CreateSaveModal(props) {
|
||||
setCreatingSave(true);
|
||||
control.sendTo(
|
||||
{ instanceId: props.instance.id },
|
||||
new libData.InstanceCreateSaveRequest(name, seed, mapGenSettings, mapSettings),
|
||||
new lib.InstanceCreateSaveRequest(name, seed, mapGenSettings, mapSettings),
|
||||
).then(() => {
|
||||
form.resetFields();
|
||||
setOpen(false);
|
||||
@@ -68,7 +68,7 @@ export default function CreateSaveModal(props) {
|
||||
let exchangeString = form.getFieldValue("exchangeString");
|
||||
let result;
|
||||
try {
|
||||
result = libFactorio.readMapExchangeString(exchangeString);
|
||||
result = lib.readMapExchangeString(exchangeString);
|
||||
} catch (err) {
|
||||
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
|
||||
return;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, InputNumber, Modal, Table, Tag, Typography } from "antd";
|
||||
import CopyOutlined from "@ant-design/icons/lib/icons/CopyOutlined";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -47,7 +47,7 @@ function GenerateHostTokenButton(props) {
|
||||
form.setFields([{ name: "hostId", errors: [] }]);
|
||||
}
|
||||
|
||||
let newToken = await control.send(new libData.HostGenerateTokenRequest(id));
|
||||
let newToken = await control.send(new lib.HostGenerateTokenRequest(id));
|
||||
setToken(newToken);
|
||||
setHostId(id);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext } from "react";
|
||||
|
||||
import { libConfig, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import BaseConfigTree from "./BaseConfigTree";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -10,12 +10,12 @@ export default function InstanceConfigTree(props) {
|
||||
let control = useContext(ControlContext);
|
||||
|
||||
async function retrieveConfig() {
|
||||
let result = await control.send(new libData.InstanceConfigGetRequest(props.id));
|
||||
let result = await control.send(new lib.InstanceConfigGetRequest(props.id));
|
||||
return result.config;
|
||||
}
|
||||
|
||||
async function setField(field, value) {
|
||||
await control.send(new libData.InstanceConfigSetFieldRequest(props.id, field, value));
|
||||
await control.send(new lib.InstanceConfigSetFieldRequest(props.id, field, value));
|
||||
}
|
||||
|
||||
async function setProp(field, prop, value) {
|
||||
@@ -26,11 +26,11 @@ export default function InstanceConfigTree(props) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
await control.send(new libData.InstanceConfigSetPropRequest(props.id, field, prop, value));
|
||||
await control.send(new lib.InstanceConfigSetPropRequest(props.id, field, prop, value));
|
||||
}
|
||||
|
||||
return <BaseConfigTree
|
||||
ConfigClass={libConfig.InstanceConfig}
|
||||
ConfigClass={lib.InstanceConfig}
|
||||
retrieveConfig={retrieveConfig}
|
||||
setField={setField}
|
||||
setProp={setProp}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Input, Typography } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
@@ -24,7 +24,7 @@ export default function InstanceRcon(props) {
|
||||
try {
|
||||
let result = await control.sendTo(
|
||||
{ instanceId: props.id },
|
||||
new libData.InstanceSendRconRequest(command),
|
||||
new lib.InstanceSendRconRequest(command),
|
||||
);
|
||||
setOutput(result);
|
||||
} finally {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Alert, Button, Descriptions, Dropdown, Menu, Modal, Space, Spin, Typogr
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
import DownOutlined from "@ant-design/icons/DownOutlined";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -134,7 +134,7 @@ export default function InstanceViewPage(props) {
|
||||
setExportingData(true);
|
||||
control.sendTo(
|
||||
{ instanceId },
|
||||
new libData.InstanceExportDataRequest(),
|
||||
new lib.InstanceExportDataRequest(),
|
||||
).catch(
|
||||
notifyErrorHandler("Error exporting data")
|
||||
).finally(() => {
|
||||
@@ -144,13 +144,13 @@ export default function InstanceViewPage(props) {
|
||||
} else if (key === "extract") {
|
||||
control.sendTo(
|
||||
{ instanceId },
|
||||
new libData.InstanceExtractPlayersRequest(),
|
||||
new lib.InstanceExtractPlayersRequest(),
|
||||
).catch(notifyErrorHandler("Error extracting player data"));
|
||||
|
||||
} else if (key === "kill") {
|
||||
control.sendTo(
|
||||
{ instanceId },
|
||||
new libData.InstanceKillRequest(),
|
||||
new lib.InstanceKillRequest(),
|
||||
).catch(notifyErrorHandler("Error killing instance"));
|
||||
|
||||
} else if (key === "delete") {
|
||||
@@ -161,7 +161,7 @@ export default function InstanceViewPage(props) {
|
||||
okButtonProps: { danger: true },
|
||||
onOk: () => {
|
||||
control.send(
|
||||
new libData.InstanceDeleteRequest(instanceId)
|
||||
new lib.InstanceDeleteRequest(instanceId)
|
||||
).then(() => {
|
||||
navigate("/instances");
|
||||
}).catch(notifyErrorHandler("Error deleting instance"));
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useContext, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal } from "antd";
|
||||
|
||||
import { libConfig, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -26,11 +26,11 @@ function CreateInstanceButton(props) {
|
||||
return;
|
||||
}
|
||||
|
||||
let instanceConfig = new libConfig.InstanceConfig("control");
|
||||
let instanceConfig = new lib.InstanceConfig("control");
|
||||
await instanceConfig.init();
|
||||
instanceConfig.set("instance.name", values.instanceName);
|
||||
let serializedConfig = instanceConfig.serialize("controller");
|
||||
await control.send(new libData.InstanceCreateRequest(serializedConfig));
|
||||
await control.send(new lib.InstanceCreateRequest(serializedConfig));
|
||||
setOpen(false);
|
||||
navigate(`/instances/${instanceConfig.get("instance.id")}/view`);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export default function InstancesPage() {
|
||||
&& <Button onClick={e => instanceList.forEach(instance => {
|
||||
if (instance.status === "stopped") {
|
||||
control.send(
|
||||
new libData.InstanceStartRequest(undefined), { instanceId: instance.id }
|
||||
new lib.InstanceStartRequest(undefined), { instanceId: instance.id }
|
||||
).catch(notifyErrorHandler("Error starting instance"));
|
||||
}
|
||||
})
|
||||
@@ -85,7 +85,7 @@ export default function InstancesPage() {
|
||||
if (["starting", "running"].includes(instance.status)) {
|
||||
control.sendTo(
|
||||
{ instanceId: instance.id },
|
||||
new libData.InstanceStopRequest(),
|
||||
new lib.InstanceStopRequest(),
|
||||
).catch(notifyErrorHandler("Error stopping instance"));
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button, Form, Input, Modal } from "antd";
|
||||
|
||||
import { libFactorio, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
@@ -22,7 +22,7 @@ export default function LoadScenarioModal(props) {
|
||||
if (values.exchangeString && values.exchangeString.trim()) {
|
||||
let result;
|
||||
try {
|
||||
result = libFactorio.readMapExchangeString(values.exchangeString);
|
||||
result = lib.readMapExchangeString(values.exchangeString);
|
||||
} catch (err) {
|
||||
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ export default function LoadScenarioModal(props) {
|
||||
setLoadingScenario(true);
|
||||
control.sendTo(
|
||||
{ instanceId: props.instance.id },
|
||||
new libData.InstanceLoadScenarioRequest(scenario, seed, mapGenSettings, mapSettings),
|
||||
new lib.InstanceLoadScenarioRequest(scenario, seed, mapGenSettings, mapSettings),
|
||||
).then(() => {
|
||||
setOpen(false);
|
||||
}).catch(
|
||||
@@ -67,7 +67,7 @@ export default function LoadScenarioModal(props) {
|
||||
let exchangeString = form.getFieldValue("exchangeString");
|
||||
let result;
|
||||
try {
|
||||
result = libFactorio.readMapExchangeString(exchangeString);
|
||||
result = lib.readMapExchangeString(exchangeString);
|
||||
} catch (err) {
|
||||
form.setFields([{ name: "exchangeString", errors: [err.message] }]);
|
||||
return;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useContext, useRef, useState } from "react";
|
||||
import { Typography } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -70,7 +70,7 @@ export default function LogConsole(props) {
|
||||
|
||||
if (account.hasPermission("core.log.query")) {
|
||||
setPastLines([<span key={0}>{"Loading past entries..."}<br/></span>]);
|
||||
control.send(new libData.LogQueryRequest(
|
||||
control.send(new lib.LogQueryRequest(
|
||||
logFilter.all,
|
||||
logFilter.controller,
|
||||
logFilter.hostIds,
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Fragment } from "react";
|
||||
import { Descriptions, Grid, Typography } from "antd";
|
||||
import ExclamationCircleOutlined from "@ant-design/icons/ExclamationCircleOutlined";
|
||||
|
||||
import { libHelpers } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { useBreakpoint } = Grid;
|
||||
|
||||
@@ -39,7 +39,7 @@ export default function ModDetails(props) {
|
||||
}
|
||||
{mod.filename && <Descriptions.Item label="Filename">{mod.filename}</Descriptions.Item>}
|
||||
{mod.size !== undefined
|
||||
&& <Descriptions.Item label="Size">{libHelpers.formatBytes(mod.size)}</Descriptions.Item>
|
||||
&& <Descriptions.Item label="Size">{lib.formatBytes(mod.size)}</Descriptions.Item>
|
||||
}
|
||||
{mod.sha1 && <Descriptions.Item label="SHA1" span={2}>{mod.sha1}</Descriptions.Item>}
|
||||
{mod.dependencies && mod.dependencies.length
|
||||
|
||||
@@ -4,16 +4,14 @@ import {
|
||||
Button, Card, Checkbox, Col, ConfigProvider, Descriptions, Form, Input, Pagination,
|
||||
Popconfirm, Row, Table, Tag, Typography, Select, Skeleton, Space, Spin, Switch, Modal, Tooltip,
|
||||
} from "antd";
|
||||
import InfoCircleOutlined from "@ant-design/icons/InfoCircleOutlined";
|
||||
import ExportOutlined from "@ant-design/icons/ExportOutlined";
|
||||
import FileUnknownOutlined from "@ant-design/icons/FileUnknownOutlined";
|
||||
import FileExclamationOutlined from "@ant-design/icons/FileExclamationOutlined";
|
||||
import CloseOutlined from "@ant-design/icons/CloseOutlined";
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
import PlusOutlined from "@ant-design/icons/PlusOutlined";
|
||||
import UploadOutlined from "@ant-design/icons/UploadOutlined";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import ControlContext from "./ControlContext";
|
||||
import { useAccount } from "../model/account";
|
||||
import { useModPack } from "../model/mod_pack";
|
||||
@@ -25,7 +23,7 @@ import PageLayout from "./PageLayout";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import ModDetails from "./ModDetails";
|
||||
|
||||
const { logger } = libLogging;
|
||||
const { logger } = lib;
|
||||
const { Paragraph, Text } = Typography;
|
||||
const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare;
|
||||
|
||||
@@ -44,7 +42,7 @@ function SearchModsTable(props) {
|
||||
|
||||
useEffect(() => {
|
||||
let canceled = false;
|
||||
control.send(new libData.ModSearchRequest(
|
||||
control.send(new lib.ModSearchRequest(
|
||||
searchText,
|
||||
factorioVersion,
|
||||
modResultPage,
|
||||
@@ -535,7 +533,7 @@ function ExportButton(props) {
|
||||
function useExportedAsset(modPack, asset) {
|
||||
let [assetData, setAssetData] = useState(asset === "locale" ? new Map() : {});
|
||||
let assetFilename;
|
||||
if (modPack instanceof libData.ModPack && modPack.exportManifest && modPack.exportManifest.assets[asset]) {
|
||||
if (modPack instanceof lib.ModPack && modPack.exportManifest && modPack.exportManifest.assets[asset]) {
|
||||
assetFilename = modPack.exportManifest.assets[asset];
|
||||
}
|
||||
useEffect(() => {
|
||||
@@ -612,7 +610,7 @@ export default function ModPackViewPage() {
|
||||
let syncTimeout = useRef();
|
||||
|
||||
let modifiedModPack;
|
||||
if (!(modPack instanceof libData.ModPack)) {
|
||||
if (!(modPack instanceof lib.ModPack)) {
|
||||
// Loading or invalid id
|
||||
modifiedModPack = modPack;
|
||||
|
||||
@@ -707,7 +705,7 @@ export default function ModPackViewPage() {
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => {
|
||||
control.send(
|
||||
new libData.ModPackDeleteRequest(modPack.id)
|
||||
new lib.ModPackDeleteRequest(modPack.id)
|
||||
).then(() => {
|
||||
navigate("/mods");
|
||||
}).catch(notifyErrorHandler("Error deleting mod pack"));
|
||||
@@ -802,7 +800,7 @@ export default function ModPackViewPage() {
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.ModPackUpdateRequest(modifiedModPack)
|
||||
new lib.ModPackUpdateRequest(modifiedModPack)
|
||||
).then(() => {
|
||||
form.resetFields();
|
||||
setChanges([]);
|
||||
|
||||
@@ -5,7 +5,7 @@ import ImportOutlined from "@ant-design/icons/ImportOutlined";
|
||||
import PlusOutlined from "@ant-design/icons/PlusOutlined";
|
||||
import UploadOutlined from "@ant-design/icons/UploadOutlined";
|
||||
|
||||
import { libData, libHelpers, libLogging } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import { useModList } from "../model/mods";
|
||||
@@ -20,8 +20,6 @@ import ModDetails from "./ModDetails";
|
||||
|
||||
const strcmp = new Intl.Collator(undefined, { numerice: "true", sensitivity: "base" }).compare;
|
||||
|
||||
const { logger } = libLogging;
|
||||
|
||||
|
||||
function ImportModPackButton() {
|
||||
let control = useContext(ControlContext);
|
||||
@@ -47,8 +45,8 @@ function ImportModPackButton() {
|
||||
} catch {
|
||||
return; // Validation failed
|
||||
}
|
||||
const modPack = libData.ModPack.fromModPackString(values.string);
|
||||
await control.send(new libData.ModPackCreateRequest(modPack));
|
||||
const modPack = lib.ModPack.fromModPackString(values.string);
|
||||
await control.send(new lib.ModPackCreateRequest(modPack));
|
||||
navigate(`/mods/mod-packs/${modPack.id}/view`);
|
||||
})().catch(notifyErrorHandler("Error creating mod pack"));
|
||||
}}
|
||||
@@ -60,7 +58,7 @@ function ImportModPackButton() {
|
||||
{ required: true },
|
||||
{ async validator(rule, value) {
|
||||
if (value) {
|
||||
libData.ModPack.fromModPackString(value);
|
||||
lib.ModPack.fromModPackString(value);
|
||||
}
|
||||
}},
|
||||
]}
|
||||
@@ -96,11 +94,11 @@ function CreateModPackButton() {
|
||||
} catch {
|
||||
return; // Validation failed
|
||||
}
|
||||
const modPack = libData.ModPack.fromJSON({});
|
||||
const modPack = lib.ModPack.fromJSON({});
|
||||
modPack.name = values.name;
|
||||
modPack.factorioVersion = values.factorioVersion;
|
||||
if (values.description) { modPack.description = values.description; }
|
||||
await control.send(new libData.ModPackCreateRequest(modPack.toJSON()));
|
||||
await control.send(new lib.ModPackCreateRequest(modPack.toJSON()));
|
||||
navigate(`/mods/mod-packs/${modPack.id}/view`);
|
||||
})().catch(notifyErrorHandler("Error creating mod pack"));
|
||||
}}
|
||||
@@ -141,7 +139,7 @@ export default function ModsPage() {
|
||||
&& <Typography.Link
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.ModDownloadRequest(mod.name, mod.version)
|
||||
new lib.ModDownloadRequest(mod.name, mod.version)
|
||||
).then(streamId => {
|
||||
let url = new URL(webRoot, document.location);
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
@@ -157,7 +155,7 @@ export default function ModsPage() {
|
||||
title={`Delete ${mod.name}_${mod.version}.zip?`}
|
||||
onConfirm={event => {
|
||||
control.send(
|
||||
new libData.ModDeleteRequest(mod.name, mod.version)
|
||||
new lib.ModDeleteRequest(mod.name, mod.version)
|
||||
).catch(notifyErrorHandler("Error deleting mod"));
|
||||
}}
|
||||
okText="Delete"
|
||||
@@ -251,7 +249,7 @@ export default function ModsPage() {
|
||||
title: "Size",
|
||||
key: "size",
|
||||
responsive: ["lg"],
|
||||
render: mod => libHelpers.formatBytes(mod.size),
|
||||
render: mod => lib.formatBytes(mod.size),
|
||||
align: "right",
|
||||
sorter: (a, b) => a.size - b.size,
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Button, Checkbox, Form, Input, Popconfirm, Spin } from "antd";
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
|
||||
import { libData, libUsers } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -19,7 +19,7 @@ function useRole(id) {
|
||||
|
||||
function updateRole() {
|
||||
// XXX optimize by requesting only the role in question
|
||||
control.send(new libData.RoleListRequest()).then(roles => {
|
||||
control.send(new lib.RoleListRequest()).then(roles => {
|
||||
let match = roles.find(u => u.id === id);
|
||||
if (!match) {
|
||||
setRole({ missing: true });
|
||||
@@ -70,7 +70,7 @@ export default function RoleViewPage() {
|
||||
name: role["name"],
|
||||
description: role["description"],
|
||||
permissions: {
|
||||
...Object.fromEntries([...libUsers.permissions.values()].map(perm => [
|
||||
...Object.fromEntries([...lib.permissions.values()].map(perm => [
|
||||
perm.name, role["permissions"].includes(perm.name),
|
||||
])),
|
||||
},
|
||||
@@ -88,7 +88,7 @@ export default function RoleViewPage() {
|
||||
}
|
||||
|
||||
control.send(
|
||||
new libData.RoleUpdateRequest(roleId, values.name || "", values.description || "", newPermissions)
|
||||
new lib.RoleUpdateRequest(roleId, values.name || "", values.description || "", newPermissions)
|
||||
).then(() => {
|
||||
setEdited(false);
|
||||
updateRole();
|
||||
@@ -106,7 +106,7 @@ export default function RoleViewPage() {
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => {
|
||||
control.send(
|
||||
new libData.RoleDeleteRequest(roleId)
|
||||
new lib.RoleDeleteRequest(roleId)
|
||||
).then(() => {
|
||||
navigate("/roles");
|
||||
}).catch(notifyErrorHandler("Error deleting role"));
|
||||
@@ -125,7 +125,7 @@ export default function RoleViewPage() {
|
||||
<Input disabled={!canUpdate}/>
|
||||
</Form.Item>
|
||||
<h3>Permissions</h3>
|
||||
{[...libUsers.permissions.values()].map(({name, title, description}) => (
|
||||
{[...lib.permissions.values()].map(({name, title, description}) => (
|
||||
<Form.Item
|
||||
name={["permissions", name]}
|
||||
key={name}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useContext, useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal, Table } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -28,7 +28,7 @@ function CreateRoleButton() {
|
||||
}
|
||||
|
||||
let result = await control.send(
|
||||
new libData.RoleCreateRequest(values.roleName, values.description || "", [])
|
||||
new lib.RoleCreateRequest(values.roleName, values.description || "", [])
|
||||
);
|
||||
setOpen(false);
|
||||
navigate(`/roles/${result.id}/view`);
|
||||
@@ -67,7 +67,7 @@ export default function RolesPage() {
|
||||
let [roles, setRoles] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
control.send(new libData.RoleListRequest()).then(newRoles => {
|
||||
control.send(new lib.RoleListRequest()).then(newRoles => {
|
||||
setRoles(newRoles);
|
||||
}).catch(notifyErrorHandler("Error fetching role list"));
|
||||
}, []);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import CaretLeftOutlined from "@ant-design/icons/CaretLeftOutlined";
|
||||
import LeftOutlined from "@ant-design/icons/LeftOutlined";
|
||||
|
||||
import { libData, libHelpers } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -37,7 +37,7 @@ function RenameModal(props) {
|
||||
initialValues={{ newName: props.save.name }}
|
||||
onFinish={values => {
|
||||
control.send(
|
||||
new libData.InstanceRenameSaveRequest(props.instanceId, props.save.name, values.newName)
|
||||
new lib.InstanceRenameSaveRequest(props.instanceId, props.save.name, values.newName)
|
||||
).then(() => {
|
||||
setOpen(false);
|
||||
form.resetFields();
|
||||
@@ -76,7 +76,7 @@ function CopyModal(props) {
|
||||
initialValues={{ newName: props.save.name }}
|
||||
onFinish={values => {
|
||||
control.send(
|
||||
new libData.InstanceCopySaveRequest(props.instanceId, props.save.name, values.newName)
|
||||
new lib.InstanceCopySaveRequest(props.instanceId, props.save.name, values.newName)
|
||||
).then(() => {
|
||||
setOpen(false);
|
||||
form.resetFields();
|
||||
@@ -120,7 +120,7 @@ function TransferModal(props) {
|
||||
onFinish={values => {
|
||||
setOpen(false);
|
||||
let hide = message.loading("Transferring save...", 0);
|
||||
control.send(new libData.InstanceTransferSaveRequest(
|
||||
control.send(new lib.InstanceTransferSaveRequest(
|
||||
props.instanceId,
|
||||
props.save.name,
|
||||
values.targetInstanceId,
|
||||
@@ -203,7 +203,7 @@ export default function SavesList(props) {
|
||||
title: "Size",
|
||||
key: "size",
|
||||
responsive: ["sm"],
|
||||
render: save => libHelpers.formatBytes(save.size),
|
||||
render: save => lib.formatBytes(save.size),
|
||||
align: "right",
|
||||
sorter: (a, b) => a.size - b.size,
|
||||
},
|
||||
@@ -229,7 +229,7 @@ export default function SavesList(props) {
|
||||
setStarting(true);
|
||||
control.sendTo(
|
||||
{ instanceId: props.instance.id },
|
||||
new libData.InstanceStartRequest(save.name),
|
||||
new lib.InstanceStartRequest(save.name),
|
||||
).catch(
|
||||
notifyErrorHandler("Error loading save")
|
||||
).finally(
|
||||
@@ -247,7 +247,7 @@ export default function SavesList(props) {
|
||||
disabled={hostOffline}
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.InstanceDownloadSaveRequest(props.instance.id, save.name)
|
||||
new lib.InstanceDownloadSaveRequest(props.instance.id, save.name)
|
||||
).then(streamId => {
|
||||
let url = new URL(webRoot, document.location);
|
||||
url.pathname += `api/stream/${streamId}`;
|
||||
@@ -267,7 +267,7 @@ export default function SavesList(props) {
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => {
|
||||
control.send(
|
||||
new libData.InstanceDeleteSaveRequest(props.instance.id, save.name)
|
||||
new lib.InstanceDeleteSaveRequest(props.instance.id, save.name)
|
||||
).catch(notifyErrorHandler("Error deleting save"));
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useContext, useState } from "react";
|
||||
import { Button } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "./ControlContext";
|
||||
import { notifyErrorHandler } from "../util/notify";
|
||||
@@ -18,7 +18,7 @@ export default function StartStopInstanceButton(props) {
|
||||
if (props.instance["status"] === "stopped") {
|
||||
action = control.sendTo(
|
||||
{ instanceId: props.instance["id"] },
|
||||
new libData.InstanceStartRequest(undefined),
|
||||
new lib.InstanceStartRequest(undefined),
|
||||
).catch(
|
||||
notifyErrorHandler("Error starting instance")
|
||||
);
|
||||
@@ -26,7 +26,7 @@ export default function StartStopInstanceButton(props) {
|
||||
} else if (["starting", "running"].includes(props.instance["status"])) {
|
||||
action = control.sendTo(
|
||||
{ instanceId: props.instance["id"] },
|
||||
new libData.InstanceStopRequest(),
|
||||
new lib.InstanceStopRequest(),
|
||||
).catch(
|
||||
notifyErrorHandler("Error stopping instance")
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
} from "antd";
|
||||
import DeleteOutlined from "@ant-design/icons/DeleteOutlined";
|
||||
|
||||
import { libErrors, libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import { useInstanceList } from "../model/instance";
|
||||
@@ -43,7 +43,7 @@ export default function UserViewPage() {
|
||||
let [rolesError, setRolesError] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
control.send(new libData.RoleListRequest()).then(newRoles => {
|
||||
control.send(new lib.RoleListRequest()).then(newRoles => {
|
||||
setRoles(new Map(newRoles.map(role => [role.id, role])));
|
||||
}).catch(() => {
|
||||
setRoles(new Map());
|
||||
@@ -122,11 +122,11 @@ export default function UserViewPage() {
|
||||
danger
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserRevokeTokenRequest(userName)
|
||||
new lib.UserRevokeTokenRequest(userName)
|
||||
).then(() => {
|
||||
notify("User token revoked");
|
||||
}, err => {
|
||||
if (err instanceof libErrors.SessionLost && userName === account.name) {
|
||||
if (err instanceof lib.SessionLost && userName === account.name) {
|
||||
// Got kicked out after revoking our own token
|
||||
notify("User token revoked");
|
||||
return;
|
||||
@@ -145,7 +145,7 @@ export default function UserViewPage() {
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => {
|
||||
control.send(
|
||||
new libData.UserDeleteRequest(userName)
|
||||
new lib.UserDeleteRequest(userName)
|
||||
).then(() => {
|
||||
navigate("/users");
|
||||
}).catch(notifyErrorHandler("Error deleting user"));
|
||||
@@ -195,7 +195,7 @@ export default function UserViewPage() {
|
||||
let newRoles = form.getFieldValue("roles");
|
||||
setApplyingRoles(true);
|
||||
control.send(
|
||||
new libData.UserUpdateRolesRequest(userName, newRoles)
|
||||
new lib.UserUpdateRolesRequest(userName, newRoles)
|
||||
).then(() => {
|
||||
setRolesDirty(false);
|
||||
setRolesError();
|
||||
@@ -215,7 +215,7 @@ export default function UserViewPage() {
|
||||
checked={user.isAdmin}
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserSetAdminRequest(userName, false, !user.isAdmin)
|
||||
new lib.UserSetAdminRequest(userName, false, !user.isAdmin)
|
||||
).catch(notifyErrorHandler("Error toggling user admin status"));
|
||||
}}
|
||||
/>
|
||||
@@ -225,7 +225,7 @@ export default function UserViewPage() {
|
||||
checked={user.isWhitelisted}
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserSetWhitelistedRequest(userName, false, !user.isWhitelisted)
|
||||
new lib.UserSetWhitelistedRequest(userName, false, !user.isWhitelisted)
|
||||
).catch(notifyErrorHandler("Error toggling user whitelisted status"));
|
||||
}}
|
||||
/>
|
||||
@@ -249,7 +249,7 @@ export default function UserViewPage() {
|
||||
type={banReasonDirty ? "primary" : "default"}
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserSetBannedRequest(
|
||||
new lib.UserSetBannedRequest(
|
||||
userName, false, true, form.getFieldValue("banReason")
|
||||
)
|
||||
).then(() => {
|
||||
@@ -260,7 +260,7 @@ export default function UserViewPage() {
|
||||
<Button
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserSetBannedRequest(userName, false, false, "")
|
||||
new lib.UserSetBannedRequest(userName, false, false, "")
|
||||
).catch(notifyErrorHandler("Error unbanning user"));
|
||||
}}
|
||||
>Unban</Button>
|
||||
@@ -269,7 +269,7 @@ export default function UserViewPage() {
|
||||
type={banReasonDirty ? "primary" : "default"}
|
||||
onClick={() => {
|
||||
control.send(
|
||||
new libData.UserSetBannedRequest(
|
||||
new lib.UserSetBannedRequest(
|
||||
userName, false, true, form.getFieldValue("banReason")
|
||||
)
|
||||
).then(() => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect, useContext, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Form, Input, Modal, Space, Table, Tag } from "antd";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import { useAccount } from "../model/account";
|
||||
import ControlContext from "./ControlContext";
|
||||
@@ -29,7 +29,7 @@ function CreateUserButton() {
|
||||
return;
|
||||
}
|
||||
|
||||
await control.send(new libData.UserCreateRequest(values.userName));
|
||||
await control.send(new lib.UserCreateRequest(values.userName));
|
||||
setOpen(false);
|
||||
navigate(`/users/${values.userName}/view`);
|
||||
}
|
||||
@@ -65,7 +65,7 @@ export default function UsersPage() {
|
||||
let [roles, setRoles] = useState(new Map());
|
||||
|
||||
useEffect(() => {
|
||||
control.send(new libData.RoleListRequest()).then(newRoles => {
|
||||
control.send(new lib.RoleListRequest()).then(newRoles => {
|
||||
setRoles(new Map(newRoles.map(role => [role.id, role])));
|
||||
}).catch(() => {
|
||||
// ignore
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useContext, useState } from "react";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export function useExportManifest() {
|
||||
let [exportManifest, setExportManifest] = useState(exportManifestCache || emptyCache);
|
||||
useEffect(() => {
|
||||
async function load() {
|
||||
let modPack = await control.send(new libData.ModPackGetDefaultRequest());
|
||||
let modPack = await control.send(new lib.ModPackGetDefaultRequest());
|
||||
if (modPack.exportManifest) {
|
||||
exportManifestCache = modPack.exportManifest;
|
||||
setExportManifest(exportManifestCache);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useContext, useState } from "react";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
import { libData } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
export function useHost(id) {
|
||||
@@ -10,7 +10,7 @@ export function useHost(id) {
|
||||
|
||||
function updateHost() {
|
||||
// XXX optimize by requesting only the host in question
|
||||
control.send(new libData.HostListRequest()).then(hosts => {
|
||||
control.send(new lib.HostListRequest()).then(hosts => {
|
||||
let match = hosts.find(i => i.id === id);
|
||||
if (!match) {
|
||||
setHost({ missing: true });
|
||||
@@ -45,7 +45,7 @@ export function useHostList() {
|
||||
let [hostList, setHostList] = useState([]);
|
||||
|
||||
function updateHostList() {
|
||||
control.send(new libData.HostListRequest()).then(hosts => {
|
||||
control.send(new lib.HostListRequest()).then(hosts => {
|
||||
setHostList(hosts);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useEffect, useContext, useState } from "react";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
const { logger } = libLogging;
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { logger } = lib;
|
||||
|
||||
export function useInstance(id) {
|
||||
let control = useContext(ControlContext);
|
||||
let [instance, setInstance] = useState({ loading: true });
|
||||
|
||||
function updateInstance() {
|
||||
control.send(new libData.InstanceDetailsGetRequest(id)).then(updatedInstance => {
|
||||
control.send(new lib.InstanceDetailsGetRequest(id)).then(updatedInstance => {
|
||||
setInstance({ ...updatedInstance, present: true });
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to get instance: ${err}`);
|
||||
@@ -44,7 +44,7 @@ export function useInstanceList() {
|
||||
let [instanceList, setInstanceList] = useState([]);
|
||||
|
||||
function updateInstanceList() {
|
||||
control.send(new libData.InstanceDetailsListRequest()).then(instances => {
|
||||
control.send(new lib.InstanceDetailsListRequest()).then(instances => {
|
||||
setInstanceList(instances);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to list instances:\n${err}`);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
const { logger } = libLogging;
|
||||
const { logger } = lib;
|
||||
|
||||
export function useModPack(id) {
|
||||
let control = useContext(ControlContext);
|
||||
let [modPack, setModPack] = useState({ loading: true });
|
||||
|
||||
function updateModPack() {
|
||||
control.send(new libData.ModPackGetRequest(id)).then(updatedModPack => {
|
||||
control.send(new lib.ModPackGetRequest(id)).then(updatedModPack => {
|
||||
setModPack(updatedModPack);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to get mod pack: ${err}`);
|
||||
@@ -40,7 +40,7 @@ export function useModPackList() {
|
||||
let [modPackList, setModPackList] = useState([]);
|
||||
|
||||
function updateModPackList() {
|
||||
control.send(new libData.ModPackListRequest()).then(modPacks => {
|
||||
control.send(new lib.ModPackListRequest()).then(modPacks => {
|
||||
setModPackList(modPacks);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to list mod packs:\n${err}`);
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
const { logger } = libLogging;
|
||||
|
||||
const { logger } = lib;
|
||||
|
||||
export function useModList() {
|
||||
let control = useContext(ControlContext);
|
||||
let [modList, setModList] = useState([]);
|
||||
|
||||
function updateModList() {
|
||||
control.send(new libData.ModListRequest()).then(mods => {
|
||||
control.send(new lib.ModListRequest()).then(mods => {
|
||||
setModList(mods);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to list mods:\n${err}`);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useEffect, useContext, useState } from "react";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
const { logger } = libLogging;
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { logger } = lib;
|
||||
|
||||
export function useSaves(instanceId) {
|
||||
let control = useContext(ControlContext);
|
||||
let [saves, setSaves] = useState([]);
|
||||
|
||||
function updateSaves() {
|
||||
control.sendTo({ instanceId }, new libData.InstanceListSavesRequest()).then(updatedSaves => {
|
||||
control.sendTo({ instanceId }, new lib.InstanceListSavesRequest()).then(updatedSaves => {
|
||||
setSaves(updatedSaves);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to list instance saves: ${err}`);
|
||||
|
||||
@@ -2,8 +2,9 @@ import React, { useEffect, useContext, useState } from "react";
|
||||
import { Tag } from "antd";
|
||||
import ControlContext from "../components/ControlContext";
|
||||
|
||||
import { libData, libLogging } from "@clusterio/lib";
|
||||
const { logger } = libLogging;
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { logger } = lib;
|
||||
|
||||
function calculateLastSeen(user, instanceId) {
|
||||
let stats;
|
||||
@@ -56,7 +57,7 @@ export function useUser(name) {
|
||||
let [user, setUser] = useState({ loading: true });
|
||||
|
||||
function updateUser() {
|
||||
control.send(new libData.UserGetRequest(name)).then(updatedUser => {
|
||||
control.send(new lib.UserGetRequest(name)).then(updatedUser => {
|
||||
setUser({ ...updatedUser, present: true });
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to get user: ${err}`);
|
||||
@@ -90,7 +91,7 @@ export function useUserList() {
|
||||
let [userList, setUserList] = useState([]);
|
||||
|
||||
function updateUserList() {
|
||||
control.send(new libData.UserListRequest()).then(users => {
|
||||
control.send(new lib.UserListRequest()).then(users => {
|
||||
setUserList(users);
|
||||
}).catch(err => {
|
||||
logger.error(`Failed to list users:\n${err}`);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { notification } from "antd";
|
||||
import { libLogging } from "@clusterio/lib";
|
||||
const { logger } = libLogging;
|
||||
import { logger } from "@clusterio/lib";
|
||||
|
||||
|
||||
export default function notify(message, type = "info", description = undefined) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { libData, libErrors, libLink, libLogging, libPlugin } from "@clusterio/lib";
|
||||
const { logFilter, logger } = libLogging;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import packageJson from "../../package.json";
|
||||
|
||||
const { logFilter, logger } = lib;
|
||||
|
||||
/**
|
||||
* Connector for control connection to controller
|
||||
* @private
|
||||
*/
|
||||
export class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
export class ControlConnector extends lib.WebSocketClientConnector {
|
||||
constructor(url, maxReconnectDelay) {
|
||||
super(url, maxReconnectDelay);
|
||||
this.token = null;
|
||||
@@ -20,8 +20,8 @@ export class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
|
||||
logger.verbose("Connector | registering control");
|
||||
this.sendHandshake(
|
||||
new libData.MessageRegisterControl(
|
||||
new libData.RegisterControlData(
|
||||
new lib.MessageRegisterControl(
|
||||
new lib.RegisterControlData(
|
||||
this.token,
|
||||
"Clusterio Web UI",
|
||||
packageJson.version,
|
||||
@@ -37,13 +37,13 @@ export class ControlConnector extends libLink.WebSocketClientConnector {
|
||||
* Connects to the controller over WebSocket and sends commands to it.
|
||||
* @static
|
||||
*/
|
||||
export class Control extends libLink.Link {
|
||||
export class Control extends lib.Link {
|
||||
constructor(connector, plugins) {
|
||||
super(connector);
|
||||
|
||||
/**
|
||||
* Mapping of plugin names to their instance for loaded plugins.
|
||||
* @type {Map<string, module:lib/plugin.BaseWebPlugin>}
|
||||
* @type {Map<string, module:lib.BaseWebPlugin>}
|
||||
*/
|
||||
this.plugins = plugins;
|
||||
for (let plugin of plugins.values()) {
|
||||
@@ -118,15 +118,15 @@ export class Control extends libLink.Link {
|
||||
});
|
||||
}
|
||||
|
||||
this.handle(libData.AccountUpdateEvent, this.handleAccountUpdateEvent.bind(this));
|
||||
this.handle(libData.HostUpdateEvent, this.handleHostUpdateEvent.bind(this));
|
||||
this.handle(libData.InstanceDetailsUpdateEvent, this.handleInstanceDetailsUpdateEvent.bind(this));
|
||||
this.handle(libData.InstanceSaveListUpdateEvent, this.handleInstanceSaveListUpdateEvent.bind(this));
|
||||
this.handle(libData.ModPackUpdateEvent, this.handleModPackUpdateEvent.bind(this));
|
||||
this.handle(libData.ModUpdateEvent, this.handleModUpdateEvent.bind(this));
|
||||
this.handle(libData.UserUpdateEvent, this.handleUserUpdateEvent.bind(this));
|
||||
this.handle(libData.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(libData.DebugWsMessageEvent, this.handleDebugWsMessageEvent.bind(this));
|
||||
this.handle(lib.AccountUpdateEvent, this.handleAccountUpdateEvent.bind(this));
|
||||
this.handle(lib.HostUpdateEvent, this.handleHostUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceDetailsUpdateEvent, this.handleInstanceDetailsUpdateEvent.bind(this));
|
||||
this.handle(lib.InstanceSaveListUpdateEvent, this.handleInstanceSaveListUpdateEvent.bind(this));
|
||||
this.handle(lib.ModPackUpdateEvent, this.handleModPackUpdateEvent.bind(this));
|
||||
this.handle(lib.ModUpdateEvent, this.handleModUpdateEvent.bind(this));
|
||||
this.handle(lib.UserUpdateEvent, this.handleUserUpdateEvent.bind(this));
|
||||
this.handle(lib.LogMessageEvent, this.handleLogMessageEvent.bind(this));
|
||||
this.handle(lib.DebugWsMessageEvent, this.handleDebugWsMessageEvent.bind(this));
|
||||
}
|
||||
|
||||
async handleAccountUpdateEvent(event) {
|
||||
@@ -206,7 +206,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.HostSetSubscriptionsRequest(
|
||||
await this.send(new lib.HostSetSubscriptionsRequest(
|
||||
this.hostUpdateHandlers.has(null),
|
||||
[...this.hostUpdateHandlers.keys()].filter(e => e !== null),
|
||||
));
|
||||
@@ -263,7 +263,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.InstanceDetailsSetSubscriptionsRequest(
|
||||
await this.send(new lib.InstanceDetailsSetSubscriptionsRequest(
|
||||
this.instanceUpdateHandlers.has(null),
|
||||
[...this.instanceUpdateHandlers.keys()].filter(e => e !== null),
|
||||
));
|
||||
@@ -317,7 +317,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.InstanceSetSaveListSubscriptionsRequest(
|
||||
await this.send(new lib.InstanceSetSaveListSubscriptionsRequest(
|
||||
false,
|
||||
[...this.saveListUpdateHandlers.keys()],
|
||||
));
|
||||
@@ -375,7 +375,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.ModPackSetSubscriptionsRequest(
|
||||
await this.send(new lib.ModPackSetSubscriptionsRequest(
|
||||
this.modPackUpdateHandlers.has(null),
|
||||
[...this.modPackUpdateHandlers.keys()].filter(k => k !== null),
|
||||
));
|
||||
@@ -433,7 +433,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.ModSetSubscriptionsRequest(
|
||||
await this.send(new lib.ModSetSubscriptionsRequest(
|
||||
this.modUpdateHandlers.has(null),
|
||||
[...this.modUpdateHandlers.keys()].filter(k => k !== null),
|
||||
));
|
||||
@@ -490,7 +490,7 @@ export class Control extends libLink.Link {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.send(new libData.UserSetSubscriptionsRequest(
|
||||
await this.send(new lib.UserSetSubscriptionsRequest(
|
||||
this.userUpdateHandlers.has(null),
|
||||
[...this.userUpdateHandlers.keys()].filter(e => e !== null),
|
||||
));
|
||||
@@ -565,7 +565,7 @@ export class Control extends libLink.Link {
|
||||
}
|
||||
}
|
||||
|
||||
await this.send(new libData.LogSetSubscriptionsRequest(all, controller, hostIds, instanceIds, null));
|
||||
await this.send(new lib.LogSetSubscriptionsRequest(all, controller, hostIds, instanceIds, null));
|
||||
}
|
||||
|
||||
async handleDebugWsMessageEvent(message) {
|
||||
@@ -577,7 +577,7 @@ export class Control extends libLink.Link {
|
||||
try {
|
||||
await this.connector.disconnect();
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 159 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user