]> git.deb.at Git - rhonda/impostor.git/commitdiff
Split up the NodeProvider into two interfaces
authorAeonLucid <aeonlucid@gmail.com>
Sat, 26 Sep 2020 17:28:46 +0000 (19:28 +0200)
committerAeonLucid <aeonlucid@gmail.com>
Sat, 26 Sep 2020 17:28:46 +0000 (19:28 +0200)
13 files changed:
src/Impostor.Server/Net/Manager/GameManager.cs
src/Impostor.Server/Net/Redirector/ClientManagerRedirector.cs
src/Impostor.Server/Net/Redirector/ClientRedirector.cs
src/Impostor.Server/Net/Redirector/INodeLocator.cs [new file with mode: 0644]
src/Impostor.Server/Net/Redirector/INodeProvider.cs
src/Impostor.Server/Net/Redirector/NodeLocatorNoOp.cs [new file with mode: 0644]
src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs [new file with mode: 0644]
src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs [new file with mode: 0644]
src/Impostor.Server/Net/Redirector/NodeProviderNoOp.cs [deleted file]
src/Impostor.Server/Net/Redirector/NodeProviderRedis.cs [deleted file]
src/Impostor.Server/Net/State/Game.cs
src/Impostor.Server/Program.cs
src/Impostor.Server/config.json

