]> git.deb.at Git - rhonda/impostor.git/commitdiff
Add spawn and leave timeout
authorAeonLucid <aeonlucid@outlook.com>
Fri, 23 Oct 2020 23:18:25 +0000 (01:18 +0200)
committerAeonLucid <aeonlucid@outlook.com>
Fri, 23 Oct 2020 23:18:25 +0000 (01:18 +0200)
src/Impostor.Api/Innersloth/Net/Objects/InnerPlayerControl.cs
src/Impostor.Api/Net/IHazelConnection.cs
src/Impostor.Api/Unity/Mathf.cs
src/Impostor.Server/Constants.cs [new file with mode: 0644]
src/Impostor.Server/Net/Hazel/HazelConnection.cs
src/Impostor.Server/Net/State/ClientPlayer.cs
src/Impostor.Server/Net/State/Game.Data.cs
src/Impostor.Server/Net/State/Game.Incoming.cs
src/Impostor.Server/Net/State/Game.State.cs
src/Impostor.Tools.ServerReplay/Program.cs

index dd2eb8a3bc114f4686d73d5c97d5ee7b30f1834c..57efe8c4bf804406d5ac13d22764bf0d6a84efc9 100644 (file)
@@ -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
index a39e0b5c41a5b90584b0d2924da1b2a11faf3695..282e439a48ad052ed9d57776926629ed5c65a5c8 100644 (file)
@@ -30,5 +30,12 @@ namespace Impostor.Api.Net
         /// <param name="writer">The message.</param>
         /// <returns></returns>
         ValueTask SendAsync(IMessageWriter writer);
+
+        /// <summary>
+        ///     Disconnects the client and invokes the disconnect handler.
+        /// </summary>
+        /// <param name="reason">A reason.</param>
+        /// <returns></returns>
+        ValueTask DisconnectAsync(string reason);
     }
 }
\ No newline at end of file
index ed883c8f85a343090abc0021c2d2e67d6c753092..4b034176de4fbde5bc46d1627ebeea4795243d64 100644 (file)
         /// </returns>
         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;
         }
 
         /// <summary>
         ///   <para>Clamps value between 0 and 1 and returns value.</para>
         /// </summary>
-        /// <param name="value"></param>
+        /// <param name="value">Value.</param>
+        /// <returns>Clamped value.</returns>
         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;
         }
 
         /// <summary>
@@ -40,6 +49,6 @@
         /// <returns>
         ///   <para>The interpolated float result between the two float values.</para>
         /// </returns>
-        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 (file)
index 0000000..62d90b2
--- /dev/null
@@ -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
index 3e92594de634f2a4b77d4494fbf9f79326d092d8..9a9a07140d98112df8e1da373f2d20fdeeba39b4 100644 (file)
@@ -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)
index 30412a1bd64307d800044ff742ae5ada19774a05..7bb6164bf9f2435c3bf901866d09a774ebd7016a 100644 (file)
@@ -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<ClientPlayer> _logger;
+
+        private Timer _spawnTimeout;
+
+        public ClientPlayer(ILogger<ClientPlayer> 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;
+        }
+
         /// <inheritdoc />
         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
index d9f3396a4fffc1ca2abc181ef828599eb982b312..e4bc64fe9d552dcdcb16b00404182cb060f613ed 100644 (file)
@@ -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.
index 7fa778df038fb5ff51d41dde07c6b276761962c5..06b5272a9a3408000f5a78c817073d98df7392b5 100644 (file)
@@ -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<ILogger<ClientPlayer>>(), client, this);
 
                 if (!_clientManager.Validate(client))
                 {
index f62f60b2f0f7a505edc882efeebc0ec7a965a122..f375e665a94d10b0e651b77d9b97c79ff9220256 100644 (file)
@@ -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;
         }
 
index 7a8802da73b6ff12b6581148dcc431422d3a1c50..c904081610fb0f0782e10c57b47a6c3566d1f108 100644 (file)
@@ -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();