// Note: not actually an embed internal static async Task RoleEmbedCreate(CommandContext ctx, DiscordChannel channel, string title, DiscordEmoji emoji, DiscordRole role) { if (title.Length > 0) { DiscordMessage roleMessage = await channel.SendMessageAsync( content : String.Format("{0}\n{1} {2}", arg0: title, arg1: EmojiConverter.GetEmojiString(emoji), arg2: role.Mention)); var a = roleMessage.CreateReactionAsync(emoji); var b = AddMessageToDatabase(roleMessage.Id, role, emoji); await Task.WhenAll(a, b); await ctx.RespondAsync( embed : Generics.GenericEmbedTemplate( color: Generics.NeutralColor, description: $"Tasks:\nCreate Reaction Success: {a.IsCompletedSuccessfully}\n" + $"Database Success: {a.IsCompletedSuccessfully}", title: @"Create new embed")); } else { await GenericResponses.HandleInvalidArguments(ctx); } }
public async Task ExcludeBase(CommandContext ctx, string action, [RemainingText] string exclude = @"") { // Check if they have the permissions to call this command. if (await Permissions.HandlePermissionsCheck(ctx)) { switch (action) { case "new": case "add": if (!(await FilterSystem.HasItem(exclude))) { // The exclude doesn't exist already. await FilterSystem.AddExclude(ctx, exclude); } else { // The exclude does exist. await GenericResponses.SendGenericCommandError( ctx.Channel, ctx.Member.Mention, "Unable to add exclude", $"the provided exclude `{exclude}` exists already as an exclude or mask..."); } break; case "remove": case "delete": if ((await FilterSystem.HasExclude(exclude))) { // The exclude exists. await FilterSystem.RemoveExclude(ctx, exclude); } else { // The exclude doesn't exist. await GenericResponses.SendGenericCommandError( ctx.Channel, ctx.Member.Mention, "Unable to remove exclude", $"the provided exclude `{exclude}` exists already..."); } break; case "list": await FilterSystem.ListExcludes(ctx); break; default: await GenericResponses.HandleInvalidArguments(ctx); break; } } }
public async Task FilterBase(CommandContext ctx, string action, [RemainingText] string mask = @"") { // Check if they have the permissions to call this command. if (await Permissions.HandlePermissionsCheck(ctx)) { switch (action) { case "new": case "add": if (!(await FilterSystem.HasItem(mask))) { // The mask doesn't exist already. await FilterSystem.AddMask(ctx, mask); } else { // The mask does exist. await GenericResponses.SendGenericCommandError( ctx.Channel, ctx.Member.Mention, "Unable to add mask", $"the provided mask `{mask}` exists already as an exclude or mask..."); } break; case "remove": case "delete": if ((await FilterSystem.HasMask(mask))) { // The mask exists. await FilterSystem.RemoveMask(ctx, mask); } else { // The mask doesn't exist. await GenericResponses.SendGenericCommandError( ctx.Channel, ctx.Member.Mention, "Unable to remove mask", $"the provided mask `{mask}` does not exist..."); } break; case "list": await FilterSystem.ListMasks(ctx); break; default: // Invalid arguments. await GenericResponses.HandleInvalidArguments(ctx); break; } } }
public async Task RoleEmbedCreate(CommandContext ctx, DiscordChannel channel, DiscordEmoji emoji, DiscordRole role, [RemainingText] string title) { if (await Permissions.HandlePermissionsCheck(ctx)) { if (!(title is null) && title.Length > 0) { await RoleRequestSystem.RoleEmbedCreate(ctx, channel, title, emoji, role); } else { await GenericResponses.HandleInvalidArguments(ctx); } }
public async Task MentionsLookup(CommandContext ctx, params string[] users) { if (await Permissions.HandlePermissionsCheck(ctx)) { // Convert the string[] into a ulong[] ulong[] userIds = new ulong[users.Length]; bool validArguments = true; for (int i = 0; i < users.Length && validArguments; i++) { Match m = UserIdLookupRegex.Match(users[i]); if (m.Success && ulong.TryParse(m.Value, out ulong a)) { userIds[i] = a; } else { validArguments = false; } } // Check if all arguments are valid. If any are not, we tell the user they f****d it up. if (validArguments) { await MentionsLookupUnwrapper(ctx, userIds); } else { await GenericResponses.HandleInvalidArguments(ctx); } } }
public async Task ExcludeChannel(CommandContext ctx, string command, params DiscordChannel[] channels) { if (await Permissions.HandlePermissionsCheck(ctx)) { Func <DiscordChannel, bool> commandsAction; string verb; string verb2; switch (command) { case "add": commandsAction = delegate(DiscordChannel c) { ulong id = c.Id; // Make sure it doesn't exist. bool notExists_returnVal = !Program.Settings.ExcludedChannels.Contains(id); // It doesn't exist, so we can add it. if (notExists_returnVal) { Program.Settings.ExcludedChannels.Add(id); } return(notExists_returnVal); }; verb = @"add"; verb2 = @"added"; break; case "remove": commandsAction = delegate(DiscordChannel c) { ulong id = c.Id; // Check if it exists. bool exists_returnVal = Program.Settings.ExcludedChannels.Contains(id); // Only remove it if it exists. if (exists_returnVal) { Program.Settings.ExcludedChannels.Remove(id); } return(exists_returnVal); }; verb = @"remove"; verb2 = @"removed"; break; default: commandsAction = null; verb = String.Empty; verb2 = String.Empty; break; } // Check if we got a valid command arg. if (commandsAction is null) { // We did not get a valid command arg. await GenericResponses.HandleInvalidArguments(ctx); } else { // We did get a valid command arg. // Array of everything and a description of if it was added or not. Dictionary <DiscordChannel, bool> successAdded = new Dictionary <DiscordChannel, bool>(channels.Length); // Loop through each channel. foreach (DiscordChannel chan in channels) { // Invoke our command on each channel successAdded.Add(chan, commandsAction.Invoke(chan)); } // Check if anything was added successfully. if (successAdded.Any(a => a.Value)) { // Yes, at least one thing was added successfully. So let's save the settings now that they've been updated. Program.SaveSettings(); } // Respond. await GenericResponses.SendMessageChangedNotChanged( channel : ctx.Channel, title : $"Attempted to {verb} channel(s)", mention : ctx.Member.Mention, body : $"I attempted to {verb} the channels you gave me.", successChanged : successAdded, verb : verb2, invertedVerb : $"not {verb2}"); } } }
public static async Task AddReminder(CommandContext ctx, string args) { // Firstly get all the matches. MatchCollection regexMatches = DateRegex.Matches(args); BitArray regexCoverage = new BitArray(args.Length); var dto = ctx.Message.CreationTimestamp; List <ulong> mentions = new List <ulong>(); // String processing - find the message and get the reminder end date. // To find what's not a date, we simply look for the first character that isn't in the boundaries of a Regex match. // // Structure of a possible string: // // Date String | Message String // DATE, DATE, DATE, DATE | message // // Beyond the Date String we want to stop processing time information as people may reference time in the message string, so we don't // erronously want that data added to the date string. // Populate the regexCoverage... foreach (Match match in regexMatches) { for (int i = match.Index; i < match.Index + match.Length; i++) { regexCoverage[i] = true; } } // So I want to explain what I'm about to do here. Every value in regexCoverage[] indicates if that's part of the initial time // string. We want to use it to determine if something is a message or a time value, so if at any point, we run into something that // isn't a time string, we want to set every instance thereafter as false so we know it's part of a message. if (regexMatches.Count > 0) { bool value = regexCoverage[0]; for (int k = 1; k < regexCoverage.Count; k++) { if (!IsWhitespace(args[k])) { if (!regexCoverage[k] && value) { value = false; } if (!value) { regexCoverage[k] = value; } } } } // We need to figure out where the date string ends. string messageString = String.Empty; int dateEndIndex = 0; bool messageFound = false; while (dateEndIndex < regexCoverage.Length && !messageFound) { char stringChar = args[dateEndIndex]; bool inRegexBoundaries = regexCoverage[dateEndIndex]; // This checks to see if the character is non-white-space and outside of any RegEx boundaries. messageFound = !IsWhitespace(stringChar) && !inRegexBoundaries; // If not found, continue; otherwise, keep incrementing. if (!messageFound) { dateEndIndex++; } } // If we aren't going out of bounds, let's set the string to this. if (dateEndIndex < regexCoverage.Length) { messageString = args.Substring(dateEndIndex); } // Get date information foreach (Match match in regexMatches) { // Only try to exclude Message String date information if a message string was found. if (!messageFound || (regexCoverage[match.Index] && regexCoverage[match.Index + match.Length - 1])) { InterpretTime(match.Groups[1].Value, match.Groups[2].Value, ref dto); } } // Get mentions foreach (DiscordUser user in ctx.Message.MentionedUsers) { ulong id = user.Id; if (!user.IsBot && !mentions.Contains(id)) { mentions.Add(id); } } // At this point, now we have the DateTimeOffset describing when this reminder needs to be set off, and we have a message string if // any. So now we just need to make sure it's within reasonable boundaries, set the reminder, and notify the user. DateTimeOffset maxtime = new DateTimeOffset(ctx.Message.CreationTimestamp.UtcDateTime).AddMonths(Program.Settings.MaxReminderTimeMonths); DiscordEmbedBuilder embed; bool sendErrorEmbed = false; if (dto.UtcTicks == ctx.Message.CreationTimestamp.UtcTicks) { // No time was added. embed = Generics.GenericEmbedTemplate( color: Generics.NegativeColor, description: Generics.NegativeDirectResponseTemplate( mention: ctx.Member.Mention, body: @"I was unable able to add the reminder you gave me. You didn't supply me a valid time..."), title: @"Unable to add reminder", thumbnail: Generics.URL_REMINDER_GENERIC ); sendErrorEmbed = true; } else if (dto.UtcTicks > maxtime.UtcTicks) { // More than our allowed time away. int maxMonths = Program.Settings.MaxReminderTimeMonths; embed = Generics.GenericEmbedTemplate( color: Generics.NegativeColor, description: Generics.NegativeDirectResponseTemplate( mention: ctx.Member.Mention, body: $"I was unable able to add the reminder you gave me. That's more than {maxMonths} month{(maxMonths > 0 ? @"s" : String.Empty)} away..."), title: @"Unable to add reminder", thumbnail: Generics.URL_REMINDER_GENERIC ); sendErrorEmbed = true; } else { // Everything is good in the world... except that the world is burning, but that's not something we're worried about here, for // now... embed = Generics.GenericEmbedTemplate( color: Generics.PositiveColor, description: Generics.PositiveDirectResponseTemplate( mention: ctx.Member.Mention, body: @"I added the reminder you gave me!"), title: @"Add reminder", thumbnail: Generics.URL_REMINDER_GENERIC ); Reminder reminder = new Reminder( originalMessageId: ctx.Message.Id.ToString(), text: messageString.Length.Equals(0) ? @"n/a" : messageString.ToString(), time: (int)(dto.ToUnixTimeSeconds() / 60), user: ctx.Member.Id, channel: ctx.Channel.Id, usersToNotify: mentions.Select(a => Generics.GetMention(a)).ToArray()); embed.AddField(@"User", ctx.Member.Mention, true); embed.AddField(@"Time (UTC)", dto.ToString(Generics.DateFormat), true); embed.AddField(@"Remaining time", Generics.GetRemainingTime(dto), true); embed.AddField(@"Notification Identifier", reminder.OriginalMessageId.ToString(), false); if (GetUsersToNotify(reminder.UsersToNotify, out string mentionsString)) { embed.AddField(@"Users to mention", mentionsString, false); } // Let's build the command. using var command = new SqliteCommand(BotDatabase.Instance.DataSource) { CommandText = QQ_AddReminder }; SqliteParameter a = new SqliteParameter("$id", reminder.OriginalMessageId.ToString()) { DbType = DbType.String }; SqliteParameter b = new SqliteParameter("$userid", reminder.User) { DbType = DbType.String }; SqliteParameter c = new SqliteParameter("$channelid", reminder.Channel) { DbType = DbType.String }; SqliteParameter d = new SqliteParameter("$message", reminder.Text) { DbType = DbType.String }; SqliteParameter e = new SqliteParameter("$time", reminder.Time) { DbType = DbType.Int32 }; var stringBuilder = new StringBuilder(); stringBuilder.AppendJoin(' ', reminder.UsersToNotify); SqliteParameter f = new SqliteParameter("$mention", stringBuilder.ToString()) { DbType = DbType.String }; command.Parameters.AddRange(new SqliteParameter[] { a, b, c, d, e, f }); await BotDatabase.Instance.ExecuteNonQuery(command); // Send the response. await ctx.Channel.SendMessageAsync(embed : embed); } if (sendErrorEmbed) { var a = ctx.Channel.SendMessageAsync(embed: embed); var b = GenericResponses.HandleInvalidArguments(ctx); await Task.WhenAll(a, b); } }