public void OnGamePlayerPreJoinEvent(IGamePlayerJoiningEvent e)
        {
            var client = e.Player.Client;
            var host   = e.Game.Host;

            if (host != null)
            {
                var hostMods   = host.Client.GetReactor()?.Mods;
                var clientMods = client.GetReactor()?.Mods;

                var clientMissing = hostMods != null
                    ? hostMods.Where(mod => mod.Side == PluginSide.Both && (clientMods == null || !clientMods.Contains(mod))).ToArray()
                    : Array.Empty <Mod>();

                var hostMissing = clientMods != null
                    ? clientMods.Where(mod => mod.Side == PluginSide.Both && (hostMods == null || !hostMods.Contains(mod))).ToArray()
                    : Array.Empty <Mod>();

                if (clientMissing.Any() || hostMissing.Any())
                {
                    var message = new StringBuilder();

                    if (clientMissing.Any())
                    {
                        message.Append("You are missing: ");
                        message.AppendJoin(", ", clientMissing.Select(x => $"{x.Id} ({x.Version})"));
                        message.AppendLine();
                    }

                    if (hostMissing.Any())
                    {
                        message.Append("Host is missing: ");
                        message.AppendJoin(", ", hostMissing.Select(x => $"{x.Id} ({x.Version})"));
                        message.AppendLine();
                    }

                    e.JoinResult = GameJoinResult.CreateCustomError(message.ToString());
                }
            }
        }
예제 #2
0
        private async ValueTask <GameJoinResult> AddClientSafeAsync(ClientBase client)
        {
            // Check if the IP of the player is banned.
            if (client.Connection != null && _bannedIps.Contains(client.Connection.EndPoint.Address))
            {
                return(GameJoinResult.FromError(GameJoinError.Banned));
            }

            var player = client.Player;

            // Check if;
            // - The player is already in this game.
            // - The game is full.
            if (player?.Game != this && _players.Count >= Options.MaxPlayers)
            {
                return(GameJoinResult.FromError(GameJoinError.GameFull));
            }

            if (GameState == GameStates.Starting || GameState == GameStates.Started)
            {
                return(GameJoinResult.FromError(GameJoinError.GameStarted));
            }

            if (GameState == GameStates.Destroyed)
            {
                return(GameJoinResult.FromError(GameJoinError.GameDestroyed));
            }

            if (Host != null)
            {
                foreach (var hostMod in Host.Client.Mods)
                {
                    if (hostMod.Side == PluginSide.Both && client.Mods.All(clientMod => hostMod.Id != clientMod.Id))
                    {
                        return(GameJoinResult.CreateCustomError($"You are missing {hostMod.Id} - {hostMod.Version}"));
                    }
                }

                foreach (var clientMod in client.Mods)
                {
                    if (clientMod.Side == PluginSide.Both && Host.Client.Mods.All(hostMod => clientMod.Id != hostMod.Id))
                    {
                        return(GameJoinResult.CreateCustomError($"Host of this game is missing {clientMod.Id} - {clientMod.Version}"));
                    }
                }
            }

            var isNew = false;

            if (player == null || player.Game != this)
            {
                var clientPlayer = new ClientPlayer(_serviceProvider.GetRequiredService <ILogger <ClientPlayer> >(), client, this);

                if (!_clientManager.Validate(client))
                {
                    return(GameJoinResult.FromError(GameJoinError.InvalidClient));
                }

                isNew         = true;
                player        = clientPlayer;
                client.Player = clientPlayer;
            }

            // Check current player state.
            if (player.Limbo == LimboStates.NotLimbo)
            {
                return(GameJoinResult.FromError(GameJoinError.InvalidLimbo));
            }

            if (GameState == GameStates.Ended)
            {
                await HandleJoinGameNext(player, isNew);

                return(GameJoinResult.CreateSuccess(player));
            }

            await HandleJoinGameNew(player, isNew);

            return(GameJoinResult.CreateSuccess(player));
        }