Esempio n. 1
0
        public override ErrorCode TryGetRandomGame(JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState, out string message)
        {
            message = null;

            if (this.gameDict.Count == 0)
            {
                gameState = null;
                return ErrorCode.NoMatchFound;
            }

            LinkedListNode<GameState> startNode;
            switch ((JoinRandomType)joinRequest.JoinRandomType)
            {
                default:
                case JoinRandomType.FillRoom:
                    startNode = this.gameDict.First;
                    break;

                case JoinRandomType.SerialMatching:
                    startNode = this.nextJoinRandomStartNode ?? this.gameDict.First;
                    break;

                case JoinRandomType.RandomMatching:
                    var startNodeIndex = this.rnd.Next(this.gameDict.Count);
                    startNode = this.gameDict.GetAtIndex(startNodeIndex);
                    break;
            }

            if (!TryGetRandomGame(startNode, joinRequest, peer, out gameState))
            {
                return ErrorCode.NoMatchFound;
            }

            return ErrorCode.Ok;
        }
Esempio n. 2
0
        public override ErrorCode TryGetRandomGame(JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState, out string message)
        {
            message = null;

            if (this.gameDict.Count == 0)
            {
                gameState = null;
                return ErrorCode.NoMatchFound;
            }

            if (string.IsNullOrEmpty(joinRequest.QueryData))
            {
                var node = this.gameDict.First;
                while (node != null)
                {
                    gameState = node.Value;
                    if (gameState.IsJoinable)
                    {
                        if (!gameState.CheckUserIdOnJoin
                            || (!gameState.ContainsUser(peer.UserId)
                                && !gameState.IsUserInExcludeList(peer.UserId)
                                && gameState.CheckSlots(peer.UserId, joinRequest.AddUsers)))
                        {
                            return ErrorCode.Ok;
                        }
                    }

                    node = node.Next;
                }

                gameState = null;
                return ErrorCode.NoMatchFound;
            }

            string id;
            try
            {
                id = this.gameDatabase.FindMatch(joinRequest.QueryData);
            }
            catch (System.Data.Common.DbException sqlException)
            {
                gameState = null;
                message = sqlException.Message;
                return ErrorCode.OperationInvalid;
            }

            if (string.IsNullOrEmpty(id))
            {
                gameState = null;
                return ErrorCode.NoMatchFound;
            }

            if (!this.gameDict.TryGet(id, out gameState))
            {
                return ErrorCode.NoMatchFound;
            }

            return ErrorCode.Ok;
        }
Esempio n. 3
0
        public override void AddGameState(GameState gameState)
        {
            base.AddGameState(gameState);

            if (gameState.IsJoinable)
            {
                this.gameDatabase.InsertGameState(gameState.Id, gameState.Properties);
            }
        }
        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;
            }
        }
Esempio n. 5
0
        public override void OnGameJoinableChanged(GameState gameState)
        {
            var isJoinable = gameState.IsJoinable;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("OnGameJoinableChanged: gameId={0}, joinable={1}", gameState.Id, isJoinable);
            }

            if (isJoinable)
            {
                this.gameDatabase.InsertGameState(gameState.Id, gameState.Properties);
            }
            else
            {
                this.gameDatabase.Delete(gameState.Id);
            }
        }
Esempio n. 6
0
        private bool TryGetRandomGame(LinkedListNode<GameState> startNode, JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState)
        {
            var node = startNode;

            do
            {
                var game = node.Value;
                node = node.Next ?? this.gameDict.First;

                if (!game.IsOpen || !game.IsVisible || !game.HasBeenCreatedOnGameServer || (game.MaxPlayer > 0 && game.PlayerCount >= game.MaxPlayer))
                {
                    continue;
                }

                if (joinRequest.GameProperties != null && game.MatchGameProperties(joinRequest.GameProperties) == false)
                {
                    continue;
                }

                if (game.CheckUserIdOnJoin
                    && (game.ContainsUser(peer.UserId)
                    || game.IsUserInExcludeList(peer.UserId)
                    || !game.CheckSlots(peer.UserId, joinRequest.AddUsers)))
                {
                    continue;
                }

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Found match. Next start node gameid={0}", node.Value.Id);
                }

                this.nextJoinRandomStartNode = node;
                gameState = game;
                return true;
            }
            while (node != startNode);

            gameState = null;
            return false;
        }
        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;
        }
