From b017618b3be355ac26561bce2099f7ba2f76368e Mon Sep 17 00:00:00 2001 From: Tarensaror Date: Thu, 7 Nov 2024 01:07:50 +0100 Subject: [PATCH] feat(dns): Softens character limit for input and resolves dns if necessary so dynamic ip-lookup can be used --- .../Connect/ClientConnectionService.cs | 79 +++++++++++++++++-- BeaverBuddies/Connect/ClientConnectionUI.cs | 18 ++++- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/BeaverBuddies/Connect/ClientConnectionService.cs b/BeaverBuddies/Connect/ClientConnectionService.cs index 3afb3c1..c6ff8d9 100644 --- a/BeaverBuddies/Connect/ClientConnectionService.cs +++ b/BeaverBuddies/Connect/ClientConnectionService.cs @@ -2,6 +2,8 @@ using BeaverBuddies.Util; using System; using System.IO; +using System.Net.Sockets; +using System.Net; using Timberborn.CoreUI; using Timberborn.GameSaveRepositorySystem; using Timberborn.GameSceneLoading; @@ -55,13 +57,42 @@ public bool TryToConnect(string address) // it's actually loaded. SingletonManager.Reset(); Plugin.Log("Connecting client"); - client = ClientEventIO.Create(address, EventIO.Config.Port, LoadMap, (error) => + Plugin.Log("Try to resolve address: " + address); + + try + { + // Parse address and port + var (hostAddress, port) = ParseAddressAndPort(address); + + // Set port if provided + if (port.HasValue) + { + EventIO.Config.Port = port.Value; + } + + // Resolve the address if it's a hostname + hostAddress = ResolveHostnameIfNecessary(hostAddress); + + // Attempt to create the client + client = ClientEventIO.Create(hostAddress, EventIO.Config.Port, LoadMap, error => + { + ShowError("BeaverBuddies.JoinCoopGame.ConnectionFailedMessageWithError", error); + }); + + if (client == null) + { + Plugin.Log("Client creation failed."); + return false; + } + + EventIO.Set(client); + return true; + } + catch (Exception ex) { - ShowError("BeaverBuddies.JoinCoopGame.ConnectionFailedMessageWithError", error); - }); - if (client == null) return false; - EventIO.Set(client); - return true; + ShowError("BeaverBuddies.JoinCoopGame.ConnectionFailedMessageWithError", ex.Message); + return false; + } } public void ConnectOrShowFailureMessage() @@ -116,5 +147,41 @@ public void UpdateSingleton() //Plugin.Log("Updating client!"); client.Update(); } + + private (string, int?) ParseAddressAndPort(string address) + { + // If address contains a port, split and parse it + if (address.Contains(":")) + { + var tokens = address.Split(':'); + if (tokens.Length == 2 && int.TryParse(tokens[1], out int port)) + { + return (tokens[0], port); + } + else + { + throw new FormatException("Invalid address format. Could not parse port."); + } + } + return (address, null); + } + + private string ResolveHostnameIfNecessary(string address) + { + // If it's not an IP address, resolve the hostname + if (!IPAddress.TryParse(address, out _)) + { + IPHostEntry hostEntry = Dns.GetHostEntry(address); + if (hostEntry.AddressList.Length > 0) + { + return hostEntry.AddressList[0].ToString(); + } + else + { + throw new Exception("Hostname could not be resolved to an IP address."); + } + } + return address; // If already an IP, return as-is + } } } diff --git a/BeaverBuddies/Connect/ClientConnectionUI.cs b/BeaverBuddies/Connect/ClientConnectionUI.cs index 0b9d5b5..f102709 100644 --- a/BeaverBuddies/Connect/ClientConnectionUI.cs +++ b/BeaverBuddies/Connect/ClientConnectionUI.cs @@ -3,6 +3,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Reflection; using System.Text; using Timberborn.CoreUI; using Timberborn.Localization; @@ -64,6 +66,12 @@ public void AddJoinButton(VisualElement __result) private void ShowBox() { + FieldInfo characterLimitField = typeof(InputBoxShower).GetField("CharacterLimit", BindingFlags.Static | BindingFlags.NonPublic); + if (characterLimitField != null) + { + characterLimitField.SetValue(null, 100); + } + ILoc _loc = _inputBoxShower._loc; var builder = _inputBoxShower.Create() .SetLocalizedMessage(_loc.T("BeaverBuddies.JoinCoopGame.EnterIp")) @@ -73,7 +81,15 @@ private void ShowBox() _configIOService.SaveConfigToFile(); _clientConnectionService.ConnectOrShowFailureMessage(ip); }); - builder._input.value = EventIO.Config.ClientConnectionAddress; + + FieldInfo inputFieldInfo = typeof(InputBoxShower.Builder).GetField("_input", BindingFlags.Instance | BindingFlags.NonPublic); + TextField inputField = inputFieldInfo?.GetValue(builder) as TextField; + if (inputField != null) + { + inputField.maxLength = 100; + inputField.value = EventIO.Config.ClientConnectionAddress; + } + builder.Show(); } }