record game metadata to gcs

This commit is contained in:
Evan
2024-12-06 14:39:31 -08:00
parent b8db74247f
commit cd09c0a1d6
6 changed files with 92 additions and 12 deletions
+19 -4
View File
@@ -1,5 +1,5 @@
import { z } from 'zod';
import { Difficulty, GameMap, PlayerType, UnitType } from './game/Game';
import { Difficulty, GameMap, GameType, PlayerType, UnitType } from './game/Game';
export type GameID = string
export type ClientID = string
@@ -41,6 +41,8 @@ export type ClientPingMessage = z.infer<typeof ClientPingMessageSchema>
export type ClientIntentMessage = z.infer<typeof ClientIntentMessageSchema>
export type ClientJoinMessage = z.infer<typeof ClientJoinMessageSchema>
export type GameRecord = z.infer<typeof GameRecordSchema>
const PlayerTypeSchema = z.nativeEnum(PlayerType);
// TODO: create Cell schema
@@ -53,7 +55,8 @@ export interface Lobby {
const GameConfigSchema = z.object({
gameMap: z.nativeEnum(GameMap),
difficulty: z.nativeEnum(Difficulty)
difficulty: z.nativeEnum(Difficulty),
gameType: z.nativeEnum(GameType)
})
const EmojiSchema = z.string().refine(
@@ -64,6 +67,8 @@ const EmojiSchema = z.string().refine(
message: "Must contain at least one emoji character"
}
);
// Zod schemas
const BaseIntentSchema = z.object({
type: z.enum(['attack', 'spawn', 'boat', 'name', 'targetPlayer', 'emoji', 'troop_ratio', 'build_unit']),
@@ -81,7 +86,6 @@ export const AttackIntentSchema = BaseIntentSchema.extend({
targetY: z.number().nullable()
});
export const SpawnIntentSchema = BaseIntentSchema.extend({
type: z.literal('spawn'),
playerID: z.string(),
@@ -223,4 +227,15 @@ export const ClientJoinMessageSchema = ClientBaseMessageSchema.extend({
lastTurn: z.number() // The last turn the client saw.
})
export const ClientMessageSchema = z.union([ClientPingMessageSchema, ClientIntentMessageSchema, ClientJoinMessageSchema]);
export const ClientMessageSchema = z.union([ClientPingMessageSchema, ClientIntentMessageSchema, ClientJoinMessageSchema]);
export const GameRecordSchema = z.object({
id: z.string(),
gameConfig: GameConfigSchema,
startTimestampMS: z.number(),
endTimestampMS: z.number(),
durationSeconds: z.number(),
date: z.string(),
usernames: z.array(z.string()),
turns: z.array(TurnSchema)
})
+24
View File
@@ -5,6 +5,7 @@ import DOMPurify from 'dompurify';
import { Cell, Game, Player, TerraNullius, Tile, Unit } from "./game/Game";
import { number } from 'zod';
import { GameRecord } from './Schemas';
export function manhattanDist(c1: Cell, c2: Cell): number {
return Math.abs(c1.x - c2.x) + Math.abs(c1.y - c2.y);
@@ -222,6 +223,29 @@ export function onlyImages(html: string) {
});
}
export function ProcessGameRecord(record: GameRecord): GameRecord {
const packed: GameRecord = structuredClone(record);
packed.turns = []
const usernames = new Set<string>()
for (const turn of record.turns) {
if (turn.intents.length != 0) {
packed.turns.push(turn)
for (const intent of turn.intents) {
if (intent.type == 'spawn') {
usernames.add(intent.name)
}
}
}
}
packed.usernames = Array.from(usernames)
packed.durationSeconds = Math.floor((record.endTimestampMS - record.startTimestampMS) / 1000)
return packed;
}
export function ToBigQuery(record: GameRecord) {
}
export function assertNever(x: never): never {
throw new Error('Unexpected value: ' + x);
}
+6
View File
@@ -23,6 +23,12 @@ export enum GameMap {
Mena
}
export enum GameType {
Singleplayer,
Public,
Private,
}
export interface UnitInfo {
cost: (player: Player) => Gold
// Determines if its owner changes when its tile is conquered.