修改bug

This commit is contained in:
liuxiaobo 2025-06-17 12:48:14 +08:00
parent e7cb90ed63
commit a023c28dc8
12 changed files with 65 additions and 67 deletions

View File

@ -159,7 +159,7 @@ func (r *BaseRoom[Seat]) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message
user.Robot().OnMessage(msgId, msg)
} else {
iMsg := ipb.MakeMsgEx(r.srv.Name(), 0, user.Id(), int32(msgId), msg)
_ = r.srv.SendByTopic(user.GateTopicName(), iMsg)
_ = r.srv.SendByServiceId(int(pb.ServiceTypeId_STI_Gate), iMsg)
}
}

View File

@ -114,7 +114,7 @@ func (r *HundredRoom) SendMsg(user IPlayer, msgId pb.MsgId, msg proto.Message) {
user.Robot().OnMessage(msgId, msg)
} else {
iMsg := ipb.MakeMsgEx(r.room.srv.Name(), 0, user.Id(), int32(msgId), msg)
_ = r.room.srv.SendByTopic(user.GateTopicName(), iMsg)
_ = r.room.srv.SendByServiceId(int(pb.ServiceTypeId_STI_Gate), iMsg)
}
}

View File

@ -31,7 +31,6 @@ type IPlayer interface {
Id() int64
Robot() IRobot
IsRobot() bool
GateTopicName() string
RoomId() int
}

View File

