From 7e767d6dcbbe5d99700cd1f14cbe51741aeb67a2 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Fri, 12 Apr 2024 14:28:57 +0200 Subject: [PATCH] idle timeout --- TanksServer/GameLogic/PlayersConfiguration.cs | 2 ++ TanksServer/GameLogic/SpawnQueue.cs | 25 +++++++++++++------ TanksServer/Interactivity/ControlsServer.cs | 2 ++ TanksServer/Models/Player.cs | 2 ++ TanksServer/appsettings.json | 5 ++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/TanksServer/GameLogic/PlayersConfiguration.cs b/TanksServer/GameLogic/PlayersConfiguration.cs index a4fb337..c21dd37 100644 --- a/TanksServer/GameLogic/PlayersConfiguration.cs +++ b/TanksServer/GameLogic/PlayersConfiguration.cs @@ -3,4 +3,6 @@ namespace TanksServer.GameLogic; public class PlayersConfiguration { public int SpawnDelayMs { get; set; } + + public int IdleTimeoutMs { get; set; } } \ No newline at end of file diff --git a/TanksServer/GameLogic/SpawnQueue.cs b/TanksServer/GameLogic/SpawnQueue.cs index 56e39ae..6fae474 100644 --- a/TanksServer/GameLogic/SpawnQueue.cs +++ b/TanksServer/GameLogic/SpawnQueue.cs @@ -6,9 +6,10 @@ internal sealed class SpawnQueue( IOptions options ) { - private ConcurrentQueue _queue = new(); - private ConcurrentDictionary _spawnTimes = new(); + private readonly ConcurrentQueue _queue = new(); + private readonly ConcurrentDictionary _spawnTimes = new(); private readonly TimeSpan _spawnDelay = TimeSpan.FromMilliseconds(options.Value.SpawnDelayMs); + private readonly TimeSpan _idleTimeout = TimeSpan.FromMilliseconds(options.Value.IdleTimeoutMs); public void EnqueueForImmediateSpawn(Player player) { @@ -24,13 +25,23 @@ internal sealed class SpawnQueue( public bool TryDequeueNext([MaybeNullWhen(false)] out Player player) { if (!_queue.TryDequeue(out player)) + return false; // no one on queue + + if (player.LastInput + _idleTimeout < DateTime.Now) + { + // player idle + _queue.Enqueue(player); return false; - + } + var now = DateTime.Now; - if (_spawnTimes.GetOrAdd(player, DateTime.MinValue) <= now) - return true; + if (_spawnTimes.GetOrAdd(player, DateTime.MinValue) > now) + { + // spawn delay + _queue.Enqueue(player); + return false; + } - _queue.Enqueue(player); - return false; + return true; } } \ No newline at end of file diff --git a/TanksServer/Interactivity/ControlsServer.cs b/TanksServer/Interactivity/ControlsServer.cs index eb6752a..a279a2e 100644 --- a/TanksServer/Interactivity/ControlsServer.cs +++ b/TanksServer/Interactivity/ControlsServer.cs @@ -83,6 +83,8 @@ internal sealed class ControlsServer(ILogger logger, ILoggerFact _ => throw new ArgumentException("invalid message type") }; + _player.LastInput = DateTime.Now; + switch (control) { case InputType.Forward: diff --git a/TanksServer/Models/Player.cs b/TanksServer/Models/Player.cs index 30638ba..24c414b 100644 --- a/TanksServer/Models/Player.cs +++ b/TanksServer/Models/Player.cs @@ -14,4 +14,6 @@ internal sealed class Player(string name) public int Kills { get; set; } public int Deaths { get; set; } + + public DateTime LastInput { get; set; } = DateTime.Now; } \ No newline at end of file diff --git a/TanksServer/appsettings.json b/TanksServer/appsettings.json index 2832663..b8cbeea 100644 --- a/TanksServer/appsettings.json +++ b/TanksServer/appsettings.json @@ -16,7 +16,7 @@ } }, "ServicePointDisplay": { - "Enable": false, + "Enable": true, "Hostname": "172.23.42.29", "Port": 2342 }, @@ -27,6 +27,7 @@ "BulletSpeed": 8 }, "Players": { - "SpawnDelayMs": 3000 + "SpawnDelayMs": 3000, + "IdleTimeoutMs": 30000 } }