mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-13 08:04:53 +09:00
The controller keeps a record per instance with its name, mod pack, Factorio version, players online, status and address, and the instance plugin pushes the list into lua over rcon. The readme and the connect commands read it through modules/exp_server_list, so expcore/external and its hardcoded server fallback are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import type { Instance, InstancePluginContext } from "@clusterio/host";
|
|
import * as lib from "@clusterio/lib";
|
|
import * as messages from "./messages.js";
|
|
|
|
/** Sends the server list to the lua side, see module/control.lua. */
|
|
export class InstancePlugin {
|
|
/** Rcon is up and the lua side can take updates */
|
|
started = false;
|
|
|
|
private constructor(
|
|
public instance: Instance,
|
|
public logger: lib.Logger,
|
|
public name: string,
|
|
) {}
|
|
|
|
static async fromContext(context: InstancePluginContext) {
|
|
const instance = context.instance;
|
|
const plugin = new InstancePlugin(instance, context.logger, context.plugin.name);
|
|
|
|
instance.handle(messages.ServerUpdatesEvent, plugin.handleServerUpdatesEvent.bind(plugin));
|
|
instance.hooks.start.attach(plugin.name, plugin.onStart.bind(plugin));
|
|
instance.hooks.exit.attach(plugin.name, plugin.onExit.bind(plugin));
|
|
instance.hooks.controllerConnectionEvent.attach(plugin.name, plugin.onControllerConnectionEvent.bind(plugin));
|
|
return plugin;
|
|
}
|
|
|
|
async onStart() {
|
|
this.started = true;
|
|
await this.syncServers();
|
|
}
|
|
|
|
async onExit() {
|
|
this.started = false;
|
|
}
|
|
|
|
/** A new session means the controller restarted and forgot the subscription. */
|
|
async onControllerConnectionEvent(event: "connect" | "drop" | "resume" | "close") {
|
|
if (event === "connect" && this.started) {
|
|
await this.syncServers();
|
|
}
|
|
}
|
|
|
|
/** Subscribe, then replace the whole list */
|
|
async syncServers() {
|
|
await this.instance.sendTo("controller", new lib.SubscriptionRequest(
|
|
`exp_server_list:${messages.ServerUpdatesEvent.name}`, "subscribe", Date.now(),
|
|
));
|
|
const servers = await this.instance.sendTo("controller", new messages.ServerListRequest());
|
|
await this.luaSendServers(servers, true);
|
|
}
|
|
|
|
async handleServerUpdatesEvent(event: messages.ServerUpdatesEvent) {
|
|
if (this.started) {
|
|
await this.luaSendServers(event.updates, false);
|
|
}
|
|
}
|
|
|
|
async luaSendServers(servers: messages.ServerRecord[], replace: boolean) {
|
|
const json = JSON.stringify({
|
|
current_id: this.instance.id,
|
|
replace,
|
|
servers: servers.map(server => server.toJSON()),
|
|
});
|
|
// Pick a long bracket the json does not contain
|
|
let level = "=";
|
|
while (json.includes(`]${level}]`)) {
|
|
level += "=";
|
|
}
|
|
await this.instance.sendRcon(
|
|
`/sc exp_server_list.receive_update(helpers.json_to_table[${level}[${json}]${level}])`, true,
|
|
);
|
|
}
|
|
}
|
|
|
|
export default async function (context: InstancePluginContext) {
|
|
await InstancePlugin.fromContext(context);
|
|
}
|