Ejemplo n.º 1
0
        public virtual bool UpdateGameState(UpdateGameEvent updateOperation, IncomingGameServerPeer incomingGameServerPeer, out GameState gameState)
        {
            if (!GetOrAddUpdatedGameState(updateOperation, out gameState))
            {
                return false;
            }

            bool oldVisible = gameState.IsVisbleInLobby;
            bool changed = gameState.Update(updateOperation);

            if (!changed)
            {
                return false;
            }

            if (log.IsDebugEnabled)
            {
                LogGameState("UpdateGameState: ", gameState);
            }

            this.HandleVisibility(gameState, oldVisible);

            return true;
        }
Ejemplo n.º 2
0
 public override bool UpdateGameState(UpdateGameEvent updateOperation, IncomingGameServerPeer incomingGameServerPeer,
     out GameState gameState)
 {
     if (base.UpdateGameState(updateOperation, incomingGameServerPeer, out gameState))
     {
         if (gameState.IsJoinable)
         {
             this.gameDatabase.Update(gameState.Id, gameState.Properties);
             return true;
         }
     }
     return false;
 }
Ejemplo n.º 3
0
        public void OnGameUpdateOnGameServer(UpdateGameEvent updateGameEvent, IncomingGameServerPeer gameServerPeer)
        {
            GameState gameState;

            lock (this.gameDict)
            {
                if (!this.gameDict.TryGetValue(updateGameEvent.GameId, out gameState))
                {
                    if (updateGameEvent.Reinitialize)
                    {
                        AppLobby lobby;
                        if (!this.LobbyFactory.GetOrCreateAppLobby(updateGameEvent.LobbyId, (AppLobbyType)updateGameEvent.LobbyType, out lobby))
                        {
                            // getting here should never happen
                            if (log.IsWarnEnabled)
                            {
                                log.WarnFormat("Could not get or create lobby: name={0}, type={1}", updateGameEvent.LobbyId, (AppLobbyType)updateGameEvent.LobbyType);
                            }
                            return;
                        }

                        if (!this.gameDict.TryGetValue(updateGameEvent.GameId, out gameState))
                        {
                            gameState = new GameState(lobby, updateGameEvent.GameId, updateGameEvent.MaxPlayers.GetValueOrDefault(0),
                                gameServerPeer);
                            this.gameDict.Add(updateGameEvent.GameId, gameState);
                        }
                    }
                }
            }

            if (gameState != null)
            {
                if (gameState.GameServer != gameServerPeer)
                {
                    return;
                }

                gameState.Lobby.UpdateGameState(updateGameEvent, gameServerPeer);
                return;
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Game to update not found: {0}", updateGameEvent.GameId);
            }
        }
