From 647672c40e07c5f42f2851f0b909008b11f334b3 Mon Sep 17 00:00:00 2001 From: Jonas Kamsker <11245306+JKamsker@users.noreply.github.com> Date: Thu, 22 Oct 2020 00:02:27 +0200 Subject: [PATCH] Feature/gamemanager improvement (#65) * Ignoring .Vs folder * Improved Gamemanager - Retry code creation - Async Node Lookup * Switched back to old using order * Removed IAsyncNodeLocator * Found one more use of find * deleted submodule Co-authored-by: Weirdo --- .gitignore | 4 ++- .../Extensions/NodeLocatorExtensions.cs | 19 ++++++++++++ .../Net/Manager/GameManager.cs | 30 +++++++++++++++---- .../Net/Redirector/ClientRedirector.cs | 2 +- .../Net/Redirector/INodeLocator.cs | 7 +++-- .../Net/Redirector/NodeLocatorNoOp.cs | 17 +++-------- .../Net/Redirector/NodeLocatorRedis.cs | 14 +++++---- .../Net/Redirector/NodeLocatorUDP.cs | 19 +++++++----- 8 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 src/Impostor.Server/Extensions/NodeLocatorExtensions.cs diff --git a/.gitignore b/.gitignore index e5150c9..95e2d57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ /.vscode -/build \ No newline at end of file +/build +/.vs +/src/Impostor.Plugins.Debugger/Properties/launchSettings.json diff --git a/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs b/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs new file mode 100644 index 0000000..671017d --- /dev/null +++ b/src/Impostor.Server/Extensions/NodeLocatorExtensions.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +using Impostor.Server.Net.Redirector; + +namespace Impostor.Server.Extensions +{ + public static class NodeLocatorExtensions + { + public static async ValueTask ExistsAsync(this INodeLocator nodeLocator, string gameCode) + { + return await nodeLocator.FindAsync(gameCode) != null; + } + } +} \ No newline at end of file diff --git a/src/Impostor.Server/Net/Manager/GameManager.cs b/src/Impostor.Server/Net/Manager/GameManager.cs index c71a56d..ccb5d37 100644 --- a/src/Impostor.Server/Net/Manager/GameManager.cs +++ b/src/Impostor.Server/Net/Manager/GameManager.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; + using Impostor.Api; using Impostor.Api.Events; using Impostor.Api.Events.Managers; @@ -11,8 +12,10 @@ using Impostor.Api.Games; using Impostor.Api.Innersloth; using Impostor.Api.Innersloth.Data; using Impostor.Server.Data; +using Impostor.Server.Extensions; using Impostor.Server.Net.Redirector; using Impostor.Server.Net.State; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -41,21 +44,38 @@ namespace Impostor.Server.Net.Manager public async ValueTask CreateAsync(GameOptionsData options) { // TODO: Prevent duplicates when using server redirector using INodeProvider. + var (success, game) = await TryCreateAsync(options); + + for (int i = 0; i < 10 && !success; i++) + { + (success, game) = await TryCreateAsync(options); + } + + if (!success) + { + throw new ImpostorException("Could not create new game"); // TODO: Fix generic exception. + } + + return game; + } + + public async ValueTask<(bool success, Game game)> TryCreateAsync(GameOptionsData options) + { var gameCode = GameCode.Create(); var gameCodeStr = gameCode.Code; var game = ActivatorUtilities.CreateInstance(_serviceProvider, _publicIp, gameCode, options); - if (_nodeLocator.Find(gameCodeStr) != null || !_games.TryAdd(gameCode, game)) + if (await _nodeLocator.ExistsAsync(gameCodeStr) || !_games.TryAdd(gameCode, game)) { - throw new ImpostorException("Could not create new game"); // TODO: Fix generic exception. + return (false, null); } - _nodeLocator.Save(gameCodeStr, _publicIp); + await _nodeLocator.SaveAsync(gameCodeStr, _publicIp); _logger.LogDebug("Created game with code {0}.", game.Code); await _eventManager.CallAsync(new GameCreatedEvent(game)); - return game; + return (true, game); } public Game Find(GameCode code) @@ -119,7 +139,7 @@ namespace Impostor.Server.Net.Manager } _logger.LogDebug("Remove game with code {0} ({1}).", GameCodeParser.IntToGameName(gameCode), gameCode); - _nodeLocator.Remove(GameCodeParser.IntToGameName(gameCode)); + await _nodeLocator.RemoveAsync(GameCodeParser.IntToGameName(gameCode)); await _eventManager.CallAsync(new GameDestroyedEvent(game)); } diff --git a/src/Impostor.Server/Net/Redirector/ClientRedirector.cs b/src/Impostor.Server/Net/Redirector/ClientRedirector.cs index 418e79c..0c6d468 100644 --- a/src/Impostor.Server/Net/Redirector/ClientRedirector.cs +++ b/src/Impostor.Server/Net/Redirector/ClientRedirector.cs @@ -58,7 +58,7 @@ namespace Impostor.Server.Net.Redirector out _); using var packet = MessageWriter.Get(MessageType.Reliable); - var endpoint = _nodeLocator.Find(GameCodeParser.IntToGameName(gameCode)); + var endpoint = await _nodeLocator.FindAsync(GameCodeParser.IntToGameName(gameCode)); if (endpoint == null) { Message01JoinGameS2C.SerializeError(packet, false, DisconnectReason.GameMissing); diff --git a/src/Impostor.Server/Net/Redirector/INodeLocator.cs b/src/Impostor.Server/Net/Redirector/INodeLocator.cs index 2dd2f07..12563b9 100644 --- a/src/Impostor.Server/Net/Redirector/INodeLocator.cs +++ b/src/Impostor.Server/Net/Redirector/INodeLocator.cs @@ -1,13 +1,14 @@ using System.Net; +using System.Threading.Tasks; namespace Impostor.Server.Net.Redirector { public interface INodeLocator { - IPEndPoint Find(string gameCode); + ValueTask FindAsync(string gameCode); - void Save(string gameCode, IPEndPoint endPoint); + ValueTask SaveAsync(string gameCode, IPEndPoint endPoint); - void Remove(string gameCode); + ValueTask RemoveAsync(string gameCode); } } \ No newline at end of file diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs index 21811c8..fd4cd56 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs @@ -1,23 +1,14 @@ using System.Net; +using System.Threading.Tasks; namespace Impostor.Server.Net.Redirector { public class NodeLocatorNoOp : INodeLocator { - public IPEndPoint Find(string gameCode) - { - // Do nothing. - return null; - } + public ValueTask FindAsync(string gameCode) => ValueTask.FromResult(default(IPEndPoint)); - public void Save(string gameCode, IPEndPoint endPoint) - { - // Do nothing. - } + public ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) => ValueTask.CompletedTask; - public void Remove(string gameCode) - { - // Do nothing. - } + public ValueTask RemoveAsync(string gameCode) => ValueTask.CompletedTask; } } \ No newline at end of file diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs index 36632a7..ec03666 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs @@ -1,5 +1,7 @@ using System; using System.Net; +using System.Threading.Tasks; + using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; @@ -15,9 +17,9 @@ namespace Impostor.Server.Net.Redirector _cache = cache; } - public IPEndPoint Find(string gameCode) + public async ValueTask FindAsync(string gameCode) { - var entry = _cache.GetString(gameCode); + var entry = await _cache.GetStringAsync(gameCode); if (entry == null) { return null; @@ -26,17 +28,17 @@ namespace Impostor.Server.Net.Redirector return IPEndPoint.Parse(entry); } - public void Save(string gameCode, IPEndPoint endPoint) + public async ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) { - _cache.SetString(gameCode, endPoint.ToString(), new DistributedCacheEntryOptions + await _cache.SetStringAsync(gameCode, endPoint.ToString(), new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(1), }); } - public void Remove(string gameCode) + public async ValueTask RemoveAsync(string gameCode) { - _cache.Remove(gameCode); + await _cache.RemoveAsync(gameCode); } } } \ No newline at end of file diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs index b1efb99..ed19b06 100644 --- a/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs +++ b/src/Impostor.Server/Net/Redirector/NodeLocatorUDP.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Text; +using System.Threading.Tasks; using Impostor.Server.Data; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -72,11 +73,11 @@ namespace Impostor.Server.Net.Redirector } } - public IPEndPoint Find(string gameCode) + public ValueTask FindAsync(string gameCode) { if (!_isMaster) { - return null; + return ValueTask.FromResult(default(IPEndPoint)); } if (_availableNodes.TryGetValue(gameCode, out var node)) @@ -84,29 +85,31 @@ namespace Impostor.Server.Net.Redirector if (node.Expired) { _availableNodes.TryRemove(gameCode, out _); - return null; + return ValueTask.FromResult(default(IPEndPoint)); } - return node.Endpoint; + return ValueTask.FromResult(node.Endpoint); } - return null; + return ValueTask.FromResult(default(IPEndPoint)); } - public void Remove(string gameCode) + public ValueTask RemoveAsync(string gameCode) { if (!_isMaster) { - return; + return ValueTask.CompletedTask; } _availableNodes.TryRemove(gameCode, out _); + return ValueTask.CompletedTask; } - public void Save(string gameCode, IPEndPoint endPoint) + public ValueTask SaveAsync(string gameCode, IPEndPoint endPoint) { var data = Encoding.UTF8.GetBytes($"{gameCode},{endPoint}"); _client.Send(data, data.Length, _server); + return ValueTask.CompletedTask; } public void Dispose() -- 2.39.5