@@ -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(); | |||
/// <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> | |||
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); | |||
} | |||
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; | |||
text = MentionUtils.ResolveUserMentions(text, Channel, MentionedUsers, userMode); | |||
text = MentionUtils.ResolveUserMentions(text, Channel, MentionedUsers, userHandling); | |||
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; | |||
} | |||
@@ -154,8 +154,10 @@ namespace Discord | |||
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 => | |||
{ | |||
ulong id; | |||
@@ -183,10 +185,12 @@ namespace Discord | |||
switch (mode) | |||
{ | |||
case UserResolveMode.NameOnly: | |||
case UserMentionHandling.Remove: | |||
default: | |||
return ""; | |||
case UserMentionHandling.Name: | |||
return $"@{name}"; | |||
case UserResolveMode.NameAndDiscriminator: | |||
case UserMentionHandling.NameAndDiscriminator: | |||
return $"@{name}#{user.Discriminator}"; | |||
} | |||
} | |||
@@ -194,8 +198,10 @@ namespace Discord | |||
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 | |||
{ | |||
return _channelRegex.Replace(text, new MatchEvaluator(e => | |||
@@ -203,37 +209,68 @@ namespace Discord | |||
ulong 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 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 => | |||
{ | |||
ulong 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; | |||
})); | |||
} | |||
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", ""); | |||
} | |||
} | |||
} | |||
} |