mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Move BaseControllerPlugin to controller/src/BaseControllerPlugin.ts Move BaseInstancePlugin to host/src/BaseInstancePlugin.ts Move BaseControlPlugin to ctl/src/BaseCtlPlugin.ts Move BaseWebPlugin to web_ui/src/BaseWebPlugin.ts This solves the circular package dependency problem of the base plugins needing types that are available only in the dependencies to lib.
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
import * as lib from "@clusterio/lib";
|
|
import { BaseInstancePlugin } from "@clusterio/host";
|
|
import {
|
|
ContributionEvent,
|
|
ProgressEvent,
|
|
FinishedEvent,
|
|
TechnologySync,
|
|
SyncTechnologiesRequest,
|
|
} from "./messages";
|
|
|
|
// ./module/sync.lua
|
|
type IpcContribution = {
|
|
name: string,
|
|
level: number,
|
|
contribution: number,
|
|
};
|
|
type IpcFinished = {
|
|
name: string,
|
|
level: number,
|
|
};
|
|
|
|
export class InstancePlugin extends BaseInstancePlugin {
|
|
syncStarted!: boolean;
|
|
|
|
unexpectedError(err: Error) {
|
|
this.logger.error(`Unexpected error:\n${err.stack}`);
|
|
}
|
|
|
|
async init() {
|
|
if (!this.instance.config.get("factorio.enable_save_patching")) {
|
|
throw new Error("research_sync plugin requires save patching.");
|
|
}
|
|
|
|
this.instance.server.on("ipc-research_sync:contribution", (tech: IpcContribution) => {
|
|
this.researchContribution(tech).catch(err => this.unexpectedError(err));
|
|
});
|
|
this.instance.server.on("ipc-research_sync:finished", (tech: IpcFinished) => {
|
|
this.researchFinished(tech).catch(err => this.unexpectedError(err));
|
|
});
|
|
|
|
this.syncStarted = false;
|
|
this.instance.handle(ProgressEvent, this.handleProgressEvent.bind(this));
|
|
this.instance.handle(FinishedEvent, this.handleFinishedEvent.bind(this));
|
|
}
|
|
|
|
async researchContribution(tech: IpcContribution) {
|
|
this.instance.sendTo("controller", new ContributionEvent(tech.name, tech.level, tech.contribution));
|
|
}
|
|
|
|
async handleProgressEvent(event: ProgressEvent) {
|
|
if (!this.syncStarted || !["starting", "running"].includes(this.instance.status)) {
|
|
return;
|
|
}
|
|
let techsJson = lib.escapeString(JSON.stringify(event.technologies));
|
|
await this.sendOrderedRcon(`/sc research_sync.update_progress("${techsJson}")`, true);
|
|
}
|
|
|
|
async researchFinished(tech: IpcFinished) {
|
|
this.instance.sendTo("allInstances", new FinishedEvent(tech.name, tech.level));
|
|
}
|
|
|
|
async handleFinishedEvent(event: FinishedEvent) {
|
|
if (!this.syncStarted || !["starting", "running"].includes(this.instance.status)) {
|
|
return;
|
|
}
|
|
let { name, level } = event;
|
|
await this.sendOrderedRcon(
|
|
`/sc research_sync.research_technology("${lib.escapeString(name)}", ${level})`, true
|
|
);
|
|
}
|
|
|
|
async onStart() {
|
|
let dumpJson = await this.sendOrderedRcon("/sc research_sync.dump_technologies()");
|
|
let techsToSend = [];
|
|
let instanceTechs = new Map();
|
|
for (let tech of JSON.parse(dumpJson)) {
|
|
techsToSend.push(new TechnologySync(
|
|
tech.name,
|
|
tech.level,
|
|
tech.progress || null,
|
|
tech.researched,
|
|
));
|
|
instanceTechs.set(tech.name, tech);
|
|
}
|
|
|
|
let controllerTechs = await this.instance.sendTo("controller", new SyncTechnologiesRequest(techsToSend));
|
|
this.syncStarted = true;
|
|
let techsToSync = [];
|
|
for (let controllerTech of controllerTechs) {
|
|
let { name, level, progress, researched } = controllerTech;
|
|
let instanceTech = instanceTechs.get(name);
|
|
if (
|
|
!instanceTech
|
|
|| instanceTech.level !== level
|
|
|| (instanceTech.progress || null) !== progress
|
|
|| instanceTech.researched !== researched
|
|
) {
|
|
techsToSync.push(controllerTech);
|
|
}
|
|
}
|
|
|
|
if (techsToSync.length) {
|
|
let syncJson = lib.escapeString(JSON.stringify(techsToSync));
|
|
await this.sendOrderedRcon(`/sc research_sync.sync_technologies("${syncJson}")`, true);
|
|
}
|
|
}
|
|
}
|