public void AddPlayer(SkyPlayer player) { InstanceInfo bestGameInstance = null; GameInfo bestAvailableGame = null; //SkyUtil.log($"Checking available games from all instances for {GameName} ({_gameInstances.Count} total instances to search)"); //Check current instance first if (_gameInstances.ContainsKey("local") && !SkyCoreAPI.IsRebootQueued) //Avoid moving players to this server if it's about to reboot { InstanceInfo instanceInfo = _gameInstances["local"]; string currentGameId = null; if (player.Level is GameLevel level) { currentGameId = level.GameId; } GameInfo nextBestGame = null; foreach (GameInfo gameInfo in instanceInfo.AvailableGames) { //SkyUtil.log($"Checking {gameInfo.GameId} on {instanceInfo.HostAddress}"); if ((bestAvailableGame == null || gameInfo.CurrentPlayers > bestAvailableGame.CurrentPlayers)) { //Try to avoid placing the player in the game they just came from. //Use this game as a fallback to avoid moving players off this instance. if (currentGameId != null && currentGameId.Equals(gameInfo.GameId)) { bestGameInstance = instanceInfo; nextBestGame = gameInfo; continue; } //SkyUtil.log("Found best game!"); bestGameInstance = instanceInfo; bestAvailableGame = gameInfo; } } if (bestAvailableGame == null) { bestAvailableGame = nextBestGame; } } if (bestAvailableGame == null) { foreach (InstanceInfo instanceInfo in _gameInstances.Values) { //SkyUtil.log($"Checking instance {instanceInfo.HostAddress} Available Servers: {instanceInfo.AvailableGames.Count}"); foreach (GameInfo gameInfo in instanceInfo.AvailableGames) { //SkyUtil.log($"Checking {gameInfo.GameId} on {instanceInfo.HostAddress}"); if (bestAvailableGame == null || gameInfo.CurrentPlayers > bestAvailableGame.CurrentPlayers) { //SkyUtil.log("Found best game!"); bestGameInstance = instanceInfo; bestAvailableGame = gameInfo; } } } } if (bestAvailableGame == null) { player.Freeze(false); //Unfreeze TitleUtil.SendCenteredSubtitle(player, $"§c§lGAME {(GetCurrentPlayers() > 0 ? "FULL" : "UNAVAILABLE")}§r\n§7Try joining again soon!", false); } else { if (player.Level is GameLevel level) { if (player.Level.LevelId.Equals(bestAvailableGame.GameId)) { return; //Cannot change game into current game. } //Remove player from level to avoid issues level.RemovePlayer(player); } if (bestGameInstance.HostAddress.Equals("local")) { SkyCoreAPI.Instance.GameModes[GameName].InstantQueuePlayer(player, bestAvailableGame); } else { ExternalGameHandler.RedisPool.GetSubscriber().PublishAsync($"{GameName}_join", $"{player.Username}:{GameName}:{bestAvailableGame.GameId}"); McpeTransfer transferPacket = new McpeTransfer { serverAddress = bestGameInstance.HostAddress, port = bestGameInstance.HostPort }; player.SendPackage(transferPacket); MiNET.Worlds.Level playerLevel = player.Level; RunnableTask.RunTaskLater(() => { if (playerLevel.Players.ContainsKey(player.EntityId)) { if (playerLevel is GameLevel gameLevel) { gameLevel.RemovePlayer(player); } playerLevel.RemoveEntity(player); playerLevel.Players.TryRemove(player.EntityId, out _); } }, 1000); } } }
//New GameLevel Method public void AddPlayer(SkyPlayer player) { if (player.Level != this && player.Level is GameLevel level) { level.RemovePlayer(player, true); //Clear from old world } //Remove a player from _incomingPlayers only if it's non-empty. //Avoid claiming a lock for a useless check if (_incomingPlayers.Count > 0) { lock (_incomingPlayers) { if (_incomingPlayers.ContainsKey(player.Username)) { _incomingPlayers.Remove(player.Username); } } } GameTeam defaultTeam = GetDefaultTeam(); SetPlayerTeam(player, defaultTeam); //SkyUtil.log($"Added {player.Username} to team {defaultTeam.DisplayName} in game {GameId}"); /*if (player.Level != this) * { * //Only show the level transition screen to players changing games on this instance * //player.SpawnLevel(this, GameLevelInfo.LobbyLocation, !_incomingPlayers.ContainsKey(player.Username)); * player.SpawnLevel(this, GameLevelInfo.LobbyLocation, false); //Remove loading screen to prevent 'building terrain' issue * } * else //Still teleport the player to the spawn location * { * player.Teleport(GameLevelInfo.LobbyLocation); * }*/ //Fix for maps on first join to an instance player.SpawnLevel(this, GameLevelInfo.LobbyLocation, false); //Remove loading screen to prevent 'building terrain' issue try { CurrentState.InitializePlayer(this, player); } catch (Exception e) { BugSnagUtil.ReportBug(e, this, CurrentState, player); } //Update Time McpeSetTime message = McpeSetTime.CreateObject(); message.time = GameLevelInfo.WorldTime; player.SendPackage(message); // //Pending Tasks //Attempts to execute tasks like spawning NPCs in once a single player has loaded the world if (_shouldSchedule) { _shouldSchedule = false; if (_pendingTasks.Count > 0) { foreach (SkyCoreAPI.PendingTask pendingTask in _pendingTasks) { RunnableTask.RunTaskLater(() => { try { pendingTask.Invoke(); } catch (Exception e) { BugSnagUtil.ReportBug(e, new AnonMetadatable((metadata) => { metadata.AddToTab("PendingTask", "Target", pendingTask.Target); metadata.AddToTab("PendingTask", "Method", pendingTask.Method); })); } }, 250); //Small delay for the level to initialize } _pendingTasks.Clear(); } } }