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): 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): 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): 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): 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): 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): QueueUpdateEvent { return new this(json.queue, json.player); } } export class QueueChange { constructor( public type: "added" | "removed" | "moved", public name: string, /** Entries for the same technology before this one, the level above the first queued level */ public offset: number, /** 1-based position in the new queue, or in the old queue for removed */ public position: number, ) { } static jsonSchema = Type.Object({ "type": Type.Union([Type.Literal("added"), Type.Literal("removed"), Type.Literal("moved")]), "name": Type.String(), "offset": Type.Integer(), "position": Type.Integer(), }); static fromJSON(json: Static): QueueChange { return new this(json.type, json.name, json.offset, json.position); } } 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 | null, /** What changed, null for a silent update or an older controller */ public changes: QueueChange[] | null = null, ) { } static jsonSchema = Type.Object({ "queue": Type.Array(Type.String()), "player": Type.Union([Type.String(), Type.Null()]), "instance": Type.Union([Type.String(), Type.Null()]), "changes": Type.Optional(Type.Union([Type.Array(QueueChange.jsonSchema), Type.Null()])), }); static fromJSON(json: Static): QueueEvent { return new this( json.queue, json.player, json.instance, json.changes ? json.changes.map(c => QueueChange.fromJSON(c)) : null, ); } } 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): QueueSyncRequest { return new this(json.queue, json.player); } static Response = lib.plainJson(Type.Array(Type.String())); }