feat: add controlled scum player state patches

This commit is contained in:
npc0-hue
2026-07-28 16:10:06 +08:00
parent 1e31a87888
commit f496fb12ec
25 changed files with 1017 additions and 48 deletions
+91
View File
@@ -0,0 +1,91 @@
package dto
import (
"browser.local/platform/domain"
"time"
)
type GamePlayerStateFieldResponse struct {
Key string `json:"key"`
Label string `json:"label"`
Kind string `json:"kind"`
Minimum float64 `json:"minimum"`
Maximum float64 `json:"maximum"`
Value float64 `json:"value"`
}
type GamePlayerStateResponse struct {
GameVersion string `json:"gameVersion"`
StateVersion string `json:"stateVersion"`
SafetyWindow string `json:"safetyWindow,omitempty"`
MaintenanceVerified bool `json:"maintenanceVerified"`
PlayerOnline bool `json:"playerOnline"`
Supported bool `json:"supported"`
Fields []GamePlayerStateFieldResponse `json:"fields"`
ObservedAt time.Time `json:"observedAt"`
}
type GamePlayerStatePatchChangeRequest struct {
FieldKey string `json:"fieldKey"`
Before float64 `json:"before"`
After float64 `json:"after"`
}
type GamePlayerStatePatchRequest struct {
GameVersion string `json:"gameVersion"`
ExpectedStateVersion string `json:"expectedStateVersion"`
SafetyWindow string `json:"safetyWindow"`
Changes []GamePlayerStatePatchChangeRequest `json:"changes"`
Reason string `json:"reason"`
}
type GamePlayerStatePatchChangeResponse struct {
FieldKey string `json:"fieldKey"`
Before float64 `json:"before"`
After float64 `json:"after"`
}
type GamePlayerStatePatchResponse struct {
ID string `json:"id"`
GameVersion string `json:"gameVersion"`
ExpectedStateVersion string `json:"expectedStateVersion"`
Changes []GamePlayerStatePatchChangeResponse `json:"changes"`
Reason string `json:"reason"`
RequesterID string `json:"requesterId"`
ApproverID string `json:"approverId,omitempty"`
Status string `json:"status"`
BridgeCommandID string `json:"bridgeCommandId,omitempty"`
ExecutionSummary string `json:"executionSummary,omitempty"`
ConfirmedStateVersion string `json:"confirmedStateVersion,omitempty"`
CreatedAt time.Time `json:"createdAt"`
ApprovedAt time.Time `json:"approvedAt,omitempty"`
CompletedAt time.Time `json:"completedAt,omitempty"`
}
type GamePlayerStatePatchListResponse struct {
Items []GamePlayerStatePatchResponse `json:"items"`
}
func (request GamePlayerStatePatchRequest) ToDomain() domain.GamePlayerStatePatchRequest {
changes := make([]domain.GamePlayerStatePatchChange, len(request.Changes))
for i, change := range request.Changes {
changes[i] = domain.GamePlayerStatePatchChange{FieldKey: change.FieldKey, Before: change.Before, After: change.After}
}
return domain.GamePlayerStatePatchRequest{GameVersion: request.GameVersion, ExpectedStateVersion: request.ExpectedStateVersion, SafetyWindow: request.SafetyWindow, Changes: changes, Reason: request.Reason}
}
func GamePlayerStateFromDomain(value domain.GamePlayerStateSnapshot) GamePlayerStateResponse {
catalog, supported := domain.SCUMPlayerStateCatalogForVersion(value.GameVersion)
fields := make([]GamePlayerStateFieldResponse, 0, len(catalog.Fields))
for _, field := range catalog.Fields {
fields = append(fields, GamePlayerStateFieldResponse{Key: field.Key, Label: field.Label, Kind: string(field.Kind), Minimum: field.Minimum, Maximum: field.Maximum, Value: value.Fields[field.Key]})
}
return GamePlayerStateResponse{GameVersion: value.GameVersion, StateVersion: value.StateVersion, SafetyWindow: value.SafetyWindow, MaintenanceVerified: value.MaintenanceVerified, PlayerOnline: value.PlayerOnline, Supported: supported, Fields: fields, ObservedAt: value.ObservedAt}
}
func GamePlayerStatePatchFromDomain(value domain.GamePlayerStatePatch) GamePlayerStatePatchResponse {
changes := make([]GamePlayerStatePatchChangeResponse, len(value.Changes))
for i, change := range value.Changes {
changes[i] = GamePlayerStatePatchChangeResponse{FieldKey: change.FieldKey, Before: change.Before, After: change.After}
}
return GamePlayerStatePatchResponse{ID: value.ID, GameVersion: value.GameVersion, ExpectedStateVersion: value.ExpectedStateVersion, Changes: changes, Reason: value.Reason, RequesterID: value.RequesterID, ApproverID: value.ApproverID, Status: string(value.Status), BridgeCommandID: value.BridgeCommandID, ExecutionSummary: value.ExecutionSummary, ConfirmedStateVersion: value.ConfirmedStateVersion, CreatedAt: value.CreatedAt, ApprovedAt: value.ApprovedAt, CompletedAt: value.CompletedAt}
}
func GamePlayerStatePatchesFromDomain(values []domain.GamePlayerStatePatch) GamePlayerStatePatchListResponse {
items := make([]GamePlayerStatePatchResponse, len(values))
for i, value := range values {
items[i] = GamePlayerStatePatchFromDomain(value)
}
return GamePlayerStatePatchListResponse{Items: items}
}