Files
factorio-clusterio/plugins/research_sync/messages.ts
T
ILLISISandClaude Opus 5.5 e3099e1e05 research_sync: cluster research queue on the controller
- QueueUpdateEvent, QueueEvent and QueueSyncRequest messages.
- The controller keeps one queue (max 7 names) in research_queue.json, saved with the other data.
- An update that changes the queue replaces it and is broadcast as QueueEvent; an equal update is ignored.
- QueueSyncRequest returns the queue and seeds it from the request when the queue is empty.
- A finished technology (completing contribution, advancing FinishedEvent, technology sync) drops its first queue entry without a broadcast.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 21:31:59 +11:00

212 lines
5.0 KiB
TypeScript

import { Type, Static } from "@sinclair/typebox";
import * as lib from "@clusterio/lib";
export class ContributionEvent {
declare ["constructor"]: typeof ContributionEvent;
static type = "event" as const;
static src = "instance" as const;
static dst = "controller" as const;
static plugin = "research_sync" as const;
constructor(
public name: string,
public level: number,
public contribution: number
) {
}
static jsonSchema = Type.Object({
"name": Type.String(),
"level": Type.Integer(),
"contribution": Type.Number(),
});
static fromJSON(json: Static<typeof ContributionEvent.jsonSchema>): ContributionEvent {
return new this(json.name, json.level, json.contribution);
}
}
export class TechnologyProgress {
constructor(
public name: string,
public level: number,
public progress: number | null,
) {
}
static jsonSchema = Type.Object({
"name": Type.String(),
"level": Type.Integer(),
"progress": Type.Number(),
});
}
export class ProgressEvent {
declare ["constructor"]: typeof ProgressEvent;
static type = "event" as const;
static src = "controller" as const;
static dst = "instance" as const;
static plugin = "research_sync" as const;
constructor(
public technologies: TechnologyProgress[],
) {
}
static jsonSchema = Type.Object({
"technologies": Type.Array(
TechnologyProgress.jsonSchema
),
});
static fromJSON(json: Static<typeof ProgressEvent.jsonSchema>): ProgressEvent {
return new this(json.technologies);
}
}
export class FinishedEvent {
declare ["constructor"]: typeof FinishedEvent;
static type = "event" as const;
static src = ["instance", "controller"] as const;
static dst = ["instance", "controller"] as const;
static plugin = "research_sync" as const;
constructor(
public name: string,
public level: number,
) {
}
static jsonSchema = Type.Object({
"name": Type.String(),
"level": Type.Integer(),
});
static fromJSON(json: Static<typeof FinishedEvent.jsonSchema>): FinishedEvent {
return new this(json.name, json.level);
}
}
export class TechnologySync {
constructor(
public name: string,
public level: number,
public progress: number | null,
public researched: boolean,
) {
}
static jsonSchema = Type.Tuple([
Type.String(),
Type.Integer(),
Type.Union([Type.Number(), Type.Null()]),
Type.Boolean(),
]);
toJSON() {
return [this.name, this.level, this.progress, this.researched];
}
static fromJSON(json: Static<typeof TechnologySync.jsonSchema>): TechnologySync {
return new this(json[0], json[1], json[2], json[3]);
}
}
export class SyncTechnologiesRequest {
declare ["constructor"]: typeof SyncTechnologiesRequest;
static type = "request" as const;
static src = "instance" as const;
static dst = "controller" as const;
static plugin = "research_sync" as const;
constructor(
public technologies: TechnologySync[]
) {
}
static jsonSchema = Type.Array(TechnologySync.jsonSchema);
toJSON() {
return this.technologies;
}
static fromJSON(json: Static<typeof SyncTechnologiesRequest.jsonSchema>): SyncTechnologiesRequest {
return new this(json.map(e => TechnologySync.fromJSON(e)));
}
static Response = lib.jsonArray(TechnologySync);
}
export class QueueUpdateEvent {
declare ["constructor"]: typeof QueueUpdateEvent;
static type = "event" as const;
static src = "instance" as const;
static dst = "controller" as const;
static plugin = "research_sync" as const;
constructor(
public queue: string[],
public player: string | null,
) {
}
static jsonSchema = Type.Object({
"queue": Type.Array(Type.String()),
"player": Type.Union([Type.String(), Type.Null()]),
});
static fromJSON(json: Static<typeof QueueUpdateEvent.jsonSchema>): QueueUpdateEvent {
return new this(json.queue, json.player);
}
}
export class QueueEvent {
declare ["constructor"]: typeof QueueEvent;
static type = "event" as const;
static src = "controller" as const;
static dst = "instance" as const;
static plugin = "research_sync" as const;
constructor(
public queue: string[],
public player: string | null,
public instance: string,
) {
}
static jsonSchema = Type.Object({
"queue": Type.Array(Type.String()),
"player": Type.Union([Type.String(), Type.Null()]),
"instance": Type.String(),
});
static fromJSON(json: Static<typeof QueueEvent.jsonSchema>): QueueEvent {
return new this(json.queue, json.player, json.instance);
}
}
export class QueueSyncRequest {
declare ["constructor"]: typeof QueueSyncRequest;
static type = "request" as const;
static src = "instance" as const;
static dst = "controller" as const;
static plugin = "research_sync" as const;
constructor(
public queue: string[] | null,
public player: string | null,
) {
}
static jsonSchema = Type.Object({
"queue": Type.Union([Type.Array(Type.String()), Type.Null()]),
"player": Type.Union([Type.String(), Type.Null()]),
});
static fromJSON(json: Static<typeof QueueSyncRequest.jsonSchema>): QueueSyncRequest {
return new this(json.queue, json.player);
}
static Response = lib.plainJson(Type.Array(Type.String()));
}