예제 #1
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "GameState" /> class.
 /// </summary>
 /// <param name = "id">
 ///   The game id.
 /// </param>
 /// <param name = "maxPlayer">
 ///   The maximum number of player who can join the game.
 /// </param>
 /// <param name = "gameServerPeer">
 ///   The game server peer.
 /// </param>
 public GameState(string id, byte maxPlayer, IncomingGameServerPeer gameServerPeer)
 {
     this.Id = id;
     this.MaxPlayer = maxPlayer;
     this.IsOpen = true;
     this.IsVisible = true;
     this.IsCreatedOnGameServer = false;
     this.GameServerPlayerCount = 0;
     this.gameServer = gameServerPeer;
 }
예제 #2
0
        public void OnGameServerRemoved(IncomingGameServerPeer gameServerPeer)
        {
            this.defaultLobby.RemoveGameServer(gameServerPeer);

            lock (this.lobbyDict)
            {
                foreach (var lobby in this.lobbyDict.Values)
                {
                    lobby.RemoveGameServer(gameServerPeer);
                }
            }
        }
예제 #3
0
        public bool GetOrCreateGame(string gameId, AppLobby lobby, IGameList gameList, byte maxPlayer, IncomingGameServerPeer gameServerPeer, out GameState gameState)
        {
            lock (this.gameDict)
            {
                if (this.gameDict.TryGetValue(gameId, out gameState))
                {
                    return false;
                }

                gameState = new GameState(lobby, gameId, maxPlayer, gameServerPeer);
                this.gameDict.Add(gameId, gameState);
                return true;
            }
        }
        private void OnUpdateGameServerStats(IncomingGameServerPeer gameServerPeer, int peerCount, int gameCount)
        {
            GameServerApplicationState stats;
            if (this.gameServerStats.TryGetValue(gameServerPeer, out stats) == false)
            {
                stats = new GameServerApplicationState();
                this.gameServerStats.Add(gameServerPeer, stats);
            }

            int playerDiff = peerCount - stats.PlayerCount;
            int gameDiff = gameCount - stats.GameCount;
            this.PeerCountGameServer += playerDiff;
            this.GameCount += gameDiff;
            stats.PlayerCount = peerCount;
            stats.GameCount = gameCount;

            if (playerDiff != 0 || gameDiff != 0)
            {
                this.OnStatsUpdated();
            }
        }
예제 #5
0
        public bool TryCreateGame(string gameId, AppLobby lobby, IGameList gameList, byte maxPlayer, IncomingGameServerPeer gameServerPeer, out GameState gameState)
        {
            bool result = false;

            lock (this.gameDict)
            {
                if (this.gameDict.TryGetValue(gameId, out gameState) == false)
                {
                    gameState = new GameState(lobby, gameId, maxPlayer, gameServerPeer);
                    this.gameDict.Add(gameId, gameState);
                    result = true;
                }
            }

            if (result)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Created game: gameId={0}, appId={1}", gameId, this.ApplicationId);
                }
            }

            return result;
        }
예제 #6
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;
 }
 public virtual void RemoveGameServerFromLobby(IncomingGameServerPeer gameServer)
 {
     this.Lobby.RemoveGameServer(gameServer);
 }
예제 #8
0
 public void UpdateGameServerStats(IncomingGameServerPeer gameServerPeer, int peerCount, int gameCount)
 {
     this.fiber.Enqueue(() => this.OnUpdateGameServerStats(gameServerPeer, peerCount, gameCount));
 }
예제 #9
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);
            }
        }
예제 #10
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;
        }
예제 #11
0
        public void RemoveGameServer(IncomingGameServerPeer gameServer)
        {
            // find games belonging to the game server instance
            var instanceGames = this.gameDict.Where(gameState => gameState.GameServer == gameServer).ToList();

            // remove game server instance games
            foreach (var gameState in instanceGames)
            {
                this.RemoveGameState(gameState.Id);
            }
        }
예제 #12
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);
            }
        }
예제 #13
0
 public virtual void RemoveGameServerFromLobby(IncomingGameServerPeer gameServerPeer)
 {
     this.DefaultApplication.OnGameServerRemoved(gameServerPeer);
 }
예제 #14
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);

                }
                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;
        }
예제 #15
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "GameState" /> class.
 /// </summary>
 /// <param name="lobby">
 /// The lobby to which the game belongs.
 /// </param>
 /// <param name = "id">
 ///   The game id.
 /// </param>
 /// <param name = "maxPlayer">
 ///   The maximum number of player who can join the game.
 /// </param>
 /// <param name = "gameServerPeer">
 ///   The game server peer.
 /// </param>
 public GameState(AppLobby lobby, string id, byte maxPlayer, IncomingGameServerPeer gameServerPeer)
 {
     this.Lobby = lobby;
     this.Id = id;
     this.MaxPlayer = maxPlayer;
     this.IsOpen = true;
     this.IsVisible = true;
     this.HasBeenCreatedOnGameServer = false;
     this.GameServerPlayerCount = 0;
     this.gameServer = gameServerPeer;
     this.IsJoinable = this.CheckIsGameJoinable();
     this.activeUserIdList = new List<string>(maxPlayer > 0 ? maxPlayer : 5);
     this.inactiveUserIdList = new List<string>(maxPlayer > 0 ? maxPlayer : 5);
     this.expectedUsersList = new List<string>(maxPlayer > 0 ? maxPlayer : 5);
     this.excludedActors = new List<ExcludedActorInfo>();
 }
