diff --git a/ArchiSteamFarm/Bot.cs b/ArchiSteamFarm/Bot.cs index 4b33b2f37..9adee1b82 100755 --- a/ArchiSteamFarm/Bot.cs +++ b/ArchiSteamFarm/Bot.cs @@ -1058,6 +1058,16 @@ namespace ArchiSteamFarm { await Core.OnBotInit(bot).ConfigureAwait(false); + HashSet customHandlers = await Core.OnBotSteamHandlersInit(bot).ConfigureAwait(false); + + if ((customHandlers != null) && (customHandlers.Count > 0)) { + foreach (ClientMsgHandler customHandler in customHandlers) { + bot.SteamClient.AddHandler(customHandler); + } + } + + await Core.OnBotSteamCallbacksInit(bot, bot.CallbackManager).ConfigureAwait(false); + await bot.InitModules().ConfigureAwait(false); bot.InitStart(); diff --git a/ArchiSteamFarm/Plugins/Core.cs b/ArchiSteamFarm/Plugins/Core.cs index 588a03281..163bb1d34 100644 --- a/ArchiSteamFarm/Plugins/Core.cs +++ b/ArchiSteamFarm/Plugins/Core.cs @@ -342,6 +342,48 @@ namespace ArchiSteamFarm.Plugins { return string.Join(Environment.NewLine, responses.Where(response => !string.IsNullOrEmpty(response))); } + internal static async Task OnBotSteamCallbacksInit(Bot bot, CallbackManager callbackManager) { + if ((bot == null) || (callbackManager == null)) { + ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(callbackManager)); + + return; + } + + if ((ActivePlugins == null) || (ActivePlugins.Count == 0)) { + return; + } + + try { + await Utilities.InParallel(ActivePlugins.OfType().Select(plugin => Task.Run(() => plugin.OnBotSteamCallbacksInit(bot, callbackManager)))).ConfigureAwait(false); + } catch (Exception e) { + ASF.ArchiLogger.LogGenericException(e); + } + } + + internal static async Task> OnBotSteamHandlersInit(Bot bot) { + if (bot == null) { + ASF.ArchiLogger.LogNullError(nameof(bot)); + + return null; + } + + if ((ActivePlugins == null) || (ActivePlugins.Count == 0)) { + return null; + } + + IList> responses; + + try { + responses = await Utilities.InParallel(ActivePlugins.OfType().Select(plugin => Task.Run(() => plugin.OnBotSteamHandlersInit(bot)))).ConfigureAwait(false); + } catch (Exception e) { + ASF.ArchiLogger.LogGenericException(e); + + return null; + } + + return responses.Where(response => response != null).SelectMany(handler => handler).Where(handler => handler != null).ToHashSet(); + } + internal static async Task OnBotTradeOffer(Bot bot, Steam.TradeOffer tradeOffer) { if ((bot == null) || (tradeOffer == null)) { ASF.ArchiLogger.LogNullError(nameof(bot) + " || " + nameof(tradeOffer)); diff --git a/ArchiSteamFarm/Plugins/IBotSteamClientHandlers.cs b/ArchiSteamFarm/Plugins/IBotSteamClientHandlers.cs new file mode 100644 index 000000000..3dab037ea --- /dev/null +++ b/ArchiSteamFarm/Plugins/IBotSteamClientHandlers.cs @@ -0,0 +1,44 @@ +// _ _ _ ____ _ _____ +// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ +// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ +// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | +// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| +// | +// Copyright 2015-2019 Ɓ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 System.Collections.Generic; +using JetBrains.Annotations; +using SteamKit2; + +namespace ArchiSteamFarm.Plugins { + [PublicAPI] + public interface IBotSteamClient : IPlugin { + /// + /// ASF will call this method right after custom SK2 client handler initialization in order to allow you listening for callbacks in your own code. + /// + /// Bot object related to this callback. + /// Callback manager object which can be used for establishing subscriptions to standard and custom callbacks. + void OnBotSteamCallbacksInit([NotNull] Bot bot, [NotNull] CallbackManager callbackManager); + + /// + /// ASF will call this method right after bot initialization in order to allow you hooking custom SK2 client handlers into the SteamClient. + /// + /// Bot object related to this callback. + /// Collection of custom client handlers that are supposed to be hooked into the SteamClient by ASF. If you do not require any, just return null. + [CanBeNull] + IReadOnlyCollection OnBotSteamHandlersInit([NotNull] Bot bot); + } +}