package service_base import ( "app/internal/message" "app/internal/msg_inner" "app/internal/service" "encoding/binary" "google.golang.org/protobuf/proto" ) // 所有与客户端通信的actor,需要在本机注册角色的当前状态、注册gate等信息 func NewVirtualUserManager() IVirtualUserManager { return &VirtualUserManager{ userMap: make(map[int64]*VirtualUser), } } type UserMsgRawFunc func(*msg_inner.VirtualUserMessage) type UserMsgFunc func(rid int64, data interface{}) (message.MSG_RESULT, proto.Message) type UserStatusFunc func(rid int64) var _ IVirtualUserManager = (*VirtualUserManager)(nil) //interface实现检查 type IVirtualUserManager interface { Init(serviceBase IServiceBase) IVirtualUserManager Send2User(rid int64, msg interface{}) BroadCast2User(sid int32, msg interface{}) GroupCast2User(ridList []int64, msg interface{}) RegistUserMsg(msg interface{}, f UserMsgFunc) RegistUserMsgRaw(f UserMsgRawFunc) RegistUserOnline(f UserStatusFunc) RegistUserOffline(f UserStatusFunc) } type VirtualUserManager struct { serviceBase IServiceBase userMap map[int64]*VirtualUser //rid->user msgHandler *VirtualUserHandler //user消息处理 msgRawHandler UserMsgRawFunc //user未解析消息处理 userStatusOnline UserStatusFunc //user上线消息 userStatusOffline UserStatusFunc //user离线消息 } type VirtualUser struct { serviceBase IServiceBase RID int64 GID int32 } func (s *VirtualUserManager) Init(serviceBase IServiceBase) IVirtualUserManager { s.serviceBase = serviceBase s.msgHandler = NewVirtualUserHandler(s) s.initAPI() return s } func (s *VirtualUserManager) BroadCast2User(sid int32, msg interface{}) { if data := s.getMessageData(msg); data != nil { s.serviceBase.Actor().Broadcast(service.Gate, &msg_inner.BroadCast2VirtualUser{ SID: sid, Data: data, }) } } func (s *VirtualUserManager) GroupCast2User(ridList []int64, msg interface{}) { groupCastMap := make(map[int32][]int64) //sid->ridList if data := s.getMessageData(msg); data != nil { for _, rid := range ridList { if user, ok := s.userMap[rid]; ok { groupCastMap[user.GID] = append(groupCastMap[user.GID], rid) } } for gid, rids := range groupCastMap { s.serviceBase.Actor().Send(service.GateId(gid), &msg_inner.GroupCast2VirtualUser{ RIDList: rids, Data: data, }) } } } func (s *VirtualUserManager) Send2User(rid int64, msg interface{}) { if user, ok := s.userMap[rid]; ok { if data := s.getMessageData(msg); data != nil { s.serviceBase.Actor().Send(service.GateId(user.GID), &msg_inner.Send2VirtualUser{ RID: user.RID, Data: data, }) } } } func (s *VirtualUserManager) RegistUserMsg(msg interface{}, f UserMsgFunc) { s.msgHandler.RegistMsg(msg, f) } func (s *VirtualUserManager) RegistUserMsgRaw(f UserMsgRawFunc) { s.msgRawHandler = f } func (s *VirtualUserManager) RegistUserOnline(f UserStatusFunc) { s.userStatusOnline = f } func (s *VirtualUserManager) RegistUserOffline(f UserStatusFunc) { s.userStatusOffline = f } func (s *VirtualUserManager) getMessageData(msg interface{}) []byte { if message, ok := msg.(proto.Message); ok { if msgId, ok2 := s.serviceBase.Parser().MsgToId(message); ok2 { if payload, err := proto.Marshal(message); err == nil { data := make([]byte, 6+len(payload)) binary.BigEndian.PutUint32(data, uint32(len(payload)+6)) binary.BigEndian.PutUint16(data[4:], uint16(msgId)) copy(data[6:], payload) return data } } } return nil } func (s *VirtualUserManager) onUserMessage(mgsId int32, rid int64, msg interface{}) { s.msgHandler.HandleMessage(mgsId, rid, msg) }