mirror of
https://github.com/Impostor/Impostor.git
synced 2026-10-20 21:35:42 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b341bea14 | ||
|
|
af371c92ef | ||
|
|
ff49e895ec | ||
|
|
0e9fb4b41c | ||
|
|
4f00bf1ee7 | ||
|
|
a519c0daed | ||
|
|
1f98102e5a | ||
|
|
93fdc83ce7 | ||
|
|
e29552ca28 | ||
|
|
8eee7f888f | ||
|
|
a77e4e17c2 | ||
|
|
9ebf5cd8e9 | ||
|
|
4ffca69714 | ||
|
|
dede1c5b09 | ||
|
|
b31e3bf1e3 | ||
|
|
c9bb8323f4 | ||
|
|
1521410e79 | ||
|
|
be8e4a49f0 | ||
|
|
631e994759 | ||
|
|
c06916084e | ||
|
|
c9c044365a | ||
|
|
5ab4bf70da | ||
|
|
58c8bdec26 | ||
|
|
5e080b290b | ||
|
|
97390a0882 |
No files matched your search
+13
-3
@@ -30,12 +30,22 @@ RUN case "$TARGETARCH" in \
|
||||
arm) NETCORE_PLATFORM='linux-arm';; \
|
||||
*) echo "unsupported architecture"; exit 1 ;; \
|
||||
esac && \
|
||||
[[ $VERSIONSUFFIX = "none" ]] && VERSIONSUFFIX=; \
|
||||
[ $VERSIONSUFFIX = "none" ] && VERSIONSUFFIX=; \
|
||||
dotnet publish -c release -o /app -r "$NETCORE_PLATFORM" -p:VersionSuffix="$VERSIONSUFFIX" --no-restore ./src/Impostor.Server/Impostor.Server.csproj
|
||||
|
||||
# Final image.
|
||||
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/runtime:7.0
|
||||
FROM --platform=$TARGETPLATFORM mcr.microsoft.com/dotnet/aspnet:7.0
|
||||
WORKDIR /app
|
||||
COPY --from=build /app ./
|
||||
EXPOSE 22023/udp
|
||||
|
||||
# Add Impostor.Http as a default built-in plugin
|
||||
ADD https://github.com/Impostor/Impostor.Http/releases/download/v0.5.0/Impostor.Http.dll /app/builtin-plugins/
|
||||
# Make it listen to 0.0.0.0 to expose it to the outside world.
|
||||
ENV IMPOSTOR_HTTP_HttpServer__ListenIp=0.0.0.0
|
||||
# Override ASPNETCORE_URLS to stop warning.
|
||||
ENV ASPNETCORE_URLS=
|
||||
# Enable the built-in plugin folder. Use a high number to prevent conflicts with existing configurations
|
||||
ENV IMPOSTOR_PluginLoader__Paths__76=/app/builtin-plugins
|
||||
|
||||
EXPOSE 22023/tcp 22023/udp
|
||||
ENTRYPOINT ["./Impostor.Server"]
|
||||
+33
-15
@@ -1,34 +1,49 @@
|
||||
# Running the server
|
||||
|
||||
There are currently two modes to run the Impostor server. The first way, Single Server, is the simplest one, can handle up to a few hundred simultaneous players, and is the one you should probably use. Multi-Server mode will distribute players across other servers and is intended for advanced users.
|
||||
There are currently two install methods for Impostor: You can install it normally or inside of a Docker container. If you do not have a particular preference, we recommend the normal installation over the Docker container method.
|
||||
|
||||
## Single server
|
||||
## General remarks for both install methods
|
||||
|
||||
### Without Docker
|
||||
This section applies to both the normal installation as well as the Docker (Compose) installation
|
||||
|
||||
1. Install the [.NET 7.0 runtime](https://dotnet.microsoft.com/download/dotnet/7.0). Installing the SDK also works, but is not necessary unless you plan on developing Impostor or Impostor plugins. If you're asked to pick between the normal, desktop or server runtime, the normal runtime is enough, but some plugins may require the ASP.NET Core Runtime as well.
|
||||
2. Find the [latest release](https://github.com/Impostor/Impostor/releases) or the [latest CI build](https://nightly.link/Impostor/Impostor/workflows/ci/master).
|
||||
3. Download the version for your OS (linux/win/osx). Impostor is built for multiple CPU-architectures, you most likely want the x64 version, unless you are running on a Raspberry Pi or another device with an ARM processor.
|
||||
4. Extract the zip.
|
||||
5. Modify `config.json` to your liking. Documentation can be found [here](Server-configuration.md) _(this step is mandatory if you want to expose this server to other devices)_
|
||||
To connect to the server, you need to configure and install a region file on https://impostor.github.io/Impostor/
|
||||
|
||||
Among Us connects to the server using two network services: the (TCP) HTTP service points Among Us to the UDP service, then the UDP service hosts the actual game traffic. Because of this, Impostor uses port 22023 using **both** the TCP and UDP protocols.
|
||||
|
||||
As the phone version of Among Us requires this HTTP connection to be secure, we recommend using a HTTP reverse proxy to terminate SSL on the HTTP service. Setup instructions for this are in the [Impostor.Http readme](https://github.com/Impostor/Impostor.Http#readme).
|
||||
|
||||
Depending on your host you may also need to port forward Impostor to the internet or pass Impostor traffic by your firewall. Port 22023 UDP needs to be accessible for everyone that wants to play on the server, then you also need to portforward your HTTP reverse proxy or port 22023 TCP if you don't use a reverse proxy. As port forwarding changes per host or router configuration, port forwarding is not covered by this guide.
|
||||
|
||||
## Normal installation
|
||||
|
||||
1. Install [.NET 7.0](https://dotnet.microsoft.com/download/dotnet/7.0). We recommend either the ASP.NET Core Runtime or the SDK. The SDK is necessary in case you want to develop Impostor or Impostor plugins.
|
||||
2. Download the [latest release](https://github.com/Impostor/Impostor/releases) or the [latest CI build](https://nightly.link/Impostor/Impostor/workflows/ci/master). Note that Impostor is built for multiple CPU-architectures and operating systems, you most likely want the x64 version, unless you are running on a Raspberry Pi or another device with an Arm processor.
|
||||
3. Extract the zip.
|
||||
4. Download the [Impostor.Http](https://github.com/Impostor/Impostor.Http) plugin and put it in your `plugins` folder. Please note the Reverse Proxy configuration: you either need to configure a reverse proxy to terminate SSL or expose the service to the world by changing ListenIp.
|
||||
5. Modify `config.json` to your liking. Documentation can be found [here](Server-configuration.md). You need to at least change `PublicIp` to the address people will connect to your server to.
|
||||
6. Run `Impostor.Server` (Linux/macOS) or `Impostor.Server.exe` (Windows)
|
||||
7. (OPTIONAL - Linux) Configure a systemd definition file and enable the service to start on boot - [systemd configuration](Server-configuration.md#systemd)
|
||||
|
||||
Depending on your host you may also need to port forward Impostor to the internet. By default Impostor uses port **22023** and the **UDP** protocol. As port forwarding changes per host or router configuration, port forwarding is not covered by this guide.
|
||||
|
||||
To connect to the server, you need to configure a region file on https://impostor.github.io/Impostor/
|
||||
|
||||
### Using Docker
|
||||
## Using Docker
|
||||
|
||||
[](https://hub.docker.com/r/aeonlucid/impostor)
|
||||
[](https://hub.docker.com/r/aeonlucid/impostor)
|
||||
|
||||
Docker is a program that allows you to run programs like Impostor in a container.
|
||||
|
||||
After installing Docker, you can just start a Docker container with `docker run`:
|
||||
|
||||
```
|
||||
docker run -p 22023:22023/udp aeonlucid/impostor:nightly
|
||||
docker run -p 127.0.0.1:22023:22023/tcp -p 22023:22023/udp -e IMPOSTOR_Server__PublicIp=your.public.ip.here aeonlucid/impostor:nightly
|
||||
```
|
||||
|
||||
### Using Docker Compose
|
||||
Please replace `your.public.ip.here` with the public IP address of your server. This is the address Among Us will try to reach your client at.
|
||||
|
||||
To configure the docker container, either use environment variables or mount config.json in your container.
|
||||
|
||||
## Using Docker Compose
|
||||
|
||||
Docker Compose allows you to start a Docker container using a prefined configuration. This is an example configuration you can continue on:
|
||||
|
||||
```
|
||||
version: '3.4'
|
||||
@@ -38,7 +53,10 @@ services:
|
||||
image: aeonlucid/impostor:nightly
|
||||
container_name: impostor
|
||||
ports:
|
||||
- 127.0.0.1:22023:22023/tcp
|
||||
- 22023:22023/udp
|
||||
environment: # Either configure Impostor using environment variables or mount a copy of config.json
|
||||
- IMPOSTOR_Server__PublicIp=your.public.ip.here
|
||||
volumes:
|
||||
- /path/to/local/config.json:/app/config.json # For easy editing of the config
|
||||
- /path/to/local/plugins:/app/plugins # Only needed if using plugins
|
||||
|
||||
@@ -93,3 +93,69 @@ IMPOSTOR_Server__ListenPort=22023
|
||||
IMPOSTOR_AntiCheat__Enabled=true
|
||||
IMPOSTOR_AntiCheat__BanIpFromGame=true
|
||||
```
|
||||
|
||||
# systemd
|
||||
|
||||
Linux users will likely want to create a systemd service definition to manage running the Impostor application. Benefits to using a systemd service include the following:
|
||||
|
||||
- The server process can automatically restart if the process dies
|
||||
- Impostor can be set to start on boot (handy if you do system updates regularly)
|
||||
- You can use systemd targets to ensure the process doesn't start until the system dependencies are met
|
||||
|
||||
Using your favorite text editor, create the following service file:
|
||||
|
||||
```
|
||||
sudoedit /etc/systemd/system/impostor.service
|
||||
```
|
||||
|
||||
Modify the following template to your needs and populate the service file.
|
||||
|
||||
```
|
||||
[Unit]
|
||||
Description=Impostor private Among Us server - https://github.com/Impostor/Impostor
|
||||
|
||||
[Service]
|
||||
# Directory where Impostor is installed
|
||||
WorkingDirectory=/opt/impostor
|
||||
# Path to Impostor binary
|
||||
ExecStart=/opt/impostor/Impostor.Server
|
||||
Restart=always
|
||||
# Restart service after 10 seconds if the dotnet service crashes
|
||||
RestartSec=10
|
||||
KillSignal=SIGTERM
|
||||
SyslogIdentifier=impostor
|
||||
|
||||
# User and group that will run the Impostor server process -- ensure that user is allowed to execute the binary
|
||||
User=impostor
|
||||
Group=impostor
|
||||
TimeoutStopSec=10
|
||||
|
||||
[Install]
|
||||
# Wait until most system services have started before starting Impostor
|
||||
After=multi-user.target
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Reload all systemd unit files to source in the new file you've created.
|
||||
|
||||
```
|
||||
sudo systemctl daemon-reload
|
||||
```
|
||||
|
||||
Start the service.
|
||||
|
||||
```
|
||||
sudo systemctl start impostor.service
|
||||
```
|
||||
|
||||
Check the log for the service and verify it has started correctly -- Hint: Use the Q key to quit out of journalctl.
|
||||
|
||||
```
|
||||
sudo journalctl -u impostor.service
|
||||
```
|
||||
|
||||
If everything has started correctly, ensure the service is set to start on boot.
|
||||
|
||||
```
|
||||
sudo systemctl enable impostor.service
|
||||
```
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<LangVersion>11</LangVersion>
|
||||
<VersionPrefix>1.8.0</VersionPrefix>
|
||||
<VersionPrefix>1.8.4</VersionPrefix>
|
||||
<VersionSuffix>dev</VersionSuffix>
|
||||
<EnforceCodeStyleInBuild Condition="$(MSBuildProjectName)!='Hazel'">true</EnforceCodeStyleInBuild>
|
||||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace Impostor.Api.Config
|
||||
{
|
||||
public class TimeoutConfig
|
||||
{
|
||||
public const string Section = "Timeout";
|
||||
|
||||
public int SpawnTimeout { get; set; } = 2500;
|
||||
|
||||
public int ConnectionTimeout { get; set; } = 2500;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ namespace Impostor.Api.Innersloth
|
||||
SpanishEU = 1024,
|
||||
Arabic = 32,
|
||||
Polish = 128,
|
||||
SChinese = 65536,
|
||||
TChinese = 131072,
|
||||
Irish = 262144,
|
||||
Other = 1,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Impostor.Server
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
public const int SpawnTimeout = 2500;
|
||||
public const int ConnectionTimeout = 2500;
|
||||
}
|
||||
}
|
||||
@@ -513,36 +513,40 @@ namespace Impostor.Server.Net.Inner.Objects
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!RequestedPlayerName.Any())
|
||||
if (RequestedPlayerName.Any())
|
||||
{
|
||||
_logger.LogWarning($"Client sent {nameof(RpcCalls.SetName)} for a player that didn't request it");
|
||||
return false;
|
||||
}
|
||||
var expected = RequestedPlayerName.Dequeue();
|
||||
|
||||
var expected = RequestedPlayerName.Dequeue();
|
||||
|
||||
if (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == expected))
|
||||
{
|
||||
var i = 1;
|
||||
while (true)
|
||||
if (Game.Players.Any(x => x.Character != null && x.Character != this && x.Character.PlayerInfo.PlayerName == expected))
|
||||
{
|
||||
var text = expected + " " + i;
|
||||
|
||||
if (Game.Players.All(x => x.Character == null || x.Character == this || x.Character.PlayerInfo.PlayerName != text))
|
||||
var i = 1;
|
||||
while (true)
|
||||
{
|
||||
expected = text;
|
||||
break;
|
||||
}
|
||||
var text = expected + " " + i;
|
||||
|
||||
i++;
|
||||
if (Game.Players.All(x => x.Character == null || x.Character == this || x.Character.PlayerInfo.PlayerName != text))
|
||||
{
|
||||
expected = text;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (name != expected)
|
||||
{
|
||||
_logger.LogWarning($"Client sent {nameof(RpcCalls.SetName)} with incorrect name");
|
||||
await SetNameAsync(expected);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (name != expected)
|
||||
else
|
||||
{
|
||||
_logger.LogWarning($"Client sent {nameof(RpcCalls.SetName)} with incorrect name");
|
||||
await SetNameAsync(expected);
|
||||
return false;
|
||||
if (await sender.Client.ReportCheatAsync(RpcCalls.SetName, $"Client sent {nameof(RpcCalls.SetName)} for a player that didn't request it"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@ namespace Impostor.Server.Net.Manager
|
||||
{
|
||||
GameVersion.GetVersion(2022, 11, 1), // 2022.12.8
|
||||
GameVersion.GetVersion(2022, 11, 9), // 2022.12.14
|
||||
GameVersion.GetVersion(2022, 12, 2), // 2023.2.28
|
||||
GameVersion.GetVersion(2023, 1, 11), // 2023.3.28s
|
||||
GameVersion.GetVersion(2023, 3, 13), // 2023.3.28a
|
||||
GameVersion.GetVersion(2023, 4, 21), // 2023.6.13
|
||||
GameVersion.GetVersion(2023, 5, 20), // 2023.7.11
|
||||
};
|
||||
|
||||
private readonly ILogger<ClientManager> _logger;
|
||||
|
||||
@@ -36,6 +36,14 @@ namespace Impostor.Server.Net
|
||||
endpoint.Port,
|
||||
_serverConfig.ResolvePublicIp(),
|
||||
_serverConfig.PublicPort);
|
||||
|
||||
// NOTE: If this warning annoys you, set your PublicIp to "localhost"
|
||||
if (_serverConfig.PublicIp == "127.0.0.1")
|
||||
{
|
||||
_logger.LogWarning("Your PublicIp is set to the default value of 127.0.0.1.");
|
||||
_logger.LogWarning("To allow people on other devices to connect to your server, change this value to your Public IP address");
|
||||
_logger.LogWarning("For more info on how to do this see https://github.com/Impostor/Impostor/blob/master/docs/Server-configuration.md");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Net;
|
||||
@@ -13,11 +13,13 @@ namespace Impostor.Server.Net.State
|
||||
{
|
||||
private readonly ILogger<ClientPlayer> _logger;
|
||||
private readonly Timer _spawnTimeout;
|
||||
private readonly int _spawnTimeoutTime;
|
||||
|
||||
public ClientPlayer(ILogger<ClientPlayer> logger, ClientBase client, Game game)
|
||||
public ClientPlayer(ILogger<ClientPlayer> logger, ClientBase client, Game game, int timeOutTime)
|
||||
{
|
||||
_logger = logger;
|
||||
_spawnTimeout = new Timer(RunSpawnTimeout!, null, -1, -1);
|
||||
_spawnTimeoutTime = timeOutTime;
|
||||
|
||||
Game = game;
|
||||
Client = client;
|
||||
@@ -41,7 +43,7 @@ namespace Impostor.Server.Net.State
|
||||
|
||||
public void InitializeSpawnTimeout()
|
||||
{
|
||||
_spawnTimeout.Change(Constants.SpawnTimeout, -1);
|
||||
_spawnTimeout.Change(_spawnTimeoutTime, -1);
|
||||
}
|
||||
|
||||
public void DisableSpawnTimeout()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api.Games;
|
||||
@@ -166,14 +166,6 @@ namespace Impostor.Server.Net.State
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
@@ -184,11 +176,19 @@ namespace Impostor.Server.Net.State
|
||||
return GameJoinResult.FromError(GameJoinError.GameDestroyed);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
var isNew = false;
|
||||
|
||||
if (player == null || player.Game != this)
|
||||
{
|
||||
var clientPlayer = new ClientPlayer(_serviceProvider.GetRequiredService<ILogger<ClientPlayer>>(), client, this);
|
||||
var clientPlayer = new ClientPlayer(_serviceProvider.GetRequiredService<ILogger<ClientPlayer>>(), client, this, _timeoutConfig.SpawnTimeout);
|
||||
|
||||
if (!_clientManager.Validate(client))
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Impostor.Api;
|
||||
using Impostor.Api.Innersloth;
|
||||
@@ -76,7 +76,7 @@ namespace Impostor.Server.Net.State
|
||||
// Player can refuse to be kicked and keep the connection open, check for this.
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(Constants.ConnectionTimeout);
|
||||
await Task.Delay(_timeoutConfig.ConnectionTimeout);
|
||||
|
||||
if (player.Client.Connection.IsConnected && player.Client.Connection is HazelConnection hazel)
|
||||
{
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Impostor.Server.Net.State
|
||||
private readonly HashSet<IPAddress> _bannedIps;
|
||||
private readonly IEventManager _eventManager;
|
||||
private readonly CompatibilityConfig _compatibilityConfig;
|
||||
private readonly TimeoutConfig _timeoutConfig;
|
||||
|
||||
public Game(
|
||||
ILogger<Game> logger,
|
||||
@@ -41,7 +42,8 @@ namespace Impostor.Server.Net.State
|
||||
GameFilterOptions filterOptions,
|
||||
ClientManager clientManager,
|
||||
IEventManager eventManager,
|
||||
IOptions<CompatibilityConfig> compatibilityConfig)
|
||||
IOptions<CompatibilityConfig> compatibilityConfig,
|
||||
IOptions<TimeoutConfig> timeoutConfig)
|
||||
{
|
||||
_logger = logger;
|
||||
_serviceProvider = serviceProvider;
|
||||
@@ -59,6 +61,7 @@ namespace Impostor.Server.Net.State
|
||||
_clientManager = clientManager;
|
||||
_eventManager = eventManager;
|
||||
_compatibilityConfig = compatibilityConfig.Value;
|
||||
_timeoutConfig = timeoutConfig.Value;
|
||||
Items = new ConcurrentDictionary<object, object>();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,19 @@ namespace Impostor.Server.Plugins
|
||||
CheckPaths(pluginPaths);
|
||||
CheckPaths(libraryPaths);
|
||||
|
||||
// Add library path for ASP.NET Core. This is useful for plugins that depend on ASP.NET Core,
|
||||
// like Impostor.Http. The path contains the .NET version number, so it changes regularly.
|
||||
var aspNetPath = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory()
|
||||
.Replace("Microsoft.NETCore.App", "Microsoft.AspNetCore.App");
|
||||
if (Directory.Exists(aspNetPath))
|
||||
{
|
||||
libraryPaths.Add(aspNetPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Information("ASP.NET Core not installed, this may cause issues if you have plugins that depend on it");
|
||||
}
|
||||
|
||||
var rootFolder = Directory.GetCurrentDirectory();
|
||||
|
||||
pluginPaths.Add(Path.Combine(rootFolder, "plugins"));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -99,6 +99,7 @@ namespace Impostor.Server
|
||||
services.Configure<AntiCheatConfig>(host.Configuration.GetSection(AntiCheatConfig.Section));
|
||||
services.Configure<CompatibilityConfig>(host.Configuration.GetSection(CompatibilityConfig.Section));
|
||||
services.Configure<ServerConfig>(host.Configuration.GetSection(ServerConfig.Section));
|
||||
services.Configure<TimeoutConfig>(host.Configuration.GetSection(TimeoutConfig.Section));
|
||||
|
||||
services.AddSingleton<ClientManager>();
|
||||
services.AddSingleton<IClientManager>(p => p.GetRequiredService<ClientManager>());
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"Enabled": true,
|
||||
"BanIpFromGame": true
|
||||
},
|
||||
"Timeout": {
|
||||
"SpawnTimeout": 2500,
|
||||
"ConnectionTimeout": 2500
|
||||
},
|
||||
"Compatibility": {
|
||||
"AllowFutureGameVersions": false,
|
||||
"AllowVersionMixing": false
|
||||
|
||||
Reference in new issue
Block a user