| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- package chat
- import (
- actorRemote "f1-game/internal/actor_remote"
- "f1-game/internal/code"
- "f1-game/internal/component/redis"
- "f1-game/internal/enum"
- nameActor "f1-game/internal/name/actor"
- nameRedis "f1-game/internal/name/redis"
- nameRemote "f1-game/internal/name/remote"
- nameRoute "f1-game/internal/name/route"
- "f1-game/internal/pb"
- "f1-game/internal/types"
- cherrySlice "github.com/cherry-game/cherry/extend/slice"
- ctime "github.com/cherry-game/cherry/extend/time"
- clog "github.com/cherry-game/cherry/logger"
- )
- type (
- actorGroup struct {
- RoomTypeList
- }
- )
- func NewActorGroup() *actorGroup {
- return &actorGroup{
- RoomTypeList: newRoomTypeList(enum.ChatType_Group),
- }
- }
- func (p *actorGroup) OnInit() {
- p.Remote().Register(nameRemote.Chat_GroupJoin, p.groupJoin)
- p.Remote().Register(nameRemote.Chat_GroupQuit, p.groupQuit)
- p.Remote().Register(nameRemote.Chat_GroupPlayerChange, p.groupPlayerChange)
- p.Remote().Register(nameRemote.Chat_Send, p.send)
- p.Remote().Register(nameRemote.Chat_Push, p.Push)
- p.Remote().Register(nameRemote.Chat_Destory, p.destory)
- p.Remote().Register(nameRemote.Chat_DelMsg, p.DelMsg)
- p.initCleanRoomTimer()
- }
- func (p *actorGroup) AliasID() string {
- return nameActor.Chat_Group
- }
- // 在列表同意加入群组
- func (p *actorGroup) groupJoin(req *pb.I64I64) int32 {
- var (
- chatID = req.Key
- playerID = req.Value
- )
- memberCount := redis.Chat.GetGroupMemberCount(chatID)
- if memberCount == 0 {
- // 群组解散没有成员了
- return code.ChatGroupNotFound
- }
- // 群组满员了
- if p.playerLimit > 0 && memberCount >= p.playerLimit {
- return code.ChatGroupMemberLimit
- }
- chatRoom := p.GetChatRoom(chatID)
- p.flushPlayerIDList(chatRoom)
- chatRoom.PlayerIDList.Add(playerID)
- redis.Chat.AddGroupMember(chatID, playerID)
- return code.OK
- }
- // 主动退出群组
- func (p *actorGroup) groupQuit(req *pb.I64I64) {
- var (
- chatID = req.Key
- playerID = req.Value
- chatRoom = p.GetChatRoom(chatID)
- )
- // 直接清理,下次会从redis中重新加载
- chatRoom.PlayerIDList.Clear()
- redis.Chat.DelGroupMember(chatID, playerID)
- }
- func (p *actorGroup) send(req *pb.ChatMsgList) {
- chatRoom := p.GetChatRoom(req.ChatID)
- p.flushPlayerIDList(chatRoom)
- p.AddChatMsg(req)
- // 通知该群成员有人发言
- p.Broadcast2Client(chatRoom, nameRoute.PushChat_MsgList, req)
- // update last send time
- chatRoom.LastSendTime = ctime.Now()
- }
- // 群组成员只有为空的时候从redis中加载
- func (p *actorGroup) flushPlayerIDList(chatRoom *ChatRoom) {
- if chatRoom.LastSendTime.NowDiffSecond() < 1 {
- return
- }
- if members, found := redis.Chat.GetGroupMembers(chatRoom.ChatID); found {
- chatRoom.PlayerIDList = types.NewList(members...)
- }
- }
- func (p *actorGroup) destory(req *pb.I64) {
- memberList, found := redis.Chat.GetGroupMembers(req.Value)
- if !found {
- return
- }
- if len(memberList) > 0 {
- rsp := &pb.I64Bool{
- Key: req.Value,
- Value: true,
- }
- // 通知所有成员销毁群组
- playerDataMap := redis.Game.GetPlayerDataMap(memberList, nameRedis.PlayerGameNodeFields...)
- for _, memberID := range memberList {
- playerData, found := playerDataMap[memberID]
- if !found {
- clog.Warnf("destory get playerData is nil, chatId: %d, memberID: %d", req.Value, memberID)
- continue
- }
- actorRemote.GamePlayer.Call(playerData.GameNodeID, playerData.PlayerID, nameRemote.Player_ChatGroupMemberRemove, rsp)
- }
- // 删除redis中的群组成员
- redis.Chat.DelAllGroupMembers(req.Value)
- }
- p.Destory(req)
- }
- // 群组玩家变更
- func (p *actorGroup) groupPlayerChange(req *pb.ChatGroupPlayerChange) {
- var (
- removeList []int64 // 移除的成员
- inviteList []int64 // 邀请的成员
- allIDList []int64 // 所有需要查询的成员ID列表
- )
- memberList, _ := redis.Chat.GetGroupMembers(req.ChatID)
- // 不在原成员列表中的PlayerID则发出邀请
- for _, playerID := range req.PlayerIDList {
- if _, ok := cherrySlice.Int64In(playerID, memberList); !ok {
- inviteList = append(inviteList, playerID)
- }
- }
- // 原成员列表的PlayerID在新成员列表中找不到的则移除
- for _, oldPlayerID := range memberList {
- // 过滤群组创建者
- if oldPlayerID == req.OwnerPlayerID {
- continue
- }
- if _, ok := cherrySlice.Int64In(oldPlayerID, req.PlayerIDList); !ok {
- removeList = append(removeList, oldPlayerID)
- }
- }
- // 所有需要查询的成员ID列表:邀请人,移除的人,群主
- allIDList = append(allIDList, inviteList...)
- allIDList = append(allIDList, removeList...)
- allIDList = append(allIDList, req.OwnerPlayerID)
- // 一次性把需要查询成员数据都查出来
- chatPlayerMap := redis.Game.GetChatPlayerMap(allIDList...)
- if chatPlayerMap == nil {
- clog.Warnf("groupPlayerChange GetPlayerDataMap is nil, allIDList len: %v", len(allIDList))
- return
- }
- // 发起邀请
- p.inviteSend(req.ChatID, req.Name, req.OwnerPlayerID, inviteList, chatPlayerMap)
- // 移除成员
- p.playerRemoveSend(req.ChatID, removeList, chatPlayerMap)
- }
- // 发起群组邀请
- func (p *actorGroup) inviteSend(chatID int64, name string, ownerPlayerID int64, invitePlayerIDList []int64, chatPlayerMap map[int64]*pb.ChatPlayer) {
- if len(invitePlayerIDList) < 1 {
- return
- }
- inviteReq := &pb.GroupInvite{
- ChatID: chatID,
- Name: name,
- InvitePlayer: chatPlayerMap[ownerPlayerID],
- }
- for _, invitePlayerID := range invitePlayerIDList {
- playerData, found := chatPlayerMap[invitePlayerID]
- if !found {
- clog.Warnf("inviteSend playerData is nil, chatID: %d, invitePlayerID: %d", chatID, invitePlayerID)
- continue
- }
- actorRemote.GamePlayer.Call(playerData.GameNodeID, playerData.PlayerID, nameRemote.Player_ChatGroupInvite, inviteReq)
- }
- }
- // 发起踢出群组聊天的成员
- func (p *actorGroup) playerRemoveSend(chatID int64, removePlayerIDList []int64, chatPlayerMap map[int64]*pb.ChatPlayer) {
- if len(removePlayerIDList) < 1 {
- return
- }
- rsp := &pb.I64Bool{
- Key: chatID,
- Value: false,
- }
- for _, removePlayerID := range removePlayerIDList {
- chatPlayer, found := chatPlayerMap[removePlayerID]
- if !found {
- clog.Warnf("playerRemoveSend chatPlayer is nil, chatID: %d, removePlayerID: %d", chatID, removePlayerID)
- continue
- }
- actorRemote.GamePlayer.Call(chatPlayer.GameNodeID, chatPlayer.PlayerID, nameRemote.Player_ChatGroupMemberRemove, rsp)
- }
- redis.Chat.DelGroupMember(chatID, removePlayerIDList...)
- chatRoom := p.GetChatRoom(chatID)
- // 清理成员缓存,下次从redis重新拉取新的
- chatRoom.PlayerIDList.Clear()
- }
|