From d836d785b4fc4947f76ab3cde36712526debf9fe Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Thu, 24 Jul 2025 12:08:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8C=AB=E8=8D=89=E5=A4=A7=E4=BD=9C=E6=88=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/conf/catnip/CatnipCfg.go | 87 +++++++++++++- src/server/game/PlayerFunc.go | 22 +++- src/server/game/PlayerMsg.go | 23 ++++ src/server/game/RegisterNetworkFunc.go | 35 +++++- src/server/game/Type.go | 1 + src/server/game/mod/catnip/Catnip.go | 153 ++++++++++++++----------- src/server/msg/Gameapi.pb.go | 9 +- 7 files changed, 250 insertions(+), 80 deletions(-) create mode 100644 src/server/game/PlayerMsg.go diff --git a/src/server/conf/catnip/CatnipCfg.go b/src/server/conf/catnip/CatnipCfg.go index df66ca03..7d44a585 100644 --- a/src/server/conf/catnip/CatnipCfg.go +++ b/src/server/conf/catnip/CatnipCfg.go @@ -1,6 +1,10 @@ package catnipCfg -import "server/gamedata" +import ( + "server/GoUtil" + "server/game/mod/item" + "server/gamedata" +) const ( CATNIP_TEMPLATE_CFG_NAME = "CatnipTemplate" @@ -9,6 +13,12 @@ const ( CATNIP_GAME_CFG_NAME = "CatnipGame" ) +const ( + CATNIP_REWARD_TYPE_LOW = 1 + CATNIP_REWARD_TYPE_MID = 2 + CATNIP_REWARD_TYPE_HIGH = 3 +) + func init() { gamedata.InitCfg(CATNIP_TEMPLATE_CFG_NAME) gamedata.InitCfg(CATNIP_JACKPOT_CFG_NAME) @@ -23,3 +33,78 @@ func GetGameNum(Id int) int { } return gamedata.GetIntValue(data, "PassNum") } + +func GetJackpotItem(Mul int) (int, []*item.Item, int) { + data, err := gamedata.GetData(CATNIP_JACKPOT_CFG_NAME) + if err != nil { + return 0, nil, 0 + } + JackpotType := GetJackpotType(Mul) + r := make(map[int]int) + for k, v := range data { + if gamedata.GetIntValue(v, "Type") == JackpotType { + r[GoUtil.Int(k)] = 1 + } + } + Id := GoUtil.RandMap(r) + if Id == 0 { + return 0, nil, 0 + } + itemData, err := gamedata.GetDataByIntKey(CATNIP_JACKPOT_CFG_NAME, Id) + if err != nil { + return 0, nil, 0 + } + return Id, gamedata.GetItemList(itemData, "Items"), gamedata.GetIntValue(itemData, "Growth") +} + +func GetJackpotType(Mul int) int { + data, err := gamedata.GetDataByIntKey(CATNIP_MULTIPLIER_CFG_NAME, Mul) + if err != nil { + return 0 + } + R := map[int]int{ + CATNIP_REWARD_TYPE_LOW: gamedata.GetIntValue(data, "Low"), + CATNIP_REWARD_TYPE_MID: gamedata.GetIntValue(data, "Mid"), + CATNIP_REWARD_TYPE_HIGH: gamedata.GetIntValue(data, "High"), + } + return GoUtil.RandMap(R) +} + +func GetTemplateId(Id int) int { + data, err := gamedata.GetDataByIntKey(CATNIP_TEMPLATE_CFG_NAME, Id) + if err != nil { + return 0 + } + return gamedata.GetIntValue(data, "Template") +} + +func GetProgressReward(Id int, Progress int) []*item.Item { + TemplateId := GetTemplateId(Id) + data, err := gamedata.GetDataByIntKey(CATNIP_GAME_CFG_NAME, Id) + if err != nil { + return nil + } + + for _, v := range data { + if gamedata.GetIntValue(v, "Need") == Progress && gamedata.GetIntValue(v, "Template") == TemplateId { + return gamedata.GetItemList(v, "Items") + } + } + return nil +} + +func GetItemCost(Id, Mul int) []*item.Item { + data, err := gamedata.GetDataByIntKey(CATNIP_TEMPLATE_CFG_NAME, Id) + if err != nil { + return nil + } + return item.MutilItem(gamedata.GetItemList(data, "ItemCost"), Mul) +} + +func GetGrandReward(Id int) []*item.Item { + data, err := gamedata.GetDataByIntKey(CATNIP_TEMPLATE_CFG_NAME, Id) + if err != nil { + return nil + } + return gamedata.GetItemList(data, "Reward") +} diff --git a/src/server/game/PlayerFunc.go b/src/server/game/PlayerFunc.go index fe327d9d..b7ddf4d5 100644 --- a/src/server/game/PlayerFunc.go +++ b/src/server/game/PlayerFunc.go @@ -309,7 +309,7 @@ func handle(p *Player, m *msg.Msg) error { p.PushClientRes(ChargeMod.BackData()) case msg.HANDLE_TYPE_PLAYROOM_KISS: // playroom亲吻 p.NotifyPlayroomKiss() - case msg.HANDLE_TYPE_CATNIP_INVITE: + case msg.HANDLE_TYPE_CATNIP_INVITE: // 邀请好友参与猫咪游戏 CatnipMod := p.PlayMod.getCatnipMod() CatnipMsg := m.Extra.(CatnipMsg) ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) @@ -317,7 +317,7 @@ func handle(p *Player, m *msg.Msg) error { return nil } CatnipMod.BeInvited(CatnipMsg.GameId, int(m.From), m.SendT) - case msg.HANDLE_TYPE_CATNIP_AGREE: + case msg.HANDLE_TYPE_CATNIP_AGREE: // 同意好友参与猫咪游戏 CatnipMod := p.PlayMod.getCatnipMod() CatnipMsgInfo := m.Extra.(CatnipMsg) ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) @@ -337,7 +337,7 @@ func handle(p *Player, m *msg.Msg) error { SendT: GoUtil.Now(), }) } - case msg.HANDLE_TYPE_CATNIP_AGREE_DEL: + case msg.HANDLE_TYPE_CATNIP_AGREE_DEL: // 同意好友参与猫咪游戏后删除邀请 CatnipMod := p.PlayMod.getCatnipMod() CatnipMsg := m.Extra.(CatnipMsg) ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) @@ -345,6 +345,22 @@ func handle(p *Player, m *msg.Msg) error { return nil } CatnipMod.DelInvited(CatnipMsg.GameId, int(m.From)) + case msg.HANDLE_TYPE_CATNIP_REFUSE: // 拒绝好友参与猫咪游戏 + CatnipMod := p.PlayMod.getCatnipMod() + CatnipMsg := m.Extra.(CatnipMsg) + ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) + if ActivityId != CatnipMsg.ActivityId { // 活动ID不匹配 + return nil + } + CatnipMod.DelInvited(CatnipMsg.GameId, int(m.From)) + case msg.HANDLE_TYPE_CATNIP_GROWTH: + CatnipMod := p.PlayMod.getCatnipMod() + CatnipGrowthInfo := m.Extra.(CatnipMsg) + ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) + if ActivityId != CatnipGrowthInfo.ActivityId { // 活动ID不匹配 + return nil + } + CatnipMod.Growth(CatnipGrowthInfo.GameId, CatnipGrowthInfo.Growth) default: log.Debug("uid : %d, handle msg type : %d not exist", p.M_DwUin, m.Type) } diff --git a/src/server/game/PlayerMsg.go b/src/server/game/PlayerMsg.go new file mode 100644 index 00000000..b0e7ddb7 --- /dev/null +++ b/src/server/game/PlayerMsg.go @@ -0,0 +1,23 @@ +package game + +import ( + "server/GoUtil" + "server/game/mod/activity" + "server/game/mod/msg" +) + +func (p *Player) CatnipGrowthMsg(To, Id, Growth int) error { + ActivityId := GetActivityId(p, activity.ACT_TYPE_CATNIP) + FriendMgrSend(&msg.Msg{ + From: int(p.M_DwUin), + To: To, + Type: msg.HANDLE_TYPE_CATNIP_GROWTH, + SendT: GoUtil.Now(), + Extra: CatnipMsg{ + ActivityId: ActivityId, + GameId: Id, + Growth: Growth, + }, + }) + return nil +} diff --git a/src/server/game/RegisterNetworkFunc.go b/src/server/game/RegisterNetworkFunc.go index 1d5cb185..ce8158cd 100644 --- a/src/server/game/RegisterNetworkFunc.go +++ b/src/server/game/RegisterNetworkFunc.go @@ -4782,7 +4782,8 @@ func ReqCatnipMultiply(player *Player, buf []byte) error { return err } player.TeLog("catnip_multiply", map[string]interface{}{ - "Id": int(req.Id), + "Id": int(req.Id), + "Mul": int(req.Multiply), }) player.PlayMod.save() player.PushClientRes(&msg.ResCatnipMultiply{ @@ -4796,7 +4797,7 @@ func ReqCatnipPlay(player *Player, buf []byte) error { req := &msg.ReqCatnipPlay{} proto.Unmarshal(buf, req) CatnipMod := player.PlayMod.getCatnipMod() - err := CatnipMod.Play(int(req.Id)) + Id, Growth, PartnerId, Items, ItemCost, err := CatnipMod.Play(int(req.Id)) if err != nil { player.SendErrClienRes(&msg.ResCatnipPlay{ Code: msg.RES_CODE_FAIL, @@ -4804,12 +4805,33 @@ func ReqCatnipPlay(player *Player, buf []byte) error { }) return err } + err = player.HandleLoseItem(ItemCost, msg.ITEM_POP_LABEL_CatnipPlay.String()) + if err != nil { + player.SendErrClienRes(&msg.ResCatnipPlay{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + } + err = player.HandleItem(Items, msg.ITEM_POP_LABEL_CatnipPlay.String()) + if err != nil { + player.SendErrClienRes(&msg.ResCatnipPlay{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + } player.TeLog("catnip_play", map[string]interface{}{ - "Id": int(req.Id), + "Id": int(req.Id), + "Growth": Growth, + "PartnerId": PartnerId, + "Items": Items, }) + if Growth > 0 { + player.CatnipGrowthMsg(PartnerId, int(req.Id), Growth) + } player.PlayMod.save() player.PushClientRes(&msg.ResCatnipPlay{ Code: msg.RES_CODE_SUCCESS, + Id: int32(Id), }) return nil } @@ -4819,7 +4841,7 @@ func ReqCatnipReward(player *Player, buf []byte) error { req := &msg.ReqCatnipReward{} proto.Unmarshal(buf, req) CatnipMod := player.PlayMod.getCatnipMod() - Items, err := CatnipMod.Reward(int(req.Progress)) + Items, err := CatnipMod.Reward(int(req.Id), int(req.Progress)) if err != nil { player.SendErrClienRes(&msg.ResCatnipReward{ Code: msg.RES_CODE_FAIL, @@ -4836,7 +4858,9 @@ func ReqCatnipReward(player *Player, buf []byte) error { return err } player.TeLog("catnip_reward", map[string]interface{}{ - "Items": Items, + "Id": int(req.Id), + "Progress": int(req.Progress), + "Items": Items, }) player.PlayMod.save() player.PushClientRes(&msg.ResCatnipReward{ @@ -4845,6 +4869,7 @@ func ReqCatnipReward(player *Player, buf []byte) error { return nil } +// 猫草大作战领取大奖 func ReqCatnipGrandReward(player *Player, buf []byte) error { req := &msg.ReqCatnipGrandReward{} proto.Unmarshal(buf, req) diff --git a/src/server/game/Type.go b/src/server/game/Type.go index 5e0c6e84..e9e552ab 100644 --- a/src/server/game/Type.go +++ b/src/server/game/Type.go @@ -85,6 +85,7 @@ type GameResult struct { type CatnipMsg struct { ActivityId int GameId int + Growth int // 增长值 } type CatnipLock struct { diff --git a/src/server/game/mod/catnip/Catnip.go b/src/server/game/mod/catnip/Catnip.go index 25a2f030..e91a314d 100644 --- a/src/server/game/mod/catnip/Catnip.go +++ b/src/server/game/mod/catnip/Catnip.go @@ -8,10 +8,10 @@ import ( ) type CatnipMod struct { - Id int - Game map[int]*CatnipGame - InviteList map[int][]*InviteInfo // 邀请列表,key: 邀请者ID, value: 被邀请者ID - BeInvitedList map[int][]*InviteInfo // 被邀请列表,key: 被邀请者ID, value: 邀请者ID + Id int + Game map[int]*CatnipGame + + IsGetGrandReward bool // 是否领取过大丰收奖励 } type InviteInfo struct { @@ -20,13 +20,15 @@ type InviteInfo struct { } type CatnipGame struct { - Id int // 游戏ID - Partner int // 伙伴ID - Progress int // 进度 - PartnerAdd int // 伙伴贡献 - Reward []int // 已领取阶段奖励 - Mul int // 倍数 - Status int // 0: Not Started, 1: In Progress, 2: Completed + Id int // 游戏ID + Partner int // 伙伴ID + Progress int // 进度 + PartnerAdd int // 伙伴贡献 + Reward []int // 已领取阶段奖励 + Mul int // 倍数 + Status int // 0: Not Started, 1: In Progress, 2: Completed + InviteList map[int]*InviteInfo // 邀请列表,key: 邀请者ID, value: 被邀请者ID + BeInvitedList map[int]*InviteInfo // 被邀请列表,key: 被邀请者ID, value: 邀请者ID } const ( @@ -40,12 +42,6 @@ func (c *CatnipMod) InitData() { if c.Game == nil { c.Game = make(map[int]*CatnipGame) } - if c.InviteList == nil { - c.InviteList = make(map[int][]*InviteInfo) - } - if c.BeInvitedList == nil { - c.BeInvitedList = make(map[int][]*InviteInfo) - } } func (c *CatnipMod) Login(Id int) int { @@ -58,6 +54,7 @@ func (c *CatnipMod) Login(Id int) int { return 0 } c.Id = Id + c.IsGetGrandReward = false // Reset grand reward status on login c.Game = make(map[int]*CatnipGame) GameNum := catnipCfg.GetGameNum(c.Id) // Assuming 1 is the default game ID for i := 1; i <= GameNum; i++ { @@ -83,15 +80,15 @@ func (c *CatnipMod) Invite(Id, Uid int) error { if GameInfo.Status != 0 { return fmt.Errorf("game with ID %d is already in progress or completed", Id) } - for _, invite := range c.InviteList[Id] { - if invite.InviteId == Uid { - return fmt.Errorf("user with ID %d is already invited to game ID %d", Uid, Id) - } + + if GameInfo.InviteList[Uid] != nil { + return fmt.Errorf("user with ID %d is already invited to game ID %d", Uid, Id) } - c.InviteList[Id] = append(c.InviteList[Id], &InviteInfo{ + + GameInfo.InviteList[Uid] = &InviteInfo{ InviteId: Uid, Time: GoUtil.Now(), - }) + } return nil } @@ -104,15 +101,14 @@ func (c *CatnipMod) BeInvited(Id, Uid int, Time int64) error { return fmt.Errorf("game with ID %d is already in progress or completed", Id) } // Check if the user is already invited - for _, invite := range c.BeInvitedList[Uid] { - if invite.InviteId == Id { - return fmt.Errorf("user with ID %d has already been invited to game ID %d", Uid, Id) - } + invite := GameInfo.BeInvitedList[Uid] + if invite != nil && invite.InviteId == Id { + return fmt.Errorf("user with ID %d has already been invited to game ID %d", Uid, Id) } - c.BeInvitedList[Uid] = append(c.BeInvitedList[Uid], &InviteInfo{ + GameInfo.BeInvitedList[Uid] = &InviteInfo{ InviteId: Id, Time: Time, - }) + } return nil } @@ -125,27 +121,15 @@ func (c *CatnipMod) Agree(Id, Uid int) ([]int, error) { return nil, fmt.Errorf("game with ID %d is already in progress or completed", Id) } // Check if the user is in the invite list - inviteList, exists := c.InviteList[Id] + _, exists := GameInfo.InviteList[Uid] if !exists { - return nil, fmt.Errorf("no invites found for game ID %d", Id) - } - userExists := false - InviteUser := []int{} - for _, invite := range inviteList { - if invite.InviteId == Uid { - userExists = true - continue - } - InviteUser = append(InviteUser, invite.InviteId) - - } - if !userExists { return nil, fmt.Errorf("user with ID %d is not invited to game ID %d", Uid, Id) } - c.InviteList[Id] = make([]*InviteInfo, 0) // Clear the invite list after agreeing - GameInfo.Partner = Uid // Set the partner for the game - GameInfo.Status = GAME_STATUS_COMPLETED // Set the game status to in progress - return InviteUser, nil + // Remove the invite after agreeing + delete(GameInfo.InviteList, Uid) + GameInfo.Partner = Uid // Set the partner for the game + GameInfo.Status = GAME_STATUS_COMPLETED // Set the game status to completed + return []int{}, nil } func (c *CatnipMod) DelInvited(Id, Uid int) error { @@ -156,14 +140,8 @@ func (c *CatnipMod) DelInvited(Id, Uid int) error { if GameInfo.Status != GAME_STATUS_IDLE { return fmt.Errorf("game with ID %d is already in progress or completed", Id) } - for k, invite := range c.BeInvitedList[Id] { - if invite.InviteId == Uid { - // Remove the invite from the list - c.BeInvitedList[Id] = append(c.InviteList[Id][:k], c.InviteList[Id][k+1:]...) - return nil - } - } - return fmt.Errorf("user with ID %d is not invited to game ID %d", Uid, Id) + delete(GameInfo.InviteList, Uid) + return nil } func (c *CatnipMod) Multiply(Id, Mul int) error { @@ -183,24 +161,61 @@ func (c *CatnipMod) Refuse(Id, Uid int) error { if GameInfo.Status != GAME_STATUS_IDLE { return fmt.Errorf("game with ID %d is already in progress or completed", Id) } - for k, invite := range c.InviteList[Id] { - if invite.InviteId == Uid { - // Remove the invite from the list - c.InviteList[Id] = append(c.InviteList[Id][:k], c.InviteList[Id][k+1:]...) - return nil - } + delete(GameInfo.BeInvitedList, Uid) + return nil +} + +func (c *CatnipMod) Play(Id int) (int, int, int, []*item.Item, []*item.Item, error) { + GameInfo, ok := c.Game[Id] + if !ok { + return 0, 0, 0, nil, nil, fmt.Errorf("game with ID %d does not exist", Id) } - return nil + Id, Items, Growth := catnipCfg.GetJackpotItem(GameInfo.Mul) + if Growth > 0 { + c.Growth(Id, Growth) + } + ItemCost := catnipCfg.GetItemCost(c.Id, GameInfo.Mul) + return Id, Growth, GameInfo.Partner, Items, ItemCost, nil } -func (c *CatnipMod) Play(Id int) error { - return nil -} - -func (c *CatnipMod) Reward(Id int) ([]*item.Item, error) { - return nil, nil +func (c *CatnipMod) Reward(Id, Progress int) ([]*item.Item, error) { + GameInfo, ok := c.Game[Id] + if !ok { + return nil, fmt.Errorf("game with Progress %d does not exist", Id) + } + if GameInfo.Progress < Progress { + return nil, fmt.Errorf("game with ID %d has not reached the required progress %d", Id, Progress) + } + if GoUtil.InArray(Progress, GameInfo.Reward) { + return nil, fmt.Errorf("reward for progress %d has already been claimed in game ID %d", Progress, Id) + } + GameInfo.Reward = append(GameInfo.Reward, Progress) + return catnipCfg.GetProgressReward(c.Id, Progress), nil } func (c *CatnipMod) GrandReward() ([]*item.Item, error) { - return nil, nil + for _, game := range c.Game { + if game.Status != GAME_STATUS_COMPLETED { + return nil, fmt.Errorf("game with ID %d is not completed", game.Id) + } + } + if c.IsGetGrandReward { + return nil, fmt.Errorf("grand reward has already been claimed") + } + c.IsGetGrandReward = true + return catnipCfg.GetGrandReward(c.Id), nil +} + +func (c *CatnipMod) Growth(Id, Growth int) { + GameInfo, ok := c.Game[Id] + if !ok { + return // Game does not exist + } + if GameInfo.Status != GAME_STATUS_IN_PROGRESS { + return // Game is not in progress + } + GameInfo.Progress += Growth + if GameInfo.Progress >= catnipCfg.GetGameNum(Id) { // Assuming the game ends when progress reaches a certain threshold + GameInfo.Status = GAME_STATUS_COMPLETED + } } diff --git a/src/server/msg/Gameapi.pb.go b/src/server/msg/Gameapi.pb.go index f562a563..21d670f3 100644 --- a/src/server/msg/Gameapi.pb.go +++ b/src/server/msg/Gameapi.pb.go @@ -93,6 +93,7 @@ const ( ITEM_POP_LABEL_DecorateReward ITEM_POP_LABEL = 66 // 装饰奖励 ITEM_POP_LABEL_CatnipReward ITEM_POP_LABEL = 67 // 猫草大作战奖励 ITEM_POP_LABEL_CatnipGrandReward ITEM_POP_LABEL = 68 // 猫草大作战大奖奖励 + ITEM_POP_LABEL_CatnipPlay ITEM_POP_LABEL = 69 // 猫草大作战玩法奖励 ) // Enum value maps for ITEM_POP_LABEL. @@ -167,6 +168,7 @@ var ( 66: "DecorateReward", 67: "CatnipReward", 68: "CatnipGrandReward", + 69: "CatnipPlay", } ITEM_POP_LABEL_value = map[string]int32{ "Playroom": 0, @@ -238,6 +240,7 @@ var ( "DecorateReward": 66, "CatnipReward": 67, "CatnipGrandReward": 68, + "CatnipPlay": 69, } ) @@ -26416,7 +26419,7 @@ const file_proto_Gameapi_proto_rawDesc = "" + "\n" + "ReqAdminGm\x12\x10\n" + "\x03Uid\x18\x01 \x01(\x03R\x03Uid\x12\x18\n" + - "\aCommand\x18\x02 \x01(\tR\aCommand*\xa5\n" + + "\aCommand\x18\x02 \x01(\tR\aCommand*\xb5\n" + "\n" + "\x0eITEM_POP_LABEL\x12\f\n" + "\bPlayroom\x10\x00\x12\r\n" + @@ -26494,7 +26497,9 @@ const file_proto_Gameapi_proto_rawDesc = "" + "\x0ePlayroomUpvote\x10A\x12\x12\n" + "\x0eDecorateReward\x10B\x12\x10\n" + "\fCatnipReward\x10C\x12\x15\n" + - "\x11CatnipGrandReward\x10D*B\n" + + "\x11CatnipGrandReward\x10D\x12\x0e\n" + + "\n" + + "CatnipPlay\x10E*B\n" + "\vHANDLE_TYPE\x12\a\n" + "\x03ADD\x10\x00\x12\v\n" + "\aCOMPOSE\x10\x01\x12\a\n" +