diff --git a/src/server/game/friend_func.go b/src/server/game/friend_func.go index 981b2ca2..ef54f240 100644 --- a/src/server/game/friend_func.go +++ b/src/server/game/friend_func.go @@ -115,7 +115,7 @@ func GetRecommendPlayer(p *Player, Num int) []int { if FriendMod.CheckSendApply(Uid) { continue } - if FriendMod.CheckFriend(Uid) { + if FriendMod.CheckAddBefore(Uid) { continue } PlayerSimpleData := G_GameLogicPtr.GetSimplePlayerByUid(Uid) @@ -124,15 +124,89 @@ func GetRecommendPlayer(p *Player, Num int) []int { } PlayerList1 = append(PlayerList1, Uid) } - if len(PlayerList1) == 0 { + // 排查7日内推荐过的用户 + now := GoUtil.Now() + candidateList := make([]int, 0) + for _, Uid := range PlayerList1 { + recommendTime := FriendMod.GetRecommendTime(Uid) + if recommendTime != 0 && recommendTime > now-604800 { + candidateList = append(candidateList, Uid) + continue + } + } + // 用户数不低于5则进入下一步筛选 + if len(candidateList) < 5 { + // 排查3日内推荐过的用户 + candidateList = make([]int, 0) + for _, Uid := range PlayerList1 { + recommendTime := FriendMod.GetRecommendTime(Uid) + if recommendTime != 0 && recommendTime > now-259200 { + candidateList = append(candidateList, Uid) + continue + } + } + } + // 用户数不低于5则进入下一步筛选 + if len(candidateList) < 5 { + // 排查2日内推荐过的用户 + candidateList = make([]int, 0) + for _, Uid := range PlayerList1 { + recommendTime := FriendMod.GetRecommendTime(Uid) + if recommendTime != 0 && recommendTime > now-172800 { + candidateList = append(candidateList, Uid) + continue + } + } + } + + if len(candidateList) == 0 { + candidateList = append(candidateList, PlayerList1...) + } + + if len(candidateList) == 0 { for _, Uid := range uids { if Uid == int(p.M_DwUin) { continue } - PlayerList1 = append(PlayerList1, Uid) + candidateList = append(candidateList, Uid) } } - return GoUtil.RandSliceNum(PlayerList1, Num) + baseList := make([]*PlayerSimpleData, 0, len(candidateList)) + for _, uid := range candidateList { + ps := G_GameLogicPtr.GetSimplePlayerByUid(uid) + if ps != nil { + baseList = append(baseList, ps) + } + } + BaseMod := p.PlayMod.getBaseMod() + level := BaseMod.GetLevel() + diffLimit := 10 + filtered := make([]int, 0, len(baseList)) + for { + filtered = filtered[:0] + for _, ps := range baseList { + if ps == nil { + continue + } + diff := level - ps.Level + if diff < 0 { + diff = -diff + } + if diff <= diffLimit { + filtered = append(filtered, ps.Uid) + } + } + if len(filtered) >= 5 || len(baseList) == 0 { + break + } + diffLimit++ + } + candidateList = filtered + recommendList := GoUtil.RandSliceNum(candidateList, Num) + for _, Uid := range recommendList { + FriendMod.AddRecommend(Uid) + } + return recommendList } func GetUidByFaceBook(Fb string) (int, error) { diff --git a/src/server/game/message_mgr.go b/src/server/game/message_mgr.go index 27d8df7a..94cd3be1 100644 --- a/src/server/game/message_mgr.go +++ b/src/server/game/message_mgr.go @@ -314,7 +314,7 @@ func PlayerLoginHandler(data *msg.Msg) (interface{}, error) { ReplyPlayerMsgASync(data, nil) // 在锁外发送离线消息 for _, message := range messagesToSend { - message.H = msg.MSG_TYPE_ONLINE // 标记为在线消息 + message.H = msg.MSG_TYPE_OFFLINE // 标记为离线消息 SendMsgToNodeAsync(message, node) } SendMsgToNodeAsync(&msg.Msg{ @@ -836,6 +836,9 @@ func SendPlayerMsgSync(m *msg.Msg) (interface{}, error) { } func FriendMgrSend(m1 *msg.Msg) error { + if m1.SendT == 0 { + m1.SendT = GoUtil.Now() + } SendPlayerMsgAsync(m1) return nil } @@ -899,6 +902,13 @@ func saveMessage(m *msg.Msg) error { } // 添加消息 messages.Messages = append(messages.Messages, m) + // 添加消息 + messages.Messages = append(messages.Messages, m) + // 设置上限为2000条,超过则丢弃最早的消息 + if len(messages.Messages) > 2000 { + excess := len(messages.Messages) - 2000 + messages.Messages = messages.Messages[excess:] + } return nil } diff --git a/src/server/game/mod/friend/Friend.go b/src/server/game/mod/friend/Friend.go index f251e99b..16919e4a 100644 --- a/src/server/game/mod/friend/Friend.go +++ b/src/server/game/mod/friend/Friend.go @@ -25,6 +25,13 @@ type FriendMod struct { ActivityLog []*ActLogInfo // 活动日志 ReplyList []*ReplyInfo // 好友回复列表 DailySponsor int // 好友赞助次数 + RecommendList map[int]*Recommend + DailyGetApply int // 每日获得申请次数 +} + +type Recommend struct { + Uid int + Time int64 } type ReplyInfo struct { @@ -206,10 +213,14 @@ func (f *FriendMod) InitData() { } } } + if f.RecommendList == nil { + f.RecommendList = make(map[int]*Recommend) + } } func (f *FriendMod) ZeroUpdate() { f.DailySponsor = f.GetDailySponsorLimit() + f.DailyGetApply = 0 } func (f *FriendMod) GetNpc() []int { @@ -310,6 +321,10 @@ func (f *FriendMod) CheckFriend(Uid int) bool { return f.NewFriendList[Uid].DelTime == 0 } +func (f *FriendMod) GetFriendLen() int { + return len(f.GetFriendList()) +} + func (f *FriendMod) RefuseApply(id int) { delete(f.ApplyList, id) delete(f.SendApply, id) @@ -355,19 +370,16 @@ func (f *FriendMod) CheckAddBefore(uid int) bool { // 收到申请 func (f *FriendMod) AddFriendApply(Uid int) bool { - ok := f.CheckApply(Uid) - if ok { - return ok + if f.DailyGetApply >= 30 { + return true } f.ApplyList[Uid] = GoUtil.Now() + f.DailyGetApply++ return false } // 发送申请 func (f *FriendMod) AddSendApply(Uid int) bool { - if _, ok := f.SendApply[Uid]; ok { - return true - } f.SendApply[Uid] = GoUtil.Now() return false } @@ -377,6 +389,13 @@ func (f *FriendMod) CheckSendApply(Id int) bool { return ok } +func (f *FriendMod) GetSendApplyTime(Id int) int64 { + if t, ok := f.SendApply[Id]; ok { + return t + } + return 0 +} + func (f *FriendMod) AgreeApply(UId int) { f.AddFriend(UId) delete(f.SendApply, UId) @@ -590,3 +609,23 @@ func (f *FriendMod) GetSponsorReward() ([]*item.Item, error) { f.DailySponsor-- return []*item.Item{item.NewItem(item.ITEM_ENERGY_ID, 25)}, nil } + +func (f *FriendMod) AddRecommend(Uid int) { + for _, v := range f.RecommendList { + if v.Uid == Uid { + v.Time = GoUtil.Now() + return + } + } + f.RecommendList[Uid] = &Recommend{ + Uid: Uid, + Time: GoUtil.Now(), + } +} + +func (f *FriendMod) GetRecommendTime(uid int) int64 { + if recommend, ok := f.RecommendList[uid]; ok { + return recommend.Time + } + return 0 +} diff --git a/src/server/game/rank_mgr.go b/src/server/game/rank_mgr.go index 7484a13c..ed969059 100644 --- a/src/server/game/rank_mgr.go +++ b/src/server/game/rank_mgr.go @@ -8,7 +8,6 @@ import ( GoUtil "server/game_util" "sort" "strconv" - "sync" ) const ( @@ -19,8 +18,6 @@ type RankMgr struct { *ServerMod } -var mu sync.Mutex - type RankData struct { List map[int][]*Rank // 玩家排行榜 Champship map[int][]*Rank // 锦标赛排行榜 diff --git a/src/server/game/register_network_func.go b/src/server/game/register_network_func.go index 9cce5ad1..fc859fce 100644 --- a/src/server/game/register_network_func.go +++ b/src/server/game/register_network_func.go @@ -1860,13 +1860,24 @@ func ReqApplyFriend(player *Player, buf []byte) error { }) return fmt.Errorf("already friend") } - // if FriendMod.AddSendApply(Uid) { - // player.SendErrClienRes(&msg.ResApplyFriend{ - // Code: msg.RES_CODE_FAIL, - // Msg: "already apply", - // }) - // return fmt.Errorf("already apply") - // } + // 好友人数到达上限(2000人)时,玩家将无法再发送好友申请 + if FriendMod.GetFriendLen() >= 2000 { + 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") + } if req.Type == 1 { Items, err := FriendMod.GetSponsorReward() if err != nil { @@ -1928,7 +1939,14 @@ func ReqAgreeFriend(player *Player, buf []byte) error { }) return fmt.Errorf("apply uid not exist") } - + // 好友人数到达上限(2000人)时,玩家将无法再同意好友申请 + if FriendMod.GetFriendLen() >= 2000 { + 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()+24*3600, nil)