package main import ( "math" "strconv" "strings" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/srvlib" "mongo.games.com/goserver/srvlib/protocol" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/protocol/webapi" ) var GameSessMgrSington = &GameSessMgr{ servers: make(map[int]*GameSession), gamesrvs: make(map[int][]*GameSession), gates: make(map[int]*GameSession), } type GameSessMgr struct { servers map[int]*GameSession // 游戏服务id gamesrvs map[int][]*GameSession // 游戏id gates map[int]*GameSession // 网关id } // 注册事件 func (this *GameSessMgr) OnRegiste(s *netlib.Session) { attr := s.GetAttribute(srvlib.SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*protocol.SSSrvRegiste); ok && srvInfo != nil { if srvInfo.GetType() == srvlib.GameServiceType { logger.Logger.Warn("(this *GameSessMgr) OnRegiste (GameSrv):", s) srvId := int(srvInfo.GetId()) gs := NewGameSession(srvId, srvlib.GameServerType, s) if gs != nil { this.servers[srvId] = gs data := srvInfo.GetData() if data != "" { gameids := strings.Split(data, ",") for _, id := range gameids { if gameid, err := strconv.Atoi(id); err == nil { if gss, exist := this.gamesrvs[gameid]; exist { gss = append(gss, gs) this.gamesrvs[gameid] = gss } else { this.gamesrvs[gameid] = []*GameSession{gs} } gs.gameIds = append(gs.gameIds, int32(gameid)) } } } else { if gss, exist := this.gamesrvs[0]; exist { gss = append(gss, gs) this.gamesrvs[0] = gss } else { this.gamesrvs[0] = []*GameSession{gs} } //gs.gameIds = append(gs.gameIds, 0) } gs.OnRegiste() //尝试创建百人场 HundredSceneMgrSingleton.TryCreateRoom() } } else if srvInfo.GetType() == srvlib.GateServiceType { logger.Logger.Warn("(this *GameSessMgr) OnRegiste (GateSrv):", s) srvId := int(srvInfo.GetId()) gs := NewGameSession(srvId, srvlib.GateServerType, s) if gs != nil { this.gates[srvId] = gs } } } } } // 注销事件 func (this *GameSessMgr) OnUnregiste(s *netlib.Session) { attr := s.GetAttribute(srvlib.SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*protocol.SSSrvRegiste); ok && srvInfo != nil { if srvInfo.GetType() == srvlib.GameServiceType { logger.Logger.Warn("(this *GameSessMgr) OnUnregiste (GameSrv):", s) srvId := int(srvInfo.GetId()) gs := this.servers[srvId] if gs != nil { delete(this.servers, srvId) data := srvInfo.GetData() if data != "" { gameids := strings.Split(data, ",") for _, id := range gameids { if gameid, err := strconv.Atoi(id); err == nil { if gss, exist := this.gamesrvs[gameid]; exist { cnt := len(gss) for j := 0; j < cnt; j++ { if gss[j] == gs { gss[j] = gss[cnt-1] gss = gss[:cnt-1] this.gamesrvs[gameid] = gss break } } } } } } else { if gss, exist := this.gamesrvs[0]; exist { cnt := len(gss) for j := 0; j < cnt; j++ { if gss[j] == gs { gss[j] = gss[cnt-1] gss = gss[:cnt-1] this.gamesrvs[0] = gss break } } } } gs.OnUnregiste() } } else if srvInfo.GetType() == srvlib.GateServiceType { logger.Logger.Warn("(this *GameSessMgr) OnUnregiste (GateSrv):", s) LoginStateMgrSington.LogoutAllBySession(s) srvId := int(srvInfo.GetId()) delete(this.gates, srvId) } } } } func (this *GameSessMgr) GetGameServerSess(gameid int) []*GameSession { return this.gamesrvs[gameid] } // 获取最小负载的GameSession func (this *GameSessMgr) GetMinLoadSess(gameid int) *GameSession { minLoad := math.MaxInt32 loadFactor := 0 var gs *GameSession if gss, exist := this.gamesrvs[gameid]; exist { if gss != nil { for _, s := range gss { if s.state == common.GameSessStateOn { loadFactor = s.GetLoadFactor() if minLoad > loadFactor { minLoad = loadFactor gs = s } } } if gs != nil { return gs } } } if gss, exist := this.gamesrvs[0]; exist { if gss != nil { for _, s := range gss { if s.state == common.GameSessStateOn { loadFactor = s.GetLoadFactor() if minLoad > loadFactor { minLoad = loadFactor gs = s } } } if gs != nil { return gs } } } return gs } func (this *GameSessMgr) GetGameSess(srvId int) *GameSession { if gs, exist := this.servers[srvId]; exist { return gs } return nil } func (this *GameSessMgr) GetAllGameSess() []*GameSession { servers := make([]*GameSession, 0) for _, v := range this.servers { servers = append(servers, v) } return servers } func (this *GameSessMgr) GetGateSess(srvId int) *GameSession { if gs, exist := this.gates[srvId]; exist { return gs } return nil } func (this *GameSessMgr) ListServerState(srvId, srvType int) []*webapi.ServerInfo { _createGateServerInfo := func(srvId, srvType int, s *GameSession) *webapi.ServerInfo { var robNum, playerNum int for _, p := range PlayerMgrSington.sidMap { if p != nil && p.gateSess == s.Session { if p.IsRob { robNum++ } else { playerNum++ } } } si := &webapi.ServerInfo{ SrvId: int32(srvId), SrvType: int32(srvType), State: int32(s.state), PlayerNum: int32(playerNum), RobotNum: int32(robNum), SceneNum: 0, } attr := s.GetAttribute(srvlib.SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*protocol.SSSrvRegiste); ok && srvInfo != nil { si.Data = srvInfo.GetData() } } return si } _createGameServerInfo := func(srvId, srvType int, s *GameSession) *webapi.ServerInfo { var playerNum int for _, p := range s.players { if !p.IsRob { playerNum++ } } si := &webapi.ServerInfo{ SrvId: int32(srvId), SrvType: int32(srvType), State: int32(s.state), PlayerNum: int32(playerNum), RobotNum: int32(len(s.players) - playerNum), SceneNum: int32(len(s.scenes)), } attr := s.GetAttribute(srvlib.SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*protocol.SSSrvRegiste); ok && srvInfo != nil { si.Data = srvInfo.GetData() } } return si } var datas []*webapi.ServerInfo if srvType != 0 { switch srvType { case srvlib.GateServiceType: if srvId != 0 { if s, exist := this.gates[srvId]; exist { si := _createGateServerInfo(srvId, srvlib.GateServiceType, s) datas = append(datas, si) } } case srvlib.GameServiceType: if srvId != 0 { if s, exist := this.servers[srvId]; exist { si := _createGameServerInfo(srvId, srvlib.GameServiceType, s) datas = append(datas, si) } } } } else { if srvId == 0 { for sid, s := range this.gates { si := _createGateServerInfo(sid, srvlib.GateServiceType, s) datas = append(datas, si) } for sid, s := range this.servers { si := _createGameServerInfo(sid, srvlib.GameServiceType, s) datas = append(datas, si) } } else { if s, exist := this.gates[srvId]; exist { si := _createGateServerInfo(srvId, srvlib.GateServiceType, s) datas = append(datas, si) } if s, exist := this.servers[srvId]; exist { si := _createGameServerInfo(srvId, srvlib.GameServiceType, s) datas = append(datas, si) } } } //worldsrv 自身的信息 myInfo := &webapi.ServerInfo{ SrvId: int32(common.GetSelfSrvId()), SrvType: int32(common.GetSelfSrvType()), State: int32(common.GameSessStateOn), PlayerNum: int32(len(PlayerMgrSington.players)), RobotNum: int32(len(PlayerMgrSington.snidMap) - len(PlayerMgrSington.players)), SceneNum: int32(len(SceneMgrSingleton.scenes)), } if model.GameParamData.SrvMaintain { if !common.SrvIsMaintaining { myInfo.State = int32(common.GameSessStateOn) } else { myInfo.State = int32(common.GameSessStateOff) } } //把自己加进去 datas = append(datas, myInfo) return datas } func init() { srvlib.ServerSessionMgrSington.AddListener(GameSessMgrSington) }