package roomclient import ( "context" "fmt" "strings" "time" "hyapp-admin-server/internal/appctx" roomv1 "hyapp.local/api/proto/room/v1" "google.golang.org/grpc" ) type Client interface { ListRooms(ctx context.Context, req ListRoomsRequest) (*ListRoomsResult, error) GetRoom(ctx context.Context, req GetRoomRequest) (*Room, error) UpdateRoom(ctx context.Context, req UpdateRoomRequest) (*CloseRoomResult, error) DeleteRoom(ctx context.Context, req DeleteRoomRequest) (*CloseRoomResult, error) GetRoomRocketConfig(ctx context.Context) (RoomRocketConfig, error) UpdateRoomRocketConfig(ctx context.Context, req UpdateRoomRocketConfigRequest) (RoomRocketConfig, error) GetRoomSeatConfig(ctx context.Context) (RoomSeatConfig, error) UpdateRoomSeatConfig(ctx context.Context, req UpdateRoomSeatConfigRequest) (RoomSeatConfig, error) GetHumanRoomRobotConfig(ctx context.Context) (HumanRoomRobotConfig, error) UpdateHumanRoomRobotConfig(ctx context.Context, req UpdateHumanRoomRobotConfigRequest) (HumanRoomRobotConfig, error) ListRoomPins(ctx context.Context, req ListRoomPinsRequest) (ListRoomPinsResult, error) CreateRoomPin(ctx context.Context, req CreateRoomPinRequest) (RoomPin, error) CancelRoomPin(ctx context.Context, req CancelRoomPinRequest) (RoomPin, error) ListRobotRooms(ctx context.Context, req ListRobotRoomsRequest) (ListRobotRoomsResult, error) CreateRobotRoom(ctx context.Context, req CreateRobotRoomRequest) (RobotRoom, error) SetRobotRoomStatus(ctx context.Context, req SetRobotRoomStatusRequest) (RobotRoom, error) FilterAvailableRoomRobots(ctx context.Context, userIDs []int64) (FilterAvailableRoomRobotsResult, error) CloseRoom(ctx context.Context, req CloseRoomRequest) (*CloseRoomResult, error) ReopenRoom(ctx context.Context, req ReopenRoomRequest) (*CloseRoomResult, error) } type ListRoomsRequest struct { Page int PageSize int Keyword string Status string RegionID int64 OwnerUserID int64 SortBy string SortDirection string } type ListRoomsResult struct { Rooms []Room Total int64 ServerTimeMs int64 } type GetRoomRequest struct { RoomID string } type UpdateRoomRequest struct { RequestID string RoomID string ActorUserID int64 Title *string CoverURL *string Description *string Mode *string Status *string VisibleRegionID *int64 CloseReason string AdminID uint64 AdminName string } type DeleteRoomRequest struct { RequestID string RoomID string ActorUserID int64 AdminID uint64 AdminName string } type Room struct { RoomID string RoomShortID string VisibleRegionID int64 OwnerUserID int64 Title string CoverURL string Mode string Status string CloseReason string ClosedByAdminID uint64 ClosedByAdminName string ClosedAtMS int64 Heat int64 OnlineCount int32 SeatCount int32 OccupiedSeatCount int32 SortScore int64 CreatedAtMS int64 UpdatedAtMS int64 } type RoomRocketConfig struct { AppCode string Enabled bool ConfigVersion int64 FuelSource string LaunchDelayMS int64 BroadcastEnabled bool BroadcastScope string BroadcastDelayMS int64 RewardStackPolicy string Levels []RoomRocketLevelConfig GiftFuelRules []GiftFuelRuleConfig UpdatedByAdminID int64 CreatedAtMS int64 UpdatedAtMS int64 } type RoomRocketLevelConfig struct { Level int32 FuelThreshold int64 CoverURL string AnimationURL string LaunchAnimationURL string LaunchedImageURL string InRoomRewards []RoomRocketRewardItem Top1Rewards []RoomRocketRewardItem IgniterRewards []RoomRocketRewardItem } type RoomRocketRewardItem struct { RewardItemID string ResourceGroupID int64 Weight int64 Quantity int64 DisplayName string IconURL string } type GiftFuelRuleConfig struct { RuleID string GiftID string GiftTypeCode string MultiplierPPM int64 FixedFuel int64 Excluded bool } type UpdateRoomRocketConfigRequest struct { Config RoomRocketConfig AdminID int64 } type RoomSeatConfig struct { CandidateSeatCounts []int32 AllowedSeatCounts []int32 DefaultSeatCount int32 UpdatedAtMS int64 } type UpdateRoomSeatConfigRequest struct { AllowedSeatCounts []int32 DefaultSeatCount int32 } type HumanRoomRobotConfig struct { AppCode string Enabled bool CandidateRoomMaxOnline int32 RoomFullStopOnline int32 RoomTargetMinOnline int32 RoomTargetMaxOnline int32 RobotStayMinMS int64 RobotStayMaxMS int64 RobotReplaceMinMS int64 RobotReplaceMaxMS int64 NormalGiftIntervalMS int64 NormalGiftIntervalMinMS int64 NormalGiftIntervalMaxMS int64 GiftIDs []string LuckyGiftIDs []string SuperLuckyGiftIDs []string LuckyComboMin int64 LuckyComboMax int64 LuckyPauseMinMS int64 LuckyPauseMaxMS int64 MaxGiftSenders int64 UpdatedByAdminID uint64 CreatedAtMS int64 UpdatedAtMS int64 } type UpdateHumanRoomRobotConfigRequest struct { Config HumanRoomRobotConfig AdminID uint64 } type RoomPinRoom struct { RoomID string RoomShortID string VisibleRegionID int64 OwnerUserID int64 Title string CoverURL string Status string } type RoomPin struct { ID int64 VisibleRegionID int64 PinType string RoomID string Weight int64 Status string PinnedAtMS int64 ExpiresAtMS int64 CancelledAtMS int64 CreatedByAdminID uint64 CancelledByAdminID uint64 CreatedAtMS int64 UpdatedAtMS int64 Room RoomPinRoom } type ListRoomPinsRequest struct { Page int PageSize int Keyword string Status string RegionID int64 PinType string } type ListRoomPinsResult struct { Pins []RoomPin Total int64 } type CreateRoomPinRequest struct { RoomID string PinType string Weight int64 DurationDays int64 PinnedAtMS int64 ExpiresAtMS int64 AdminID uint64 } type CancelRoomPinRequest struct { PinID int64 AdminID uint64 } type RobotRoomGiftRule struct { GiftIDs []string LuckyGiftIDs []string NormalGiftIntervalMS int64 LuckyComboMin int64 LuckyComboMax int64 LuckyPauseMinMS int64 LuckyPauseMaxMS int64 RobotStayMinMS int64 RobotStayMaxMS int64 RobotReplaceMinMS int64 RobotReplaceMaxMS int64 MaxGiftSenders int64 } type RobotRoom struct { AppCode string RoomID string RoomShortID string Title string CoverURL string VisibleRegionID int64 Status string OwnerRobotUserID int64 RobotUserIDs []int64 ActiveRobotCount int32 SeatCount int32 GiftRule RobotRoomGiftRule CreatedByAdminID uint64 CreatedAtMS int64 UpdatedAtMS int64 } type ListRobotRoomsRequest struct { Page int PageSize int Status string } type ListRobotRoomsResult struct { Rooms []RobotRoom Total int64 } type CreateRobotRoomRequest struct { OwnerRobotUserID int64 CandidateRobotUserIDs []int64 MinRobotCount int32 MaxRobotCount int32 RoomName string RoomAvatar string VisibleRegionID int64 OwnerCountryCode string SeatCount int32 GiftRule RobotRoomGiftRule AdminID uint64 } type SetRobotRoomStatusRequest struct { RoomID string Status string AdminID uint64 } type FilterAvailableRoomRobotsResult struct { AvailableUserIDs []int64 OccupiedUserIDs []int64 } type CloseRoomRequest struct { RequestID string RoomID string ActorUserID int64 Reason string } type CloseRoomResult struct { Applied bool RoomVersion int64 ServerTimeMs int64 RoomStatus string OnlineUserNum int } type ReopenRoomRequest struct { RequestID string RoomID string ActorUserID int64 } type GRPCClient struct { client roomv1.RoomCommandServiceClient queryClient roomv1.RoomQueryServiceClient } func NewGRPC(conn grpc.ClientConnInterface) *GRPCClient { return &GRPCClient{client: roomv1.NewRoomCommandServiceClient(conn), queryClient: roomv1.NewRoomQueryServiceClient(conn)} } func (c *GRPCClient) ListRooms(ctx context.Context, req ListRoomsRequest) (*ListRoomsResult, error) { resp, err := c.queryClient.AdminListRooms(ctx, &roomv1.AdminListRoomsRequest{ Meta: requestMeta(ctx, "", 0, "admin-list-rooms"), Page: int32(req.Page), PageSize: int32(req.PageSize), Keyword: strings.TrimSpace(req.Keyword), Status: strings.TrimSpace(req.Status), VisibleRegionId: req.RegionID, OwnerUserId: req.OwnerUserID, SortBy: strings.TrimSpace(req.SortBy), SortDirection: strings.TrimSpace(req.SortDirection), }) if err != nil { return nil, err } rooms := make([]Room, 0, len(resp.GetRooms())) for _, item := range resp.GetRooms() { rooms = append(rooms, roomFromProto(item)) } return &ListRoomsResult{Rooms: rooms, Total: resp.GetTotal(), ServerTimeMs: resp.GetServerTimeMs()}, nil } func (c *GRPCClient) GetRoom(ctx context.Context, req GetRoomRequest) (*Room, error) { resp, err := c.queryClient.AdminGetRoom(ctx, &roomv1.AdminGetRoomRequest{ Meta: requestMeta(ctx, strings.TrimSpace(req.RoomID), 0, "admin-get-room"), RoomId: strings.TrimSpace(req.RoomID), }) if err != nil { return nil, err } room := roomFromProto(resp.GetRoom()) return &room, nil } func (c *GRPCClient) UpdateRoom(ctx context.Context, req UpdateRoomRequest) (*CloseRoomResult, error) { resp, err := c.client.AdminUpdateRoom(ctx, &roomv1.AdminUpdateRoomRequest{ Meta: requestMeta(ctx, req.RoomID, req.ActorUserID, firstNonEmpty(req.RequestID, "admin-update-room")), Title: req.Title, CoverUrl: req.CoverURL, Description: req.Description, Mode: req.Mode, Status: req.Status, VisibleRegionId: req.VisibleRegionID, CloseReason: strings.TrimSpace(req.CloseReason), AdminId: req.AdminID, AdminName: strings.TrimSpace(req.AdminName), }) if err != nil { return nil, err } return closeRoomResultFromCommand(resp.GetResult(), resp.GetRoom()), nil } func (c *GRPCClient) DeleteRoom(ctx context.Context, req DeleteRoomRequest) (*CloseRoomResult, error) { resp, err := c.client.AdminDeleteRoom(ctx, &roomv1.AdminDeleteRoomRequest{ Meta: requestMeta(ctx, req.RoomID, req.ActorUserID, firstNonEmpty(req.RequestID, "admin-delete-room")), AdminId: req.AdminID, AdminName: strings.TrimSpace(req.AdminName), }) if err != nil { return nil, err } return closeRoomResultFromCommand(resp.GetResult(), resp.GetRoom()), nil } func (c *GRPCClient) GetRoomRocketConfig(ctx context.Context) (RoomRocketConfig, error) { resp, err := c.queryClient.AdminGetRoomRocketConfig(ctx, &roomv1.AdminGetRoomRocketConfigRequest{ Meta: requestMeta(ctx, "", 0, "admin-get-room-rocket-config"), }) if err != nil { return RoomRocketConfig{}, err } return roomRocketConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) UpdateRoomRocketConfig(ctx context.Context, req UpdateRoomRocketConfigRequest) (RoomRocketConfig, error) { resp, err := c.client.AdminUpdateRoomRocketConfig(ctx, &roomv1.AdminUpdateRoomRocketConfigRequest{ Meta: requestMeta(ctx, "", req.AdminID, "admin-update-room-rocket-config"), Config: roomRocketConfigToProto(req.Config), AdminId: req.AdminID, }) if err != nil { return RoomRocketConfig{}, err } return roomRocketConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) GetRoomSeatConfig(ctx context.Context) (RoomSeatConfig, error) { resp, err := c.queryClient.AdminGetRoomSeatConfig(ctx, &roomv1.AdminGetRoomSeatConfigRequest{Meta: requestMeta(ctx, "", 0, "admin-get-room-seat-config")}) if err != nil { return RoomSeatConfig{}, err } return roomSeatConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) UpdateRoomSeatConfig(ctx context.Context, req UpdateRoomSeatConfigRequest) (RoomSeatConfig, error) { resp, err := c.client.AdminUpdateRoomSeatConfig(ctx, &roomv1.AdminUpdateRoomSeatConfigRequest{ Meta: requestMeta(ctx, "", 0, "admin-update-room-seat-config"), AllowedSeatCounts: req.AllowedSeatCounts, DefaultSeatCount: req.DefaultSeatCount, }) if err != nil { return RoomSeatConfig{}, err } return roomSeatConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) GetHumanRoomRobotConfig(ctx context.Context) (HumanRoomRobotConfig, error) { resp, err := c.queryClient.AdminGetHumanRoomRobotConfig(ctx, &roomv1.AdminGetHumanRoomRobotConfigRequest{Meta: requestMeta(ctx, "", 0, "admin-get-human-room-robot-config")}) if err != nil { return HumanRoomRobotConfig{}, err } return humanRoomRobotConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) UpdateHumanRoomRobotConfig(ctx context.Context, req UpdateHumanRoomRobotConfigRequest) (HumanRoomRobotConfig, error) { resp, err := c.client.AdminUpdateHumanRoomRobotConfig(ctx, &roomv1.AdminUpdateHumanRoomRobotConfigRequest{ Meta: requestMeta(ctx, "", int64(req.AdminID), "admin-update-human-room-robot-config"), Config: humanRoomRobotConfigToProto(req.Config), AdminId: req.AdminID, }) if err != nil { return HumanRoomRobotConfig{}, err } return humanRoomRobotConfigFromProto(resp.GetConfig()), nil } func (c *GRPCClient) ListRoomPins(ctx context.Context, req ListRoomPinsRequest) (ListRoomPinsResult, error) { resp, err := c.queryClient.AdminListRoomPins(ctx, &roomv1.AdminListRoomPinsRequest{ Meta: requestMeta(ctx, "", 0, "admin-list-room-pins"), Page: int32(req.Page), PageSize: int32(req.PageSize), Keyword: strings.TrimSpace(req.Keyword), Status: strings.TrimSpace(req.Status), VisibleRegionId: req.RegionID, PinType: strings.TrimSpace(req.PinType), }) if err != nil { return ListRoomPinsResult{}, err } pins := make([]RoomPin, 0, len(resp.GetPins())) for _, pin := range resp.GetPins() { pins = append(pins, roomPinFromProto(pin)) } return ListRoomPinsResult{Pins: pins, Total: resp.GetTotal()}, nil } func (c *GRPCClient) CreateRoomPin(ctx context.Context, req CreateRoomPinRequest) (RoomPin, error) { resp, err := c.client.AdminCreateRoomPin(ctx, &roomv1.AdminCreateRoomPinRequest{ Meta: requestMeta(ctx, strings.TrimSpace(req.RoomID), int64(req.AdminID), "admin-create-room-pin"), RoomId: strings.TrimSpace(req.RoomID), PinType: strings.TrimSpace(req.PinType), Weight: req.Weight, DurationDays: req.DurationDays, PinnedAtMs: req.PinnedAtMS, ExpiresAtMs: req.ExpiresAtMS, AdminId: req.AdminID, }) if err != nil { return RoomPin{}, err } return roomPinFromProto(resp.GetPin()), nil } func (c *GRPCClient) CancelRoomPin(ctx context.Context, req CancelRoomPinRequest) (RoomPin, error) { resp, err := c.client.AdminCancelRoomPin(ctx, &roomv1.AdminCancelRoomPinRequest{ Meta: requestMeta(ctx, "", int64(req.AdminID), "admin-cancel-room-pin"), PinId: req.PinID, AdminId: req.AdminID, }) if err != nil { return RoomPin{}, err } return roomPinFromProto(resp.GetPin()), nil } func (c *GRPCClient) ListRobotRooms(ctx context.Context, req ListRobotRoomsRequest) (ListRobotRoomsResult, error) { resp, err := c.queryClient.AdminListRobotRooms(ctx, &roomv1.AdminListRobotRoomsRequest{ Meta: requestMeta(ctx, "", 0, "admin-list-robot-rooms"), Page: int32(req.Page), PageSize: int32(req.PageSize), Status: strings.TrimSpace(req.Status), }) if err != nil { return ListRobotRoomsResult{}, err } items := make([]RobotRoom, 0, len(resp.GetRooms())) for _, item := range resp.GetRooms() { items = append(items, robotRoomFromProto(item)) } return ListRobotRoomsResult{Rooms: items, Total: resp.GetTotal()}, nil } func (c *GRPCClient) CreateRobotRoom(ctx context.Context, req CreateRobotRoomRequest) (RobotRoom, error) { resp, err := c.client.AdminCreateRobotRoom(ctx, &roomv1.AdminCreateRobotRoomRequest{ Meta: requestMeta(ctx, "", int64(req.AdminID), "admin-create-robot-room"), OwnerRobotUserId: req.OwnerRobotUserID, CandidateRobotUserIds: append([]int64(nil), req.CandidateRobotUserIDs...), MinRobotCount: req.MinRobotCount, MaxRobotCount: req.MaxRobotCount, RoomName: strings.TrimSpace(req.RoomName), RoomAvatar: strings.TrimSpace(req.RoomAvatar), VisibleRegionId: req.VisibleRegionID, OwnerCountryCode: strings.ToUpper(strings.TrimSpace(req.OwnerCountryCode)), SeatCount: req.SeatCount, GiftRule: robotRoomGiftRuleToProto(req.GiftRule), AdminId: req.AdminID, }) if err != nil { return RobotRoom{}, err } return robotRoomFromProto(resp.GetRoom()), nil } func (c *GRPCClient) SetRobotRoomStatus(ctx context.Context, req SetRobotRoomStatusRequest) (RobotRoom, error) { resp, err := c.client.AdminSetRobotRoomStatus(ctx, &roomv1.AdminSetRobotRoomStatusRequest{ Meta: requestMeta(ctx, strings.TrimSpace(req.RoomID), int64(req.AdminID), "admin-set-robot-room-status"), Status: strings.TrimSpace(req.Status), AdminId: req.AdminID, }) if err != nil { return RobotRoom{}, err } return robotRoomFromProto(resp.GetRoom()), nil } func (c *GRPCClient) FilterAvailableRoomRobots(ctx context.Context, userIDs []int64) (FilterAvailableRoomRobotsResult, error) { resp, err := c.queryClient.AdminFilterAvailableRoomRobots(ctx, &roomv1.AdminFilterAvailableRoomRobotsRequest{ Meta: requestMeta(ctx, "", 0, "admin-filter-available-room-robots"), UserIds: append([]int64(nil), userIDs...), }) if err != nil { return FilterAvailableRoomRobotsResult{}, err } return FilterAvailableRoomRobotsResult{ AvailableUserIDs: append([]int64(nil), resp.GetAvailableUserIds()...), OccupiedUserIDs: append([]int64(nil), resp.GetOccupiedUserIds()...), }, nil } func (c *GRPCClient) CloseRoom(ctx context.Context, req CloseRoomRequest) (*CloseRoomResult, error) { return c.setRoomLifecycle(ctx, req.RequestID, req.RoomID, req.ActorUserID, firstNonEmpty(req.Reason, "admin_closed")) } func (c *GRPCClient) ReopenRoom(ctx context.Context, req ReopenRoomRequest) (*CloseRoomResult, error) { return c.setRoomLifecycle(ctx, req.RequestID, req.RoomID, req.ActorUserID, "admin_reopen") } func (c *GRPCClient) setRoomLifecycle(ctx context.Context, rawRequestID string, rawRoomID string, actorUserID int64, rawReason string) (*CloseRoomResult, error) { if c == nil || c.client == nil { return nil, fmt.Errorf("room service client is not configured") } roomID := strings.TrimSpace(rawRoomID) reason := strings.TrimSpace(rawReason) if roomID == "" || actorUserID <= 0 || reason == "" { return nil, fmt.Errorf("room lifecycle request is incomplete") } requestID := strings.TrimSpace(rawRequestID) if requestID == "" { requestID = fmt.Sprintf("admin-room-lifecycle-%s-%d", roomID, time.Now().UnixMilli()) } resp, err := c.client.CloseRoom(ctx, &roomv1.CloseRoomRequest{ Meta: requestMeta(ctx, roomID, actorUserID, requestID+":"+reason), Reason: reason, }) if err != nil { return nil, err } return closeRoomResultFromCommand(resp.GetResult(), resp.GetRoom()), nil } func closeRoomResultFromCommand(result *roomv1.CommandResult, room *roomv1.RoomSnapshot) *CloseRoomResult { return &CloseRoomResult{ Applied: result.GetApplied(), RoomVersion: result.GetRoomVersion(), ServerTimeMs: result.GetServerTimeMs(), RoomStatus: room.GetStatus(), OnlineUserNum: len(room.GetOnlineUsers()), } } func commandID(requestID string, reason string, roomID string) string { base := strings.TrimSpace(requestID) if base == "" { base = fmt.Sprintf("admin-room-lifecycle-%d", time.Now().UnixMilli()) } value := base + ":" + strings.TrimSpace(reason) + ":" + strings.TrimSpace(roomID) if len(value) <= 128 { return value } return value[:128] } func requestMeta(ctx context.Context, roomID string, actorUserID int64, seed string) *roomv1.RequestMeta { requestID := strings.TrimSpace(seed) if requestID == "" { requestID = fmt.Sprintf("admin-room-%d", time.Now().UnixMilli()) } return &roomv1.RequestMeta{ RequestId: requestID, CommandId: commandID(requestID, "admin", roomID), ActorUserId: actorUserID, RoomId: strings.TrimSpace(roomID), AppCode: appctx.FromContext(ctx), SentAtMs: time.Now().UnixMilli(), } } func roomFromProto(item *roomv1.AdminRoomListItem) Room { if item == nil { return Room{} } return Room{ RoomID: item.GetRoomId(), RoomShortID: item.GetRoomShortId(), VisibleRegionID: item.GetVisibleRegionId(), OwnerUserID: item.GetOwnerUserId(), Title: item.GetTitle(), CoverURL: item.GetCoverUrl(), Mode: item.GetMode(), Status: item.GetStatus(), CloseReason: item.GetCloseReason(), ClosedByAdminID: item.GetClosedByAdminId(), ClosedByAdminName: item.GetClosedByAdminName(), ClosedAtMS: item.GetClosedAtMs(), Heat: item.GetHeat(), OnlineCount: item.GetOnlineCount(), SeatCount: item.GetSeatCount(), OccupiedSeatCount: item.GetOccupiedSeatCount(), SortScore: item.GetSortScore(), CreatedAtMS: item.GetCreatedAtMs(), UpdatedAtMS: item.GetUpdatedAtMs(), } } func roomRocketConfigFromProto(input *roomv1.AdminRoomRocketConfig) RoomRocketConfig { if input == nil { return RoomRocketConfig{} } return RoomRocketConfig{ AppCode: input.GetAppCode(), Enabled: input.GetEnabled(), ConfigVersion: input.GetConfigVersion(), FuelSource: input.GetFuelSource(), LaunchDelayMS: input.GetLaunchDelayMs(), BroadcastEnabled: input.GetBroadcastEnabled(), BroadcastScope: input.GetBroadcastScope(), BroadcastDelayMS: input.GetBroadcastDelayMs(), RewardStackPolicy: input.GetRewardStackPolicy(), Levels: roomRocketLevelsFromProto(input.GetLevels()), GiftFuelRules: roomRocketFuelRulesFromProto(input.GetGiftFuelRules()), UpdatedByAdminID: input.GetUpdatedByAdminId(), CreatedAtMS: input.GetCreatedAtMs(), UpdatedAtMS: input.GetUpdatedAtMs(), } } func roomSeatConfigFromProto(input *roomv1.AdminRoomSeatConfig) RoomSeatConfig { if input == nil { return RoomSeatConfig{} } return RoomSeatConfig{ CandidateSeatCounts: input.GetCandidateSeatCounts(), AllowedSeatCounts: input.GetAllowedSeatCounts(), DefaultSeatCount: input.GetDefaultSeatCount(), UpdatedAtMS: input.GetUpdatedAtMs(), } } func humanRoomRobotConfigFromProto(input *roomv1.AdminHumanRoomRobotConfig) HumanRoomRobotConfig { if input == nil { return HumanRoomRobotConfig{} } config := HumanRoomRobotConfig{ AppCode: input.GetAppCode(), Enabled: input.GetEnabled(), CandidateRoomMaxOnline: input.GetCandidateRoomMaxOnline(), RoomFullStopOnline: input.GetRoomFullStopOnline(), RoomTargetMinOnline: input.GetRoomTargetMinOnline(), RoomTargetMaxOnline: input.GetRoomTargetMaxOnline(), RobotStayMinMS: input.GetRobotStayMinMs(), RobotStayMaxMS: input.GetRobotStayMaxMs(), RobotReplaceMinMS: input.GetRobotReplaceMinMs(), RobotReplaceMaxMS: input.GetRobotReplaceMaxMs(), NormalGiftIntervalMS: input.GetNormalGiftIntervalMs(), NormalGiftIntervalMinMS: input.GetNormalGiftIntervalMinMs(), NormalGiftIntervalMaxMS: input.GetNormalGiftIntervalMaxMs(), GiftIDs: append([]string(nil), input.GetGiftIds()...), LuckyGiftIDs: append([]string(nil), input.GetLuckyGiftIds()...), SuperLuckyGiftIDs: append([]string(nil), input.GetSuperLuckyGiftIds()...), LuckyComboMin: input.GetLuckyComboMin(), LuckyComboMax: input.GetLuckyComboMax(), LuckyPauseMinMS: input.GetLuckyPauseMinMs(), LuckyPauseMaxMS: input.GetLuckyPauseMaxMs(), MaxGiftSenders: input.GetMaxGiftSenders(), UpdatedByAdminID: input.GetUpdatedByAdminId(), CreatedAtMS: input.GetCreatedAtMs(), UpdatedAtMS: input.GetUpdatedAtMs(), } return config } func humanRoomRobotConfigToProto(input HumanRoomRobotConfig) *roomv1.AdminHumanRoomRobotConfig { out := &roomv1.AdminHumanRoomRobotConfig{ AppCode: input.AppCode, Enabled: input.Enabled, CandidateRoomMaxOnline: input.CandidateRoomMaxOnline, RoomFullStopOnline: input.RoomFullStopOnline, RoomTargetMinOnline: input.RoomTargetMinOnline, RoomTargetMaxOnline: input.RoomTargetMaxOnline, RobotStayMinMs: input.RobotStayMinMS, RobotStayMaxMs: input.RobotStayMaxMS, RobotReplaceMinMs: input.RobotReplaceMinMS, RobotReplaceMaxMs: input.RobotReplaceMaxMS, NormalGiftIntervalMs: input.NormalGiftIntervalMS, NormalGiftIntervalMinMs: input.NormalGiftIntervalMinMS, NormalGiftIntervalMaxMs: input.NormalGiftIntervalMaxMS, GiftIds: append([]string(nil), input.GiftIDs...), LuckyGiftIds: append([]string(nil), input.LuckyGiftIDs...), SuperLuckyGiftIds: append([]string(nil), input.SuperLuckyGiftIDs...), LuckyComboMin: input.LuckyComboMin, LuckyComboMax: input.LuckyComboMax, LuckyPauseMinMs: input.LuckyPauseMinMS, LuckyPauseMaxMs: input.LuckyPauseMaxMS, MaxGiftSenders: input.MaxGiftSenders, UpdatedByAdminId: input.UpdatedByAdminID, CreatedAtMs: input.CreatedAtMS, UpdatedAtMs: input.UpdatedAtMS, } return out } func roomPinFromProto(input *roomv1.AdminRoomPin) RoomPin { if input == nil { return RoomPin{} } room := input.GetRoom() return RoomPin{ ID: input.GetId(), VisibleRegionID: input.GetVisibleRegionId(), PinType: input.GetPinType(), RoomID: input.GetRoomId(), Weight: input.GetWeight(), Status: input.GetStatus(), PinnedAtMS: input.GetPinnedAtMs(), ExpiresAtMS: input.GetExpiresAtMs(), CancelledAtMS: input.GetCancelledAtMs(), CreatedByAdminID: input.GetCreatedByAdminId(), CancelledByAdminID: input.GetCancelledByAdminId(), CreatedAtMS: input.GetCreatedAtMs(), UpdatedAtMS: input.GetUpdatedAtMs(), Room: RoomPinRoom{ RoomID: room.GetRoomId(), RoomShortID: room.GetRoomShortId(), VisibleRegionID: room.GetVisibleRegionId(), OwnerUserID: room.GetOwnerUserId(), Title: room.GetTitle(), CoverURL: room.GetCoverUrl(), Status: room.GetStatus(), }, } } func robotRoomFromProto(input *roomv1.AdminRobotRoom) RobotRoom { if input == nil { return RobotRoom{} } return RobotRoom{ AppCode: input.GetAppCode(), RoomID: input.GetRoomId(), RoomShortID: input.GetRoomShortId(), Title: input.GetTitle(), CoverURL: input.GetCoverUrl(), VisibleRegionID: input.GetVisibleRegionId(), Status: input.GetStatus(), OwnerRobotUserID: input.GetOwnerRobotUserId(), RobotUserIDs: append([]int64(nil), input.GetRobotUserIds()...), ActiveRobotCount: input.GetActiveRobotCount(), SeatCount: input.GetSeatCount(), GiftRule: robotRoomGiftRuleFromProto(input.GetGiftRule()), CreatedByAdminID: input.GetCreatedByAdminId(), CreatedAtMS: input.GetCreatedAtMs(), UpdatedAtMS: input.GetUpdatedAtMs(), } } func robotRoomGiftRuleFromProto(input *roomv1.AdminRobotRoomGiftRule) RobotRoomGiftRule { if input == nil { return RobotRoomGiftRule{} } return RobotRoomGiftRule{ GiftIDs: append([]string(nil), input.GetGiftIds()...), LuckyGiftIDs: append([]string(nil), input.GetLuckyGiftIds()...), NormalGiftIntervalMS: input.GetNormalGiftIntervalMs(), LuckyComboMin: input.GetLuckyComboMin(), LuckyComboMax: input.GetLuckyComboMax(), LuckyPauseMinMS: input.GetLuckyPauseMinMs(), LuckyPauseMaxMS: input.GetLuckyPauseMaxMs(), RobotStayMinMS: input.GetRobotStayMinMs(), RobotStayMaxMS: input.GetRobotStayMaxMs(), RobotReplaceMinMS: input.GetRobotReplaceMinMs(), RobotReplaceMaxMS: input.GetRobotReplaceMaxMs(), MaxGiftSenders: input.GetMaxGiftSenders(), } } func robotRoomGiftRuleToProto(input RobotRoomGiftRule) *roomv1.AdminRobotRoomGiftRule { return &roomv1.AdminRobotRoomGiftRule{ GiftIds: append([]string(nil), input.GiftIDs...), LuckyGiftIds: append([]string(nil), input.LuckyGiftIDs...), NormalGiftIntervalMs: input.NormalGiftIntervalMS, LuckyComboMin: input.LuckyComboMin, LuckyComboMax: input.LuckyComboMax, LuckyPauseMinMs: input.LuckyPauseMinMS, LuckyPauseMaxMs: input.LuckyPauseMaxMS, RobotStayMinMs: input.RobotStayMinMS, RobotStayMaxMs: input.RobotStayMaxMS, RobotReplaceMinMs: input.RobotReplaceMinMS, RobotReplaceMaxMs: input.RobotReplaceMaxMS, MaxGiftSenders: input.MaxGiftSenders, } } func roomRocketConfigToProto(input RoomRocketConfig) *roomv1.AdminRoomRocketConfig { return &roomv1.AdminRoomRocketConfig{ AppCode: input.AppCode, Enabled: input.Enabled, FuelSource: input.FuelSource, LaunchDelayMs: input.LaunchDelayMS, BroadcastEnabled: input.BroadcastEnabled, BroadcastScope: input.BroadcastScope, BroadcastDelayMs: input.BroadcastDelayMS, RewardStackPolicy: input.RewardStackPolicy, Levels: roomRocketLevelsToProto(input.Levels), GiftFuelRules: roomRocketFuelRulesToProto(input.GiftFuelRules), } } func roomRocketLevelsFromProto(input []*roomv1.RoomRocketLevel) []RoomRocketLevelConfig { out := make([]RoomRocketLevelConfig, 0, len(input)) for _, level := range input { if level == nil { continue } out = append(out, RoomRocketLevelConfig{ Level: level.GetLevel(), FuelThreshold: level.GetFuelThreshold(), CoverURL: level.GetCoverUrl(), AnimationURL: level.GetAnimationUrl(), LaunchAnimationURL: level.GetLaunchAnimationUrl(), LaunchedImageURL: level.GetLaunchedImageUrl(), InRoomRewards: roomRocketRewardsFromProto(level.GetInRoomRewards()), Top1Rewards: roomRocketRewardsFromProto(level.GetTop1Rewards()), IgniterRewards: roomRocketRewardsFromProto(level.GetIgniterRewards()), }) } return out } func roomRocketLevelsToProto(input []RoomRocketLevelConfig) []*roomv1.RoomRocketLevel { out := make([]*roomv1.RoomRocketLevel, 0, len(input)) for _, level := range input { out = append(out, &roomv1.RoomRocketLevel{ Level: level.Level, FuelThreshold: level.FuelThreshold, CoverUrl: level.CoverURL, AnimationUrl: level.AnimationURL, LaunchAnimationUrl: level.LaunchAnimationURL, LaunchedImageUrl: level.LaunchedImageURL, InRoomRewards: roomRocketRewardsToProto(level.InRoomRewards), Top1Rewards: roomRocketRewardsToProto(level.Top1Rewards), IgniterRewards: roomRocketRewardsToProto(level.IgniterRewards), }) } return out } func roomRocketRewardsFromProto(input []*roomv1.RoomRocketRewardItem) []RoomRocketRewardItem { out := make([]RoomRocketRewardItem, 0, len(input)) for _, reward := range input { if reward == nil { continue } out = append(out, RoomRocketRewardItem{ RewardItemID: reward.GetRewardItemId(), ResourceGroupID: reward.GetResourceGroupId(), Weight: reward.GetWeight(), Quantity: reward.GetQuantity(), DisplayName: reward.GetDisplayName(), IconURL: reward.GetIconUrl(), }) } return out } func roomRocketRewardsToProto(input []RoomRocketRewardItem) []*roomv1.RoomRocketRewardItem { out := make([]*roomv1.RoomRocketRewardItem, 0, len(input)) for _, reward := range input { out = append(out, &roomv1.RoomRocketRewardItem{ RewardItemId: reward.RewardItemID, ResourceGroupId: reward.ResourceGroupID, Weight: reward.Weight, Quantity: reward.Quantity, DisplayName: reward.DisplayName, IconUrl: reward.IconURL, }) } return out } func roomRocketFuelRulesFromProto(input []*roomv1.RoomRocketGiftFuelRule) []GiftFuelRuleConfig { out := make([]GiftFuelRuleConfig, 0, len(input)) for _, rule := range input { if rule == nil { continue } out = append(out, GiftFuelRuleConfig{ RuleID: rule.GetRuleId(), GiftID: rule.GetGiftId(), GiftTypeCode: rule.GetGiftTypeCode(), MultiplierPPM: rule.GetMultiplierPpm(), FixedFuel: rule.GetFixedFuel(), Excluded: rule.GetExcluded(), }) } return out } func roomRocketFuelRulesToProto(input []GiftFuelRuleConfig) []*roomv1.RoomRocketGiftFuelRule { out := make([]*roomv1.RoomRocketGiftFuelRule, 0, len(input)) for _, rule := range input { out = append(out, &roomv1.RoomRocketGiftFuelRule{ RuleId: rule.RuleID, GiftId: rule.GiftID, GiftTypeCode: rule.GiftTypeCode, MultiplierPpm: rule.MultiplierPPM, FixedFuel: rule.FixedFuel, Excluded: rule.Excluded, }) } return out } func firstNonEmpty(values ...string) string { for _, value := range values { if strings.TrimSpace(value) != "" { return value } } return "" }