264 lines
9.6 KiB
Go
264 lines
9.6 KiB
Go
package baishun
|
|
|
|
import (
|
|
"chatapp3-golang/internal/model"
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// ListShortcutGames 返回房间里的快捷游戏列表,数量上限为 5 个。
|
|
func (s *BaishunService) ListShortcutGames(ctx context.Context, user AuthUser, roomID string) ([]RoomGameListItem, error) {
|
|
items, err := s.listRoomGames(ctx, user.SysOrigin, roomID, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(items) > 5 {
|
|
items = items[:5]
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
// ListRoomGames 返回房间可启动的完整游戏列表。
|
|
func (s *BaishunService) ListRoomGames(ctx context.Context, user AuthUser, roomID string, category string) (*RoomGameListResponse, error) {
|
|
items, err := s.listRoomGames(ctx, user.SysOrigin, roomID, category)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &RoomGameListResponse{Items: items}, nil
|
|
}
|
|
|
|
// GetRoomState 返回房间当前的游戏挂载状态。
|
|
func (s *BaishunService) GetRoomState(ctx context.Context, user AuthUser, roomID string) (*BaishunRoomStateResponse, error) {
|
|
var state model.BaishunRoomState
|
|
if err := s.repo.DB.WithContext(ctx).
|
|
Where("sys_origin = ? AND room_id = ?", user.SysOrigin, roomID).
|
|
First(&state).Error; err != nil {
|
|
if err == gorm.ErrRecordNotFound {
|
|
return &BaishunRoomStateResponse{RoomID: roomID, State: baishunRoomStateIdle}, nil
|
|
}
|
|
return nil, err
|
|
}
|
|
resp := &BaishunRoomStateResponse{
|
|
RoomID: roomID,
|
|
State: defaultIfBlank(state.State, baishunRoomStateIdle),
|
|
GameSessionID: state.GameSessionID,
|
|
CurrentGameID: state.CurrentGameID,
|
|
CurrentGameName: state.CurrentGameName,
|
|
CurrentGameCover: state.CurrentGameCover,
|
|
HostUserID: state.HostUserID,
|
|
}
|
|
if state.CurrentVendorGameID != nil {
|
|
resp.CurrentVendorGameID = *state.CurrentVendorGameID
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// listRoomGames 联表读取房间可启动游戏,并按展示规则排序。
|
|
func (s *BaishunService) listRoomGames(ctx context.Context, sysOrigin, roomID, category string) ([]RoomGameListItem, error) {
|
|
sysOrigin = normalizeAdminSysOrigin(sysOrigin)
|
|
profile, err := s.activeProfile(ctx, sysOrigin)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var rows []gameListRow
|
|
query := s.repo.DB.WithContext(ctx).
|
|
Table("sys_game_list_config AS cfg").
|
|
Select(`
|
|
cfg.id AS config_id,
|
|
cfg.sys_origin AS sys_origin,
|
|
ext.profile AS profile,
|
|
cfg.game_id AS internal_game_id,
|
|
cfg.name AS name,
|
|
cfg.category AS category,
|
|
cfg.cover AS cover,
|
|
cfg.sort AS sort,
|
|
cfg.full_screen AS full_screen,
|
|
cfg.game_mode AS game_mode_raw,
|
|
ext.vendor_type AS vendor_type,
|
|
ext.vendor_game_id AS vendor_game_id,
|
|
ext.launch_mode AS launch_mode,
|
|
ext.package_version AS ext_package_version,
|
|
ext.preview_url AS ext_preview_url,
|
|
ext.package_url AS package_url,
|
|
ext.orientation AS ext_orientation,
|
|
ext.safe_height AS ext_safe_height,
|
|
ext.currency_icon AS currency_icon,
|
|
ext.gsp AS ext_gsp,
|
|
ext.extra_json AS ext_extra_json,
|
|
cat.name AS catalog_name,
|
|
cat.cover AS catalog_cover,
|
|
cat.preview_url AS catalog_preview_url,
|
|
cat.download_url AS catalog_download_url,
|
|
cat.package_version AS catalog_package_version,
|
|
cat.orientation AS catalog_orientation,
|
|
cat.safe_height AS catalog_safe_height,
|
|
cat.status AS catalog_status
|
|
`).
|
|
Joins("JOIN sys_game_list_vendor_ext ext ON ext.game_list_config_id = cfg.id AND ext.enabled = 1 AND ext.profile = ?", profile).
|
|
Joins("LEFT JOIN baishun_game_catalog cat ON cat.sys_origin = cfg.sys_origin AND cat.profile = ext.profile AND CAST(cat.vendor_game_id AS CHAR) = ext.vendor_game_id").
|
|
Where("cfg.sys_origin = ? AND cfg.is_showcase = 1 AND ext.vendor_type = ?", sysOrigin, baishunVendorType)
|
|
if strings.TrimSpace(category) != "" && !strings.EqualFold(strings.TrimSpace(category), "CHAT_ROOM") {
|
|
query = query.Where("cfg.category = ?", category)
|
|
}
|
|
if err := query.Order("cfg.sort DESC").Scan(&rows).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
items := make([]RoomGameListItem, 0, len(rows))
|
|
for _, row := range rows {
|
|
items = append(items, row.toListItem())
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
// findGameRow 按内部游戏 ID 查询游戏聚合信息。
|
|
func (s *BaishunService) findGameRow(ctx context.Context, sysOrigin, gameID string) (gameListRow, error) {
|
|
sysOrigin = normalizeAdminSysOrigin(sysOrigin)
|
|
profile, err := s.activeProfile(ctx, sysOrigin)
|
|
if err != nil {
|
|
return gameListRow{}, err
|
|
}
|
|
var row gameListRow
|
|
err = s.repo.DB.WithContext(ctx).
|
|
Table("sys_game_list_config AS cfg").
|
|
Select(`
|
|
cfg.id AS config_id,
|
|
cfg.sys_origin AS sys_origin,
|
|
ext.profile AS profile,
|
|
cfg.game_id AS internal_game_id,
|
|
cfg.name AS name,
|
|
cfg.category AS category,
|
|
cfg.cover AS cover,
|
|
cfg.sort AS sort,
|
|
cfg.full_screen AS full_screen,
|
|
cfg.game_mode AS game_mode_raw,
|
|
ext.vendor_type AS vendor_type,
|
|
ext.vendor_game_id AS vendor_game_id,
|
|
ext.launch_mode AS launch_mode,
|
|
ext.package_version AS ext_package_version,
|
|
ext.preview_url AS ext_preview_url,
|
|
ext.package_url AS package_url,
|
|
ext.orientation AS ext_orientation,
|
|
ext.safe_height AS ext_safe_height,
|
|
ext.currency_icon AS currency_icon,
|
|
ext.gsp AS ext_gsp,
|
|
ext.extra_json AS ext_extra_json,
|
|
cat.name AS catalog_name,
|
|
cat.cover AS catalog_cover,
|
|
cat.preview_url AS catalog_preview_url,
|
|
cat.download_url AS catalog_download_url,
|
|
cat.package_version AS catalog_package_version,
|
|
cat.orientation AS catalog_orientation,
|
|
cat.safe_height AS catalog_safe_height,
|
|
cat.status AS catalog_status
|
|
`).
|
|
Joins("JOIN sys_game_list_vendor_ext ext ON ext.game_list_config_id = cfg.id AND ext.enabled = 1 AND ext.profile = ?", profile).
|
|
Joins("LEFT JOIN baishun_game_catalog cat ON cat.sys_origin = cfg.sys_origin AND cat.profile = ext.profile AND CAST(cat.vendor_game_id AS CHAR) = ext.vendor_game_id").
|
|
Where("cfg.sys_origin = ? AND cfg.game_id = ? AND ext.vendor_type = ?", sysOrigin, gameID, baishunVendorType).
|
|
Limit(1).
|
|
Scan(&row).Error
|
|
if err != nil {
|
|
return gameListRow{}, err
|
|
}
|
|
if strings.TrimSpace(row.InternalGameID) != "" {
|
|
return row, nil
|
|
}
|
|
|
|
var catalog model.BaishunGameCatalog
|
|
if err := s.repo.DB.WithContext(ctx).
|
|
Where("sys_origin = ? AND profile = ? AND internal_game_id = ?", sysOrigin, profile, gameID).
|
|
First(&catalog).Error; err == nil {
|
|
return gameListRow{
|
|
SysOrigin: sysOrigin,
|
|
Profile: profile,
|
|
InternalGameID: defaultIfBlank(catalog.InternalGameID, fmt.Sprintf("bs_%d", catalog.VendorGameID)),
|
|
Name: catalog.Name,
|
|
Cover: catalog.Cover,
|
|
VendorType: baishunVendorType,
|
|
VendorGameID: strconv.Itoa(catalog.VendorGameID),
|
|
LaunchMode: baishunLaunchModeRemote,
|
|
ExtGSP: catalog.GSP,
|
|
CatalogCover: catalog.Cover,
|
|
CatalogPreviewURL: catalog.PreviewURL,
|
|
CatalogDownloadURL: catalog.DownloadURL,
|
|
CatalogPackageVersion: catalog.PackageVersion,
|
|
CatalogSafeHeight: catalog.SafeHeight,
|
|
CatalogOrientation: catalog.Orientation,
|
|
CatalogStatus: catalog.Status,
|
|
GameModeRaw: formatAdminGameModeRaw(baishunFixedGameMode),
|
|
}, nil
|
|
} else if err != gorm.ErrRecordNotFound {
|
|
return gameListRow{}, err
|
|
}
|
|
|
|
return gameListRow{}, NewAppError(http.StatusNotFound, "game_not_found", "room game config not found")
|
|
}
|
|
|
|
// findGameRowByConfigID 按系统游戏配置主键查询游戏聚合信息。
|
|
func (s *BaishunService) findGameRowByConfigID(ctx context.Context, sysOrigin string, configID int64) (gameListRow, error) {
|
|
sysOrigin = normalizeAdminSysOrigin(sysOrigin)
|
|
profile, err := s.activeProfile(ctx, sysOrigin)
|
|
if err != nil {
|
|
return gameListRow{}, err
|
|
}
|
|
var row gameListRow
|
|
err = s.repo.DB.WithContext(ctx).
|
|
Table("sys_game_list_config AS cfg").
|
|
Select(`
|
|
cfg.id AS config_id,
|
|
cfg.sys_origin AS sys_origin,
|
|
ext.profile AS profile,
|
|
cfg.game_id AS internal_game_id,
|
|
cfg.name AS name,
|
|
cfg.category AS category,
|
|
cfg.cover AS cover,
|
|
cfg.sort AS sort,
|
|
cfg.full_screen AS full_screen,
|
|
cfg.game_mode AS game_mode_raw,
|
|
ext.vendor_type AS vendor_type,
|
|
ext.vendor_game_id AS vendor_game_id,
|
|
ext.launch_mode AS launch_mode,
|
|
ext.package_version AS ext_package_version,
|
|
ext.preview_url AS ext_preview_url,
|
|
ext.package_url AS package_url,
|
|
ext.orientation AS ext_orientation,
|
|
ext.safe_height AS ext_safe_height,
|
|
ext.currency_icon AS currency_icon,
|
|
ext.gsp AS ext_gsp,
|
|
ext.extra_json AS ext_extra_json,
|
|
cat.name AS catalog_name,
|
|
cat.cover AS catalog_cover,
|
|
cat.preview_url AS catalog_preview_url,
|
|
cat.download_url AS catalog_download_url,
|
|
cat.package_version AS catalog_package_version,
|
|
cat.orientation AS catalog_orientation,
|
|
cat.safe_height AS catalog_safe_height,
|
|
cat.status AS catalog_status
|
|
`).
|
|
Joins("JOIN sys_game_list_vendor_ext ext ON ext.game_list_config_id = cfg.id AND ext.enabled = 1 AND ext.profile = ?", profile).
|
|
Joins("LEFT JOIN baishun_game_catalog cat ON cat.sys_origin = cfg.sys_origin AND cat.profile = ext.profile AND CAST(cat.vendor_game_id AS CHAR) = ext.vendor_game_id").
|
|
Where("cfg.sys_origin = ? AND cfg.id = ? AND ext.vendor_type = ?", sysOrigin, configID, baishunVendorType).
|
|
Limit(1).
|
|
Scan(&row).Error
|
|
if err != nil {
|
|
return gameListRow{}, err
|
|
}
|
|
if row.ConfigID > 0 {
|
|
return row, nil
|
|
}
|
|
return gameListRow{}, NewAppError(http.StatusNotFound, "game_not_found", "room game config not found")
|
|
}
|
|
|
|
// resolveGSP 解析行模型中的 GSP 值。
|
|
func (s *BaishunService) resolveGSP(row gameListRow, runtimeCfg baishunRuntimeConfig) int {
|
|
if parsed, err := strconv.Atoi(strings.TrimSpace(row.ExtGSP)); err == nil && parsed > 0 {
|
|
return parsed
|
|
}
|
|
return runtimeCfg.gsp()
|
|
}
|