Ejemplo n.º 4
0
        public bool UpdateGameState(UpdateGameEvent updateOperation, IncomingGameServerPeer incomingGameServerPeer, out GameState gameState)
        {
            // try to get the game state 
            if (this.gameDict.TryGet(updateOperation.GameId, out gameState) == false)
            {
                if (updateOperation.Reinitialize)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Reinitialize: Add Game State {0}", updateOperation.GameId);
                    }

                    if (!this.Lobby.Application.TryGetGame(updateOperation.GameId, out gameState))
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("Could not find game to reinitialize: {0}", updateOperation.GameId);
                        }

                        return false;
                    }

                    this.gameDict.Add(updateOperation.GameId, gameState);
                    if (this.IsGameJoinable(gameState))
                    {
                        this.gameDatabase.InsertGameState(updateOperation.GameId, gameState.Properties);
                    }
                }
                else
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Game not found: {0}", updateOperation.GameId);
                    }
                    return false;
                }
            }

            bool oldIsJoinable = this.IsGameJoinable(gameState);
            bool oldVisible = gameState.IsVisbleInLobby;
            bool changed = gameState.Update(updateOperation);

            if (changed)
            {
                if (gameState.IsVisbleInLobby)
                {
                    this.changedGames[gameState.Id] = gameState;

                    if (oldVisible == false)
                    {
                        this.removedGames.Remove(gameState.Id);
                    }
                }
                else
                {
                    if (oldVisible)
                    {
                        this.changedGames.Remove(gameState.Id);
                        this.removedGames.Add(gameState.Id);
                    }
                }

                if (log.IsDebugEnabled)
                {
                    LogGameState("UpdateGameState: ", gameState);
                }

                var newIsJoinable = this.IsGameJoinable(gameState);
                if (newIsJoinable != oldIsJoinable)
                {
                    if (newIsJoinable)
                    {
                        this.gameDatabase.InsertGameState(gameState.Id, gameState.Properties);
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("GameState added to database: reason=Became joinable, gameId={0}", gameState.Id);
                        }
                    }
                    else
                    {
                        this.gameDatabase.Delete(gameState.Id);
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("GameState removed from database: reason=Became not joinable, gameId={0}", gameState.Id);
                        }
                    }
                }
                else
                {
                    if (oldIsJoinable)
                    {
                        this.gameDatabase.Update(gameState.Id, gameState.Properties);
                    }
                }
            }

            return true;
        }
        public void UpdateGameState(string gameId, byte actorCount, Hashtable changedProperties, List<string> newUsers, List<string> removedUsers, bool reinitialize)
        {
            if (!this.IsRegistered)
            {
                return;
            }

            var e = new UpdateGameEvent { GameId = gameId, ActorCount = actorCount, GameProperties = changedProperties, Reinitialize = reinitialize };

            if (newUsers != null)
            {
                e.NewUsers = newUsers.ToArray();
            }

            if (removedUsers != null)
            {
                e.RemovedUsers = removedUsers.ToArray();
            }

            var eventData = new EventData((byte)ServerEventCode.UpdateGameState, e);
            this.SendEvent(eventData, new SendParameters());
        }
Ejemplo n.º 6
0
        public override bool UpdateGameState(UpdateGameEvent updateOperation, IncomingGameServerPeer gameServerPeer, out GameState gameState)
        {
            // try to get the game state
            if (this.gameDict.TryGetValue(updateOperation.GameId, out gameState) == false)
            {
                if (updateOperation.Reinitialize)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Reinitialize: Add Game State {0}", updateOperation.GameId);
                    }

                    gameState = new GameState(this.Lobby, updateOperation.GameId, 0, gameServerPeer);

                    this.AddGameState(gameState);
                }
                else
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Game not found: {0}", updateOperation.GameId);
                    }

                    return false;
                }
            }

            bool oldVisible = gameState.IsVisbleInLobby;
            bool changed = gameState.Update(updateOperation);

            if (!changed)
            {
                return false;
            }

            if (log.IsDebugEnabled)
            {
                LogGameState("UpdateGameState: ", gameState);
            }

            if (gameState.IsVisbleInLobby)
            {
                foreach (GameChannel channel in this.GameChannels.Values)
                {
                    channel.OnGameUpdated(gameState);
                }

                return true;
            }

            if (oldVisible)
            {
                foreach (GameChannel channel in this.GameChannels.Values)
                {
                    channel.OnGameRemoved(gameState);
                }
            }

            return true;
        }
Ejemplo n.º 7
0
        public bool Update(UpdateGameEvent updateOperation)
        {
            bool changed = false;

            if (this.IsCreatedOnGameServer == false)
            {
                this.IsCreatedOnGameServer = true;
                changed = true;
            }

            if (this.GameServerPlayerCount != updateOperation.ActorCount)
            {
                this.GameServerPlayerCount = updateOperation.ActorCount;
                changed = true;
            }

            if (updateOperation.NewUsers != null)
            {
                foreach (string userId in updateOperation.NewUsers)
                {
                    this.OnPeerJoinedGameServer(userId);
                }
            }

            if (updateOperation.RemovedUsers != null)
            {
                foreach (string userId in updateOperation.RemovedUsers)
                {
                    this.OnPeerLeftGameServer(userId);
                }
            }

            if (updateOperation.GameProperties != null)
            {
                changed |= this.UpdateProperties(updateOperation.GameProperties);
            }

            return changed;
        }
