Files
galaxy-game/pkg/transcoder/lobby.go
T
2026-04-28 20:39:18 +02:00

257 lines
9.4 KiB
Go

package transcoder
import (
"errors"
"fmt"
"time"
lobbymodel "galaxy/model/lobby"
lobbyfbs "galaxy/schema/fbs/lobby"
flatbuffers "github.com/google/flatbuffers/go"
)
// MyGamesListRequestToPayload converts a typed lobbymodel.MyGamesListRequest
// to FlatBuffers bytes suitable for the authenticated gateway transport.
func MyGamesListRequestToPayload(request *lobbymodel.MyGamesListRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode my games list request payload: request is nil")
}
builder := flatbuffers.NewBuilder(32)
lobbyfbs.MyGamesListRequestStart(builder)
offset := lobbyfbs.MyGamesListRequestEnd(builder)
lobbyfbs.FinishMyGamesListRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToMyGamesListRequest converts FlatBuffers payload bytes into
// lobbymodel.MyGamesListRequest.
func PayloadToMyGamesListRequest(data []byte) (result *lobbymodel.MyGamesListRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode my games list request payload: data is empty")
}
defer recoverLobbyDecodePanic("decode my games list request payload", &result, &err)
_ = lobbyfbs.GetRootAsMyGamesListRequest(data, 0)
return &lobbymodel.MyGamesListRequest{}, nil
}
// MyGamesListResponseToPayload converts lobbymodel.MyGamesListResponse to
// FlatBuffers bytes suitable for the authenticated gateway transport.
func MyGamesListResponseToPayload(response *lobbymodel.MyGamesListResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode my games list response payload: response is nil")
}
builder := flatbuffers.NewBuilder(512)
itemOffsets := make([]flatbuffers.UOffsetT, len(response.Items))
for index := range response.Items {
itemOffsets[index] = encodeGameSummary(builder, response.Items[index])
}
var itemsVector flatbuffers.UOffsetT
if len(itemOffsets) > 0 {
lobbyfbs.MyGamesListResponseStartItemsVector(builder, len(itemOffsets))
for index := len(itemOffsets) - 1; index >= 0; index-- {
builder.PrependUOffsetT(itemOffsets[index])
}
itemsVector = builder.EndVector(len(itemOffsets))
}
lobbyfbs.MyGamesListResponseStart(builder)
if itemsVector != 0 {
lobbyfbs.MyGamesListResponseAddItems(builder, itemsVector)
}
offset := lobbyfbs.MyGamesListResponseEnd(builder)
lobbyfbs.FinishMyGamesListResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToMyGamesListResponse converts FlatBuffers payload bytes into
// lobbymodel.MyGamesListResponse.
func PayloadToMyGamesListResponse(data []byte) (result *lobbymodel.MyGamesListResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode my games list response payload: data is empty")
}
defer recoverLobbyDecodePanic("decode my games list response payload", &result, &err)
response := lobbyfbs.GetRootAsMyGamesListResponse(data, 0)
out := &lobbymodel.MyGamesListResponse{
Items: make([]lobbymodel.GameSummary, 0, response.ItemsLength()),
}
summary := new(lobbyfbs.GameSummary)
for index := 0; index < response.ItemsLength(); index++ {
if !response.Items(summary, index) {
return nil, fmt.Errorf("decode my games list response payload: items[%d] is missing", index)
}
out.Items = append(out.Items, decodeGameSummary(summary))
}
return out, nil
}
// OpenEnrollmentRequestToPayload converts lobbymodel.OpenEnrollmentRequest to
// FlatBuffers bytes suitable for the authenticated gateway transport.
func OpenEnrollmentRequestToPayload(request *lobbymodel.OpenEnrollmentRequest) ([]byte, error) {
if request == nil {
return nil, errors.New("encode open enrollment request payload: request is nil")
}
builder := flatbuffers.NewBuilder(64)
gameID := builder.CreateString(request.GameID)
lobbyfbs.OpenEnrollmentRequestStart(builder)
lobbyfbs.OpenEnrollmentRequestAddGameId(builder, gameID)
offset := lobbyfbs.OpenEnrollmentRequestEnd(builder)
lobbyfbs.FinishOpenEnrollmentRequestBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToOpenEnrollmentRequest converts FlatBuffers payload bytes into
// lobbymodel.OpenEnrollmentRequest.
func PayloadToOpenEnrollmentRequest(data []byte) (result *lobbymodel.OpenEnrollmentRequest, err error) {
if len(data) == 0 {
return nil, errors.New("decode open enrollment request payload: data is empty")
}
defer recoverLobbyDecodePanic("decode open enrollment request payload", &result, &err)
request := lobbyfbs.GetRootAsOpenEnrollmentRequest(data, 0)
return &lobbymodel.OpenEnrollmentRequest{
GameID: string(request.GameId()),
}, nil
}
// OpenEnrollmentResponseToPayload converts lobbymodel.OpenEnrollmentResponse to
// FlatBuffers bytes suitable for the authenticated gateway transport.
func OpenEnrollmentResponseToPayload(response *lobbymodel.OpenEnrollmentResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode open enrollment response payload: response is nil")
}
builder := flatbuffers.NewBuilder(64)
gameID := builder.CreateString(response.GameID)
status := builder.CreateString(response.Status)
lobbyfbs.OpenEnrollmentResponseStart(builder)
lobbyfbs.OpenEnrollmentResponseAddGameId(builder, gameID)
lobbyfbs.OpenEnrollmentResponseAddStatus(builder, status)
offset := lobbyfbs.OpenEnrollmentResponseEnd(builder)
lobbyfbs.FinishOpenEnrollmentResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToOpenEnrollmentResponse converts FlatBuffers payload bytes into
// lobbymodel.OpenEnrollmentResponse.
func PayloadToOpenEnrollmentResponse(data []byte) (result *lobbymodel.OpenEnrollmentResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode open enrollment response payload: data is empty")
}
defer recoverLobbyDecodePanic("decode open enrollment response payload", &result, &err)
response := lobbyfbs.GetRootAsOpenEnrollmentResponse(data, 0)
return &lobbymodel.OpenEnrollmentResponse{
GameID: string(response.GameId()),
Status: string(response.Status()),
}, nil
}
// LobbyErrorResponseToPayload converts lobbymodel.ErrorResponse to FlatBuffers
// bytes suitable for the authenticated gateway transport.
func LobbyErrorResponseToPayload(response *lobbymodel.ErrorResponse) ([]byte, error) {
if response == nil {
return nil, errors.New("encode lobby error response payload: response is nil")
}
builder := flatbuffers.NewBuilder(128)
code := builder.CreateString(response.Error.Code)
message := builder.CreateString(response.Error.Message)
lobbyfbs.ErrorBodyStart(builder)
lobbyfbs.ErrorBodyAddCode(builder, code)
lobbyfbs.ErrorBodyAddMessage(builder, message)
errorOffset := lobbyfbs.ErrorBodyEnd(builder)
lobbyfbs.ErrorResponseStart(builder)
lobbyfbs.ErrorResponseAddError(builder, errorOffset)
offset := lobbyfbs.ErrorResponseEnd(builder)
lobbyfbs.FinishErrorResponseBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyErrorResponse converts FlatBuffers payload bytes into
// lobbymodel.ErrorResponse.
func PayloadToLobbyErrorResponse(data []byte) (result *lobbymodel.ErrorResponse, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby error response payload: data is empty")
}
defer recoverLobbyDecodePanic("decode lobby error response payload", &result, &err)
response := lobbyfbs.GetRootAsErrorResponse(data, 0)
body := response.Error(nil)
if body == nil {
return nil, errors.New("decode lobby error response payload: error is missing")
}
return &lobbymodel.ErrorResponse{
Error: lobbymodel.ErrorBody{
Code: string(body.Code()),
Message: string(body.Message()),
},
}, nil
}
func encodeGameSummary(builder *flatbuffers.Builder, summary lobbymodel.GameSummary) flatbuffers.UOffsetT {
gameID := builder.CreateString(summary.GameID)
gameName := builder.CreateString(summary.GameName)
gameType := builder.CreateString(summary.GameType)
status := builder.CreateString(summary.Status)
ownerUserID := builder.CreateString(summary.OwnerUserID)
lobbyfbs.GameSummaryStart(builder)
lobbyfbs.GameSummaryAddGameId(builder, gameID)
lobbyfbs.GameSummaryAddGameName(builder, gameName)
lobbyfbs.GameSummaryAddGameType(builder, gameType)
lobbyfbs.GameSummaryAddStatus(builder, status)
lobbyfbs.GameSummaryAddOwnerUserId(builder, ownerUserID)
lobbyfbs.GameSummaryAddMinPlayers(builder, int32(summary.MinPlayers))
lobbyfbs.GameSummaryAddMaxPlayers(builder, int32(summary.MaxPlayers))
lobbyfbs.GameSummaryAddEnrollmentEndsAtMs(builder, summary.EnrollmentEndsAt.UTC().UnixMilli())
lobbyfbs.GameSummaryAddCreatedAtMs(builder, summary.CreatedAt.UTC().UnixMilli())
lobbyfbs.GameSummaryAddUpdatedAtMs(builder, summary.UpdatedAt.UTC().UnixMilli())
return lobbyfbs.GameSummaryEnd(builder)
}
func decodeGameSummary(summary *lobbyfbs.GameSummary) lobbymodel.GameSummary {
return lobbymodel.GameSummary{
GameID: string(summary.GameId()),
GameName: string(summary.GameName()),
GameType: string(summary.GameType()),
Status: string(summary.Status()),
OwnerUserID: string(summary.OwnerUserId()),
MinPlayers: int(summary.MinPlayers()),
MaxPlayers: int(summary.MaxPlayers()),
EnrollmentEndsAt: time.UnixMilli(summary.EnrollmentEndsAtMs()).UTC(),
CreatedAt: time.UnixMilli(summary.CreatedAtMs()).UTC(),
UpdatedAt: time.UnixMilli(summary.UpdatedAtMs()).UTC(),
}
}
func recoverLobbyDecodePanic[T any](message string, result **T, err *error) {
if recovered := recover(); recovered != nil {
*result = nil
*err = fmt.Errorf("%s: panic recovered: %v", message, recovered)
}
}