package model import ( "encoding/base64" "rocommon" "rocommon/service" "rocommon/util" model2 "roserver/baseserver/model" model3 "roserver/db/model" "roserver/serverproto" "strconv" ) /* func (this *GuildManager) RemoveGuildBoss(bossId uint32, guild *GuildData) { if guild == nil || guild.GuildBoss == nil || len(guild.GuildBoss) <= 0 { return } fieldStr := strconv.FormatUint(uint64(bossId), 10) value := strconv.FormatUint(uint64(guild.GuildBase.GuildBrief.GuildId), 10) keyStr := model2.GuildBossPrefix + value service.GetRedis().HDel(keyStr, fieldStr) delete(guild.GuildBoss, bossId) } */ func (this *GuildManager) SaveGuildDemon(guild *GuildData) { if guild == nil || guild.GuildDemon == nil { return } fieldStr := strconv.FormatUint(uint64(guild.GuildBase.GuildBrief.GuildId), 10) keyStr := model2.GuildDemonPrefix msgData, err := rocommon.GetCodec().Marshal(guild.GuildDemon) if err != nil { util.InfoF("[SaveGuildDemon] Marshal err:%v %v", err, fieldStr) return } msgStr := base64.StdEncoding.EncodeToString(msgData.([]byte)) ret, err := service.GetRedis().HSet(keyStr, fieldStr, msgStr).Result() if err != nil { util.InfoF("[SaveGuildDemon] err:%v %v", err, ret) return } } //加载1个公会的公会BOSS func (this *GuildManager) LoadGuildDemon(guild *GuildData) error { if guild == nil { return nil } if guild.GuildDemon == nil { guild.GuildDemon = &serverproto.GuildDemon{} } fieldStr := strconv.FormatUint(uint64(guild.GuildBase.GuildBrief.GuildId), 10) baseStr := model2.GuildDemonPrefix guildBaseStr, baseErr := service.GetRedis().HGet(baseStr, fieldStr).Result() if baseErr == nil { guildDemon := &serverproto.GuildDemon{} err := model2.GetDecodeMessage(guildDemon, guildBaseStr) if err == nil { guild.GuildDemon = guildDemon } else { util.ErrorF("[LoadGuildDemon] get guilddemonStr [%v] err:%v", guildBaseStr, err) } } this.RefreshGuildDemon(guild, 0) return nil } func (this *GuildManager) RemoveGuildDemonRank(guildId uint64, guildDemon *serverproto.GuildDemon) { if guildDemon == nil || guildDemon.TotalDamage <= 0 || len(guildDemon.DamageList) <= 0 { return } keyStr := strconv.FormatUint(uint64(guildId), 10) //删除公会榜 service.GetRedis().ZRem(model2.GuildDemonGuildPrefix, keyStr) //删除公会MVP榜 service.GetRedis().ZRem(model2.GuildDemonMVPPrefix, keyStr) util.InfoF("[RemoveGuildDemonRank] uid:%v", guildId) } //保存公会魔王总伤害排名榜单 func (this *GuildManager) SaveDemonGuildDamageRank(guildId uint64, guildDemon *serverproto.GuildDemon) { scoreStr := this.GetDemonRankScoreDailyReset(uint64(guildDemon.TotalDamage), util.GetCurrentTime()) // scoreStr := model2.GetRankScoreCommon(uint64(guildDemon.TotalDamage), util.GetCurrentTime()) keyStr := strconv.FormatUint(uint64(guildId), 10) _, err := service.GetRedis().ZAdd(model2.GuildDemonGuildPrefix, service.BaseZ{Score: float64(scoreStr), Member: keyStr}).Result() if err != nil { util.ErrorF("[AddSkillScoreRank] err:%v uid:%v", err, guildId) } } //清除公会魔王总伤害排名榜单 func (this *GuildManager) ClearDemonGuildDamageRank() { service.GetRedis().Del(model2.GuildDemonGuildPrefix) util.InfoF("[ClearDemonGuildDamageRank] clean guild rank") } func (this *GuildManager) SaveDemonMVPDamageRank(guildId, damage uint64) { //公会没有人,或者公会第一名就是本人 scoreStr := this.GetDemonRankScoreDailyReset(uint64(damage), util.GetCurrentTime()) keyStr := strconv.FormatUint(uint64(guildId), 10) _, err := service.GetRedis().ZAdd(model2.GuildDemonMVPPrefix, service.BaseZ{Score: float64(scoreStr), Member: keyStr}).Result() if err != nil { util.ErrorF("[AddSkillScoreRank] err:%v guildId:%v", err, guildId) } } //保存公会魔王总伤害排名榜单 func (this *GuildManager) ClearDemonMVPDamageRank() { service.GetRedis().Del(model2.GuildDemonMVPPrefix) util.InfoF("[ClearDemonMVPDamageRank] clean mvp rank") } func (this *GuildManager)GetCurStartDay() { } func (this *GuildManager)RefreshGuildDemon(guild *GuildData, curTime uint64) bool { if guild == nil { return false } if guild.GuildDemon.RefreshTime == 0 { guild.GuildDemon.RefreshTime = util.GetLatest5Hour() return false } if curTime == 0 { curTime = util.GetCurrentTime() } if curTime < guild.GuildDemon.RefreshTime { return false } util.DebugF("[RefreshGuildDemon] save guild demon reward data begin damage :%v count :%v ", guild.GuildDemon.TotalDamage, len(guild.GuildDemon.DamageList)) if guild.GuildDemon != nil && guild.GuildDemon.TotalDamage != 0 && len(guild.GuildDemon.DamageList) > 0 { nowTime := util.GetCurrentTimeNow() curWeekDay := nowTime.Weekday() if curWeekDay == 0 { curWeekDay = 7 } demonData := model2.GetDemonInfoByTimeStamp(guild.GuildDemon.RefreshTime) if demonData == nil { util.InfoF("[RefreshGuildDemon] guild demon config not found err:%v ", curWeekDay) return false } util.DebugF("[RefreshGuildDemon] save guild demon reward data success :%v refTime :%v, demonId :%v", curWeekDay, guild.GuildDemon.RefreshTime, demonData.DemonId) //保存当天的战斗结果(参与战斗的人,和战斗的结算等级) value := strconv.FormatUint(uint64(guild.GuildBase.GuildBrief.GuildId), 10) keyStr := model2.GuildDemonRewardPrefix + value fieldStr := strconv.FormatUint(uint64(demonData.DemonId), 10) //存储配置ID reward := &serverproto.GuildDemonReward{} reward.TotalDamage = guild.GuildDemon.TotalDamage reward.DamageList = guild.GuildDemon.DamageList reward.DemonId = demonData.DemonId msgData, err := rocommon.GetCodec().Marshal(reward) if err != nil { util.InfoF("[RefreshGuildDemonf] DamageList Marshal err:%v %v", err, fieldStr) return false } msgStr := base64.StdEncoding.EncodeToString(msgData.([]byte)) ret, err := service.GetRedis().HSet(keyStr, fieldStr, msgStr).Result() if err != nil { util.InfoF("[RefreshGuildDemon] DamageList err:%v %v", err, ret) return false } //打包奖励 rewardNtf := &serverproto.SSGuildDemonRewardNtf{ DemonId: reward.DemonId, DemonLevel: demonData.DemonLevel, TotalDamage: reward.TotalDamage, } for _, data := range guild.GuildDemon.DamageList { if data.Uid != 0 { rewardNtf.UidList = append(rewardNtf.UidList, data.Uid) } } SendToAllGame(rewardNtf) //当天战斗的数据,和伤害,全部清除 guild.GuildDemon.TotalDamage = 0 guild.GuildDemon.DamageList = append(guild.GuildDemon.DamageList[0:0]) } guild.GuildDemon.RefreshTime = util.GetLatest5Hour() this.SaveGuildDemon(guild) return true } const TickGapTime = 5*1000 //刷新公会魔王 func (this *GuildManager) RefreshGuildDemonAll(nowTime uint64) { if this.DemonTickTime == 0 { this.DemonTickTime = nowTime return } if this.DemonTickTime + TickGapTime > nowTime { return } this.DemonTickTime = nowTime needClear := false for _, guild := range this.Guilds { bRet := this.RefreshGuildDemon(guild, nowTime) if bRet == true { needClear = true } } if needClear == true { //清除排行榜 this.ClearDemonGuildDamageRank() this.ClearDemonMVPDamageRank() } } //初始化公会魔王 func (this *GuildManager) InitGuildDemon(guildId uint64) { //如果公会数据为空,则初始化 } //是否在魔王战斗时间 func (this *GuildManager) IsInDemonFightTime() serverproto.ErrorCode { nowTime := util.GetCurrentTimeNow() //凌晨4.30 到 5点前 if nowTime.Hour() == 4 && 30 <= nowTime.Minute() && nowTime.Minute()<= 59 { return serverproto.ErrorCode_ERROR_FAIL } return serverproto.ErrorCode_ERROR_OK } func (this *GuildManager) GetNextUpTime(demonData *model2.GuildDemonData, durationDay int32) uint64 { if demonData == nil { return 0 } levelUpDay := demonData.EndDay - demonData.StartDay + 1 if levelUpDay <= 0 { return 0 } if durationDay > demonData.EndDay { return 0 } else if durationDay < demonData.EndDay { util.DebugF("[GetNextUpTime] durationDay: %v, demonData.EndDay: %v, demonData.WeekDay: %v ",durationDay, demonData.EndDay, demonData.WeekDay) return util.GetLatest5Hour() + uint64((demonData.EndDay - durationDay - 1)*DayMillSecond) } return 0 } const DayMillSecond = 24*3600*1000 func (this *GuildManager) GetGuildDemonInfo(uid, guildid uint64, ackMsg *serverproto.SCGuildDemonInfoAck) { if ackMsg == nil { return } guild := this.GetGuild(guildid) if guild == nil || guild.GuildDemon == nil { return } ackMsg.DemonId = guild.GuildDemon.CurDemonId ackMsg.TotalBossDamage = guild.GuildDemon.TotalDamage nowTime := util.GetCurrentTimeNow() curWeekDay := nowTime.Weekday() if curWeekDay == 0 { curWeekDay = 7 } demonData, durationDay := model2.GetDemonInfo(int32(curWeekDay), nowTime) ackMsg.DemonId = demonData.DemonId ackMsg.DemonLevel = demonData.DemonLevel ackMsg.NextUpTime = this.GetNextUpTime(demonData, durationDay) ackMsg.Damage = 0 ackMsg.MvpDamage = 0 ackMsg.MvpBrief = nil ackMsg.EndTime = util.GetLatest5Hour() - 30*60*1000 maxUid := uint64(0) fightTime := uint64(0) if len(guild.GuildDemon.DamageList) > 0 { //打包列表 ackMsg.RankList = guild.GuildDemon.DamageList for _, data := range guild.GuildDemon.DamageList { if ackMsg.MvpDamage < data.Damage || (ackMsg.MvpDamage == data.Damage && data.FightTime < fightTime) { ackMsg.MvpDamage = data.Damage maxUid = data.Uid fightTime = data.FightTime } if uid == data.Uid { ackMsg.Damage = data.Damage } } } if maxUid != 0 { ackMsg.MvpBrief = &serverproto.CommonPlayerBriefInfo{} model3.GetSystemDataFromRedis(model3.RolePlayerBriefPrefix, maxUid, ackMsg.MvpBrief) } } //todo msg.Damage <= 0 在 game就要屏蔽掉 func (this *GuildManager) GuildDemonFight(msg *serverproto.SSGuildDemonFightReq, ackMsg *serverproto.SSGuildDemonFightAck) { if msg == nil || ackMsg == nil || msg.Damage <= 0 { return } nowTime := util.GetCurrentTimeNow() curWeekDay := nowTime.Weekday() if curWeekDay == 0 { curWeekDay = 7 } demonData, _ := model2.GetDemonInfo(int32(curWeekDay), nowTime) if demonData == nil { return } if demonData.DemonId != msg.DemonId { return } bRet := this.IsInDemonFightTime() if bRet != serverproto.ErrorCode_ERROR_OK { return } guild := this.GetGuild(msg.GuildId) if guild == nil || guild.GuildDemon == nil { return } oldTotalDamage := guild.GuildDemon.TotalDamage // oldMvpDamage := uint64(0) curUidDamage := msg.Damage //找到这个公会成员是否参加过 bFind := false if len(guild.GuildDemon.DamageList) > 0 { for _, data := range guild.GuildDemon.DamageList { if oldMvpDamage < data.Damage { oldMvpDamage = data.Damage } //跟新本次战斗的玩家数据 if data.Uid == msg.Uid { bFind = true data.Damage += msg.Damage //总伤害 guild.GuildDemon.TotalDamage += msg.Damage curUidDamage = data.Damage } } } if bFind == false { guild.GuildDemon.DamageList = append(guild.GuildDemon.DamageList, &serverproto.DemonDamage{ Uid: msg.Uid, Damage: msg.Damage, }) guild.GuildDemon.TotalDamage += msg.Damage } this.SaveGuildDemon(guild) //如果本公会最大伤害有变化 if oldMvpDamage < curUidDamage { this.SaveDemonMVPDamageRank(msg.GuildId, curUidDamage) } util.InfoF("guild demon mvp changed guildId:%v , uid:%v, damage:%v, totalDamage:%v, guilddamage:%v", msg.GuildId, msg.Uid, msg.Damage, curUidDamage, guild.GuildDemon.TotalDamage) //刷新公会总伤害榜单 this.SaveDemonGuildDamageRank(msg.GuildId, guild.GuildDemon) ackMsg.RefreshTime = uint64(demonData.DemonId) ackMsg.TotalDamage = guild.GuildDemon.TotalDamage ackMsg.DemonId = demonData.DemonId ackMsg.FreeFightCount = demonData.ChallengeCount oldDamageLevel := int32(0) for _, levelData := range demonData.RewardStage { if levelData.StageMin <= guild.GuildDemon.TotalDamage && (guild.GuildDemon.TotalDamage <= levelData.StageMax || levelData.Level >=int32( len(demonData.RewardStage))) && levelData.Level >= model2.GlobalGuildDemonBroadCastLevel { //发送全局播报 ackMsg.GuildName = guild.GuildBase.GuildBrief.GuildName ackMsg.RewardLevel = levelData.Level } if levelData.StageMin <= oldTotalDamage && (oldTotalDamage <= levelData.StageMax || levelData.Level >= int32( len(demonData.RewardStage))) && levelData.Level >= model2.GlobalGuildDemonBroadCastLevel { //发送全局播报 oldDamageLevel = levelData.Level } } //如果本次战斗为提升奖励档位,则不发送广播 if oldDamageLevel >= ackMsg.RewardLevel { ackMsg.GuildName = "" ackMsg.RewardLevel = 0 } } func (this *GuildManager) GetDemonGuildRank(page int32, guildId uint64, ackMsg *serverproto.SCGuildDemonGuildRankAck) { if ackMsg == nil || page == 0 { return } rankBegin := (page - 1) * 10 rankEnd := (page * 10) - 1 rankCount, err3 := service.GetRedis().ZCard(model2.GuildDemonGuildPrefix).Result() if err3 == nil { if rankCount > 0 { topListWithScore, err := service.GetRedis().ZRevRangeWithScores(model2.GuildDemonGuildPrefix, int64(rankBegin), int64(rankEnd)).Result() if err == nil && len(topListWithScore) > 0 { for i := 0; i < len(topListWithScore); i++ { // rankUid, _ := strconv.ParseUint(topListWithScore[i].Member.(string), 10, 64) score := this.GetDemonValByRankScoreDailyReset(topListWithScore[i].Score) guildUid, _ := strconv.ParseUint(topListWithScore[i].Member.(string), 10, 64) guild := this.GetGuild(guildUid) if guild == nil { continue } ntfData := &serverproto.GuildNotifyData{ Brief: &serverproto.GuildBrief{}, } ntfData.Brief = guild.GuildBase.GuildBrief //todo wangzhaocan 公会数据打包 ackMsg.RankList = append(ackMsg.RankList, &serverproto.GuildDemonGuildRank{ Data: ntfData, Rank: rankBegin + int32(i+1), Damage: score, }) } } } } else { util.DebugF("GetDemonGuildRank totalRanks err=%v", err3) } if int32(rankCount) <= rankEnd { ackMsg.IsEnd = true } //获得本公会的相关数据 if guildId != 0 && page == 1 { guild := this.GetGuild(guildId) if guild == nil { return } ackMsg.SelfGuild = &serverproto.GuildDemonGuildRank{ Data:&serverproto.GuildNotifyData{ Brief:&serverproto.GuildBrief{}, }, } prefixStr := model2.GuildDemonGuildPrefix keyStr := strconv.FormatUint(guildId, 10) selfRank, rankErr := service.GetRedis().ZRevRank(prefixStr, keyStr).Result() if rankErr == nil && rankErr != service.NIL { topListWithScore, err := service.GetRedis().ZRevRangeWithScores(prefixStr, selfRank, selfRank).Result() if err == nil { for index, _ := range topListWithScore { rankGuildId, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64) if rankGuildId == guildId { skillScore := this.GetDemonValByRankScoreDailyReset(topListWithScore[index].Score) ackMsg.SelfGuild.Rank = int32(selfRank + 1) ackMsg.SelfGuild.Damage = skillScore break } } } else { util.DebugF("[GetTopSkillRank] selfRank err:%v", err) return } } ackMsg.SelfGuild.Data.Brief = guild.GuildBase.GuildBrief } } func (this *GuildManager) GetGuildDemonMVPReq(page int32, guildId uint64, ackMsg *serverproto.SCGuildDemonMVPRankAck) { if ackMsg == nil { return } rankBegin := (page - 1) * 10 rankEnd := (page * 10) - 1 rankCount, err3 := service.GetRedis().ZCard(model2.GuildDemonMVPPrefix).Result() if err3 == nil { topListWithScore, err := service.GetRedis().ZRevRangeWithScores(model2.GuildDemonMVPPrefix, int64(rankBegin), int64(rankEnd)).Result() if err == nil && len(topListWithScore) > 0 { for i := 0; i < len(topListWithScore); i++ { // rankUid, _ := strconv.ParseUint(topListWithScore[i].Member.(string), 10, 64) rankGuildId, _ := strconv.ParseUint(topListWithScore[i].Member.(string), 10, 64) score := this.GetDemonValByRankScoreDailyReset(topListWithScore[i].Score) guild := this.GetGuild(rankGuildId) if guild == nil || guild.GuildBase == nil || guild.GuildDemon == nil { continue } mvpUid, _ := this.GetGuildDemonMvp(guild.GuildDemon) /* guildId := this.GetPlayerGuildId(rankUid) guild := this.GetGuild(guildId) */ ackMsg.RankList = append(ackMsg.RankList, &serverproto.GuildDemonRank{ Uuid: mvpUid, Rank: rankBegin + int32(i+1), Damage: score, GuildBadge: guild.GuildBase.GuildBrief.GuildBadge, GuildName: guild.GuildBase.GuildBrief.GuildName, }) } } } else { util.DebugF("GetGuildDemonMVPReq totalRanks err=%v", err3) } if int32(rankCount) <= rankEnd { ackMsg.IsEnd = true } //获得本公会相关MVP数据 if guildId != 0 && page == 1 { guild := this.GetGuild(guildId) if guild == nil || guild.GuildBase == nil { return } mvpUid, mvpDamage := this.GetGuildDemonMvp(guild.GuildDemon) if mvpUid != 0 { prefixStr := model2.GuildDemonMVPPrefix // keyStr := strconv.FormatUint(mvpUid, 10) keyStr := strconv.FormatUint(guildId, 10) selfRank, rankErr := service.GetRedis().ZRevRank(prefixStr, keyStr).Result() if rankErr == nil && rankErr != service.NIL { topListWithScore, err := service.GetRedis().ZRevRangeWithScores(prefixStr, selfRank, selfRank).Result() if err == nil { for index, _ := range topListWithScore { rankGuildId, _ := strconv.ParseUint(topListWithScore[index].Member.(string), 10, 64) if rankGuildId == guildId { ackMsg.SelfGuildMvp = &serverproto.GuildDemonRank{} // skillScore := model2.GetValByRankScoreDailyReset(topListWithScore[index].Score) ackMsg.SelfGuildMvp.Rank = int32(selfRank + 1) ackMsg.SelfGuildMvp.Damage = mvpDamage ackMsg.SelfGuildMvp.Uuid = mvpUid ackMsg.SelfGuildMvp.GuildName = guild.GuildBase.GuildBrief.GuildName ackMsg.MvpBrief = &serverproto.CommonPlayerBriefInfo{} model3.GetSystemDataFromRedis(model3.RolePlayerBriefPrefix, mvpUid, ackMsg.MvpBrief) break } } } else { util.DebugF("[GetTopSkillRank] selfRank err:%v", err) return } } } } } //return :mvpUid, mvpDamage func (this *GuildManager) GetGuildDemonMvp(guildDemon *serverproto.GuildDemon) (uint64, uint64) { if guildDemon == nil || len(guildDemon.DamageList) <= 0 || guildDemon.TotalDamage <= 0 { return 0, 0 } mvpDamage := uint64(0) mvpUid := uint64(0) mvpTime := uint64(0) for _, data := range guildDemon.DamageList { if mvpDamage < data.Damage || (mvpDamage == data.Damage && data.FightTime < mvpTime){ mvpDamage = data.Damage mvpUid = data.Uid mvpTime = data.FightTime } } return mvpUid, mvpDamage } func (this *GuildManager) OnlineGetDemonReward(uid, demonConfigId uint64, ev rocommon.ProcEvent) { if demonConfigId <= 0 { //表示没有参加过公会魔王挑战 return } guildId := this.GetPlayerGuildId(uid) if guildId == 0 { util.InfoF("guild get demon reward error guild not found: uid:%v", uid) return } guildData := this.GetGuild(guildId) if guildData == nil { util.InfoF("guild get demon reward error guild data not found: uid:%v, guildId:%v", uid, guildId) return } value := strconv.FormatUint(uint64(guildId), 10) demonStr := model2.GuildDemonRewardPrefix + value fieldStr := strconv.FormatUint(uint64(demonConfigId), 10) guildDemonStr, demonErr := service.GetRedis().HGet(demonStr, fieldStr).Result() rewardData := &serverproto.GuildDemonReward{} if demonErr == nil { err := model2.GetDecodeMessage(rewardData, guildDemonStr) if err != nil { util.InfoF("[OnlineGetDemonReward] get guildDemonStr [%v] err:%v", guildDemonStr, err) return } } else { util.InfoF("[OnlineGetDemonReward] get guildDemonStr [%v] demonErr:%v", guildDemonStr, demonErr) return } //查找这个人是否参与过战斗 bFind := false for _, data := range rewardData.DamageList { if data.Uid == uid { bFind = true } } if bFind == true { demonData := model2.GetDemonDataByConfigId(rewardData.DemonId) if demonData == nil { util.ErrorF("guild get demon reward config error uid:%v, demon:%v demonConfigId:%v", uid, rewardData.DemonId, demonConfigId) return } //给奖励 rewardMsg := &serverproto.SSGuildDemonOnlineGetRewardNtf{ DemonId: rewardData.DemonId, } for _, data := range demonData.RewardStage { if data.StageMin <= rewardData.TotalDamage && (rewardData.TotalDamage <= data.StageMax || data.Level >= int32(len(demonData.RewardStage))) { if len(data.Reward) <= 0 { util.ErrorF("guild get demon reward failed uid:%v, demonId:%v", uid, rewardData.DemonId) return } rewardMsg.RewardList = data.Reward util.InfoF("guild get demon reward success uid:%v, demonId:%v, reward%v, demonConfigId:%v", uid, rewardData.DemonId, data.Reward, demonConfigId) break } } model2.ServiceReplay(ev, rewardMsg) } } //排行榜每日重置时使用,切记!!! func (this *GuildManager)GetDemonRankScoreDailyReset(val uint64, passTime uint64) uint64 { //score var scoreStr = val if scoreStr >= (1 << 40) { scoreStr = (1 << 40) - 1 } //时间修改成以一天内的时间 tmpTime := util.GetCurrentTimeNow() if tmpTime.Hour() >= 5 { passTime = uint64(tmpTime.Hour()*60*60+tmpTime.Minute()*60+tmpTime.Second()) * 1000 } else { passTime = uint64((23+tmpTime.Hour())*60*60+tmpTime.Minute()*60+tmpTime.Second()) * 1000 } scoreStr <<= 24 scoreStr |= 0xffffff - passTime/50 return scoreStr } func (this *GuildManager)GetDemonValByRankScoreDailyReset(score float64) uint64 { val := uint64(score) >> 24 return val }