From 535d2c36491c033476460543e8a5accaa46c0c5e Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Sun, 11 Oct 2026 01:45:53 +0700 Subject: [PATCH] up --- proto/main.proto | 27 ++++++++ .../crabs/evening_detective_server/index.ts | 66 +++++++++++++++++++ src/components/GamePage.vue | 15 ++++- src/components/GamesPage.vue | 7 ++ src/components/TeamStoryPage.vue | 1 + 5 files changed, 115 insertions(+), 1 deletion(-) diff --git a/proto/main.proto b/proto/main.proto index 3639752..7137476 100644 --- a/proto/main.proto +++ b/proto/main.proto @@ -626,6 +626,17 @@ service EveningDetectiveServer { }; } + rpc StartGameExport(StartGameExportReq) returns (GameExportRsp) { + option (google.api.http) = { + post: "/api/games/{ID}/export" + body: "*" + }; + } + + rpc GetGameExport(GetGameExportReq) returns (GameExportRsp) { + option (google.api.http) = {get: "/api/games/{ID}/export"}; + } + rpc IssueGameTickets(IssueGameTicketsReq) returns (IssueGameTicketsRsp) { option (google.api.http) = { post: "/api/games/{gameID}/tickets" @@ -1628,8 +1639,24 @@ message Game { optional google.protobuf.Timestamp ended_at = 9; string format = 10; string location = 11; + GameExport export = 12; } +// Download ready ZIP through the authenticated streaming HTTP route: +// GET /api/games/{ID}/export/download (not an HttpBody RPC). +message GameExport { + string ID = 1; + string state = 2; // preparing, ready or failed; preparing/ready lock game writes. + string packageID = 3; + int64 size = 4; + string sha256 = 5; + string failure = 6; +} + +message StartGameExportReq { int32 ID = 1; } +message GetGameExportReq { int32 ID = 1; } +message GameExportRsp { GameExport export = 1; } + enum ScreenMode { SCREEN_MODE_UNSPECIFIED = 0; SCREEN_MODE_COVER = 1; diff --git a/src/api/generated/crabs/evening_detective_server/index.ts b/src/api/generated/crabs/evening_detective_server/index.ts index bffaea5..b6d09d6 100644 --- a/src/api/generated/crabs/evening_detective_server/index.ts +++ b/src/api/generated/crabs/evening_detective_server/index.ts @@ -560,6 +560,30 @@ export type Game = { endedAt?: wellKnownTimestamp; format: string | undefined; location: string | undefined; + export: GameExport | undefined; +}; + +// Download ready ZIP through the authenticated streaming HTTP route: +// GET /api/games/{ID}/export/download (not an HttpBody RPC). +export type GameExport = { + ID: string | undefined; + state: string | undefined; + packageID: string | undefined; + size: number | undefined; + sha256: string | undefined; + failure: string | undefined; +}; + +export type StartGameExportReq = { + ID: number | undefined; +}; + +export type GetGameExportReq = { + ID: number | undefined; +}; + +export type GameExportRsp = { + export: GameExport | undefined; }; export type ScreenState = { @@ -1248,6 +1272,8 @@ export interface EveningDetectiveServer { AddGame(request: AddGameReq): Promise; GetGames(request: GetGamesReq): Promise; GetGame(request: GetGameReq): Promise; + StartGameExport(request: StartGameExportReq): Promise; + GetGameExport(request: GetGameExportReq): Promise; IssueGameTickets(request: IssueGameTicketsReq): Promise; GetTicket(request: GetTicketReq): Promise; AcceptTicket(request: AcceptTicketReq): Promise; @@ -2392,6 +2418,46 @@ export function createEveningDetectiveServerClient( method: "GetGame", }) as Promise; }, + StartGameExport(request) { // eslint-disable-line @typescript-eslint/no-unused-vars + if (!request.ID) { + throw new Error("missing required field request.ID"); + } + const path = `api/games/${request.ID}/export`; // eslint-disable-line quotes + const body = JSON.stringify(request); + const queryParams: string[] = []; + let uri = path; + if (queryParams.length > 0) { + uri += `?${queryParams.join("&")}` + } + return handler({ + path: uri, + method: "POST", + body, + }, { + service: "EveningDetectiveServer", + method: "StartGameExport", + }) as Promise; + }, + GetGameExport(request) { // eslint-disable-line @typescript-eslint/no-unused-vars + if (!request.ID) { + throw new Error("missing required field request.ID"); + } + const path = `api/games/${request.ID}/export`; // eslint-disable-line quotes + const body = null; + const queryParams: string[] = []; + let uri = path; + if (queryParams.length > 0) { + uri += `?${queryParams.join("&")}` + } + return handler({ + path: uri, + method: "GET", + body, + }, { + service: "EveningDetectiveServer", + method: "GetGameExport", + }) as Promise; + }, IssueGameTickets(request) { // eslint-disable-line @typescript-eslint/no-unused-vars if (!request.gameID) { throw new Error("missing required field request.gameID"); diff --git a/src/components/GamePage.vue b/src/components/GamePage.vue index f77f96b..05f67ee 100644 --- a/src/components/GamePage.vue +++ b/src/components/GamePage.vue @@ -1,7 +1,7 @@