From b3689ca93d63802a8a360fae98b66be57297c734 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Sat, 28 Feb 2026 18:36:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=A0=E7=89=A9=E7=9A=AE=E6=AF=9B=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/conf/fur/fur_cfg.go | 57 ++++++++++++++++++++ src/server/game/GameLogic.go | 4 ++ src/server/game/game_type.go | 1 + src/server/game/mod/fur/fur.go | 84 +++++++++++++++++++++++++++++ src/server/game/mod/item/Item.go | 1 + src/server/game/mod_factory.go | 5 ++ src/server/game/player_data.go | 14 ++++- src/server/game/player_mod.go | 7 +++ src/server/game/req_func_fur.go | 52 ++++++++++++++++++ src/server/test/fix_test.go | 2 +- src/server/test/fur_test.go | 92 ++++++++++++++++++++++++++++++++ 11 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 src/server/conf/fur/fur_cfg.go create mode 100644 src/server/game/mod/fur/fur.go create mode 100644 src/server/game/req_func_fur.go create mode 100644 src/server/test/fur_test.go diff --git a/src/server/conf/fur/fur_cfg.go b/src/server/conf/fur/fur_cfg.go new file mode 100644 index 00000000..a4cb7a6b --- /dev/null +++ b/src/server/conf/fur/fur_cfg.go @@ -0,0 +1,57 @@ +package fur_cfg + +import ( + "server/game/mod/item" + "server/gamedata" +) + +const ( + CFG_FUR_CONST = "FurShopConst" + CFG_FUR_SHOP = "FurShop" +) + +func init() { + gamedata.InitCfg(CFG_FUR_CONST) + gamedata.InitCfg(CFG_FUR_SHOP) +} + +func GetFurShopCost(id int) []*item.Item { + data, err := gamedata.GetDataByIntKey(CFG_FUR_SHOP, id) + if err != nil { + return nil + } + return gamedata.GetItemList(data, "Cost") +} + +func GetFurShopFreeTimes() int { + data, err := gamedata.GetDataByKey(CFG_FUR_CONST, "free_unlock") + if err != nil { + return 0 + } + return gamedata.GetIntValue(data, "Value") +} + +func GetFurShopTag(id int) int { + data, err := gamedata.GetDataByIntKey(CFG_FUR_SHOP, id) + if err != nil { + return 0 + } + return gamedata.GetIntValue(data, "TAG") +} + +func GetFurShopItem(id int) []*item.Item { + data, err := gamedata.GetDataByIntKey(CFG_FUR_SHOP, id) + if err != nil { + return nil + } + itemId := gamedata.GetIntValue(data, "ItemID") + if itemId == 0 { + return nil + } + return []*item.Item{ + { + Id: itemId, + Num: 1, + }, + } +} diff --git a/src/server/game/GameLogic.go b/src/server/game/GameLogic.go index 8c86e9d8..64d3a035 100644 --- a/src/server/game/GameLogic.go +++ b/src/server/game/GameLogic.go @@ -454,6 +454,7 @@ func (ad *GameLogic) GetResFriendPlayerByUid(Id int) *msg.ResFriendPlayerSimple Physiology: GoUtil.MapIntToInt32(player.Physiology), Last: last, PetName: player.PetName, + PetFur: int32(player.PetFur), } } @@ -840,6 +841,9 @@ func (ad *GameLogic) RegisterNetWorkFunc() { RegisterMsgProcessFunc("ReqPlayroomTaskReward", ReqPlayroomTaskReward) // 领取任务奖励 RegisterMsgProcessFunc("ReqPlayroomGameShowReward", ReqPlayroomGameShowReward) // 展示游戏结果数据 RegisterMsgProcessFunc("ReqPlayroomGuide", ReqPlayroomGuide) // 展示游戏结果数据 + RegisterMsgProcessFunc("ReqPetFur", ReqPetFur) // 宠物毛皮信息 + RegisterMsgProcessFunc("ReqPetFurBuy", ReqPetFurBuy) // 宠物毛皮商店购买 + RegisterMsgProcessFunc("ReqFurSet", ReqFurSet) //宠物毛皮设置 // 宠物宝藏 RegisterMsgProcessFunc("ReqFriendTreasure", ReqFriendTreasure) // 请求好友宝藏数据 RegisterMsgProcessFunc("ReqFriendTreasureStart", ReqFriendTreasureStart) // 开始游戏 diff --git a/src/server/game/game_type.go b/src/server/game/game_type.go index 5fae4517..1522dbce 100644 --- a/src/server/game/game_type.go +++ b/src/server/game/game_type.go @@ -39,6 +39,7 @@ type PlayerSimpleData struct { Physiology map[int]int Lang int Account string + PetFur int } type VarGoldCard struct { diff --git a/src/server/game/mod/fur/fur.go b/src/server/game/mod/fur/fur.go new file mode 100644 index 00000000..6a68f166 --- /dev/null +++ b/src/server/game/mod/fur/fur.go @@ -0,0 +1,84 @@ +package fur + +import ( + "fmt" + fur_cfg "server/conf/fur" + "server/game/mod/item" + "server/msg" +) + +type FurMod struct { + Set int + List map[int]*FurInfo + Free int +} + +type FurInfo struct { + Id int + AddTime int64 + EndTime int64 +} + +func (f *FurMod) InitData() { + if f.List == nil { + f.List = make(map[int]*FurInfo) + } +} + +// 获取毛皮信息 +func (f *FurMod) GetFurInfo(id int) *FurInfo { + info, ok := f.List[id] + if !ok { + return nil + } + return info +} + +// 增加毛皮 +func (f *FurMod) AddFurInfo(id int, addTime, endTime int64) { + f.List[id] = &FurInfo{ + Id: id, + AddTime: addTime, + EndTime: endTime, + } +} + +func (f *FurMod) GetFurBuyCost(id int) ([]*item.Item, []*item.Item) { + freeCount := fur_cfg.GetFurShopFreeTimes() + if f.Free < freeCount { + f.Free++ + return nil, fur_cfg.GetFurShopItem(id) + } + return fur_cfg.GetFurShopCost(id), fur_cfg.GetFurShopItem(id) +} + +// 设置毛皮 +func (f *FurMod) SetFur(id int) error { + if id == 0 { + f.Set = 0 + return nil + } + if _, ok := f.List[id]; !ok { + return fmt.Errorf("fur id not found") + } + f.Set = id + return nil +} + +func (f *FurMod) GetFurSet() int { + return f.Set +} + +// 消息返回 +func (f *FurMod) BackData() *msg.ResPetFur { + freeCount := fur_cfg.GetFurShopFreeTimes() + furId := make([]int32, 0, len(f.List)) + for id := range f.List { + furId = append(furId, int32(id)) + } + return &msg.ResPetFur{ + FurId: furId, + FurSet: int32(f.Set), + FreeCount: int32(freeCount - f.Free), + } +} diff --git a/src/server/game/mod/item/Item.go b/src/server/game/mod/item/Item.go index 64bf0dbb..8b7918f1 100644 --- a/src/server/game/mod/item/Item.go +++ b/src/server/game/mod/item/Item.go @@ -58,6 +58,7 @@ const ( ITEM_TYPE_PLAYROOM_DRESS_SET = 114 // playroom服饰套装 ITEM_TYPE_PLAYROOM_BOX = 115 // playroom宝箱 ITEM_TYPE_ACT_PASS = 116 // 通行证活动道具 + ITEM_TYPE_PET_FUR = 117 // 宠物毛皮 ) func (i *ItemMod) InitData() { diff --git a/src/server/game/mod_factory.go b/src/server/game/mod_factory.go index aebf09ed..502d5ed1 100644 --- a/src/server/game/mod_factory.go +++ b/src/server/game/mod_factory.go @@ -7,6 +7,7 @@ import ( "server/game/mod/chess" "server/game/mod/decorate" "server/game/mod/endless" + "server/game/mod/fur" limitedTimeEvent "server/game/mod/limited_time_event" "server/game/mod/mail" "server/game/mod/order" @@ -57,3 +58,7 @@ func (p *Player) GetSevenLoginMod() *sevenLogin.SevenLoginMod { func (p *Player) GetOrderMod() *order.OrderMod { return p.PlayMod.getOrderMod() } + +func (p *Player) GetFurMod() *fur.FurMod { + return p.PlayMod.getFurMod() +} diff --git a/src/server/game/player_data.go b/src/server/game/player_data.go index 535959af..49d975bd 100644 --- a/src/server/game/player_data.go +++ b/src/server/game/player_data.go @@ -582,6 +582,9 @@ func (p *Player) GetAgentByPlayer() gate.Agent { // 处理物品 func (p *Player) HandleLoseItem(itemList []*item.Item, Label string) error { + if itemList == nil { + return nil + } for _, v := range itemList { if v.Num > 0 { v.Num = -v.Num @@ -590,7 +593,7 @@ func (p *Player) HandleLoseItem(itemList []*item.Item, Label string) error { return p.HandleItem(itemList, Label) } func (p *Player) HandleItem(itemList []*item.Item, Label string) error { - if len(itemList) == 0 { + if itemList == nil { return nil } is_update := false @@ -892,6 +895,11 @@ func (p *Player) HandleItem(itemList []*item.Item, Label string) error { PassMod := p.PlayMod.getPassMod() PassMod.AddExp(v.Num) p.ActPassBackData() + case item.ITEM_TYPE_PET_FUR: + FurMod := p.PlayMod.getFurMod() + Effect := itemCfg.GetItemEffect(v.Id) + FurMod.AddFurInfo(Effect, GoUtil.Now(), 0) + BackDataType[item.ITEM_TYPE_PET_FUR] = struct{}{} default: err := ItemMod.AddItem(v.Id, v.Num) p.TeLog("asset_change", map[string]interface{}{ @@ -931,6 +939,9 @@ func (p *Player) HandleItem(itemList []*item.Item, Label string) error { item.ITEM_TYPE_PLAYROOM_DECORATION_SET, item.ITEM_TYPE_PLAYROOM_DRESS_SET: p.PlayroomBackData() + case item.ITEM_TYPE_PET_FUR: + FurMod := p.PlayMod.getFurMod() + p.PushClientRes(FurMod.BackData()) } } p.PetItemUseLog(itemList) @@ -1063,6 +1074,7 @@ func (p *Player) UpdateUserInfo() { simple.Physiology = p.PlayMod.getPlayroomMod().GetPhysiologyList() simple.Lang = int(p.PlayMod.getBaseMod().Lang) simple.Account = p.PlayMod.getBaseMod().Account + simple.PetFur = p.PlayMod.getFurMod().GetFurSet() //TODO 存储到redis 在新版本中将优化成gob进行压缩 value, _ := json.Marshal(simple) IdStr := GoUtil.String(p.M_DwUin) diff --git a/src/server/game/player_mod.go b/src/server/game/player_mod.go index 5f0330eb..89b19f69 100644 --- a/src/server/game/player_mod.go +++ b/src/server/game/player_mod.go @@ -23,6 +23,7 @@ import ( "server/game/mod/face" "server/game/mod/friend" friendTreasure "server/game/mod/friend_treasure.go" + "server/game/mod/fur" guesscolor "server/game/mod/guess_color" "server/game/mod/guide" guideTask "server/game/mod/guide_task" @@ -120,6 +121,7 @@ type PlayerModList struct { Catnip catnip.CatnipMod // 猫草大作战 GuideTask guideTask.GuideTaskMod // 引导任务 Pass pass.PassMod // 通行证 + Fur fur.FurMod // 毛皮 } func (p *PlayerModData) LoadDataFromDB(dwUin interface{}) bool { @@ -221,6 +223,7 @@ func (p *PlayerModData) InitMod(player *Player) (bool, error) { p.ModList.Compensation.InitData() p.ModList.GuideTask.InitData() p.ModList.Pass.InitData() + p.ModList.Fur.InitData() return is_update, nil } @@ -439,3 +442,7 @@ func (p *PlayerMod) getGuideTaskMod() *guideTask.GuideTaskMod { func (p *PlayerMod) getPassMod() *pass.PassMod { return &p.mod_list.Pass } + +func (p *PlayerMod) getFurMod() *fur.FurMod { + return &p.mod_list.Fur +} diff --git a/src/server/game/req_func_fur.go b/src/server/game/req_func_fur.go new file mode 100644 index 00000000..d107a030 --- /dev/null +++ b/src/server/game/req_func_fur.go @@ -0,0 +1,52 @@ +package game + +import ( + "server/msg" + + "google.golang.org/protobuf/proto" +) + +func ReqPetFur(player *Player, buf []byte) error { + FurMod := player.GetFurMod() + player.PushClientRes(FurMod.BackData()) + return nil +} + +func ReqPetFurBuy(player *Player, buf []byte) error { + var req msg.ReqPetFurBuy + err := proto.Unmarshal(buf, &req) + if err != nil { + return err + } + FurMod := player.GetFurMod() + costList, AddItem := FurMod.GetFurBuyCost(int(req.FurId)) + // 扣除物品 + err = player.HandleLoseItem(costList, msg.ITEM_POP_LABEL_PetFurShop.String()) + if err != nil { + return err + } + // 增加物品 + err = player.HandleItem(AddItem, msg.ITEM_POP_LABEL_PetFurShop.String()) + if err != nil { + return err + } + player.PlayMod.save() + return nil +} + +func ReqFurSet(player *Player, buf []byte) error { + var req msg.ReqFurSet + err := proto.Unmarshal(buf, &req) + if err != nil { + return err + } + FurMod := player.GetFurMod() + err = FurMod.SetFur(int(req.FurId)) + if err != nil { + return err + } + player.UpdateUserInfo() + player.PlayMod.save() + player.PushClientRes(FurMod.BackData()) + return nil +} diff --git a/src/server/test/fix_test.go b/src/server/test/fix_test.go index ff06170f..03d6d438 100644 --- a/src/server/test/fix_test.go +++ b/src/server/test/fix_test.go @@ -106,7 +106,7 @@ func TestNotify(t *testing.T) { // titlekey, infokey := notification_cfg.GetPetroomGameNotificationMsg() // title := languageCfg.GetLanguage(msg.LANG_TYPE(1), titlekey) // info := languageCfg.GetLanguage(msg.LANG_TYPE(1), infokey) - GoUtil.NotifyPlayer(10130, 2, title, fmt.Sprintf(info, "猫猫")) + GoUtil.NotifyPlayer(3625212, 2, title, fmt.Sprintf(info, "猫猫")) // GoUtil.NotifyPlayer(19246, 1, "Test Notification", "This is a test notification from the server.") } diff --git a/src/server/test/fur_test.go b/src/server/test/fur_test.go new file mode 100644 index 00000000..2d595828 --- /dev/null +++ b/src/server/test/fur_test.go @@ -0,0 +1,92 @@ +package test + +import ( + "fmt" + fur_cfg "server/conf/fur" + "server/game" + "server/msg" + "testing" + + "google.golang.org/protobuf/proto" +) + +func TestGetFurShopCost(t *testing.T) { + cost := fur_cfg.GetFurShopCost(1) + fmt.Printf("cost: %v", cost) +} + +func TestGetFurShopFreeTimes(t *testing.T) { + freeTimes := fur_cfg.GetFurShopFreeTimes() + fmt.Printf("freeTimes: %d", freeTimes) +} + +func TestGetFurShopTag(t *testing.T) { + tag := fur_cfg.GetFurShopTag(1) + fmt.Printf("tag: %d", tag) +} + +func TestReqPetFur(t *testing.T) { + player := new(game.Player) + err := game.ReqPetFur(player, nil) + if err != nil { + t.Errorf("ReqPetFur error: %v", err) + } +} + +func TestReqPetFurBuy(t *testing.T) { + player := new(game.Player) + player.InitPlayerByUid(100001) + m := msg.ReqPetFurBuy{ + FurId: 1, + } + buf, err := proto.Marshal(&m) + if err != nil { + t.Errorf("marshal error: %v", err) + } + err = game.ReqPetFurBuy(player, buf) + if err != nil { + t.Errorf("ReqPetFurBuy error: %v", err) + } + + m = msg.ReqPetFurBuy{ + FurId: 2, + } + buf, err = proto.Marshal(&m) + if err != nil { + t.Errorf("marshal error: %v", err) + } + err = game.ReqPetFurBuy(player, buf) + if err != nil { + t.Errorf("ReqPetFurBuy error: %v", err) + } +} + +func TestReqFurSet(t *testing.T) { + player := new(game.Player) + player.InitPlayerByUid(100001) + m := msg.ReqFurSet{ + FurId: 1, + } + buf, err := proto.Marshal(&m) + if err != nil { + t.Errorf("marshal error: %v", err) + } + FurMod := player.GetFurMod() + FurMod.AddFurInfo(1, 0, 0) + err = game.ReqFurSet(player, buf) + if err != nil { + t.Errorf("ReqFurSet error: %v", err) + } + + m = msg.ReqFurSet{ + FurId: 0, + } + buf, err = proto.Marshal(&m) + if err != nil { + t.Errorf("marshal error: %v", err) + } + err = game.ReqFurSet(player, buf) + if err != nil { + t.Errorf("ReqFurSet error: %v", err) + } +}