package baishun import ( "chatapp3-golang/internal/service/gameprovider" "context" "errors" "strconv" ) var _ gameprovider.Provider = (*AppProvider)(nil) // AppProvider 把百顺服务适配成统一厂商接口。 type AppProvider struct { service *BaishunService } // NewAppProvider 创建百顺统一厂商适配器。 func NewAppProvider(service *BaishunService) *AppProvider { if service == nil { return nil } return &AppProvider{service: service} } // Key 返回统一厂商标识。 func (p *AppProvider) Key() string { return baishunVendorType } // DisplayName 返回厂商展示名。 func (p *AppProvider) DisplayName() string { return "百顺" } // SupportsLaunch 判断启动请求是否属于百顺。 func (p *AppProvider) SupportsLaunch(ctx context.Context, user gameprovider.AuthUser, req gameprovider.LaunchRequest) (bool, error) { _, err := p.service.resolveLaunchGameRow(ctx, user.SysOrigin, BaishunLaunchAppRequest{ ID: req.ID, GameID: req.GameID, }) if err == nil { return true, nil } var appErr *AppError if errors.As(err, &appErr) && appErr.Code == "game_not_found" { return false, nil } return false, err } // ListShortcutGames 返回百顺房间快捷游戏。 func (p *AppProvider) ListShortcutGames(ctx context.Context, user gameprovider.AuthUser, roomID string) ([]gameprovider.RoomGameListItem, error) { items, err := p.service.ListShortcutGames(ctx, user, roomID) if err != nil { return nil, err } return mapRoomGameListItems(items), nil } // ListRoomGames 返回百顺房间游戏列表。 func (p *AppProvider) ListRoomGames(ctx context.Context, user gameprovider.AuthUser, roomID, category string) (*gameprovider.RoomGameListResponse, error) { resp, err := p.service.ListRoomGames(ctx, user, roomID, category) if err != nil { return nil, err } return &gameprovider.RoomGameListResponse{Items: mapRoomGameListItems(resp.Items)}, nil } // GetRoomState 返回百顺房间状态。 func (p *AppProvider) GetRoomState(ctx context.Context, user gameprovider.AuthUser, roomID string) (*gameprovider.RoomStateResponse, error) { resp, err := p.service.GetRoomState(ctx, user, roomID) if err != nil { return nil, err } return mapRoomStateResponse(resp), nil } // LaunchGame 启动百顺游戏。 func (p *AppProvider) LaunchGame(ctx context.Context, user gameprovider.AuthUser, req gameprovider.LaunchRequest, clientIP string) (*gameprovider.LaunchResponse, error) { resp, err := p.service.LaunchGame(ctx, user, BaishunLaunchAppRequest{ ID: req.ID, RoomID: req.RoomID, GameID: req.GameID, SceneMode: req.SceneMode, ClientOrigin: req.ClientOrigin, }, clientIP) if err != nil { return nil, err } return &gameprovider.LaunchResponse{ ID: resp.ID, GameSessionID: resp.GameSessionID, Provider: baishunVendorType, GameID: resp.GameID, ProviderGameID: strconv.Itoa(resp.VendorGameID), Entry: gameprovider.LaunchEntry{ LaunchMode: resp.Entry.LaunchMode, EntryURL: resp.Entry.EntryURL, PreviewURL: resp.Entry.PreviewURL, DownloadURL: resp.Entry.DownloadURL, PackageVersion: resp.Entry.PackageVersion, Orientation: resp.Entry.Orientation, SafeHeight: resp.Entry.SafeHeight, }, LaunchConfig: resp.BridgeConfig, RoomState: *mapRoomStateResponse(&resp.RoomState), }, nil } // CloseGame 关闭百顺游戏。 func (p *AppProvider) CloseGame(ctx context.Context, user gameprovider.AuthUser, req gameprovider.CloseRequest) (*gameprovider.RoomStateResponse, error) { resp, err := p.service.CloseGame(ctx, user, BaishunCloseAppRequest{ RoomID: req.RoomID, GameSessionID: req.GameSessionID, Reason: req.Reason, }) if err != nil { return nil, err } return mapRoomStateResponse(resp), nil } func mapRoomGameListItems(items []RoomGameListItem) []gameprovider.RoomGameListItem { result := make([]gameprovider.RoomGameListItem, 0, len(items)) for _, item := range items { result = append(result, gameprovider.RoomGameListItem{ ID: item.ID, GameID: item.GameID, GameType: item.GameType, Provider: baishunVendorType, ProviderGameID: strconv.Itoa(item.VendorGameID), Name: item.Name, Cover: item.Cover, Category: item.Category, Sort: item.Sort, LaunchMode: item.LaunchMode, FullScreen: item.FullScreen, GameMode: item.GameMode, SafeHeight: item.SafeHeight, Orientation: item.Orientation, PackageVersion: item.PackageVersion, Status: item.Status, LaunchParams: item.LaunchParams, }) } return result } func mapRoomStateResponse(resp *BaishunRoomStateResponse) *gameprovider.RoomStateResponse { if resp == nil { return nil } state := &gameprovider.RoomStateResponse{ RoomID: resp.RoomID, State: resp.State, Provider: baishunVendorType, GameSessionID: resp.GameSessionID, CurrentGameID: resp.CurrentGameID, CurrentGameName: resp.CurrentGameName, CurrentGameCover: resp.CurrentGameCover, HostUserID: resp.HostUserID, } if resp.CurrentVendorGameID > 0 { state.CurrentProviderGameID = strconv.Itoa(resp.CurrentVendorGameID) } return state }