Added ordered user mentions, fixed role and channel mention resolving
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Discord.Commands
|
namespace Discord.Commands
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ namespace Discord
|
|||||||
IReadOnlyCollection<IEmbed> Embeds { get; }
|
IReadOnlyCollection<IEmbed> Embeds { get; }
|
||||||
/// <summary> Returns a collection of channel ids mentioned in this message. </summary>
|
/// <summary> Returns a collection of channel ids mentioned in this message. </summary>
|
||||||
IReadOnlyCollection<ulong> MentionedChannelIds { get; }
|
IReadOnlyCollection<ulong> MentionedChannelIds { get; }
|
||||||
/// <summary> Returns a collection of role ids mentioned in this message. </summary>
|
/// <summary> Returns a collection of roles mentioned in this message. </summary>
|
||||||
IReadOnlyCollection<ulong> MentionedRoleIds { get; }
|
IReadOnlyCollection<IRole> MentionedRoles { get; }
|
||||||
/// <summary> Returns a collection of user ids mentioned in this message. </summary>
|
/// <summary> Returns a collection of users mentioned in this message. </summary>
|
||||||
IReadOnlyCollection<IUser> MentionedUsers { get; }
|
IReadOnlyCollection<IUser> MentionedUsers { get; }
|
||||||
|
|
||||||
/// <summary> Modifies this message. </summary>
|
/// <summary> Modifies this message. </summary>
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ namespace Discord
|
|||||||
public IMessageChannel Channel { get; }
|
public IMessageChannel Channel { get; }
|
||||||
public IUser Author { get; }
|
public IUser Author { get; }
|
||||||
|
|
||||||
public ImmutableArray<Attachment> Attachments { get; private set; }
|
public IReadOnlyCollection<Attachment> Attachments { get; private set; }
|
||||||
public ImmutableArray<Embed> Embeds { get; private set; }
|
public IReadOnlyCollection<IEmbed> Embeds { get; private set; }
|
||||||
public ImmutableArray<ulong> MentionedChannelIds { get; private set; }
|
public IReadOnlyCollection<ulong> MentionedChannelIds { get; private set; }
|
||||||
public ImmutableArray<ulong> MentionedRoleIds { get; private set; }
|
public IReadOnlyCollection<IRole> MentionedRoles { get; private set; }
|
||||||
public ImmutableArray<User> MentionedUsers { get; private set; }
|
public IReadOnlyCollection<IUser> MentionedUsers { get; private set; }
|
||||||
|
|
||||||
public override DiscordClient Discord => (Channel as Entity<ulong>).Discord;
|
public override DiscordClient Discord => (Channel as Entity<ulong>).Discord;
|
||||||
public DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
public DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
|
||||||
@@ -41,9 +41,9 @@ namespace Discord
|
|||||||
|
|
||||||
if (channel is IGuildChannel)
|
if (channel is IGuildChannel)
|
||||||
{
|
{
|
||||||
MentionedUsers = ImmutableArray.Create<User>();
|
MentionedUsers = ImmutableArray.Create<IUser>();
|
||||||
MentionedChannelIds = ImmutableArray.Create<ulong>();
|
MentionedChannelIds = ImmutableArray.Create<ulong>();
|
||||||
MentionedRoleIds = ImmutableArray.Create<ulong>();
|
MentionedRoles = ImmutableArray.Create<IRole>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Update(model, UpdateSource.Creation);
|
Update(model, UpdateSource.Creation);
|
||||||
@@ -106,21 +106,31 @@ namespace Discord
|
|||||||
MentionedUsers = ImmutableArray.Create(mentions);
|
MentionedUsers = ImmutableArray.Create(mentions);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
MentionedUsers = ImmutableArray.Create<User>();
|
MentionedUsers = ImmutableArray.Create<IUser>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.Content.IsSpecified)
|
if (model.Content.IsSpecified)
|
||||||
{
|
{
|
||||||
RawText = model.Content.Value;
|
RawText = model.Content.Value;
|
||||||
|
|
||||||
if (Channel is IGuildChannel)
|
if (guildChannel != null)
|
||||||
{
|
{
|
||||||
Text = MentionUtils.CleanUserMentions(RawText, MentionedUsers);
|
var orderedMentionedUsers = ImmutableArray.CreateBuilder<IUser>(5);
|
||||||
MentionedChannelIds = MentionUtils.GetChannelMentions(RawText);
|
Text = MentionUtils.CleanUserMentions(RawText, Channel.IsAttached ? Channel : null, MentionedUsers, orderedMentionedUsers);
|
||||||
var mentionedRoleIds = MentionUtils.GetRoleMentions(RawText);
|
MentionedUsers = orderedMentionedUsers.ToImmutable();
|
||||||
if (_isMentioningEveryone)
|
|
||||||
mentionedRoleIds = mentionedRoleIds.Add(guildChannel.Guild.EveryoneRole.Id);
|
var roles = ImmutableArray.CreateBuilder<IRole>(5);
|
||||||
MentionedRoleIds = mentionedRoleIds;
|
Text = MentionUtils.CleanRoleMentions(Text, guildChannel.Guild, roles);
|
||||||
|
MentionedRoles = roles.ToImmutable();
|
||||||
|
|
||||||
|
if (guildChannel.IsAttached) //It's too expensive to do a channel lookup in REST mode
|
||||||
|
{
|
||||||
|
var channelIds = ImmutableArray.CreateBuilder<ulong>(5);
|
||||||
|
Text = MentionUtils.CleanChannelMentions(Text, guildChannel.Guild, channelIds);
|
||||||
|
MentionedChannelIds = channelIds.ToImmutable();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MentionedChannelIds = MentionUtils.GetChannelMentions(RawText);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Text = RawText;
|
Text = RawText;
|
||||||
@@ -172,12 +182,6 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => Text;
|
public override string ToString() => Text;
|
||||||
private string DebuggerDisplay => $"{Author}: {Text}{(Attachments.Length > 0 ? $" [{Attachments.Length} Attachments]" : "")}";
|
private string DebuggerDisplay => $"{Author}: {Text}{(Attachments.Count > 0 ? $" [{Attachments.Count} Attachments]" : "")}";
|
||||||
|
|
||||||
IReadOnlyCollection<Attachment> IMessage.Attachments => Attachments;
|
|
||||||
IReadOnlyCollection<IEmbed> IMessage.Embeds => Embeds;
|
|
||||||
IReadOnlyCollection<ulong> IMessage.MentionedChannelIds => MentionedChannelIds;
|
|
||||||
IReadOnlyCollection<ulong> IMessage.MentionedRoleIds => MentionedRoleIds;
|
|
||||||
IReadOnlyCollection<IUser> IMessage.MentionedUsers => MentionedUsers;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Immutable;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
@@ -107,7 +108,7 @@ namespace Discord
|
|||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string CleanUserMentions(string text, ImmutableArray<User> mentions)
|
/*internal static string CleanUserMentions(string text, ImmutableArray<User> mentions)
|
||||||
{
|
{
|
||||||
return _userRegex.Replace(text, new MatchEvaluator(e =>
|
return _userRegex.Replace(text, new MatchEvaluator(e =>
|
||||||
{
|
{
|
||||||
@@ -123,58 +124,71 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
}
|
}*/
|
||||||
internal static string CleanUserMentions<T>(string text, IReadOnlyDictionary<ulong, T> users, ImmutableArray<T>.Builder mentions = null)
|
internal static string CleanUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> fallbackUsers, ImmutableArray<IUser>.Builder mentions = null)
|
||||||
where T : IGuildUser
|
|
||||||
{
|
{
|
||||||
return _channelRegex.Replace(text, new MatchEvaluator(e =>
|
return _userRegex.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))
|
||||||
{
|
{
|
||||||
T user;
|
IUser user = null;
|
||||||
if (users.TryGetValue(id, out user))
|
if (channel != null)
|
||||||
|
user = channel.GetUserAsync(id).GetAwaiter().GetResult() as IUser;
|
||||||
|
if (user == null)
|
||||||
{
|
{
|
||||||
if (users != null)
|
foreach (var fallbackUser in fallbackUsers)
|
||||||
mentions.Add(user);
|
{
|
||||||
if (e.Value[2] == '!' && user.Nickname != null)
|
if (fallbackUser.Id == id)
|
||||||
return '@' + user.Nickname;
|
{
|
||||||
else
|
user = fallbackUser;
|
||||||
return '@' + user.Username;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
mentions.Add(user);
|
||||||
|
|
||||||
|
if (e.Value[2] == '!')
|
||||||
|
{
|
||||||
|
var guildUser = user as IGuildUser;
|
||||||
|
if (guildUser != null && guildUser.Nickname != null)
|
||||||
|
return '@' + guildUser.Nickname;
|
||||||
|
}
|
||||||
|
return '@' + user.Username;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
internal static string CleanChannelMentions<T>(string text, IReadOnlyDictionary<ulong, T> channels, ImmutableArray<T>.Builder mentions = null)
|
internal static string CleanChannelMentions(string text, IGuild guild, ImmutableArray<ulong>.Builder mentions = null)
|
||||||
where T : IGuildChannel
|
|
||||||
{
|
{
|
||||||
return _channelRegex.Replace(text, new MatchEvaluator(e =>
|
return _channelRegex.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))
|
||||||
{
|
{
|
||||||
T channel;
|
var channel = guild.GetChannelAsync(id).GetAwaiter().GetResult() as IGuildChannel;
|
||||||
if (channels.TryGetValue(id, out channel))
|
if (channel != null)
|
||||||
{
|
{
|
||||||
if (channels != null)
|
if (mentions != null)
|
||||||
mentions.Add(channel);
|
mentions.Add(channel.Id);
|
||||||
return '#' + channel.Name;
|
return '#' + channel.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
internal static string CleanRoleMentions<T>(string text, IReadOnlyDictionary<ulong, T> roles, ImmutableArray<T>.Builder mentions = null)
|
internal static string CleanRoleMentions(string text, IGuild guild, ImmutableArray<IRole>.Builder mentions = null)
|
||||||
where T : IRole
|
|
||||||
{
|
{
|
||||||
return _channelRegex.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))
|
||||||
{
|
{
|
||||||
T role;
|
var role = guild.GetRole(id);
|
||||||
if (roles.TryGetValue(id, out role))
|
if (role != null)
|
||||||
{
|
{
|
||||||
if (mentions != null)
|
if (mentions != null)
|
||||||
mentions.Add(role);
|
mentions.Add(role);
|
||||||
|
|||||||
Reference in New Issue
Block a user