Browse Source

Restructure and replace emojis with a new emote system (#619)

tags/1.0.0-rc2
Christopher F RogueException 8 years ago
parent
commit
576a52cdc6
18 changed files with 169 additions and 139 deletions
  1. +23
    -0
      src/Discord.Net.Core/Entities/Emotes/Emoji.cs
  2. +63
    -0
      src/Discord.Net.Core/Entities/Emotes/Emote.cs
  3. +5
    -6
      src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs
  4. +13
    -0
      src/Discord.Net.Core/Entities/Emotes/IEmote.cs
  5. +1
    -1
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  6. +0
    -51
      src/Discord.Net.Core/Entities/Messages/Emoji.cs
  7. +1
    -1
      src/Discord.Net.Core/Entities/Messages/IReaction.cs
  8. +3
    -7
      src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
  9. +1
    -1
      src/Discord.Net.Core/Utils/MentionUtils.cs
  10. +8
    -8
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  11. +6
    -11
      src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
  12. +9
    -4
      src/Discord.Net.Rest/Entities/Messages/RestReaction.cs
  13. +6
    -12
      src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
  14. +2
    -2
      src/Discord.Net.Rest/Extensions/EntityExtensions.cs
  15. +5
    -11
      src/Discord.Net.Rpc/Entities/Messages/RpcUserMessage.cs
  16. +9
    -9
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  17. +9
    -4
      src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs
  18. +5
    -11
      src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs

+ 23
- 0
src/Discord.Net.Core/Entities/Emotes/Emoji.cs View File

@@ -0,0 +1,23 @@
namespace Discord
{
/// <summary>
/// A unicode emoji
/// </summary>
public class Emoji : IEmote
{
// TODO: need to constrain this to unicode-only emojis somehow
/// <summary>
/// Creates a unciode emoji.
/// </summary>
/// <param name="unicode">The pure UTF-8 encoding of an emoji</param>
public Emoji(string unicode)
{
Name = unicode;
}

/// <summary>
/// The unicode representation of this emote.
/// </summary>
public string Name { get; }
}
}

+ 63
- 0
src/Discord.Net.Core/Entities/Emotes/Emote.cs View File

@@ -0,0 +1,63 @@
using System;
using System.Globalization;

namespace Discord
{
/// <summary>
/// A custom image-based emote
/// </summary>
public class Emote : IEmote, ISnowflakeEntity
{
/// <summary>
/// The display name (tooltip) of this emote
/// </summary>
public string Name { get; }
/// <summary>
/// The ID of this emote
/// </summary>
public ulong Id { get; }
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
public string Url => CDN.GetEmojiUrl(Id);

internal Emote(ulong id, string name)
{
Id = id;
Name = name;
}

/// <summary>
/// Parse an Emote from its raw format
/// </summary>
/// <param name="text">The raw encoding of an emote; for example, &lt;:dab:277855270321782784&gt;</param>
/// <returns>An emote</returns>
public static Emote Parse(string text)
{
if (TryParse(text, out Emote result))
return result;
throw new ArgumentException("Invalid emote format", nameof(text));
}

public static bool TryParse(string text, out Emote result)
{
result = null;
if (text.Length >= 4 && text[0] == '<' && text[1] == ':' && text[text.Length - 1] == '>')
{
int splitIndex = text.IndexOf(':', 2);
if (splitIndex == -1)
return false;

if (!ulong.TryParse(text.Substring(splitIndex + 1, text.Length - splitIndex - 2), NumberStyles.None, CultureInfo.InvariantCulture, out ulong id))
return false;

string name = text.Substring(2, splitIndex - 2);
result = new Emote(id, name);
return true;
}
return false;

}

private string DebuggerDisplay => $"{Name} ({Id})";
public override string ToString() => Name;
}
}

src/Discord.Net.Core/Entities/Guilds/GuildEmoji.cs → src/Discord.Net.Core/Entities/Emotes/GuildEmote.cs View File

@@ -3,19 +3,18 @@ using System.Diagnostics;


namespace Discord namespace Discord
{ {
/// <summary>
/// An image-based emote that is attached to a guild
/// </summary>
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public struct GuildEmoji
public class GuildEmote : Emote
{ {
public ulong Id { get; }
public string Name { get; }
public bool IsManaged { get; } public bool IsManaged { get; }
public bool RequireColons { get; } public bool RequireColons { get; }
public IReadOnlyList<ulong> RoleIds { get; } public IReadOnlyList<ulong> RoleIds { get; }


internal GuildEmoji(ulong id, string name, bool isManaged, bool requireColons, IReadOnlyList<ulong> roleIds)
internal GuildEmote(ulong id, string name, bool isManaged, bool requireColons, IReadOnlyList<ulong> roleIds) : base(id, name)
{ {
Id = id;
Name = name;
IsManaged = isManaged; IsManaged = isManaged;
RequireColons = requireColons; RequireColons = requireColons;
RoleIds = roleIds; RoleIds = roleIds;

+ 13
- 0
src/Discord.Net.Core/Entities/Emotes/IEmote.cs View File

@@ -0,0 +1,13 @@
namespace Discord
{
/// <summary>
/// A general container for any type of emote in a message.
/// </summary>
public interface IEmote
{
/// <summary>
/// The display name or unicode representation of this emote
/// </summary>
string Name { get; }
}
}

+ 1
- 1
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -45,7 +45,7 @@ namespace Discord
/// <summary> Gets the built-in role containing all users in this guild. </summary> /// <summary> Gets the built-in role containing all users in this guild. </summary>
IRole EveryoneRole { get; } IRole EveryoneRole { get; }
/// <summary> Gets a collection of all custom emojis for this guild. </summary> /// <summary> Gets a collection of all custom emojis for this guild. </summary>
IReadOnlyCollection<GuildEmoji> Emojis { get; }
IReadOnlyCollection<GuildEmote> Emotes { get; }
/// <summary> Gets a collection of all extra features added to this guild. </summary> /// <summary> Gets a collection of all extra features added to this guild. </summary>
IReadOnlyCollection<string> Features { get; } IReadOnlyCollection<string> Features { get; }
/// <summary> Gets a collection of all roles in this guild. </summary> /// <summary> Gets a collection of all roles in this guild. </summary>


+ 0
- 51
src/Discord.Net.Core/Entities/Messages/Emoji.cs View File

@@ -1,51 +0,0 @@
using System;
using System.Diagnostics;
using System.Globalization;

namespace Discord
{
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public struct Emoji
{
public ulong? Id { get; }
public string Name { get; }

public string Url => Id != null ? CDN.GetEmojiUrl(Id.Value) : null;

internal Emoji(ulong? id, string name)
{
Id = id;
Name = name;
}

public static Emoji Parse(string text)
{
if (TryParse(text, out Emoji result))
return result;
throw new ArgumentException("Invalid emoji format", nameof(text));
}

public static bool TryParse(string text, out Emoji result)
{
result = default(Emoji);
if (text.Length >= 4 && text[0] == '<' && text[1] == ':' && text[text.Length - 1] == '>')
{
int splitIndex = text.IndexOf(':', 2);
if (splitIndex == -1)
return false;

if (!ulong.TryParse(text.Substring(splitIndex + 1, text.Length - splitIndex - 2), NumberStyles.None, CultureInfo.InvariantCulture, out ulong id))
return false;

string name = text.Substring(2, splitIndex - 2);
result = new Emoji(id, name);
return true;
}
return false;

}

private string DebuggerDisplay => $"{Name} ({Id})";
public override string ToString() => Name;
}
}

+ 1
- 1
src/Discord.Net.Core/Entities/Messages/IReaction.cs View File

@@ -2,6 +2,6 @@
{ {
public interface IReaction public interface IReaction
{ {
Emoji Emoji { get; }
IEmote Emote { get; }
} }
} }

+ 3
- 7
src/Discord.Net.Core/Entities/Messages/IUserMessage.cs View File

@@ -14,16 +14,12 @@ namespace Discord
Task UnpinAsync(RequestOptions options = null); Task UnpinAsync(RequestOptions options = null);


/// <summary> Returns all reactions included in this message. </summary> /// <summary> Returns all reactions included in this message. </summary>
IReadOnlyDictionary<Emoji, ReactionMetadata> Reactions { get; }
IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions { get; }


/// <summary> Adds a reaction to this message. </summary> /// <summary> Adds a reaction to this message. </summary>
Task AddReactionAsync(Emoji emoji, RequestOptions options = null);
/// <summary> Adds a reaction to this message. </summary>
Task AddReactionAsync(string emoji, RequestOptions options = null);
Task AddReactionAsync(IEmote emote, RequestOptions options = null);
/// <summary> Removes a reaction from message. </summary> /// <summary> Removes a reaction from message. </summary>
Task RemoveReactionAsync(Emoji emoji, IUser user, RequestOptions options = null);
/// <summary> Removes a reaction from this message. </summary>
Task RemoveReactionAsync(string emoji, IUser user, RequestOptions options = null);
Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null);
/// <summary> Removes all reactions from this message. </summary> /// <summary> Removes all reactions from this message. </summary>
Task RemoveAllReactionsAsync(RequestOptions options = null); Task RemoveAllReactionsAsync(RequestOptions options = null);
Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(string emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null); Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(string emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null);


+ 1
- 1
src/Discord.Net.Core/Utils/MentionUtils.cs View File

@@ -252,7 +252,7 @@ namespace Discord
{ {
if (mode != TagHandling.Remove) if (mode != TagHandling.Remove)
{ {
Emoji emoji = (Emoji)tag.Value;
Emote emoji = (Emote)tag.Value;


//Remove if its name contains any bad chars (prevents a few tag exploits) //Remove if its name contains any bad chars (prevents a few tag exploits)
for (int i = 0; i < emoji.Name.Length; i++) for (int i = 0; i < emoji.Name.Length; i++)


+ 8
- 8
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -3,10 +3,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Model = Discord.API.Guild;
using EmbedModel = Discord.API.GuildEmbed; using EmbedModel = Discord.API.GuildEmbed;
using System.Linq;
using Model = Discord.API.Guild;


namespace Discord.Rest namespace Discord.Rest
{ {
@@ -14,7 +14,7 @@ namespace Discord.Rest
public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable public class RestGuild : RestEntity<ulong>, IGuild, IUpdateable
{ {
private ImmutableDictionary<ulong, RestRole> _roles; private ImmutableDictionary<ulong, RestRole> _roles;
private ImmutableArray<GuildEmoji> _emojis;
private ImmutableArray<GuildEmote> _emotes;
private ImmutableArray<string> _features; private ImmutableArray<string> _features;


public string Name { get; private set; } public string Name { get; private set; }
@@ -39,7 +39,7 @@ namespace Discord.Rest


public RestRole EveryoneRole => GetRole(Id); public RestRole EveryoneRole => GetRole(Id);
public IReadOnlyCollection<RestRole> Roles => _roles.ToReadOnlyCollection(); public IReadOnlyCollection<RestRole> Roles => _roles.ToReadOnlyCollection();
public IReadOnlyCollection<GuildEmoji> Emojis => _emojis;
public IReadOnlyCollection<GuildEmote> Emotes => _emotes;
public IReadOnlyCollection<string> Features => _features; public IReadOnlyCollection<string> Features => _features;


internal RestGuild(BaseDiscordClient client, ulong id) internal RestGuild(BaseDiscordClient client, ulong id)
@@ -69,13 +69,13 @@ namespace Discord.Rest


if (model.Emojis != null) if (model.Emojis != null)
{ {
var emojis = ImmutableArray.CreateBuilder<GuildEmoji>(model.Emojis.Length);
var emotes = ImmutableArray.CreateBuilder<GuildEmote>(model.Emojis.Length);
for (int i = 0; i < model.Emojis.Length; i++) for (int i = 0; i < model.Emojis.Length; i++)
emojis.Add(model.Emojis[i].ToEntity());
_emojis = emojis.ToImmutableArray();
emotes.Add(model.Emojis[i].ToEntity());
_emotes = emotes.ToImmutableArray();
} }
else else
_emojis = ImmutableArray.Create<GuildEmoji>();
_emotes = ImmutableArray.Create<GuildEmote>();


if (model.Features != null) if (model.Features != null)
_features = model.Features.ToImmutableArray(); _features = model.Features.ToImmutableArray();


+ 6
- 11
src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs View File

@@ -28,19 +28,14 @@ namespace Discord.Rest
await client.ApiClient.DeleteMessageAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false); await client.ApiClient.DeleteMessageAsync(msg.Channel.Id, msg.Id, options).ConfigureAwait(false);
} }


public static async Task AddReactionAsync(IMessage msg, Emoji emoji, BaseDiscordClient client, RequestOptions options)
=> await AddReactionAsync(msg, $"{emoji.Name}:{emoji.Id}", client, options).ConfigureAwait(false);
public static async Task AddReactionAsync(IMessage msg, string emoji, BaseDiscordClient client, RequestOptions options)
public static async Task AddReactionAsync(IMessage msg, IEmote emote, BaseDiscordClient client, RequestOptions options)
{ {
await client.ApiClient.AddReactionAsync(msg.Channel.Id, msg.Id, emoji, options).ConfigureAwait(false);
await client.ApiClient.AddReactionAsync(msg.Channel.Id, msg.Id, emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name, options).ConfigureAwait(false);
} }


public static async Task RemoveReactionAsync(IMessage msg, IUser user, Emoji emoji, BaseDiscordClient client, RequestOptions options)
=> await RemoveReactionAsync(msg, user, emoji.Id == null ? emoji.Name : $"{emoji.Name}:{emoji.Id}", client, options).ConfigureAwait(false);
public static async Task RemoveReactionAsync(IMessage msg, IUser user, string emoji, BaseDiscordClient client,
RequestOptions options)
public static async Task RemoveReactionAsync(IMessage msg, IUser user, IEmote emote, BaseDiscordClient client, RequestOptions options)
{ {
await client.ApiClient.RemoveReactionAsync(msg.Channel.Id, msg.Id, user.Id, emoji, options).ConfigureAwait(false);
await client.ApiClient.RemoveReactionAsync(msg.Channel.Id, msg.Id, user.Id, emote is Emote e ? $"{e.Name}:{e.Id}" : emote.Name, options).ConfigureAwait(false);
} }


public static async Task RemoveAllReactionsAsync(IMessage msg, BaseDiscordClient client, RequestOptions options) public static async Task RemoveAllReactionsAsync(IMessage msg, BaseDiscordClient client, RequestOptions options)
@@ -109,8 +104,8 @@ namespace Discord.Rest
mentionedRole = guild.GetRole(id); mentionedRole = guild.GetRole(id);
tags.Add(new Tag<IRole>(TagType.RoleMention, index, content.Length, id, mentionedRole)); tags.Add(new Tag<IRole>(TagType.RoleMention, index, content.Length, id, mentionedRole));
} }
else if (Emoji.TryParse(content, out var emoji))
tags.Add(new Tag<Emoji>(TagType.Emoji, index, content.Length, emoji.Id ?? 0, emoji));
else if (Emote.TryParse(content, out var emoji))
tags.Add(new Tag<Emote>(TagType.Emoji, index, content.Length, emoji.Id, emoji));
else //Bad Tag else //Bad Tag
{ {
index = index + 1; index = index + 1;


+ 9
- 4
src/Discord.Net.Rest/Entities/Messages/RestReaction.cs View File

@@ -4,19 +4,24 @@ namespace Discord.Rest
{ {
public class RestReaction : IReaction public class RestReaction : IReaction
{ {
public Emoji Emoji { get; }
public IEmote Emote { get; }
public int Count { get; } public int Count { get; }
public bool Me { get; } public bool Me { get; }


internal RestReaction(Emoji emoji, int count, bool me)
internal RestReaction(IEmote emote, int count, bool me)
{ {
Emoji = emoji;
Emote = emote;
Count = count; Count = count;
Me = me; Me = me;
} }
internal static RestReaction Create(Model model) internal static RestReaction Create(Model model)
{ {
return new RestReaction(new Emoji(model.Emoji.Id, model.Emoji.Name), model.Count, model.Me);
IEmote emote;
if (model.Emoji.Id.HasValue)
emote = new Emote(model.Emoji.Id.Value, model.Emoji.Name);
else
emote = new Emoji(model.Emoji.Name);
return new RestReaction(emote, model.Count, model.Me);
} }
} }
} }

+ 6
- 12
src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs View File

@@ -27,7 +27,7 @@ namespace Discord.Rest
public override IReadOnlyCollection<ulong> MentionedRoleIds => MessageHelper.FilterTagsByKey(TagType.RoleMention, _tags); public override IReadOnlyCollection<ulong> MentionedRoleIds => MessageHelper.FilterTagsByKey(TagType.RoleMention, _tags);
public override IReadOnlyCollection<RestUser> MentionedUsers => MessageHelper.FilterTagsByValue<RestUser>(TagType.UserMention, _tags); public override IReadOnlyCollection<RestUser> MentionedUsers => MessageHelper.FilterTagsByValue<RestUser>(TagType.UserMention, _tags);
public override IReadOnlyCollection<ITag> Tags => _tags; public override IReadOnlyCollection<ITag> Tags => _tags;
public IReadOnlyDictionary<Emoji, ReactionMetadata> Reactions => _reactions.ToDictionary(x => x.Emoji, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me });


internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source)
: base(discord, id, channel, author, source) : base(discord, id, channel, author, source)
@@ -130,21 +130,15 @@ namespace Discord.Rest
Update(model); Update(model);
} }


public Task AddReactionAsync(Emoji emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);
public Task AddReactionAsync(string emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);

public Task RemoveReactionAsync(Emoji emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);
public Task RemoveReactionAsync(string emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);

public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emote, Discord, options);
public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options);
public Task RemoveAllReactionsAsync(RequestOptions options = null) public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options); => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);
public Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(string emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null) public Task<IReadOnlyCollection<IUser>> GetReactionUsersAsync(string emoji, int limit = 100, ulong? afterUserId = null, RequestOptions options = null)
=> MessageHelper.GetReactionUsersAsync(this, emoji, x => { x.Limit = limit; x.AfterUserId = afterUserId.HasValue ? afterUserId.Value : Optional.Create<ulong>(); }, Discord, options);
=> MessageHelper.GetReactionUsersAsync(this, emoji, x => { x.Limit = limit; x.AfterUserId = afterUserId ?? Optional.Create<ulong>(); }, Discord, options);


public Task PinAsync(RequestOptions options = null) public Task PinAsync(RequestOptions options = null)


+ 2
- 2
src/Discord.Net.Rest/Extensions/EntityExtensions.cs View File

@@ -5,9 +5,9 @@ namespace Discord.Rest
{ {
internal static class EntityExtensions internal static class EntityExtensions
{ {
public static GuildEmoji ToEntity(this API.Emoji model)
public static GuildEmote ToEntity(this API.Emoji model)
{ {
return new GuildEmoji(model.Id.Value, model.Name, model.Managed, model.RequireColons, ImmutableArray.Create(model.Roles));
return new GuildEmote(model.Id.Value, model.Name, model.Managed, model.RequireColons, ImmutableArray.Create(model.Roles));
} }


public static Embed ToEntity(this API.Embed model) public static Embed ToEntity(this API.Embed model)


+ 5
- 11
src/Discord.Net.Rpc/Entities/Messages/RpcUserMessage.cs View File

@@ -29,7 +29,7 @@ namespace Discord.Rpc
public override IReadOnlyCollection<ulong> MentionedRoleIds => MessageHelper.FilterTagsByKey(TagType.RoleMention, _tags); public override IReadOnlyCollection<ulong> MentionedRoleIds => MessageHelper.FilterTagsByKey(TagType.RoleMention, _tags);
public override IReadOnlyCollection<ulong> MentionedUserIds => MessageHelper.FilterTagsByKey(TagType.UserMention, _tags); public override IReadOnlyCollection<ulong> MentionedUserIds => MessageHelper.FilterTagsByKey(TagType.UserMention, _tags);
public override IReadOnlyCollection<ITag> Tags => _tags; public override IReadOnlyCollection<ITag> Tags => _tags;
public IReadOnlyDictionary<Emoji, ReactionMetadata> Reactions => ImmutableDictionary.Create<Emoji, ReactionMetadata>();
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => ImmutableDictionary.Create<IEmote, ReactionMetadata>();


internal RpcUserMessage(DiscordRpcClient discord, ulong id, RestVirtualMessageChannel channel, RpcUser author, MessageSource source) internal RpcUserMessage(DiscordRpcClient discord, ulong id, RestVirtualMessageChannel channel, RpcUser author, MessageSource source)
: base(discord, id, channel, author, source) : base(discord, id, channel, author, source)
@@ -102,16 +102,10 @@ namespace Discord.Rpc
public Task ModifyAsync(Action<MessageProperties> func, RequestOptions options) public Task ModifyAsync(Action<MessageProperties> func, RequestOptions options)
=> MessageHelper.ModifyAsync(this, Discord, func, options); => MessageHelper.ModifyAsync(this, Discord, func, options);


public Task AddReactionAsync(Emoji emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);
public Task AddReactionAsync(string emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);

public Task RemoveReactionAsync(Emoji emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);
public Task RemoveReactionAsync(string emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);

public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emote, Discord, options);
public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options);
public Task RemoveAllReactionsAsync(RequestOptions options = null) public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options); => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);


+ 9
- 9
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -30,7 +30,7 @@ namespace Discord.WebSocket
private ConcurrentDictionary<ulong, SocketGuildUser> _members; private ConcurrentDictionary<ulong, SocketGuildUser> _members;
private ConcurrentDictionary<ulong, SocketRole> _roles; private ConcurrentDictionary<ulong, SocketRole> _roles;
private ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; private ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates;
private ImmutableArray<GuildEmoji> _emojis;
private ImmutableArray<GuildEmote> _emotes;
private ImmutableArray<string> _features; private ImmutableArray<string> _features;
private AudioClient _audioClient; private AudioClient _audioClient;


@@ -93,7 +93,7 @@ namespace Discord.WebSocket
return channels.Select(x => state.GetChannel(x) as SocketGuildChannel).Where(x => x != null).ToReadOnlyCollection(channels); return channels.Select(x => state.GetChannel(x) as SocketGuildChannel).Where(x => x != null).ToReadOnlyCollection(channels);
} }
} }
public IReadOnlyCollection<GuildEmoji> Emojis => _emojis;
public IReadOnlyCollection<GuildEmote> Emotes => _emotes;
public IReadOnlyCollection<string> Features => _features; public IReadOnlyCollection<string> Features => _features;
public IReadOnlyCollection<SocketGuildUser> Users => _members.ToReadOnlyCollection(); public IReadOnlyCollection<SocketGuildUser> Users => _members.ToReadOnlyCollection();
public IReadOnlyCollection<SocketRole> Roles => _roles.ToReadOnlyCollection(); public IReadOnlyCollection<SocketRole> Roles => _roles.ToReadOnlyCollection();
@@ -102,7 +102,7 @@ namespace Discord.WebSocket
: base(client, id) : base(client, id)
{ {
_audioLock = new SemaphoreSlim(1, 1); _audioLock = new SemaphoreSlim(1, 1);
_emojis = ImmutableArray.Create<GuildEmoji>();
_emotes = ImmutableArray.Create<GuildEmote>();
_features = ImmutableArray.Create<string>(); _features = ImmutableArray.Create<string>();
} }
internal static SocketGuild Create(DiscordSocketClient discord, ClientState state, ExtendedModel model) internal static SocketGuild Create(DiscordSocketClient discord, ClientState state, ExtendedModel model)
@@ -201,13 +201,13 @@ namespace Discord.WebSocket


