mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 15:04:52 +09:00
Flatten lib namespace
Move all functions and classes currently available through lib/name and libName to be under a single flat namespace in lib. This make reorganising the lib namespace much simpler as the location of symbols can move without breaking the consumers of lib. The multi-entrypoint design was already problematic for the web plugin system which couldn't effectively use it due to how webpack's shared module system is awkward to set up with multiple entrypoints per package.
This commit is contained in:
1 parent
bb58670597
commit
bfe119eaa3
143 files changed
+1798
-1918
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"));
|
||||
@@ -154,7 +146,7 @@ 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));
|
||||
@@ -168,7 +160,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 +204,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 +254,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 +277,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 +299,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 +308,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 +385,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,7 @@
|
||||
"use strict";
|
||||
const fs = require("fs-extra");
|
||||
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libUsers = require("@clusterio/lib/users");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
/**
|
||||
* Manages users and roles
|
||||
@@ -21,12 +20,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 +35,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 +62,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 +71,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,7 +79,7 @@ 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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
+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,38 @@ 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 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 +91,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 +106,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 +143,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 lib.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 +183,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 +202,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 +294,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 +316,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 +344,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 +365,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 +382,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 +398,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 +431,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 +458,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 +480,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 +507,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 +544,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 +579,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 +616,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 +682,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 +690,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 +700,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 +722,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 +823,7 @@ rcon.print(game.table_to_json(players))`.replace(/\r?\n/g, " ");
|
||||
}
|
||||
}
|
||||
|
||||
await libFactorio.patch(this.path("saves", saveName), [...modules.values()]);
|
||||
await lib.patch(this.path("saves", saveName), [...modules.values()]);
|
||||
return saveName;
|
||||
}
|
||||
|
||||
@@ -860,7 +851,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 +876,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 +885,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 +964,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 +978,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 +1003,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 +1028,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 +1082,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 lib.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) {
|
||||
|
||||
@@ -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 {
|
||||
/**
|
||||
|
||||
+12
-10
@@ -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 "./config";
|
||||
export * from "./data";
|
||||
export * from "./errors";
|
||||
export * from "./factorio/exchange_string";
|
||||
export * from "./helpers";
|
||||
export * from "./ini";
|
||||
export * from "./link";
|
||||
export * from "./logging";
|
||||
export * from "./plugin";
|
||||
export * from "./schema";
|
||||
export * from "./users";
|
||||
|
||||
export { default as ExponentialBackoff } from "./ExponentialBackoff";
|
||||
export { default as PlayerStats } from "./PlayerStats";
|
||||
export { default as RateLimiter } from "./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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
@@ -16,9 +16,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:lib.FactorioServer} server -
|
||||
* The server to generate the export mod for.
|
||||
* @memberof module:lib/factorio
|
||||
* @memberof module:lib
|
||||
*/
|
||||
async function generateExportMod(server) {
|
||||
let dependencies = [];
|
||||
@@ -63,12 +63,12 @@ async function loadZip(server, modVersions, mod) {
|
||||
/**
|
||||
* Load the given Factorio file path into a Buffer
|
||||
*
|
||||
* @param {module:lib/factorio.FactorioServer} server -
|
||||
* @param {module:lib.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 +250,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:lib.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 +321,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:lib.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
|
||||
*/
|
||||
@@ -377,10 +377,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:lib.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);
|
||||
|
||||
@@ -27,7 +27,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 +77,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,7 +175,7 @@ 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));
|
||||
|
||||
@@ -21,7 +21,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 +55,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 +87,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 +145,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 +164,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 +207,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 +412,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 {
|
||||
/**
|
||||
|
||||
@@ -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 = {}) {
|
||||
|
||||
+31
-21
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Shared library for Clusterio
|
||||
* @module lib
|
||||
*/
|
||||
"use strict";
|
||||
const libBuildMod = require("./build_mod");
|
||||
const libCommand = require("./command");
|
||||
@@ -9,6 +13,7 @@ const libFactorio = require("./factorio");
|
||||
const libFileOps = require("./file_ops");
|
||||
const libHash = require("./hash");
|
||||
const libHelpers = require("./helpers");
|
||||
const libIni = require("./ini");
|
||||
const libLink = require("./link");
|
||||
const libLogging = require("./logging");
|
||||
const libLoggingUtils = require("./logging_utils");
|
||||
@@ -18,36 +23,41 @@ const libPluginLoader = require("./plugin_loader");
|
||||
const libPrometheus = require("./prometheus");
|
||||
const libSchema = require("./schema");
|
||||
const libSharedCommands = require("./shared_commands");
|
||||
const libStream = require("./stream");
|
||||
const libUsers = require("./users");
|
||||
const libZipOps = require("./zip_ops");
|
||||
|
||||
const ExponentialBackoff = require("./ExponentialBackoff");
|
||||
const PlayerStats = require("./PlayerStats");
|
||||
const RateLimiter = require("./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,
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
+16
-16
@@ -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
|
||||
*/
|
||||
|
||||
+26
-26
@@ -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(
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -100,8 +100,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 +121,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 +186,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 +200,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 +210,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();
|
||||
|
||||
@@ -286,7 +286,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 +336,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"use strict";
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const { BaseControlPlugin, CommandTree, Command } = require("@clusterio/lib");
|
||||
const { ChatEvent } = require("./messages");
|
||||
const libCommand = require("@clusterio/lib/command");
|
||||
|
||||
|
||||
const globalChatCommands = new libCommand.CommandTree({
|
||||
const globalChatCommands = new CommandTree({
|
||||
name: "global-chat", description: "Global Chat plugin commands",
|
||||
});
|
||||
globalChatCommands.add(new libCommand.Command({
|
||||
globalChatCommands.add(new Command({
|
||||
definition: ["shout <message>", "Send message to all instances", (yargs) => {
|
||||
yargs.positional("message", { describe: "message to send", type: "string" });
|
||||
}],
|
||||
@@ -16,7 +15,7 @@ globalChatCommands.add(new libCommand.Command({
|
||||
},
|
||||
}));
|
||||
|
||||
class ControlPlugin extends libPlugin.BaseControlPlugin {
|
||||
class ControlPlugin extends BaseControlPlugin {
|
||||
async addCommands(rootCommand) {
|
||||
rootCommand.add(globalChatCommands);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
* @module
|
||||
*/
|
||||
"use strict";
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libLuaTools = require("@clusterio/lib/lua_tools");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ChatEvent } = require("./messages");
|
||||
|
||||
|
||||
@@ -17,7 +16,7 @@ function removeTags(content) {
|
||||
return content.replace(/(\[gps=-?\d+,-?\d+\]|\[train=\d+\])/g, "");
|
||||
}
|
||||
|
||||
class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
class InstancePlugin extends lib.BaseInstancePlugin {
|
||||
async init() {
|
||||
this.messageQueue = [];
|
||||
this.instance.handle(ChatEvent, this.handleChatEvent.bind(this));
|
||||
@@ -35,7 +34,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
async handleChatEvent(event) {
|
||||
// TODO check if cross server chat is enabled
|
||||
let content = `[${event.instanceName}] ${removeTags(event.content)}`;
|
||||
await this.sendRcon(`/sc game.print('${libLuaTools.escapeString(content)}')`, true);
|
||||
await this.sendRcon(`/sc game.print('${lib.escapeString(content)}')`, true);
|
||||
}
|
||||
|
||||
sendChat(message) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const libLink = require("@clusterio/lib/link");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
const mock = require("../../../test/mock");
|
||||
const lines = require("../../../test/lib/factorio/lines");
|
||||
@@ -26,7 +26,7 @@ describe("global_chat plugin", function() {
|
||||
let instancePlugin;
|
||||
|
||||
before(async function() {
|
||||
libLink.Link.register(ChatEvent);
|
||||
lib.Link.register(ChatEvent);
|
||||
instancePlugin = new instance.InstancePlugin(info, new mock.MockInstance(), new mock.MockHost());
|
||||
await instancePlugin.init();
|
||||
});
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
const {
|
||||
AcquireRequest,
|
||||
@@ -34,11 +33,11 @@ async function saveDatabase(controllerConfig, playerDatastore, logger) {
|
||||
let file = path.resolve(controllerConfig.get("controller.database_directory"), "inventories.json");
|
||||
logger.verbose(`writing ${file}`);
|
||||
let content = JSON.stringify(Array.from(playerDatastore));
|
||||
await libFileOps.safeOutputFile(file, content);
|
||||
await lib.safeOutputFile(file, content);
|
||||
}
|
||||
}
|
||||
|
||||
class ControllerPlugin extends libPlugin.BaseControllerPlugin {
|
||||
class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
async init() {
|
||||
this.acquiredPlayers = new Map();
|
||||
this.playerDatastore = await loadDatabase(this.controller.config, this.logger);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
const { libConfig, libUsers } = require("@clusterio/lib");
|
||||
const lib = require("@clusterio/lib");
|
||||
let messages = require("./messages");
|
||||
|
||||
class ControllerConfigGroup extends libConfig.PluginConfigGroup { }
|
||||
class ControllerConfigGroup extends lib.PluginConfigGroup { }
|
||||
ControllerConfigGroup.defaultAccess = ["controller", "host", "control"];
|
||||
ControllerConfigGroup.groupName = "inventory_sync";
|
||||
ControllerConfigGroup.define({
|
||||
@@ -22,7 +22,7 @@ ControllerConfigGroup.define({
|
||||
});
|
||||
ControllerConfigGroup.finalize();
|
||||
|
||||
class InstanceConfigGroup extends libConfig.PluginConfigGroup { }
|
||||
class InstanceConfigGroup extends lib.PluginConfigGroup { }
|
||||
InstanceConfigGroup.defaultAccess = ["controller", "host", "control"];
|
||||
InstanceConfigGroup.groupName = "inventory_sync";
|
||||
InstanceConfigGroup.define({
|
||||
@@ -34,7 +34,7 @@ InstanceConfigGroup.define({
|
||||
});
|
||||
InstanceConfigGroup.finalize();
|
||||
|
||||
libUsers.definePermission({
|
||||
lib.definePermission({
|
||||
name: "inventory_sync.inventory.view",
|
||||
title: "View player inventories",
|
||||
description: "View player inventories",
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
* @module
|
||||
*/
|
||||
"use strict";
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libLuaTools = require("@clusterio/lib/lua_tools");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
const {
|
||||
AcquireRequest,
|
||||
ReleaseRequest,
|
||||
UploadRequest,
|
||||
DownloadRequest,
|
||||
DatabaseStatsRequest,
|
||||
} = require("./messages");
|
||||
|
||||
/**
|
||||
@@ -24,7 +21,7 @@ function chunkify(chunkSize, string) {
|
||||
return string.match(new RegExp(`.{1,${chunkSize}}`, "g"));
|
||||
}
|
||||
|
||||
class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
class InstancePlugin extends lib.BaseInstancePlugin {
|
||||
async init() {
|
||||
this.playersToRelease = new Set();
|
||||
this.disconnecting = false;
|
||||
@@ -82,14 +79,14 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
message: acquireResponse.message,
|
||||
};
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
this.logger.error(`Unexpected error sending aquire request:\n${err.stack}`);
|
||||
response.message = err.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let json = libLuaTools.escapeString(JSON.stringify(response));
|
||||
let json = lib.escapeString(JSON.stringify(response));
|
||||
await this.sendRcon(`/sc inventory_sync.acquire_response("${json}")`, true);
|
||||
}
|
||||
|
||||
@@ -101,7 +98,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
try {
|
||||
await this.instance.sendTo("controller", new ReleaseRequest(this.instance.id, request.player_name));
|
||||
} catch (err) {
|
||||
if (err instanceof libErrors.SessionLost) {
|
||||
if (err instanceof lib.SessionLost) {
|
||||
this.playersToRelease.set(request.player_name);
|
||||
} else {
|
||||
this.logger.error(`Unexpected error releasing player ${request.player_name}:\n${err.stack}`);
|
||||
@@ -122,7 +119,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
if (!(err instanceof libErrors.SessionLost)) {
|
||||
if (!(err instanceof lib.SessionLost)) {
|
||||
this.logger.error(`Unexpected error uploading inventory for ${player_data.name}:\n${err.stack}`);
|
||||
}
|
||||
return;
|
||||
@@ -149,7 +146,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
this.logger.verbose(`Sending inventory for ${playerName} in ${chunks.length} chunks`);
|
||||
for (let i = 0; i < chunks.length; i++) {
|
||||
// this.logger.verbose(`Sending chunk ${i+1} of ${chunks.length}`)
|
||||
const chunk = libLuaTools.escapeString(chunks[i]);
|
||||
const chunk = lib.escapeString(chunks[i]);
|
||||
await this.sendRcon(
|
||||
`/sc inventory_sync.download_inventory('${playerName}','${chunk}',${i + 1},${chunks.length})`,
|
||||
true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext, useEffect, useState } from "react";
|
||||
|
||||
import { libPlugin } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { PageLayout, ControlContext } from "@clusterio/web_ui";
|
||||
import { DatabaseStatsRequest } from "../messages";
|
||||
|
||||
@@ -28,7 +28,7 @@ function InventoryPage() {
|
||||
</PageLayout>;
|
||||
}
|
||||
|
||||
export class WebPlugin extends libPlugin.BaseWebPlugin {
|
||||
export class WebPlugin extends lib.BaseWebPlugin {
|
||||
async init() {
|
||||
this.pages = [
|
||||
{
|
||||
|
||||
@@ -7,9 +7,8 @@ const express = require("express");
|
||||
const util = require("util");
|
||||
const jwt = require("jsonwebtoken");
|
||||
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const { basicType } = require("@clusterio/lib/helpers");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { basicType } = lib;
|
||||
|
||||
const { FetchPlayerCodeRequest, SetVerifyCodeRequest } = require("./messages");
|
||||
|
||||
@@ -30,7 +29,7 @@ async function generateCode(length) {
|
||||
}
|
||||
|
||||
|
||||
class ControllerPlugin extends libPlugin.BaseControllerPlugin {
|
||||
class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
async init() {
|
||||
// Store of validation attempts by players
|
||||
this.players = new Map();
|
||||
@@ -174,12 +173,12 @@ class ControllerPlugin extends libPlugin.BaseControllerPlugin {
|
||||
async handleSetVerifyCodeRequest(request) {
|
||||
let { player, verifyCode } = request;
|
||||
if (!this.players.has(player)) {
|
||||
throw new libErrors.RequestError("invalid player");
|
||||
throw new lib.RequestError("invalid player");
|
||||
}
|
||||
|
||||
let entry = this.players.get(player);
|
||||
if (entry.expires < Date.now()) {
|
||||
throw new libErrors.RequestError("invalid player");
|
||||
throw new lib.RequestError("invalid player");
|
||||
}
|
||||
|
||||
entry.verifyCode = verifyCode;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
let { libConfig } = require("@clusterio/lib");
|
||||
const lib = require("@clusterio/lib");
|
||||
let messages = require("./messages");
|
||||
|
||||
|
||||
class ControllerConfigGroup extends libConfig.PluginConfigGroup {}
|
||||
class ControllerConfigGroup extends lib.PluginConfigGroup {}
|
||||
ControllerConfigGroup.defaultAccess = ["controller", "host", "control"];
|
||||
ControllerConfigGroup.groupName = "player_auth";
|
||||
ControllerConfigGroup.define({
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
* @module
|
||||
*/
|
||||
"use strict";
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
const { FetchPlayerCodeRequest, SetVerifyCodeRequest } = require("./messages");
|
||||
|
||||
|
||||
class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
class InstancePlugin extends lib.BaseInstancePlugin {
|
||||
async init() {
|
||||
if (!this.instance.config.get("factorio.enable_save_patching")) {
|
||||
throw new Error("player_auth plugin requires save patching.");
|
||||
|
||||
@@ -9,8 +9,7 @@ const controller = require("../controller");
|
||||
const instance = require("../instance");
|
||||
const info = require("../info");
|
||||
const { FetchPlayerCodeRequest, SetVerifyCodeRequest } = require("../messages");
|
||||
const libData = require("@clusterio/lib/data");
|
||||
const libErrors = require("@clusterio/lib/errors");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
|
||||
describe("player_auth", function() {
|
||||
@@ -312,7 +311,7 @@ describe("player_auth", function() {
|
||||
controllerPlugin.handleSetVerifyCodeRequest(
|
||||
new SetVerifyCodeRequest("invalid", "invalid")
|
||||
),
|
||||
new libErrors.RequestError("invalid player")
|
||||
new lib.RequestError("invalid player")
|
||||
);
|
||||
});
|
||||
it("should throw if player code has expired", async function() {
|
||||
@@ -322,7 +321,7 @@ describe("player_auth", function() {
|
||||
controllerPlugin.handleSetVerifyCodeRequest(
|
||||
new SetVerifyCodeRequest("expired", "expired")
|
||||
),
|
||||
new libErrors.RequestError("invalid player")
|
||||
new lib.RequestError("invalid player")
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -379,8 +378,8 @@ describe("player_auth", function() {
|
||||
instancePlugin.instance.server.reset();
|
||||
instancePlugin.instance.connector.once("send", message => {
|
||||
instancePlugin.instance.connector.emit("message",
|
||||
new libData.MessageResponseError(1, message.dst, message.src,
|
||||
new libData.ResponseError("controller error")
|
||||
new lib.MessageResponseError(1, message.dst, message.src,
|
||||
new lib.ResponseError("controller error")
|
||||
)
|
||||
);
|
||||
});
|
||||
@@ -392,7 +391,7 @@ describe("player_auth", function() {
|
||||
instancePlugin.instance.server.reset();
|
||||
instancePlugin.instance.connector.once("send", message => {
|
||||
instancePlugin.instance.connector.emit("message",
|
||||
new libData.MessageResponse(1, message.dst, message.src,
|
||||
new lib.MessageResponse(1, message.dst, message.src,
|
||||
new FetchPlayerCodeRequest.Response("code", "controller-url")
|
||||
)
|
||||
);
|
||||
@@ -407,7 +406,7 @@ describe("player_auth", function() {
|
||||
instancePlugin.instance.server.reset();
|
||||
instancePlugin.instance.connector.once("send", message => {
|
||||
instancePlugin.instance.connector.emit("message",
|
||||
new libData.MessageResponse(1, message.dst, message.src)
|
||||
new lib.MessageResponse(1, message.dst, message.src)
|
||||
);
|
||||
});
|
||||
await instancePlugin.handleEvent(
|
||||
@@ -420,8 +419,8 @@ describe("player_auth", function() {
|
||||
instancePlugin.instance.server.reset();
|
||||
instancePlugin.instance.connector.once("send", message => {
|
||||
instancePlugin.instance.connector.emit("message",
|
||||
new libData.MessageResponseError(1, message.dst, message.src,
|
||||
new libData.ResponseError("controller error")
|
||||
new lib.MessageResponseError(1, message.dst, message.src,
|
||||
new lib.ResponseError("controller error")
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { libPlugin } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { notifyErrorHandler } from "@clusterio/web_ui";
|
||||
import { Button, Form, Input, Spin, Typography } from "antd";
|
||||
|
||||
@@ -146,7 +146,7 @@ function LoginForm(props) {
|
||||
}
|
||||
|
||||
|
||||
export class WebPlugin extends libPlugin.BaseWebPlugin {
|
||||
export class WebPlugin extends lib.BaseWebPlugin {
|
||||
async init() {
|
||||
this.logger.info("Player Auth init");
|
||||
this.loginForms = [{
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const libFileOps = require("@clusterio/lib/file_ops");
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const RateLimiter = require("@clusterio/lib/RateLimiter");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { RateLimiter } = lib;
|
||||
|
||||
const {
|
||||
ContributionEvent,
|
||||
@@ -34,10 +33,10 @@ async function loadTechnologies(controllerConfig, logger) {
|
||||
async function saveTechnologies(controllerConfig, technologies, logger) {
|
||||
let filePath = path.join(controllerConfig.get("controller.database_directory"), "technologies.json");
|
||||
logger.verbose(`writing ${filePath}`);
|
||||
await libFileOps.safeOutputFile(filePath, JSON.stringify([...technologies.entries()], null, 4));
|
||||
await lib.safeOutputFile(filePath, JSON.stringify([...technologies.entries()], null, 4));
|
||||
}
|
||||
|
||||
class ControllerPlugin extends libPlugin.BaseControllerPlugin {
|
||||
class ControllerPlugin extends lib.BaseControllerPlugin {
|
||||
async init() {
|
||||
this.technologies = await loadTechnologies(this.controller.config, this.logger);
|
||||
this.progressRateLimiter = new RateLimiter({
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libLuaTools = require("@clusterio/lib/lua_tools");
|
||||
const lib = require("@clusterio/lib");
|
||||
const {
|
||||
ContributionEvent,
|
||||
ProgressEvent,
|
||||
@@ -10,7 +9,7 @@ const {
|
||||
} = require("./messages");
|
||||
|
||||
|
||||
class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
class InstancePlugin extends lib.BaseInstancePlugin {
|
||||
unexpectedError(err) {
|
||||
this.logger.error(`Unexpected error:\n${err.stack}`);
|
||||
}
|
||||
@@ -40,7 +39,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
if (!this.syncStarted || !["starting", "running"].includes(this.instance.status)) {
|
||||
return;
|
||||
}
|
||||
let techsJson = libLuaTools.escapeString(JSON.stringify(event.technologies));
|
||||
let techsJson = lib.escapeString(JSON.stringify(event.technologies));
|
||||
await this.sendOrderedRcon(`/sc research_sync.update_progress("${techsJson}")`, true);
|
||||
}
|
||||
|
||||
@@ -54,7 +53,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
}
|
||||
let { name, level } = event;
|
||||
await this.sendOrderedRcon(
|
||||
`/sc research_sync.research_technology("${libLuaTools.escapeString(name)}", ${level})`, true
|
||||
`/sc research_sync.research_technology("${lib.escapeString(name)}", ${level})`, true
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ class InstancePlugin extends libPlugin.BaseInstancePlugin {
|
||||
}
|
||||
|
||||
if (techsToSync.length) {
|
||||
let syncJson = libLuaTools.escapeString(JSON.stringify(techsToSync));
|
||||
let syncJson = lib.escapeString(JSON.stringify(techsToSync));
|
||||
await this.sendOrderedRcon(`/sc research_sync.sync_technologies("${syncJson}")`, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
const { libData } = require("@clusterio/lib");
|
||||
const lib = require("@clusterio/lib");
|
||||
|
||||
class ContributionEvent {
|
||||
static type = "event";
|
||||
@@ -41,7 +41,7 @@ class ProgressEvent {
|
||||
static dst = "instance";
|
||||
static plugin = "research_sync";
|
||||
|
||||
/** @type {Array<>} */
|
||||
/** @type {Array<Technology>} */
|
||||
technologies;
|
||||
|
||||
constructor(technologies) {
|
||||
@@ -167,7 +167,7 @@ class SyncTechnologiesRequest {
|
||||
return new this(json.map(e => Technology.fromJSON(e)));
|
||||
}
|
||||
|
||||
static Response = libData.jsonArray(Technology);
|
||||
static Response = lib.jsonArray(Technology);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
Loaded 100 of 143 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user