Esempio n. 8
0
        private void PopulateGameListFromRedis()
        {
            if (this.redisManager == null)
            {
                return;
            }
            try
            {
                var redisGameIdPattern = string.Format("{0}/{1}_*", this.ApplicationId, 0);
                using (var redisClient = this.redisManager.GetDisposableClient<RedisClient>())
                {
                    var keys = redisClient.Client.Keys(redisGameIdPattern);
                    foreach (var key in keys)
                    {
                        var keyString = Encoding.UTF8.GetString(key);
                        var gameData = redisClient.Client.Get(keyString);

                        if (gameData == null || gameData.Length == 0)
                        {
                            continue;
                        }

                        var redisData = (Hashtable)DeserializeNew(gameData);

                        var lobbyName = (string)redisData[GameState.LobbyNameId];
                        var lobbyType = (AppLobbyType)(byte)redisData[GameState.LobbyTypeId];
                        AppLobby lobby;
                        if (!this.LobbyFactory.GetOrCreateAppLobby(lobbyName, lobbyType, out lobby))
                        {
                            // getting here should never happen
                            if (log.IsWarnEnabled)
                            {
                                log.WarnFormat("Could not get or create lobby: name={0}, type={1}", lobbyName, lobbyType);
                            }
                            return;
                        }

                        lock (this.gameDict)
                        {
                            var gameState = new GameState(lobby, redisData);
                            this.gameDict.Add((string)redisData[GameState.GameId], gameState);
                            lobby.GameList.AddGameState(gameState);
                        }
                    }
                }
            }
            catch(Exception e)
            {
                log.ErrorFormat("Exception in PopulateGameListFromRedis. {0}", e);
            }
        }
Esempio n. 9
0
        private void AddGameToExpiryList(GameState gameState)
        {
            if (MasterServerSettings.Default.PersistentGameExpiryMinute != 0)
            {
                return;
            }

            lock (this.expiryList)
            {
                if (gameState.ExpiryListNode != null)
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Expiry time for game '{0}' updated", gameState.Id);
                    }

                    gameState.ExpiryListNode.Value.ExpiryStart = DateTime.UtcNow;
                }
                else
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("Game '{0}' added to expiry list", gameState.Id);
                    }
                    gameState.ExpiryListNode = this.expiryList.AddLast(new GameState.ExpiryInfo(gameState, DateTime.UtcNow));
                }
            }
        }
Esempio n. 10
0
 protected virtual DebugGameResponse GetDebugGameResponse(MasterClientPeer peer, GameState gameState)
 {
     return(new DebugGameResponse
     {
         Address = gameState.GetServerAddress(peer),
         Info = gameState.ToString()
     });
 }
Esempio n. 11
0
        protected override bool RemoveGameState(GameState gameState)
        {
            if (log.IsDebugEnabled)
            {
                LogGameState("RemoveGameState:", gameState);
            }

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

            this.gameDict.Remove(gameState.Id);
            this.PlayerCount -= gameState.PlayerCount;

            return true;
        }
Esempio n. 12
0
 public virtual void AddGameState(GameState gameState)
 {
     this.gameDict.Add(gameState.Id, gameState);
 }
Esempio n. 13
0
        private bool TryCreateGame(Operation operation, string gameId, Hashtable properties, out GameState gameState, out OperationResponse errorResponse)
        {
            // try to get a game server instance from the load balancer
            IncomingGameServerPeer gameServer;

            if (!this.LoadBalancer.TryGetServer(out gameServer))
            {
                errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                {
                    ReturnCode   = (int)ErrorCode.ServerFull,
                    DebugMessage = "Failed to get server instance."
                };
                gameState = null;
                return(false);
            }

            // try to create create new game state
            gameState = new GameState(gameId, (byte)this.MaxPlayersDefault, gameServer);
            if (properties != null)
            {
                bool   changed;
                string debugMessage;

                if (!gameState.TrySetProperties(properties, out changed, out debugMessage))
                {
                    errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                    {
                        ReturnCode   = (int)ErrorCode.OperationInvalid,
                        DebugMessage = debugMessage
                    };
                    return(false);
                }
            }

            this.GameList.AddGameState(gameState);
            this.SchedulePublishGameChanges();

            errorResponse = null;
            return(true);
        }
Esempio n. 14
0
 public virtual void OnPlayerCountChanged(GameState gameState, int oldPlayerCount)
 {
     this.PlayerCount = this.PlayerCount - oldPlayerCount + gameState.PlayerCount;
     if (log.IsDebugEnabled)
     {
         log.DebugFormat("PlayerCount updated:newValue={0}, oldPlayerCount={1}, plyaerCount={2}",
             this.PlayerCount, oldPlayerCount, gameState.PlayerCount);
     }
 }
Esempio n. 15
0
 public abstract ErrorCode TryGetRandomGame(JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState, out string message);
Esempio n. 16
0
 protected virtual void OnGameStateChanged(GameState gameState)
 {
 }
Esempio n. 17
0
 protected override bool RemoveGameState(GameState gameState)
 {
     this.gameDatabase.Delete(gameState.Id);
     return base.RemoveGameState(gameState);
 }
Esempio n. 18
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;
 }
Esempio n. 19
0
        public void AddGameState(GameState gameState)
        {
            this.gameDict.Add(gameState.Id, gameState);

            if (this.IsGameJoinable(gameState))
            {
                this.gameDatabase.InsertGameState(gameState.Id, gameState.Properties);
            }
        }