@ -10,7 +10,6 @@ import (
"github.com/fox/fox/log"
"github.com/fox/fox/xrand"
"github.com/go-redis/redis/v8"
"time"
)
const (
@ -45,7 +44,7 @@ func NewUserBindService(rdb *redis.Client, etcdRegistry *etcd.Registry[etcd.Serv
}
func (m *UserBindService) makeRedisKey(userId int64) string {
return fmt.Sprintf("%s:%s", prefix, userId)
return fmt.Sprintf("%s:%d", prefix, userId)
}
func (m *UserBindService) makeRedisSubKey(typeId pb.ServiceTypeId) string {
return typeId.String()
@ -76,7 +75,7 @@ func (m *UserBindService) DelUserService(userId int64, typeId pb.ServiceTypeId)
func (m *UserBindService) SaveUserService(userId int64, typeId pb.ServiceTypeId, serviceName string) {
key := m.makeRedisKey(userId)
subKey := m.makeRedisSubKey(typeId)
m.rdb.HSet(context.Background(), key, subKey, serviceName, 2*24*time.Hour)
m.rdb.HSet(context.Background(), key, subKey, serviceName)
}
// 从etcd中检查节点是否有效如果有game1(旧服),game2(新服),都算有效,但是旧服会拒绝新玩家进入,
@ -84,13 +83,11 @@ func (m *UserBindService) SaveUserService(userId int64, typeId pb.ServiceTypeId,
func (m *UserBindService) findServiceNodeByServiceName(serviceName string) (*etcd.ServiceNode, bool) {
var sNode *etcd.ServiceNode
valid := false
m.etcdRegistry.GetNodes().Range(func(k, v interface{}) bool {
if node, ok := v.(etcd.ServiceNode); ok {
if node.Name == serviceName {
valid = true
sNode = &node
return false
}
m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool {
if node.Name == serviceName {
valid = true
sNode = node
return false
}
return true
})
@ -98,35 +95,41 @@ func (m *UserBindService) findServiceNodeByServiceName(serviceName string) (*etc
}
func (m *UserBindService) stringAllServiceNode() string {
var nodes []any
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
nodes = append(nodes, value)
var nodes []*etcd.ServiceNode
m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool {
nodes = append(nodes, node)
return true
})
return utils.JsonMarshal(nodes)
}
// 从etcd中找可用服务节点随机选择一个
func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.ServiceNode, error) {
// 获取最新的节点
func (m *UserBindService) getLatestServiceNode(typeId pb.ServiceTypeId) []etcd.ServiceNode {
var nodes []etcd.ServiceNode
var version string
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
node, ok := value.(etcd.ServiceNode)
if ok && node.TypeId == int(typeId) {
// 查找最新版本号
m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool {
if node.TypeId == int(typeId) {
if version < node.Version {
version = node.Version
}
}
return true
})
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
if node, ok := value.(etcd.ServiceNode); ok && node.TypeId == int(typeId) {
m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool {
if node.TypeId == int(typeId) {
if version == node.Version {
nodes = append(nodes, node)
nodes = append(nodes, *node)
}
}
return true
})
return nodes
}
// 从etcd中找可用服务节点随机选择一个
func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.ServiceNode, error) {
var nodes = m.getLatestServiceNode(typeId)
if len(nodes) == 0 {
return nil, fmt.Errorf("not found service node.type id:%v. all node:%v", typeId, m.stringAllServiceNode())
}
@ -137,25 +140,7 @@ func (m *UserBindService) randServiceNode(typeId pb.ServiceTypeId) (*etcd.Servic
// 从etcd中hash一个服务节点。不需要保存玩家在哪个服务。
// 该服务是类似于db服这种有序操作的hash服
func (m *UserBindService) HashServiceNode(typeId pb.ServiceTypeId, uid int64) (*etcd.ServiceNode, error) {
var nodes []etcd.ServiceNode
var version string
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
node, ok := value.(etcd.ServiceNode)
if ok && node.TypeId == int(typeId) {
if version < node.Version {
version = node.Version
}
}
return true
})
m.etcdRegistry.GetNodes().Range(func(_, value any) bool {
if node, ok := value.(etcd.ServiceNode); ok && node.TypeId == int(typeId) {
if version == node.Version {
nodes = append(nodes, node)
}
}
return true
})
var nodes = m.getLatestServiceNode(typeId)
if len(nodes) == 0 {
return nil, fmt.Errorf("not found service node.type id:%v. all node:%v", typeId, m.stringAllServiceNode())
}
@ -184,7 +169,9 @@ func (m *UserBindService) FindServiceNode(typeId pb.ServiceTypeId, userId int64)
return nil, err
}
// log.DebugF("etcd中随机一个服务节点:%s", node.Name)
m.rdb.HSet(context.Background(), m.makeRedisKey(userId), node.Name, 2*24*time.Hour)
if m.CheckServiceNodeStateType(typeId) == etcd.SNST_Stateful {
m.SaveUserService(userId, typeId, node.Name)
}
return node, nil
}
@ -196,12 +183,10 @@ func (m *UserBindService) RangeUserAllServiceNode(userId int64, proc func(node *
return
}
if len(maps) > 0 {
m.etcdRegistry.GetNodes().Range(func(k, v interface{}) bool {
if node, ok := v.(etcd.ServiceNode); ok {
if _, ok = maps[node.Name]; ok {
if !proc(&node) {
return false
}
m.etcdRegistry.RangeNode(func(_ string, node *etcd.ServiceNode) bool {
if _, ok := maps[node.Name]; ok {
if !proc(node) {
return false
}
}
return true

View File

@ -3,6 +3,7 @@ package room
import (
"game/common/proto/pb"
"github.com/fox/fox/ipb"
"github.com/fox/fox/log"
)
func (rm *ColorRoom) checkEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom) pb.ErrCode {
@ -28,6 +29,7 @@ func (rm *ColorRoom) enterRoom(user *ColorPlayer) {
user.resetData()
}
rm.notifyColorRoomInfo(user)
log.Debug(rm.Log("玩家:%v进入房间", user.ID))
}
func (rm *ColorRoom) onEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom) {
@ -43,19 +45,20 @@ func (rm *ColorRoom) onEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *
func (rm *ColorRoom) checkLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqLeaveRoom) pb.ErrCode {
_ = iMsg
_ = req
if user.totalBet == 0 {
return pb.ErrCode_OK
}
if rm.status >= pb.ColorGameStatus_CGS_Settle || rm.status < pb.ColorGameStatus_CGS_Betting {
return pb.ErrCode_OK
}
if user.totalBet == 0 {
return pb.ErrCode_NotLeaveRoom
}
return pb.ErrCode_OK
return pb.ErrCode_NotLeaveRoom
}
func (rm *ColorRoom) leaveRoom(user *ColorPlayer) {
rm.DelPlayer(user.Id())
rm.userMgr.Del(user.ID)
rm.bindService.DelUserService(user.ID, pb.ServiceTypeId_STI_ColorGame)
log.Debug(rm.Log("玩家:%v离开房间", user.ID))
}
func (rm *ColorRoom) onLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.ReqLeaveRoom) {
@ -63,9 +66,15 @@ func (rm *ColorRoom) onLeaveRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *
rm.SendMsg(user, pb.MsgId_RspEnterRoomId, &pb.RspEnterRoom{Code: code})
if code == pb.ErrCode_OK {
rm.leaveRoom(user)
return
}
return
}
func (rm *ColorRoom) onUserOffline(user *ColorPlayer, iMsg *ipb.InternalMsg, ntf *pb.NtfUserOffline) {
_ = ntf
code := rm.checkLeaveRoom(user, iMsg, &pb.ReqLeaveRoom{})
if code == pb.ErrCode_OK {
rm.leaveRoom(user)
}
}
func (rm *ColorRoom) checkBet(user *ColorPlayer, _ *ipb.InternalMsg, req *pb.ReqColorBetting) pb.ErrCode {

View File

@ -9,8 +9,7 @@ import (
type ColorPlayer struct {
*user.User
*user.UserResources
gateTopicName string
roomId int
roomId int
notBetCount int // 不投注局数
totalBet int64 // 总下注金额
@ -18,11 +17,10 @@ type ColorPlayer struct {
settleMsg *pb.NtfColorSettle // 本局结算消息
}
func NewColorPlayer(gateTopicName string, roomId int, u *user.User, res *user.UserResources) *ColorPlayer {
func NewColorPlayer(roomId int, u *user.User, res *user.UserResources) *ColorPlayer {
return &ColorPlayer{
User: u,
UserResources: res,
gateTopicName: gateTopicName,
roomId: roomId,
}
}
@ -39,10 +37,6 @@ func (p *ColorPlayer) IsRobot() bool {
return false
}
func (p *ColorPlayer) GateTopicName() string {
return p.gateTopicName
}
func (p *ColorPlayer) RoomId() int {
return p.roomId
}

View File

@ -73,6 +73,7 @@ func (rm *ColorRoom) OnInit() {
pb.MsgId_ReqColorBettingId: {pb.ReqColorBetting{}, rm.onBet},
pb.MsgId_ReqEnterRoomId: {pb.ReqEnterRoom{}, rm.onEnterRoom},
pb.MsgId_ReqLeaveRoomId: {pb.ReqLeaveRoom{}, rm.onLeaveRoom},
pb.MsgId_NtfUserOfflineId: {pb.NtfUserOffline{}, rm.onUserOffline},
})
rm.RegisterTimerMessages(processor.RegisterTimerMetas{
TtGameStart: rm.gameStart,

View File

@ -7,7 +7,6 @@ import (
"github.com/fox/fox/ipb"
"github.com/fox/fox/ksync"
"github.com/fox/fox/processor"
"github.com/fox/fox/service"
)
const (
@ -31,7 +30,7 @@ func (s *ColorService) onEnterRoom(iMsg *ipb.InternalMsg, req *pb.ReqEnterRoom)
}
// 切回服务协程处理业务逻辑
s.RunOnce(func() {
colorUser := room.NewColorPlayer(service.TopicEx(iMsg.ServiceName), s.room.Id(), &us.User, &us.UserResources)
colorUser := room.NewColorPlayer(s.room.Id(), &us.User, &us.UserResources)
s.playerMgr.Add(colorUser)
_ = s.room.Dispatch(colorUser, iMsg.MsgId, iMsg, req)
})

View File

@ -6,6 +6,7 @@ import (
"game/common/gameService"
"game/common/proto/pb"
"game/common/serviceName"
"game/common/topicName"
"game/server/colorgame/config"
"game/server/colorgame/room"
"github.com/fox/fox/ipb"
@ -59,6 +60,7 @@ func newColorService(serviceId int) service.IService {
TypeId: int(pb.ServiceTypeId_STI_ColorGame),
Version: config.Cfg.BuildDate,
}, &config.Cfg.Redis)
_ = s.GameService.Subscribe(topicName.UserOffline)
s.initProcessor()
s.playerMgr = baseroom.NewPlayerMgr(nil)

View File

@ -58,3 +58,9 @@ func (s *MatchService) onMatchRoom(iMsg *ipb.InternalMsg, req *pb.ReqMatchRoom)
s.SendServiceMsg(pb.ServiceTypeId_STI_Gate, iMsg.UserId, int32(pb.MsgId_RspMatchRoomId), rsp)
}, nil)
}
// 匹配房间
func (s *MatchService) onUserOffline(iMsg *ipb.InternalMsg, ntf *pb.NtfUserOffline) {
_ = iMsg
log.DebugF(s.Log("收到玩家下线消息:%v从匹配队列中移除该玩家", ntf.UserId))
}

View File

@ -11,6 +11,7 @@ const (
func (s *MatchService) initProcessor() {
s.Processor().RegisterMessages(processor.RegisterMetas{
pb.MsgId_ReqMatchRoomId: {pb.ReqMatchRoom{}, s.onMatchRoom},
pb.MsgId_ReqMatchRoomId: {pb.ReqMatchRoom{}, s.onMatchRoom},
pb.MsgId_NtfUserOfflineId: {pb.NtfUserOffline{}, s.onUserOffline},
})
}

View File

@ -5,6 +5,7 @@ import (
"game/common/gameService"
"game/common/proto/pb"
"game/common/serviceName"
"game/common/topicName"
"game/server/match/config"
"game/server/match/match"
"github.com/fox/fox/ipb"
@ -56,6 +57,7 @@ func newService(serviceId int) *MatchService {
TypeId: int(pb.ServiceTypeId_STI_Match),
Version: config.Cfg.BuildDate,
}, &config.Cfg.Redis)
_ = s.GameService.Subscribe(topicName.UserOffline)
s.initProcessor()
s.OnInit()