Ejemplo n.º 8
0
        protected virtual void UpdateGameStateOnMaster(
            byte? newMaxPlayer = null, 
            bool? newIsOpen = null,
            bool? newIsVisble = null,
            object[] lobbyPropertyFilter = null,
            Hashtable gameProperties = null, 
            string newPeerId = null, 
            string removedPeerId = null, 
            bool reinitialize = false)
        {
            if (reinitialize && Actors.Count == 0)
            {
                Log.WarnFormat("Reinitialize tried to update GameState with ActorCount = 0. " + this);
                return;
            }

            var updateGameEvent = new UpdateGameEvent
                {
                    GameId = this.Name,
                    ActorCount = (byte)this.Actors.Count,
                    Reinitialize = reinitialize,
                    MaxPlayers = newMaxPlayer,
                    IsOpen = newIsOpen,
                    IsVisible = newIsVisble,
                    PropertyFilter = lobbyPropertyFilter
                };

            if (reinitialize)
            {
                updateGameEvent.LobbyId = this.lobbyId;
                updateGameEvent.LobbyType = (byte)this.lobbyType;
            }

            if (gameProperties != null && gameProperties.Count > 0)
            {
                updateGameEvent.GameProperties = gameProperties;
            }

            if (newPeerId != null)
            {
                updateGameEvent.NewUsers = new[] { newPeerId };
            }

            if (removedPeerId != null)
            {
                updateGameEvent.RemovedUsers = new[] { removedPeerId };
            }

            this.UpdateGameStateOnMaster(updateGameEvent);
        }
Ejemplo n.º 9
0
 protected virtual void UpdateGameStateOnMaster(UpdateGameEvent updateEvent)
 {
     var eventData = new EventData((byte)ServerEventCode.UpdateGameState, updateEvent);
     GameApplication.Instance.MasterPeer.SendEvent(eventData, new SendParameters());
 }
Ejemplo n.º 10
0
        protected virtual void UpdateGameStateOnMaster(
            byte? newMaxPlayer = null, 
            bool? newIsOpen = null,
            bool? newIsVisble = null,
            object[] lobbyPropertyFilter = null,
            Hashtable gameProperties = null, 
            string[] newUserId = null, 
            string removedUserId = null, 
            bool reinitialize = false,
            string[] inactiveList = null,
            ExcludedActorInfo[] excludedActorInfos = null,
            string[] expectedList = null,
            bool? checkUserIdOnJoin = null)
        {
            if (reinitialize && this.ActorsManager.ActorsCount == 0 && this.ActorsManager.InactiveActorsCount == 0)
            {
                Log.WarnFormat("Reinitialize tried to update GameState with ActorCount = 0 - {0}." , this.ToString());
                return;
            }

            if (Log.IsDebugEnabled)
            {
                Log.DebugFormat("UpdateGameStateOnMaster: game - '{0}', reinitialize:{1}", this.Name, reinitialize);
            }

            var updateGameEvent = new UpdateGameEvent
                {
                    GameId = this.Name,
                    ActorCount = (byte)this.ActorsManager.ActorsCount,
                    Reinitialize = reinitialize,
                    MaxPlayers = newMaxPlayer,
                    IsOpen = newIsOpen,
                    IsVisible = newIsVisble,
                    IsPersistent = this.IsPersistent,
                    InactiveCount = (byte)this.ActorsManager.InactiveActorsCount,
                    PropertyFilter = lobbyPropertyFilter,
                    CheckUserIdOnJoin = checkUserIdOnJoin,
                };

            // TBD - we have to send this in case we are re-joining and we are creating the room (load)
            if (reinitialize)
            {
                updateGameEvent.LobbyId = this.LobbyId;
                updateGameEvent.LobbyType = (byte)this.LobbyType;
            }

            if (gameProperties != null && gameProperties.Count > 0)
            {
                updateGameEvent.GameProperties = gameProperties;
            }

            if (newUserId != null)
            {
                updateGameEvent.NewUsers = newUserId;
            }

            if (removedUserId != null)
            {
                updateGameEvent.RemovedUsers = new[] { removedUserId };
            }

            if (excludedActorInfos != null)
            {
                updateGameEvent.ExcludedUsers = excludedActorInfos;
            }

            if (expectedList != null)
            {
                updateGameEvent.ExpectedUsers = expectedList;
            }

            this.UpdateGameStateOnMaster(updateGameEvent);
        }
