idle timeout

This commit is contained in:
Vinzenz Schroeter 2024-04-12 14:28:57 +02:00
parent ad211433fb
commit 7e767d6dcb
5 changed files with 27 additions and 9 deletions

View file

@ -3,4 +3,6 @@ namespace TanksServer.GameLogic;
public class PlayersConfiguration public class PlayersConfiguration
{ {
public int SpawnDelayMs { get; set; } public int SpawnDelayMs { get; set; }
public int IdleTimeoutMs { get; set; }
} }

View file

@ -6,9 +6,10 @@ internal sealed class SpawnQueue(
IOptions<PlayersConfiguration> options IOptions<PlayersConfiguration> options
) )
{ {
private ConcurrentQueue<Player> _queue = new(); private readonly ConcurrentQueue<Player> _queue = new();
private ConcurrentDictionary<Player, DateTime> _spawnTimes = new(); private readonly ConcurrentDictionary<Player, DateTime> _spawnTimes = new();
private readonly TimeSpan _spawnDelay = TimeSpan.FromMilliseconds(options.Value.SpawnDelayMs); private readonly TimeSpan _spawnDelay = TimeSpan.FromMilliseconds(options.Value.SpawnDelayMs);
private readonly TimeSpan _idleTimeout = TimeSpan.FromMilliseconds(options.Value.IdleTimeoutMs);
public void EnqueueForImmediateSpawn(Player player) public void EnqueueForImmediateSpawn(Player player)
{ {
@ -24,13 +25,23 @@ internal sealed class SpawnQueue(
public bool TryDequeueNext([MaybeNullWhen(false)] out Player player) public bool TryDequeueNext([MaybeNullWhen(false)] out Player player)
{ {
if (!_queue.TryDequeue(out 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; return false;
}
var now = DateTime.Now; var now = DateTime.Now;
if (_spawnTimes.GetOrAdd(player, DateTime.MinValue) <= now) if (_spawnTimes.GetOrAdd(player, DateTime.MinValue) > now)
return true; {
// spawn delay
_queue.Enqueue(player);
return false;
}
_queue.Enqueue(player); return true;
return false;
} }
} }

View file

@ -83,6 +83,8 @@ internal sealed class ControlsServer(ILogger<ControlsServer> logger, ILoggerFact
_ => throw new ArgumentException("invalid message type") _ => throw new ArgumentException("invalid message type")
}; };
_player.LastInput = DateTime.Now;
switch (control) switch (control)
{ {
case InputType.Forward: case InputType.Forward:

View file

@ -14,4 +14,6 @@ internal sealed class Player(string name)
public int Kills { get; set; } public int Kills { get; set; }
public int Deaths { get; set; } public int Deaths { get; set; }
public DateTime LastInput { get; set; } = DateTime.Now;
} }

View file

@ -16,7 +16,7 @@
} }
}, },
"ServicePointDisplay": { "ServicePointDisplay": {
"Enable": false, "Enable": true,
"Hostname": "172.23.42.29", "Hostname": "172.23.42.29",
"Port": 2342 "Port": 2342
}, },
@ -27,6 +27,7 @@
"BulletSpeed": 8 "BulletSpeed": 8
}, },
"Players": { "Players": {
"SpawnDelayMs": 3000 "SpawnDelayMs": 3000,
"IdleTimeoutMs": 30000
} }
} }