package roomrank import ( "apigame/configs/confroomrank" "apigame/models" "apigame/service/code-msg" "apigame/util/util-lx/lxtime" "apigame/util/zredislock" ) // HandleGetConfig 活动配置 func HandleGetConfig(req *models.ReqRoomRankGetConfig) (code string, rsp models.RspRoomRankGetConfig) { rsp = models.RspRoomRankGetConfig{Config: make([]any, 0)} code = code_msg.RECODE_OK gameId := req.GameID // 尝试更新配置 configs := confroomrank.GetCurrentConfigs(gameId) for _, config := range configs { rsp.Config = append(rsp.Config, config.GenerateConfigClient()) } return } // HandleInfo 房间排行信息 func HandleInfo(req *models.ReqRoomRankInfo) (code string, rsp models.RspRoomRankInfo) { rsp = models.RspRoomRankInfo{} code = code_msg.RECODE_OK gameId := req.GameID playerUid := req.UID playerLevel := req.PlayerLevel // 尝试更新配置 config, hasConfig := confroomrank.GetCurrent(gameId, req.TopType) if !hasConfig { config = new(confroomrank.ActivityConfig) code = code_msg.RECODE_MERGE_ROOMRANK_NOTOPEN_ERROR return } // 读取游戏数据 player := LoadPlayer(gameId, playerUid, req.TopType) player.Name = req.PlayerName player.Icon = req.PlayerIcon // 采用分布式锁 lockKey := getLockKey(gameId, req.TopType, config.Id) opt := zredislock.GetOptionLimitRetry(RoomLockLinearBackoff, RoomLockMaxCount) lock := zredislock.Obtain(lockKey, RoomLockMillisecond, opt) if lock.Err != nil { code = code_msg.RECODE_CAOZUOPINFAN_ERROR return } defer lock.Release() activityTime := GetActivityTime(config) // 尝试判断结算 hasSettleChange := TrySettle(gameId, req.TopType, player, config, activityTime) if hasSettleChange { SavePlayer(gameId, player) } if player.SettleHas() { rsp.RoomRankInfo = GetInfoFromSettle(player, config) return } // 判断玩家等级 if req.PlayerLevel < config.OpenLevel { code = code_msg.RECODE_MERGE_ROOMRANK_LEVEL_ERROR return } // 于此同时,如果活动倒计时 < 关门时间 * 2,则不再允许报名 secNow := lxtime.NowUninx() dtEnd := GetTimeEnd(activityTime, config.ReleaseTime).Unix() if secNow > dtEnd-RoomCloseSecond*2 { code = code_msg.RECODE_MERGE_ROOMRANK_CANTSIGN_ERROR return } needSavePlayer := false defer func() { if needSavePlayer { SavePlayer(gameId, player) } }() if player.ActivityId != config.Id && player.ActivityTime != activityTime { player.ActivityId = config.Id player.ActivityTime = activityTime player.RoomUid = 0 player.Score = 0 needSavePlayer = true } // 判断玩家积分 if player.Score < config.OpenScore { rsp.RoomRankInfo = GetInfoFromPlayer(gameId, player, config) return } // 尝试加入房间 room, hasRoom, firstJoin := TryGetRoom(gameId, req.TopType, player, config, playerLevel, activityTime) if !hasRoom { code = code_msg.RECODE_MERGE_CONFIG_ERROR return } needSavePlayer = true TryReSort(room, config) SavePlayer(gameId, player) SaveRoom(gameId, room) rsp.RoomRankInfo = GetInfoFromRoom(gameId, player, room, config) rsp.RoomRankInfo.FirstJoin = firstJoin return } // HandleGetSettleAward 领取上期结算奖励 func HandleGetSettleAward(req *models.ReqRoomRankGetSettleAward) (code string, rsp models.RspRoomRankGetSettleAward) { rsp = models.RspRoomRankGetSettleAward{} code = code_msg.RECODE_OK gameId := req.GameID playerUid := req.UID // 尝试更新配置 config, hasConfig := confroomrank.GetCurrent(gameId, req.TopType) if !hasConfig { config = new(confroomrank.ActivityConfig) code = code_msg.RECODE_MERGE_ROOMRANK_NOTOPEN_ERROR return } // 读取游戏数据 player := LoadPlayer(gameId, playerUid, req.TopType) player.Name = req.PlayerName player.Icon = req.PlayerIcon // 采用分布式锁 lockKey := getLockKey(gameId, req.TopType, config.Id) opt := zredislock.GetOptionLimitRetry(RoomLockLinearBackoff, RoomLockMaxCount) lock := zredislock.Obtain(lockKey, RoomLockMillisecond, opt) if lock.Err != nil { code = code_msg.RECODE_CAOZUOPINFAN_ERROR return } defer lock.Release() activityTime := GetActivityTime(config) // 尝试判断结算 _ = TrySettle(gameId, req.TopType, player, config, activityTime) if !player.SettleHas() { code = code_msg.RECODE_MERGE_ROOMRANK_NOTHASSETTLE_ERROR return } oldActivityId := player.ActivityId // 领取奖励 rsp.SettleRank = player.SettleRank rsp.SettleScore = player.SettleScore rsp.UserClass = player.SettleUserClass rsp.AwardText = player.SettleAward player.SettleAward = "" player.ActivityId = config.Id player.ActivityTime = 0 player.RoomUid = 0 player.Score = 0 SavePlayer(gameId, player) // 记录日志 recordBase := NewRecordBase(player.Uid, req.TopType, oldActivityId) SaveRecordGetSettleAward(gameId, NewRecordGetSettleAward(recordBase, rsp.AwardText)) return } // HandleAddScore 房间排行增加积分 func HandleAddScore(req *models.ReqRoomRankAddScore) (code string, rsp models.RspRoomRankAddScore) { rsp = models.RspRoomRankAddScore{} code = code_msg.RECODE_OK gameId := req.GameID playerUid := req.UID playerLevel := req.PlayerLevel // 尝试更新配置 config, hasConfig := confroomrank.GetCurrent(gameId, req.TopType) if !hasConfig { config = new(confroomrank.ActivityConfig) code = code_msg.RECODE_MERGE_ROOMRANK_NOTOPEN_ERROR return } // 读取游戏数据 player := LoadPlayer(gameId, playerUid, req.TopType) player.Name = req.PlayerName player.Icon = req.PlayerIcon // 采用分布式锁 lockKey := getLockKey(gameId, req.TopType, config.Id) opt := zredislock.GetOptionLimitRetry(RoomLockLinearBackoff, RoomLockMaxCount) lock := zredislock.Obtain(lockKey, RoomLockMillisecond, opt) if lock.Err != nil { code = code_msg.RECODE_CAOZUOPINFAN_ERROR return } defer lock.Release() activityTime := GetActivityTime(config) // 尝试判断结算 hasSettleChange := TrySettle(gameId, req.TopType, player, config, activityTime) if hasSettleChange { SavePlayer(gameId, player) } if player.SettleHas() { rsp.RoomRankInfo = GetInfoFromSettle(player, config) code = code_msg.RECODE_MERGE_ROOMRANK_HASSETTLE_ERROR return } // 判断玩家等级 if req.PlayerLevel < config.OpenLevel { code = code_msg.RECODE_MERGE_ROOMRANK_LEVEL_ERROR return } // 于此同时,如果活动倒计时 < 关门时间 * 2,则不再允许报名 secNow := lxtime.NowUninx() dtEnd := GetTimeEnd(activityTime, config.ReleaseTime).Unix() if secNow > dtEnd-RoomCloseSecond*2 { code = code_msg.RECODE_MERGE_ROOMRANK_CANTSIGN_ERROR return } needSavePlayer := false defer func() { if needSavePlayer { SavePlayer(gameId, player) } }() if player.ActivityId != config.Id && player.ActivityTime != activityTime { player.ActivityId = config.Id player.ActivityTime = activityTime player.RoomUid = 0 player.Score = 0 needSavePlayer = true } oldScore := player.Score player.Score += req.AddScore newScore := player.Score needSavePlayer = true // 记录日志 recordBase := NewRecordBase(player.Uid, req.TopType, config.Id) SaveRecordAddScore(gameId, NewRecordAddScore(recordBase, req.AddScore, oldScore, newScore)) // 判断玩家积分 if player.Score < config.OpenScore { rsp.RoomRankInfo = GetInfoFromPlayer(gameId, player, config) return } // 尝试加入房间 room, hasRoom, firstJoin := TryGetRoom(gameId, req.TopType, player, config, playerLevel, activityTime) if !hasRoom { code = code_msg.RECODE_MERGE_CONFIG_ERROR return } // 房间排行增加积分 UpdatePlayerScore(room, player) TryReSort(room, config) SaveRoom(gameId, room) rsp.RoomRankInfo = GetInfoFromRoom(gameId, player, room, config) rsp.RoomRankInfo.FirstJoin = firstJoin return }