517 lines
20 KiB
Go
517 lines
20 KiB
Go
package gameapi
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
gamev1 "hyapp.local/api/proto/game/v1"
|
||
)
|
||
|
||
type gameListData struct {
|
||
Games []gameItemData `json:"games"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type gameItemData struct {
|
||
GameID string `json:"game_id"`
|
||
PlatformCode string `json:"platform_code"`
|
||
NameKey string `json:"name_key"`
|
||
Name string `json:"name"`
|
||
IconURL string `json:"icon_url"`
|
||
CoverURL string `json:"cover_url"`
|
||
Category string `json:"category"`
|
||
LaunchMode string `json:"launch_mode"`
|
||
Orientation string `json:"orientation"`
|
||
SafeHeight int32 `json:"safe_height"`
|
||
SafeHeightV2 int32 `json:"safeHeight"`
|
||
MinCoin int64 `json:"min_coin"`
|
||
Enabled bool `json:"enabled"`
|
||
Maintenance bool `json:"maintenance"`
|
||
SortOrder int32 `json:"sort_order"`
|
||
}
|
||
|
||
type exploreWinnerListData struct {
|
||
Items []exploreWinnerItemData `json:"items"`
|
||
Total int `json:"total"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type exploreWinnerItemData struct {
|
||
WinID string `json:"win_id"`
|
||
GameCode string `json:"game_code"`
|
||
GameID string `json:"game_id"`
|
||
UserID string `json:"user_id"`
|
||
UserIDNumber int64 `json:"user_id_number"`
|
||
DisplayName string `json:"display_name"`
|
||
AvatarURL string `json:"avatar_url"`
|
||
CoinAmount int64 `json:"coin_amount"`
|
||
WonAtMS int64 `json:"won_at_ms"`
|
||
}
|
||
|
||
type gameLaunchData struct {
|
||
SessionID string `json:"session_id"`
|
||
LaunchURL string `json:"launch_url"`
|
||
ExpiresAtMS int64 `json:"expires_at_ms"`
|
||
Orientation string `json:"orientation"`
|
||
SafeHeight int32 `json:"safe_height"`
|
||
SafeHeightV2 int32 `json:"safeHeight"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type gameBridgeScriptData struct {
|
||
BridgeScriptURL string `json:"bridge_script_url"`
|
||
BridgeScriptURLV2 string `json:"bridgeScriptUrl"`
|
||
BridgeScriptVersion string `json:"bridge_script_version"`
|
||
BridgeScriptVersionV2 string `json:"bridgeScriptVersion"`
|
||
BridgeScriptSHA256 string `json:"bridge_script_sha256"`
|
||
BridgeScriptSHA256V2 string `json:"bridgeScriptSha256"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type diceMatchData struct {
|
||
Match diceMatchItemData `json:"match"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type diceConfigData struct {
|
||
Config diceConfigItemData `json:"config"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type roomRPSConfigData struct {
|
||
Config roomRPSConfigItemData `json:"config"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type roomRPSChallengeData struct {
|
||
Challenge roomRPSChallengeItemData `json:"challenge"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type roomRPSChallengeListData struct {
|
||
Challenges []*roomRPSChallengeItemData `json:"challenges"`
|
||
NextCursor string `json:"next_cursor"`
|
||
PageSize int32 `json:"page_size"`
|
||
ServerTimeMS int64 `json:"server_time_ms"`
|
||
}
|
||
|
||
type diceConfigItemData struct {
|
||
AppCode string `json:"app_code"`
|
||
GameID string `json:"game_id"`
|
||
Status string `json:"status"`
|
||
StakeOptions []diceStakeOptionData `json:"stake_options"`
|
||
FeeBPS int32 `json:"fee_bps"`
|
||
PoolBPS int32 `json:"pool_bps"`
|
||
MinPlayers int32 `json:"min_players"`
|
||
MaxPlayers int32 `json:"max_players"`
|
||
RobotEnabled bool `json:"robot_enabled"`
|
||
RobotMatchWaitMS int64 `json:"robot_match_wait_ms"`
|
||
PoolBalanceCoin int64 `json:"pool_balance_coin"`
|
||
}
|
||
|
||
type diceStakeOptionData struct {
|
||
StakeCoin int64 `json:"stake_coin"`
|
||
Enabled bool `json:"enabled"`
|
||
SortOrder int32 `json:"sort_order"`
|
||
}
|
||
|
||
type roomRPSConfigItemData struct {
|
||
AppCode string `json:"app_code"`
|
||
GameID string `json:"game_id"`
|
||
Status string `json:"status"`
|
||
ChallengeTimeoutMS int64 `json:"challenge_timeout_ms"`
|
||
RevealCountdownMS int64 `json:"reveal_countdown_ms"`
|
||
StakeGifts []roomRPSStakeGiftData `json:"stake_gifts"`
|
||
}
|
||
|
||
type roomRPSStakeGiftData struct {
|
||
GiftID string `json:"gift_id"`
|
||
GiftIDNumber int64 `json:"gift_id_number"`
|
||
GiftName string `json:"gift_name"`
|
||
GiftIconURL string `json:"gift_icon_url"`
|
||
GiftPriceCoin int64 `json:"gift_price_coin"`
|
||
Enabled bool `json:"enabled"`
|
||
SortOrder int32 `json:"sort_order"`
|
||
}
|
||
|
||
type diceMatchItemData struct {
|
||
AppCode string `json:"app_code"`
|
||
MatchID string `json:"match_id"`
|
||
GameID string `json:"game_id"`
|
||
RoomID string `json:"room_id"`
|
||
RegionID int64 `json:"region_id"`
|
||
MinPlayers int32 `json:"min_players"`
|
||
MaxPlayers int32 `json:"max_players"`
|
||
CurrentPlayers int32 `json:"current_players"`
|
||
StakeCoin int64 `json:"stake_coin"`
|
||
RoundNo int32 `json:"round_no"`
|
||
Status string `json:"status"`
|
||
Result string `json:"result"`
|
||
Participants []diceParticipantItemData `json:"participants"`
|
||
JoinDeadlineMS int64 `json:"join_deadline_ms"`
|
||
ReadyAtMS int64 `json:"ready_at_ms"`
|
||
CreatedAtMS int64 `json:"created_at_ms"`
|
||
UpdatedAtMS int64 `json:"updated_at_ms"`
|
||
SettledAtMS int64 `json:"settled_at_ms"`
|
||
CanceledAtMS int64 `json:"canceled_at_ms"`
|
||
Phase string `json:"phase"`
|
||
PhaseDeadlineMS int64 `json:"phase_deadline_ms"`
|
||
FeeBPS int32 `json:"fee_bps"`
|
||
PoolBPS int32 `json:"pool_bps"`
|
||
MatchMode string `json:"match_mode"`
|
||
ForcedResult string `json:"forced_result"`
|
||
PoolDeltaCoin int64 `json:"pool_delta_coin"`
|
||
}
|
||
|
||
type diceParticipantItemData struct {
|
||
UserID string `json:"user_id"`
|
||
UserIDNumber int64 `json:"user_id_number"`
|
||
SeatNo int32 `json:"seat_no"`
|
||
Status string `json:"status"`
|
||
StakeCoin int64 `json:"stake_coin"`
|
||
DicePoints []int32 `json:"dice_points"`
|
||
RPSGesture string `json:"rps_gesture"`
|
||
Gesture string `json:"gesture"`
|
||
Result string `json:"result"`
|
||
PayoutCoin int64 `json:"payout_coin"`
|
||
BalanceAfter int64 `json:"balance_after"`
|
||
JoinedAtMS int64 `json:"joined_at_ms"`
|
||
UpdatedAtMS int64 `json:"updated_at_ms"`
|
||
ParticipantType string `json:"participant_type"`
|
||
IsRobot bool `json:"is_robot"`
|
||
User diceUserData `json:"user"`
|
||
AvatarFrame map[string]any `json:"avatar_frame"`
|
||
}
|
||
|
||
type diceUserData struct {
|
||
UserID string `json:"user_id"`
|
||
DisplayUserID string `json:"display_user_id"`
|
||
Nickname string `json:"nickname"`
|
||
Avatar string `json:"avatar"`
|
||
}
|
||
|
||
type roomRPSChallengeItemData struct {
|
||
AppCode string `json:"app_code"`
|
||
ChallengeID string `json:"challenge_id"`
|
||
RoomID string `json:"room_id"`
|
||
RegionID int64 `json:"region_id"`
|
||
Status string `json:"status"`
|
||
StakeGiftID string `json:"stake_gift_id"`
|
||
StakeGiftIDNumber int64 `json:"stake_gift_id_number"`
|
||
StakeCoin int64 `json:"stake_coin"`
|
||
Initiator roomRPSPlayerItemData `json:"initiator"`
|
||
Challenger roomRPSPlayerItemData `json:"challenger"`
|
||
WinnerUserID string `json:"winner_user_id"`
|
||
WinnerUserIDNumber int64 `json:"winner_user_id_number"`
|
||
SettlementStatus string `json:"settlement_status"`
|
||
FailureReason string `json:"failure_reason"`
|
||
TimeoutAtMS int64 `json:"timeout_at_ms"`
|
||
RevealAtMS int64 `json:"reveal_at_ms"`
|
||
CreatedAtMS int64 `json:"created_at_ms"`
|
||
MatchedAtMS int64 `json:"matched_at_ms"`
|
||
SettledAtMS int64 `json:"settled_at_ms"`
|
||
UpdatedAtMS int64 `json:"updated_at_ms"`
|
||
}
|
||
|
||
type roomRPSPlayerItemData struct {
|
||
UserID string `json:"user_id"`
|
||
UserIDNumber int64 `json:"user_id_number"`
|
||
Gesture string `json:"gesture"`
|
||
Result string `json:"result"`
|
||
BalanceAfter int64 `json:"balance_after"`
|
||
JoinedAtMS int64 `json:"joined_at_ms"`
|
||
User diceUserData `json:"user"`
|
||
}
|
||
|
||
func gameListDataFromProto(resp *gamev1.ListGamesResponse) gameListData {
|
||
if resp == nil {
|
||
return gameListData{}
|
||
}
|
||
items := make([]gameItemData, 0, len(resp.GetGames()))
|
||
for _, item := range resp.GetGames() {
|
||
items = append(items, gameItemData{
|
||
GameID: item.GetGameId(),
|
||
PlatformCode: item.GetPlatformCode(),
|
||
NameKey: item.GetNameKey(),
|
||
Name: item.GetName(),
|
||
IconURL: item.GetIconUrl(),
|
||
CoverURL: item.GetCoverUrl(),
|
||
Category: item.GetCategory(),
|
||
LaunchMode: item.GetLaunchMode(),
|
||
Orientation: item.GetOrientation(),
|
||
SafeHeight: item.GetSafeHeight(),
|
||
SafeHeightV2: item.GetSafeHeight(),
|
||
MinCoin: item.GetMinCoin(),
|
||
Enabled: item.GetEnabled(),
|
||
Maintenance: item.GetMaintenance(),
|
||
SortOrder: item.GetSortOrder(),
|
||
})
|
||
}
|
||
return gameListData{Games: items, ServerTimeMS: resp.GetServerTimeMs()}
|
||
}
|
||
|
||
func exploreWinnerListDataFromProto(resp *gamev1.ListExploreWinnersResponse) exploreWinnerListData {
|
||
if resp == nil {
|
||
return exploreWinnerListData{}
|
||
}
|
||
items := make([]exploreWinnerItemData, 0, len(resp.GetWinners()))
|
||
for _, item := range resp.GetWinners() {
|
||
items = append(items, exploreWinnerItemData{
|
||
WinID: item.GetWinId(),
|
||
GameCode: item.GetGameCode(),
|
||
GameID: item.GetGameId(),
|
||
UserID: int64String(item.GetUserId()),
|
||
UserIDNumber: item.GetUserId(),
|
||
DisplayName: item.GetDisplayName(),
|
||
AvatarURL: item.GetAvatarUrl(),
|
||
CoinAmount: item.GetCoinAmount(),
|
||
WonAtMS: item.GetWonAtMs(),
|
||
})
|
||
}
|
||
return exploreWinnerListData{Items: items, Total: len(items), ServerTimeMS: resp.GetServerTimeMs()}
|
||
}
|
||
|
||
func gameLaunchDataFromProto(resp *gamev1.LaunchGameResponse) gameLaunchData {
|
||
if resp == nil {
|
||
return gameLaunchData{}
|
||
}
|
||
return gameLaunchData{
|
||
SessionID: resp.GetSessionId(),
|
||
LaunchURL: resp.GetLaunchUrl(),
|
||
ExpiresAtMS: resp.GetExpiresAtMs(),
|
||
Orientation: resp.GetOrientation(),
|
||
SafeHeight: resp.GetSafeHeight(),
|
||
SafeHeightV2: resp.GetSafeHeight(),
|
||
ServerTimeMS: resp.GetServerTimeMs(),
|
||
}
|
||
}
|
||
|
||
func diceConfigDataFromProto(resp *gamev1.DiceConfigResponse) diceConfigData {
|
||
if resp == nil {
|
||
return diceConfigData{}
|
||
}
|
||
config := resp.GetConfig()
|
||
options := make([]diceStakeOptionData, 0, len(config.GetStakeOptions()))
|
||
for _, option := range config.GetStakeOptions() {
|
||
options = append(options, diceStakeOptionData{
|
||
StakeCoin: option.GetStakeCoin(),
|
||
Enabled: option.GetEnabled(),
|
||
SortOrder: option.GetSortOrder(),
|
||
})
|
||
}
|
||
return diceConfigData{
|
||
Config: diceConfigItemData{
|
||
AppCode: config.GetAppCode(),
|
||
GameID: config.GetGameId(),
|
||
Status: config.GetStatus(),
|
||
StakeOptions: options,
|
||
FeeBPS: config.GetFeeBps(),
|
||
PoolBPS: config.GetPoolBps(),
|
||
MinPlayers: config.GetMinPlayers(),
|
||
MaxPlayers: config.GetMaxPlayers(),
|
||
RobotEnabled: config.GetRobotEnabled(),
|
||
RobotMatchWaitMS: config.GetRobotMatchWaitMs(),
|
||
PoolBalanceCoin: config.GetPoolBalanceCoin(),
|
||
},
|
||
ServerTimeMS: resp.GetServerTimeMs(),
|
||
}
|
||
}
|
||
|
||
func roomRPSConfigDataFromProto(resp *gamev1.RoomRPSConfigResponse) roomRPSConfigData {
|
||
if resp == nil {
|
||
return roomRPSConfigData{}
|
||
}
|
||
// 配置响应保持一层 config 包装,方便 Flutter 在同一个模型里同时读取配置和 server_time_ms 做倒计时校准。
|
||
return roomRPSConfigData{Config: roomRPSConfigItemDataFromProto(resp.GetConfig()), ServerTimeMS: resp.GetServerTimeMs()}
|
||
}
|
||
|
||
func roomRPSConfigItemDataFromProto(config *gamev1.RoomRPSConfig) roomRPSConfigItemData {
|
||
if config == nil {
|
||
return roomRPSConfigItemData{}
|
||
}
|
||
gifts := make([]roomRPSStakeGiftData, 0, len(config.GetStakeGifts()))
|
||
for _, gift := range config.GetStakeGifts() {
|
||
// 礼物 ID 同时返回字符串和数字;Flutter 展示、缓存和路由参数优先用字符串,提交 body 时仍可用数字字段。
|
||
gifts = append(gifts, roomRPSStakeGiftData{
|
||
GiftID: int64String(gift.GetGiftId()),
|
||
GiftIDNumber: gift.GetGiftId(),
|
||
GiftName: gift.GetGiftName(),
|
||
GiftIconURL: gift.GetGiftIconUrl(),
|
||
GiftPriceCoin: gift.GetGiftPriceCoin(),
|
||
Enabled: gift.GetEnabled(),
|
||
SortOrder: gift.GetSortOrder(),
|
||
})
|
||
}
|
||
return roomRPSConfigItemData{
|
||
AppCode: config.GetAppCode(),
|
||
GameID: config.GetGameId(),
|
||
Status: config.GetStatus(),
|
||
ChallengeTimeoutMS: config.GetChallengeTimeoutMs(),
|
||
RevealCountdownMS: config.GetRevealCountdownMs(),
|
||
StakeGifts: gifts,
|
||
}
|
||
}
|
||
|
||
func diceMatchDataFromProto(resp *gamev1.DiceMatchResponse) diceMatchData {
|
||
if resp == nil {
|
||
return diceMatchData{}
|
||
}
|
||
return diceMatchData{
|
||
Match: diceMatchItemDataFromProto(resp.GetMatch()),
|
||
ServerTimeMS: resp.GetServerTimeMs(),
|
||
}
|
||
}
|
||
|
||
func diceMatchItemDataFromProto(match *gamev1.DiceMatch) diceMatchItemData {
|
||
if match == nil {
|
||
return diceMatchItemData{}
|
||
}
|
||
participants := make([]diceParticipantItemData, 0, len(match.GetParticipants()))
|
||
for _, participant := range match.GetParticipants() {
|
||
participants = append(participants, diceParticipantItemDataFromProto(participant))
|
||
}
|
||
return diceMatchItemData{
|
||
AppCode: match.GetAppCode(),
|
||
MatchID: match.GetMatchId(),
|
||
GameID: match.GetGameId(),
|
||
RoomID: match.GetRoomId(),
|
||
RegionID: match.GetRegionId(),
|
||
MinPlayers: match.GetMinPlayers(),
|
||
MaxPlayers: match.GetMaxPlayers(),
|
||
CurrentPlayers: match.GetCurrentPlayers(),
|
||
StakeCoin: match.GetStakeCoin(),
|
||
RoundNo: match.GetRoundNo(),
|
||
Status: match.GetStatus(),
|
||
Result: match.GetResult(),
|
||
Participants: participants,
|
||
JoinDeadlineMS: match.GetJoinDeadlineMs(),
|
||
ReadyAtMS: match.GetReadyAtMs(),
|
||
CreatedAtMS: match.GetCreatedAtMs(),
|
||
UpdatedAtMS: match.GetUpdatedAtMs(),
|
||
SettledAtMS: match.GetSettledAtMs(),
|
||
CanceledAtMS: match.GetCanceledAtMs(),
|
||
Phase: match.GetPhase(),
|
||
PhaseDeadlineMS: match.GetPhaseDeadlineMs(),
|
||
FeeBPS: match.GetFeeBps(),
|
||
PoolBPS: match.GetPoolBps(),
|
||
MatchMode: match.GetMatchMode(),
|
||
ForcedResult: match.GetForcedResult(),
|
||
PoolDeltaCoin: match.GetPoolDeltaCoin(),
|
||
}
|
||
}
|
||
|
||
func diceParticipantItemDataFromProto(participant *gamev1.DiceParticipant) diceParticipantItemData {
|
||
if participant == nil {
|
||
return diceParticipantItemData{}
|
||
}
|
||
return diceParticipantItemData{
|
||
UserID: int64String(participant.GetUserId()),
|
||
UserIDNumber: participant.GetUserId(),
|
||
SeatNo: participant.GetSeatNo(),
|
||
Status: participant.GetStatus(),
|
||
StakeCoin: participant.GetStakeCoin(),
|
||
DicePoints: participant.GetDicePoints(),
|
||
RPSGesture: participant.GetRpsGesture(),
|
||
Gesture: participant.GetRpsGesture(),
|
||
Result: participant.GetResult(),
|
||
PayoutCoin: participant.GetPayoutCoin(),
|
||
BalanceAfter: participant.GetBalanceAfter(),
|
||
JoinedAtMS: participant.GetJoinedAtMs(),
|
||
UpdatedAtMS: participant.GetUpdatedAtMs(),
|
||
ParticipantType: participant.GetParticipantType(),
|
||
IsRobot: participant.GetIsRobot(),
|
||
AvatarFrame: map[string]any{},
|
||
}
|
||
}
|
||
|
||
func gameBridgeScriptDataFromProto(resp *gamev1.GetBridgeScriptResponse) gameBridgeScriptData {
|
||
if resp == nil {
|
||
return gameBridgeScriptData{}
|
||
}
|
||
config := resp.GetConfig()
|
||
return gameBridgeScriptData{
|
||
BridgeScriptURL: config.GetBridgeScriptUrl(),
|
||
BridgeScriptURLV2: config.GetBridgeScriptUrl(),
|
||
BridgeScriptVersion: config.GetBridgeScriptVersion(),
|
||
BridgeScriptVersionV2: config.GetBridgeScriptVersion(),
|
||
BridgeScriptSHA256: config.GetBridgeScriptSha256(),
|
||
BridgeScriptSHA256V2: config.GetBridgeScriptSha256(),
|
||
ServerTimeMS: resp.GetServerTimeMs(),
|
||
}
|
||
}
|
||
|
||
func int64String(value int64) string {
|
||
return fmt.Sprintf("%d", value)
|
||
}
|
||
|
||
func roomRPSChallengeDataFromProto(resp *gamev1.RoomRPSChallengeResponse) roomRPSChallengeData {
|
||
if resp == nil {
|
||
return roomRPSChallengeData{}
|
||
}
|
||
// 单挑战响应和列表响应使用同一个 challenge 结构,避免 Flutter 为发起、应战、详情维护多套字段映射。
|
||
return roomRPSChallengeData{Challenge: roomRPSChallengeItemDataFromProto(resp.GetChallenge()), ServerTimeMS: resp.GetServerTimeMs()}
|
||
}
|
||
|
||
func roomRPSChallengeListDataFromProto(resp *gamev1.ListRoomRPSChallengesResponse) roomRPSChallengeListData {
|
||
if resp == nil {
|
||
return roomRPSChallengeListData{}
|
||
}
|
||
items := make([]*roomRPSChallengeItemData, 0, len(resp.GetChallenges()))
|
||
for _, challenge := range resp.GetChallenges() {
|
||
// 使用指针切片是为了后续展示资料补全可以原地写入 initiator/challenger.user,不再复制整份挑战单。
|
||
item := roomRPSChallengeItemDataFromProto(challenge)
|
||
items = append(items, &item)
|
||
}
|
||
return roomRPSChallengeListData{
|
||
Challenges: items,
|
||
NextCursor: resp.GetNextCursor(),
|
||
PageSize: resp.GetPageSize(),
|
||
ServerTimeMS: resp.GetServerTimeMs(),
|
||
}
|
||
}
|
||
|
||
func roomRPSChallengeItemDataFromProto(challenge *gamev1.RoomRPSChallenge) roomRPSChallengeItemData {
|
||
if challenge == nil {
|
||
return roomRPSChallengeItemData{}
|
||
}
|
||
// game-service 返回的是订单事实,gateway 这里只做 JSON 形态转换;状态、胜负、结算失败原因不能在这里二次推导。
|
||
// 所有可能超过 JS 安全整数范围的 ID 都保留 string 和 number 双字段,Flutter 优先使用 string,后台排查仍可读 number。
|
||
return roomRPSChallengeItemData{
|
||
AppCode: challenge.GetAppCode(),
|
||
ChallengeID: challenge.GetChallengeId(),
|
||
RoomID: challenge.GetRoomId(),
|
||
RegionID: challenge.GetRegionId(),
|
||
Status: challenge.GetStatus(),
|
||
StakeGiftID: int64String(challenge.GetStakeGiftId()),
|
||
StakeGiftIDNumber: challenge.GetStakeGiftId(),
|
||
StakeCoin: challenge.GetStakeCoin(),
|
||
Initiator: roomRPSPlayerItemDataFromProto(challenge.GetInitiator()),
|
||
Challenger: roomRPSPlayerItemDataFromProto(challenge.GetChallenger()),
|
||
WinnerUserID: int64String(challenge.GetWinnerUserId()),
|
||
WinnerUserIDNumber: challenge.GetWinnerUserId(),
|
||
SettlementStatus: challenge.GetSettlementStatus(),
|
||
FailureReason: challenge.GetFailureReason(),
|
||
TimeoutAtMS: challenge.GetTimeoutAtMs(),
|
||
RevealAtMS: challenge.GetRevealAtMs(),
|
||
CreatedAtMS: challenge.GetCreatedAtMs(),
|
||
MatchedAtMS: challenge.GetMatchedAtMs(),
|
||
SettledAtMS: challenge.GetSettledAtMs(),
|
||
UpdatedAtMS: challenge.GetUpdatedAtMs(),
|
||
}
|
||
}
|
||
|
||
func roomRPSPlayerItemDataFromProto(player *gamev1.RoomRPSPlayer) roomRPSPlayerItemData {
|
||
if player == nil {
|
||
return roomRPSPlayerItemData{}
|
||
}
|
||
// user 先放 user_id 兜底;真正的 nickname/avatar 在 enrichRoomRPSChallenges 里批量补齐,资料失败不影响订单返回。
|
||
return roomRPSPlayerItemData{
|
||
UserID: int64String(player.GetUserId()),
|
||
UserIDNumber: player.GetUserId(),
|
||
Gesture: player.GetGesture(),
|
||
Result: player.GetResult(),
|
||
BalanceAfter: player.GetBalanceAfter(),
|
||
JoinedAtMS: player.GetJoinedAtMs(),
|
||
User: diceUserData{UserID: int64String(player.GetUserId())},
|
||
}
|
||
}
|