Ejemplo n.º 11
0
 protected virtual void UpdateGameStateOnMaster(UpdateGameEvent updateEvent)
 {
     var eventData = new EventData((byte)ServerEventCode.UpdateGameState, updateEvent);
     if (this.Application.MasterServerConnection != null)
     {
         this.Application.MasterServerConnection.SendEventIfRegistered(eventData, new SendParameters());
     }
 }
Ejemplo n.º 12
0
        public bool Update(UpdateGameEvent updateOperation)
        {
            if (updateOperation.Reinitialize)
            {
                this.StateCleanUp();
            }

            this.UpdateSanityChecks(updateOperation);

            var changed = false;

            if (this.HasBeenCreatedOnGameServer == false)
            {
                this.HasBeenCreatedOnGameServer = true;
                changed = true;
            }

            if (updateOperation.CheckUserIdOnJoin != null)
            {
                this.CheckUserIdOnJoin = updateOperation.CheckUserIdOnJoin.Value;
            }
            if (updateOperation.InactiveCount != this.InactivePlayerCount)
            {
                var oldPlayerCount = this.PlayerCount;
                this.InactivePlayerCount = updateOperation.InactiveCount;
                this.Lobby.GameList.OnPlayerCountChanged(this, oldPlayerCount);
                changed = true;
            }

            if (this.GameServerPlayerCount != updateOperation.ActorCount)
            {
                var oldPlayerCount = this.PlayerCount;
                this.GameServerPlayerCount = updateOperation.ActorCount;
                this.Lobby.GameList.OnPlayerCountChanged(this, oldPlayerCount);
                changed = true;
            }

            if (updateOperation.InactiveUsers != null)
            {
                foreach (var userId in updateOperation.InactiveUsers)
                {
                    this.OnPeerLeftGameOnGameServer(userId, deactivate: true);
                }
            }

            if (updateOperation.NewUsers != null)
            {
                foreach (var userId in updateOperation.NewUsers)
                {
                    this.OnPeerJoinedGameOnGameServer(userId);
                }
            }

            if (updateOperation.RemovedUsers != null)
            {
                foreach (var userId in updateOperation.RemovedUsers)
                {
                    this.OnPeerLeftGameOnGameServer(userId);
                }
            }

            if (updateOperation.FailedToAdd != null)
            {
                foreach (var userId in updateOperation.FailedToAdd)
                {
                    this.OnPeerFailedToJoinOnGameServer(userId);
                }
            }

            if (updateOperation.ExcludedUsers != null)
            {
                this.OnUsersExcluded(updateOperation.ExcludedUsers);
                changed = true;
            }

            if (updateOperation.ExpectedUsers != null)
            {
                this.OnExpectedListUpdated(updateOperation.ExpectedUsers);
                changed = true;
            }

            if (updateOperation.MaxPlayers.HasValue && updateOperation.MaxPlayers.Value != this.MaxPlayer)
            {
                this.MaxPlayer = updateOperation.MaxPlayers.Value;
                this.properties[(byte)GameParameter.MaxPlayers] = this.MaxPlayer;
                changed = true;
            }

            if (updateOperation.IsOpen.HasValue && updateOperation.IsOpen.Value != this.IsOpen)
            {
                this.IsOpen = updateOperation.IsOpen.Value;
                this.properties[(byte)GameParameter.IsOpen] = this.MaxPlayer;
                changed = true;
            }

            if (updateOperation.IsVisible.HasValue && updateOperation.IsVisible.Value != this.IsVisible)
            {
                this.IsVisible = updateOperation.IsVisible.Value;
                changed = true;
            }

            if (updateOperation.PropertyFilter != null)
            {
                var lobbyProperties = new HashSet<object>(updateOperation.PropertyFilter);

                var keys = new object[this.properties.Keys.Count];
                this.properties.Keys.CopyTo(keys, 0);

                foreach (var key in keys)
                {
                    if (lobbyProperties.Contains(key) == false)
                    {
                        this.properties.Remove(key);
                        changed = true;
                    }
                }

                // add max players even if it's not in the property filter
                // MaxPlayer is always reported to the client and available
                // for JoinRandom matchmaking
                this.properties[(byte)GameParameter.MaxPlayers] = (byte)this.MaxPlayer;
            }

            if (updateOperation.GameProperties != null)
            {
                changed |= this.UpdateProperties(updateOperation.GameProperties);
            }

            this.IsJoinable = this.CheckIsGameJoinable();

            if (updateOperation.IsPersistent.HasValue && updateOperation.IsPersistent.Value != this.IsPersistent)
            {
                this.IsPersistent = updateOperation.IsPersistent.Value;
                changed = true;
            }

            return changed;
        }
