mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-16 04:00:52 +00:00
feat: remove LocalPersistantStats so we locally save GameRecords
GameRecords also now include PlayerStats
This commit is contained in:
@@ -77,6 +77,9 @@ export type ClientHashMessage = z.infer<typeof ClientHashSchema>;
|
||||
export type PlayerRecord = z.infer<typeof PlayerRecordSchema>;
|
||||
export type GameRecord = z.infer<typeof GameRecordSchema>;
|
||||
|
||||
export type AllPlayersStats = z.infer<typeof AllPlayersStatsSchema>;
|
||||
export type PlayerStats = z.infer<typeof PlayerStatsSchema>;
|
||||
|
||||
const PlayerTypeSchema = z.nativeEnum(PlayerType);
|
||||
|
||||
export interface GameInfo {
|
||||
@@ -132,6 +135,21 @@ const ID = z
|
||||
.regex(/^[a-zA-Z0-9]+$/)
|
||||
.length(8);
|
||||
|
||||
const NukesEnum = z.enum([
|
||||
"Atom Bomb",
|
||||
"Hydrogen Bomb",
|
||||
"MIRV",
|
||||
"MIRV Warhead",
|
||||
]);
|
||||
|
||||
const NukeStatsSchema = z.record(NukesEnum, z.number());
|
||||
|
||||
export const PlayerStatsSchema = z.object({
|
||||
sentNukes: z.record(ID, NukeStatsSchema),
|
||||
});
|
||||
|
||||
export const AllPlayersStatsSchema = z.record(ID, PlayerStatsSchema);
|
||||
|
||||
// Zod schemas
|
||||
const BaseIntentSchema = z.object({
|
||||
type: z.enum([
|
||||
@@ -313,6 +331,7 @@ const ClientBaseMessageSchema = z.object({
|
||||
export const ClientSendWinnerSchema = ClientBaseMessageSchema.extend({
|
||||
type: z.literal("winner"),
|
||||
winner: ID.nullable(),
|
||||
allPlayersStats: AllPlayersStatsSchema,
|
||||
});
|
||||
|
||||
export const ClientHashSchema = ClientBaseMessageSchema.extend({
|
||||
@@ -371,4 +390,6 @@ export const GameRecordSchema = z.object({
|
||||
num_turns: z.number(),
|
||||
turns: z.array(TurnSchema),
|
||||
winner: ID.nullable(),
|
||||
allPlayersStats: z.record(ID, PlayerStatsSchema),
|
||||
version: z.enum(["v0.0.1"]),
|
||||
});
|
||||
|
||||
@@ -3,11 +3,13 @@ import twemoji from "twemoji";
|
||||
import DOMPurify from "dompurify";
|
||||
import { Cell, Game, Player, Unit } from "./game/Game";
|
||||
import {
|
||||
AllPlayersStats,
|
||||
ClientID,
|
||||
GameConfig,
|
||||
GameID,
|
||||
GameRecord,
|
||||
PlayerRecord,
|
||||
PlayerStats,
|
||||
Turn,
|
||||
} from "./Schemas";
|
||||
import { customAlphabet, nanoid } from "nanoid";
|
||||
@@ -262,6 +264,7 @@ export function CreateGameRecord(
|
||||
start: number,
|
||||
end: number,
|
||||
winner: ClientID | null,
|
||||
allPlayersStats: AllPlayersStats,
|
||||
): GameRecord {
|
||||
const record: GameRecord = {
|
||||
id: id,
|
||||
@@ -270,6 +273,8 @@ export function CreateGameRecord(
|
||||
endTimestampMS: end,
|
||||
date: new Date().toISOString().split("T")[0],
|
||||
turns: [],
|
||||
allPlayersStats,
|
||||
version: "v0.0.1",
|
||||
};
|
||||
|
||||
for (const turn of turns) {
|
||||
|
||||
@@ -33,7 +33,7 @@ export class WinCheckExecution implements Execution {
|
||||
(max.numTilesOwned() / numTilesWithoutFallout) * 100 >
|
||||
this.mg.config().percentageTilesOwnedToWin()
|
||||
) {
|
||||
this.mg.setWinner(max);
|
||||
this.mg.setWinner(max, this.mg.stats().stats());
|
||||
console.log(`${max.name()} has won the game`);
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Config } from "../configuration/Config";
|
||||
import { GameEvent } from "../EventBus";
|
||||
import { PlayerView } from "./GameView";
|
||||
import { ClientID, GameConfig, GameID } from "../Schemas";
|
||||
import { ClientID, GameConfig, GameID, AllPlayersStats } from "../Schemas";
|
||||
import { GameMap, GameMapImpl, TileRef } from "./GameMap";
|
||||
import {
|
||||
GameUpdate,
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
PlayerUpdate,
|
||||
UnitUpdate,
|
||||
} from "./GameUpdates";
|
||||
import { PlayerStats, Stats } from "./Stats";
|
||||
import { Stats } from "./Stats";
|
||||
|
||||
export type PlayerID = string;
|
||||
export type Tick = number;
|
||||
@@ -378,7 +378,7 @@ export interface Game extends GameMap {
|
||||
ticks(): Tick;
|
||||
inSpawnPhase(): boolean;
|
||||
executeNextTick(): GameUpdates;
|
||||
setWinner(winner: Player): void;
|
||||
setWinner(winner: Player, allPlayersStats: AllPlayersStats): void;
|
||||
config(): Config;
|
||||
|
||||
// Units
|
||||
|
||||
@@ -24,7 +24,7 @@ import { PlayerImpl } from "./PlayerImpl";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
import { AllianceRequestImpl } from "./AllianceRequestImpl";
|
||||
import { AllianceImpl } from "./AllianceImpl";
|
||||
import { ClientID, GameConfig } from "../Schemas";
|
||||
import { ClientID, AllPlayersStats } from "../Schemas";
|
||||
import { MessageType } from "./Game";
|
||||
import { UnitImpl } from "./UnitImpl";
|
||||
import { consolex } from "../Consolex";
|
||||
@@ -516,10 +516,11 @@ export class GameImpl implements Game {
|
||||
});
|
||||
}
|
||||
|
||||
setWinner(winner: Player): void {
|
||||
setWinner(winner: Player, allPlayersStats: AllPlayersStats): void {
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Win,
|
||||
winnerID: winner.smallID(),
|
||||
allPlayersStats,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ClientID } from "../Schemas";
|
||||
import { ClientID, PlayerStats, AllPlayersStats } from "../Schemas";
|
||||
import {
|
||||
AllianceRequest,
|
||||
EmojiMessage,
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
UnitType,
|
||||
} from "./Game";
|
||||
import { TileRef, TileUpdate } from "./GameMap";
|
||||
import { PlayerStats } from "./Stats";
|
||||
|
||||
export interface GameUpdateViewData {
|
||||
tick: number;
|
||||
@@ -156,6 +155,7 @@ export interface DisplayMessageUpdate {
|
||||
|
||||
export interface WinUpdate {
|
||||
type: GameUpdateType.Win;
|
||||
allPlayersStats: AllPlayersStats;
|
||||
winnerID: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,12 @@ import {
|
||||
UnitInfo,
|
||||
UnitType,
|
||||
} from "./Game";
|
||||
import { ClientID, GameID } from "../Schemas";
|
||||
import { ClientID, GameID, PlayerStats } from "../Schemas";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
import { WorkerClient } from "../worker/WorkerClient";
|
||||
import { GameMap, GameMapImpl, TileRef, TileUpdate } from "./GameMap";
|
||||
import { GameUpdateViewData } from "./GameUpdates";
|
||||
import { DefenseGrid } from "./DefensePostGrid";
|
||||
import { PlayerStats } from "./Stats";
|
||||
|
||||
export class UnitView {
|
||||
public _wasUpdated = true;
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import { AllPlayersStats, PlayerStats } from "../Schemas";
|
||||
import { NukeType, PlayerID } from "./Game";
|
||||
|
||||
export interface PlayerStats {
|
||||
sentNukes: {
|
||||
// target
|
||||
[key: PlayerID]: {
|
||||
[key in NukeType]: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface Stats {
|
||||
increaseNukeCount(sender: PlayerID, target: PlayerID, type: NukeType): void;
|
||||
getPlayerStats(player: PlayerID): PlayerStats;
|
||||
stats(): AllPlayersStats;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
import { NukeType, Player, PlayerID, UnitType } from "./Game";
|
||||
import { PlayerStats, Stats } from "./Stats";
|
||||
|
||||
interface StatsInternalData {
|
||||
// player
|
||||
[key: PlayerID]: PlayerStats;
|
||||
}
|
||||
import { AllPlayersStats, PlayerStats } from "../Schemas";
|
||||
import { NukeType, PlayerID, UnitType } from "./Game";
|
||||
import { Stats } from "./Stats";
|
||||
|
||||
export class StatsImpl implements Stats {
|
||||
data: StatsInternalData = {};
|
||||
data: AllPlayersStats = {};
|
||||
|
||||
_createUserData(sender: PlayerID, target: PlayerID): void {
|
||||
if (!this.data[sender]) {
|
||||
@@ -31,4 +27,8 @@ export class StatsImpl implements Stats {
|
||||
getPlayerStats(player: PlayerID): PlayerStats {
|
||||
return this.data[player];
|
||||
}
|
||||
|
||||
stats() {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user