using Discord.WebSocket; using Newtonsoft.Json.Linq; using System; using System.Diagnostics; using System.Threading.Tasks; using static Kerobot.Kerobot; namespace Kerobot { /// /// Base class for a Kerobot module. A module implements a user-facing feature and is expected to directly handle /// user input (both by means of configuration and incoming Discord events) and process it accordingly. /// /// /// Implementing classes should not rely on local variables to store runtime data regarding guilds. /// Use and . /// public abstract class ModuleBase { /// /// Retrieves the Kerobot instance. /// public Kerobot Kerobot { get; } /// /// Retrieves the Discord client instance. /// public DiscordSocketClient DiscordClient { get => Kerobot.DiscordClient; } /// /// When a module is loaded, this constructor is called. /// Services are available at this point. Do not attempt to communicate to Discord within the constructor. /// public ModuleBase(Kerobot kb) => Kerobot = kb; /// /// Gets the module name. /// This value is derived from the class's name. It is used in configuration and logging. /// public string Name => GetType().Name; /// /// Called when a guild becomes available. The implementing class should construct an object to hold /// data specific to the corresponding guild for use during runtime. /// /// JSON token holding module configuration specific to this guild. /// /// An object containing state and/or configuration information for the guild currently being processed. /// public abstract Task CreateGuildStateAsync(JToken config); /// /// Retrieves the state object that corresponds with the given guild. /// /// The state object's type. /// The guild ID for which to retrieve the state object. /// The state object cast in the given type, or Default(T) if none exists. /// /// Thrown if the stored state object cannot be cast as specified. /// [DebuggerStepThrough] protected T GetGuildState(ulong guildId) => Kerobot.GetGuildState(guildId, GetType()); /// /// Appends a message to the global instance log. Use sparingly. /// /// /// Specifies if the log message should be sent to the reporting channel. /// Only messages of very high importance should use this option. /// protected Task LogAsync(string message, bool report = false) => Kerobot.InstanceLogAsync(report, Name, message); /// /// Appends a message to the log for the specified guild. /// protected Task LogAsync(ulong guild, string message) => Kerobot.GuildLogAsync(guild, Name, message); /// /// Attempts to ban the given user from the specified guild. It is greatly preferred to call this method /// instead of manually executing the equivalent method found in Discord.Net. It notifies other services /// that the action originated from the bot, and allows them to handle the action appropriately. /// /// A structure containing results of the ban operation. /// The guild in which to attempt the action. /// The user, module, or service which is requesting this action to be taken. /// The user which to perform the action to. /// Number of days of prior post history to delete on ban. Must be between 0-7. /// Reason for the action. Sent to the Audit Log and user (if specified). /// /// Message to DM the target user. Set null to disable. Instances of "%s" are replaced with the guild name /// and instances of "%r" are replaced with the reason. /// protected Task BanAsync(SocketGuild guild, string source, ulong targetUser, int purgeDays, string reason, string dmMsg) => Kerobot.BanOrKickAsync(RemovalType.Ban, guild, source, targetUser, purgeDays, reason, dmMsg); protected Task BanAsync(SocketGuild guild, SocketGuildUser source, string targetSearch, string reason, string dmMsg) { // TODO requires EntityCache lookup. Do this when that feature gets implemented. throw new NotImplementedException(); } /// /// Attempts to ban the given user from the specified guild. It is greatly preferred to call this method /// instead of manually executing the equivalent method found in Discord.Net. It notifies other services /// that the action originated from the bot, and allows them to handle the action appropriately. /// /// A structure containing results of the ban operation. /// The guild in which to attempt the action. /// The user, if any, which requested the action to be taken. /// The user which to perform the action to. /// Reason for the action. Sent to the Audit Log and user (if specified). /// /// Message to DM the target user. Set null to disable. Instances of "%s" are replaced with the guild name /// and instances of "%r" are replaced with the reason. /// protected Task KickAsync(SocketGuild guild, string source, ulong targetUser, string reason, string dmMsg) => Kerobot.BanOrKickAsync(RemovalType.Ban, guild, source, targetUser, 0, reason, dmMsg); protected Task KickAsync(SocketGuild guild, SocketUser user, string reason, string dmMsg) { // TODO requires EntityCache lookup. Do this when that feature gets implemented. throw new NotImplementedException(); } } /// /// Represents errors that occur when a module attempts to create a new guild state object. /// public class ModuleLoadException : Exception { /// /// Initializes this exception class with the specified error message. /// /// public ModuleLoadException(string message) : base(message) { } } }