if (model.Emojis != null) if (model.Emojis != null)
{ {
var emojis = ImmutableArray.CreateBuilder<GuildEmoji>(model.Emojis.Length);
var emojis = ImmutableArray.CreateBuilder<GuildEmote>(model.Emojis.Length);
for (int i = 0; i < model.Emojis.Length; i++) for (int i = 0; i < model.Emojis.Length; i++)
emojis.Add(model.Emojis[i].ToEntity()); emojis.Add(model.Emojis[i].ToEntity());
_emojis = emojis.ToImmutable();
_emotes = emojis.ToImmutable();
} }
else else
_emojis = ImmutableArray.Create<GuildEmoji>();
_emotes = ImmutableArray.Create<GuildEmote>();


if (model.Features != null) if (model.Features != null)
_features = model.Features.ToImmutableArray(); _features = model.Features.ToImmutableArray();
@@ -253,10 +253,10 @@ namespace Discord.WebSocket


internal void Update(ClientState state, EmojiUpdateModel model) internal void Update(ClientState state, EmojiUpdateModel model)
{ {
var emojis = ImmutableArray.CreateBuilder<GuildEmoji>(model.Emojis.Length);
var emotes = ImmutableArray.CreateBuilder<GuildEmote>(model.Emojis.Length);
for (int i = 0; i < model.Emojis.Length; i++) for (int i = 0; i < model.Emojis.Length; i++)
emojis.Add(model.Emojis[i].ToEntity());
_emojis = emojis.ToImmutable();
emotes.Add(model.Emojis[i].ToEntity());
_emotes = emotes.ToImmutable();
} }


