feat: add ranking and hall of fame features
- Implemented new routes for Best General and Hall of Fame views in the frontend. - Created BestGeneralView and HallOfFameView components to display rankings based on game data. - Added new database models for RankData and HallOfFame to store ranking information. - Introduced ranking types and hall of fame types in common types for better type safety. - Developed ranking router to handle fetching of best general and hall of fame data. - Updated database schema with migrations to include new tables for rank data and hall of fame. - Enhanced the main view with links to the new ranking features.
This commit is contained in:
@@ -15,3 +15,4 @@ export * from './tournament/autoStart.js';
|
||||
export * from './turnDaemon/types.js';
|
||||
export * from './realtime/keys.js';
|
||||
export * from './realtime/types.js';
|
||||
export * from './ranking/types.js';
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
export const RANK_DATA_TYPES = [
|
||||
'experience',
|
||||
'dedication',
|
||||
'firenum',
|
||||
'warnum',
|
||||
'killnum',
|
||||
'deathnum',
|
||||
'occupied',
|
||||
'killcrew',
|
||||
'deathcrew',
|
||||
'killcrew_person',
|
||||
'deathcrew_person',
|
||||
'dex1',
|
||||
'dex2',
|
||||
'dex3',
|
||||
'dex4',
|
||||
'dex5',
|
||||
'ttw',
|
||||
'ttd',
|
||||
'ttl',
|
||||
'ttg',
|
||||
'ttp',
|
||||
'tlw',
|
||||
'tld',
|
||||
'tll',
|
||||
'tlg',
|
||||
'tlp',
|
||||
'tsw',
|
||||
'tsd',
|
||||
'tsl',
|
||||
'tsg',
|
||||
'tsp',
|
||||
'tiw',
|
||||
'tid',
|
||||
'til',
|
||||
'tig',
|
||||
'tip',
|
||||
'betwin',
|
||||
'betgold',
|
||||
'betwingold',
|
||||
'inherit_earned',
|
||||
'inherit_spent',
|
||||
] as const;
|
||||
|
||||
export type RankDataType = (typeof RANK_DATA_TYPES)[number];
|
||||
|
||||
export const HALL_OF_FAME_TYPES = [
|
||||
'experience',
|
||||
'dedication',
|
||||
'firenum',
|
||||
'warnum',
|
||||
'killnum',
|
||||
'winrate',
|
||||
'occupied',
|
||||
'killcrew',
|
||||
'killrate',
|
||||
'killcrew_person',
|
||||
'killrate_person',
|
||||
'dex1',
|
||||
'dex2',
|
||||
'dex3',
|
||||
'dex4',
|
||||
'dex5',
|
||||
'ttrate',
|
||||
'tlrate',
|
||||
'tsrate',
|
||||
'tirate',
|
||||
'betgold',
|
||||
'betwin',
|
||||
'betwingold',
|
||||
'betrate',
|
||||
] as const;
|
||||
|
||||
export type HallOfFameType = (typeof HALL_OF_FAME_TYPES)[number];
|
||||
@@ -146,6 +146,53 @@ model General {
|
||||
@@map("general")
|
||||
}
|
||||
|
||||
model RankData {
|
||||
id Int @id @default(autoincrement())
|
||||
nationId Int @default(0) @map("nation_id")
|
||||
generalId Int @map("general_id")
|
||||
type String @db.VarChar(20)
|
||||
value Int @default(0)
|
||||
|
||||
@@unique([generalId, type])
|
||||
@@index([type, value], name: "by_type")
|
||||
@@index([nationId, type, value], name: "by_nation")
|
||||
@@map("rank_data")
|
||||
}
|
||||
|
||||
model HallOfFame {
|
||||
id Int @id @default(autoincrement())
|
||||
serverId String @map("server_id")
|
||||
season Int
|
||||
scenario Int
|
||||
generalNo Int @map("general_no")
|
||||
type String @db.VarChar(20)
|
||||
value Float
|
||||
owner String? @map("owner")
|
||||
aux Json @default(dbgenerated("'{}'::jsonb"))
|
||||
|
||||
@@unique([serverId, type, generalNo])
|
||||
@@unique([owner, serverId, type], name: "hall_owner")
|
||||
@@index([serverId, type, value], name: "server_show")
|
||||
@@index([season, scenario, type, value], name: "scenario")
|
||||
@@map("hall")
|
||||
}
|
||||
|
||||
model GameHistory {
|
||||
id Int @id @default(autoincrement())
|
||||
serverId String @map("server_id")
|
||||
date DateTime
|
||||
winnerNation Int? @map("winner_nation")
|
||||
map String? @map("map")
|
||||
season Int
|
||||
scenario Int
|
||||
scenarioName String @map("scenario_name")
|
||||
env Json @default(dbgenerated("'{}'::jsonb"))
|
||||
|
||||
@@unique([serverId])
|
||||
@@index([date])
|
||||
@@map("ng_games")
|
||||
}
|
||||
|
||||
model Troop {
|
||||
troopLeaderId Int @id @map("troop_leader")
|
||||
nationId Int @map("nation")
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
CREATE TABLE "rank_data" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"nation_id" INTEGER NOT NULL DEFAULT 0,
|
||||
"general_id" INTEGER NOT NULL,
|
||||
"type" VARCHAR(20) NOT NULL,
|
||||
"value" INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "rank_data_by_general" ON "rank_data"("general_id", "type");
|
||||
CREATE INDEX "rank_data_by_type" ON "rank_data"("type", "value");
|
||||
CREATE INDEX "rank_data_by_nation" ON "rank_data"("nation_id", "type", "value");
|
||||
|
||||
CREATE TABLE "hall" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"server_id" TEXT NOT NULL,
|
||||
"season" INTEGER NOT NULL,
|
||||
"scenario" INTEGER NOT NULL,
|
||||
"general_no" INTEGER NOT NULL,
|
||||
"type" VARCHAR(20) NOT NULL,
|
||||
"value" DOUBLE PRECISION NOT NULL,
|
||||
"owner" TEXT,
|
||||
"aux" JSONB NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "hall_server_general" ON "hall"("server_id", "type", "general_no");
|
||||
CREATE UNIQUE INDEX "hall_owner" ON "hall"("owner", "server_id", "type");
|
||||
CREATE INDEX "hall_server_show" ON "hall"("server_id", "type", "value");
|
||||
CREATE INDEX "hall_scenario" ON "hall"("season", "scenario", "type", "value");
|
||||
|
||||
CREATE TABLE "ng_games" (
|
||||
"id" SERIAL PRIMARY KEY,
|
||||
"server_id" TEXT NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"winner_nation" INTEGER,
|
||||
"map" TEXT,
|
||||
"season" INTEGER NOT NULL,
|
||||
"scenario" INTEGER NOT NULL,
|
||||
"scenario_name" TEXT NOT NULL,
|
||||
"env" JSONB NOT NULL DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "ng_games_server_id" ON "ng_games"("server_id");
|
||||
CREATE INDEX "ng_games_date" ON "ng_games"("date");
|
||||
@@ -11,6 +11,9 @@ export interface DatabaseClient {
|
||||
diplomacy: GamePrisma.DiplomacyDelegate;
|
||||
diplomacyLetter: GamePrisma.DiplomacyLetterDelegate;
|
||||
yearbookHistory: GamePrisma.YearbookHistoryDelegate;
|
||||
rankData: GamePrisma.RankDataDelegate;
|
||||
hallOfFame: GamePrisma.HallOfFameDelegate;
|
||||
gameHistory: GamePrisma.GameHistoryDelegate;
|
||||
generalTurn: GamePrisma.GeneralTurnDelegate;
|
||||
nationTurn: GamePrisma.NationTurnDelegate;
|
||||
troop: GamePrisma.TroopDelegate;
|
||||
|
||||
Reference in New Issue
Block a user