From 97b764367a8ce98177b1a89fbdd1a8b4919ab15c Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Wed, 1 Apr 2026 16:30:01 +0800 Subject: [PATCH 1/4] 1 --- src/server/db/Mysql.go | 2 +- src/server/db/SqlStruct.go | 1 + src/server/game/activity_mgr.go | 14 ++++++++++++++ src/server/game/mod/activity/activity.go | 18 ++++++++++-------- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/server/db/Mysql.go b/src/server/db/Mysql.go index 9ddb7c30..f1b469be 100644 --- a/src/server/db/Mysql.go +++ b/src/server/db/Mysql.go @@ -415,7 +415,7 @@ func GetServerMailData(data *[]*SqlServerMailStruct) error { } func GetActivityData(data *[]*SqlActivityCfgStruct) error { - sql := "select `id`, `type`, `title`, `mail_title`, `mail_content`, `level_limit`, `start_time`, `end_time`, `cfg_buf`, `extra` from t_activity_mod" + sql := "select `id`, `type`, `title`, `mail_title`, `mail_content`, `level_limit`, `start_time`, `end_time`, `cfg_buf`, `extra`, `interval` from t_activity_mod" err := SqlDb.Select(data, sql) return err } diff --git a/src/server/db/SqlStruct.go b/src/server/db/SqlStruct.go index c60bd90a..c7135689 100644 --- a/src/server/db/SqlStruct.go +++ b/src/server/db/SqlStruct.go @@ -507,6 +507,7 @@ type SqlActivityCfgStruct struct { Start_time int64 `db:"start_time"` End_time int64 `db:"end_time"` Cfg []byte `db:"cfg_buf"` + Interval int64 `db:"interval"` Extra string `db:"extra"` } diff --git a/src/server/game/activity_mgr.go b/src/server/game/activity_mgr.go index 5baba4c7..ef3ca268 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -5,6 +5,7 @@ import ( "server/db" "server/game/mod/msg" Msg "server/game/mod/msg" + GoUtil "server/game_util" protoMsg "server/msg" "sync" @@ -32,6 +33,7 @@ type ActivityCfg struct { MailTitle string MailContent string cfg interface{} + Interval int64 Extra map[string]interface{} } @@ -64,7 +66,18 @@ func (r *ActivityMgr) GetActivityList() []ActivityCfg { data.mu.Lock() defer data.mu.Unlock() list := make([]ActivityCfg, 0, len(data.List)) + now := GoUtil.Now() for _, v := range data.List { + //循环活动,重新计算活动时间 + if v.Interval > 0 { + if now > v.Endtime { + //活动已结束,计算下一次活动时间 + interval := (now - v.Startime) / v.Interval + v.Startime += interval * v.Interval + v.Endtime += interval * v.Interval + } + v.Id = int(v.Startime) //活动id用开始时间表示,方便客户端排序 + } list = append(list, *v) } return list @@ -112,6 +125,7 @@ func (r *ActivityMgr) Reload() error { MailTitle: v.MailTitle, MailContent: v.MailContent, cfg: activityCfg, + Interval: v.Interval, } log.Debug("load activity cfg: %v", cfg) data.List[v.Id] = cfg diff --git a/src/server/game/mod/activity/activity.go b/src/server/game/mod/activity/activity.go index a4d7e194..a80763e9 100644 --- a/src/server/game/mod/activity/activity.go +++ b/src/server/game/mod/activity/activity.go @@ -15,14 +15,16 @@ const ( ) const ( - ACT_TYPE_MINING = 1 // 挖矿 - ACT_TYPE_GUESS_COLOR = 2 // 猜颜色 - ACT_TYPE_RACE = 3 // 赛跑 - ACT_TYPE_DISCOUNT_GIFT = 4 // 折扣礼包 - ACT_TYPE_ADD_GIFT = 5 // 买一赠一礼包 - ACT_TYPE_SUPER_GIFT = 6 // 超值加购礼包 - ACT_TYPE_CATNIP = 7 // 猫草大作战 - ACT_TYPE_PASS = 8 // 通行证 + ACT_TYPE_MINING = 1 // 挖矿 + ACT_TYPE_GUESS_COLOR = 2 // 猜颜色 + ACT_TYPE_RACE = 3 // 赛跑 + ACT_TYPE_DISCOUNT_GIFT = 4 // 折扣礼包 + ACT_TYPE_ADD_GIFT = 5 // 买一赠一礼包 + ACT_TYPE_SUPER_GIFT = 6 // 超值加购礼包 + ACT_TYPE_CATNIP = 7 // 猫草大作战 + ACT_TYPE_PASS = 8 // 通行证 + ACT_TYPE_CHAMPION = 9 // 冠军赛 + ACT_TYPE_MEOW_GIFT = 10 // 喵喵回礼 ) const ( From 557dec4612e8639735bf0a62f765444c669efa63 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Thu, 2 Apr 2026 10:42:53 +0800 Subject: [PATCH 2/4] 1 --- src/server/game/activity_mgr.go | 10 ++++++++++ src/server/game_util/timeUtil.go | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/src/server/game/activity_mgr.go b/src/server/game/activity_mgr.go index ef3ca268..3aed7178 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -75,6 +75,10 @@ func (r *ActivityMgr) GetActivityList() []ActivityCfg { interval := (now - v.Startime) / v.Interval v.Startime += interval * v.Interval v.Endtime += interval * v.Interval + if now > v.Endtime { + v.Startime += v.Interval + v.Endtime += v.Interval + } } v.Id = int(v.Startime) //活动id用开始时间表示,方便客户端排序 } @@ -130,6 +134,12 @@ func (r *ActivityMgr) Reload() error { log.Debug("load activity cfg: %v", cfg) data.List[v.Id] = cfg } + go func() { + actList := r.GetActivityList() + for _, v := range actList { + log.Debug("activity load success: type :%d, id :%d, startTime :%s, endTime :%s", v.Type, v.Id, GoUtil.FormatTime(v.Startime), GoUtil.FormatTime(v.Endtime)) + } + }() G_GameLogicPtr.NotifyAll(&Msg.Msg{Type: Msg.HANDLE_TYPE_ACTIVITY_RELOAD}) return nil } diff --git a/src/server/game_util/timeUtil.go b/src/server/game_util/timeUtil.go index 083a5c81..54f5404b 100644 --- a/src/server/game_util/timeUtil.go +++ b/src/server/game_util/timeUtil.go @@ -178,3 +178,8 @@ func IsFirstDayOfMonth() bool { func NowMonth() int { return int(time.Now().Month()) } + +func FormatTime(timestamp int64) string { + t := time.Unix(timestamp, 0) + return t.Format("2006-01-02 15:04:05") +} From 063bad8a18e23d8e49e2ee12b13ba6b24dde31cb Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:04:50 +0800 Subject: [PATCH 3/4] 1 --- src/server/game/activity_mgr.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/server/game/activity_mgr.go b/src/server/game/activity_mgr.go index 3aed7178..2a3fde16 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -25,6 +25,7 @@ type ActivityData struct { type ActivityCfg struct { Id int + AId int Type int Startime int64 Endtime int64 @@ -80,7 +81,9 @@ func (r *ActivityMgr) GetActivityList() []ActivityCfg { v.Endtime += v.Interval } } - v.Id = int(v.Startime) //活动id用开始时间表示,方便客户端排序 + v.AId = int(v.Startime) //活动id用开始时间表示,方便客户端排序 + } else { + v.AId = v.Id } list = append(list, *v) } From 19233e02d8f141667e53c8574424d8334c351f83 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Thu, 2 Apr 2026 21:33:56 +0800 Subject: [PATCH 4/4] 1 --- src/server/game/GameLogic.go | 3 + src/server/game/activity_func.go | 53 ++++++++- src/server/game/activity_mgr.go | 15 +++ src/server/game/game_type.go | 1 + src/server/game/mod/activity/activity.go | 20 ++-- .../mod/cat_return_gift/cat_return_gift.go | 49 +++++++++ src/server/game/mod/item/Item.go | 14 +++ src/server/game/mod_factory.go | 5 + src/server/game/player_data.go | 1 + src/server/game/player_mod.go | 3 + src/server/game/register_network_func.go | 104 ++++++++++++++++++ 11 files changed, 257 insertions(+), 11 deletions(-) create mode 100644 src/server/game/mod/cat_return_gift/cat_return_gift.go diff --git a/src/server/game/GameLogic.go b/src/server/game/GameLogic.go index 167094ef..9d2d3380 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -828,6 +828,9 @@ func (ad *GameLogic) RegisterNetWorkFunc() { RegisterMsgProcessFunc("ReqCatnipReward", ReqCatnipReward) // 猫草大作战领取奖励 RegisterMsgProcessFunc("ReqCatnipGrandReward", ReqCatnipGrandReward) // 猫草大作战领取大奖 RegisterMsgProcessFunc("ReqCatnipEmoji", ReqCatnipEmoji) + // 猫猫回礼 + RegisterMsgProcessFunc("CatReturnGiftCfg", CatReturnGiftCfg) // 请求猫猫回礼数据 + RegisterMsgProcessFunc("ReqCatReturnGiftReward", ReqCatReturnGiftReward) // 领取猫猫回礼奖励 // 活动通行证 RegisterMsgProcessFunc("ReqActPass", ReqActPass) // 请求活动通行证数据 RegisterMsgProcessFunc("ReqActPassReward", ReqActPassReward) // 领取活动通行证奖励 diff --git a/src/server/game/activity_func.go b/src/server/game/activity_func.go index 36df31ff..ecaaa024 100644 --- a/src/server/game/activity_func.go +++ b/src/server/game/activity_func.go @@ -136,8 +136,8 @@ func (p *Player) SendActivityMail(ItemId, ItemNum, ActivityId int, RewardItems [ // 活动模块 零点更新 func (p *Player) ActivityZeroUpdate() { + p.CatReturnGiftZeroUpdate() p.ActivityLogin() - type zeroHandler struct { actType int updateFn func(int) @@ -156,6 +156,36 @@ func (p *Player) ActivityZeroUpdate() { } } +// 猫猫回礼0点更新 +func (p *Player) CatReturnGiftZeroUpdate() { + activityInfo := p.GetActivityInfo(activity.ACT_TYPE_CAT_RETURN_GIFT) + var aid int + var id int + if activityInfo != nil { + id = activityInfo.Id + aid = activityInfo.AId + } + oldId, oldScore, oldReward := p.GetCatReturnGiftMod().ZeroUpdate(id, aid) + if oldId != 0 { + log.Debug("CatReturnGiftZeroUpdate oldId : %d, oldScore : %d, oldReward : %d", oldId, oldScore, oldReward) + cfg := G_GameLogicPtr.ActivityMgr.GetCatReturnGiftCfg(oldId) + items := make([]*item.Item, 0) + if cfg != nil { + for _, v := range cfg.RewardList { + if oldScore >= int(v.Score) && oldReward < int(v.Id) { + items = append(items, item.MsgToItem(v.Reward)...) + } + } + } + if len(items) > 0 { + err := p.HandleItem(items, "") + if err != nil { + log.Debug("CatReturnGiftZeroUpdate HandleItem err : %s", err) + } + } + } +} + // 获取活动信息 func (p *Player) GetActivityInfo(actType int) *ActivityInfo { for _, v := range p.activity { @@ -509,3 +539,24 @@ func (p *Player) GetDailyTaskActivityId() int { } return activityId } + +// 猫猫回礼返回 +func (p *Player) CatReturnGiftBackData() { + activityInfo := p.GetActivityInfo(activity.ACT_TYPE_CAT_RETURN_GIFT) + if activityInfo == nil { + return + } + cfg := G_GameLogicPtr.ActivityMgr.GetCatReturnGiftCfg(activityInfo.Id) + if cfg == nil { + return + } + CatReturnGiftMod := p.GetCatReturnGiftMod() + res := &msg.ResCatReturnGift{ + StartTime: activityInfo.StartT, + EndTime: activityInfo.EndT, + Cfg: cfg, + Score: int32(CatReturnGiftMod.GetScore()), + Reward: int32(CatReturnGiftMod.GetReward()), + } + p.PushClientRes(res) +} diff --git a/src/server/game/activity_mgr.go b/src/server/game/activity_mgr.go index 2a3fde16..43334074 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -3,6 +3,7 @@ package game import ( "fmt" "server/db" + "server/game/mod/activity" "server/game/mod/msg" Msg "server/game/mod/msg" GoUtil "server/game_util" @@ -162,3 +163,17 @@ func unmarshalActivityCfg(atype int, buf []byte) (interface{}, error) { } return nil, nil } + +func (r *ActivityMgr) GetCatReturnGiftCfg(id int) *protoMsg.CatReturnGiftCfg { + data := r.getData() + data.mu.Lock() + defer data.mu.Unlock() + for _, v := range data.List { + if v.Type == activity.ACT_TYPE_CAT_RETURN_GIFT && v.Id == id { + if cfg, ok := v.cfg.(*protoMsg.CatReturnGiftCfg); ok { + return cfg + } + } + } + return nil +} diff --git a/src/server/game/game_type.go b/src/server/game/game_type.go index 109d3eab..cc027b54 100644 --- a/src/server/game/game_type.go +++ b/src/server/game/game_type.go @@ -87,6 +87,7 @@ type ActivityInfo struct { StartT int64 EndT int64 Id int + AId int Type int Title string Name string diff --git a/src/server/game/mod/activity/activity.go b/src/server/game/mod/activity/activity.go index a80763e9..bcec093a 100644 --- a/src/server/game/mod/activity/activity.go +++ b/src/server/game/mod/activity/activity.go @@ -15,16 +15,16 @@ const ( ) const ( - ACT_TYPE_MINING = 1 // 挖矿 - ACT_TYPE_GUESS_COLOR = 2 // 猜颜色 - ACT_TYPE_RACE = 3 // 赛跑 - ACT_TYPE_DISCOUNT_GIFT = 4 // 折扣礼包 - ACT_TYPE_ADD_GIFT = 5 // 买一赠一礼包 - ACT_TYPE_SUPER_GIFT = 6 // 超值加购礼包 - ACT_TYPE_CATNIP = 7 // 猫草大作战 - ACT_TYPE_PASS = 8 // 通行证 - ACT_TYPE_CHAMPION = 9 // 冠军赛 - ACT_TYPE_MEOW_GIFT = 10 // 喵喵回礼 + ACT_TYPE_MINING = 1 // 挖矿 + ACT_TYPE_GUESS_COLOR = 2 // 猜颜色 + ACT_TYPE_RACE = 3 // 赛跑 + ACT_TYPE_DISCOUNT_GIFT = 4 // 折扣礼包 + ACT_TYPE_ADD_GIFT = 5 // 买一赠一礼包 + ACT_TYPE_SUPER_GIFT = 6 // 超值加购礼包 + ACT_TYPE_CATNIP = 7 // 猫草大作战 + ACT_TYPE_PASS = 8 // 通行证 + ACT_TYPE_CHAMPION = 9 // 冠军赛 + ACT_TYPE_CAT_RETURN_GIFT = 10 // 喵喵回礼 ) const ( diff --git a/src/server/game/mod/cat_return_gift/cat_return_gift.go b/src/server/game/mod/cat_return_gift/cat_return_gift.go new file mode 100644 index 00000000..6decea24 --- /dev/null +++ b/src/server/game/mod/cat_return_gift/cat_return_gift.go @@ -0,0 +1,49 @@ +package catreturngift + +type CatReturnGiftMod struct { + Id int + AId int + Score int + Reward int +} + +func (c *CatReturnGiftMod) InitData() {} + +func (c *CatReturnGiftMod) ZeroUpdate(id, aid int) (int, int, int) { + score := c.Score + reward := c.Reward + oldId := c.Login(id, aid) + c.Score = 0 + c.Reward = 0 + return oldId, score, reward +} + +func (c *CatReturnGiftMod) Login(id, aid int) int { + oldId := c.Id + if aid == 0 { + c.AId = 0 + return oldId + } + if c.AId == aid { + return 0 + } + c.AId = aid + c.Id = id + return oldId +} + +func (c *CatReturnGiftMod) GetReward() int { + return c.Reward +} + +func (c *CatReturnGiftMod) GetScore() int { + return c.Score +} + +func (c *CatReturnGiftMod) AddScore(score int) { + c.Score += score +} + +func (c *CatReturnGiftMod) SetReward(reward int) { + c.Reward = reward +} diff --git a/src/server/game/mod/item/Item.go b/src/server/game/mod/item/Item.go index 88f32cda..a5b3f892 100644 --- a/src/server/game/mod/item/Item.go +++ b/src/server/game/mod/item/Item.go @@ -183,6 +183,20 @@ func ItemListToMsg(items []*Item) *msg.ItemList { } } +func MsgToItem(items []*msg.ItemInfo) []*Item { + if items == nil { + return nil + } + itemList := make([]*Item, 0, len(items)) + for _, v := range items { + itemList = append(itemList, &Item{ + Id: int(v.Id), + Num: int(v.Num), + }) + } + return itemList +} + // 道具叠加 func Merge(item1, item2 []*Item) []*Item { if item1 == nil { diff --git a/src/server/game/mod_factory.go b/src/server/game/mod_factory.go index 3f56ed00..0148a338 100644 --- a/src/server/game/mod_factory.go +++ b/src/server/game/mod_factory.go @@ -4,6 +4,7 @@ import ( "server/game/mod/activity" "server/game/mod/base" "server/game/mod/card" + catreturngift "server/game/mod/cat_return_gift" "server/game/mod/champship" "server/game/mod/charge" "server/game/mod/chess" @@ -115,3 +116,7 @@ func (p *Player) GetCollectMod() *collect.Collect { func (p *Player) GetInviteMod() *invite.InviteMod { return p.PlayMod.getInviteMod() } + +func (p *Player) GetCatReturnGiftMod() *catreturngift.CatReturnGiftMod { + return &p.PlayMod.mod_list.CatReturnGift +} diff --git a/src/server/game/player_data.go b/src/server/game/player_data.go index 73124331..26cec793 100644 --- a/src/server/game/player_data.go +++ b/src/server/game/player_data.go @@ -1259,6 +1259,7 @@ func (p *Player) InitActivity() { StartT: v.Startime, EndT: v.Endtime, Id: v.Id, + AId: v.AId, Type: v.Type, Status: Status, Title: v.Title, diff --git a/src/server/game/player_mod.go b/src/server/game/player_mod.go index c394a050..4b5c76d7 100644 --- a/src/server/game/player_mod.go +++ b/src/server/game/player_mod.go @@ -10,6 +10,7 @@ import ( "server/game/mod/avatar" "server/game/mod/base" "server/game/mod/card" + catreturngift "server/game/mod/cat_return_gift" "server/game/mod/catnip" "server/game/mod/champship" "server/game/mod/charge" @@ -123,6 +124,7 @@ type PlayerModList struct { GuideTask guideTask.GuideTaskMod // 引导任务 Pass pass.PassMod // 通行证 Fur fur.FurMod // 毛皮 + CatReturnGift catreturngift.CatReturnGiftMod // 猫咪回归礼包 } func (p *PlayerModData) LoadDataFromDB(dwUin interface{}) bool { @@ -225,6 +227,7 @@ func (p *PlayerModData) InitMod(player *Player) (bool, error) { p.ModList.GuideTask.InitData() p.ModList.Pass.InitData() p.ModList.Fur.InitData() + p.ModList.CatReturnGift.InitData() return is_update, nil } diff --git a/src/server/game/register_network_func.go b/src/server/game/register_network_func.go index 683a5132..33e2309d 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -5572,3 +5572,107 @@ func ReqCatnipEmoji(player *Player, buf []byte) error { player.CatnipBackData() return nil } + +// 猫咪回礼 +func CatReturnGiftCfg(player *Player, buf []byte) error { + player.CatReturnGiftBackData() + return nil +} + +// 猫猫回礼领取奖励 +func ReqCatReturnGiftReward(player *Player, buf []byte) error { + req := &msg.ReqCatReturnGiftReward{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + activityInfo := player.GetActivityInfo(activity.ACT_TYPE_CAT_RETURN_GIFT) + if activityInfo == nil { + player.SendErrClienRes(&msg.ResCatReturnGiftReward{ + Code: msg.RES_CODE_FAIL, + Msg: "activity not exist", + }) + return fmt.Errorf("activity not exist") + } + cfg := G_GameLogicPtr.ActivityMgr.GetCatReturnGiftCfg(activityInfo.Id) + if cfg == nil { + player.SendErrClienRes(&msg.ResCatReturnGiftReward{ + Code: msg.RES_CODE_FAIL, + Msg: "config not exist", + }) + return fmt.Errorf("config not exist") + } + CatReturnGiftMod := player.GetCatReturnGiftMod() + reward := CatReturnGiftMod.GetReward() + score := CatReturnGiftMod.GetScore() + items := make([]*item.Item, 0) + var maxRewardId int + for _, v := range cfg.RewardList { + if score >= int(v.Score) && reward < int(v.Id) { + items = append(items, item.MsgToItem(v.Reward)...) + maxRewardId = max(maxRewardId, int(v.Id)) + } + } + if len(items) == 0 { + player.SendErrClienRes(&msg.ResCatReturnGiftReward{ + Code: msg.RES_CODE_FAIL, + Msg: "no reward", + }) + return fmt.Errorf("no reward") + } + err = player.HandleItem(items, msg.ITEM_POP_LABEL_CatReturnGiftReward.String()) + if err != nil { + player.SendErrClienRes(&msg.ResCatReturnGiftReward{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + CatReturnGiftMod.SetReward(maxRewardId) + player.TeLog("cat_return_gift_reward", map[string]interface{}{ + "Score": score, + "RewardId": maxRewardId, + "Items": items, + }) + player.PlayMod.save() + player.CatReturnGiftBackData() + return nil +} + +func ReqCatReturnGiftRewardGfit(player *Player, buf []byte) error { + req := &msg.ReqCatReturnGiftRewardGfit{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + LimitedTimeEventMod := player.PlayMod.getLimitedTimeEventMod() + BaseMod := player.PlayMod.getBaseMod() + items, eventType, orderNum, rewardList, err := LimitedTimeEventMod.SelectProgressReward(int(req.Id), BaseMod.GetLevel(), BaseMod.GetEnergy()) + if err != nil { + player.SendErrClienRes(&msg.ResSelectLimitEvent{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + err = player.HandleItem(items, msg.ITEM_POP_LABEL_SelectLimitEvent.String()) + if err != nil { + player.SendErrClienRes(&msg.ResSelectLimitEvent{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + player.TeLog("time_limited_slot", map[string]interface{}{ + "slot_order_number": orderNum, + "slot_reward_list": rewardList, + "slot_reward": limitedTimeEventCfg.GetEventName(eventType), + }) + player.PlayMod.save() + player.PushClientRes(LimitedTimeEventMod.BackData()) + player.PushClientRes(LimitedTimeEventMod.ProgressBackData()) + player.PushClientRes(&msg.ResSelectLimitEvent{ + Code: msg.RES_CODE_SUCCESS, + }) + return nil +}