Ejemplo n.º 13
0
        void UpdateSanityChecks(UpdateGameEvent updateOperation)
        {
            if (updateOperation == null) throw new ArgumentNullException("updateOperation");

            //if (updateOperation.InactiveUsers != null)
            //{
            //    Debug.Assert(this.GameServerPlayerCount != updateOperation.ActorCount
            //      && updateOperation.InactiveCount != this.InactivePlayerCount,
            //      "Inactive added but neither ActorCount nor InactiveCount changed");
            //}

            // this may happen if user was not added on GS
            //if (updateOperation.RemovedUsers != null)
            //{
            //    Debug.Assert(this.GameServerPlayerCount != updateOperation.ActorCount || updateOperation.InactiveCount != this.InactivePlayerCount,
            //      "Player removed but neither ActorCount nor InactiveCount changed");
            //}
            //if (updateOperation.NewUsers != null)
            //{
            //    Debug.Assert(this.GameServerPlayerCount != updateOperation.ActorCount, "New added but ActorCount not changed");
            //}
        }
Ejemplo n.º 14
0
        public bool UpdateGameState(UpdateGameEvent updateOperation, out GameState gameState)
        {
            // try to get the game state
            if (this.gameDict.TryGet(updateOperation.GameId, out gameState) == false)
            {
                if (updateOperation.Reinitialize)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Reinitialize: Add Game State {0}", updateOperation.GameId);
                    }

                    this.AddGameState(gameState);

                }
                else
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Game not found: {0}", updateOperation.GameId);
                    }
                    return false;
                }
            }

            bool oldVisible = gameState.IsVisbleInLobby;
            bool changed = gameState.Update(updateOperation);

            if (changed)
            {
                if (gameState.IsVisbleInLobby)
                {
                    this.changedGames[gameState.Id] = gameState;

                    if (oldVisible == false)
                    {
                        this.removedGames.Remove(gameState.Id);
                    }
                }
                else
                {
                    if (oldVisible)
                    {
                        this.changedGames.Remove(gameState.Id);
                        this.removedGames.Add(gameState.Id);
                    }
                }

                if (log.IsDebugEnabled)
                {
                    LogGameState("UpdateGameState: ", gameState);
                }
            }

            return true;
        }
Ejemplo n.º 15
0
        protected bool GetOrAddUpdatedGameState(UpdateGameEvent updateOperation, out GameState gameState)
        {
            // try to get the game state
            gameState = GetGameState(updateOperation.GameId);
            if (gameState == null)
            {
                if (updateOperation.Reinitialize)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Reinitialize: Add Game State {0}", updateOperation.GameId);
                    }

                    if (!this.Lobby.Application.TryGetGame(updateOperation.GameId, out gameState))
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("Could not find game to reinitialize: {0}", updateOperation.GameId);
                        }

                        return false;
                    }

                    this.AddGameState(gameState);
                }
                else
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Game not found: {0}", updateOperation.GameId);
                    }

                    return false;
                }
            }
            return true;
        }
