Removed IMessage.Text, renamed RawText -> Text, added Resolve
This commit is contained in:
@@ -225,7 +225,7 @@ namespace Discord.Commands
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchResult Search(IMessage message, int argPos) => Search(message, message.RawText.Substring(argPos));
|
public SearchResult Search(IMessage message, int argPos) => Search(message, message.Text.Substring(argPos));
|
||||||
public SearchResult Search(IMessage message, string input)
|
public SearchResult Search(IMessage message, string input)
|
||||||
{
|
{
|
||||||
string lowerInput = input.ToLowerInvariant();
|
string lowerInput = input.ToLowerInvariant();
|
||||||
@@ -237,7 +237,7 @@ namespace Discord.Commands
|
|||||||
return SearchResult.FromError(CommandError.UnknownCommand, "Unknown command.");
|
return SearchResult.FromError(CommandError.UnknownCommand, "Unknown command.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IResult> Execute(IMessage message, int argPos) => Execute(message, message.RawText.Substring(argPos));
|
public Task<IResult> Execute(IMessage message, int argPos) => Execute(message, message.Text.Substring(argPos));
|
||||||
public async Task<IResult> Execute(IMessage message, string input)
|
public async Task<IResult> Execute(IMessage message, string input)
|
||||||
{
|
{
|
||||||
var searchResult = Search(message, input);
|
var searchResult = Search(message, input);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
{
|
{
|
||||||
public static bool HasCharPrefix(this IMessage msg, char c, ref int argPos)
|
public static bool HasCharPrefix(this IMessage msg, char c, ref int argPos)
|
||||||
{
|
{
|
||||||
var text = msg.RawText;
|
var text = msg.Text;
|
||||||
if (text.Length > 0 && text[0] == c)
|
if (text.Length > 0 && text[0] == c)
|
||||||
{
|
{
|
||||||
argPos = 1;
|
argPos = 1;
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
}
|
}
|
||||||
public static bool HasStringPrefix(this IMessage msg, string str, ref int argPos)
|
public static bool HasStringPrefix(this IMessage msg, string str, ref int argPos)
|
||||||
{
|
{
|
||||||
var text = msg.RawText;
|
var text = msg.Text;
|
||||||
//str = str + ' ';
|
//str = str + ' ';
|
||||||
if (text.StartsWith(str))
|
if (text.StartsWith(str))
|
||||||
{
|
{
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
}
|
}
|
||||||
public static bool HasMentionPrefix(this IMessage msg, IUser user, ref int argPos)
|
public static bool HasMentionPrefix(this IMessage msg, IUser user, ref int argPos)
|
||||||
{
|
{
|
||||||
var text = msg.RawText;
|
var text = msg.Text;
|
||||||
string mention = user.Mention + ' ';
|
string mention = user.Mention + ' ';
|
||||||
if (text.StartsWith(mention))
|
if (text.StartsWith(mention))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,9 +13,7 @@ namespace Discord
|
|||||||
bool IsTTS { get; }
|
bool IsTTS { get; }
|
||||||
/// <summary> Returns true if this message was added to its channel's pinned messages. </summary>
|
/// <summary> Returns true if this message was added to its channel's pinned messages. </summary>
|
||||||
bool IsPinned { get; }
|
bool IsPinned { get; }
|
||||||
/// <summary> Returns the original, unprocessed text for this message. </summary>
|
/// <summary> Returns the text for this message. </summary>
|
||||||
string RawText { get; }
|
|
||||||
/// <summary> Returns the text for this message after mention processing. </summary>
|
|
||||||
string Text { get; }
|
string Text { get; }
|
||||||
/// <summary> Gets the time this message was sent. </summary>
|
/// <summary> Gets the time this message was sent. </summary>
|
||||||
DateTimeOffset Timestamp { get; }
|
DateTimeOffset Timestamp { get; }
|
||||||
@@ -41,5 +39,10 @@ namespace Discord
|
|||||||
Task PinAsync();
|
Task PinAsync();
|
||||||
/// <summary> Removes this message from its channel's pinned messages. </summary>
|
/// <summary> Removes this message from its channel's pinned messages. </summary>
|
||||||
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>
|
||||||
|
string Resolve(int startIndex, int length, UserResolveMode userMode = UserResolveMode.NameOnly);
|
||||||
|
/// <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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,6 @@ namespace Discord
|
|||||||
private long? _editedTimestampTicks;
|
private long? _editedTimestampTicks;
|
||||||
|
|
||||||
public bool IsTTS { get; private set; }
|
public bool IsTTS { get; private set; }
|
||||||
public string RawText { get; private set; }
|
|
||||||
public string Text { get; private set; }
|
public string Text { get; private set; }
|
||||||
public bool IsPinned { get; private set; }
|
public bool IsPinned { get; private set; }
|
||||||
|
|
||||||
@@ -111,29 +110,15 @@ namespace Discord
|
|||||||
|
|
||||||
if (model.Content.IsSpecified)
|
if (model.Content.IsSpecified)
|
||||||
{
|
{
|
||||||
RawText = model.Content.Value;
|
var text = model.Content.Value;
|
||||||
|
|
||||||
if (guildChannel != null)
|
if (guildChannel != null)
|
||||||
{
|
{
|
||||||
var orderedMentionedUsers = ImmutableArray.CreateBuilder<IUser>(5);
|
MentionedUsers = MentionUtils.GetUserMentions(text, Channel.IsAttached ? Channel : null, MentionedUsers);
|
||||||
Text = MentionUtils.CleanUserMentions(RawText, Channel.IsAttached ? Channel : null, MentionedUsers, orderedMentionedUsers);
|
MentionedChannelIds = MentionUtils.GetChannelMentions(text, guildChannel.Guild);
|
||||||
MentionedUsers = orderedMentionedUsers.ToImmutable();
|
MentionedRoles = MentionUtils.GetRoleMentions(text, guildChannel.Guild);
|
||||||
|
|
||||||
var roles = ImmutableArray.CreateBuilder<IRole>(5);
|
|
||||||
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
|
Text = text;
|
||||||
Text = RawText;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,17 +153,33 @@ namespace Discord
|
|||||||
else
|
else
|
||||||
await Discord.ApiClient.DeleteDMMessageAsync(Channel.Id, Id).ConfigureAwait(false);
|
await Discord.ApiClient.DeleteDMMessageAsync(Channel.Id, Id).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
/// <summary> Adds this message to its channel's pinned messages. </summary>
|
|
||||||
public async Task PinAsync()
|
public async Task PinAsync()
|
||||||
{
|
{
|
||||||
await Discord.ApiClient.AddPinAsync(Channel.Id, Id).ConfigureAwait(false);
|
await Discord.ApiClient.AddPinAsync(Channel.Id, Id).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
/// <summary> Removes this message from its channel's pinned messages. </summary>
|
|
||||||
public async Task UnpinAsync()
|
public async Task UnpinAsync()
|
||||||
{
|
{
|
||||||
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(Text.Substring(startIndex, length), userMode);
|
||||||
|
public string Resolve(UserResolveMode userMode = UserResolveMode.NameOnly)
|
||||||
|
=> Resolve(Text, userMode);
|
||||||
|
|
||||||
|
private string Resolve(string text, UserResolveMode userMode = UserResolveMode.NameOnly)
|
||||||
|
{
|
||||||
|
var guild = (Channel as IGuildChannel)?.Guild;
|
||||||
|
text = MentionUtils.ResolveUserMentions(text, Channel, MentionedUsers, userMode);
|
||||||
|
if (guild != null)
|
||||||
|
{
|
||||||
|
if (guild.IsAttached) //It's too expensive to do a channel lookup in REST mode
|
||||||
|
text = MentionUtils.ResolveChannelMentions(text, guild);
|
||||||
|
text = MentionUtils.ResolveRoleMentions(text, guild, MentionedRoles);
|
||||||
|
}
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString() => Text;
|
public override string ToString() => Text;
|
||||||
private string DebuggerDisplay => $"{Author}: {Text}{(Attachments.Count > 0 ? $" [{Attachments.Count} Attachments]" : "")}";
|
private string DebuggerDisplay => $"{Author}: {Text}{(Attachments.Count > 0 ? $" [{Attachments.Count} Attachments]" : "")}";
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/Discord.Net/Entities/Messages/UserResolveMode.cs
Normal file
8
src/Discord.Net/Entities/Messages/UserResolveMode.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
public enum UserResolveMode
|
||||||
|
{
|
||||||
|
NameOnly = 0,
|
||||||
|
NameAndDiscriminator
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -65,6 +65,7 @@ namespace Discord
|
|||||||
channelId = 0;
|
channelId = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Parses a provided role mention string. </summary>
|
/// <summary> Parses a provided role mention string. </summary>
|
||||||
public static ulong ParseRole(string mentionText)
|
public static ulong ParseRole(string mentionText)
|
||||||
{
|
{
|
||||||
@@ -88,48 +89,14 @@ namespace Discord
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets the ids of all users mentioned in a provided text.</summary>
|
internal static ImmutableArray<IUser> GetUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> fallbackUsers)
|
||||||
public static ImmutableArray<ulong> GetUserMentions(string text) => GetMentions(text, _userRegex).ToImmutable();
|
|
||||||
/// <summary> Gets the ids of all channels mentioned in a provided text.</summary>
|
|
||||||
public static ImmutableArray<ulong> GetChannelMentions(string text) => GetMentions(text, _channelRegex).ToImmutable();
|
|
||||||
/// <summary> Gets the ids of all roles mentioned in a provided text.</summary>
|
|
||||||
public static ImmutableArray<ulong> GetRoleMentions(string text) => GetMentions(text, _roleRegex).ToImmutable();
|
|
||||||
private static ImmutableArray<ulong>.Builder GetMentions(string text, Regex regex)
|
|
||||||
{
|
{
|
||||||
var matches = regex.Matches(text);
|
var matches = _userRegex.Matches(text);
|
||||||
var builder = ImmutableArray.CreateBuilder<ulong>(matches.Count);
|
var builder = ImmutableArray.CreateBuilder<IUser>(matches.Count);
|
||||||
foreach (var match in matches.OfType<Match>())
|
foreach (var match in matches.OfType<Match>())
|
||||||
{
|
{
|
||||||
ulong id;
|
ulong id;
|
||||||
if (ulong.TryParse(match.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
if (ulong.TryParse(match.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
||||||
builder.Add(id);
|
|
||||||
}
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*internal static string CleanUserMentions(string text, ImmutableArray<User> mentions)
|
|
||||||
{
|
|
||||||
return _userRegex.Replace(text, new MatchEvaluator(e =>
|
|
||||||
{
|
|
||||||
ulong id;
|
|
||||||
if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < mentions.Length; i++)
|
|
||||||
{
|
|
||||||
var mention = mentions[i];
|
|
||||||
if (mention.Id == id)
|
|
||||||
return '@' + mention.Username;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return e.Value;
|
|
||||||
}));
|
|
||||||
}*/
|
|
||||||
internal static string CleanUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> fallbackUsers, ImmutableArray<IUser>.Builder mentions = null)
|
|
||||||
{
|
|
||||||
return _userRegex.Replace(text, new MatchEvaluator(e =>
|
|
||||||
{
|
|
||||||
ulong id;
|
|
||||||
if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
|
||||||
{
|
{
|
||||||
IUser user = null;
|
IUser user = null;
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
@@ -145,54 +112,120 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
builder.Add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.ToImmutable();
|
||||||
|
}
|
||||||
|
internal static ImmutableArray<ulong> GetChannelMentions(string text, IGuild guild)
|
||||||
|
{
|
||||||
|
var matches = _channelRegex.Matches(text);
|
||||||
|
var builder = ImmutableArray.CreateBuilder<ulong>(matches.Count);
|
||||||
|
foreach (var match in matches.OfType<Match>())
|
||||||
|
{
|
||||||
|
ulong id;
|
||||||
|
if (ulong.TryParse(match.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
||||||
|
{
|
||||||
|
/*var channel = guild.GetChannelAsync(id).GetAwaiter().GetResult();
|
||||||
|
if (channel != null)
|
||||||
|
builder.Add(channel);*/
|
||||||
|
builder.Add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.ToImmutable();
|
||||||
|
}
|
||||||
|
internal static ImmutableArray<IRole> GetRoleMentions(string text, IGuild guild)
|
||||||
|
{
|
||||||
|
var matches = _roleRegex.Matches(text);
|
||||||
|
var builder = ImmutableArray.CreateBuilder<IRole>(matches.Count);
|
||||||
|
foreach (var match in matches.OfType<Match>())
|
||||||
|
{
|
||||||
|
ulong id;
|
||||||
|
if (ulong.TryParse(match.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
||||||
|
{
|
||||||
|
var role = guild.GetRole(id);
|
||||||
|
if (role != null)
|
||||||
|
builder.Add(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.ToImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string ResolveUserMentions(string text, IMessageChannel channel, IReadOnlyCollection<IUser> mentions, UserResolveMode mode)
|
||||||
|
{
|
||||||
|
return _userRegex.Replace(text, new MatchEvaluator(e =>
|
||||||
|
{
|
||||||
|
ulong id;
|
||||||
|
if (ulong.TryParse(e.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out id))
|
||||||
|
{
|
||||||
|
IUser user = null;
|
||||||
|
foreach (var mention in mentions)
|
||||||
|
{
|
||||||
|
if (mention.Id == id)
|
||||||
|
{
|
||||||
|
user = mention;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
mentions.Add(user);
|
string name = user.Username;
|
||||||
|
|
||||||
|
var guildUser = user as IGuildUser;
|
||||||
if (e.Value[2] == '!')
|
if (e.Value[2] == '!')
|
||||||
{
|
{
|
||||||
var guildUser = user as IGuildUser;
|
|
||||||
if (guildUser != null && guildUser.Nickname != null)
|
if (guildUser != null && guildUser.Nickname != null)
|
||||||
return '@' + guildUser.Nickname;
|
name = guildUser.Nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case UserResolveMode.NameOnly:
|
||||||
|
default:
|
||||||
|
return $"@{name}";
|
||||||
|
case UserResolveMode.NameAndDiscriminator:
|
||||||
|
return $"@{name}#{user.Discriminator}";
|
||||||
}
|
}
|
||||||
return '@' + user.Username;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
internal static string CleanChannelMentions(string text, IGuild guild, ImmutableArray<ulong>.Builder mentions = null)
|
internal static string ResolveChannelMentions(string text, IGuild guild)
|
||||||
{
|
{
|
||||||
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))
|
||||||
{
|
{
|
||||||
var channel = guild.GetChannelAsync(id).GetAwaiter().GetResult() as IGuildChannel;
|
IGuildChannel channel = null;
|
||||||
|
channel = guild.GetChannelAsync(id).GetAwaiter().GetResult();
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
{
|
|
||||||
if (mentions != null)
|
|
||||||
mentions.Add(channel.Id);
|
|
||||||
return '#' + channel.Name;
|
return '#' + channel.Name;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
internal static string CleanRoleMentions(string text, IGuild guild, ImmutableArray<IRole>.Builder mentions = null)
|
internal static string ResolveRoleMentions(string text, IGuild guild, IReadOnlyCollection<IRole> mentions)
|
||||||
{
|
{
|
||||||
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))
|
||||||
{
|
{
|
||||||
var role = guild.GetRole(id);
|
IRole role = null;
|
||||||
if (role != null)
|
foreach (var mention in mentions)
|
||||||
{
|
{
|
||||||
if (mentions != null)
|
if (mention.Id == id)
|
||||||
mentions.Add(role);
|
{
|
||||||
return '@' + role.Name;
|
role = mention;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (role != null)
|
||||||
|
return '@' + role.Name;
|
||||||
}
|
}
|
||||||
return e.Value;
|
return e.Value;
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user