game_sync/worldsrv/gamesessmgr.go

320 lines
8.2 KiB
Go

package main
import (
"math"
"mongo.games.com/game/protocol/webapi"
"strconv"
"strings"
"mongo.games.com/game/common"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib"
"mongo.games.com/goserver/srvlib"
"mongo.games.com/goserver/srvlib/protocol"
)
//const (
// ReplayServerType int = 8
// ReplayServerId = 801
//)
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
gamesrvs map[int][]*GameSession
gates map[int]*GameSession
}
// 注册事件
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.GAME_SESS_STATE_ON {
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.GAME_SESS_STATE_ON {
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) RebindPlayerSnId(oldSnId, newSnId int32) {
for _, gs := range this.servers {
gs.RebindPlayerSnId(oldSnId, newSnId)
}
}
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.GAME_SESS_STATE_ON),
PlayerNum: int32(len(PlayerMgrSington.players)),
RobotNum: int32(len(PlayerMgrSington.snidMap) - len(PlayerMgrSington.players)),
SceneNum: int32(len(SceneMgrSingleton.scenes)),
}
if SrvIsMaintaining {
myInfo.State = int32(common.GAME_SESS_STATE_ON)
} else {
myInfo.State = int32(common.GAME_SESS_STATE_OFF)
}
//把自己加进去
datas = append(datas, myInfo)
return datas
}
func init() {
srvlib.ServerSessionMgrSington.AddListener(GameSessMgrSington)
}