From 21fa824b602dacec5295f982d67763a8fae9b525 Mon Sep 17 00:00:00 2001 From: JustArchi Date: Sun, 22 Jan 2017 20:10:28 +0100 Subject: [PATCH] HttpTimeout -> ConnectionTimeout Since HttpTimeout started affecting WCF timeout as well, and now I'm about to add yet another responsibility to this, this should be renamed to ConnectionTimeout. Basically new HeartBeats() are cool, but user should have a direct way to configure the number of failed attempts allowed, as it can differ between stable and unstable networks, same like HttpTimeout. This change apart from renaming HttpTimeout makes HeartBeats depend on it, allowing ConnectionTimeout / 10 failed attempts, and giving ConnectionTimeout / 30 minutes for steam servers to respond to out connection attempt. Both divisions are rounded up. This should allow people with less unstable networks to get less clients being abandoned due to steam instability --- ArchiSteamFarm/ArchiWebHandler.cs | 6 ++-- ArchiSteamFarm/Bot.cs | 7 ++-- ArchiSteamFarm/GlobalConfig.cs | 12 +++---- ArchiSteamFarm/WCF.cs | 4 +-- ArchiSteamFarm/WebBrowser.cs | 2 +- ArchiSteamFarm/config/ASF.json | 2 +- ConfigGenerator/GlobalConfig.cs | 53 +++++++++++++++---------------- 7 files changed, 42 insertions(+), 44 deletions(-) diff --git a/ArchiSteamFarm/ArchiWebHandler.cs b/ArchiSteamFarm/ArchiWebHandler.cs index 0925d0ed7..33cb85ec6 100644 --- a/ArchiSteamFarm/ArchiWebHandler.cs +++ b/ArchiSteamFarm/ArchiWebHandler.cs @@ -45,7 +45,7 @@ namespace ArchiSteamFarm { private const string ISteamUserAuth = "ISteamUserAuth"; private const string ITwoFactorService = "ITwoFactorService"; - private const byte MinSessionTTL = GlobalConfig.DefaultHttpTimeout / 4; // Assume session is valid for at least that amount of seconds + private const byte MinSessionTTL = GlobalConfig.DefaultConnectionTimeout / 4; // Assume session is valid for at least that amount of seconds // We must use HTTPS for SteamCommunity, as http would make certain POST requests failing (trades) private const string SteamCommunityHost = "steamcommunity.com"; @@ -55,7 +55,7 @@ namespace ArchiSteamFarm { private const string SteamStoreHost = "store.steampowered.com"; private const string SteamStoreURL = "http://" + SteamStoreHost; - private static int Timeout = GlobalConfig.DefaultHttpTimeout * 1000; // This must be int type + private static int Timeout = GlobalConfig.DefaultConnectionTimeout * 1000; // This must be int type private readonly Bot Bot; private readonly SemaphoreSlim SessionSemaphore = new SemaphoreSlim(1); @@ -786,7 +786,7 @@ namespace ArchiSteamFarm { internal async Task HasValidApiKey() => !string.IsNullOrEmpty(await GetApiKey().ConfigureAwait(false)); - internal static void Init() => Timeout = Program.GlobalConfig.HttpTimeout * 1000; + internal static void Init() => Timeout = Program.GlobalConfig.ConnectionTimeout * 1000; internal async Task Init(ulong steamID, EUniverse universe, string webAPIUserNonce, string parentalPin) { if ((steamID == 0) || (universe == EUniverse.Invalid) || string.IsNullOrEmpty(webAPIUserNonce) || string.IsNullOrEmpty(parentalPin)) { diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index bd978a85d..b6cebcdf7 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -46,7 +46,6 @@ namespace ArchiSteamFarm { private const byte FamilySharingInactivityMinutes = 5; private const byte LoginCooldownInMinutes = 25; // Captcha disappears after around 20 minutes, so we make it 25 private const uint LoginID = GlobalConfig.DefaultWCFPort; // This must be the same for all ASF bots and all ASF processes - private const byte MaxHeartBeatFailures = 5; // Effectively number of minutes we allow Steam client to be down private const ushort MaxSteamMessageLength = 2048; private const byte MaxTwoFactorCodeFailures = 3; @@ -765,7 +764,7 @@ namespace ArchiSteamFarm { return; } - if (++HeartBeatFailures > MaxHeartBeatFailures) { + if (++HeartBeatFailures > (byte) Math.Ceiling(Program.GlobalConfig.ConnectionTimeout / 10.0)) { HeartBeatFailures = byte.MaxValue; ArchiLogger.LogGenericWarning(Strings.BotConnectionLost); Connect(true).Forget(); @@ -818,7 +817,7 @@ namespace ArchiSteamFarm { ConnectionFailureTimer = new Timer( e => InitPermanentConnectionFailure(), null, - TimeSpan.FromMinutes(2), // Delay + TimeSpan.FromMinutes(Math.Ceiling(Program.GlobalConfig.ConnectionTimeout / 30.0)), // Delay Timeout.InfiniteTimeSpan // Period ); } @@ -1234,7 +1233,7 @@ namespace ArchiSteamFarm { await Task.Delay(1000).ConfigureAwait(false); // Wait a second for eventual PlayingSessionStateCallback or SharedLibraryLockStatusCallback if (!ArchiWebHandler.Ready) { - for (byte i = 0; (i < Program.GlobalConfig.HttpTimeout) && !ArchiWebHandler.Ready; i++) { + for (byte i = 0; (i < Program.GlobalConfig.ConnectionTimeout) && !ArchiWebHandler.Ready; i++) { await Task.Delay(1000).ConfigureAwait(false); } diff --git a/ArchiSteamFarm/GlobalConfig.cs b/ArchiSteamFarm/GlobalConfig.cs index 015ce330e..d3365fa2a 100644 --- a/ArchiSteamFarm/GlobalConfig.cs +++ b/ArchiSteamFarm/GlobalConfig.cs @@ -35,7 +35,7 @@ namespace ArchiSteamFarm { [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")] [SuppressMessage("ReSharper", "ConvertToConstant.Global")] internal sealed class GlobalConfig { - internal const byte DefaultHttpTimeout = 60; + internal const byte DefaultConnectionTimeout = 60; internal const ushort DefaultWCFPort = 1242; private const byte DefaultFarmingDelay = 15; @@ -54,6 +54,9 @@ namespace ArchiSteamFarm { [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)] internal readonly HashSet Blacklist = new HashSet(GlobalBlacklist); + [JsonProperty(Required = Required.DisallowNull)] + internal readonly byte ConnectionTimeout = DefaultConnectionTimeout; + [JsonProperty] internal readonly string CurrentCulture = null; @@ -69,9 +72,6 @@ namespace ArchiSteamFarm { [JsonProperty(Required = Required.DisallowNull)] internal readonly bool Headless = false; - [JsonProperty(Required = Required.DisallowNull)] - internal readonly byte HttpTimeout = DefaultHttpTimeout; - [JsonProperty(Required = Required.DisallowNull)] internal readonly byte IdleFarmingPeriod = 3; @@ -155,8 +155,8 @@ namespace ArchiSteamFarm { return null; } - if (globalConfig.HttpTimeout == 0) { - Program.ArchiLogger.LogGenericError(string.Format(Strings.ErrorConfigPropertyInvalid, nameof(globalConfig.HttpTimeout), globalConfig.HttpTimeout)); + if (globalConfig.ConnectionTimeout == 0) { + Program.ArchiLogger.LogGenericError(string.Format(Strings.ErrorConfigPropertyInvalid, nameof(globalConfig.ConnectionTimeout), globalConfig.ConnectionTimeout)); return null; } diff --git a/ArchiSteamFarm/WCF.cs b/ArchiSteamFarm/WCF.cs index c2363f7ca..8d9270a39 100644 --- a/ArchiSteamFarm/WCF.cs +++ b/ArchiSteamFarm/WCF.cs @@ -103,7 +103,7 @@ namespace ArchiSteamFarm { // We use SecurityMode.None for Mono compatibility // Yes, also on Windows, for Mono<->Windows communication Security = { Mode = SecurityMode.None }, - SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.HttpTimeout) + SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.ConnectionTimeout) }, new EndpointAddress(URL) ); @@ -127,7 +127,7 @@ namespace ArchiSteamFarm { // We use SecurityMode.None for Mono compatibility // Yes, also on Windows, for Mono<->Windows communication Security = { Mode = SecurityMode.None }, - SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.HttpTimeout) + SendTimeout = new TimeSpan(0, 0, Program.GlobalConfig.ConnectionTimeout) }, string.Empty ); diff --git a/ArchiSteamFarm/WebBrowser.cs b/ArchiSteamFarm/WebBrowser.cs index 5660b0b86..e31efb7bf 100644 --- a/ArchiSteamFarm/WebBrowser.cs +++ b/ArchiSteamFarm/WebBrowser.cs @@ -58,7 +58,7 @@ namespace ArchiSteamFarm { }; HttpClient = new HttpClient(httpClientHandler) { - Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.HttpTimeout) + Timeout = TimeSpan.FromSeconds(Program.GlobalConfig.ConnectionTimeout) }; // Most web services expect that UserAgent is set, so we declare it globally diff --git a/ArchiSteamFarm/config/ASF.json b/ArchiSteamFarm/config/ASF.json index ee2fb77c4..878d95966 100644 --- a/ArchiSteamFarm/config/ASF.json +++ b/ArchiSteamFarm/config/ASF.json @@ -10,12 +10,12 @@ 480730, 566020 ], + "ConnectionTimeout": 60, "CurrentCulture": null, "Debug": false, "FarmingDelay": 15, "GiftsLimiterDelay": 1, "Headless": false, - "HttpTimeout": 60, "IdleFarmingPeriod": 3, "InventoryLimiterDelay": 3, "LoginLimiterDelay": 10, diff --git a/ConfigGenerator/GlobalConfig.cs b/ConfigGenerator/GlobalConfig.cs index 7b8f8f7be..9f72e3785 100644 --- a/ConfigGenerator/GlobalConfig.cs +++ b/ConfigGenerator/GlobalConfig.cs @@ -36,8 +36,8 @@ namespace ConfigGenerator { [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] [SuppressMessage("ReSharper", "UnusedMember.Global")] internal sealed class GlobalConfig : ASFConfig { + private const byte DefaultConnectionTimeout = 60; private const byte DefaultFarmingDelay = 15; - private const byte DefaultHttpTimeout = 60; private const byte DefaultMaxFarmingTime = 10; private const ProtocolType DefaultSteamProtocol = ProtocolType.Tcp; private const ushort DefaultWCFPort = 1242; @@ -56,6 +56,10 @@ namespace ConfigGenerator { [JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace, Required = Required.DisallowNull)] public List Blacklist { get; set; } = new List(GlobalBlacklist); + [LocalizedCategory("Debugging")] + [JsonProperty(Required = Required.DisallowNull)] + public byte ConnectionTimeout { get; set; } = DefaultConnectionTimeout; + [JsonProperty] public string CurrentCulture { get; set; } = null; @@ -75,10 +79,6 @@ namespace ConfigGenerator { [JsonProperty(Required = Required.DisallowNull)] public bool Headless { get; set; } = false; - [LocalizedCategory("Debugging")] - [JsonProperty(Required = Required.DisallowNull)] - public byte HttpTimeout { get; set; } = DefaultHttpTimeout; - [LocalizedCategory("Performance")] [JsonProperty(Required = Required.DisallowNull)] public byte IdleFarmingPeriod { get; set; } = 3; @@ -163,6 +163,27 @@ namespace ConfigGenerator { internal override void ValidateAndFix() { base.ValidateAndFix(); + if (ConnectionTimeout == 0) { + Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(ConnectionTimeout), ConnectionTimeout)); + ConnectionTimeout = DefaultConnectionTimeout; + Save(); + Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(ConnectionTimeout), ConnectionTimeout)); + } + + if (FarmingDelay == 0) { + Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(FarmingDelay), FarmingDelay)); + FarmingDelay = DefaultFarmingDelay; + Save(); + Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(FarmingDelay), FarmingDelay)); + } + + if (MaxFarmingTime == 0) { + Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(MaxFarmingTime), MaxFarmingTime)); + MaxFarmingTime = DefaultMaxFarmingTime; + Save(); + Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(MaxFarmingTime), MaxFarmingTime)); + } + switch (SteamProtocol) { case ProtocolType.Tcp: case ProtocolType.Udp: @@ -175,28 +196,6 @@ namespace ConfigGenerator { break; } - if (MaxFarmingTime == 0) { - Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(MaxFarmingTime), MaxFarmingTime)); - MaxFarmingTime = DefaultMaxFarmingTime; - Save(); - Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(MaxFarmingTime), MaxFarmingTime)); - - } - - if (FarmingDelay == 0) { - Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(FarmingDelay), FarmingDelay)); - FarmingDelay = DefaultFarmingDelay; - Save(); - Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(FarmingDelay), FarmingDelay)); - } - - if (HttpTimeout == 0) { - Logging.LogGenericWarning(string.Format(CGStrings.ErrorConfigPropertyInvalid, nameof(HttpTimeout), HttpTimeout)); - HttpTimeout = DefaultHttpTimeout; - Save(); - Logging.LogGenericWarning(string.Format(CGStrings.WarningConfigPropertyModified, nameof(HttpTimeout), HttpTimeout)); - } - if (WCFPort != 0) { return; }