From 4347974b17788dbcdab49b058a60cbc3273e73cd Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Fri, 3 Apr 2026 16:25:17 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8C=AB=E5=92=AA=E5=9B=9E=E7=A4=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../limited_time_event_cfg.go | 9 ++ src/server/db/Mysql.go | 2 +- src/server/db/SqlStruct.go | 1 + src/server/game/GameLogic.go | 4 + src/server/game/activity_func.go | 53 +++++++- src/server/game/activity_mgr.go | 49 +++++++ src/server/game/game_type.go | 1 + src/server/game/gm_handler.go | 12 +- src/server/game/mod/activity/activity.go | 18 +-- .../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 | 5 + src/server/game/player_mod.go | 3 + src/server/game/register_network_func.go | 121 +++++++++++++++++- src/server/game_util/timeUtil.go | 5 + 16 files changed, 336 insertions(+), 15 deletions(-) create mode 100644 src/server/game/mod/cat_return_gift/cat_return_gift.go diff --git a/src/server/conf/limited_time_event/limited_time_event_cfg.go b/src/server/conf/limited_time_event/limited_time_event_cfg.go index 6e33a3d7..87236a18 100644 --- a/src/server/conf/limited_time_event/limited_time_event_cfg.go +++ b/src/server/conf/limited_time_event/limited_time_event_cfg.go @@ -312,6 +312,15 @@ func GetUnlockLv() int { return gamedata.GetIntValue(data, "Value") } +func GetCatReturnGiftItems() []*item.Item { + data, err := gamedata.GetDataByKey(CFG_LIMITED_TIME_EVENT_CONST, "Cat_Return_Gift_Items") + if err != nil { + log.Debug("GetCatReturnGiftItems err:%v", err) + return nil + } + return gamedata.GetItemList(data, "Items") +} + func GetCatSaleCD() int64 { data, err := gamedata.GetDataByKey(CFG_LIMITED_TIME_EVENT_CONST, "Event_Cooldown_7days") if err != nil { 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/GameLogic.go b/src/server/game/GameLogic.go index 79563db3..5e3920e3 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -906,6 +906,10 @@ func (ad *GameLogic) RegisterNetWorkFunc() { RegisterNewMsgProcessFunc("ReqCatnipReward", ReqCatnipReward) // 猫草大作战领取奖励 RegisterNewMsgProcessFunc("ReqCatnipGrandReward", ReqCatnipGrandReward) // 猫草大作战领取大奖 RegisterNewMsgProcessFunc("ReqCatnipEmoji", ReqCatnipEmoji) + // 猫猫回礼 + RegisterNewMsgProcessFunc("ReqCatReturnGift", ReqCatReturnGift) // 请求猫猫回礼数据 + RegisterNewMsgProcessFunc("ReqCatReturnGiftReward", ReqCatReturnGiftReward) // 领取猫猫回礼奖励 + RegisterNewMsgProcessFunc("ReqCatReturnGiftScore", ReqCatReturnGiftScore) // 领取猫猫回礼积分 // 活动通行证 RegisterNewMsgProcessFunc("ReqActPass", ReqActPass) // 请求活动通行证数据 RegisterNewMsgProcessFunc("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 5baba4c7..4306a490 100644 --- a/src/server/game/activity_mgr.go +++ b/src/server/game/activity_mgr.go @@ -3,8 +3,10 @@ package game import ( "fmt" "server/db" + "server/game/mod/activity" "server/game/mod/msg" Msg "server/game/mod/msg" + GoUtil "server/game_util" protoMsg "server/msg" "sync" @@ -24,6 +26,7 @@ type ActivityData struct { type ActivityCfg struct { Id int + AId int Type int Startime int64 Endtime int64 @@ -32,6 +35,7 @@ type ActivityCfg struct { MailTitle string MailContent string cfg interface{} + Interval int64 Extra map[string]interface{} } @@ -64,7 +68,24 @@ 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 + if now > v.Endtime { + v.Startime += v.Interval + v.Endtime += v.Interval + } + } + v.AId = int(v.Startime) //活动id用开始时间表示,方便客户端排序 + } else { + v.AId = v.Id + } list = append(list, *v) } return list @@ -112,10 +133,17 @@ 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 } + 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 } @@ -132,6 +160,27 @@ func unmarshalActivityCfg(atype int, buf []byte) (interface{}, error) { return nil, err } return cfg, nil + case 10: + cfg := &protoMsg.CatReturnGiftCfg{} + err := proto.Unmarshal(buf, cfg) + if err != nil { + return nil, err + } + return cfg, nil } 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/gm_handler.go b/src/server/game/gm_handler.go index c97fbcbe..9c460453 100644 --- a/src/server/game/gm_handler.go +++ b/src/server/game/gm_handler.go @@ -670,9 +670,13 @@ func ReqGmCommand_(player *Player, Command string) error { }) } } + case "catScore": + score := GoUtil.Int(arg[1]) + player.GetCatReturnGiftMod().AddScore(score) + player.CatReturnGiftBackData() case "debugLogoutMsg": - ToUid, _ := strconv.Atoi(arg[1]) - uidList, err := db.GetDebugPlayer(ToUid) + toUid, _ := strconv.Atoi(arg[1]) + uidList, err := db.GetDebugPlayer(toUid) if err != nil { log.Error("GetDebugPlayer err:%s", err.Error()) return err @@ -682,13 +686,13 @@ func ReqGmCommand_(player *Player, Command string) error { Type: MsgMod.HANDLE_TYPE_APPLY, SendT: GoUtil.Now(), From: uid, - To: ToUid, + To: toUid, }) FriendMgrSend(&MsgMod.Msg{ Type: MsgMod.HANDLE_TYPE_HANDBOOK_COLLECTION, SendT: GoUtil.Now(), From: uid, - To: ToUid, + To: toUid, }) } default: diff --git a/src/server/game/mod/activity/activity.go b/src/server/game/mod/activity/activity.go index a4d7e194..bcec093a 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_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..edded328 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, @@ -1490,3 +1491,7 @@ func (p *Player) FixPlayroomPyhical() { func (p *Player) GetOrderFactor() int { return orderCfg.GetOrderFactor(p.GetDecorateMod().AreaId) } + +func (p *Player) Save() { + p.PlayMod.save() +} 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 ff4ac751..e707dc5d 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -2572,7 +2572,7 @@ func ReqLimitEvent(player *Player, req *msg.ReqLimitEvent) error { func ReqKv(player *Player, req *msg.ReqKv) error { KvMod := player.PlayMod.getKvMod() KvMod.SetVar(int(req.Key), req.Value) - log.Debug("player %d set kv key %d value %s", player.M_DwUin, req.Key, req.Value) + //log.Debug("player %d set kv key %d value %s", player.M_DwUin, req.Key, req.Value) return nil } @@ -4957,3 +4957,122 @@ func ReqCatnipEmoji(player *Player, req *msg.ReqCatnipEmoji) error { player.CatnipBackData() return nil } + +// 猫咪回礼 +func ReqCatReturnGift(player *Player, req *msg.ReqCatReturnGift) error { + player.CatReturnGiftBackData() + return nil +} + +// 猫猫回礼领取奖励 +func ReqCatReturnGiftReward(player *Player, req *msg.ReqCatReturnGiftReward) error { + 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, req *msg.ReqCatReturnGiftRewardGfit) error { + items := limitedTimeEventCfg.GetCatReturnGiftItems() + err := player.HandleLoseItem(items, msg.ITEM_POP_LABEL_SelectLimitEvent.String()) + if err != nil { + player.SendErrClienRes(&msg.ResCatReturnGiftRewardGfit{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + 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 +} + +func ReqCatReturnGiftScore(player *Player, req *msg.ReqCatReturnGiftScore) error { + activityInfo := player.GetActivityInfo(activity.ACT_TYPE_CAT_RETURN_GIFT) + if activityInfo == nil { + player.SendErrClienRes(&msg.ResCatReturnGiftScore{ + Code: msg.RES_CODE_FAIL, + Msg: "activity not exist", + }) + return fmt.Errorf("activity not exist") + } + CatReturnGiftMod := player.GetCatReturnGiftMod() + CatReturnGiftMod.AddScore(int(req.Score)) + player.Save() + player.CatReturnGiftBackData() + 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") +}