diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs index ae8cb1c37..0cfe7f7e5 100644 --- a/ArchiSteamFarm/ArchiWebHandler.cs +++ b/ArchiSteamFarm/ArchiWebHandler.cs @@ -76,7 +76,7 @@ namespace ArchiSteamFarm { internal ArchiWebHandler(Bot bot) { Bot = bot ?? throw new ArgumentNullException(nameof(bot)); - WebBrowser = new WebBrowser(bot.ArchiLogger); + WebBrowser = new WebBrowser(bot.ArchiLogger, Program.GlobalConfig.WebProxy); } public void Dispose() { diff --git a/ArchiSteamFarm/GlobalConfig.cs b/ArchiSteamFarm/GlobalConfig.cs index 144f80711..8075bfe8c 100644 --- a/ArchiSteamFarm/GlobalConfig.cs +++ b/ArchiSteamFarm/GlobalConfig.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Net; using System.Threading; using System.Threading.Tasks; using ArchiSteamFarm.Localization; @@ -120,6 +121,81 @@ namespace ArchiSteamFarm { [JsonProperty(Required = Required.DisallowNull)] internal ProtocolTypes SteamProtocols { get; private set; } = DefaultSteamProtocols; + internal WebProxy WebProxy { get; private set; } + + [JsonProperty] + internal string WebProxyPassword { + get => WebProxyCredentials.Password; + set { + if (string.IsNullOrEmpty(value)) { + if (WebProxyCredentials == null) { + return; + } + + WebProxyCredentials.Password = null; + + if (!string.IsNullOrEmpty(WebProxyCredentials.UserName)) { + return; + } + + WebProxyCredentials = null; + if (WebProxy != null) { + WebProxy.Credentials = null; + } + + return; + } + + if (WebProxyCredentials == null) { + WebProxyCredentials = new NetworkCredential(); + } + + WebProxyCredentials.Password = value; + + if ((WebProxy != null) && (WebProxy.Credentials != WebProxyCredentials)) { + WebProxy.Credentials = WebProxyCredentials; + } + } + } + + [JsonProperty] + internal string WebProxyUsername { + get => WebProxyCredentials.UserName; + set { + if (string.IsNullOrEmpty(value)) { + if (WebProxyCredentials == null) { + return; + } + + WebProxyCredentials.UserName = null; + + if (!string.IsNullOrEmpty(WebProxyCredentials.Password)) { + return; + } + + WebProxyCredentials = null; + if (WebProxy != null) { + WebProxy.Credentials = null; + } + + return; + } + + if (WebProxyCredentials == null) { + WebProxyCredentials = new NetworkCredential(); + } + + WebProxyCredentials.UserName = value; + + if ((WebProxy != null) && (WebProxy.Credentials != WebProxyCredentials)) { + WebProxy.Credentials = WebProxyCredentials; + } + } + } + + private bool ShouldSerializeSensitiveDetails = true; + private NetworkCredential WebProxyCredentials; + [JsonProperty(PropertyName = SharedInfo.UlongCompatibilityStringPrefix + nameof(SteamOwnerID), Required = Required.DisallowNull)] private string SSteamOwnerID { get => SteamOwnerID.ToString(); @@ -133,6 +209,43 @@ namespace ArchiSteamFarm { } } + [JsonProperty(PropertyName = nameof(WebProxy))] + private string WebProxyText { + get => WebProxy?.Address.OriginalString; + set { + if (string.IsNullOrEmpty(value)) { + if (WebProxy != null) { + WebProxy = null; + } + + return; + } + + Uri uri; + + try { + uri = new Uri(value); + } catch (UriFormatException e) { + ASF.ArchiLogger.LogGenericException(e); + return; + } + + if (WebProxy == null) { + WebProxy = new WebProxy { BypassProxyOnLocal = true }; + } + + WebProxy.Address = uri; + + if ((WebProxyCredentials != null) && (WebProxy.Credentials != WebProxyCredentials)) { + WebProxy.Credentials = WebProxyCredentials; + } + } + } + + public bool ShouldSerializeWebProxyPassword() => ShouldSerializeSensitiveDetails; + + public bool ShouldSerializeWebProxyUsername() => ShouldSerializeSensitiveDetails; + internal static GlobalConfig Load(string filePath) { if (string.IsNullOrEmpty(filePath)) { ASF.ArchiLogger.LogNullError(nameof(filePath)); diff --git a/ArchiSteamFarm/IPC.cs b/ArchiSteamFarm/IPC.cs index 43e60bd13..536a6eb72 100644 --- a/ArchiSteamFarm/IPC.cs +++ b/ArchiSteamFarm/IPC.cs @@ -273,6 +273,16 @@ namespace ArchiSteamFarm { return true; } + if (jsonRequest.KeepSensitiveDetails) { + if (string.IsNullOrEmpty(jsonRequest.GlobalConfig.WebProxyPassword) && !string.IsNullOrEmpty(Program.GlobalConfig.WebProxyPassword)) { + jsonRequest.GlobalConfig.WebProxyPassword = Program.GlobalConfig.WebProxyPassword; + } + + if (string.IsNullOrEmpty(jsonRequest.GlobalConfig.WebProxyUsername) && !string.IsNullOrEmpty(Program.GlobalConfig.WebProxyUsername)) { + jsonRequest.GlobalConfig.WebProxyUsername = Program.GlobalConfig.WebProxyUsername; + } + } + string filePath = Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName); if (!await GlobalConfig.Write(filePath, jsonRequest.GlobalConfig).ConfigureAwait(false)) { @@ -412,15 +422,15 @@ namespace ArchiSteamFarm { string botName = WebUtility.UrlDecode(arguments[argumentsIndex]); if (jsonRequest.KeepSensitiveDetails && Bot.Bots.TryGetValue(botName, out Bot bot)) { - if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamLogin)) { + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamLogin) && !string.IsNullOrEmpty(bot.BotConfig.SteamLogin)) { jsonRequest.BotConfig.SteamLogin = bot.BotConfig.SteamLogin; } - if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamParentalPIN)) { + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamParentalPIN) && !string.IsNullOrEmpty(bot.BotConfig.SteamParentalPIN)) { jsonRequest.BotConfig.SteamParentalPIN = bot.BotConfig.SteamParentalPIN; } - if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamPassword)) { + if (string.IsNullOrEmpty(jsonRequest.BotConfig.SteamPassword) && !string.IsNullOrEmpty(bot.BotConfig.SteamPassword)) { jsonRequest.BotConfig.SteamPassword = bot.BotConfig.SteamPassword; } } @@ -1172,6 +1182,9 @@ namespace ArchiSteamFarm { internal readonly GlobalConfig GlobalConfig; #pragma warning restore 649 + [JsonProperty(Required = Required.DisallowNull)] + internal readonly bool KeepSensitiveDetails = true; + // Deserialized from JSON private ASFRequest() { } } diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs index 285da8491..5b98d0984 100644 --- a/ArchiSteamFarm/Program.cs +++ b/ArchiSteamFarm/Program.cs @@ -346,7 +346,7 @@ namespace ArchiSteamFarm { } WebBrowser.Init(); - WebBrowser = new WebBrowser(ASF.ArchiLogger, true); + WebBrowser = new WebBrowser(ASF.ArchiLogger, GlobalConfig.WebProxy, true); if (GlobalConfig.IPC && (GlobalConfig.IPCPrefixes.Count > 0)) { IPC.Start(GlobalConfig.IPCPrefixes); diff --git a/ArchiSteamFarm/WebBrowser.cs b/ArchiSteamFarm/WebBrowser.cs index 59131c0c7..d9a52541c 100644 --- a/ArchiSteamFarm/WebBrowser.cs +++ b/ArchiSteamFarm/WebBrowser.cs @@ -45,7 +45,7 @@ namespace ArchiSteamFarm { private readonly ArchiLogger ArchiLogger; private readonly HttpClient HttpClient; - internal WebBrowser(ArchiLogger archiLogger, bool extendedTimeout = false) { + internal WebBrowser(ArchiLogger archiLogger, IWebProxy webProxy = null, bool extendedTimeout = false) { ArchiLogger = archiLogger ?? throw new ArgumentNullException(nameof(archiLogger)); HttpClientHandler httpClientHandler = new HttpClientHandler { @@ -53,7 +53,8 @@ namespace ArchiSteamFarm { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, CookieContainer = CookieContainer, MaxConnectionsPerServer = MaxConnections, - UseProxy = false + Proxy = webProxy, + UseProxy = webProxy != null }; HttpClient = new HttpClient(httpClientHandler) { Timeout = TimeSpan.FromSeconds(extendedTimeout ? ExtendedTimeoutMultiplier * Program.GlobalConfig.ConnectionTimeout : Program.GlobalConfig.ConnectionTimeout) }; diff --git a/ArchiSteamFarm/config/ASF.json b/ArchiSteamFarm/config/ASF.json index 50df6800a..a06da3c1b 100644 --- a/ArchiSteamFarm/config/ASF.json +++ b/ArchiSteamFarm/config/ASF.json @@ -26,5 +26,8 @@ "SteamProtocols": 3, "UpdateChannel": 1, "UpdatePeriod": 24, - "WebLimiterDelay": 200 + "WebLimiterDelay": 200, + "WebProxy": null, + "WebProxyPassword": null, + "WebProxyUsername": null } \ No newline at end of file