diff --git a/DisCatSharp.ApplicationCommands/ExtensionMethods.cs b/DisCatSharp.ApplicationCommands/ExtensionMethods.cs index 21156ec1e..7bb23a125 100644 --- a/DisCatSharp.ApplicationCommands/ExtensionMethods.cs +++ b/DisCatSharp.ApplicationCommands/ExtensionMethods.cs @@ -1,189 +1,214 @@ // This file is part of the DisCatSharp project, based off DSharpPlus. // // Copyright (c) 2021-2022 AITSYS // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + namespace DisCatSharp.ApplicationCommands; /// /// Defines various extension methods for application commands. /// public static class ExtensionMethods { /// /// Enables application commands on this . /// /// Client to enable application commands for. /// Configuration to use. /// Created . public static ApplicationCommandsExtension UseApplicationCommands(this DiscordClient client, ApplicationCommandsConfiguration config = null) { if (client.GetExtension() != null) throw new InvalidOperationException("Application commands are already enabled for that client."); var scomm = new ApplicationCommandsExtension(config); client.AddExtension(scomm); return scomm; } /// /// Gets the application commands module for this client. /// /// Client to get application commands for. /// The module, or null if not activated. public static ApplicationCommandsExtension GetApplicationCommands(this DiscordClient client) => client.GetExtension(); /// /// Gets the application commands from this . /// /// Client to get application commands from. /// A dictionary of current with the key being the shard id. public static async Task > GetApplicationCommandsAsync(this DiscordShardedClient client) { await client.InitializeShardsAsync().ConfigureAwait(false); var modules = new Dictionary(); foreach (var shard in client.ShardClients.Values) modules.Add(shard.ShardId, shard.GetExtension()); return modules; } /// /// Registers a command class with optional translation setup globally. /// /// Sharding extensions. /// The command class to register. /// A callback to setup translations with. public static void RegisterGlobalCommands(this IReadOnlyDictionary extensions, Action translationSetup = null) where T : ApplicationCommandsModule { foreach (var extension in extensions.Values) extension.RegisterGlobalCommands(translationSetup); } /// /// Registers a command class with optional translation setup globally. /// /// Sharding extensions. /// The of the command class to register. /// A callback to setup translations with. public static void RegisterGlobalCommands(this IReadOnlyDictionary extensions, Type type, Action translationSetup = null) { if (!typeof(ApplicationCommandsModule).IsAssignableFrom(type)) throw new ArgumentException("Command classes have to inherit from ApplicationCommandsModule", nameof(type)); foreach (var extension in extensions.Values) extension.RegisterGlobalCommands(type, translationSetup); } /// /// Registers a command class with optional translation setup for a guild. /// /// The command class to register. /// Sharding extensions. /// The guild id to register it on. /// A callback to setup translations with. public static void RegisterGuildCommands(this IReadOnlyDictionary extensions, ulong guildId, Action translationSetup = null) where T : ApplicationCommandsModule { foreach (var extension in extensions.Values) { + extension.Client.Logger.LogInformation("Request to register guild commands on shard {shard} for guild {guild}!", extension.Client.ShardId, guildId); if (extension.Client.Guilds.ContainsKey(guildId)) { - extension.RegisterGuildCommands(guildId, translationSetup); - break; + try + { + extension.Client.Logger.LogInformation("Found guild {guild} in shard {shard}!", guildId, extension.Client.ShardId); + extension.RegisterGuildCommands(guildId, translationSetup); + extension.Client.Logger.LogInformation("Registered"); + } + catch (Exception ex) + { + extension.Client.Logger.LogError(ex.Message); + extension.Client.Logger.LogError(ex.StackTrace); + } + return; } } } /// /// Registers a command class with optional translation setup for a guild. /// /// Sharding extensions. /// The of the command class to register. /// The guild id to register it on. /// A callback to setup translations with. public static void RegisterGuildCommands(this IReadOnlyDictionary extensions, Type type, ulong guildId, Action translationSetup = null) { if (!typeof(ApplicationCommandsModule).IsAssignableFrom(type)) throw new ArgumentException("Command classes have to inherit from ApplicationCommandsModule", nameof(type)); foreach (var extension in extensions.Values) { + extension.Client.Logger.LogInformation("Request to register guild commands on shard {shard} for guild {guild}!", extension.Client.ShardId, guildId); + if (extension.Client.Guilds.ContainsKey(guildId)) { - extension.RegisterGuildCommands(type, guildId, translationSetup); - break; + try + { + extension.Client.Logger.LogInformation("Found guild {guild} in shard {shard}!", guildId, extension.Client.ShardId); + extension.RegisterGuildCommands(type, guildId, translationSetup); + extension.Client.Logger.LogInformation("Registered"); + } + catch (Exception ex) + { + extension.Client.Logger.LogError(ex.Message); + extension.Client.Logger.LogError(ex.StackTrace); + } + return; } } } /// /// Enables application commands on this . /// /// Client to enable application commands on. /// Configuration to use. /// A dictionary of created with the key being the shard id. public static async Task> UseApplicationCommandsAsync(this DiscordShardedClient client, ApplicationCommandsConfiguration config = null) { var modules = new Dictionary(); await client.InitializeShardsAsync().ConfigureAwait(false); foreach (var shard in client.ShardClients.Values) { var scomm = shard.GetExtension(); if (scomm == null) scomm = shard.UseApplicationCommands(config); modules[shard.ShardId] = scomm; } return modules; } /// /// Gets the name from the for this enum value. /// /// The name. public static string GetName(this T e) where T : IConvertible { if (e is Enum) { var type = e.GetType(); var values = Enum.GetValues(type); foreach (int val in values) { if (val == e.ToInt32(CultureInfo.InvariantCulture)) { var memInfo = type.GetMember(type.GetEnumName(val)); return memInfo[0] .GetCustomAttributes(typeof(ChoiceNameAttribute), false) .FirstOrDefault() is ChoiceNameAttribute nameAttribute ? nameAttribute.Name : type.GetEnumName(val); } } } return null; } }