From 0673b2e2985de1e498a118dd9ac8379dabf13d6a Mon Sep 17 00:00:00 2001 From: Archi Date: Thu, 18 Nov 2021 23:44:49 +0100 Subject: [PATCH] Closes #2420 --- ArchiSteamFarm/Core/ASF.cs | 15 ++------ .../Interfaces/ICustomMachineInfoProvider.cs | 35 +++++++++++++++++++ ArchiSteamFarm/Plugins/PluginsCore.cs | 18 ++++++++++ ArchiSteamFarm/Steam/Bot.cs | 19 ++++++++-- 4 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 ArchiSteamFarm/Plugins/Interfaces/ICustomMachineInfoProvider.cs diff --git a/ArchiSteamFarm/Core/ASF.cs b/ArchiSteamFarm/Core/ASF.cs index 4d7005ca7..631bfc5e4 100644 --- a/ArchiSteamFarm/Core/ASF.cs +++ b/ArchiSteamFarm/Core/ASF.cs @@ -120,8 +120,9 @@ public static class ASF { await InitRateLimiters().ConfigureAwait(false); StringComparer botsComparer = await PluginsCore.GetBotsComparer().ConfigureAwait(false); + IMachineInfoProvider? customMachineInfoProvider = await PluginsCore.GetCustomMachineInfoProvider().ConfigureAwait(false); - InitBotsComparer(botsComparer); + Bot.Init(botsComparer, customMachineInfoProvider); if (!Program.Service && !GlobalConfig.Headless && !Console.IsInputRedirected) { Logging.StartInteractiveConsole(); @@ -364,18 +365,6 @@ public static class ASF { return LastWriteEvents.TryGetValue(filePath, out object? savedWriteEvent) && (currentWriteEvent == savedWriteEvent) && LastWriteEvents.TryRemove(filePath, out _); } - private static void InitBotsComparer(StringComparer botsComparer) { - if (botsComparer == null) { - throw new ArgumentNullException(nameof(botsComparer)); - } - - if (Bot.Bots != null) { - return; - } - - Bot.Init(botsComparer); - } - private static void InitConfigWatchEvents() { if ((FileSystemWatcher != null) || (LastWriteEvents != null)) { return; diff --git a/ArchiSteamFarm/Plugins/Interfaces/ICustomMachineInfoProvider.cs b/ArchiSteamFarm/Plugins/Interfaces/ICustomMachineInfoProvider.cs new file mode 100644 index 000000000..e3a7f24da --- /dev/null +++ b/ArchiSteamFarm/Plugins/Interfaces/ICustomMachineInfoProvider.cs @@ -0,0 +1,35 @@ +// _ _ _ ____ _ _____ +// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ +// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ +// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | +// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| +// | +// Copyright 2015-2021 Ɓukasz "JustArchi" Domeradzki +// Contact: JustArchi@JustArchi.net +// | +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// | +// http://www.apache.org/licenses/LICENSE-2.0 +// | +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using JetBrains.Annotations; +using SteamKit2; + +namespace ArchiSteamFarm.Plugins.Interfaces; + +[PublicAPI] +public interface ICustomMachineInfoProvider : IPlugin { + /// + /// ASF will use this property as the for the bots. + /// Unless you know what you're doing, you should not implement this property yourself and let ASF decide. + /// + /// that will be used for the bots. + IMachineInfoProvider MachineInfoProvider { get; } +} diff --git a/ArchiSteamFarm/Plugins/PluginsCore.cs b/ArchiSteamFarm/Plugins/PluginsCore.cs index d8e4213d4..f27eab557 100644 --- a/ArchiSteamFarm/Plugins/PluginsCore.cs +++ b/ArchiSteamFarm/Plugins/PluginsCore.cs @@ -117,6 +117,24 @@ internal static class PluginsCore { return responses.FirstOrDefault(static response => response != null) ?? new CrossProcessFileBasedSemaphore(resourceName); } + internal static async Task GetCustomMachineInfoProvider() { + if (ActivePlugins == null) { + return null; + } + + IList results; + + try { + results = await Utilities.InParallel(ActivePlugins.OfType().Select(static plugin => Task.Run(() => plugin.MachineInfoProvider))).ConfigureAwait(false); + } catch (Exception e) { + ASF.ArchiLogger.LogGenericException(e); + + return null; + } + + return results.FirstOrDefault(); + } + internal static bool InitPlugins() { if (ActivePlugins != null) { return false; diff --git a/ArchiSteamFarm/Steam/Bot.cs b/ArchiSteamFarm/Steam/Bot.cs index c976a13a0..7d093f7cc 100644 --- a/ArchiSteamFarm/Steam/Bot.cs +++ b/ArchiSteamFarm/Steam/Bot.cs @@ -79,6 +79,8 @@ public sealed class Bot : IAsyncDisposable { private static readonly SemaphoreSlim BotsSemaphore = new(1, 1); + private static IMachineInfoProvider? CustomMachineInfoProvider; + [JsonIgnore] [PublicAPI] public Actions Actions { get; } @@ -279,7 +281,18 @@ public sealed class Bot : IAsyncDisposable { ArchiWebHandler = new ArchiWebHandler(this); - SteamConfiguration = SteamConfiguration.Create(builder => builder.WithProtocolTypes(ASF.GlobalConfig.SteamProtocols).WithCellID(ASF.GlobalDatabase.CellID).WithServerListProvider(ASF.GlobalDatabase.ServerListProvider).WithHttpClientFactory(ArchiWebHandler.GenerateDisposableHttpClient)); + SteamConfiguration = SteamConfiguration.Create( + builder => { + builder.WithCellID(ASF.GlobalDatabase.CellID); + builder.WithHttpClientFactory(ArchiWebHandler.GenerateDisposableHttpClient); + builder.WithProtocolTypes(ASF.GlobalConfig.SteamProtocols); + builder.WithServerListProvider(ASF.GlobalDatabase.ServerListProvider); + + if (CustomMachineInfoProvider != null) { + builder.WithMachineInfoProvider(CustomMachineInfoProvider); + } + } + ); // Initialize SteamClient = new SteamClient(SteamConfiguration, botName); @@ -1333,12 +1346,14 @@ public sealed class Bot : IAsyncDisposable { } } - internal static void Init(StringComparer botsComparer) { + internal static void Init(StringComparer botsComparer, IMachineInfoProvider? customMachineInfoProvider = null) { if (Bots != null) { throw new InvalidOperationException(nameof(Bots)); } BotsComparer = botsComparer ?? throw new ArgumentNullException(nameof(botsComparer)); + + CustomMachineInfoProvider = customMachineInfoProvider; Bots = new ConcurrentDictionary(botsComparer); }