mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-11-11 15:54:52 +09:00
161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
import * as lib from "@clusterio/lib";
|
|
import { Type, Static } from "@sinclair/typebox";
|
|
|
|
const StatsSchema = Type.Record(Type.String(), Type.Number());
|
|
|
|
/** Totals for one player across every instance, keyed by player name. */
|
|
export class PlayerStatistics {
|
|
constructor(
|
|
public id: string,
|
|
/** Statistic name to total, missing statistics are zero */
|
|
public stats: Record<string, number> = {},
|
|
public updatedAtMs: number = 0,
|
|
public isDeleted: boolean = false,
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
id: Type.String(),
|
|
stats: StatsSchema,
|
|
updated_at_ms: Type.Optional(Type.Number()),
|
|
is_deleted: Type.Optional(Type.Boolean()),
|
|
});
|
|
|
|
toJSON() {
|
|
const json: Static<typeof PlayerStatistics.jsonSchema> = {
|
|
id: this.id,
|
|
stats: this.stats,
|
|
};
|
|
|
|
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.stats }, json.updated_at_ms ?? 0, json.is_deleted ?? false);
|
|
}
|
|
}
|
|
|
|
/** Statistics clusterio already keeps for every user, shown with the others but never added to, existing stats may contain legacy values */
|
|
export function userStatistics(user?: Pick<lib.UserDetails, "playerStats">, stats: Record<string, number> = {}): Record<string, number> {
|
|
return {
|
|
Playtime: (stats.Playtime ?? 0) + Math.floor((user?.playerStats.onlineTimeMs ?? 0) / 60e3),
|
|
JoinCount: (stats.JoinCount ?? 0) + (user?.playerStats.joinCount ?? 0),
|
|
};
|
|
}
|
|
|
|
/** Statistics gained by one player since the last update */
|
|
export class StatisticsDelta {
|
|
constructor(
|
|
public name: string,
|
|
public stats: Record<string, number>,
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
name: Type.String(),
|
|
stats: StatsSchema,
|
|
});
|
|
|
|
toJSON() {
|
|
return { name: this.name, stats: this.stats };
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.name, json.stats);
|
|
}
|
|
}
|
|
|
|
/** Sent by an instance to add to the totals of its players. */
|
|
export class StatisticsUpdateEvent {
|
|
declare ["constructor"]: typeof StatisticsUpdateEvent;
|
|
static plugin = "exp_player_statistics" as const;
|
|
static type = "event" as const;
|
|
static src = "instance" as const;
|
|
static dst = "controller" as const;
|
|
static permission = null;
|
|
|
|
constructor(
|
|
public deltas: StatisticsDelta[],
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
deltas: Type.Array(StatisticsDelta.jsonSchema),
|
|
});
|
|
|
|
toJSON() {
|
|
return { deltas: this.deltas.map(delta => delta.toJSON()) };
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.deltas.map(delta => StatisticsDelta.fromJSON(delta)));
|
|
}
|
|
}
|
|
|
|
export class PlayerStatisticsUpdatedEvent {
|
|
declare ["constructor"]: typeof PlayerStatisticsUpdatedEvent;
|
|
static plugin = "exp_player_statistics" as const;
|
|
static type = "event" as const;
|
|
static src = "controller" as const;
|
|
static dst = "control" as const;
|
|
static permission = "exp_player_statistics.view" as const;
|
|
|
|
constructor(
|
|
public updates: PlayerStatistics[],
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
updates: Type.Array(PlayerStatistics.jsonSchema),
|
|
});
|
|
|
|
toJSON() {
|
|
return { updates: this.updates.map(player => player.toJSON()) };
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.updates.map(player => PlayerStatistics.fromJSON(player)));
|
|
}
|
|
}
|
|
|
|
/** Totals for one player, with Playtime and JoinCount from their clusterio user. */
|
|
export class StatisticsGetRequest {
|
|
declare ["constructor"]: typeof StatisticsGetRequest;
|
|
static plugin = "exp_player_statistics" as const;
|
|
static type = "request" as const;
|
|
static src = ["control", "instance"] as const;
|
|
static dst = "controller" as const;
|
|
static permission = "exp_player_statistics.view" as const;
|
|
static Response = PlayerStatistics;
|
|
|
|
constructor(
|
|
public name: string,
|
|
) {}
|
|
|
|
static jsonSchema = Type.Object({
|
|
name: Type.String(),
|
|
});
|
|
|
|
toJSON() {
|
|
return { name: this.name };
|
|
}
|
|
|
|
static fromJSON(json: Static<typeof this.jsonSchema>) {
|
|
return new this(json.name);
|
|
}
|
|
}
|
|
|
|
export class StatisticsListRequest {
|
|
declare ["constructor"]: typeof StatisticsListRequest;
|
|
static plugin = "exp_player_statistics" as const;
|
|
static type = "request" as const;
|
|
static src = ["control", "instance"] as const;
|
|
static dst = "controller" as const;
|
|
static permission = "exp_player_statistics.view" as const;
|
|
static Response = lib.jsonArray(PlayerStatistics);
|
|
}
|