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; }
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; }
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; } }
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); } }
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; }
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); } }
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)); } } }
protected virtual DebugGameResponse GetDebugGameResponse(MasterClientPeer peer, GameState gameState) { return(new DebugGameResponse { Address = gameState.GetServerAddress(peer), Info = gameState.ToString() }); }
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; }
public virtual void AddGameState(GameState gameState) { this.gameDict.Add(gameState.Id, gameState); }
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); }
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); } }
public abstract ErrorCode TryGetRandomGame(JoinRandomGameRequest joinRequest, ILobbyPeer peer, out GameState gameState, out string message);
protected virtual void OnGameStateChanged(GameState gameState) { }
protected override bool RemoveGameState(GameState gameState) { this.gameDatabase.Delete(gameState.Id); return base.RemoveGameState(gameState); }
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 void AddGameState(GameState gameState) { this.gameDict.Add(gameState.Id, gameState); if (this.IsGameJoinable(gameState)) { this.gameDatabase.InsertGameState(gameState.Id, gameState.Properties); } }
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; }
public virtual void OnGameJoinableChanged(GameState gameState) { }
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 ); } }
public bool TryGetGame(string gameId, out GameState gameState) { return this.gameDict.TryGet(gameId, out gameState); }
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); } } }
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; }
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); } }
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; }
public bool TryGetGame(string gameId, out GameState gameState) { lock (this.gameDict) { return this.gameDict.TryGetValue(gameId, out gameState); } }
// 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; }
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); } }
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; }
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); } }
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; }
protected virtual object GetJoinRandomGameResponse(MasterClientPeer peer, GameState gameState) { return(new JoinRandomGameResponse { GameId = gameState.Id, Address = gameState.GetServerAddress(peer) }); }