From 67e302798fe1283250c01aa358d98040383a650c Mon Sep 17 00:00:00 2001 From: AeonLucid Date: Sat, 24 Oct 2020 01:18:25 +0200 Subject: [PATCH] Add spawn and leave timeout --- .../Net/Objects/InnerPlayerControl.cs | 2 - src/Impostor.Api/Net/IHazelConnection.cs | 7 +++ src/Impostor.Api/Unity/Mathf.cs | 21 ++++++--- src/Impostor.Server/Constants.cs | 8 ++++ .../Net/Hazel/HazelConnection.cs | 10 ++++ src/Impostor.Server/Net/State/ClientPlayer.cs | 46 ++++++++++++++++++- src/Impostor.Server/Net/State/Game.Data.cs | 1 + .../Net/State/Game.Incoming.cs | 3 +- src/Impostor.Server/Net/State/Game.State.cs | 15 ++++++ src/Impostor.Tools.ServerReplay/Program.cs | 10 ++-- 10 files changed, 107 insertions(+), 16 deletions(-) create mode 100644 src/Impostor.Server/Constants.cs diff --git a/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs b/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs index dd2eb8a..57efe8c 100644 --- a/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs +++ b/src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs @@ -395,8 +395,6 @@ namespace Impostor.Api.Innersloth.Net.Objects { PlayerInfo.IsDead = true; PlayerInfo.LastDeathReason = reason; - - Console.WriteLine($"{PlayerInfo.PlayerName,-15} died {reason}"); } } } \ No newline at end of file diff --git a/src/Impostor.Api/Net/IHazelConnection.cs b/src/Impostor.Api/Net/IHazelConnection.cs index a39e0b5..282e439 100644 --- a/src/Impostor.Api/Net/IHazelConnection.cs +++ b/src/Impostor.Api/Net/IHazelConnection.cs @@ -30,5 +30,12 @@ namespace Impostor.Api.Net /// The message. /// ValueTask SendAsync(IMessageWriter writer); + + /// + /// Disconnects the client and invokes the disconnect handler. + /// + /// A reason. + /// + ValueTask DisconnectAsync(string reason); } } \ No newline at end of file diff --git a/src/Impostor.Api/Unity/Mathf.cs b/src/Impostor.Api/Unity/Mathf.cs index ed883c8..4b03417 100644 --- a/src/Impostor.Api/Unity/Mathf.cs +++ b/src/Impostor.Api/Unity/Mathf.cs @@ -13,22 +13,31 @@ /// public static float Clamp(float value, float min, float max) { - if ((double) value < (double) min) + if (value < (double)min) + { value = min; - else if ((double) value > (double) max) + } + else if (value > (double)max) + { value = max; + } + return value; } /// /// Clamps value between 0 and 1 and returns value. /// - /// + /// Value. + /// Clamped value. public static float Clamp01(float value) { - if ((double) value < 0.0) + if (value < 0.0) + { return 0.0f; - return (double) value > 1.0 ? 1f : value; + } + + return (double)value > 1.0 ? 1f : value; } /// @@ -40,6 +49,6 @@ /// /// The interpolated float result between the two float values. /// - public static float Lerp(float a, float b, float t) => a + (b - a) * Mathf.Clamp01(t); + public static float Lerp(float a, float b, float t) => a + ((b - a) * Clamp01(t)); } } \ No newline at end of file diff --git a/src/Impostor.Server/Constants.cs b/src/Impostor.Server/Constants.cs new file mode 100644 index 0000000..62d90b2 --- /dev/null +++ b/src/Impostor.Server/Constants.cs @@ -0,0 +1,8 @@ +namespace Impostor.Server +{ + internal static class Constants + { + public const int SpawnTimeout = 2500; + public const int ConnectionTimeout = 2500; + } +} \ No newline at end of file diff --git a/src/Impostor.Server/Net/Hazel/HazelConnection.cs b/src/Impostor.Server/Net/Hazel/HazelConnection.cs index 3e92594..9a9a071 100644 --- a/src/Impostor.Server/Net/Hazel/HazelConnection.cs +++ b/src/Impostor.Server/Net/Hazel/HazelConnection.cs @@ -32,6 +32,16 @@ namespace Impostor.Server.Net.Hazel return InnerConnection.SendAsync(writer); } + public ValueTask DisconnectAsync(string reason) + { + return InnerConnection.Disconnect(reason); + } + + public void DisposeInnerConnection() + { + InnerConnection.Dispose(); + } + private async ValueTask ConnectionOnDisconnected(DisconnectedEventArgs e) { if (Client != null) diff --git a/src/Impostor.Server/Net/State/ClientPlayer.cs b/src/Impostor.Server/Net/State/ClientPlayer.cs index 30412a1..7bb6164 100644 --- a/src/Impostor.Server/Net/State/ClientPlayer.cs +++ b/src/Impostor.Server/Net/State/ClientPlayer.cs @@ -1,14 +1,24 @@ -using System.Threading.Tasks; +using System; +using System.Threading; +using System.Threading.Tasks; using Impostor.Api.Innersloth.Net; using Impostor.Api.Innersloth.Net.Objects; using Impostor.Api.Net; +using Microsoft.Extensions.Logging; namespace Impostor.Server.Net.State { internal partial class ClientPlayer : IClientPlayer { - public ClientPlayer(ClientBase client, Game game) + private readonly ILogger _logger; + + private Timer _spawnTimeout; + + public ClientPlayer(ILogger logger, ClientBase client, Game game) { + _logger = logger; + _spawnTimeout = new Timer(RunSpawnTimeout, null, -1, -1); + Game = game; Client = client; Limbo = LimboStates.PreSpawn; @@ -27,6 +37,17 @@ namespace Impostor.Server.Net.State public string Scene { get; internal set; } + public void InitializeSpawnTimeout() + { + _spawnTimeout.Change(Constants.SpawnTimeout, -1); + } + + public void DisableSpawnTimeout() + { + _spawnTimeout.Dispose(); + _spawnTimeout = null; + } + /// public bool IsOwner(InnerNetObject netObject) { @@ -44,5 +65,26 @@ namespace Impostor.Server.Net.State { return Game.HandleKickPlayer(Client.Id, true); } + + private async void RunSpawnTimeout(object state) + { + try + { + if (Character == null) + { + _logger.LogInformation("{0} - Player {1} spawn timed out, kicking.", Game.Code, Client.Id); + + await KickAsync(); + } + } + catch (Exception e) + { + _logger.LogError(e, "Exception caught while kicking player for spawn timeout."); + } + finally + { + await _spawnTimeout.DisposeAsync(); + } + } } } \ No newline at end of file diff --git a/src/Impostor.Server/Net/State/Game.Data.cs b/src/Impostor.Server/Net/State/Game.Data.cs index d9f3396..e4bc64f 100644 --- a/src/Impostor.Server/Net/State/Game.Data.cs +++ b/src/Impostor.Server/Net/State/Game.Data.cs @@ -81,6 +81,7 @@ namespace Impostor.Server.Net.State if (TryGetPlayer(control.OwnerId, out var player)) { player.Character = control; + player.DisableSpawnTimeout(); } // Hook up InnerPlayerControl <-> InnerPlayerControl.PlayerInfo. diff --git a/src/Impostor.Server/Net/State/Game.Incoming.cs b/src/Impostor.Server/Net/State/Game.Incoming.cs index 7fa778d..06b5272 100644 --- a/src/Impostor.Server/Net/State/Game.Incoming.cs +++ b/src/Impostor.Server/Net/State/Game.Incoming.cs @@ -6,6 +6,7 @@ using Impostor.Api.Innersloth.Data; using Impostor.Api.Net; using Impostor.Api.Net.Messages; using Impostor.Hazel; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Impostor.Server.Net.State @@ -79,7 +80,7 @@ namespace Impostor.Server.Net.State if (player == null || player.Game != this) { - var clientPlayer = new ClientPlayer(client, this); + var clientPlayer = new ClientPlayer(_serviceProvider.GetRequiredService>(), client, this); if (!_clientManager.Validate(client)) { diff --git a/src/Impostor.Server/Net/State/Game.State.cs b/src/Impostor.Server/Net/State/Game.State.cs index f62f60b..f375e66 100644 --- a/src/Impostor.Server/Net/State/Game.State.cs +++ b/src/Impostor.Server/Net/State/Game.State.cs @@ -6,6 +6,7 @@ using Impostor.Api.Innersloth.Data; using Impostor.Api.Net; using Impostor.Api.Net.Messages; using Impostor.Hazel; +using Impostor.Server.Net.Hazel; using Microsoft.Extensions.Logging; namespace Impostor.Server.Net.State @@ -27,6 +28,8 @@ namespace Impostor.Server.Net.State await InitGameDataAsync(player); } + player.InitializeSpawnTimeout(); + await _eventManager.CallAsync(new PlayerJoinedGameEvent(this, player)); } @@ -73,6 +76,18 @@ namespace Impostor.Server.Net.State await _eventManager.CallAsync(new PlayerLeftGameEvent(this, player, isBan)); + // Player can refuse to be kicked and keep the connection open, check for this. + _ = Task.Run(async () => + { + await Task.Delay(Constants.ConnectionTimeout); + + if (player.Client.Connection.IsConnected) + { + _logger.LogInformation("{0} - Player {1} ({2}) kept connection open after leaving, disposing.", Code, player.Client.Name, playerId); + ((HazelConnection) player.Client.Connection).DisposeInnerConnection(); + } + }); + return true; } diff --git a/src/Impostor.Tools.ServerReplay/Program.cs b/src/Impostor.Tools.ServerReplay/Program.cs index 7a8802d..c904081 100644 --- a/src/Impostor.Tools.ServerReplay/Program.cs +++ b/src/Impostor.Tools.ServerReplay/Program.cs @@ -42,11 +42,11 @@ namespace Impostor.Tools.ServerReplay private static async Task Main(string[] args) { - // Log.Logger = new LoggerConfiguration() - // // .MinimumLevel.Verbose() - // .MinimumLevel.Debug() - // .WriteTo.Console() - // .CreateLogger(); + Log.Logger = new LoggerConfiguration() + // .MinimumLevel.Verbose() + .MinimumLevel.Debug() + .WriteTo.Console() + .CreateLogger(); var stopwatch = Stopwatch.StartNew(); -- 2.39.5