diff --git a/SS14.Launcher/Assets/Locale/en-US/text.ftl b/SS14.Launcher/Assets/Locale/en-US/text.ftl index 10e1d0283..5d53d410e 100644 --- a/SS14.Launcher/Assets/Locale/en-US/text.ftl +++ b/SS14.Launcher/Assets/Locale/en-US/text.ftl @@ -339,7 +339,9 @@ tab-options-disable-signing-desc = { "[" }DEV ONLY] Disables verification of eng tab-options-hub-settings = Hub Settings tab-options-hub-settings-desc = Change what hub server or servers you would like to use to fetch the server list. tab-options-desc-incompatible = This option is incompatible with your platform and has been disabled. - +tab-options-desc-proxy-address = Proxy information for connecting to the server hub and authentication services. Supports http, https and socks5 proxies (requires launcher restart) +tab-options-desc-proxy-enable = Enable Proxy +tab-options-desc-proxy-tooltip = Supports http, https, and socks5 proxies. For socks5, replace https:// with socks5:// ## For the language selection menu. # Text on the button that opens the menu. diff --git a/SS14.Launcher/HappyEyeballsHttp.cs b/SS14.Launcher/HappyEyeballsHttp.cs index bf594ba4e..7c5958568 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,24 @@ 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('"')); + Uri proxyURI; + if (Uri.TryCreate(proxyUrl,uriKind: 0, out proxyURI)){ //Catches malformed URI, in the event of a malformed URI, the launcher will boot but will be unable to retrive servers. + WebProxy clientProxy = new WebProxy(proxyUrl.Trim('"')); //No clue why .trim('"') is required. C# jank? Doesn't work otherwise. + clientProxy.BypassProxyOnLocal = true; + 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..e164e763d 100644 --- a/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml +++ b/SS14.Launcher/Views/MainWindowTabs/OptionsTabView.xaml @@ -65,7 +65,13 @@ - + + + + +