From 5775bbdf42cf8c3c1191841b4cbb96de7b0aedee Mon Sep 17 00:00:00 2001 From: Redstones563 Date: Mon, 10 Mar 2025 18:00:11 -0400 Subject: [PATCH 1/9] Added proxy support for the hub Very rough code. I never really use C# to be honest, and my networking experience is lacking, but it does work, and fairly well. --- SS14.Launcher/HappyEyeballsHttp.cs | 18 +++++++++++++++-- SS14.Launcher/HttpSelfTest.cs | 2 +- SS14.Launcher/Models/Data/CVars.cs | 10 ++++++++++ SS14.Launcher/Program.cs | 2 +- .../MainWindowTabs/OptionsTabViewModel.cs | 20 +++++++++++++++++++ .../Views/MainWindowTabs/OptionsTabView.xaml | 8 +++++++- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/SS14.Launcher/HappyEyeballsHttp.cs b/SS14.Launcher/HappyEyeballsHttp.cs index bf594ba4e..b64bd3f58 100644 --- a/SS14.Launcher/HappyEyeballsHttp.cs +++ b/SS14.Launcher/HappyEyeballsHttp.cs @@ -9,7 +9,6 @@ using System.Threading; using System.Threading.Tasks; using Serilog; - namespace SS14.Launcher; public static class HappyEyeballsHttp @@ -39,8 +38,9 @@ public static class HappyEyeballsHttp // * Look I wanted to keep this simple OK? // We don't do any fancy shit like statefulness or incremental sorting // or incremental DNS updates who cares about that. - public static HttpClient CreateHttpClient(bool autoRedirect = true) + public static HttpClient CreateHttpClient(bool autoRedirect = true, string proxyUrl = "") { + // Log.Verbose("PROXY_URL: ", proxyUrl); var handler = new SocketsHttpHandler { ConnectCallback = OnConnect, @@ -48,6 +48,20 @@ public static HttpClient CreateHttpClient(bool autoRedirect = true) AllowAutoRedirect = autoRedirect, // PooledConnectionLifetime = TimeSpan.FromSeconds(1) }; + if (!String.IsNullOrEmpty(proxyUrl)){ //Note: I'm VERY new to writing c#. This is heavily copied from koksnull's work in https://github.com/space-wizards/SS14.Launcher/pull/144 . I've just made some adjustments to make it work for the modern versions of .net + //I'm unsure of how to go about this, but having some way to sanity check the proxy before activating it (i.e. a test ping) would be great. + Uri proxyURI = new Uri(proxyUrl.Trim('"')); + WebProxy clientProxy = new WebProxy(proxyUrl.Trim('"')); + if (!string.IsNullOrWhiteSpace(proxyURI.UserInfo)){ + string[] credentials = proxyURI.UserInfo.Split(new[] { ':' }); + if (credentials.Length > 1){ + NetworkCredential cred = new NetworkCredential(userName: credentials[0], password: credentials[1]); + clientProxy.Credentials = cred; + } + } + handler.UseProxy = true; + handler.Proxy = clientProxy; + } return new HttpClient(handler); } diff --git a/SS14.Launcher/HttpSelfTest.cs b/SS14.Launcher/HttpSelfTest.cs index bf476fe22..7eddf2e6f 100644 --- a/SS14.Launcher/HttpSelfTest.cs +++ b/SS14.Launcher/HttpSelfTest.cs @@ -80,7 +80,7 @@ async Task RunSingleTest(string name, Func test) private static async Task TestHappyEyeballsHttp(int id, string url) { - using var client = HappyEyeballsHttp.CreateHttpClient(false); + using var client = HappyEyeballsHttp.CreateHttpClient(false); //Note: It may be worth refactoring this to also allow the http checks to be done via proxy. Afaik it doesn't cause issues, and would require giving it a ref to DataManager but it could certainly be done. using var resp = await client.GetAsync(url); diff --git a/SS14.Launcher/Models/Data/CVars.cs b/SS14.Launcher/Models/Data/CVars.cs index 331889b74..899f516ef 100644 --- a/SS14.Launcher/Models/Data/CVars.cs +++ b/SS14.Launcher/Models/Data/CVars.cs @@ -114,6 +114,16 @@ public static readonly CVarDef HasDismissedEarlyAccessWarning /// Language the user selected. Null means it should be automatically selected based on system language. /// public static readonly CVarDef Language = CVarDef.Create("Language", null); + + /// + /// Weather the proxy is enabled for HappyEyeballsHttp connections (ie auth server/build server/hub connections, not game server connections) + /// + public static readonly CVarDef ProxyEnable = CVarDef.Create("ProxyEnable", false); + + /// + /// Url for proxy connections. + /// + public static readonly CVarDef ProxyURL = CVarDef.Create("ProxyURL", ""); } /// diff --git a/SS14.Launcher/Program.cs b/SS14.Launcher/Program.cs index e27bec068..e02422626 100644 --- a/SS14.Launcher/Program.cs +++ b/SS14.Launcher/Program.cs @@ -213,7 +213,7 @@ private static AppBuilder BuildAvaloniaApp(DataManager cfg) { var locator = Locator.CurrentMutable; - var http = HappyEyeballsHttp.CreateHttpClient(); + var http = (cfg.GetCVar(CVars.ProxyEnable)) ? HappyEyeballsHttp.CreateHttpClient(proxyUrl: cfg.GetCVar(CVars.ProxyURL)) : HappyEyeballsHttp.CreateHttpClient(); //Ternary for creating connection with or without proxy http.DefaultRequestHeaders.UserAgent.Add( new ProductInfoHeaderValue(LauncherVersion.Name, LauncherVersion.Version?.ToString())); http.DefaultRequestHeaders.Add("SS14-Launcher-Fingerprint", cfg.Fingerprint.ToString()); diff --git a/SS14.Launcher/ViewModels/MainWindowTabs/OptionsTabViewModel.cs b/SS14.Launcher/ViewModels/MainWindowTabs/OptionsTabViewModel.cs index 2dec1f94c..1605bcf30 100644 --- a/SS14.Launcher/ViewModels/MainWindowTabs/OptionsTabViewModel.cs +++ b/SS14.Launcher/ViewModels/MainWindowTabs/OptionsTabViewModel.cs @@ -100,6 +100,26 @@ public void ClearEngines() _engineManager.ClearAllEngines(); } + public bool ProxyEnable + { + get => Cfg.GetCVar(CVars.ProxyEnable); + set + { + Cfg.SetCVar(CVars.ProxyEnable, value); + Cfg.CommitConfig(); + } + } + + public string ProxyURL + { + get => Cfg.GetCVar(CVars.ProxyURL); + set + { + Cfg.SetCVar(CVars.ProxyURL, value); + Cfg.CommitConfig(); + } + } + public void ClearServerContent() { _contentManager.ClearAll(); diff --git a/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml b/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml index 1d12c675a..30fabfa09 100644 --- a/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml +++ b/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml @@ -65,7 +65,13 @@ - + + Enable proxy + + +