index 7c0db53d36da1c31115dd37c532e495a644ba349..515ae5bda86ce729092d92cfa5ff59d4d8310151 100644 (file)
@@ -15,14 +15,14 @@ namespace Impostor.Server.Net.Manager
     internal class GameManager
     {
         private readonly ILogger<GameManager> _logger;
-        private readonly INodeProvider _nodeProvider;
+        private readonly INodeLocator _nodeLocator;
         private readonly IPEndPoint _publicIp;
         private readonly ConcurrentDictionary<int, Game> _games;
 
-        public GameManager(ILogger<GameManager> logger, IOptions<ServerConfig> config, INodeProvider nodeProvider)
+        public GameManager(ILogger<GameManager> logger, IOptions<ServerConfig> config, INodeLocator nodeLocator)
         {
             _logger = logger;
-            _nodeProvider = nodeProvider;
+            _nodeLocator = nodeLocator;
             _publicIp = new IPEndPoint(IPAddress.Parse(config.Value.PublicIp), config.Value.PublicPort);
             _games = new ConcurrentDictionary<int, Game>();
         }
@@ -33,12 +33,12 @@ namespace Impostor.Server.Net.Manager
             
             var gameCode = GameCode.GenerateCode(6);
             var gameCodeStr = GameCode.IntToGameName(gameCode);
-            var game = new Game(this, _nodeProvider, _publicIp, gameCode, options);
+            var game = new Game(this, _nodeLocator, _publicIp, gameCode, options);
 
-            if (_nodeProvider.Find(gameCodeStr) == null && 
+            if (_nodeLocator.Find(gameCodeStr) == null && 
                 _games.TryAdd(gameCode, game))
             {
-                _nodeProvider.Save(gameCodeStr, _publicIp);
+                _nodeLocator.Save(gameCodeStr, _publicIp);
                 _logger.LogDebug("Created game with code {0} ({1}).", game.CodeStr, gameCode);        
                 return game;
             }
@@ -86,7 +86,7 @@ namespace Impostor.Server.Net.Manager
         public void Remove(int gameCode)
         {
             _logger.LogDebug("Remove game with code {0} ({1}).", GameCode.IntToGameName(gameCode), gameCode);
-            _nodeProvider.Remove(GameCode.IntToGameName(gameCode));
+            _nodeLocator.Remove(GameCode.IntToGameName(gameCode));
             _games.TryRemove(gameCode, out _);
         }
     }
index f22a6243ff4f4c587403b25a4a30ed4598a2d224..78631dc932963636ed6394d69567e68a22107afa 100644 (file)
@@ -9,19 +9,21 @@ namespace Impostor.Server.Net.Redirector
     {
         private readonly ILogger<ClientManagerRedirector> _logger;
         private readonly INodeProvider _nodeProvider;
+        private readonly INodeLocator _nodeLocator;
         private readonly HashSet<ClientRedirector> _clients;
 
-        public ClientManagerRedirector(ILogger<ClientManagerRedirector> logger, INodeProvider nodeProvider)
+        public ClientManagerRedirector(ILogger<ClientManagerRedirector> logger, INodeProvider nodeProvider, INodeLocator nodeLocator)
         {
             _logger = logger;
             _nodeProvider = nodeProvider;
+            _nodeLocator = nodeLocator;
             _clients = new HashSet<ClientRedirector>();
         }
         
         public void Create(string name, Connection connection)
         {
             _logger.LogInformation("Client connected.");
-            _clients.Add(new ClientRedirector(name, connection, this, _nodeProvider));
+            _clients.Add(new ClientRedirector(name, connection, this, _nodeProvider, _nodeLocator));
         }
 
         public void Remove(ClientRedirector client)
index ce857580ed7fbeb8ac09858f61ba26523ba65440..8bbe6059fbe5963fd0fbc283fc3cbd896d9be90e 100644 (file)
@@ -17,8 +17,9 @@ namespace Impostor.Server.Net.Redirector
         private readonly Connection _connection;
         private readonly ClientManagerRedirector _clientManager;
         private readonly INodeProvider _nodeProvider;
+        private readonly INodeLocator _nodeLocator;
 
-        public ClientRedirector(string name, Connection connection, ClientManagerRedirector clientManager, INodeProvider nodeProvider)
+        public ClientRedirector(string name, Connection connection, ClientManagerRedirector clientManager, INodeProvider nodeProvider, INodeLocator nodeLocator)
         {
             _name = name;
             _connection = connection;
@@ -26,6 +27,7 @@ namespace Impostor.Server.Net.Redirector
             _connection.Disconnected += OnDisconnected;
             _clientManager = clientManager;
             _nodeProvider = nodeProvider;
+            _nodeLocator = nodeLocator;
         }
 
         private void OnDataReceived(DataReceivedEventArgs e)
@@ -74,7 +76,7 @@ namespace Impostor.Server.Net.Redirector
 
                     using (var packet = MessageWriter.Get(SendOption.Reliable))
                     {
-                        var endpoint = _nodeProvider.Find(GameCode.IntToGameName(gameCode));
+                        var endpoint = _nodeLocator.Find(GameCode.IntToGameName(gameCode));
                         if (endpoint == null)
                         {
                             Message01JoinGame.SerializeError(packet, false, DisconnectReason.GameMissing);
diff --git a/src/Impostor.Server/Net/Redirector/INodeLocator.cs b/src/Impostor.Server/Net/Redirector/INodeLocator.cs
new file mode 100644 (file)
index 0000000..f7dcf57
--- /dev/null
@@ -0,0 +1,11 @@
+using System.Net;
+
+namespace Impostor.Server.Net.Redirector
+{
+    public interface INodeLocator
+    {
+        IPEndPoint Find(string gameCode);
+        void Save(string gameCode, IPEndPoint endPoint);
+        void Remove(string gameCode);
+    }
+}
\ No newline at end of file
index 37418e6c39e1e4c1da584dae91bbf6d45623dcc1..318fcb2d66da824b4f2786e360b999ba3e4903a4 100644 (file)
@@ -5,8 +5,5 @@ namespace Impostor.Server.Net.Redirector
     internal interface INodeProvider
     {
         IPEndPoint Get();
-        IPEndPoint Find(string gameCode);
-        void Save(string gameCode, IPEndPoint endPoint);
-        void Remove(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
new file mode 100644 (file)
index 0000000..21811c8
--- /dev/null
@@ -0,0 +1,23 @@
+using System.Net;
+
+namespace Impostor.Server.Net.Redirector
+{
+    public class NodeLocatorNoOp : INodeLocator
+    {
+        public IPEndPoint Find(string gameCode)
+        {
+            // Do nothing.
+            return null;
+        }
+
+        public void Save(string gameCode, IPEndPoint endPoint)
+        {
+            // Do nothing.
+        }
+
+        public void Remove(string gameCode)
+        {
+            // Do nothing.
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs b/src/Impostor.Server/Net/Redirector/NodeLocatorRedis.cs
new file mode 100644 (file)
index 0000000..1819eac
--- /dev/null
@@ -0,0 +1,40 @@
+using System;
+using System.Net;
+using Microsoft.Extensions.Caching.Distributed;
+
+namespace Impostor.Server.Net.Redirector
+{
+    public class NodeLocatorRedis : INodeLocator
+    {
+        private readonly IDistributedCache _cache;
+        
+        public NodeLocatorRedis(IDistributedCache cache)
+        {
+            _cache = cache;
+        }
+
+        public IPEndPoint Find(string gameCode)
+        {
+            var entry = _cache.GetString(gameCode);
+            if (entry == null)
+            {
+                return null;
+            }
+            
+            return IPEndPoint.Parse(entry);
+        }
+
+        public void Save(string gameCode, IPEndPoint endPoint)
+        {
+            _cache.SetString(gameCode, endPoint.ToString(), new DistributedCacheEntryOptions
+            {
+                SlidingExpiration = TimeSpan.FromHours(1)
+            });
+        }
+
+        public void Remove(string gameCode)
+        {
+            _cache.Remove(gameCode);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs b/src/Impostor.Server/Net/Redirector/NodeProviderConfig.cs
new file mode 100644 (file)
index 0000000..864a540
--- /dev/null
@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Net;
+using Impostor.Server.Data;
+using Microsoft.Extensions.Options;
+
+namespace Impostor.Server.Net.Redirector
+{
+    internal class NodeProviderConfig : INodeProvider
+    {
+        private readonly List<IPEndPoint> _nodes;
+        private readonly object _lock;
+        private int _currentIndex;
+        
+        public NodeProviderConfig(IOptions<ServerRedirectorConfig> redirectorConfig)
+        {
+            _nodes = new List<IPEndPoint>();
+            _lock = new object();
+
+            if (redirectorConfig.Value.Nodes != null)
+            {
+                foreach (var node in redirectorConfig.Value.Nodes)
+                {
+                    _nodes.Add(new IPEndPoint(IPAddress.Parse(node.Ip), node.Port));
+                }
+            }
+        }
+
+        public IPEndPoint Get()
+        {
+            lock (_lock)
+            {
+                var node = _nodes[_currentIndex++];
+
+                if (_currentIndex == _nodes.Count)
+                {
+                    _currentIndex = 0;
+                }
+                
+                return node;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Redirector/NodeProviderNoOp.cs b/src/Impostor.Server/Net/Redirector/NodeProviderNoOp.cs
deleted file mode 100644 (file)
index fa97968..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-using System;
-using System.Net;
-
-namespace Impostor.Server.Net.Redirector
-{
-    public class NodeProviderNoOp : INodeProvider
-    {
-        public IPEndPoint Get()
-        {
-            throw new NotImplementedException();
-        }
-
-        public IPEndPoint Find(string gameCode)
-        {
-            // Do nothing.
-            return null;
-        }
-
-        public void Save(string gameCode, IPEndPoint endPoint)
-        {
-            // Do nothing.
-        }
-
-        public void Remove(string gameCode)
-        {
-            // Do nothing.
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/Impostor.Server/Net/Redirector/NodeProviderRedis.cs b/src/Impostor.Server/Net/Redirector/NodeProviderRedis.cs
deleted file mode 100644 (file)
index ceaec46..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Net;
-using Impostor.Server.Data;
-using Microsoft.Extensions.Caching.Distributed;
-using Microsoft.Extensions.Options;
-
-namespace Impostor.Server.Net.Redirector
-{
-    internal class NodeProviderRedis : INodeProvider
-    {
-        private readonly IDistributedCache _cache;
-        private readonly List<IPEndPoint> _nodes;
-        private readonly object _lock;
-        private int _currentIndex;
-        
-        public NodeProviderRedis(IOptions<ServerRedirectorConfig> redirectorConfig, IDistributedCache cache)
-        {
-            _cache = cache;
-            _nodes = new List<IPEndPoint>();
-            _lock = new object();
-
-            if (redirectorConfig.Value.Nodes != null)
-            {
-                foreach (var node in redirectorConfig.Value.Nodes)
-                {
-                    _nodes.Add(new IPEndPoint(IPAddress.Parse(node.Ip), node.Port));
-                }
-            }
-        }
-
-        public IPEndPoint Get()
-        {
-            lock (_lock)
-            {
-                var node = _nodes[_currentIndex++];
-
-                if (_currentIndex == _nodes.Count)
-                {
-                    _currentIndex = 0;
-                }
-                
-                return node;
-            }
-        }
-
-        public IPEndPoint Find(string gameCode)
-        {
-            var entry = _cache.GetString(gameCode);
-            if (entry == null)
-            {
-                return null;
-            }
-            
-            return IPEndPoint.Parse(entry);
-        }
-
-        public void Save(string gameCode, IPEndPoint endPoint)
-        {
-            _cache.SetString(gameCode, endPoint.ToString(), new DistributedCacheEntryOptions
-            {
-                SlidingExpiration = TimeSpan.FromHours(1)
-            });
-        }
-
-        public void Remove(string gameCode)
-        {
-            _cache.Remove(gameCode);
-        }
-    }
-}
\ No newline at end of file
index bb8ff6a95e932b956c5b02fbd6bd745185fbb2d2..4ffcb7b4eb88036d130f8f99f7e3c9cf4d711a23 100644 (file)
@@ -18,14 +18,14 @@ namespace Impostor.Server.Net.State
         private static readonly ILogger Logger = Log.ForContext<Game>();
         
         private readonly GameManager _gameManager;
-        private readonly INodeProvider _nodeProvider;
+        private readonly INodeLocator _nodeLocator;
         private readonly ConcurrentDictionary<int, ClientPlayer> _players;
         private readonly HashSet<IPAddress> _bannedIps;
 
-        public Game(GameManager gameManager, INodeProvider nodeProvider, IPEndPoint publicIp, int code, GameOptionsData options)
+        public Game(GameManager gameManager, INodeLocator nodeLocator, IPEndPoint publicIp, int code, GameOptionsData options)
         {
             _gameManager = gameManager;
-            _nodeProvider = nodeProvider;
+            _nodeLocator = nodeLocator;
             _players = new ConcurrentDictionary<int, ClientPlayer>();
             _bannedIps = new HashSet<IPAddress>();
 
index fea258a51e14b8298c412b44e84510fe77282cf8..7a665f1db62f46495edf69feb012b6d7fd8da406 100644 (file)
@@ -64,7 +64,15 @@ namespace Impostor.Server
 
                     if (redirector.Enabled)
                     {
-                        services.AddSingleton<INodeProvider, NodeProviderRedis>();
+                        // When joining a game, it retrieves the game server ip from redis.
+                        // When a game has been created on this node, it stores the game code with its ip in redis.
+                        services.AddSingleton<INodeLocator, NodeLocatorRedis>();
+                        
+                        // Use the configuration as source for the list of nodes to provide
+                        // when creating a game.
+                        services.AddSingleton<INodeProvider, NodeProviderConfig>();
+                        
+                        // Dependency for the NodeLocatorRedis.
                         services.AddStackExchangeRedisCache(options =>
                         {
                             options.Configuration = redirector.Redis;
@@ -73,12 +81,15 @@ namespace Impostor.Server
                     }
                     else
                     {
-                        services.AddSingleton<INodeProvider, NodeProviderNoOp>();
+                        // Redirector is not enabled but the dependency is still required.
+                        // So we provide one that ignores all calls.
+                        services.AddSingleton<INodeLocator, NodeLocatorNoOp>();
                     }
                     
                     if (redirector.Enabled && redirector.Master)
                     {
                         services.AddSingleton<IClientManager, ClientManagerRedirector>();
+                        // For a master server, we don't need a GameManager.
                     }
                     else
                     {
index 5e9f6347063be1ea62d1d8f9f3bb5967d32c994c..6c8f49a8be2810ede26d6f2452ceaac1940bccdd 100644 (file)
       {
         "Ip": "127.0.0.1",
         "Port": 22024
-      },
-      {
-        "Ip": "127.0.0.1",
-        "Port": 22025
       }
     ]
   }