126 lines
5.0 KiB
Go
126 lines
5.0 KiB
Go
package ports
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
)
|
|
|
|
//go:generate go run go.uber.org/mock/mockgen -destination=../adapters/mocks/mock_engineclient.go -package=mocks galaxy/gamemaster/internal/ports EngineClient
|
|
|
|
// EngineClient is the narrow surface Game Master uses against a running
|
|
// engine container. The production adapter (Stage 12) speaks REST/JSON
|
|
// against the engine routes documented in `galaxy/game/openapi.yaml`:
|
|
//
|
|
// - admin paths under `/api/v1/admin/*` (init, status, turn,
|
|
// race/banish);
|
|
// - player paths under `/api/v1/{command, order, report}`.
|
|
//
|
|
// The admin-path responses are typed (Init, Status, Turn) because GM
|
|
// reads structured fields out of them (`current_turn`, `finished`,
|
|
// per-player stats). The player-path payloads are forwarded verbatim:
|
|
// the gateway transcodes FlatBuffers to JSON, GM passes the JSON
|
|
// through, and the engine response is returned to the gateway
|
|
// unchanged.
|
|
type EngineClient interface {
|
|
// Init calls POST /api/v1/admin/init. The returned StateResponse
|
|
// carries the initial player roster used to install
|
|
// `player_mappings`.
|
|
Init(ctx context.Context, baseURL string, request InitRequest) (StateResponse, error)
|
|
|
|
// Status calls GET /api/v1/admin/status. Used by inspect surfaces
|
|
// and by recovery flows.
|
|
Status(ctx context.Context, baseURL string) (StateResponse, error)
|
|
|
|
// Turn calls PUT /api/v1/admin/turn. The returned StateResponse
|
|
// carries the new turn number, the per-player stats projected into
|
|
// `player_turn_stats`, and the `finished` flag.
|
|
Turn(ctx context.Context, baseURL string) (StateResponse, error)
|
|
|
|
// BanishRace calls POST /api/v1/admin/race/banish with body
|
|
// `{race_name}`. The engine returns 204 on success.
|
|
BanishRace(ctx context.Context, baseURL, raceName string) error
|
|
|
|
// ExecuteCommands calls PUT /api/v1/command. The request payload
|
|
// is forwarded verbatim; the engine response body is returned
|
|
// verbatim.
|
|
ExecuteCommands(ctx context.Context, baseURL string, payload json.RawMessage) (json.RawMessage, error)
|
|
|
|
// PutOrders calls PUT /api/v1/order with the same forwarding
|
|
// semantics as ExecuteCommands.
|
|
PutOrders(ctx context.Context, baseURL string, payload json.RawMessage) (json.RawMessage, error)
|
|
|
|
// GetReport calls GET /api/v1/report?player=<raceName>&turn=<turn>.
|
|
// The engine response body is returned verbatim.
|
|
GetReport(ctx context.Context, baseURL, raceName string, turn int) (json.RawMessage, error)
|
|
}
|
|
|
|
// InitRequest carries the race roster sent to the engine `/admin/init`
|
|
// route. The shape mirrors `galaxy/game/openapi.yaml`'s `InitRequest`.
|
|
type InitRequest struct {
|
|
// Races stores the per-player race entries in the order returned
|
|
// by Lobby's roster.
|
|
Races []InitRace
|
|
}
|
|
|
|
// InitRace stores one entry of an InitRequest.
|
|
type InitRace struct {
|
|
// RaceName stores the in-game race name reserved for the player.
|
|
RaceName string
|
|
}
|
|
|
|
// StateResponse is the typed projection of the engine's `StateResponse`
|
|
// payload (`galaxy/game/openapi.yaml`). GM reads only the fields it
|
|
// needs; the adapter is allowed to discard the rest.
|
|
type StateResponse struct {
|
|
// Turn stores the engine's current turn number.
|
|
Turn int
|
|
|
|
// Players stores the per-player state entries returned by the
|
|
// engine. Each entry is mapped into `player_turn_stats[]` by
|
|
// resolving `RaceName` through `playermappingstore.ListByGame` to
|
|
// the platform `user_id`.
|
|
Players []PlayerState
|
|
|
|
// Finished reports whether the engine considers the game finished.
|
|
// Becomes true on a turn-generation response when the engine's
|
|
// finish condition is satisfied.
|
|
Finished bool
|
|
}
|
|
|
|
// PlayerState stores one entry of StateResponse.Players. The set of
|
|
// fields is the minimum GM needs from the engine surface; the adapter
|
|
// may decode additional fields and discard them.
|
|
type PlayerState struct {
|
|
// RaceName stores the in-game race name.
|
|
RaceName string
|
|
|
|
// EnginePlayerUUID stores the engine-side player handle. Populated
|
|
// from `/admin/init` and `/admin/status`.
|
|
EnginePlayerUUID string
|
|
|
|
// Planets stores the planet count reported for this player on the
|
|
// most recent turn.
|
|
Planets int
|
|
|
|
// Population stores the population count reported for this player
|
|
// on the most recent turn.
|
|
Population int
|
|
}
|
|
|
|
// ErrEngineUnreachable reports that the engine returned a transport
|
|
// error or 5xx status code. Surfaced to callers as `engine_unreachable`.
|
|
var ErrEngineUnreachable = errors.New("engine unreachable")
|
|
|
|
// ErrEngineProtocolViolation reports that the engine responded with a
|
|
// payload that did not match the expected schema (missing required
|
|
// fields, malformed JSON, unexpected types). Surfaced as
|
|
// `engine_protocol_violation`.
|
|
var ErrEngineProtocolViolation = errors.New("engine protocol violation")
|
|
|
|
// ErrEngineValidation reports that the engine returned 4xx with a
|
|
// per-command result. Surfaced as `engine_validation_error`; the
|
|
// engine's body is returned verbatim to the caller through the player
|
|
// command/order forwarding paths.
|
|
var ErrEngineValidation = errors.New("engine validation error")
|