//General //General


+ 9
- 4
src/Discord.Net.WebSocket/Entities/Messages/SocketReaction.cs View File

@@ -9,20 +9,25 @@ namespace Discord.WebSocket
public ulong MessageId { get; } public ulong MessageId { get; }
public Optional<SocketUserMessage> Message { get; } public Optional<SocketUserMessage> Message { get; }
public ISocketMessageChannel Channel { get; } public ISocketMessageChannel Channel { get; }
public Emoji Emoji { get; }
public IEmote Emote { get; }


internal SocketReaction(ISocketMessageChannel channel, ulong messageId, Optional<SocketUserMessage> message, ulong userId, Optional<IUser> user, Emoji emoji)
internal SocketReaction(ISocketMessageChannel channel, ulong messageId, Optional<SocketUserMessage> message, ulong userId, Optional<IUser> user, IEmote emoji)
{ {
Channel = channel; Channel = channel;
MessageId = messageId; MessageId = messageId;
Message = message; Message = message;
UserId = userId; UserId = userId;
User = user; User = user;
Emoji = emoji;
Emote = emoji;
} }
internal static SocketReaction Create(Model model, ISocketMessageChannel channel, Optional<SocketUserMessage> message, Optional<IUser> user) internal static SocketReaction Create(Model model, ISocketMessageChannel channel, Optional<SocketUserMessage> message, Optional<IUser> user)
{ {
return new SocketReaction(channel, model.MessageId, message, model.UserId, user, new Emoji(model.Emoji.Id, model.Emoji.Name));
IEmote emote;
if (model.Emoji.Id.HasValue)
emote = new Emote(model.Emoji.Id.Value, model.Emoji.Name);
else
emote = new Emoji(model.Emoji.Name);
return new SocketReaction(channel, model.MessageId, message, model.UserId, user, emote);
} }
} }
} }