예제 #16
0
        private void HandleRemoveGameServer(IncomingGameServerPeer gameServer)
        {
            try
            {
                this.GameList.RemoveGameServer(gameServer);

                if (this.schedule == null)
                {
                    this.schedule = this.ExecutionFiber.Schedule(this.PublishGameChanges, 1000);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
            }
        }
예제 #17
0
 // savedgames-poc:
 public void ResetGameServer()
 {
     this.gameServer = null;
 }
예제 #18
0
        public string GetServerAddress(ILobbyPeer peer)
        {
            string address;

            // savedgames-poc:
            if (this.gameServer == null)
            {
                IncomingGameServerPeer newGameServer;
                if (!this.Lobby.Application.LoadBalancer.TryGetServer(out newGameServer))
                {
                    throw new Exception("Failed to get server instance.");
                }
                this.gameServer = newGameServer;
                log.DebugFormat("GetServerAddress: game={0} got new host GS={1}", this.Id, this.gameServer.Key);
            }

            var useHostnames = peer.UseHostnames; // || config settimg ForceHostnames

            var useIPv4 = peer.LocalIPAddress.AddressFamily == AddressFamily.InterNetwork;
            switch (peer.NetworkProtocol)
            {
                case NetworkProtocolType.Udp:
                    address = useHostnames ? this.GameServer.UdpHostname : (useIPv4 ? this.GameServer.UdpAddress : this.GameServer.UdpAddressIPv6);
                    break;
                case NetworkProtocolType.Tcp:
                    address = useHostnames ? this.GameServer.TcpHostname : (useIPv4 ? this.GameServer.TcpAddress : this.GameServer.TcpAddressIPv6);
                    break;
                case NetworkProtocolType.WebSocket:
                    address = useHostnames ? this.GameServer.WebSocketHostname : (useIPv4 ? this.GameServer.WebSocketAddress : this.GameServer.WebSocketAddressIPv6);
                    break;
                case NetworkProtocolType.SecureWebSocket:
                    address = this.GameServer.SecureWebSocketHostname;
                    break;
                case NetworkProtocolType.Http:
                    if (peer.LocalPort == 443) // https:
                    {
                        address = this.gameServer.SecureHttpHostname;
                    }
                    else // http:
                    {
                        address = useIPv4 ? this.gameServer.HttpAddress : this.gameServer.HttpAddressIPv6;
                    }
                    break;
                default:
                    throw new NotSupportedException(string.Format("No GS address configured for Protocol {0} (Peer Type: {1})", peer.NetworkProtocol, ((PeerBase)peer).NetworkProtocol));
            }
            if (string.IsNullOrEmpty(address))
            {
                throw new NotSupportedException(
                    string.Format("No GS address configured for Protocol {0} (Peer Type: {1}, AddressFamily: {2})", peer.NetworkProtocol, peer.NetworkProtocol, peer.LocalIPAddress.AddressFamily));
            }
            return address;
        }
예제 #19
0
        public GameState(AppLobby lobby, Hashtable data)
        {
            this.Lobby = lobby;
            this.Id = (string)data[GameId];
            this.MaxPlayer = (int)data[MaxPlayerId];
            this.IsOpen = (bool)data[IsOpenId];
            this.IsVisible = (bool)data[IsVisibleId];

            this.InactivePlayerCount = (int)data[InactiveCountId];
            this.createDateUtc = DateTime.FromBinary((long)data[CreateDateId]);
            this.activeUserIdList = new List<string>((string[])data[UserListId]);
            this.inactiveUserIdList = new List<string>((string[])data[InactiveUsersId]);
            this.expectedUsersList = new List<string>((string[])data[ExpectedUsersId]);
            this.excludedActors = new List<ExcludedActorInfo>((ExcludedActorInfo[])data[ExcludedUsersId]);
            this.properties = (Dictionary<object, object>)data[PropertiesId];

            this.HasBeenCreatedOnGameServer = true;
            this.GameServerPlayerCount = 0;
            this.gameServer = null;
            this.IsJoinable = this.CheckIsGameJoinable();
        }
예제 #20
0
 public virtual void OnGameServerRemoved(IncomingGameServerPeer gameServer)
 {
     this.LobbyFactory.OnGameServerRemoved(gameServer);
 }
예제 #21
0
 public void UpdateGameState(UpdateGameEvent operation, IncomingGameServerPeer incomingGameServerPeer)
 {
     this.ExecutionFiber.Enqueue(() => this.HandleUpdateGameState(operation, incomingGameServerPeer));
 }
예제 #22
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);
            }
        }
예제 #23
0
 private void HandleRemoveGameServer(IncomingGameServerPeer gameServer)
 {
     try
     {
         this.GameList.RemoveGameServer(gameServer);
         this.SchedulePublishGameChanges();
     }
     catch (Exception ex)
     {
         log.Error(ex);
     }
 }
예제 #24
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;
        }
예제 #25
0
        public void RemoveGameServer(IncomingGameServerPeer gameServer)
        {
            // find games belonging to the game server instance
            var instanceGames = new List<GameState>();
            foreach (var gameState in this.GameDict.Values)
            {
                if (gameState.GameServer == gameServer)
                {
                    instanceGames.Add(gameState);
                }
            }

            // remove game server instance games
            foreach (GameState gameState in instanceGames)
            {
                this.RemoveGameState(gameState.Id);
            }
        }
예제 #26
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;
        }
예제 #27
0
 public void RemoveGameServer(IncomingGameServerPeer gameServer)
 {
     this.ExecutionFiber.Enqueue(() => this.HandleRemoveGameServer(gameServer));
 }