Ejemplo n.º 16
0
 public void UpdateGameState(UpdateGameEvent operation, IncomingGameServerPeer incomingGameServerPeer)
 {
     this.ExecutionFiber.Enqueue(() => this.HandleUpdateGameState(operation, incomingGameServerPeer));
 }
        protected virtual void HandleUpdateGameState(IEventData eventData)
        {
            if (log.IsDebugEnabled)
            {
                log.DebugFormat("HandleUpdateGameState");
            }

            var updateEvent = new UpdateGameEvent(this.Protocol, eventData);
            if (updateEvent.IsValid == false)
            {
                string msg = updateEvent.GetErrorMessage();
                log.ErrorFormat("UpdateGame contract error: {0}", msg);
                return;
            }

            this.application.Lobby.UpdateGameState(updateEvent, this);
        }
Ejemplo n.º 18
0
        private void HandleUpdateGameState(UpdateGameEvent operation, IncomingGameServerPeer incomingGameServerPeer)
        {
            try
            {
                GameState gameState;

                if (this.GameList.UpdateGameState(operation, incomingGameServerPeer, out gameState) == false)
                {
                    return;
                }

                this.SchedulePublishGameChanges();

                this.OnGameStateChanged(gameState);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
Ejemplo n.º 19
0
        public bool Update(UpdateGameEvent updateOperation)
        {
            bool changed = false;

            if (this.IsCreatedOnGameServer == false)
            {
                this.IsCreatedOnGameServer = true;
                changed = true;
            }

            if (this.GameServerPlayerCount != updateOperation.ActorCount)
            {
                this.GameServerPlayerCount = updateOperation.ActorCount;
                changed = true;
            }

            if (updateOperation.NewUsers != null)
            {
                foreach (string userId in updateOperation.NewUsers)
                {
                    this.OnPeerJoinedGameServer(userId);
                }
            }

            if (updateOperation.RemovedUsers != null)
            {
                foreach (string userId in updateOperation.RemovedUsers)
                {
                    this.OnPeerLeftGameServer(userId);
                }
            }

            if (updateOperation.MaxPlayers.HasValue && updateOperation.MaxPlayers.Value != this.MaxPlayer)
            {
                this.MaxPlayer = updateOperation.MaxPlayers.Value;
                this.properties[(byte)GameParameter.MaxPlayer] = this.MaxPlayer;
                changed = true;
            }

            if (updateOperation.IsOpen.HasValue && updateOperation.IsOpen.Value != this.IsOpen)
            {
                this.IsOpen = updateOperation.IsOpen.Value;
                this.properties[(byte)GameParameter.IsOpen] = this.MaxPlayer;
                changed = true;
            }

            if (updateOperation.IsVisible.HasValue && updateOperation.IsVisible.Value != this.IsVisible)
            {
                this.IsVisible = updateOperation.IsVisible.Value;
                changed = true;
            }

            if (updateOperation.PropertyFilter != null)
            {
                var lobbyProperties = new HashSet<object>(updateOperation.PropertyFilter);

                var keys = new object[this.properties.Keys.Count];
                this.properties.Keys.CopyTo(keys, 0);

                foreach (var key in keys)
                {
                    if (lobbyProperties.Contains(key) == false)
                    {
                        this.properties.Remove(key);
                        changed = true;
                    }
                }

                // add max players even if it's not in the property filter
                // MaxPlayer is always reported to the client and available 
                // for JoinRandom matchmaking
                this.properties[(byte)GameParameter.MaxPlayer] = (byte)this.MaxPlayer;
            }

            if (updateOperation.GameProperties != null)
            {
                changed |= this.UpdateProperties(updateOperation.GameProperties);
            }

            return changed;
        }
Ejemplo n.º 20
0
        private void HandleUpdateGameState(UpdateGameEvent operation, IncomingGameServerPeer incomingGameServerPeer)
        {
            try
            {
                GameState gameState;

                if (operation.Reinitialize && !this.GameList.ContainsGameId(operation.GameId))
                {
                    this.GameList.AddGameState(
                        new GameState(operation.GameId, (byte)this.MaxPlayersDefault, incomingGameServerPeer));
                }

                if (this.GameList.UpdateGameState(operation, out gameState) == false)
                {
                    return;
                }

                if (this.schedule == null)
                {
                    this.schedule = this.ExecutionFiber.Schedule(this.PublishGameChanges, 1000);
                }

                this.OnGameStateChanged(gameState);
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }