From cd8c9cf80e57311b33b6d4da5724ef106dc3939a Mon Sep 17 00:00:00 2001 From: Archi Date: Sat, 3 Jun 2023 17:50:50 +0200 Subject: [PATCH] Closes #2908 --- .../RemoteCommunication.cs | 16 ++++++++++++ .../Steam/Integration/ArchiHandler.cs | 25 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs index d173ae642..6f64a431b 100644 --- a/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs +++ b/ArchiSteamFarm.OfficialPlugins.ItemsMatcher/RemoteCommunication.cs @@ -56,6 +56,7 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { private const byte MinAnnouncementTTL = 5; // Minimum amount of minutes we must wait before the next Announcement private const byte MinHeartBeatTTL = 10; // Minimum amount of minutes we must wait before sending next HeartBeat private const byte MinimumSteamGuardEnabledDays = 15; // As imposed by Steam limits + private const byte MinimumPasswordResetCooldownDays = 5; // As imposed by Steam limits private const byte MinPersonaStateTTL = 5; // Minimum amount of minutes we must wait before requesting persona state update private static readonly ImmutableHashSet AcceptedMatchableTypes = ImmutableHashSet.Create( @@ -561,6 +562,21 @@ internal sealed class RemoteCommunication : IAsyncDisposable, IDisposable { return false; } + CCredentials_LastCredentialChangeTime_Response? lastCredentialChangeTime = await Bot.ArchiHandler.GetLastCredentialChangeTime().ConfigureAwait(false); + + if (lastCredentialChangeTime == null) { + Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(lastCredentialChangeTime)}: null")); + + return null; + } + + // Bot didn't change password in last 5 days + if ((lastCredentialChangeTime.timestamp_last_password_reset > 0) && ((DateTimeOffset.UtcNow - DateTimeOffset.FromUnixTimeSeconds(lastCredentialChangeTime.timestamp_last_password_reset)).TotalDays < MinimumPasswordResetCooldownDays)) { + Bot.ArchiLogger.LogGenericTrace(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, $"{nameof(lastCredentialChangeTime.timestamp_last_password_reset)}: {lastCredentialChangeTime.timestamp_last_password_reset}")); + + return false; + } + // Bot must have valid API key (e.g. not being restricted account) bool? hasValidApiKey = await Bot.ArchiWebHandler.HasValidApiKey().ConfigureAwait(false); diff --git a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs index 297836eb1..d75a628ff 100644 --- a/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs +++ b/ArchiSteamFarm/Steam/Integration/ArchiHandler.cs @@ -91,6 +91,31 @@ public sealed class ArchiHandler : ClientMsgHandler { return response.Result == EResult.OK; } + [PublicAPI] + public async Task GetLastCredentialChangeTime() { + if (Client == null) { + throw new InvalidOperationException(nameof(Client)); + } + + if (!Client.IsConnected) { + return null; + } + + CCredentials_LastCredentialChangeTime_Request request = new(); + + SteamUnifiedMessages.ServiceMethodResponse response; + + try { + response = await UnifiedCredentialsService.SendMessage(x => x.GetCredentialChangeTimeDetails(request)).ToLongRunningTask().ConfigureAwait(false); + } catch (Exception e) { + ArchiLogger.LogGenericWarningException(e); + + return null; + } + + return response.Result == EResult.OK ? response.GetDeserializedResponse() : null; + } + [PublicAPI] public async Task?> GetOwnedGames(ulong steamID) { if ((steamID == 0) || !new SteamID(steamID).IsIndividualAccount) {