Esempio n. 20
0
 private LinkedListNode<GameState.ExpiryInfo> RemoveFromExpiryList(GameState state, LinkedListNode<GameState.ExpiryInfo> node)
 {
     state.ExpiryListNode = null;
     var remove = node;
     node = node.Next;
     this.expiryList.Remove(remove);
     return node;
 }
Esempio n. 21
0
 public virtual void OnGameJoinableChanged(GameState gameState)
 {
 }
Esempio n. 22
0
 protected static void LogGameState(string prefix, GameState gameState)
 {
     if (log.IsDebugEnabled)
     {
         log.DebugFormat(
             "{0}id={1}, peers={2}, max={3}, open={4}, visible={5}, peersJoining={6}, inactive={7}, ispersistent={8}",
             prefix,
             gameState.Id,
             gameState.GameServerPlayerCount,
             gameState.MaxPlayer,
             gameState.IsOpen,
             gameState.IsVisible,
             gameState.JoiningPlayerCount,
             gameState.InactivePlayerCount,
             gameState.IsPersistent
             );
     }
 }
Esempio n. 23
0
 public bool TryGetGame(string gameId, out GameState gameState)
 {
     return this.gameDict.TryGet(gameId, out gameState);
 }
Esempio n. 24
0
        protected void HandleVisibility(GameState gameState, bool oldVisible)
        {
            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);
                }
            }
        }
Esempio n. 25
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;
        }
Esempio n. 26
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);
            }
        }
Esempio n. 27
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;
        }
Esempio n. 28
0
 public bool TryGetGame(string gameId, out GameState gameState)
 {
     lock (this.gameDict)
     {
         return this.gameDict.TryGetValue(gameId, out gameState);
     }
 }
Esempio n. 29
0
        // override in GameChannelList, SqlGameList
        protected virtual bool RemoveGameState(GameState gameState)
        {
            if (log.IsDebugEnabled)
            {
                LogGameState("RemoveGameState:", gameState);
            }

            if (this.nextJoinRandomStartNode != null && this.nextJoinRandomStartNode.Value == gameState)
            {
                this.AdvanceNextJoinRandomStartNode();
            }

            gameState.OnRemoved();

            var gameId = gameState.Id;
            this.gameDict.Remove(gameId);
            this.changedGames.Remove(gameId);
            this.removedGames.Add(gameId);

            this.PlayerCount -= gameState.PlayerCount;

            return true;
        }
Esempio n. 30
0
        protected void AddGameToRedis(GameState gameState)
        {
            if (this.redisManager == null)
            {
                return;
            }

            try
            {
                using (var redisClient = this.redisManager.GetDisposableClient<RedisClient>())
                {
                    // making redis game id
                    var redisGameId = this.GetRedisGameId(gameState.Id);
                    var data = SerializeNew(gameState.GetRedisData());

                    redisClient.Client.Set(redisGameId, data,
                        new TimeSpan(0, 0, MasterServerSettings.Default.PersistentGameExpiryMinute, 0));
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("Exception during saving game '{0}' to redis. Exception:{1}", gameState.Id, e);
            }
        }
Esempio n. 31
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;
        }
Esempio n. 32
0
        protected void RemoveGameFromRedis(GameState gameState)
        {
            if (this.redisManager == null)
            {
                return;
            }

            try
            {
                using (var redisClient = this.redisManager.GetDisposableClient<RedisClient>())
                {
                    // making redis game id
                    var redisGameId = this.GetRedisGameId(gameState.Id);

                    redisClient.Client.Remove(redisGameId);
                }
            }
            catch (Exception e)
            {
                log.ErrorFormat("Exception during removing game '{0}' from redis. Exception:{1}", gameState.Id, e);
            }
        }
Esempio n. 33
0
        public override ErrorCode TryGetRandomGame(JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState, out string message)
        {
            message = null;

            foreach (GameState game in this.gameDict)
            {
                if (!game.IsOpen || !game.IsVisible || !game.HasBeenCreatedOnGameServer || (game.MaxPlayer > 0 && game.PlayerCount >= game.MaxPlayer))
                {
                    continue;
                }

                if (joinRequest.GameProperties != null && game.MatchGameProperties(joinRequest.GameProperties) == false)
                {
                    continue;
                }

                if (game.CheckUserIdOnJoin
                    && (game.ContainsUser(peer.UserId)
                    || game.IsUserInExcludeList(peer.UserId)
                    || !game.CheckSlots(peer.UserId, joinRequest.AddUsers)))
                {
                    continue;
                }

                gameState = game;
                return ErrorCode.Ok;
            }

            gameState = null;
            return ErrorCode.NoMatchFound;
        }
Esempio n. 34
0
 protected virtual object GetJoinRandomGameResponse(MasterClientPeer peer, GameState gameState)
 {
     return(new JoinRandomGameResponse {
         GameId = gameState.Id, Address = gameState.GetServerAddress(peer)
     });
 }