diff --git a/ArchiSteamFarm.sln.DotSettings b/ArchiSteamFarm.sln.DotSettings
index 687003933..d027f800b 100644
--- a/ArchiSteamFarm.sln.DotSettings
+++ b/ArchiSteamFarm.sln.DotSettings
@@ -12,6 +12,7 @@
False
False
False
+ LINE_BREAK
True
END_OF_LINE
255
diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs
index 7ef23782c..054f55c5d 100755
--- a/ArchiSteamFarm/Bot.cs
+++ b/ArchiSteamFarm/Bot.cs
@@ -41,6 +41,7 @@ using SteamKit2.Discovery;
namespace ArchiSteamFarm {
internal sealed class Bot : IDisposable {
private const ushort CallbackSleep = 500; // In miliseconds
+ private const byte FamilySharingInactivityMinutes = 5;
private const uint LoginID = 0; // This must be the same for all ASF bots and all ASF processes
private const ushort MaxSteamMessageLength = 2048;
@@ -81,6 +82,7 @@ namespace ArchiSteamFarm {
private bool FirstTradeSent, LibraryLocked, PlayingBlocked, SkipFirstShutdown;
private string AuthCode, TwoFactorCode;
private EResult LastLogOnResult;
+ private Timer FamilySharingInactivityTimer;
internal static string GetAPIStatus() {
var response = new {
@@ -286,6 +288,7 @@ namespace ArchiSteamFarm {
// Those are objects that might be null and the check should be in-place
AcceptConfirmationsTimer?.Dispose();
+ FamilySharingInactivityTimer?.Dispose();
SendItemsTimer?.Dispose();
}
@@ -589,6 +592,7 @@ namespace ArchiSteamFarm {
private void CheckOccupationStatus() {
if (!IsFarmingPossible) {
Logging.LogGenericInfo("Account is currently being used, ASF will resume farming when it's free...", BotName);
+ StopFamilySharingInactivityTimer();
return;
}
@@ -596,6 +600,38 @@ namespace ArchiSteamFarm {
CardsFarmer.Resume();
}
+ private void CheckFamilySharingInactivity() {
+ if (!IsFarmingPossible) {
+ return;
+ }
+
+ Logging.LogGenericInfo("Shared library has not been launched in given time period, farming process resumed!", BotName);
+ CardsFarmer.Resume();
+ }
+
+ private void StartFamilySharingInactivityTimer() {
+ if (FamilySharingInactivityTimer != null) {
+ return;
+ }
+
+ FamilySharingInactivityTimer = new Timer(
+ e => CheckFamilySharingInactivity(),
+ null,
+ TimeSpan.FromMinutes(FamilySharingInactivityMinutes), // Delay
+ Timeout.InfiniteTimeSpan // Period
+ );
+ }
+
+ private void StopFamilySharingInactivityTimer() {
+ if (FamilySharingInactivityTimer == null) {
+ return;
+ }
+
+ FamilySharingInactivityTimer.Change(Timeout.Infinite, Timeout.Infinite);
+ FamilySharingInactivityTimer.Dispose();
+ FamilySharingInactivityTimer = null;
+ }
+
private async Task InitializeFamilySharing() {
HashSet steamIDs = await ArchiWebHandler.GetFamilySharingSteamIDs().ConfigureAwait(false);
if (steamIDs == null || steamIDs.Count == 0) {
@@ -699,13 +735,20 @@ namespace ArchiSteamFarm {
}
await CardsFarmer.Pause().ConfigureAwait(false);
- return "Automatic farming is now paused!";
+
+ if (!SteamFamilySharingIDs.Contains(steamID)) {
+ return "Automatic farming is now paused!";
+ }
+
+ StartFamilySharingInactivityTimer();
+ return "Automatic farming is now paused! You have " + FamilySharingInactivityMinutes + " minutes to start a game.";
}
if (!CardsFarmer.Paused) {
return "Automatic farming is resumed already!";
}
+ StopFamilySharingInactivityTimer();
CardsFarmer.Resume();
return "Automatic farming is now resumed!";
}
@@ -1975,7 +2018,7 @@ namespace ArchiSteamFarm {
case EResult.OK:
Logging.LogGenericInfo("Successfully logged on!", BotName);
- PlayingBlocked = false; // If playing is really blocked, we'll be notified in a callback, old status doesn't matter
+ LibraryLocked = PlayingBlocked = false; // Old status for these doesn't matter, we'll be notified in callback if needed
if ((callback.CellID != 0) && (Program.GlobalDatabase.CellID != callback.CellID)) {
Program.GlobalDatabase.CellID = callback.CellID;