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
This commit is contained in:
JustArchi 2017-01-22 20:10:28 +01:00
parent 79913e1e11
commit 21fa824b60
7 changed files with 42 additions and 44 deletions

View file

@ -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<bool> 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<bool> Init(ulong steamID, EUniverse universe, string webAPIUserNonce, string parentalPin) {
if ((steamID == 0) || (universe == EUniverse.Invalid) || string.IsNullOrEmpty(webAPIUserNonce) || string.IsNullOrEmpty(parentalPin)) {

View file

@ -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);
}

View file

@ -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<uint> Blacklist = new HashSet<uint>(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;
}

View file

@ -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
);

View file

@ -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

View file

@ -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,

View file

@ -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<uint> Blacklist { get; set; } = new List<uint>(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;
}