mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-16 10:53:06 +00:00
Account Modal - Games Tab (#4473)
## Description: Continuation of https://github.com/openfrontio/infra/pull/386, adds play games sessions <img width="971" height="771" alt="image" src="https://github.com/user-attachments/assets/42c6bcbb-d690-4cd1-b859-3299a03f4350" /> ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory ## Please put your Discord username so you can be contacted if a bug or regression is found: w.o.n --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+52
-13
@@ -2,7 +2,7 @@ import { z } from "zod";
|
||||
import { base64urlToUuid } from "./Base64";
|
||||
import { ClanTagSchema } from "./Schemas";
|
||||
import { BigIntStringSchema, PlayerStatsSchema } from "./StatsSchemas";
|
||||
import { Difficulty, GameMode, GameType, RankedType } from "./game/Game";
|
||||
import { Difficulty, GameMode, RankedType } from "./game/Game";
|
||||
|
||||
function stripClanTagFromUsername(username: string): string {
|
||||
return username.replace(/^\s*\[[a-zA-Z0-9]{2,5}\]\s*/u, "").trim();
|
||||
@@ -160,25 +160,64 @@ export const PlayerStatsTreeSchema = z.object({
|
||||
});
|
||||
export type PlayerStatsTree = z.infer<typeof PlayerStatsTreeSchema>;
|
||||
|
||||
export const PlayerGameSchema = z.object({
|
||||
gameId: z.string(),
|
||||
start: z.iso.datetime(),
|
||||
mode: z.enum(GameMode),
|
||||
type: z.enum(GameType),
|
||||
map: z.string(),
|
||||
difficulty: z.enum(Difficulty),
|
||||
clientId: z.string().optional(),
|
||||
});
|
||||
export type PlayerGame = z.infer<typeof PlayerGameSchema>;
|
||||
|
||||
export const PlayerProfileSchema = z.object({
|
||||
createdAt: z.iso.datetime(),
|
||||
user: DiscordUserSchema.optional(),
|
||||
games: PlayerGameSchema.array(),
|
||||
stats: PlayerStatsTreeSchema,
|
||||
});
|
||||
export type PlayerProfile = z.infer<typeof PlayerProfileSchema>;
|
||||
|
||||
// Mode buckets for GET /public/player/:publicId/games — mirrors the clan
|
||||
// game-history filter (see ClanGameFilter). Resolved server-side off the
|
||||
// games join (mode / ranked_type / player_teams).
|
||||
export const PlayerGameModeFilters = ["ffa", "team", "hvn", "ranked"] as const;
|
||||
export const PlayerGameModeFilterSchema = z.enum(PlayerGameModeFilters);
|
||||
export type PlayerGameModeFilter = z.infer<typeof PlayerGameModeFilterSchema>;
|
||||
|
||||
// Game-type split — orthogonal to the mode filter. Matches games.type.
|
||||
export const PlayerGameTypeFilters = [
|
||||
"public",
|
||||
"private",
|
||||
"singleplayer",
|
||||
] as const;
|
||||
export const PlayerGameTypeFilterSchema = z.enum(PlayerGameTypeFilters);
|
||||
export type PlayerGameTypeFilter = z.infer<typeof PlayerGameTypeFilterSchema>;
|
||||
|
||||
// "incomplete" covers games with no recorded winner (winnerType IS NULL).
|
||||
export const PlayerGameResultSchema = z.enum([
|
||||
"victory",
|
||||
"defeat",
|
||||
"incomplete",
|
||||
]);
|
||||
export type PlayerGameResult = z.infer<typeof PlayerGameResultSchema>;
|
||||
|
||||
export const PublicPlayerGameSchema = z.object({
|
||||
gameId: z.string(),
|
||||
start: z.iso.datetime(),
|
||||
durationSeconds: z.number().int().nonnegative(),
|
||||
map: z.string(),
|
||||
mode: z.string(),
|
||||
type: z.string(),
|
||||
playerTeams: z.string().nullable(),
|
||||
rankedType: z.string(),
|
||||
result: PlayerGameResultSchema,
|
||||
totalPlayers: z.number().int().nonnegative().nullable(),
|
||||
username: z.string(),
|
||||
clanTag: z.string().nullable(),
|
||||
});
|
||||
export type PublicPlayerGame = z.infer<typeof PublicPlayerGameSchema>;
|
||||
|
||||
export const PublicPlayerGamesResponseSchema = z.object({
|
||||
results: PublicPlayerGameSchema.array(),
|
||||
// Opaque continuation token. Round-trip verbatim as the `cursor` query
|
||||
// parameter to fetch the next page; never construct or parse it. `null`
|
||||
// means the server has no more rows to serve.
|
||||
nextCursor: z.string().nullable(),
|
||||
});
|
||||
export type PublicPlayerGamesResponse = z.infer<
|
||||
typeof PublicPlayerGamesResponseSchema
|
||||
>;
|
||||
|
||||
export const PlayerLeaderboardEntrySchema = z.object({
|
||||
rank: z.number(),
|
||||
playerId: z.string(),
|
||||
|
||||
Reference in New Issue
Block a user