package main import ( "fmt" "mongo.games.com/game/protocol/webapi" "sync" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/proto" gamehall_proto "mongo.games.com/game/protocol/gamehall" server_proto "mongo.games.com/game/protocol/server" "mongo.games.com/game/srvdata" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/srvlib" libproto "mongo.games.com/goserver/srvlib/protocol" ) type GameSessionListener interface { OnGameSessionRegiste(*GameSession) OnGameSessionUnregiste(*GameSession) } var GameSessionListenerSet = new(sync.Map) func RegisteGameSessionListener(listener GameSessionListener) { GameSessionListenerSet.Store(listener, listener) } func UnregisteGameSessionListener(listener GameSessionListener) { GameSessionListenerSet.Delete(listener) } type GameSession struct { *netlib.Session srvId int srvType int state common.GameSessState players map[int32]*Player scenes map[int]*Scene cps map[string]*model.CoinPoolSetting gameIds []int32 } // 构造函数 func NewGameSession(srvId, srvType int, s *netlib.Session) *GameSession { gs := &GameSession{ Session: s, srvId: srvId, srvType: srvType, state: common.GAME_SESS_STATE_ON, players: make(map[int32]*Player), scenes: make(map[int]*Scene), cps: make(map[string]*model.CoinPoolSetting), } return gs } func (this *GameSession) RebindPlayerSnId(oldSnId, newSnId int32) { if p, exist := this.players[oldSnId]; exist { delete(this.players, oldSnId) this.players[newSnId] = p } } func (this *GameSession) GetSrvId() int32 { if this.Session == nil { return 0 } attr := this.GetAttribute(srvlib.SessionAttributeServerInfo) if attr != nil { if srvInfo, ok := attr.(*libproto.SSSrvRegiste); ok && srvInfo != nil { return srvInfo.GetId() } } return 0 } // 关闭其上的所有场景 func (this *GameSession) CloseAllScene() { for sceneId, scene := range this.scenes { scDestroyRoom := &gamehall_proto.SCDestroyRoom{ RoomId: proto.Int(sceneId), OpRetCode: gamehall_proto.OpResultCode_Game_OPRC_Sucess_Game, IsForce: proto.Int(1), } proto.SetDefaults(scDestroyRoom) scene.Broadcast(int(gamehall_proto.GameHallPacketID_PACKET_SC_DESTROYROOM), scDestroyRoom, 0) SceneMgrSingleton.DestroyScene(sceneId, true) } this.scenes = nil this.players = nil } // 注册事件 func (this *GameSession) OnRegiste() { GameSessionListenerSet.Range(func(key, val interface{}) bool { if lis, ok := val.(GameSessionListener); ok { lis.OnGameSessionRegiste(this) } return true }) } // 注销事件 func (this *GameSession) OnUnregiste() { //销毁比赛 //MatchMgrSington.DestroyAllMatchByGameSession(this) //解散房间 this.CloseAllScene() GameSessionListenerSet.Range(func(key, val interface{}) bool { if lis, ok := val.(GameSessionListener); ok { lis.OnGameSessionUnregiste(this) } return true }) } // 负载因数 func (this *GameSession) GetLoadFactor() int { return len(this.scenes)*20 + len(this.players) } // 设置状态 func (this *GameSession) SwitchState(state common.GameSessState) { if state == this.state { return } this.state = state switch state { case common.GAME_SESS_STATE_ON: this.OnStateOn() case common.GAME_SESS_STATE_OFF: this.OnStateOff() } } func (this *GameSession) OnStateOn() { pack := &server_proto.ServerState{ SrvState: proto.Int(int(this.state)), } proto.SetDefaults(pack) this.Send(int(server_proto.SSPacketID_PACKET_WG_SERVER_STATE), pack) } func (this *GameSession) OnStateOff() { pack := &server_proto.ServerState{ SrvState: proto.Int(int(this.state)), } proto.SetDefaults(pack) this.Send(int(server_proto.SSPacketID_PACKET_WG_SERVER_STATE), pack) } type AddSceneParam struct { S *Scene } func (this *GameSession) AddScene(args *AddSceneParam) { this.scenes[args.S.sceneId] = args.S //send msg msg := &server_proto.WGCreateScene{ Platform: args.S.limitPlatform.IdStr, SceneId: int32(args.S.sceneId), GameId: int32(args.S.gameId), GameMode: int32(args.S.gameMode), SceneMode: int32(args.S.sceneMode), ReplayCode: args.S.replayCode, DBGameFree: args.S.dbGameFree, TotalOfGames: args.S.totalRound, PlayerNum: int32(args.S.playerNum), Creator: args.S.creator, BaseScore: args.S.BaseScore, Custom: args.S.CustomParam, Match: args.S.MatchParam, Params: args.S.params, } if args.S.GetRoomTypeId() != 0 { cfg := PlatformMgrSingleton.GetConfig(args.S.limitPlatform.IdStr).RoomConfig[args.S.GetRoomTypeId()] if cfg != nil { for _, v := range cfg.GetReward() { msg.Items = append(msg.Items, &server_proto.Item{ Id: v.GetItemId(), Num: v.GetItemNum(), }) } for _, v := range cfg.GetCost() { msg.CostItems = append(msg.CostItems, &server_proto.Item{ Id: v.GetItemId(), Num: v.GetItemNum(), }) } } } if sp, ok := args.S.sp.(*ScenePolicyData); ok { msg.EnterAfterStart = proto.Bool(sp.EnterAfterStart) } // 象棋游戏添加段位配置 if args.S.dbGameFree != nil && srvdata.GameFreeMgr.IsGameDif(int32(args.S.gameId), common.GameDifChess) { msg.ChessRank = ChessRankMgrSington.GetChessRankArr(args.S.limitPlatform.Name, int32(args.S.gameId)) } this.Send(int(server_proto.SSPacketID_PACKET_WG_CREATESCENE), msg) logger.Logger.Tracef("WGCreateScene: %v", msg) } func (this *GameSession) DelScene(s *Scene) { delete(this.scenes, s.sceneId) } func (this *GameSession) AddPlayer(p *Player) { this.players[p.SnId] = p } func (this *GameSession) DelPlayer(p *Player) { delete(this.players, p.SnId) } func (this *GameSession) GenCoinPoolSettingKey(platform string, groupId, gamefreeid, srvid int32) string { var key string if groupId != 0 { key = fmt.Sprintf("%v+%v_%v", gamefreeid, groupId, srvid) } else { key = fmt.Sprintf("%v_%v_%v", gamefreeid, platform, srvid) } return key } func (this *GameSession) DetectCoinPoolSetting(platform string, gamefreeid, groupId int32) bool { srvid := this.GetSrvId() key := this.GenCoinPoolSettingKey(platform, groupId, gamefreeid, srvid) if _, exist := this.cps[key]; !exist { data := model.GetCoinPoolSetting(gamefreeid, srvid, groupId, platform) if data == nil { dbGameCoinPool := srvdata.PBDB_GameCoinPoolMgr.GetData(gamefreeid) if dbGameCoinPool != nil { data = model.NewCoinPoolSetting(platform, groupId, gamefreeid, srvid, dbGameCoinPool) if data != nil { err := model.UpsertCoinPoolSetting(data, nil) // 入库 if err == nil { model.ManageCoinPoolSetting(data) } } } } if data != nil { this.cps[key] = data //send msg msg := &webapi.CoinPoolSetting{ Platform: platform, GameFreeId: gamefreeid, ServerId: srvid, GroupId: groupId, InitValue: data.InitValue, LowerLimit: data.LowerLimit, UpperLimit: data.UpperLimit, QuDu: data.QuDu, UpperOdds: data.UpperOdds, UpperOddsMax: data.UpperOddsMax, LowerOdds: data.LowerOdds, LowerOddsMax: data.LowerOddsMax, ProfitRate: data.ProfitRate, CtrlRate: data.CtrlRate, InitNoviceValue: data.InitNoviceValue, ResetTime: data.ResetTime, Switch: data.Switch, } proto.SetDefaults(msg) this.Send(int(server_proto.SSPacketID_PACKET_WG_COINPOOLSETTING), msg) } } return true } // SendToGame 给某个游戏服务发消息 func SendToGame(gameId int, packetId int, pack interface{}) { gameServers := GameSessMgrSington.GetGameServerSess(gameId) if len(gameServers) == 0 { gameServers = GameSessMgrSington.GetGameServerSess(common.GameId_Unknow) } for _, value := range gameServers { value.Send(packetId, pack) } }