using Discord;
using System.Diagnostics.CodeAnalysis;
using System.Text;
using System.Text.RegularExpressions;
namespace RegexBot.Common;
///
/// Miscellaneous utility methods useful for the bot and modules.
///
public static class Utilities {
///
/// Gets a compiled regex that matches a channel tag and pulls its snowflake value.
///
public static Regex ChannelMention { get; } = new(@"<#(?\d+)>", RegexOptions.Compiled);
///
/// Gets a compiled regex that matches a custom emoji and pulls its name and ID.
///
public static Regex CustomEmoji { get; } = new(@"<:(?[A-Za-z0-9_]{2,}):(?\d+)>", RegexOptions.Compiled);
///
/// Gets a compiled regex that matches a fully formed Discord handle, extracting the name and discriminator.
///
public static Regex DiscriminatorSearch { get; } = new(@"(.+)#(\d{4}(?!\d))", RegexOptions.Compiled);
///
/// Gets a compiled regex that matches a user tag and pulls its snowflake value.
///
public static Regex UserMention { get; } = new(@"<@!?(?\d+)>", RegexOptions.Compiled);
///
/// Performs common checks on the specified message to see if it fits all the criteria of a
/// typical, ordinary message sent by an ordinary guild user.
///
public static bool IsValidUserMessage(SocketMessage msg, [NotNullWhen(true)] out SocketTextChannel? channel) {
channel = default;
if (msg.Channel is not SocketTextChannel ch) return false;
if (msg.Author.IsBot || msg.Author.IsWebhook) return false;
if (((IMessage)msg).Type != MessageType.Default) return false;
if (msg is SocketSystemMessage) return false;
channel = ch;
return true;
}
///
/// Given a JToken, gets all string-based values out of it if the token may be a string
/// or an array of strings.
///
/// The JSON token to analyze and retrieve strings from.
/// Thrown if the given token is not a string or array containing all strings.
/// Thrown if the given token is null.
public static List LoadStringOrStringArray(JToken? token) {
const string ExNotString = "This token contains a non-string element.";
if (token == null) throw new ArgumentNullException(nameof(token), "The provided token is null.");
var results = new List();
if (token.Type == JTokenType.String) {
results.Add(token.Value()!);
} else if (token.Type == JTokenType.Array) {
foreach (var entry in token.Values()) {
if (entry.Type != JTokenType.String) throw new ArgumentException(ExNotString, nameof(token));
results.Add(entry.Value()!);
}
} else {
throw new ArgumentException(ExNotString, nameof(token));
}
return results;
}
///
/// Builds and returns an embed which displays this log entry.
///
public static Embed BuildEmbed(this Data.ModLogEntry entry, RegexbotClient bot) {
var logEmbed = new EmbedBuilder()
.WithTitle("Moderation log entry")
.WithTimestamp(entry.Timestamp)
.WithFooter($"Log ID {entry.LogId}");
string? issuedDisplay = null;
try {
var entityTry = new EntityName(entry.IssuedBy, EntityType.User);
var issueq = bot.EcQueryUser(entityTry.Id!.Value.ToString());
if (issueq != null) issuedDisplay = $"<@{issueq.UserId}> - {issueq.Username}#{issueq.Discriminator} `{issueq.UserId}`";
else issuedDisplay = $"Unknown user with ID `{entityTry.Id!.Value}`";
} catch (Exception) { }
issuedDisplay ??= entry.IssuedBy;
string targetDisplay;
var targetq = bot.EcQueryUser(entry.UserId.ToString());
if (targetq != null) targetDisplay = $"<@{targetq.UserId}> - {targetq.Username}#{targetq.Discriminator} `{targetq.UserId}`";
else targetDisplay = $"Unknown user with ID `{entry.UserId}`";
var contextStr = new StringBuilder();
contextStr.AppendLine($"Log type: {Enum.GetName(typeof(ModLogType), entry.LogType)}");
contextStr.AppendLine($"Regarding user: {targetDisplay}");
contextStr.AppendLine($"Logged by: {issuedDisplay}");
logEmbed.AddField(new EmbedFieldBuilder() {
Name = "Context",
Value = contextStr.ToString()
});
if (entry.Message != null) {
logEmbed.AddField(new EmbedFieldBuilder() {
Name = "Message",
Value = entry.Message
});
}
return logEmbed.Build();
}
}