diff --git a/src/server/conf/server.json b/src/server/conf/server.json index 25ea9004..38770d42 100644 --- a/src/server/conf/server.json +++ b/src/server/conf/server.json @@ -2,7 +2,7 @@ "AppID": 0, "LogLevel": "debug", "LogPath": "./log", - "TCPAddr": ":3602", + "TCPAddr": ":3601", "WSAddr": ":3567", "RPCAddr": ":50051", "MySqlAddr": "127.0.0.1", diff --git a/src/server/game/GameLogic.go b/src/server/game/GameLogic.go index da556aaa..552c45ad 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -561,12 +561,11 @@ func G_getGameLogic() *GameLogic { G_GameLogicPtr.RegisterEvent() // 注册事件 G_GameLogicPtr.RegisterNetWorkFunc() // 注册客户端接口 G_GameLogicPtr.InitActivity() // 初始化活动 + G_GameLogicPtr.CreateActivityMgr() //创建活动管理器 if conf.Server.ServerType == "center" { // G_GameLogicPtr.CreateFriendMgr() //创建好友管理器 G_GameLogicPtr.CreateChampshipMgr() // 创建竞标赛管理器 G_GameLogicPtr.CreateVarMgr() // 创建变量管理器 - } else { - G_GameLogicPtr.CreateActivityMgr() //创建活动管理器 } G_GameLogicPtr.CreateRankMgr() //创建排行榜管理器 G_GameLogicPtr.CreateMailMgr() //创建邮件管理器 diff --git a/src/server/game/activity_func.go b/src/server/game/activity_func.go index a29735d5..9c4e2bef 100644 --- a/src/server/game/activity_func.go +++ b/src/server/game/activity_func.go @@ -102,6 +102,8 @@ func (p *Player) ActivityLogin() { // 猫猫回礼登录 p.CatReturnGiftLogin() + // 赛季活动登录 + p.ChampionshipLogin() } // 发送活动邮件 @@ -185,6 +187,11 @@ func (p *Player) CatReturnGiftLogin() { p.CatReturnGiftZeroUpdate() } +func (p *Player) ChampionshipLogin() { + p.ChampionshipZeroUpdate() + p.BackChampship() +} + // 猫猫回礼0点更新 func (p *Player) CatReturnGiftZeroUpdate() { activityInfo := p.GetActivityInfo(activity.ACT_TYPE_CAT_RETURN_GIFT) @@ -592,16 +599,18 @@ func (p *Player) GetTodayAndYesterdayActivityId(atype int) (int, int) { } func (p *Player) ChampionshipZeroUpdate() { - todayActivityId, _ := p.GetChampshipActivityId() ChampionshipMod := p.PlayMod.getChampshipMod() - aid := ChampionshipMod.AId + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + if activityCfg.AId != 0 && activityCfg.AId == ChampionshipMod.AId { + return + } var items []*item.Item - items = p.GetChampshipReward(aid) + items = p.GetChampshipReward(ChampionshipMod.Id) if len(items) > 0 { p.SendActivityMail2(items, "backend_championship_mail_title", "backend_championship_mail_content") p.PushClientRes(p.GetMailMod().BackData()) } - p.PlayMod.getChampshipMod().ZeroUpdate(todayActivityId) + p.PlayMod.getChampshipMod().ZeroUpdate(activityCfg.Id, activityCfg.AId) } func (p *Player) GetChampshipReward(id int) []*item.Item { diff --git a/src/server/game/activity_mgr.go b/src/server/game/activity_mgr.go index 4e13ff45..9120aafb 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -107,6 +107,41 @@ func (r *ActivityMgr) GetActivityList() []ActivityCfg { return list } +func (r *ActivityMgr) GetActivityListByType(atype int) ActivityCfg { + // 获取活动列表 + data := r.getData() + data.mu.Lock() + defer data.mu.Unlock() + list := make([]ActivityCfg, 0, len(data.List)) + now := GoUtil.Now() + for _, v := range data.List { + if v.Type == atype { + info := v.Copy() + //循环活动,重新计算活动时间 + if info.Interval > 0 { + info.AId = int(info.Startime) + list = append(list, info) + internal := (now - info.Startime) / info.Interval + for i := int64(0); i <= internal; i++ { + newInfo := info.Copy() + newInfo.Startime += info.Interval + newInfo.Endtime += info.Interval + newInfo.AId = int(newInfo.Startime) //活动id用开始时间表示,方便客户端排序 + list = append(list, newInfo) + } + } else { + list = append(list, info) + } + } + } + for _, v := range list { + if v.Startime <= GoUtil.Now() && v.Endtime > GoUtil.Now() { + return v + } + } + return ActivityCfg{} +} + func (r *ActivityMgr) GetActivityCfg(Id int) ActivityCfg { // 获取活动配置 data := r.getData() diff --git a/src/server/game/admin.go b/src/server/game/admin.go index 5c00ded4..8ce8590b 100644 --- a/src/server/game/admin.go +++ b/src/server/game/admin.go @@ -326,7 +326,12 @@ func ReqAdminBan(args []interface{}) error { } func AcitivityCfgReload() { - G_GameLogicPtr.ActivityMgr.Reload() + if G_GameLogicPtr.ActivityMgr != nil { + G_GameLogicPtr.ActivityMgr.Reload() + } + if G_GameLogicPtr.ChampshipMgr != nil { + go G_GameLogicPtr.ChampshipMgr.ReloadActivity() + } } func AdminShipping(req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) { diff --git a/src/server/game/champship_mgr.go b/src/server/game/champship_mgr.go index 7d8acff2..ca08d603 100644 --- a/src/server/game/champship_mgr.go +++ b/src/server/game/champship_mgr.go @@ -10,6 +10,7 @@ import ( faceCfg "server/conf/face" randnameCfg "server/conf/randname" "server/db" + "server/game/mod/activity" "server/game/mod/friend" "server/game/mod/msg" GoUtil "server/game_util" @@ -19,6 +20,7 @@ import ( "time" "gitea.bywaystudios.com/pet_home/leaf/log" + "gitea.bywaystudios.com/pet_home/leaf/timer" ) const ( @@ -29,6 +31,8 @@ type ChampshipMgr struct { *ServerMod } +var dispterTimer map[string]*timer.Timer + type ChampshipData struct { mu sync.RWMutex AutoId int @@ -42,6 +46,7 @@ type ChampshipData struct { PreRobot map[int]*ChampshipRobot // 机器人 备份 ZeroTime int64 Version int + Aid int // 当前活动ID } type ChampshipRank struct { @@ -86,6 +91,7 @@ type CRank struct { } func (c *ChampshipMgr) Init() { + dispterTimer = make(map[string]*timer.Timer, 0) c.key = CHAMPSHIP_MGR_KEY c.data = &ChampshipData{ Rank: make(map[int][]*ChampshipRank, 0), @@ -101,20 +107,18 @@ func (c *ChampshipMgr) Init() { c.version() now := GoUtil.Now() zeroTime := GoUtil.ZeroTimestamp() - if c.getData().ZeroTime != zeroTime { + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + t := c.mDispatr.AfterFunc(time.Duration(activityCfg.Endtime-now)*time.Second, func() { c.ZeroUpdate() - } else { - c.mDispatr.AfterFunc(time.Duration(GoUtil.NextZeroTimestampDuration())*time.Second, func() { - c.ZeroUpdate() - }) - } + }) + dispterTimer["zero"] = t + log.Debug("ChampshipMgr init success, activity endtime:%d, now:%d, remain:%d, next zero update time:%s", activityCfg.Endtime, now, activityCfg.Endtime-now, GoUtil.FormatTime(activityCfg.Endtime)) remain := now - zeroTime remain1 := 1800 - remain%1800 c.mDispatr.AfterFunc(time.Duration(remain1)*time.Second, func() { // 30分钟后重新分组 - c.group(false) + c.group() }) - c.mDispatr.AfterFunc(time.Duration(60)*time.Second, func() { c.ai() }) @@ -140,6 +144,14 @@ func (c *ChampshipMgr) version() { } } } + if c.data.(*ChampshipData).Version == 1 { + c.data.(*ChampshipData).Version = 2 + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + // 如果活动ID没有变化,说明没有新的活动,不需要重置数据 + if activityCfg.AId != 0 && c.data.(*ChampshipData).Aid == 0 { + c.data.(*ChampshipData).Aid = activityCfg.AId + } + } } func sortChampionshipRank(rankList []*ChampshipRank) { @@ -171,11 +183,38 @@ func (c *ChampshipMgr) ZeroNotifyAll() (interface{}, error) { return nil, nil } +func (c *ChampshipMgr) ReloadActivity() { + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + log.Debug("championship reload activity %v", activityCfg) + if activityCfg.AId == 0 { + log.Debug("championship reload activity failed, no active, aid:%d", activityCfg.AId) + return + } + t := dispterTimer["zero"] + if t != nil { + t.Stop() + } + timeDuration := activityCfg.Endtime - GoUtil.Now() + t = c.mDispatr.AfterFunc(time.Duration(timeDuration)*time.Second, func() { + c.ZeroUpdate() + }) + dispterTimer["zero"] = t + log.Debug("ChampshipMgr reload activity success, activity endtime:%d, now:%d, remain:%d, next zero update time:%s", activityCfg.Endtime, GoUtil.Now(), activityCfg.Endtime-GoUtil.Now(), GoUtil.FormatTime(activityCfg.Endtime)) +} + func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) { - c.group(true) log.Debug("ChampshipMgr ZeroUpdate") data := c.getData() data.mu.Lock() + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + // 如果活动ID没有变化,说明没有新的活动,不需要重置数据 + if activityCfg.AId != 0 && activityCfg.AId == data.Aid { + log.Debug("championship zero update not init by aid %d", data.Aid) + data.mu.Unlock() + return nil, nil + } + log.Debug("championship zero update by aid %d", activityCfg.AId) + data.Aid = activityCfg.AId data.ZeroTime = GoUtil.ZeroTimestamp() // 深拷贝 map,避免多个协程持有同一个 map 引用导致并发读写 oldRank := make(map[int][]*ChampshipRank, len(data.Rank)) @@ -203,14 +242,13 @@ func (c *ChampshipMgr) ZeroUpdate() (interface{}, error) { c.SetRankCache(k) } data.mu.Unlock() - timeDuration := GoUtil.NextZeroTimestampDuration() - if timeDuration <= 0 { - log.Error("championship zero update error") - timeDuration = 24 * 3600 - } - c.mDispatr.AfterFunc(time.Duration(timeDuration)*time.Second, func() { + timeDuration := activityCfg.Endtime - GoUtil.Now() + t := c.mDispatr.AfterFunc(time.Duration(timeDuration)*time.Second, func() { c.ZeroUpdate() }) + dispterTimer["zero"] = t + now := GoUtil.Now() + log.Debug("ChampshipMgr init success, activity endtime:%d, now:%d, remain:%d, next zero update time:%s", activityCfg.Endtime, now, activityCfg.Endtime-now, GoUtil.FormatTime(activityCfg.Endtime)) c.mDispatr.AfterFunc(time.Duration(timeDuration+1800)*time.Second, func() { c.ZeroNotifyAll() }) @@ -484,14 +522,9 @@ func (c *ChampshipMgr) GetRankMsg(uid int) *proto.ResChampshipRank { } // 分组 -func (c *ChampshipMgr) group(iszero bool) (interface{}, error) { - now := GoUtil.Now() - zero := GoUtil.ZeroTimestamp() - if now-zero < 1800 && !iszero { // 0点30分钟内不分组 - return nil, nil - } +func (c *ChampshipMgr) group() (interface{}, error) { c.mDispatr.AfterFunc(time.Duration(1800)*time.Second, func() { // 30分钟后重新分组 - c.group(false) + c.group() }) ChampshipData := c.getData() ChampshipData.mu.Lock() @@ -1043,7 +1076,7 @@ func (c *ChampshipMgr) Debug() { H: GoUtil.RandNum(1, 99), } } - c.group(true) + c.group() var i int for _, v := range ChampshipData.Rank { for _, v1 := range v { diff --git a/src/server/game/message_mgr.go b/src/server/game/message_mgr.go index 4e7a6323..62f0d61d 100644 --- a/src/server/game/message_mgr.go +++ b/src/server/game/message_mgr.go @@ -221,7 +221,7 @@ func NotifyAllPlayerMsg(m *msg.Msg) { } func ChampshipGroupHandler(data *msg.Msg) (interface{}, error) { - G_GameLogicPtr.ChampshipMgr.group(true) + G_GameLogicPtr.ChampshipMgr.group() return nil, nil } diff --git a/src/server/game/mod/champship/Champship.go b/src/server/game/mod/champship/Champship.go index e997b827..6be5f9ac 100644 --- a/src/server/game/mod/champship/Champship.go +++ b/src/server/game/mod/champship/Champship.go @@ -15,19 +15,23 @@ type ChampshipMod struct { RankReward bool PreMax int // 昨日最高档 Max int // 历史最高档 - AId int // 活动id - LastAId int // 上次活动id + AId int // 活动aid 当前活动开始时间戳 + LastAId int // 上次活动aid + Id int // 活动配置id + LastId int } func (c *ChampshipMod) InitData() {} -func (c *ChampshipMod) ZeroUpdate(aid int) { +func (c *ChampshipMod) ZeroUpdate(id, aid int) { c.PreMax = c.Reward c.Score = 0 c.Reward = 0 c.RankReward = false c.LastAId = c.AId c.AId = aid + c.LastId = c.Id + c.Id = id } func (c *ChampshipMod) GetScore() int { @@ -100,6 +104,6 @@ func (c *ChampshipMod) GetN() int { return c.Max } -func (c *ChampshipMod) GetAId() int { - return c.AId +func (c *ChampshipMod) GetId() int { + return c.Id } diff --git a/src/server/game/player_data.go b/src/server/game/player_data.go index cb76ddb7..5c14de8d 100644 --- a/src/server/game/player_data.go +++ b/src/server/game/player_data.go @@ -291,6 +291,7 @@ func (p *Player) InitPlayer(UserName string) error { p.FixDecorate() p.FixPlayroomPyhical() p.FixPlayroomInteract() + p.FixChampionshipActivity() return nil } @@ -354,6 +355,7 @@ func (p *Player) InitPlayerByUid(Uid int) error { p.FixDecorate() p.FixPlayroomPyhical() p.FixPlayroomInteract() + p.FixChampionshipActivity() return nil } @@ -418,8 +420,6 @@ func (p *Player) ZeroUpdate(a []interface{}) { PlayroomMod.ResetWeeklyDiscount() } p.PlayroomBackData() - p.ChampionshipZeroUpdate() - p.BackChampship() // p.InitActivity() // p.ActivityZeroUpdate() @@ -1495,6 +1495,15 @@ func (p *Player) FixPlayroomInteract() { } } +func (p *Player) FixChampionshipActivity() { + activityCfg := G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + ChampshipMod := p.PlayMod.getChampshipMod() + if activityCfg.Id != 0 && ChampshipMod.Id == 0 { + ChampshipMod.Id = activityCfg.Id + ChampshipMod.AId = activityCfg.AId + } +} + func (p *Player) GetOrderFactor() int { return orderCfg.GetOrderFactor(p.GetDecorateMod().AreaId) } diff --git a/src/server/game/register_network_func.go b/src/server/game/register_network_func.go index 56214f73..769c28ff 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -2549,7 +2549,7 @@ func ReqChampship(player *Player, req *msg.ReqChampship) error { func ReqChampshipReward(player *Player, req *msg.ReqChampshipReward) error { ChampshipMod := player.PlayMod.getChampshipMod() rewardId := ChampshipMod.Reward - itemList := player.GetChampshipReward(ChampshipMod.GetAId()) + itemList := player.GetChampshipReward(ChampshipMod.GetId()) err := player.HandleItem(itemList, msg.ITEM_POP_LABEL_ChampshipReward.String()) if err != nil { player.SendErrClienRes(&msg.ResChampshipReward{ diff --git a/src/server/unit_test/championship_test.go b/src/server/unit_test/championship_test.go index 51d57256..4429a7b3 100644 --- a/src/server/unit_test/championship_test.go +++ b/src/server/unit_test/championship_test.go @@ -2,6 +2,8 @@ package unit import ( "fmt" + "server/game" + "server/game/mod/activity" "testing" ) @@ -9,9 +11,11 @@ func TestChampionshipReward(t *testing.T) { player := getTestPlayer() player.GetChampshipMod().AddScore([]int{15, 15, 15}) todayAid, yestAid := player.GetChampshipActivityId() + activityCfg := game.G_GameLogicPtr.ActivityMgr.GetActivityListByType(activity.ACT_TYPE_CHAMPION) + fmt.Printf("activity cfg : %v\n", activityCfg) items := player.GetChampshipReward(todayAid) fmt.Printf("today id %d items : %v\n", todayAid, items) - player.GetChampshipMod().ZeroUpdate(todayAid) + player.GetChampshipMod().ZeroUpdate(activityCfg.Id, activityCfg.AId) player.GetChampshipMod().AddScore([]int{15, 15, 15}) yestAid = 0 items = player.GetChampshipReward(yestAid)