using System.Globalization; namespace PluralKit.Bot.Utils; // PK note: class is wholesale copied from Discord.NET (MIT-licensed) // https://github.com/discord-net/Discord.Net/blob/ff0fea98a65d907fbce07856f1a9ef4aebb9108b/src/Discord.Net.Core/Utils/MentionUtils.cs /// /// Provides a series of helper methods for parsing mentions. /// public static class MentionUtils { private const char SanitizeChar = '\x200b'; //If the system can't be positive a user doesn't have a nickname, assume useNickname = true (source: Jake) internal static string MentionUser(string id, bool useNickname = true) => useNickname ? $"<@!{id}>" : $"<@{id}>"; /// /// Returns a mention string based on the user ID. /// /// /// A user mention string (e.g. <@80351110224678912>). /// public static string MentionUser(ulong id) => MentionUser(id.ToString()); internal static string MentionChannel(string id) => $"<#{id}>"; /// /// Returns a mention string based on the channel ID. /// /// /// A channel mention string (e.g. <#103735883630395392>). /// public static string MentionChannel(ulong id) => MentionChannel(id.ToString()); internal static string MentionRole(string id) => $"<@&{id}>"; /// /// Returns a mention string based on the role ID. /// /// /// A role mention string (e.g. <@&165511591545143296>). /// public static string MentionRole(ulong id) => MentionRole(id.ToString()); /// /// Parses a provided user mention string. /// /// Invalid mention format. public static ulong ParseUser(string text) { if (TryParseUser(text, out var id)) return id; throw new ArgumentException("Invalid mention format.", nameof(text)); } /// /// Tries to parse a provided user mention string. /// public static bool TryParseUser(string text, out ulong userId) { if (text.Length >= 3 && text[0] == '<' && text[1] == '@' && text[text.Length - 1] == '>') { if (text.Length >= 4 && text[2] == '!') text = text.Substring(3, text.Length - 4); //<@!123> else text = text.Substring(2, text.Length - 3); //<@123> if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out userId)) return true; } userId = 0; return false; } /// /// Parses a provided channel mention string. /// /// Invalid mention format. public static ulong ParseChannel(string text) { if (TryParseChannel(text, out var id)) return id; throw new ArgumentException("Invalid mention format.", nameof(text)); } /// /// Tries to parse a provided channel mention string. /// public static bool TryParseChannel(string text, out ulong channelId) { if (text.Length > 3 && text[0] == '<' && text[1] == '#' && text[text.Length - 1] == '>') text = text.Substring(2, text.Length - 3); //<#123> if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out channelId)) return true; channelId = 0; return false; } /// /// Parses a provided role mention string. /// /// Invalid mention format. public static ulong ParseRole(string text) { if (TryParseRole(text, out var id)) return id; throw new ArgumentException("Invalid mention format.", nameof(text)); } /// /// Tries to parse a provided role mention string. /// public static bool TryParseRole(string text, out ulong roleId) { if (text.Length >= 4 && text[0] == '<' && text[1] == '@' && text[2] == '&' && text[text.Length - 1] == '>') { text = text.Substring(3, text.Length - 4); //<@&123> if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out roleId)) return true; } roleId = 0; return false; } }