From 4115094cd1d8b7c067ac370ad1e7dd6213c63d21 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Tue, 12 Mar 2024 15:35:57 +0800 Subject: [PATCH 1/7] Make network servers configurable --- ClientCore/ClientConfiguration.cs | 42 ++++++++- DTAConfig/OptionPanels/CnCNetOptionsPanel.cs | 6 +- DXMainClient/DXGUI/Generic/MainMenu.cs | 2 +- DXMainClient/Domain/DiscordHandler.cs | 2 +- DXMainClient/Domain/MainClientConstants.cs | 4 +- .../CnCNet/CnCNetPlayerCountTask.cs | 9 +- .../Domain/Multiplayer/CnCNet/MapSharer.cs | 26 ++++-- .../Multiplayer/CnCNet/TunnelHandler.cs | 87 +++++++++++++------ DXMainClient/Online/Connection.cs | 55 ++++++++---- DXMainClient/Online/Server.cs | 21 +++++ .../Resources/DTA/NetworkDefinitions.ini | 24 +++++ 11 files changed, 216 insertions(+), 62 deletions(-) create mode 100644 DXMainClient/Resources/DTA/NetworkDefinitions.ini diff --git a/ClientCore/ClientConfiguration.cs b/ClientCore/ClientConfiguration.cs index 25b8069ad..313be94bc 100644 --- a/ClientCore/ClientConfiguration.cs +++ b/ClientCore/ClientConfiguration.cs @@ -20,12 +20,14 @@ public class ClientConfiguration private const string CLIENT_SETTINGS = "DTACnCNetClient.ini"; private const string GAME_OPTIONS = "GameOptions.ini"; private const string CLIENT_DEFS = "ClientDefinitions.ini"; + private const string NETWORK_DEFS = "NetworkDefinitions.ini"; private static ClientConfiguration _instance; private IniFile gameOptions_ini; private IniFile DTACnCNetClient_ini; private IniFile clientDefinitionsIni; + private IniFile networkDefinitionIni; protected ClientConfiguration() { @@ -36,7 +38,7 @@ protected ClientConfiguration() FileInfo clientDefinitionsFile = SafePath.GetFile(baseResourceDirectory.FullName, CLIENT_DEFS); - if (clientDefinitionsFile is null) + if (!(clientDefinitionsFile?.Exists ?? false)) throw new FileNotFoundException($"Couldn't find {CLIENT_DEFS} at {baseResourceDirectory}. Please verify that you're running the client from the correct directory."); clientDefinitionsIni = new IniFile(clientDefinitionsFile.FullName); @@ -44,6 +46,8 @@ protected ClientConfiguration() DTACnCNetClient_ini = new IniFile(SafePath.CombineFilePath(ProgramConstants.GetResourcePath(), CLIENT_SETTINGS)); gameOptions_ini = new IniFile(SafePath.CombineFilePath(baseResourceDirectory.FullName, GAME_OPTIONS)); + + networkDefinitionIni = new IniFile(SafePath.CombineFilePath(ProgramConstants.GetResourcePath(), NETWORK_DEFS)); } /// @@ -99,7 +103,7 @@ public void RefreshSettings() public string AltUIBackgroundColor => DTACnCNetClient_ini.GetStringValue(GENERAL, "AltUIBackgroundColor", "196,196,196"); - public string WindowBorderColor => DTACnCNetClient_ini.GetStringValue(GENERAL, "WindowBorderColor", "128,128,128"); + public string WindowBorderColor => DTACnCNetClient_ini.GetStringValue(GENERAL, "WindowBorderColor", "128,128,128"); public string PanelBorderColor => DTACnCNetClient_ini.GetStringValue(GENERAL, "PanelBorderColor", "255,255,255"); @@ -385,6 +389,40 @@ public IEnumerable SupplementalMapFileExtensions #endregion + #region Network definitions + + public string CnCNetTunnelListURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetTunnelListURL", "http://cncnet.org/master-list"); + + public string CnCNetPlayerCountURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetPlayerCountURL", "http://api.cncnet.org/status"); + + public string CnCNetMapDBDownloadURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetMapDBDownloadURL", "http://mapdb.cncnet.org"); + + public string CnCNetMapDBUploadURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetMapDBUploadURL", "http://mapdb.cncnet.org/upload"); + + public bool DisableDiscordIntegration => networkDefinitionIni.GetBooleanValue(SETTINGS, "DisableDiscordIntegration", false); + + public List IRCServers => GetIRCServers(); + + #endregion + + public List GetIRCServers() + { + List servers = []; + + IniSection serversSection = networkDefinitionIni.GetSection("IRCServers"); + if (serversSection != null) + foreach ((_, string value) in serversSection.Keys) + if (!string.IsNullOrWhiteSpace(value)) + servers.Add(value); + + return servers; + } + + public bool IsDiscordIntegrationGloballyDisabled() + { + return string.IsNullOrWhiteSpace(DiscordAppId) || DisableDiscordIntegration; + } + public OSVersion GetOperatingSystemVersion() { #if NETFRAMEWORK diff --git a/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs b/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs index 1ba5e8756..8e329b117 100644 --- a/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs +++ b/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs @@ -140,7 +140,7 @@ private void InitOptions() chkConnectOnStartup.Bottom + 12, 0, 0); chkDiscordIntegration.Text = "Show detailed game info in Discord status".L10N("Client:DTAConfig:DiscordStatus"); - if (String.IsNullOrEmpty(ClientConfiguration.Instance.DiscordAppId)) + if (ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) { chkDiscordIntegration.AllowChecking = false; chkDiscordIntegration.Checked = false; @@ -317,7 +317,7 @@ public override void Load() chkSkipLoginWindow.Checked = IniSettings.SkipConnectDialog; chkPersistentMode.Checked = IniSettings.PersistentMode; - chkDiscordIntegration.Checked = !String.IsNullOrEmpty(ClientConfiguration.Instance.DiscordAppId) + chkDiscordIntegration.Checked = !ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled() && IniSettings.DiscordIntegration; chkAllowGameInvitesFromFriendsOnly.Checked = IniSettings.AllowGameInvitesFromFriendsOnly; @@ -352,7 +352,7 @@ public override bool Save() IniSettings.SkipConnectDialog.Value = chkSkipLoginWindow.Checked; IniSettings.PersistentMode.Value = chkPersistentMode.Checked; - if (!String.IsNullOrEmpty(ClientConfiguration.Instance.DiscordAppId)) + if (!ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) { IniSettings.DiscordIntegration.Value = chkDiscordIntegration.Checked; } diff --git a/DXMainClient/DXGUI/Generic/MainMenu.cs b/DXMainClient/DXGUI/Generic/MainMenu.cs index 795c55a66..8187761d1 100644 --- a/DXMainClient/DXGUI/Generic/MainMenu.cs +++ b/DXMainClient/DXGUI/Generic/MainMenu.cs @@ -410,7 +410,7 @@ private void SettingsSaved(object sender, EventArgs e) if (!connectionManager.IsConnected) ProgramConstants.PLAYERNAME = UserINISettings.Instance.PlayerName; - if (UserINISettings.Instance.DiscordIntegration) + if (UserINISettings.Instance.DiscordIntegration && !ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) discordHandler.Connect(); else discordHandler.Disconnect(); diff --git a/DXMainClient/Domain/DiscordHandler.cs b/DXMainClient/Domain/DiscordHandler.cs index b87e2bbfa..9cecb9ba8 100644 --- a/DXMainClient/Domain/DiscordHandler.cs +++ b/DXMainClient/Domain/DiscordHandler.cs @@ -48,7 +48,7 @@ public RichPresence CurrentPresence /// public DiscordHandler() { - if (!UserINISettings.Instance.DiscordIntegration || string.IsNullOrEmpty(ClientConfiguration.Instance.DiscordAppId)) + if (!UserINISettings.Instance.DiscordIntegration || ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) return; InitializeClient(); diff --git a/DXMainClient/Domain/MainClientConstants.cs b/DXMainClient/Domain/MainClientConstants.cs index b35e5346c..f5f05ec76 100644 --- a/DXMainClient/Domain/MainClientConstants.cs +++ b/DXMainClient/Domain/MainClientConstants.cs @@ -12,7 +12,7 @@ namespace DTAClient.Domain { public static class MainClientConstants { - public const string CNCNET_TUNNEL_LIST_URL = "http://cncnet.org/master-list"; + public static string CNCNET_TUNNEL_LIST_URL = "http://cncnet.org/master-list"; public static string GAME_NAME_LONG = "CnCNet Client"; public static string GAME_NAME_SHORT = "CnCNet"; @@ -92,6 +92,8 @@ public static void Initialize() CREDITS_URL = clientConfiguration.CreditsURL; + CNCNET_TUNNEL_LIST_URL = clientConfiguration.CnCNetTunnelListURL; + USE_ISOMETRIC_CELLS = clientConfiguration.UseIsometricCells; TDRA_WAYPOINT_COEFFICIENT = clientConfiguration.WaypointCoefficient; MAP_CELL_SIZE_X = clientConfiguration.MapCellSizeX; diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/CnCNetPlayerCountTask.cs b/DXMainClient/Domain/Multiplayer/CnCNet/CnCNetPlayerCountTask.cs index 0bf357b90..b417dd1d9 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/CnCNetPlayerCountTask.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/CnCNetPlayerCountTask.cs @@ -50,10 +50,15 @@ private static int GetCnCNetPlayerCount() { try { + // Don't fetch the player count if it is explicitly disabled + // For example, the official CnCNet server might be unavailable/unstable in a country with Internet censorship, + // which causes lags in the splash screen. In the worst case, say if packets are dropped, it waits until timeouts --- 30 seconds + if (string.IsNullOrWhiteSpace(ClientConfiguration.Instance.CnCNetPlayerCountURL)) + return -1; + WebClient client = new WebClient(); + Stream data = client.OpenRead(ClientConfiguration.Instance.CnCNetPlayerCountURL); - Stream data = client.OpenRead("http://api.cncnet.org/status"); - string info = string.Empty; using (StreamReader reader = new StreamReader(data)) diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs index 7dfa4e8a2..40b92e2ea 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs @@ -36,8 +36,6 @@ public static class MapSharer private static readonly object locker = new object(); - private const string MAPDB_URL = "http://mapdb.cncnet.org/upload"; - /// /// Adds a map into the CnCNet map upload queue. /// @@ -78,8 +76,14 @@ private static void Upload(object mapAndGame) Logger.Log("MapSharer: Starting upload of " + map.BaseFilePath); - bool success = false; - string message = MapUpload(MAPDB_URL, map, myGameId, out success); + if (string.IsNullOrWhiteSpace(ClientConfiguration.Instance.CnCNetMapDBUploadURL)) + { + Logger.Log("MapSharer: Upload URL is not set."); + MapUploadFailed?.Invoke(null, new MapEventArgs(map)); + return; + } + + string message = MapUpload(ClientConfiguration.Instance.CnCNetMapDBUploadURL, map, myGameId, out bool success); if (success) { @@ -380,12 +384,21 @@ private static string DownloadMain(string sha1, string myGame, string mapName, o using (TWebClient webClient = new TWebClient()) { + // TODO enable proxy support for some users webClient.Proxy = null; + if (string.IsNullOrWhiteSpace(ClientConfiguration.Instance.CnCNetMapDBDownloadURL)) + { + success = false; + return "MapSharer: Download URL is not set."; + } + + string url = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}.zip", ClientConfiguration.Instance.CnCNetMapDBDownloadURL, myGame, sha1); + try { - Logger.Log("MapSharer: Downloading URL: " + "http://mapdb.cncnet.org/" + myGame + "/" + sha1 + ".zip"); - webClient.DownloadFile("http://mapdb.cncnet.org/" + myGame + "/" + sha1 + ".zip", destinationFile.FullName); + Logger.Log($"MapSharer: Downloading URL: {url}"); + webClient.DownloadFile(url, destinationFile.FullName); } catch (Exception ex) { @@ -449,6 +462,7 @@ class TWebClient : WebClient public TWebClient() { + // TODO enable proxy support for some users this.Proxy = null; } diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs b/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs index 929a193b3..ae09ce8b9 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs @@ -143,48 +143,78 @@ private Task PingCurrentTunnelAsync(bool checkTunnelList = false) }); } - /// - /// Downloads and parses the list of CnCNet tunnels. - /// - /// A list of tunnel servers. - private List RefreshTunnels() - { - FileInfo tunnelCacheFile = SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache"); - - List returnValue = new List(); + private bool IsOnlineTunnelDataAvailable() => !string.IsNullOrWhiteSpace(MainClientConstants.CNCNET_TUNNEL_LIST_URL); + private bool IsOfflineTunnelDataAvailable() => SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache").Exists; + private byte[] GetRawTunnelDataOnline() + { WebClient client = new WebClient(); + return client.DownloadData(MainClientConstants.CNCNET_TUNNEL_LIST_URL); + } - byte[] data; + private byte[] GetRawTunnelDataOffline() + { + FileInfo tunnelCacheFile = SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache"); + return File.ReadAllBytes(tunnelCacheFile.FullName); + } + private byte[] GetRawTunnelData(int retryCount = 2) + { Logger.Log("Fetching tunnel server info."); - try - { - data = client.DownloadData(MainClientConstants.CNCNET_TUNNEL_LIST_URL); - } - catch (Exception ex) + if (IsOnlineTunnelDataAvailable()) { - Logger.Log("Error when downloading tunnel server info: " + ex.ToString()); - Logger.Log("Retrying."); - try + for (int i = 0; i < retryCount; i++) { - data = client.DownloadData(MainClientConstants.CNCNET_TUNNEL_LIST_URL); - } - catch - { - if (!tunnelCacheFile.Exists) + try { - Logger.Log("Tunnel cache file doesn't exist!"); - return returnValue; + byte[] data = GetRawTunnelDataOnline(); + return data; } - else + catch (Exception ex) { - Logger.Log("Fetching tunnel server list failed. Using cached tunnel data."); - data = File.ReadAllBytes(tunnelCacheFile.FullName); + Logger.Log("Error when downloading tunnel server info: " + ex.Message); + if (i < retryCount - 1) + Logger.Log("Retrying."); + else + Logger.Log("Fetching tunnel server list failed."); } } } + else + { + // Don't fetch the latest tunnel list if it is explicitly disabled + // For example, the official CnCNet server might be unavailable/unstable in a country with Internet censorship, + // where players might either establish a substitute server or manually distribute the tunnel cache file + Logger.Log("Fetching tunnel server list online is disabled."); + } + + if (IsOfflineTunnelDataAvailable()) + { + Logger.Log("Using cached tunnel data."); + byte[] data = GetRawTunnelDataOffline(); + return data; + } + else + Logger.Log("Tunnel cache file doesn't exist!"); + + return null; + } + + + /// + /// Downloads and parses the list of CnCNet tunnels. + /// + /// A list of tunnel servers. + private List RefreshTunnels() + { + List returnValue = new List(); + + FileInfo tunnelCacheFile = SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache"); + + byte[] data = GetRawTunnelData(); + if (data is null) + return returnValue; string convertedData = Encoding.Default.GetString(data); @@ -234,6 +264,7 @@ private List RefreshTunnels() } } + Logger.Log($"Successfully refreshed tunnel cache with {returnValue.Count} servers."); return returnValue; } diff --git a/DXMainClient/Online/Connection.cs b/DXMainClient/Online/Connection.cs index 3eed41359..27337787b 100644 --- a/DXMainClient/Online/Connection.cs +++ b/DXMainClient/Online/Connection.cs @@ -31,28 +31,47 @@ public Connection(IConnectionManager connectionManager) IConnectionManager connectionManager; + private static IList _servers = null; /// /// The list of CnCNet / GameSurge IRC servers to connect to. /// - private static readonly IList Servers = new List + private static IList Servers { - new Server("Burstfire.UK.EU.GameSurge.net", "GameSurge London, UK", new int[3] { 6667, 6668, 7000 }), - new Server("ColoCrossing.IL.US.GameSurge.net", "GameSurge Chicago, IL", new int[5] { 6660, 6666, 6667, 6668, 6669 }), - new Server("Gameservers.NJ.US.GameSurge.net", "GameSurge Newark, NJ", new int[7] { 6665, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("Krypt.CA.US.GameSurge.net", "GameSurge Santa Ana, CA", new int[4] { 6666, 6667, 6668, 6669 }), - new Server("NuclearFallout.WA.US.GameSurge.net", "GameSurge Seattle, WA", new int[2] { 6667, 5960 }), - new Server("Portlane.SE.EU.GameSurge.net", "GameSurge Stockholm, Sweden", new int[5] { 6660, 6666, 6667, 6668, 6669 }), - new Server("Prothid.NY.US.GameSurge.Net", "GameSurge NYC, NY", new int[7] { 5960, 6660, 6666, 6667, 6668, 6669, 6697 }), - new Server("TAL.DE.EU.GameSurge.net", "GameSurge Wuppertal, Germany", new int[5] { 6660, 6666, 6667, 6668, 6669 }), - new Server("208.167.237.120", "GameSurge IP 208.167.237.120", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("192.223.27.109", "GameSurge IP 192.223.27.109", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("108.174.48.100", "GameSurge IP 108.174.48.100", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("208.146.35.105", "GameSurge IP 208.146.35.105", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("195.8.250.180", "GameSurge IP 195.8.250.180", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("91.217.189.76", "GameSurge IP 91.217.189.76", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("195.68.206.250", "GameSurge IP 195.68.206.250", new int[7] { 6660, 6666, 6667, 6668, 6669, 7000, 8080 }), - new Server("irc.gamesurge.net", "GameSurge", new int[1] { 6667 }), - }.AsReadOnly(); + get + { + if (_servers is not null) + return _servers; + + IEnumerable serversList; + if (ClientConfiguration.Instance.IRCServers.Count > 0) + serversList = ClientConfiguration.Instance.IRCServers; + else + { + // fallback to the hardcoded server list + serversList = [ + "Burstfire.UK.EU.GameSurge.net|GameSurge London, UK|6667,6668,7000", + "ColoCrossing.IL.US.GameSurge.net|GameSurge Chicago, IL|6660,6666,6667,6668,6669", + "Gameservers.NJ.US.GameSurge.net|GameSurge Newark, NJ|6665,6666,6667,6668,6669,7000,8080", + "Krypt.CA.US.GameSurge.net|GameSurge Santa Ana, CA|6666,6667,6668,6669", + "NuclearFallout.WA.US.GameSurge.net|GameSurge Seattle, WA|6667,5960", + "Portlane.SE.EU.GameSurge.net|GameSurge Stockholm, Sweden|6660,6666,6667,6668,6669", + "Prothid.NY.US.GameSurge.Net|GameSurge NYC, NY|5960,6660,6666,6667,6668,6669,6697", + "TAL.DE.EU.GameSurge.net|GameSurge Wuppertal, Germany|6660,6666,6667,6668,6669", + "208.167.237.120|GameSurge IP 208.167.237.120|6660,6666,6667,6668,6669,7000,8080", + "192.223.27.109|GameSurge IP 192.223.27.109|6660,6666,6667,6668,6669,7000,8080", + "108.174.48.100|GameSurge IP 108.174.48.100|6660,6666,6667,6668,6669,7000,8080", + "208.146.35.105|GameSurge IP 208.146.35.105|6660,6666,6667,6668,6669,7000,8080", + "195.8.250.180|GameSurge IP 195.8.250.180|6660,6666,6667,6668,6669,7000,8080", + "91.217.189.76|GameSurge IP 91.217.189.76|6660,6666,6667,6668,6669,7000,8080", + "195.68.206.250|GameSurge IP 195.68.206.250|6660,6666,6667,6668,6669,7000,8080", + "irc.gamesurge.net|GameSurge|6667", + ]; + } + + _servers = serversList.Select(Server.Deserialize).ToList(); + return _servers; + } + } bool _isConnected = false; public bool IsConnected diff --git a/DXMainClient/Online/Server.cs b/DXMainClient/Online/Server.cs index e603b8135..7072bc220 100644 --- a/DXMainClient/Online/Server.cs +++ b/DXMainClient/Online/Server.cs @@ -15,5 +15,26 @@ public Server(string host, string name, int[] ports) public string Host; public string Name; public int[] Ports; + + public string Serialize() + { + return $"{Host}|{Name}|{string.Join(",", Ports)}"; + } + + public static Server Deserialize(string serialized) + { + string[] parts = serialized.Split('|'); + string host = parts[0]; + string name = parts[1]; + string[] portStrings = parts[2].Split(','); + int[] ports = new int[portStrings.Length]; + + for (int i = 0; i < portStrings.Length; i++) + { + ports[i] = int.Parse(portStrings[i]); + } + + return new Server(host, name, ports); + } } } diff --git a/DXMainClient/Resources/DTA/NetworkDefinitions.ini b/DXMainClient/Resources/DTA/NetworkDefinitions.ini new file mode 100644 index 000000000..fcd148840 --- /dev/null +++ b/DXMainClient/Resources/DTA/NetworkDefinitions.ini @@ -0,0 +1,24 @@ +[Settings] +CnCNetTunnelListURL=http://cncnet.org/master-list +CnCNetPlayerCountURL=http://api.cncnet.org/status +CnCNetMapDBDownloadURL=http://mapdb.cncnet.org +CnCNetMapDBUploadURL=http://mapdb.cncnet.org/upload +DisableDiscordIntegration=False + +[IRCServers] +1=Burstfire.UK.EU.GameSurge.net|GameSurge London, UK|6667,6668,7000 +2=ColoCrossing.IL.US.GameSurge.net|GameSurge Chicago, IL|6660,6666,6667,6668,6669 +3=Gameservers.NJ.US.GameSurge.net|GameSurge Newark, NJ|6665,6666,6667,6668,6669,7000,8080 +4=Krypt.CA.US.GameSurge.net|GameSurge Santa Ana, CA|6666,6667,6668,6669 +5=NuclearFallout.WA.US.GameSurge.net|GameSurge Seattle, WA|6667,5960 +6=Portlane.SE.EU.GameSurge.net|GameSurge Stockholm, Sweden|6660,6666,6667,6668,6669 +7=Prothid.NY.US.GameSurge.Net|GameSurge NYC, NY|5960,6660,6666,6667,6668,6669,6697 +8=TAL.DE.EU.GameSurge.net|GameSurge Wuppertal, Germany|6660,6666,6667,6668,6669 +9=208.167.237.120|GameSurge IP 208.167.237.120|6660,6666,6667,6668,6669,7000,8080 +10=192.223.27.109|GameSurge IP 192.223.27.109|6660,6666,6667,6668,6669,7000,8080 +11=108.174.48.100|GameSurge IP 108.174.48.100|6660,6666,6667,6668,6669,7000,8080 +12=208.146.35.105|GameSurge IP 208.146.35.105|6660,6666,6667,6668,6669,7000,8080 +13=195.8.250.180|GameSurge IP 195.8.250.180|6660,6666,6667,6668,6669,7000,8080 +14=91.217.189.76|GameSurge IP 91.217.189.76|6660,6666,6667,6668,6669,7000,8080 +15=195.68.206.250|GameSurge IP 195.68.206.250|6660,6666,6667,6668,6669,7000,8080 +16=irc.gamesurge.net|GameSurge|6667 From 709a3b988ffae75f7d464fbe943f4eae40df2331 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 00:07:53 +0800 Subject: [PATCH 2/7] Remove duplicated IRC servers --- DXMainClient/Online/Connection.cs | 19 ++----------------- .../Resources/DTA/NetworkDefinitions.ini | 17 +---------------- 2 files changed, 3 insertions(+), 33 deletions(-) diff --git a/DXMainClient/Online/Connection.cs b/DXMainClient/Online/Connection.cs index 27337787b..15ad88087 100644 --- a/DXMainClient/Online/Connection.cs +++ b/DXMainClient/Online/Connection.cs @@ -47,24 +47,9 @@ private static IList Servers serversList = ClientConfiguration.Instance.IRCServers; else { - // fallback to the hardcoded server list + // fallback to the hardcoded servers list serversList = [ - "Burstfire.UK.EU.GameSurge.net|GameSurge London, UK|6667,6668,7000", - "ColoCrossing.IL.US.GameSurge.net|GameSurge Chicago, IL|6660,6666,6667,6668,6669", - "Gameservers.NJ.US.GameSurge.net|GameSurge Newark, NJ|6665,6666,6667,6668,6669,7000,8080", - "Krypt.CA.US.GameSurge.net|GameSurge Santa Ana, CA|6666,6667,6668,6669", - "NuclearFallout.WA.US.GameSurge.net|GameSurge Seattle, WA|6667,5960", - "Portlane.SE.EU.GameSurge.net|GameSurge Stockholm, Sweden|6660,6666,6667,6668,6669", - "Prothid.NY.US.GameSurge.Net|GameSurge NYC, NY|5960,6660,6666,6667,6668,6669,6697", - "TAL.DE.EU.GameSurge.net|GameSurge Wuppertal, Germany|6660,6666,6667,6668,6669", - "208.167.237.120|GameSurge IP 208.167.237.120|6660,6666,6667,6668,6669,7000,8080", - "192.223.27.109|GameSurge IP 192.223.27.109|6660,6666,6667,6668,6669,7000,8080", - "108.174.48.100|GameSurge IP 108.174.48.100|6660,6666,6667,6668,6669,7000,8080", - "208.146.35.105|GameSurge IP 208.146.35.105|6660,6666,6667,6668,6669,7000,8080", - "195.8.250.180|GameSurge IP 195.8.250.180|6660,6666,6667,6668,6669,7000,8080", - "91.217.189.76|GameSurge IP 91.217.189.76|6660,6666,6667,6668,6669,7000,8080", - "195.68.206.250|GameSurge IP 195.68.206.250|6660,6666,6667,6668,6669,7000,8080", - "irc.gamesurge.net|GameSurge|6667", + "irc.gamesurge.net|GameSurge|6667,6660,6666,6668,6669", ]; } diff --git a/DXMainClient/Resources/DTA/NetworkDefinitions.ini b/DXMainClient/Resources/DTA/NetworkDefinitions.ini index fcd148840..7d4490937 100644 --- a/DXMainClient/Resources/DTA/NetworkDefinitions.ini +++ b/DXMainClient/Resources/DTA/NetworkDefinitions.ini @@ -6,19 +6,4 @@ CnCNetMapDBUploadURL=http://mapdb.cncnet.org/upload DisableDiscordIntegration=False [IRCServers] -1=Burstfire.UK.EU.GameSurge.net|GameSurge London, UK|6667,6668,7000 -2=ColoCrossing.IL.US.GameSurge.net|GameSurge Chicago, IL|6660,6666,6667,6668,6669 -3=Gameservers.NJ.US.GameSurge.net|GameSurge Newark, NJ|6665,6666,6667,6668,6669,7000,8080 -4=Krypt.CA.US.GameSurge.net|GameSurge Santa Ana, CA|6666,6667,6668,6669 -5=NuclearFallout.WA.US.GameSurge.net|GameSurge Seattle, WA|6667,5960 -6=Portlane.SE.EU.GameSurge.net|GameSurge Stockholm, Sweden|6660,6666,6667,6668,6669 -7=Prothid.NY.US.GameSurge.Net|GameSurge NYC, NY|5960,6660,6666,6667,6668,6669,6697 -8=TAL.DE.EU.GameSurge.net|GameSurge Wuppertal, Germany|6660,6666,6667,6668,6669 -9=208.167.237.120|GameSurge IP 208.167.237.120|6660,6666,6667,6668,6669,7000,8080 -10=192.223.27.109|GameSurge IP 192.223.27.109|6660,6666,6667,6668,6669,7000,8080 -11=108.174.48.100|GameSurge IP 108.174.48.100|6660,6666,6667,6668,6669,7000,8080 -12=208.146.35.105|GameSurge IP 208.146.35.105|6660,6666,6667,6668,6669,7000,8080 -13=195.8.250.180|GameSurge IP 195.8.250.180|6660,6666,6667,6668,6669,7000,8080 -14=91.217.189.76|GameSurge IP 91.217.189.76|6660,6666,6667,6668,6669,7000,8080 -15=195.68.206.250|GameSurge IP 195.68.206.250|6660,6666,6667,6668,6669,7000,8080 -16=irc.gamesurge.net|GameSurge|6667 +1=irc.gamesurge.net|GameSurge|6667,6660,6666,6668,6669 \ No newline at end of file From f1f4e2aaffd3b5a71a927e9b77de2a9e105c78a0 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 17:36:13 +0800 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Kerbiter --- DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs | 2 +- DXMainClient/Online/Server.cs | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs index 40b92e2ea..a2dca7075 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs @@ -78,7 +78,7 @@ private static void Upload(object mapAndGame) if (string.IsNullOrWhiteSpace(ClientConfiguration.Instance.CnCNetMapDBUploadURL)) { - Logger.Log("MapSharer: Upload URL is not set."); + Logger.Log("MapSharer: Upload URL is not configured."); MapUploadFailed?.Invoke(null, new MapEventArgs(map)); return; } diff --git a/DXMainClient/Online/Server.cs b/DXMainClient/Online/Server.cs index 7072bc220..bb14d7d35 100644 --- a/DXMainClient/Online/Server.cs +++ b/DXMainClient/Online/Server.cs @@ -16,10 +16,7 @@ public Server(string host, string name, int[] ports) public string Name; public int[] Ports; - public string Serialize() - { - return $"{Host}|{Name}|{string.Join(",", Ports)}"; - } + public string Serialize() => $"{Host}|{Name}|{string.Join(",", Ports)}"; public static Server Deserialize(string serialized) { @@ -30,9 +27,7 @@ public static Server Deserialize(string serialized) int[] ports = new int[portStrings.Length]; for (int i = 0; i < portStrings.Length; i++) - { ports[i] = int.Parse(portStrings[i]); - } return new Server(host, name, ports); } From 4576193ff067ebfe94de23061f42455c42642776 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 17:39:22 +0800 Subject: [PATCH 4/7] Make methods as properties --- ClientCore/ClientConfiguration.cs | 7 ++----- DTAConfig/OptionPanels/CnCNetOptionsPanel.cs | 6 +++--- DXMainClient/DXGUI/Generic/MainMenu.cs | 2 +- DXMainClient/Domain/DiscordHandler.cs | 2 +- DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs | 8 ++++---- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ClientCore/ClientConfiguration.cs b/ClientCore/ClientConfiguration.cs index 313be94bc..f3d23ea60 100644 --- a/ClientCore/ClientConfiguration.cs +++ b/ClientCore/ClientConfiguration.cs @@ -418,11 +418,8 @@ public List GetIRCServers() return servers; } - public bool IsDiscordIntegrationGloballyDisabled() - { - return string.IsNullOrWhiteSpace(DiscordAppId) || DisableDiscordIntegration; - } - + public bool DiscordIntegrationGloballyDisabled => string.IsNullOrWhiteSpace(DiscordAppId) || DisableDiscordIntegration; + public OSVersion GetOperatingSystemVersion() { #if NETFRAMEWORK diff --git a/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs b/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs index 8e329b117..13ce2142f 100644 --- a/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs +++ b/DTAConfig/OptionPanels/CnCNetOptionsPanel.cs @@ -140,7 +140,7 @@ private void InitOptions() chkConnectOnStartup.Bottom + 12, 0, 0); chkDiscordIntegration.Text = "Show detailed game info in Discord status".L10N("Client:DTAConfig:DiscordStatus"); - if (ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) + if (ClientConfiguration.Instance.DiscordIntegrationGloballyDisabled) { chkDiscordIntegration.AllowChecking = false; chkDiscordIntegration.Checked = false; @@ -317,7 +317,7 @@ public override void Load() chkSkipLoginWindow.Checked = IniSettings.SkipConnectDialog; chkPersistentMode.Checked = IniSettings.PersistentMode; - chkDiscordIntegration.Checked = !ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled() + chkDiscordIntegration.Checked = !ClientConfiguration.Instance.DiscordIntegrationGloballyDisabled && IniSettings.DiscordIntegration; chkAllowGameInvitesFromFriendsOnly.Checked = IniSettings.AllowGameInvitesFromFriendsOnly; @@ -352,7 +352,7 @@ public override bool Save() IniSettings.SkipConnectDialog.Value = chkSkipLoginWindow.Checked; IniSettings.PersistentMode.Value = chkPersistentMode.Checked; - if (!ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) + if (!ClientConfiguration.Instance.DiscordIntegrationGloballyDisabled) { IniSettings.DiscordIntegration.Value = chkDiscordIntegration.Checked; } diff --git a/DXMainClient/DXGUI/Generic/MainMenu.cs b/DXMainClient/DXGUI/Generic/MainMenu.cs index 8187761d1..8c0749a38 100644 --- a/DXMainClient/DXGUI/Generic/MainMenu.cs +++ b/DXMainClient/DXGUI/Generic/MainMenu.cs @@ -410,7 +410,7 @@ private void SettingsSaved(object sender, EventArgs e) if (!connectionManager.IsConnected) ProgramConstants.PLAYERNAME = UserINISettings.Instance.PlayerName; - if (UserINISettings.Instance.DiscordIntegration && !ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) + if (UserINISettings.Instance.DiscordIntegration && !ClientConfiguration.Instance.DiscordIntegrationGloballyDisabled) discordHandler.Connect(); else discordHandler.Disconnect(); diff --git a/DXMainClient/Domain/DiscordHandler.cs b/DXMainClient/Domain/DiscordHandler.cs index 9cecb9ba8..7fc292a93 100644 --- a/DXMainClient/Domain/DiscordHandler.cs +++ b/DXMainClient/Domain/DiscordHandler.cs @@ -48,7 +48,7 @@ public RichPresence CurrentPresence /// public DiscordHandler() { - if (!UserINISettings.Instance.DiscordIntegration || ClientConfiguration.Instance.IsDiscordIntegrationGloballyDisabled()) + if (!UserINISettings.Instance.DiscordIntegration || ClientConfiguration.Instance.DiscordIntegrationGloballyDisabled) return; InitializeClient(); diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs b/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs index ae09ce8b9..d569e017b 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/TunnelHandler.cs @@ -143,8 +143,8 @@ private Task PingCurrentTunnelAsync(bool checkTunnelList = false) }); } - private bool IsOnlineTunnelDataAvailable() => !string.IsNullOrWhiteSpace(MainClientConstants.CNCNET_TUNNEL_LIST_URL); - private bool IsOfflineTunnelDataAvailable() => SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache").Exists; + private bool OnlineTunnelDataAvailable => !string.IsNullOrWhiteSpace(MainClientConstants.CNCNET_TUNNEL_LIST_URL); + private bool OfflineTunnelDataAvailable => SafePath.GetFile(ProgramConstants.ClientUserFilesPath, "tunnel_cache").Exists; private byte[] GetRawTunnelDataOnline() { @@ -162,7 +162,7 @@ private byte[] GetRawTunnelData(int retryCount = 2) { Logger.Log("Fetching tunnel server info."); - if (IsOnlineTunnelDataAvailable()) + if (OnlineTunnelDataAvailable) { for (int i = 0; i < retryCount; i++) { @@ -189,7 +189,7 @@ private byte[] GetRawTunnelData(int retryCount = 2) Logger.Log("Fetching tunnel server list online is disabled."); } - if (IsOfflineTunnelDataAvailable()) + if (OfflineTunnelDataAvailable) { Logger.Log("Using cached tunnel data."); byte[] data = GetRawTunnelDataOffline(); From d6a2aff3c9bdb29b37ceb4749c31ced0dfa61c5b Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 17:41:08 +0800 Subject: [PATCH 5/7] Use Invariant culture in Server.Serialize() --- DXMainClient/Online/Server.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DXMainClient/Online/Server.cs b/DXMainClient/Online/Server.cs index bb14d7d35..96cc3c51b 100644 --- a/DXMainClient/Online/Server.cs +++ b/DXMainClient/Online/Server.cs @@ -1,4 +1,6 @@ -namespace DTAClient.Online +using System; + +namespace DTAClient.Online { /// /// A struct containing information on an IRC server. @@ -16,7 +18,7 @@ public Server(string host, string name, int[] ports) public string Name; public int[] Ports; - public string Serialize() => $"{Host}|{Name}|{string.Join(",", Ports)}"; + public string Serialize() => FormattableString.Invariant($"{Host}|{Name}|{string.Join(",", Ports)}"); public static Server Deserialize(string serialized) { From 22e1554ed756c9c0eadc60ae1702c25e4ca43b49 Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 17:43:43 +0800 Subject: [PATCH 6/7] Log when Download URL is not configured --- DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs index a2dca7075..99fb6905d 100644 --- a/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs +++ b/DXMainClient/Domain/Multiplayer/CnCNet/MapSharer.cs @@ -390,7 +390,8 @@ private static string DownloadMain(string sha1, string myGame, string mapName, o if (string.IsNullOrWhiteSpace(ClientConfiguration.Instance.CnCNetMapDBDownloadURL)) { success = false; - return "MapSharer: Download URL is not set."; + Logger.Log("MapSharer: Download URL is not configured."); + return null; } string url = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}.zip", ClientConfiguration.Instance.CnCNetMapDBDownloadURL, myGame, sha1); From 1afaaf7e594b6e9ef1434d27d48363f84119f9ff Mon Sep 17 00:00:00 2001 From: SadPencil Date: Fri, 15 Mar 2024 17:49:02 +0800 Subject: [PATCH 7/7] networkDefinitionIni -> networkDefinitionsIni --- ClientCore/ClientConfiguration.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/ClientCore/ClientConfiguration.cs b/ClientCore/ClientConfiguration.cs index f3d23ea60..d80fb6a05 100644 --- a/ClientCore/ClientConfiguration.cs +++ b/ClientCore/ClientConfiguration.cs @@ -27,7 +27,7 @@ public class ClientConfiguration private IniFile gameOptions_ini; private IniFile DTACnCNetClient_ini; private IniFile clientDefinitionsIni; - private IniFile networkDefinitionIni; + private IniFile networkDefinitionsIni; protected ClientConfiguration() { @@ -47,7 +47,7 @@ protected ClientConfiguration() gameOptions_ini = new IniFile(SafePath.CombineFilePath(baseResourceDirectory.FullName, GAME_OPTIONS)); - networkDefinitionIni = new IniFile(SafePath.CombineFilePath(ProgramConstants.GetResourcePath(), NETWORK_DEFS)); + networkDefinitionsIni = new IniFile(SafePath.CombineFilePath(ProgramConstants.GetResourcePath(), NETWORK_DEFS)); } /// @@ -391,15 +391,15 @@ public IEnumerable SupplementalMapFileExtensions #region Network definitions - public string CnCNetTunnelListURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetTunnelListURL", "http://cncnet.org/master-list"); + public string CnCNetTunnelListURL => networkDefinitionsIni.GetStringValue(SETTINGS, "CnCNetTunnelListURL", "http://cncnet.org/master-list"); - public string CnCNetPlayerCountURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetPlayerCountURL", "http://api.cncnet.org/status"); + public string CnCNetPlayerCountURL => networkDefinitionsIni.GetStringValue(SETTINGS, "CnCNetPlayerCountURL", "http://api.cncnet.org/status"); - public string CnCNetMapDBDownloadURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetMapDBDownloadURL", "http://mapdb.cncnet.org"); + public string CnCNetMapDBDownloadURL => networkDefinitionsIni.GetStringValue(SETTINGS, "CnCNetMapDBDownloadURL", "http://mapdb.cncnet.org"); - public string CnCNetMapDBUploadURL => networkDefinitionIni.GetStringValue(SETTINGS, "CnCNetMapDBUploadURL", "http://mapdb.cncnet.org/upload"); + public string CnCNetMapDBUploadURL => networkDefinitionsIni.GetStringValue(SETTINGS, "CnCNetMapDBUploadURL", "http://mapdb.cncnet.org/upload"); - public bool DisableDiscordIntegration => networkDefinitionIni.GetBooleanValue(SETTINGS, "DisableDiscordIntegration", false); + public bool DisableDiscordIntegration => networkDefinitionsIni.GetBooleanValue(SETTINGS, "DisableDiscordIntegration", false); public List IRCServers => GetIRCServers(); @@ -409,7 +409,7 @@ public List GetIRCServers() { List servers = []; - IniSection serversSection = networkDefinitionIni.GetSection("IRCServers"); + IniSection serversSection = networkDefinitionsIni.GetSection("IRCServers"); if (serversSection != null) foreach ((_, string value) in serversSection.Keys) if (!string.IsNullOrWhiteSpace(value))