You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.6 KiB
Go

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)
}