+ 5
- 11
src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs View File

@@ -28,7 +28,7 @@ namespace Discord.WebSocket
public override IReadOnlyCollection<SocketGuildChannel> MentionedChannels => MessageHelper.FilterTagsByValue<SocketGuildChannel>(TagType.ChannelMention, _tags); public override IReadOnlyCollection<SocketGuildChannel> MentionedChannels => MessageHelper.FilterTagsByValue<SocketGuildChannel>(TagType.ChannelMention, _tags);
public override IReadOnlyCollection<SocketRole> MentionedRoles => MessageHelper.FilterTagsByValue<SocketRole>(TagType.RoleMention, _tags); public override IReadOnlyCollection<SocketRole> MentionedRoles => MessageHelper.FilterTagsByValue<SocketRole>(TagType.RoleMention, _tags);
public override IReadOnlyCollection<SocketUser> MentionedUsers => MessageHelper.FilterTagsByValue<SocketUser>(TagType.UserMention, _tags); public override IReadOnlyCollection<SocketUser> MentionedUsers => MessageHelper.FilterTagsByValue<SocketUser>(TagType.UserMention, _tags);
public IReadOnlyDictionary<Emoji, ReactionMetadata> Reactions => _reactions.GroupBy(r => r.Emoji).ToDictionary(x => x.Key, x => new ReactionMetadata { ReactionCount = x.Count(), IsMe = x.Any(y => y.UserId == Discord.CurrentUser.Id) });
public IReadOnlyDictionary<IEmote, ReactionMetadata> Reactions => _reactions.GroupBy(r => r.Emote).ToDictionary(x => x.Key, x => new ReactionMetadata { ReactionCount = x.Count(), IsMe = x.Any(y => y.UserId == Discord.CurrentUser.Id) });


internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source) internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source)
: base(discord, id, channel, author, source) : base(discord, id, channel, author, source)
@@ -124,16 +124,10 @@ namespace Discord.WebSocket
public Task ModifyAsync(Action<MessageProperties> func, RequestOptions options = null) public Task ModifyAsync(Action<MessageProperties> func, RequestOptions options = null)
=> MessageHelper.ModifyAsync(this, Discord, func, options); => MessageHelper.ModifyAsync(this, Discord, func, options);


public Task AddReactionAsync(Emoji emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);
public Task AddReactionAsync(string emoji, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emoji, Discord, options);

public Task RemoveReactionAsync(Emoji emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);
public Task RemoveReactionAsync(string emoji, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emoji, Discord, options);

public Task AddReactionAsync(IEmote emote, RequestOptions options = null)
=> MessageHelper.AddReactionAsync(this, emote, Discord, options);
public Task RemoveReactionAsync(IEmote emote, IUser user, RequestOptions options = null)
=> MessageHelper.RemoveReactionAsync(this, user, emote, Discord, options);
public Task RemoveAllReactionsAsync(RequestOptions options = null) public Task RemoveAllReactionsAsync(RequestOptions options = null)
=> MessageHelper.RemoveAllReactionsAsync(this, Discord, options); => MessageHelper.RemoveAllReactionsAsync(this, Discord, options);




Loading…
Cancel
Save