color game

This commit is contained in:
liuxiaobo 2025-06-07 11:57:56 +08:00
parent a213ea01b9
commit 5db1090d7d
8 changed files with 125 additions and 224 deletions

View File

@ -3,7 +3,10 @@ package baseroom
import ( import (
"fmt" "fmt"
"game/common/proto/pb" "game/common/proto/pb"
"github.com/fox/fox/ipb"
"github.com/fox/fox/log" "github.com/fox/fox/log"
"github.com/fox/fox/processor"
"github.com/fox/fox/service"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"time" "time"
) )
@ -14,23 +17,23 @@ type BaseRoom[Seat ISeat] struct {
playType int // 玩法配置id color玩法id playType int // 玩法配置id color玩法id
gameNo string gameNo string
Seats []Seat Seats []Seat
timeTypes map[TimerType]uint32 processor *processor.Processor
timeProcessor *processor.Processor
subRoom IRoom timeTypes map[TimerType]uint32
sTimer ITimer srv service.IService
sender ISender
} }
func NewBaseRoom[Seat ISeat](id, roomType, playType int, subRoom IRoom, sTimer ITimer, sender ISender) (*BaseRoom[Seat], pb.ErrCode) { func NewBaseRoom[Seat ISeat](id, roomType, playType int, srv service.IService) (*BaseRoom[Seat], pb.ErrCode) {
room := &BaseRoom[Seat]{ room := &BaseRoom[Seat]{
id: id, id: id,
roomType: roomType, roomType: roomType,
playType: playType, playType: playType,
gameNo: "", gameNo: "",
timeTypes: make(map[TimerType]uint32), timeTypes: make(map[TimerType]uint32),
subRoom: subRoom, srv: srv,
sTimer: sTimer, processor: processor.NewProcessor(),
sender: sender, timeProcessor: processor.NewProcessor(),
} }
return room, pb.ErrCode_OK return room, pb.ErrCode_OK
@ -44,10 +47,6 @@ func (r *BaseRoom[Seat]) RoomType() int {
return r.roomType return r.roomType
} }
func (r *BaseRoom[Seat]) SetTruthRoom(rm IRoom) {
r.subRoom = rm
}
func (r *BaseRoom[Seat]) PlayType() int { func (r *BaseRoom[Seat]) PlayType() int {
return r.playType return r.playType
} }
@ -121,14 +120,6 @@ func (r *BaseRoom[Seat]) RemovePlayer(player IPlayer) {
} }
} }
func (r *BaseRoom[Seat]) OnMessage(cmd int32, params ...any) {
if r.subRoom == nil {
log.Error(r.Log("sub room is nil"))
return
}
r.subRoom.OnMessage(cmd, params...)
}
func (r *BaseRoom[Seat]) DebugSendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) { func (r *BaseRoom[Seat]) DebugSendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
log.Debug(r.UserLog(user.Id(), "send msg:%v %v", msgId, msg.String())) log.Debug(r.UserLog(user.Id(), "send msg:%v %v", msgId, msg.String()))
} }
@ -140,7 +131,8 @@ func (r *BaseRoom[Seat]) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message
} else { } else {
for _, seat := range r.Seats { for _, seat := range r.Seats {
if !seat.Empty() && seat.Player().Id() == user.Id() { if !seat.Empty() && seat.Player().Id() == user.Id() {
r.sender.SendMsg(user, msgId, msg) iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg)
_ = r.srv.Send(user.GateTopicName(), iMsg)
break break
} }
} }
@ -165,11 +157,7 @@ func (r *BaseRoom[Seat]) Broadcast(msgId pb.MsgId, msg proto.Message, exclude ..
} }
} }
func (r *BaseRoom[Seat]) NewTimer(timerType TimerType, duration time.Duration, args ...interface{}) { func (r *BaseRoom[Seat]) NewTimer(timerType TimerType, duration time.Duration, args ...any) {
if r.sTimer == nil {
log.Error(r.Log("timer handler is nil"))
return
}
if _, ok := r.timeTypes[timerType]; ok { if _, ok := r.timeTypes[timerType]; ok {
log.Error(r.Log("timer type:%v is exist.can not new timer", timerType.String())) log.Error(r.Log("timer type:%v is exist.can not new timer", timerType.String()))
// if timerType == TtPlayerAct { // if timerType == TtPlayerAct {
@ -177,8 +165,10 @@ func (r *BaseRoom[Seat]) NewTimer(timerType TimerType, duration time.Duration, a
// } // }
return return
} }
tid := r.sTimer.NewTimer(duration+time.Duration(10)*time.Millisecond, func() { tid := r.srv.NewTimer(duration+time.Duration(10)*time.Millisecond, func() {
r.sTimer.OnTimer(timerType, args...) if err := r.timeProcessor.Dispatch(int32(timerType), args...); err != nil {
log.ErrorF(r.Log("timer dispatch err:%v", err))
}
}, true, r.Log("start type:%v timer", timerType.String())) }, true, r.Log("start type:%v timer", timerType.String()))
r.timeTypes[timerType] = tid r.timeTypes[timerType] = tid
// log.Debug(r.Log("start type:%v timer", timerType.String())) // log.Debug(r.Log("start type:%v timer", timerType.String()))
@ -186,7 +176,7 @@ func (r *BaseRoom[Seat]) NewTimer(timerType TimerType, duration time.Duration, a
func (r *BaseRoom[Seat]) CancelTimer(timerType TimerType) { func (r *BaseRoom[Seat]) CancelTimer(timerType TimerType) {
if tid, ok := r.timeTypes[timerType]; ok { if tid, ok := r.timeTypes[timerType]; ok {
r.sTimer.CancelTimer(tid) r.srv.CancelTimer(tid)
delete(r.timeTypes, timerType) delete(r.timeTypes, timerType)
// log.Debug(r.Log("stop type:%v timer, rest timer:%+v", timerType.String(), r.timeTypes)) // log.Debug(r.Log("stop type:%v timer, rest timer:%+v", timerType.String(), r.timeTypes))
} }
@ -194,7 +184,7 @@ func (r *BaseRoom[Seat]) CancelTimer(timerType TimerType) {
func (r *BaseRoom[Seat]) CancelAllTimer() { func (r *BaseRoom[Seat]) CancelAllTimer() {
for _, tid := range r.timeTypes { for _, tid := range r.timeTypes {
r.sTimer.CancelTimer(tid) r.srv.CancelTimer(tid)
// log.Debug(r.Log("start type:%v timer", timerType.String())) // log.Debug(r.Log("start type:%v timer", timerType.String()))
} }
r.timeTypes = make(map[TimerType]uint32) r.timeTypes = make(map[TimerType]uint32)
@ -233,12 +223,34 @@ func (r *BaseRoom[Seat]) UserLog(uid int64, format string, a ...any) string {
} }
} }
// 玩家俱乐部房间玩游戏 func (r *BaseRoom[Seat]) Unmarshal(cmd int32, data []byte) (any, error) {
func (r *BaseRoom[Seat]) GameStart() { return r.processor.Unmarshal(cmd, data)
} }
// 玩家俱乐部房间玩游戏 func (r *BaseRoom[Seat]) Dispatch(user IPlayer, cmd int32, params ...any) error {
func (r *BaseRoom[Seat]) GameEnd() { inp := make([]any, len(params)+1)
inp = append(inp, user)
inp = append(inp, params...)
return r.processor.Dispatch(cmd, inp...)
}
func (r *BaseRoom[Seat]) RegisterMessages(metas processor.RegisterMetas) {
r.processor.RegisterMessages(metas)
}
func (r *BaseRoom[Seat]) timerDispatch(user IPlayer, cmd int32, params ...any) error {
inp := make([]any, len(params)+1)
inp = append(inp, user)
inp = append(inp, params...)
return r.timeProcessor.Dispatch(cmd, inp...)
}
// 注册时间事件及处理
func (r *BaseRoom[Seat]) RegisterTimerMessages(metas processor.RegisterMetas) {
r.timeProcessor.RegisterMessages(metas)
}
// 初始化房间
func (r *BaseRoom[Seat]) OnInit() {
} }

View File

@ -2,18 +2,18 @@ package baseroom
import ( import (
"game/common/proto/pb" "game/common/proto/pb"
"github.com/golang/protobuf/proto"
"time"
) )
type IRoom interface { type IRoom interface {
Id() int Id() int
RoomType() int // 房间配置id RoomType() int // 房间配置id
PlayType() int PlayType() int
OnInit()
// SeatPlayerNum() int // SeatPlayerNum() int
// HasEmptySeat() bool // HasEmptySeat() bool
// HasPlayer(uid int64) bool // HasPlayer(uid int64) bool
OnMessage(cmd int32, params ...any) Unmarshal(cmd int32, data []byte) (any, error)
Dispatch(user IPlayer, cmd int32, params ...any) error
// ReleaseRoom() // ReleaseRoom()
} }
@ -29,22 +29,14 @@ type ISeat interface {
type IPlayer interface { type IPlayer interface {
Id() int64 Id() int64
Robot() IRobot Robot() IRobot
GateTopicName() string
RoomId() int
} }
type IRobot interface { type IRobot interface {
OnMessage(cmd pb.MsgId, params ...any) OnMessage(cmd pb.MsgId, params ...any)
} }
type ITimer interface {
OnTimer(timerType TimerType, args ...interface{})
NewTimer(duration time.Duration, cb func(), needLog bool, desc ...string) uint32
CancelTimer(timerId uint32)
}
type ISender interface {
SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message)
}
type ICreateRoom interface { type ICreateRoom interface {
CreateRoom(id, roomType int) (IRoom, pb.ErrCode) CreateRoom(id, roomType int) (IRoom, pb.ErrCode)
} }

View File

@ -8,6 +8,7 @@ import (
"game/common/utils" "game/common/utils"
"github.com/fox/fox/etcd" "github.com/fox/fox/etcd"
"github.com/fox/fox/log" "github.com/fox/fox/log"
"github.com/fox/fox/service"
"github.com/fox/fox/xrand" "github.com/fox/fox/xrand"
"github.com/go-redis/redis/v8" "github.com/go-redis/redis/v8"
"time" "time"
@ -113,7 +114,7 @@ func (m *UserBindService) RandServiceNode(typeId pb.ServiceTypeId) (*etcd.Servic
} }
// 根据服务类型,路由到对应的服务节点 // 根据服务类型,路由到对应的服务节点
func (m *UserBindService) FindServiceName(userId int64, typeId pb.ServiceTypeId) (string, error) { func (m *UserBindService) findServiceName(userId int64, typeId pb.ServiceTypeId) (string, error) {
if userId > 0 { if userId > 0 {
// 向redis中查询。redis中保留的服务节点不一定是可用的还需要向etcd中验证 // 向redis中查询。redis中保留的服务节点不一定是可用的还需要向etcd中验证
sName := m.LoadFromRedis(userId, typeId) sName := m.LoadFromRedis(userId, typeId)
@ -134,3 +135,16 @@ func (m *UserBindService) FindServiceName(userId int64, typeId pb.ServiceTypeId)
m.rdb.Set(context.Background(), m.makeRedisKey(userId, typeId), node.Name, 2*24*time.Hour) m.rdb.Set(context.Background(), m.makeRedisKey(userId, typeId), node.Name, 2*24*time.Hour)
return node.Name, nil return node.Name, nil
} }
/*
查找topic,根据serviceTypeId以及玩家id查找玩家过往访问该服务的节点优先使用原节点
*/
func (m *UserBindService) FindTopic(userId int64, serviceTypeId pb.ServiceTypeId) (topic, sName string) {
var err error
if sName, err = m.findServiceName(userId, serviceTypeId); err == nil {
return service.TopicEx(sName), sName
} else {
log.Error(err.Error())
}
return "", sName
}

View File

@ -18,12 +18,11 @@ func (s *ChatService) initProcessor() {
func (s *ChatService) onChat(uid int64, msg *pb.C2SChat) { func (s *ChatService) onChat(uid int64, msg *pb.C2SChat) {
switch msg.Type { switch msg.Type {
case pb.ChatType_CT_Private: case pb.ChatType_CT_Private:
sName, err := s.bindService.FindServiceName(msg.DstUser.UserId, pb.ServiceTypeId_STI_Gate) tName, _ := s.bindService.FindTopic(msg.DstUser.UserId, pb.ServiceTypeId_STI_Gate)
if err != nil { if tName == "" {
log.DebugF("find user:%v in gate err: %v", uid, err) log.DebugF("user:%v find gate failed", uid)
return
} }
s.SendServiceMsg(service.TopicEx(sName), msg.DstUser.UserId, int32(pb.MsgId_S2CChatId), msg) s.SendServiceMsg(service.TopicEx(tName), msg.DstUser.UserId, int32(pb.MsgId_S2CChatId), msg)
default: default:
s.SendServiceMsg(service.TopicEx(topicName.WorldMessage), uid, int32(pb.MsgId_S2CChatId), msg) s.SendServiceMsg(service.TopicEx(topicName.WorldMessage), uid, int32(pb.MsgId_S2CChatId), msg)
} }

View File

@ -4,19 +4,26 @@ import (
"game/common/baseroom" "game/common/baseroom"
"game/common/proto/pb" "game/common/proto/pb"
"github.com/fox/fox/log" "github.com/fox/fox/log"
"github.com/fox/fox/service"
) )
type ColorRoom struct { type ColorRoom struct {
*baseroom.BaseRoom[ColorSeat] *baseroom.BaseRoom[ColorSeat]
} }
func newColorRoom(id, roomType int) (baseroom.IRoom, pb.ErrCode) { func newColorRoom(id, roomType int, srv service.IService) (baseroom.IRoom, pb.ErrCode) {
rm := &ColorRoom{} rm := &ColorRoom{}
playType := 0 playType := 0
code := pb.ErrCode_OK code := pb.ErrCode_OK
rm.BaseRoom, code = baseroom.NewBaseRoom[ColorSeat](id, roomType, playType, rm, rm, rm) rm.BaseRoom, code = baseroom.NewBaseRoom[ColorSeat](id, roomType, playType, srv)
if code != pb.ErrCode_OK { if code != pb.ErrCode_OK {
log.ErrorF("new color room err code:%v", code) log.ErrorF("new color room err code:%v", code)
return nil, code
} }
rm.OnInit()
return rm, code return rm, code
} }
func (rm *ColorRoom) OnInit() {
return
}

View File

@ -1,156 +1,15 @@
package server package server
import ( import (
"encoding/json"
"game/common/model/user"
"game/common/proto/pb"
"game/common/rpcName"
"game/common/utils"
"github.com/fox/fox/etcd"
"github.com/fox/fox/ipb"
"github.com/fox/fox/ksync"
"github.com/fox/fox/log"
"github.com/fox/fox/processor" "github.com/fox/fox/processor"
"github.com/fox/fox/service"
"time"
) )
const ( const (
timeout = time.Second * 30 // timeout = time.Second * 30
) )
func (s *ColorService) initProcessor() { func (s *ColorService) initProcessor() {
s.processor.RegisterMessages(processor.RegisterMetas{ s.processor.RegisterMessages(processor.RegisterMetas{
pb.MsgId_C2SUserLoginId: {pb.C2SUserLogin{}, s.onLoginOrRegister}, //pb.MsgId_C2SUserLoginId: {pb.C2SUserLogin{}, s.onLoginOrRegister},
}) })
} }
func (s *ColorService) checkLoginOrRegister(req *pb.C2SUserLogin) (us *user.UserAccount, code pb.ErrCode, node *etcd.ServiceNode) {
var err error
node, err = s.bindService.RandServiceNode(pb.ServiceTypeId_STI_DB)
if err != nil {
log.ErrorF(s.Log("not find db service.err:%s ", err.Error()))
return nil, pb.ErrCode_SystemErr, node
}
if req.Version < "20250601123030" {
return nil, pb.ErrCode_VersionTooLow, node
}
us = &user.UserAccount{
Username: req.Username,
Password: req.Password,
DeviceID: req.DeviceId,
LastLoginIP: req.Ip,
}
rpcMsg := ipb.MakeRpcMsg[user.UserAccount](rpcName.GetUserAccount, 0, us)
rspMsg, err := s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
if err != nil {
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
return nil, pb.ErrCode_SystemErr, node
}
_ = json.Unmarshal(rspMsg.Msg, us)
//log.DebugF("收到rpc:%v返回数据:%v", rpcName.GetUserAccount, string(rspMsg.Msg))
if us.ID == 0 {
// 没有帐号,创建帐号
us = &user.UserAccount{
Username: req.Username,
Password: req.Password,
DeviceID: req.DeviceId,
LastLoginIP: req.Ip,
LastLoginTime: time.Now(),
RegisterIP: req.Ip,
RegisterTime: time.Now(),
}
rpcMsg = ipb.MakeRpcMsg[user.UserAccount](rpcName.CreateUserAccount, 0, us)
rspMsg, err = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
if err != nil {
log.ErrorF(s.Log("call rpc:%v err:%s ", rpcMsg.RpcMsgId, err.Error()))
return nil, pb.ErrCode_SystemErr, node
}
_ = json.Unmarshal(rspMsg.Msg, us)
if us.ID == 0 {
log.ErrorF(s.Log("call rpc:%v err", rpcMsg.RpcMsgId))
return nil, pb.ErrCode_SystemErr, node
}
log.DebugF("收到rcp:%v返回数据:%v", rpcName.CreateUserAccount, string(rspMsg.Msg))
}
if !utils.CheckPassword(req.Password, us.Password) {
log.ErrorF(s.Log("用户密码:%v 数据库中密码:%v", req.Password, us.Password))
return nil, pb.ErrCode_LoginUserOrPwdErr, node
}
switch us.Status {
case user.AccountFrozen:
return nil, pb.ErrCode_AccountFrozen, node
case user.AccountBanned:
return nil, pb.ErrCode_AccountBanned, node
default:
return us, pb.ErrCode_OK, node
}
}
// 生成JWT令牌(简化版)
func generateToken(userID int64, username string) (string, error) {
_ = userID
_ = username
// 这里应该使用JWT库生成实际令牌
// 简化实现实际项目中请使用安全的JWT实现
return "generated-token-placeholder", nil
}
// 获取用户数据,如果没有则创建
func (s *ColorService) getUser(accountId int64, tName string) (*user.User, pb.ErrCode) {
us := &user.User{
AccountId: accountId,
}
rpcMsg := ipb.MakeRpcMsg[user.User](rpcName.GetUserByAccountId, 0, us)
rsp, err := s.Call(service.RpcTopicEx(tName), timeout, rpcMsg)
if err != nil {
log.ErrorF(s.Log("call rpc:%v err:%s", rpcMsg.RpcMsgId, err.Error()))
return nil, pb.ErrCode_SystemErr
}
_ = json.Unmarshal(rsp.Msg, us)
if us.ID == 0 {
log.ErrorF(s.Log("call rpc:%v return:%v", rpcMsg.RpcMsgId, string(rsp.Msg)))
return us, pb.ErrCode_SystemErr
}
return us, pb.ErrCode_OK
}
// 登录或注册
func (s *ColorService) onLoginOrRegister(iMsg *ipb.InternalMsg, req *pb.C2SUserLogin) {
ksync.GoSafe(func() {
account, code, node := s.checkLoginOrRegister(req)
userId := int64(0)
rsp := &pb.S2CUserLogin{Code: code}
if account != nil && code == pb.ErrCode_OK {
// 拉取用户数据
us := &user.User{}
us, code = s.getUser(userId, req.Username)
if code == pb.ErrCode_OK {
rsp.UserId = us.ID
rsp.Token, _ = generateToken(account.ID, account.Username)
userId = rsp.UserId
}
}
s.SendServiceMsg(service.TopicEx(iMsg.ServiceName), iMsg.ConnId, userId, int32(pb.MsgId_S2CUserLoginId), rsp)
if account != nil && account.ID > 0 {
loginLog := &user.UserLoginLog{
AccountID: account.ID,
LoginIP: req.Ip,
LoginTime: time.Now(),
DeviceInfo: req.DeviceId,
LoginResult: code == pb.ErrCode_OK,
FailReason: code.String(),
}
switch code {
case pb.ErrCode_LoginUserOrPwdErr, pb.ErrCode_OK:
rpcMsg := ipb.MakeRpcMsg[user.UserLoginLog](rpcName.LogUserAccountLogin, 0, loginLog)
ksync.GoSafe(func() {
_, _ = s.Call(service.RpcTopicEx(node.Name), timeout, rpcMsg)
}, nil)
}
}
}, nil)
}

View File

@ -89,6 +89,16 @@ func (s *ColorService) NotifyStop() {
} }
func (s *ColorService) CanStop() bool { func (s *ColorService) CanStop() bool {
switch s.roomMgr.Status() {
case baseroom.SsWorking:
return false
case baseroom.SsWaitStop, baseroom.SsStopped:
// 没有玩家
if s.playerMgr.Count() == 0 {
return true
}
return false
}
return true return true
} }
@ -97,6 +107,18 @@ func (s *ColorService) OnStop() {
log.Debug("OnStop") log.Debug("OnStop")
} }
func (s *ColorService) findRoom(uid int64) (baseroom.IPlayer, baseroom.IRoom, error) {
if user := s.playerMgr.Find(uid); user != nil {
if rm := s.roomMgr.Find(user.RoomId()); rm != nil {
return user, rm, nil
} else {
return nil, nil, fmt.Errorf("user:%v not found room %d", uid, user.RoomId())
}
} else {
return nil, nil, fmt.Errorf("user:%v not exist", uid)
}
}
// 处理其它服发送过来的消息 // 处理其它服发送过来的消息
func (s *ColorService) OnMessage(data []byte) error { func (s *ColorService) OnMessage(data []byte) error {
var iMsg = &ipb.InternalMsg{} var iMsg = &ipb.InternalMsg{}
@ -108,8 +130,17 @@ func (s *ColorService) OnMessage(data []byte) error {
if req, err := s.processor.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil { if req, err := s.processor.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil {
err = s.processor.Dispatch(iMsg.MsgId, iMsg, req) err = s.processor.Dispatch(iMsg.MsgId, iMsg, req)
} else { } else {
var user baseroom.IPlayer
var rm baseroom.IRoom
if user, rm, err = s.findRoom(iMsg.UserId); err == nil {
if req, err = rm.Unmarshal(iMsg.MsgId, iMsg.Msg); err == nil {
err = rm.Dispatch(user, iMsg.MsgId, iMsg, req)
}
}
if err != nil {
log.Error(err.Error()) log.Error(err.Error())
} }
}
log.Debug(s.Log("received message:%v", iMsg.MsgId)) log.Debug(s.Log("received message:%v", iMsg.MsgId))
return nil return nil
} }

View File

@ -152,19 +152,6 @@ func (s *GateService) OnMessage(data []byte) error {
return nil return nil
} }
/*
查找topic,根据serviceTypeId以及玩家id查找玩家过往访问该服务的节点优先使用原节点
*/
func (s *GateService) findTopic(userId int64, serviceTypeId pb.ServiceTypeId) (topic, sName string) {
var err error
if sName, err = s.bindService.FindServiceName(userId, serviceTypeId); err == nil {
return service.TopicEx(sName), sName
} else {
log.Error(err.Error())
}
return "", sName
}
// 运行在conn的read协程里。将消息转发给内部服务 // 运行在conn的read协程里。将消息转发给内部服务
func (s *GateService) WsOnMessage(conn ws.IConn, data []byte) { func (s *GateService) WsOnMessage(conn ws.IConn, data []byte) {
msg := &pb.ClientMsg{} msg := &pb.ClientMsg{}
@ -179,7 +166,7 @@ func (s *GateService) WsOnMessage(conn ws.IConn, data []byte) {
if msg.ServiceName != "" { if msg.ServiceName != "" {
topic = service.TopicEx(msg.ServiceName) topic = service.TopicEx(msg.ServiceName)
} else { } else {
topic, msg.ServiceName = s.findTopic(conn.UserId(), msg.ServiceTid) topic, msg.ServiceName = s.bindService.FindTopic(conn.UserId(), msg.ServiceTid)
} }
if topic != "" { if topic != "" {
if msg.MsgId == int32(pb.MsgId_C2SUserLoginId) { if msg.MsgId == int32(pb.MsgId_C2SUserLoginId) {