From 64901ca8b05188a5e9b4ca0eb4925e43e4e0b9c7 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:34:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A5=BD=E5=8F=8B=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/conf/friend/friend_cfg.go | 27 ++ src/server/game/message_handler.go | 7 +- src/server/game/mod/friend/Friend.go | 99 +++- src/server/game/register_network_func.go | 556 ---------------------- src/server/game/req_func_friend.go | 577 +++++++++++++++++++++++ 5 files changed, 688 insertions(+), 578 deletions(-) create mode 100644 src/server/game/req_func_friend.go diff --git a/src/server/conf/friend/friend_cfg.go b/src/server/conf/friend/friend_cfg.go index 5c7327ae..23309f27 100644 --- a/src/server/conf/friend/friend_cfg.go +++ b/src/server/conf/friend/friend_cfg.go @@ -41,3 +41,30 @@ func GetFriendLimitNum() int { } return gamedata.GetIntValue(data, "Value") } + +func GetDailyRecommendLimit() int { + data, err := gamedata.GetDataByKey(CFG_CONST, "friend_daily_recommend_limit") + if err != nil { + log.Debug("GetDailyRecommendLimit err:%v", err) + return 0 + } + return gamedata.GetIntValue(data, "Value") +} + +func GetApplyListLimit() int { + data, err := gamedata.GetDataByKey(CFG_CONST, "friend_apply_list_limit") + if err != nil { + log.Debug("GetApplyListLimit err:%v", err) + return 0 + } + return gamedata.GetIntValue(data, "Value") +} + +func GetDailyGetApplyLimit() int { + data, err := gamedata.GetDataByKey(CFG_CONST, "friend_daily_get_apply_limit") + if err != nil { + log.Debug("GetDailyGetApplyLimit err:%v", err) + return 0 + } + return gamedata.GetIntValue(data, "Value") +} diff --git a/src/server/game/message_handler.go b/src/server/game/message_handler.go index 226c8847..5173e4d1 100644 --- a/src/server/game/message_handler.go +++ b/src/server/game/message_handler.go @@ -62,7 +62,12 @@ func (p *Player) handle(m *msg.Msg) error { switch m.Type { case msg.HANDLE_TYPE_APPLY: // 好友申请 FriendMod := p.PlayMod.getFriendMod() - ok := FriendMod.AddFriendApply(m.From) + var addType int + info, ok := m.Extra.(map[string]interface{}) + if ok { + addType = GoUtil.Int(info["type"]) + } + ok = FriendMod.AddFriendApply(m.From, addType) // 已申请 if ok { return nil diff --git a/src/server/game/mod/friend/Friend.go b/src/server/game/mod/friend/Friend.go index 0bd63474..6e49ffda 100644 --- a/src/server/game/mod/friend/Friend.go +++ b/src/server/game/mod/friend/Friend.go @@ -11,22 +11,25 @@ import ( ) type FriendMod struct { - FriendList map[int]struct{} // TODO 废弃 好友列表 - NewFriendList map[int]*FriendInfo // 好友列表 - ApplyList map[int]int64 // 好友请求列表 - SendApply map[int]int64 // 发送的申请 - Apply []*ApplyInfo // 其他请求列表 - Card map[string]*card.CardInfo // 收到的申请交换 - Log []*LogInfo // 日志 - AutoId int - Id int64 // 已同步msg ID - Npc []int // npc id - Bubble map[int]*BubbleInfo // 气泡 - ActivityLog []*ActLogInfo // 活动日志 - ReplyList []*ReplyInfo // 好友回复列表 - DailySponsor int // 好友赞助次数 - RecommendList map[int]*Recommend - DailyGetApply int // 每日获得申请次数 + FriendList map[int]struct{} // 废弃 好友列表 + NewFriendList map[int]*FriendInfo // 好友列表 + ApplyList map[int]int64 // 废弃 好友请求列表 + NewApplyList map[int]*ApplyInfo // 好友请求列表 + SendApply map[int]int64 // 发送的申请 + Apply []*ApplyInfo // 其他请求列表 + Card map[string]*card.CardInfo // 收到的申请交换 + Log []*LogInfo // 日志 + AutoId int + Id int64 // 已同步msg ID + Npc []int // npc id + Bubble map[int]*BubbleInfo // 气泡 + ActivityLog []*ActLogInfo // 活动日志 + ReplyList []*ReplyInfo // 好友回复列表 + DailySponsor int // 好友赞助次数 + RecommendList map[int]*Recommend + DailyGetApply int // 每日获得申请次数 + DailyRecommend int // 每日推荐次数 + Version int // 数据版本,增加新字段时需要更新版本号 } type Recommend struct { @@ -71,7 +74,7 @@ type Interact struct { } type ApplyInfo struct { - Type int // 1:申请 2:同意 3:拒绝 4:删除 + Type int Time int64 Uid int64 } @@ -133,7 +136,8 @@ const ( ) const ( - APPLY_TYPE_WISH = 1 // 心愿单请求 + APPLY_TYPE_FRIEND_CODE = 1 // 好友码申请 + APPLY_TYPE_WISH = 2 // 心愿单请求 ) const ( @@ -216,12 +220,29 @@ func (f *FriendMod) InitData() { if f.RecommendList == nil { f.RecommendList = make(map[int]*Recommend) } + if f.NewApplyList == nil { + f.NewApplyList = make(map[int]*ApplyInfo) + } + f.version() +} + +func (f *FriendMod) version() { + if f.Version == 0 { + f.Version = 1 + for k := range f.ApplyList { + f.NewApplyList[k] = &ApplyInfo{ + Type: APPLY_TYPE_FRIEND_CODE, + Time: f.ApplyList[k], + } + } + } } // 零点更新 func (f *FriendMod) ZeroUpdate() { f.DailySponsor = f.GetDailySponsorLimit() f.DailyGetApply = 0 + f.DailyRecommend = 0 } func (f *FriendMod) GetNpc() []int { @@ -384,11 +405,39 @@ func (f *FriendMod) CheckAddBefore(uid int) bool { } // 收到申请 -func (f *FriendMod) AddFriendApply(Uid int) bool { - if f.DailyGetApply >= 30 { +func (f *FriendMod) AddFriendApply(Uid, Type int) bool { + if f.DailyGetApply >= friendCfg.GetDailyGetApplyLimit() { return true } - f.ApplyList[Uid] = GoUtil.Now() + var code_type int + for _, v := range f.NewApplyList { + if v.Type == APPLY_TYPE_FRIEND_CODE { + code_type++ + } + } + // 好友申请列表只保留十条,好友码申请不受数量限制 + if code_type >= friendCfg.GetApplyListLimit() && Type != APPLY_TYPE_FRIEND_CODE { + return true + } + var minTime int64 + if len(f.NewApplyList) >= friendCfg.GetApplyListLimit() { + for _, v := range f.NewApplyList { + if v.Type != APPLY_TYPE_FRIEND_CODE && (minTime == 0 || v.Time < minTime) { + minTime = v.Time + } + } + for k, v := range f.NewApplyList { + if v.Time == minTime { + delete(f.NewApplyList, k) + break + } + } + } + f.NewApplyList[Uid] = &ApplyInfo{ + Type: Type, + Time: GoUtil.Now(), + Uid: int64(Uid), + } f.DailyGetApply++ return false } @@ -658,3 +707,11 @@ func (f *FriendMod) GetRecommendTime(uid int) int64 { } return 0 } + +func (f *FriendMod) AddDailyRecommend() error { + f.DailyRecommend++ + if f.DailyRecommend > friendCfg.GetDailyRecommendLimit() { + return fmt.Errorf("daily recommend limit %d reached", friendCfg.GetDailyRecommendLimit()) + } + return nil +} diff --git a/src/server/game/register_network_func.go b/src/server/game/register_network_func.go index b771cc4b..546f8620 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -4,14 +4,11 @@ import ( "errors" "fmt" "math" - "server/conf" - baseCfg "server/conf/base" cardCfg "server/conf/card" champshipCfg "server/conf/champship" collectCfg "server/conf/collect" decorateCfg "server/conf/decorate" emojiCfg "server/conf/emoji" - friendCfg "server/conf/friend" GuideTaskCfg "server/conf/guide_task" handbookCfg "server/conf/handbook" limitedTimeEventCfg "server/conf/limited_time_event" @@ -19,7 +16,6 @@ import ( miningCfg "server/conf/mining" orderCfg "server/conf/order" playroomCfg "server/conf/playroom" - "server/db" "server/game/internal" "server/game/mod/activity" "server/game/mod/card" @@ -1795,251 +1791,6 @@ func ReqGetGoldCard(player *Player, buf []byte) error { return nil } -// 搜索用户 -func ReqSearchPlayer(player *Player, buf []byte) error { - req := &msg.ReqSearchPlayer{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - Uid, err := strconv.Atoi(req.Uid) - list := make([]*msg.ResPlayerSimple, 0) - if err == nil { - SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(Uid) - if SearchPlayer != nil && SearchPlayer.Level != 0 { - list = append(list, SearchPlayer) - } - } - data, err := db.SearchPlayer(req.Uid) - if err != nil { - player.SendErrClienRes(&msg.ResSearchPlayer{ - Code: 0, - }) - } - for _, v := range data { - if player.M_DwUin == v.DwUin { - continue - } - SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(int(v.DwUin)) - list = append(list, SearchPlayer) - - } - // list 列表去重 - l := make(map[int]*msg.ResPlayerSimple) - for _, v := range list { - if _, ok := l[int(v.Uid)]; !ok { - l[int(v.Uid)] = v - } - } - l2 := make([]*msg.ResPlayerSimple, 0) - for _, v := range l { - l2 = append(l2, v) - } - player.PushClientRes(&msg.ResSearchPlayer{ - List: l2, - }) - return nil -} - -// 申请好友 -func ReqApplyFriend(player *Player, buf []byte) error { - req := &msg.ReqApplyFriend{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - Uid := int(req.Uid) - FriendMod := player.PlayMod.getFriendMod() - if Uid == int(player.M_DwUin) { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "cannot apply yourself", - }) - return fmt.Errorf("cannot apply yourself") - } - if FriendMod.CheckFriend(Uid) { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "already friend", - }) - return fmt.Errorf("already friend") - } - // 好友人数到达上限(2000人)时,玩家将无法再发送好友申请 - if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "friend list full", - }) - return fmt.Errorf("friend list full") - } - // 对于任何玩家而言,向自己在24小时内已从任意途径发送过好友申请的玩家再次发送好友申请时,该次申请不会被发出 - sendApplyTime := FriendMod.GetSendApplyTime(Uid) - if sendApplyTime != 0 && GoUtil.Now()-sendApplyTime < 86400 { - player.PushClientRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Uid: req.Uid, - Msg: "already applied", - }) - return fmt.Errorf("already applied") - } - now := GoUtil.Now() - if req.Type == 1 { - Items, err := FriendMod.GetSponsorReward() - if err != nil { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - BaseMod := player.PlayMod.getBaseMod() - BaseMod.GetEnergyByAD() - err = player.HandleItem(Items, msg.ITEM_POP_LABEL_ApplyFriendSponsor.String()) - if err != nil { - player.SendErrClienRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - player.AddLog(int(req.Uid), friend.LOG_TYPE_FRIEND_SPONSOR, "", now) - FriendMgrSend(&MsqMod.Msg{ - Type: MsqMod.HANDLE_TYPE_FRIEND_SPONSOER, - From: int(player.M_DwUin), - To: Uid, - SendT: now, - End: now + sevendays, - }) - player.PushClientRes(BaseMod.BackData()) - player.TeLog("friend_invite_reward", map[string]interface{}{ - "item_list": Items, - }) - } - m := &MsqMod.Msg{ - Type: MsqMod.HANDLE_TYPE_APPLY, - From: int(player.M_DwUin), - To: Uid, - SendT: now, - End: now + sevendays, - } - FriendMgrSend(m) - player.PushClientRes(&msg.ResApplyFriend{ - Code: msg.RES_CODE_SUCCESS, - Uid: req.Uid, - }) - return nil -} - -// 同意申请 -func ReqAgreeFriend(player *Player, buf []byte) error { - req := &msg.ReqAgreeFriend{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - Uid := int(req.Uid) - FriendMod := player.PlayMod.getFriendMod() - if !FriendMod.CheckApply(Uid) { - player.SendErrClienRes(&msg.ResAgreeFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "apply uid not exist", - }) - return fmt.Errorf("apply uid not exist") - } - // 好友人数到达上限(2000人)时,玩家将无法再同意好友申请 - if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { - player.SendErrClienRes(&msg.ResAgreeFriend{ - Code: msg.RES_CODE_FAIL, - Msg: "friend list full", - }) - return fmt.Errorf("friend list full") - } - // 新好友才可以打招呼 - if !FriendMod.CheckAddBefore(Uid) { - FriendMod.AddReplyInfo(Uid, friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) - } - FriendMod.AddFriend(Uid) - player.PushClientRes(&msg.ResAgreeFriend{ - Code: msg.RES_CODE_SUCCESS, - Uid: req.Uid, - Player: G_GameLogicPtr.GetResSimplePlayerByUid(int(req.Uid)), - }) - player.TeLog("friend_add", map[string]interface{}{ - "player_id": Uid, - "add_type": "接受申请", - }) - player.AddLog(Uid, friend.LOG_TYPE_FRIEND_BECOME, "", GoUtil.Now()) - m := &MsqMod.Msg{ - Type: MsqMod.HADNLE_TYPE_AGREE, - From: int(player.M_DwUin), - To: Uid, - SendT: GoUtil.Now(), - } - FriendMgrSend(m) - player.FriendApplyBackData() - player.FriendLogBackData() - player.PlayMod.save() - return nil -} - -// 删除好友 -func ReqDelFriend(player *Player, buf []byte) error { - req := &msg.ReqDelFriend{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - Uid := int(req.Uid) - m := &MsqMod.Msg{ - Type: MsqMod.HANDLE_TYPE_DEL, - From: int(player.M_DwUin), - To: Uid, - SendT: GoUtil.Now(), - } - FriendMgrSend(m) - FriendMod := player.PlayMod.getFriendMod() - FriendMod.DelFriend(Uid) - player.PlayMod.save() - player.PushClientRes(&msg.ResDelFriend{ - Code: msg.RES_CODE_SUCCESS, - Uid: req.Uid, - }) - player.AddLog(Uid, friend.LOG_TYPE_FRIEND_DELETE, "", GoUtil.Now()) - player.FriendListBackData() - player.TeLog("friend_delete", map[string]interface{}{ - "player_id": Uid, - }) - return nil -} - -// 拒绝申请 -func ReqRefuseFriend(player *Player, buf []byte) error { - req := &msg.ReqRefuseFriend{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - Uid := int(req.Uid) - FriendMod := player.PlayMod.getFriendMod() - FriendMod.RefuseApply(Uid) - player.PlayMod.save() - player.PushClientRes(&msg.ResRefuseFriend{ - Code: msg.RES_CODE_SUCCESS, - Uid: req.Uid, - }) - now := GoUtil.Now() - m := &MsqMod.Msg{ - Type: MsqMod.HANDLE_TYPE_REFUSE, - From: int(player.M_DwUin), - To: Uid, - SendT: now, - End: now + 86400*7, - } - FriendMgrSend(m) - player.FriendApplyBackData() - return nil -} - // 向好友请求卡牌 func ReqCardGive(player *Player, buf []byte) error { req := &msg.ReqCardGive{} @@ -3035,136 +2786,6 @@ func ReqKv(player *Player, buf []byte) error { return nil } -func ReqFriendRecommend(player *Player, buf []byte) error { - FriendMod := player.PlayMod.getFriendMod() - RecommendList := make([]*msg.ResPlayerSimple, 0) - FriendNum := FriendMod.GetFriendNum() - var n int - if FriendNum < 10 { - n = 3 - } else { - Active := 0 - for k := range FriendMod.GetFriendList() { - PlayerSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(k) - if PlayerSimpleData == nil { - continue - } - if PlayerSimpleData.Login > GoUtil.Now()-86400 { - Active++ - } - } - n = max(0, 3-(Active/10)) - } - PlayerList := GetRecommendPlayer(player, n) - - for _, v := range PlayerList { - PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(v) - RecommendList = append(RecommendList, PlayerSimpleData) - } - player.PushClientRes(&msg.ResFriendRecommend{ - List: RecommendList, - }) - player.PlayMod.save() - return nil -} - -func ReqFriendList(player *Player, buf []byte) error { - player.FriendListBackData() - return nil -} - -func ReqFriendApply(player *Player, buf []byte) error { - player.FriendApplyBackData() - return nil -} - -func ReqFriendCardMsg(player *Player, buf []byte) error { - player.FriendCardBackData() - return nil -} - -func ReqFriendTimeLine(player *Player, buf []byte) error { - player.FriendLogBackData() - return nil -} - -func ReqFriendTLUpvote(player *Player, buf []byte) error { - req := &msg.ReqFriendTLUpvote{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - FriendMod := player.PlayMod.getFriendMod() - Items, FUid, err := FriendMod.Upvote(int(req.Id)) - if err != nil { - player.SendErrClienRes(&msg.ResFriendTLUpvote{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - err = player.HandleItem(Items, msg.ITEM_POP_LABEL_TLUpvote.String()) - if err != nil { - player.SendErrClienRes(&msg.ResFriendTLUpvote{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - now := GoUtil.Now() - // 添加时间线 - m := &MsqMod.Msg{ - Type: MsqMod.HANDLE_TYPE_HANDBOOK_UPVOTE, - From: int(player.M_DwUin), - To: int(FUid), - SendT: now, - End: now + sevendays, - } - FriendMod.AddActLog(friend.ACT_LOG_TYPE_VISIT_UPVOTE, "") - player.UpdateUserInfo() - FriendMgrSend(m) - player.PlayMod.save() - player.PushClientRes(&msg.ResFriendTLUpvote{ - Code: msg.RES_CODE_SUCCESS, - Id: req.Id, - }) - player.TeLog("friend_upvote", map[string]interface{}{ - "player_id": int(req.Id), - }) - return nil -} - -func ReqFriendTReward(player *Player, buf []byte) error { - req := &msg.ReqFriendTReward{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - FriendMod := player.PlayMod.getFriendMod() - Items, err := FriendMod.GetReward(int(req.Id)) - if err != nil { - player.SendErrClienRes(&msg.ResFriendTReward{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendTReward.String()) - if err != nil { - player.SendErrClienRes(&msg.ResFriendTReward{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - player.PlayMod.save() - player.PushClientRes(&msg.ResFriendTReward{ - Code: msg.RES_CODE_SUCCESS, - Id: req.Id, - }) - return nil -} - func ReqChampshipRankReward(player *Player, buf []byte) error { _, myPreRank := player.GetChampshipRank() ChampshipMod := player.PlayMod.getChampshipMod() @@ -5046,40 +4667,6 @@ func ReqCatTrickReward(player *Player, buf []byte) error { return nil } -func ReqAddNpc(player *Player, buf []byte) error { - req := &msg.ReqAddNpc{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - FriendMod := player.PlayMod.getFriendMod() - err = FriendMod.SetNpc(int(req.NpcId)) - if err != nil { - player.SendErrClienRes(&msg.ResAddNpc{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - if len(FriendMod.Npc) == 1 { // 首次添加NPC 视为邀请好友成功 - InviteMod := player.PlayMod.getInviteMod() - InviteMod.AddInvite(int(req.NpcId)) - } - player.PlayMod.save() - player.FriendListBackData() - player.TeLog("add_npc", map[string]interface{}{ - "NpcId": int(req.NpcId), - }) - FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) - FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING_Get, "", GoUtil.Now()+oneday, nil) - player.AddLog(int(req.NpcId), friend.LOG_TYPE_FRIEND_BECOME_NPC, GoUtil.String(req.NpcId), GoUtil.Now()) - player.PushClientRes(&msg.ResAddNpc{ - Code: msg.RES_CODE_SUCCESS, - NpcId: req.NpcId, - }) - return nil -} - func ReqChargeReceive(player *Player, buf []byte) error { req := &msg.ReqChargeReceive{} err := proto.Unmarshal(buf, req) @@ -5329,51 +4916,6 @@ func ReqId2Verify(player *Player, buf []byte) error { return nil } -func ReqFriendByCode(player *Player, buf []byte) error { - req := &msg.ReqFriendByCode{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - if req.Code == "" { - player.SendErrClienRes(&msg.ResFriendByCode{ - Code: msg.RES_CODE_FAIL, - Msg: "code is empty", - }) - return fmt.Errorf("code is empty") - } - CodeNum := GoUtil.ParseUniqueStringToInt(req.Code) - if CodeNum <= 0 { - player.SendErrClienRes(&msg.ResFriendByCode{ - Code: msg.RES_CODE_FAIL, - Msg: "code is invalid", - }) - return fmt.Errorf("code is invalid") - } - Uid := int64(CodeNum) + int64(100000) + int64(conf.Server.AppID*100000000) - if Uid == player.M_DwUin { - player.SendErrClienRes(&msg.ResFriendByCode{ - Code: msg.RES_CODE_FAIL, - Msg: "can not add yourself", - }) - return fmt.Errorf("can not add yourself") - } - - PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(int(Uid)) - if PlayerSimpleData == nil { - player.SendErrClienRes(&msg.ResFriendByCode{ - Code: msg.RES_CODE_FAIL, - Msg: "player not exist", - }) - return fmt.Errorf("player not exist") - } - player.PushClientRes(&msg.ResFriendByCode{ - Code: msg.RES_CODE_SUCCESS, - Player: PlayerSimpleData, - }) - return nil -} - func ReqPlayroomGameShowReward(player *Player, buf []byte) error { req := &msg.ReqPlayroomGameShowReward{} err := proto.Unmarshal(buf, req) @@ -5776,104 +5318,6 @@ func ReqActPassReward(player *Player, buf []byte) error { return nil } -func ReqFriendReplyHandle(player *Player, buf []byte) error { - req := &msg.ReqFriendReplyHandle{} - err := proto.Unmarshal(buf, req) - if err != nil { - return err - } - FriendMod := player.PlayMod.getFriendMod() - ReplyInfo := FriendMod.ReplyFriend(int(req.LogId)) - if ReplyInfo == nil { - player.SendErrClienRes(&msg.ResFriendReplyHandle{ - Code: msg.RES_CODE_FAIL, - Msg: "reply info not exist", - }) - return fmt.Errorf("reply info not exist") - } - ErrType := msg.FRIEND_REPLY_HANDLE_ERR_TYPE_NONE - now := GoUtil.Now() - if req.Type == 1 && ReplyInfo.Uid > 10000 { - switch ReplyInfo.Type { - case friend.REPLY_TYPE_GREETING: - ReplyData := friend.ReplyInfo{ - Uid: int(player.M_DwUin), - Type: friend.REPLY_TYPE_GREETING_Get, - Param: req.Param, - } - FriendMgrSend(&MsqMod.Msg{ - From: int(player.M_DwUin), - To: int(ReplyInfo.Uid), - Type: MsqMod.HANDLE_TYPE_FRIEND_GREETING_REPLY, - SendT: now, - End: now + sevendays, - Extra: ReplyData, - }) - case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请 - GameId := GoUtil.Int(ReplyInfo.Param) - activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP)) - if activityInfo == nil { - break - } - err := player.SetCatnipPartner(GameId, ReplyInfo.Uid, activityInfo.EndT) - if err == nil { - CatnipMod := player.PlayMod.getCatnipMod() - ActivityId := player.GetActivityId(activity.ACT_TYPE_CATNIP) - UserList, _ := CatnipMod.Agree(GameId, ReplyInfo.Uid) - player.TeLog("catnip_agree", map[string]interface{}{ - "Id": int(GameId), - }) - FriendMgrSend(&MsqMod.Msg{ - From: int(player.M_DwUin), - To: int(ReplyInfo.Uid), - Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, - Extra: CatnipMsg{ - ActivityId: ActivityId, - GameId: int(GameId), - }, - SendT: now, - End: now + sevendays, - }) - - for _, v := range UserList { - FriendMgrSend(&MsqMod.Msg{ - From: int(player.M_DwUin), - To: int(v), - Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, - Extra: CatnipMsg{ - ActivityId: ActivityId, - GameId: int(GameId), - }, - SendT: now, - End: now + sevendays, - }) - } - player.CatnipBackData() - } else { - ErrType = msg.FRIEND_REPLY_HANDLE_ERR_TYPE_CATNIP - } - - } - } - Items := baseCfg.GetFriendReplyReward() - err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendReplyHandle.String()) - if err != nil { - player.SendErrClienRes(&msg.ResFriendReplyHandle{ - Code: msg.RES_CODE_FAIL, - Msg: err.Error(), - }) - return err - } - player.FriendLogBackData() - player.PushClientRes(&msg.ResFriendReplyHandle{ - Code: msg.RES_CODE_SUCCESS, - LogId: req.LogId, - Type: req.Type, - ErrType: ErrType, - }) - return nil -} - func ReqGetChessRetireReward(player *Player, buf []byte) error { req := &msg.ReqGetChessRetireReward{} err := proto.Unmarshal(buf, req) diff --git a/src/server/game/req_func_friend.go b/src/server/game/req_func_friend.go new file mode 100644 index 00000000..a62d3e41 --- /dev/null +++ b/src/server/game/req_func_friend.go @@ -0,0 +1,577 @@ +package game + +import ( + "fmt" + "server/conf" + baseCfg "server/conf/base" + friendCfg "server/conf/friend" + "server/db" + "server/game/mod/activity" + "server/game/mod/friend" + MsqMod "server/game/mod/msg" + GoUtil "server/game_util" + "server/msg" + "strconv" + + "google.golang.org/protobuf/proto" +) + +func ReqFriendRecommend(player *Player, buf []byte) error { + FriendMod := player.PlayMod.getFriendMod() + RecommendList := make([]*msg.ResPlayerSimple, 0) + FriendNum := FriendMod.GetFriendNum() + err := FriendMod.AddDailyRecommend() + if err != nil { + player.SendErrClienRes(&msg.ResFriendRecommend{}) + return err + } + var n int + if FriendNum < 10 { + n = 3 + } else { + Active := 0 + for k := range FriendMod.GetFriendList() { + PlayerSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(k) + if PlayerSimpleData == nil { + continue + } + if PlayerSimpleData.Login > GoUtil.Now()-86400 { + Active++ + } + } + n = max(0, 3-(Active/10)) + } + PlayerList := GetRecommendPlayer(player, n) + + for _, v := range PlayerList { + PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(v) + RecommendList = append(RecommendList, PlayerSimpleData) + } + player.PushClientRes(&msg.ResFriendRecommend{ + List: RecommendList, + }) + player.PlayMod.save() + return nil +} + +// 搜索用户 +func ReqSearchPlayer(player *Player, buf []byte) error { + req := &msg.ReqSearchPlayer{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + Uid, err := strconv.Atoi(req.Uid) + list := make([]*msg.ResPlayerSimple, 0) + if err == nil { + SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(Uid) + if SearchPlayer != nil && SearchPlayer.Level != 0 { + list = append(list, SearchPlayer) + } + } + data, err := db.SearchPlayer(req.Uid) + if err != nil { + player.SendErrClienRes(&msg.ResSearchPlayer{ + Code: 0, + }) + } + for _, v := range data { + if player.M_DwUin == v.DwUin { + continue + } + SearchPlayer := G_GameLogicPtr.GetResSimplePlayerByUid(int(v.DwUin)) + list = append(list, SearchPlayer) + + } + // list 列表去重 + l := make(map[int]*msg.ResPlayerSimple) + for _, v := range list { + if _, ok := l[int(v.Uid)]; !ok { + l[int(v.Uid)] = v + } + } + l2 := make([]*msg.ResPlayerSimple, 0) + for _, v := range l { + l2 = append(l2, v) + } + player.PushClientRes(&msg.ResSearchPlayer{ + List: l2, + }) + return nil +} + +// 申请好友 +func ReqApplyFriend(player *Player, buf []byte) error { + req := &msg.ReqApplyFriend{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + Uid := int(req.Uid) + FriendMod := player.PlayMod.getFriendMod() + if Uid == int(player.M_DwUin) { + player.SendErrClienRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Msg: "cannot apply yourself", + }) + return fmt.Errorf("cannot apply yourself") + } + if FriendMod.CheckFriend(Uid) { + player.SendErrClienRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Msg: "already friend", + }) + return fmt.Errorf("already friend") + } + // 好友人数到达上限(2000人)时,玩家将无法再发送好友申请 + if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { + player.SendErrClienRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Msg: "friend list full", + }) + return fmt.Errorf("friend list full") + } + // 对于任何玩家而言,向自己在24小时内已从任意途径发送过好友申请的玩家再次发送好友申请时,该次申请不会被发出 + sendApplyTime := FriendMod.GetSendApplyTime(Uid) + if sendApplyTime != 0 && GoUtil.Now()-sendApplyTime < 86400 { + player.PushClientRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Uid: req.Uid, + Msg: "already applied", + }) + return fmt.Errorf("already applied") + } + now := GoUtil.Now() + if req.Type == 1 { + Items, err := FriendMod.GetSponsorReward() + if err != nil { + player.SendErrClienRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + BaseMod := player.PlayMod.getBaseMod() + BaseMod.GetEnergyByAD() + err = player.HandleItem(Items, msg.ITEM_POP_LABEL_ApplyFriendSponsor.String()) + if err != nil { + player.SendErrClienRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + player.AddLog(int(req.Uid), friend.LOG_TYPE_FRIEND_SPONSOR, "", now) + FriendMgrSend(&MsqMod.Msg{ + Type: MsqMod.HANDLE_TYPE_FRIEND_SPONSOER, + From: int(player.M_DwUin), + To: Uid, + SendT: now, + End: now + sevendays, + }) + player.PushClientRes(BaseMod.BackData()) + player.TeLog("friend_invite_reward", map[string]interface{}{ + "item_list": Items, + }) + } + m := &MsqMod.Msg{ + Type: MsqMod.HANDLE_TYPE_APPLY, + From: int(player.M_DwUin), + To: Uid, + SendT: now, + End: now + sevendays, + Extra: map[string]interface{}{ + "type": req.Type, + }, + } + FriendMgrSend(m) + player.PushClientRes(&msg.ResApplyFriend{ + Code: msg.RES_CODE_SUCCESS, + Uid: req.Uid, + }) + return nil +} + +// 同意申请 +func ReqAgreeFriend(player *Player, buf []byte) error { + req := &msg.ReqAgreeFriend{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + Uid := int(req.Uid) + FriendMod := player.PlayMod.getFriendMod() + if !FriendMod.CheckApply(Uid) { + player.SendErrClienRes(&msg.ResAgreeFriend{ + Code: msg.RES_CODE_FAIL, + Msg: "apply uid not exist", + }) + return fmt.Errorf("apply uid not exist") + } + // 好友人数到达上限(2000人)时,玩家将无法再同意好友申请 + if FriendMod.GetFriendLen() >= friendCfg.GetFriendLimitNum() { + player.SendErrClienRes(&msg.ResAgreeFriend{ + Code: msg.RES_CODE_FAIL, + Msg: "friend list full", + }) + return fmt.Errorf("friend list full") + } + // 新好友才可以打招呼 + if !FriendMod.CheckAddBefore(Uid) { + FriendMod.AddReplyInfo(Uid, friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) + } + FriendMod.AddFriend(Uid) + player.PushClientRes(&msg.ResAgreeFriend{ + Code: msg.RES_CODE_SUCCESS, + Uid: req.Uid, + Player: G_GameLogicPtr.GetResSimplePlayerByUid(int(req.Uid)), + }) + player.TeLog("friend_add", map[string]interface{}{ + "player_id": Uid, + "add_type": "接受申请", + }) + player.AddLog(Uid, friend.LOG_TYPE_FRIEND_BECOME, "", GoUtil.Now()) + m := &MsqMod.Msg{ + Type: MsqMod.HADNLE_TYPE_AGREE, + From: int(player.M_DwUin), + To: Uid, + SendT: GoUtil.Now(), + } + FriendMgrSend(m) + player.FriendApplyBackData() + player.FriendLogBackData() + player.PlayMod.save() + return nil +} + +// 删除好友 +func ReqDelFriend(player *Player, buf []byte) error { + req := &msg.ReqDelFriend{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + Uid := int(req.Uid) + m := &MsqMod.Msg{ + Type: MsqMod.HANDLE_TYPE_DEL, + From: int(player.M_DwUin), + To: Uid, + SendT: GoUtil.Now(), + } + FriendMgrSend(m) + FriendMod := player.PlayMod.getFriendMod() + FriendMod.DelFriend(Uid) + player.PlayMod.save() + player.PushClientRes(&msg.ResDelFriend{ + Code: msg.RES_CODE_SUCCESS, + Uid: req.Uid, + }) + player.AddLog(Uid, friend.LOG_TYPE_FRIEND_DELETE, "", GoUtil.Now()) + player.FriendListBackData() + player.TeLog("friend_delete", map[string]interface{}{ + "player_id": Uid, + }) + return nil +} + +// 拒绝申请 +func ReqRefuseFriend(player *Player, buf []byte) error { + req := &msg.ReqRefuseFriend{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + Uid := int(req.Uid) + FriendMod := player.PlayMod.getFriendMod() + FriendMod.RefuseApply(Uid) + player.PlayMod.save() + player.PushClientRes(&msg.ResRefuseFriend{ + Code: msg.RES_CODE_SUCCESS, + Uid: req.Uid, + }) + now := GoUtil.Now() + m := &MsqMod.Msg{ + Type: MsqMod.HANDLE_TYPE_REFUSE, + From: int(player.M_DwUin), + To: Uid, + SendT: now, + End: now + 86400*7, + } + FriendMgrSend(m) + player.FriendApplyBackData() + return nil +} + +func ReqFriendList(player *Player, buf []byte) error { + player.FriendListBackData() + return nil +} + +func ReqFriendApply(player *Player, buf []byte) error { + player.FriendApplyBackData() + return nil +} + +func ReqFriendCardMsg(player *Player, buf []byte) error { + player.FriendCardBackData() + return nil +} + +func ReqFriendTimeLine(player *Player, buf []byte) error { + player.FriendLogBackData() + return nil +} + +func ReqFriendTLUpvote(player *Player, buf []byte) error { + req := &msg.ReqFriendTLUpvote{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + FriendMod := player.PlayMod.getFriendMod() + Items, FUid, err := FriendMod.Upvote(int(req.Id)) + if err != nil { + player.SendErrClienRes(&msg.ResFriendTLUpvote{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + err = player.HandleItem(Items, msg.ITEM_POP_LABEL_TLUpvote.String()) + if err != nil { + player.SendErrClienRes(&msg.ResFriendTLUpvote{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + now := GoUtil.Now() + // 添加时间线 + m := &MsqMod.Msg{ + Type: MsqMod.HANDLE_TYPE_HANDBOOK_UPVOTE, + From: int(player.M_DwUin), + To: int(FUid), + SendT: now, + End: now + sevendays, + } + FriendMod.AddActLog(friend.ACT_LOG_TYPE_VISIT_UPVOTE, "") + player.UpdateUserInfo() + FriendMgrSend(m) + player.PlayMod.save() + player.PushClientRes(&msg.ResFriendTLUpvote{ + Code: msg.RES_CODE_SUCCESS, + Id: req.Id, + }) + player.TeLog("friend_upvote", map[string]interface{}{ + "player_id": int(req.Id), + }) + return nil +} + +func ReqFriendTReward(player *Player, buf []byte) error { + req := &msg.ReqFriendTReward{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + FriendMod := player.PlayMod.getFriendMod() + Items, err := FriendMod.GetReward(int(req.Id)) + if err != nil { + player.SendErrClienRes(&msg.ResFriendTReward{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendTReward.String()) + if err != nil { + player.SendErrClienRes(&msg.ResFriendTReward{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + player.PlayMod.save() + player.PushClientRes(&msg.ResFriendTReward{ + Code: msg.RES_CODE_SUCCESS, + Id: req.Id, + }) + return nil +} + +func ReqFriendReplyHandle(player *Player, buf []byte) error { + req := &msg.ReqFriendReplyHandle{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + FriendMod := player.PlayMod.getFriendMod() + ReplyInfo := FriendMod.ReplyFriend(int(req.LogId)) + if ReplyInfo == nil { + player.SendErrClienRes(&msg.ResFriendReplyHandle{ + Code: msg.RES_CODE_FAIL, + Msg: "reply info not exist", + }) + return fmt.Errorf("reply info not exist") + } + ErrType := msg.FRIEND_REPLY_HANDLE_ERR_TYPE_NONE + now := GoUtil.Now() + if req.Type == 1 && ReplyInfo.Uid > 10000 { + switch ReplyInfo.Type { + case friend.REPLY_TYPE_GREETING: + ReplyData := friend.ReplyInfo{ + Uid: int(player.M_DwUin), + Type: friend.REPLY_TYPE_GREETING_Get, + Param: req.Param, + } + FriendMgrSend(&MsqMod.Msg{ + From: int(player.M_DwUin), + To: int(ReplyInfo.Uid), + Type: MsqMod.HANDLE_TYPE_FRIEND_GREETING_REPLY, + SendT: now, + End: now + sevendays, + Extra: ReplyData, + }) + case friend.REPLY_TYPE_CATNIP: // 猫草大作战同意邀请 + GameId := GoUtil.Int(ReplyInfo.Param) + activityInfo := player.GetActivityInfo(player.GetActivityId(activity.ACT_TYPE_CATNIP)) + if activityInfo == nil { + break + } + err := player.SetCatnipPartner(GameId, ReplyInfo.Uid, activityInfo.EndT) + if err == nil { + CatnipMod := player.PlayMod.getCatnipMod() + ActivityId := player.GetActivityId(activity.ACT_TYPE_CATNIP) + UserList, _ := CatnipMod.Agree(GameId, ReplyInfo.Uid) + player.TeLog("catnip_agree", map[string]interface{}{ + "Id": int(GameId), + }) + FriendMgrSend(&MsqMod.Msg{ + From: int(player.M_DwUin), + To: int(ReplyInfo.Uid), + Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, + Extra: CatnipMsg{ + ActivityId: ActivityId, + GameId: int(GameId), + }, + SendT: now, + End: now + sevendays, + }) + + for _, v := range UserList { + FriendMgrSend(&MsqMod.Msg{ + From: int(player.M_DwUin), + To: int(v), + Type: MsqMod.HANDLE_TYPE_CATNIP_AGREE, + Extra: CatnipMsg{ + ActivityId: ActivityId, + GameId: int(GameId), + }, + SendT: now, + End: now + sevendays, + }) + } + player.CatnipBackData() + } else { + ErrType = msg.FRIEND_REPLY_HANDLE_ERR_TYPE_CATNIP + } + + } + } + Items := baseCfg.GetFriendReplyReward() + err = player.HandleItem(Items, msg.ITEM_POP_LABEL_FriendReplyHandle.String()) + if err != nil { + player.SendErrClienRes(&msg.ResFriendReplyHandle{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + player.FriendLogBackData() + player.PushClientRes(&msg.ResFriendReplyHandle{ + Code: msg.RES_CODE_SUCCESS, + LogId: req.LogId, + Type: req.Type, + ErrType: ErrType, + }) + return nil +} + +func ReqFriendByCode(player *Player, buf []byte) error { + req := &msg.ReqFriendByCode{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + if req.Code == "" { + player.SendErrClienRes(&msg.ResFriendByCode{ + Code: msg.RES_CODE_FAIL, + Msg: "code is empty", + }) + return fmt.Errorf("code is empty") + } + CodeNum := GoUtil.ParseUniqueStringToInt(req.Code) + if CodeNum <= 0 { + player.SendErrClienRes(&msg.ResFriendByCode{ + Code: msg.RES_CODE_FAIL, + Msg: "code is invalid", + }) + return fmt.Errorf("code is invalid") + } + Uid := int64(CodeNum) + int64(100000) + int64(conf.Server.AppID*100000000) + if Uid == player.M_DwUin { + player.SendErrClienRes(&msg.ResFriendByCode{ + Code: msg.RES_CODE_FAIL, + Msg: "can not add yourself", + }) + return fmt.Errorf("can not add yourself") + } + + PlayerSimpleData := G_GameLogicPtr.GetResSimplePlayerByUid(int(Uid)) + if PlayerSimpleData == nil { + player.SendErrClienRes(&msg.ResFriendByCode{ + Code: msg.RES_CODE_FAIL, + Msg: "player not exist", + }) + return fmt.Errorf("player not exist") + } + player.PushClientRes(&msg.ResFriendByCode{ + Code: msg.RES_CODE_SUCCESS, + Player: PlayerSimpleData, + }) + return nil +} + +func ReqAddNpc(player *Player, buf []byte) error { + req := &msg.ReqAddNpc{} + err := proto.Unmarshal(buf, req) + if err != nil { + return err + } + FriendMod := player.PlayMod.getFriendMod() + err = FriendMod.SetNpc(int(req.NpcId)) + if err != nil { + player.SendErrClienRes(&msg.ResAddNpc{ + Code: msg.RES_CODE_FAIL, + Msg: err.Error(), + }) + return err + } + if len(FriendMod.Npc) == 1 { // 首次添加NPC 视为邀请好友成功 + InviteMod := player.PlayMod.getInviteMod() + InviteMod.AddInvite(int(req.NpcId)) + } + player.PlayMod.save() + player.FriendListBackData() + player.TeLog("add_npc", map[string]interface{}{ + "NpcId": int(req.NpcId), + }) + FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING, "", GoUtil.Now()+oneday, nil) + FriendMod.AddReplyInfo(int(req.NpcId), friend.REPLY_TYPE_GREETING_Get, "", GoUtil.Now()+oneday, nil) + player.AddLog(int(req.NpcId), friend.LOG_TYPE_FRIEND_BECOME_NPC, GoUtil.String(req.NpcId), GoUtil.Now()) + player.PushClientRes(&msg.ResAddNpc{ + Code: msg.RES_CODE_SUCCESS, + NpcId: req.NpcId, + }) + return nil +}