| @@ -0,0 +1,9 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum ChannelMentionHandling | |||||
| { | |||||
| Ignore = 0, | |||||
| Remove, | |||||
| Name | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum EveryoneMentionHandling | |||||
| { | |||||
| Ignore = 0, | |||||
| Remove, | |||||
| Sanitize | |||||
| } | |||||
| } | |||||
| @@ -43,8 +43,16 @@ namespace Discord | |||||
| Task UnpinAsync(); | Task UnpinAsync(); | ||||
| /// <summary> Transforms this message's text into a human readable form, resolving things like mentions to that object's name. </summary> | /// <summary> Transforms this message's text into a human readable form, resolving things like mentions to that object's name. </summary> | ||||
| string Resolve(int startIndex, int length, UserResolveMode userMode = UserResolveMode.NameOnly); | |||||
| string Resolve(int startIndex, int length, | |||||
| UserMentionHandling userHandling = UserMentionHandling.Name, | |||||
| ChannelMentionHandling channelHandling = ChannelMentionHandling.Name, | |||||
| RoleMentionHandling roleHandling = RoleMentionHandling.Name, | |||||
| EveryoneMentionHandling everyoneHandling = EveryoneMentionHandling.Ignore); | |||||
| /// <summary> Transforms this message's text into a human readable form, resolving things like mentions to that object's name. </summary> | /// <summary> Transforms this message's text into a human readable form, resolving things like mentions to that object's name. </summary> | ||||
| string Resolve(UserResolveMode userMode = UserResolveMode.NameOnly); | |||||
| string Resolve( | |||||
| UserMentionHandling userHandling = UserMentionHandling.Name, | |||||
| ChannelMentionHandling channelHandling = ChannelMentionHandling.Name, | |||||
| RoleMentionHandling roleHandling = RoleMentionHandling.Name, | |||||
| EveryoneMentionHandling everyoneHandling = EveryoneMentionHandling.Ignore); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,9 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum RoleMentionHandling | |||||
| { | |||||
| Ignore = 0, | |||||
| Remove, | |||||
| Name | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,10 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum UserMentionHandling | |||||
| { | |||||
| Ignore = 0, | |||||
| Remove, | |||||
| Name, | |||||
| NameAndDiscriminator | |||||
| } | |||||
| } | |||||
| @@ -1,8 +0,0 @@ | |||||
| namespace Discord | |||||
| { | |||||
| public enum UserResolveMode | |||||
| { | |||||
| NameOnly = 0, | |||||
| NameAndDiscriminator | |||||
| } | |||||
| } | |||||
| @@ -161,19 +161,23 @@ namespace Discord | |||||
| await Discord.ApiClient.RemovePinAsync(Channel.Id, Id).ConfigureAwait(false); | await Discord.ApiClient.RemovePinAsync(Channel.Id, Id).ConfigureAwait(false); | ||||
| } | } | ||||
| public string Resolve(int startIndex, int length, UserResolveMode userMode = UserResolveMode.NameOnly) | |||||
| => Resolve(Content.Substring(startIndex, length), userMode); | |||||
| public string Resolve(UserResolveMode userMode = UserResolveMode.NameOnly) | |||||
| => Resolve(Content, userMode); | |||||
| public string Resolve(int startIndex, int length, UserMentionHandling userHandling, ChannelMentionHandling channelHandling, | |||||
| RoleMentionHandling roleHandling, EveryoneMentionHandling everyoneHandling) | |||||
| => Resolve(Content.Substring(startIndex, length), userHandling, channelHandling, roleHandling, everyoneHandling); | |||||
| public string Resolve(UserMentionHandling userHandling, ChannelMentionHandling channelHandling, | |||||
| RoleMentionHandling roleHandling, EveryoneMentionHandling everyoneHandling) | |||||
| => Resolve(Content, userHandling, channelHandling, roleHandling, everyoneHandling); | |||||
| private string Resolve(string text, UserResolveMode userMode = UserResolveMode.NameOnly) | |||||
| private string Resolve(string text, UserMentionHandling userHandling, ChannelMentionHandling channelHandling, | |||||
| RoleMentionHandling roleHandling, EveryoneMentionHandling everyoneHandling) | |||||
| { | { | ||||
| var guild = (Channel as IGuildChannel)?.Guild; | var guild = (Channel as IGuildChannel)?.Guild; | ||||
| text = MentionUtils.ResolveUserMentions(text, Channel, MentionedUsers, userMode); | |||||
| text = MentionUtils.ResolveUserMentions(text, Channel, MentionedUsers, userHandling); | |||||
| if (guild != null) | if (guild != null) | ||||
| { | { | ||||
| text = MentionUtils.ResolveChannelMentions(text, guild); | |||||
| text = MentionUtils.ResolveRoleMentions(text, guild, MentionedRoles); | |||||
| text = MentionUtils.ResolveChannelMentions(text, guild, channelHandling); | |||||
| text = MentionUtils.ResolveRoleMentions(text, guild, MentionedRoles, roleHandling); | |||||
| text = MentionUtils.ResolveEveryoneMentions(text, everyoneHandling); | |||||
| } | } | ||||
| return text; | return text; | ||||
| } | } | ||||
| @@ -154,8 +154,10 @@ namespace Discord | |||||
| return builder.ToImmutable(); | return builder.ToImmutable(); | ||||
| } | } | ||||
| internal static string ResolveUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> mentions, UserResolveMode mode) | |||||
| internal static string ResolveUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> mentions, UserMentionHandling mode) | |||||
| { | { | ||||
| if (mode == UserMentionHandling.Ignore) return text; | |||||
| return _userRegex.Replace(text, new MatchEvaluator(e => | return _userRegex.Replace(text, new MatchEvaluator(e => | ||||
| { | { | ||||
| ulong id; | ulong id; | ||||
| @@ -183,10 +185,12 @@ namespace Discord | |||||
| switch (mode) | switch (mode) | ||||
| { | { | ||||
| case UserResolveMode.NameOnly: | |||||
| case UserMentionHandling.Remove: | |||||
| default: | default: | ||||
| return ""; | |||||
| case UserMentionHandling.Name: | |||||
| return $"@{name}"; | return $"@{name}"; | ||||
| case UserResolveMode.NameAndDiscriminator: | |||||
| case UserMentionHandling.NameAndDiscriminator: | |||||
| return $"@{name}#{user.Discriminator}"; | return $"@{name}#{user.Discriminator}"; | ||||
| } | } | ||||
| } | } | ||||
| @@ -194,8 +198,10 @@ namespace Discord | |||||
| return e.Value; | return e.Value; | ||||
| })); | })); | ||||
| } | } | ||||
| internal static string ResolveChannelMentions(string text, IGuild guild) | |||||
| internal static string ResolveChannelMentions(string text, IGuild guild, ChannelMentionHandling mode) | |||||
| { | { | ||||
| if (mode == ChannelMentionHandling.Ignore) return text; | |||||
| if (guild.IsAttached) //It's too expensive to do a channel lookup in REST mode | if (guild.IsAttached) //It's too expensive to do a channel lookup in REST mode | ||||
| { | { | ||||
| return _channelRegex.Replace(text, new MatchEvaluator(e => | return _channelRegex.Replace(text, new MatchEvaluator(e => | ||||
| @@ -203,37 +209,68 @@ namespace Discord | |||||
| ulong id; | ulong id; | ||||
| if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | ||||
| { | { | ||||
| IGuildChannel channel = null; | |||||
| channel = guild.GetChannelAsync(id).GetAwaiter().GetResult(); | |||||
| if (channel != null) | |||||
| return '#' + channel.Name; | |||||
| switch (mode) | |||||
| { | |||||
| case ChannelMentionHandling.Remove: | |||||
| return ""; | |||||
| case ChannelMentionHandling.Name: | |||||
| IGuildChannel channel = null; | |||||
| channel = guild.GetChannelAsync(id).GetAwaiter().GetResult(); | |||||
| if (channel != null) | |||||
| return $"#{channel.Name}"; | |||||
| else | |||||
| return $"#deleted-channel"; | |||||
| } | |||||
| } | } | ||||
| return e.Value; | return e.Value; | ||||
| })); | })); | ||||
| } | } | ||||
| return text; | return text; | ||||
| } | } | ||||
| internal static string ResolveRoleMentions(string text, IGuild guild, IReadOnlyCollection<IRole> mentions) | |||||
| internal static string ResolveRoleMentions(string text, IGuild guild, IReadOnlyCollection<IRole> mentions, RoleMentionHandling mode) | |||||
| { | { | ||||
| if (mode == RoleMentionHandling.Ignore) return text; | |||||
| return _roleRegex.Replace(text, new MatchEvaluator(e => | return _roleRegex.Replace(text, new MatchEvaluator(e => | ||||
| { | { | ||||
| ulong id; | ulong id; | ||||
| if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id)) | ||||
| { | { | ||||
| IRole role = null; | |||||
| foreach (var mention in mentions) | |||||
| switch (mode) | |||||
| { | { | ||||
| if (mention.Id == id) | |||||
| { | |||||
| role = mention; | |||||
| break; | |||||
| } | |||||
| case RoleMentionHandling.Remove: | |||||
| return ""; | |||||
| case RoleMentionHandling.Name: | |||||
| IRole role = null; | |||||
| foreach (var mention in mentions) | |||||
| { | |||||
| if (mention.Id == id) | |||||
| { | |||||
| role = mention; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (role != null) | |||||
| return $"@{role.Name}"; | |||||
| else | |||||
| return $"@deleted-role"; | |||||
| } | } | ||||
| if (role != null) | |||||
| return '@' + role.Name; | |||||
| } | } | ||||
| return e.Value; | return e.Value; | ||||
| })); | })); | ||||
| } | } | ||||
| internal static string ResolveEveryoneMentions(string text, EveryoneMentionHandling mode) | |||||
| { | |||||
| if (mode == EveryoneMentionHandling.Ignore) return text; | |||||
| switch (mode) | |||||
| { | |||||
| case EveryoneMentionHandling.Sanitize: | |||||
| return text.Replace("@everyone", "@\x200beveryone").Replace("@here", "@\x200bhere"); | |||||
| case EveryoneMentionHandling.Remove: | |||||
| default: | |||||
| return text.Replace("@everyone", "").Replace("@here", ""); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||