mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-16 00:24:52 +09:00
- The instance sends every value of a feature, defaults included, so update_config is one loop which sets each field and compares. The stored table is the last set of values, and _apply is gone. - values_equal compares table sizes before the contents. - Protected entities are registered with register_on_object_destroyed and forgotten in on_object_destroyed, which covers every way an entity can go. The four removal handlers and the validity checks are gone. Entities destroyed while the feature is disabled are swept when it is enabled again. Saves from before the registrations table get it through the Storage on_init callback. - Spawn area applied the water offset twice and the pattern offset never. The pattern tiles now move with the entities above them. - pruneFeatureValues reads a validation result instead of catching an error, and FeaturesPage hands its pending state and unsaved bar to helpers. - Shorter comments throughout. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
129 lines
3.5 KiB
TypeScript
129 lines
3.5 KiB
TypeScript
import * as lib from "@clusterio/lib";
|
|
import { Type, Static } from "@sinclair/typebox";
|
|
import type { FeatureValue } from "./features.js";
|
|
|
|
/** Create the roles and permission groups the scenario shipped with, see seed.ts. */
|
|
export class SeedRequest {
|
|
declare ["constructor"]: typeof SeedRequest;
|
|
static plugin = "exp_scenario" as const;
|
|
static type = "request" as const;
|
|
static src = "control" as const;
|
|
static dst = "controller" as const;
|
|
static permission = "exp_scenario.seed" as const;
|
|
|
|
constructor() {}
|
|
}
|
|
|
|
const FeatureValueSchema = Type.Union([Type.Boolean(), Type.Number(), Type.String(), Type.Array(Type.String()), Type.Null()]);
|
|
|
|
/** The config of one feature, see features.ts. Only values which differ from the default are stored. */
|
|
export class FeatureRecord {
|
|
constructor(
|
|
/** Name of the feature in features.ts */
|
|
public id: string,
|
|
public enabled: boolean,
|
|
public values: Record<string, FeatureValue> = {},
|
|
public updatedAtMs: number = 0,
|
|
public isDeleted: boolean = false,
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
id: Type.String(),
|
|
enabled: Type.Boolean(),
|
|
values: Type.Record(Type.String(), FeatureValueSchema),
|
|
updated_at_ms: Type.Optional(Type.Number()),
|
|
is_deleted: Type.Optional(Type.Boolean()),
|
|
});
|
|
|
|
toJSON() {
|
|
const json: Static<typeof FeatureRecord.jsonSchema> = {
|
|
id: this.id,
|
|
enabled: this.enabled,
|
|
values: this.values,
|
|
};
|
|
|
|
if (this.updatedAtMs) {
|
|
json.updated_at_ms = this.updatedAtMs;
|
|
}
|
|
|
|
if (this.isDeleted) {
|
|
json.is_deleted = true;
|
|
}
|
|
|
|
return json;
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(
|
|
json.id,
|
|
json.enabled,
|
|
json.values,
|
|
json.updated_at_ms ?? 0,
|
|
json.is_deleted ?? false,
|
|
);
|
|
}
|
|
}
|
|
|
|
export class FeatureUpdatedEvent {
|
|
declare ["constructor"]: typeof FeatureUpdatedEvent;
|
|
static plugin = "exp_scenario" as const;
|
|
static type = "event" as const;
|
|
static src = "controller" as const;
|
|
static dst = ["control", "instance"] as const;
|
|
static permission = "exp_scenario.config.view" as const;
|
|
|
|
constructor(
|
|
public updates: FeatureRecord[],
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
updates: Type.Array(FeatureRecord.jsonSchema),
|
|
});
|
|
|
|
toJSON() {
|
|
return { updates: this.updates.map(feature => feature.toJSON()) };
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.updates.map(feature => FeatureRecord.fromJSON(feature)));
|
|
}
|
|
}
|
|
|
|
/** List the config of every feature. */
|
|
export class FeatureListRequest {
|
|
declare ["constructor"]: typeof FeatureListRequest;
|
|
static plugin = "exp_scenario" as const;
|
|
static type = "request" as const;
|
|
static src = ["control", "instance"] as const;
|
|
static dst = "controller" as const;
|
|
static permission = "exp_scenario.config.view" as const;
|
|
static Response = lib.jsonArray(FeatureRecord);
|
|
}
|
|
|
|
/** Replace the config of a feature, values left out go back to their default. */
|
|
export class FeatureUpdateRequest {
|
|
declare ["constructor"]: typeof FeatureUpdateRequest;
|
|
static plugin = "exp_scenario" as const;
|
|
static type = "request" as const;
|
|
static src = "control" as const;
|
|
static dst = "controller" as const;
|
|
static permission = "exp_scenario.config.edit" as const;
|
|
static Response = FeatureRecord;
|
|
|
|
constructor(
|
|
public id: string,
|
|
public enabled: boolean,
|
|
public values: Record<string, FeatureValue>,
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
id: Type.String(),
|
|
enabled: Type.Boolean(),
|
|
values: Type.Record(Type.String(), FeatureValueSchema),
|
|
});
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.id, json.enabled, json.values);
|
|
}
|
|
}
|