From f868c346784767aadab51a9a0b22b2abf8712846 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Fri, 3 Jul 2020 20:45:37 -0700 Subject: [PATCH] Adds listening sockets to the configuration file (#172) --- .../Configuration/ServerConfiguration.cs | 80 ++++++++++++++++--- .../Converters/IPEndPointConverter.cs | 42 ++++++++++ .../Converters/IPEndPointConverterFactory.cs | 35 ++++++++ .../Converters/Point2DConverter.cs | 2 +- .../Converters/Point3DConverter.cs | 2 +- .../Converters/Rectangle3DConverter.cs | 2 +- .../Server/JsonConfiguration/JsonConfig.cs | 1 + Projects/Server/Main.cs | 2 - Projects/Server/Network/TcpServer.cs | 4 +- Projects/UOContent/Misc/SocketOptions.cs | 22 ----- 10 files changed, 153 insertions(+), 39 deletions(-) create mode 100644 Projects/Server/JsonConfiguration/Converters/IPEndPointConverter.cs create mode 100644 Projects/Server/JsonConfiguration/Converters/IPEndPointConverterFactory.cs delete mode 100644 Projects/UOContent/Misc/SocketOptions.cs diff --git a/Projects/Server/Configuration/ServerConfiguration.cs b/Projects/Server/Configuration/ServerConfiguration.cs index fa7a237bb..04fbe7db3 100644 --- a/Projects/Server/Configuration/ServerConfiguration.cs +++ b/Projects/Server/Configuration/ServerConfiguration.cs @@ -3,7 +3,7 @@ * Copyright (C) 2019-2020 - ModernUO Development Team * * Email: hi@modernuo.com * * File: ServerConfiguration.cs * - * Created: 2019/10/04 - Updated: 2020/05/09 * + * Created: 2019/10/04 - Updated: 2020/07/03 * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net; using System.Text.Json.Serialization; using Server.Json; @@ -36,6 +37,8 @@ namespace Server public static List DataDirectories => m_Settings.dataDirectories; + public static List Listeners => m_Settings.listeners; + public static string GetSetting(string key, string defaultValue) { m_Settings.settings.TryGetValue(key, out string value); @@ -167,8 +170,19 @@ namespace Server if (m_Settings.dataDirectories.Count == 0) { updated = true; + Utility.PushColor(ConsoleColor.DarkYellow); Console.WriteLine("Core: Server configuration is missing data directories."); - m_Settings.dataDirectories.Add(GetDataDirectory()); + Utility.PopColor(); + m_Settings.dataDirectories.AddRange(GetDataDirectories()); + } + + if (m_Settings.listeners.Count == 0) + { + updated = true; + Utility.PushColor(ConsoleColor.DarkYellow); + Console.WriteLine("Core: Server is missing socket listener IP addresses."); + Utility.PopColor(); + m_Settings.listeners.AddRange(GetListeners()); } if (updated) @@ -185,6 +199,9 @@ namespace Server [JsonPropertyName("dataDirectories")] public List dataDirectories { get; set; } = new List(); + [JsonPropertyName("listeners")] + public List listeners { get; set; } = new List(); + [JsonPropertyName("settings")] public Dictionary settings { get; set; } = new Dictionary(); @@ -192,18 +209,63 @@ namespace Server public Dictionary metadata { get; set; } = new Dictionary(); } - private static string GetDataDirectory() + private static List GetDataDirectories() { - Console.WriteLine("Please enter the Ultima Online directory:"); + Console.WriteLine("Please enter the absolute path to the Ultima Online data:"); + + List directories = new List(); - string directory; do { - Console.Write("> "); - directory = Console.ReadLine(); - } while (!Directory.Exists(directory)); + Console.Write("{0}> ", directories.Count > 0 ? "[finish] " : " "); + var directory = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(directory)) break; - return directory; + if (Directory.Exists(directory)) + { + directories.Add(directory); + Console.WriteLine("Core: Path {0} added.", directory); + } + else + Console.WriteLine("Core: Path does not exist. ({0})"); + + } while (true); + + return directories; + } + + private static List GetListeners() + { + Console.WriteLine("Please enter the IP and ports to listen:"); + Console.WriteLine(" - Only enter IP addresses directly bound to this machine"); + Console.WriteLine(" - To listen to all IP addresses enter 0.0.0.0"); + + List ips = new List(); + + do + { // IP:Port? + Console.Write("[{0}]> ", ips.Count > 0 ? "finish" : "0.0.0.0:2593"); + var ipStr = Console.ReadLine(); + if (string.IsNullOrWhiteSpace(ipStr)) break; + + if (ipStr.IndexOf(":", StringComparison.Ordinal) == -1) + ipStr += ":2593"; + + if (IPEndPoint.TryParse(ipStr, out var ip)) + { + ips.Add(ip); + Console.WriteLine("Core: {0} added.", ipStr); + } + else + { + Console.WriteLine("Core: {0} is not a valid IP or port"); + } + } while (true); + + if (ips.Count == 0) + ips.Add(new IPEndPoint(IPAddress.Any, 2593)); + + return ips; } public static void Save() diff --git a/Projects/Server/JsonConfiguration/Converters/IPEndPointConverter.cs b/Projects/Server/JsonConfiguration/Converters/IPEndPointConverter.cs new file mode 100644 index 000000000..c7d4ce307 --- /dev/null +++ b/Projects/Server/JsonConfiguration/Converters/IPEndPointConverter.cs @@ -0,0 +1,42 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: IPEndPointConverter.cs * + * Created: 2020/07/03 - Updated: 2020/07/03 * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Server.Json +{ + public class IPEndPointConverter : JsonConverter + { + public override IPEndPoint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (IPEndPoint.TryParse(reader.GetString(), out var ipep)) + return ipep; + + throw new JsonException("IPEndPoint must be in the correct format"); + } + + public override void Write(Utf8JsonWriter writer, IPEndPoint value, JsonSerializerOptions options) + => writer.WriteStringValue(value.ToString()); + } +} diff --git a/Projects/Server/JsonConfiguration/Converters/IPEndPointConverterFactory.cs b/Projects/Server/JsonConfiguration/Converters/IPEndPointConverterFactory.cs new file mode 100644 index 000000000..6bfc336c7 --- /dev/null +++ b/Projects/Server/JsonConfiguration/Converters/IPEndPointConverterFactory.cs @@ -0,0 +1,35 @@ +/************************************************************************* + * ModernUO * + * Copyright (C) 2019-2020 - ModernUO Development Team * + * Email: hi@modernuo.com * + * File: IPEndPointConverterFactory.cs * + * Created: 2020/07/03 - Updated: 2020/07/03 * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *************************************************************************/ + +using System; +using System.Net; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Server.Json +{ + public class IPEndPointConverterFactory : JsonConverterFactory + { + public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(IPEndPoint); + + public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new IPEndPointConverter(); + } +} diff --git a/Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs b/Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs index 1061e6a6d..c424313ba 100644 --- a/Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs +++ b/Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs @@ -64,7 +64,7 @@ namespace Server.Json break; if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException("Invalid Json structure for Point2D object"); + throw new JsonException("Invalid json structure for Point2D object"); var key = reader.GetString(); diff --git a/Projects/Server/JsonConfiguration/Converters/Point3DConverter.cs b/Projects/Server/JsonConfiguration/Converters/Point3DConverter.cs index 17bec52ba..107f2b535 100644 --- a/Projects/Server/JsonConfiguration/Converters/Point3DConverter.cs +++ b/Projects/Server/JsonConfiguration/Converters/Point3DConverter.cs @@ -64,7 +64,7 @@ namespace Server.Json break; if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException("Invalid Json structure for Point3D object"); + throw new JsonException("Invalid json structure for Point3D object"); var key = reader.GetString(); diff --git a/Projects/Server/JsonConfiguration/Converters/Rectangle3DConverter.cs b/Projects/Server/JsonConfiguration/Converters/Rectangle3DConverter.cs index b074ce9d1..101fc59b5 100644 --- a/Projects/Server/JsonConfiguration/Converters/Rectangle3DConverter.cs +++ b/Projects/Server/JsonConfiguration/Converters/Rectangle3DConverter.cs @@ -67,7 +67,7 @@ namespace Server.Json break; if (reader.TokenType != JsonTokenType.PropertyName) - throw new JsonException("Invalid Json structure for Rectangle3D object"); + throw new JsonException("Invalid json structure for Rectangle3D object"); var key = reader.GetString(); diff --git a/Projects/Server/JsonConfiguration/JsonConfig.cs b/Projects/Server/JsonConfiguration/JsonConfig.cs index 95146eadc..eaec4039e 100644 --- a/Projects/Server/JsonConfiguration/JsonConfig.cs +++ b/Projects/Server/JsonConfiguration/JsonConfig.cs @@ -46,6 +46,7 @@ namespace Server.Json options.Converters.Add(new Point3DConverterFactory()); options.Converters.Add(new Rectangle3DConverterFactory()); options.Converters.Add(new TimeSpanConverterFactory()); + options.Converters.Add(new IPEndPointConverterFactory()); for (int i = 0; i < converters.Length; i++) options.Converters.Add(converters[i]); diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 1681f59e5..31854a0ad 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -386,8 +386,6 @@ namespace Server AssemblyHandler.Invoke("Initialize"); - AssemblyHandler.Invoke("RegisterListeners"); - timerThread.Start(); foreach (var m in Map.AllMaps) diff --git a/Projects/Server/Network/TcpServer.cs b/Projects/Server/Network/TcpServer.cs index 8778bae98..69da009b4 100644 --- a/Projects/Server/Network/TcpServer.cs +++ b/Projects/Server/Network/TcpServer.cs @@ -32,8 +32,6 @@ namespace Server.Network { public static class TcpServer { - public static List Listeners { get; } = new List(); - // Make this thread safe public static List Instances { get; } = new List(); @@ -45,7 +43,7 @@ namespace Server.Network .ConfigureServices(services => { services.AddSingleton(new MessagePumpService()); }) .UseKestrel(options => { - foreach (var ipep in Listeners) + foreach (var ipep in ServerConfiguration.Listeners) { options.Listen(ipep, builder => { builder.UseConnectionHandler(); }); m_ListeningAddresses = GetListeningAddresses(ipep); diff --git a/Projects/UOContent/Misc/SocketOptions.cs b/Projects/UOContent/Misc/SocketOptions.cs deleted file mode 100644 index 32f0fca9e..000000000 --- a/Projects/UOContent/Misc/SocketOptions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Net; -using Server.Network; - -namespace Server -{ - public class SocketOptions - { - private static readonly IPEndPoint[] m_ListenerEndPoints = - { - new IPEndPoint(IPAddress.Any, 2593) // Default: Listen on port 2593 on all IP addresses - - // Examples: - // new IPEndPoint( IPAddress.Any, 80 ), // Listen on port 80 on all IP addresses - // new IPEndPoint( IPAddress.Parse( "1.2.3.4" ), 2593 ), // Listen on port 2593 on IP address 1.2.3.4 - }; - - public static void RegisterListeners() - { - TcpServer.Listeners.AddRange(m_ListenerEndPoints); - } - } -}