Added IWebhookUser and MessageSource

This commit is contained in:
RogueException
2017-03-30 23:29:30 -03:00
parent e7401eda68
commit bf0be82d15
32 changed files with 371 additions and 96 deletions

View File

@@ -1045,8 +1045,11 @@ namespace Discord.WebSocket
await _gatewayLogger.DebugAsync("Ignored GUILD_BAN_ADD, guild is not synced yet.").ConfigureAwait(false);
return;
}
await _userBannedEvent.InvokeAsync(SocketSimpleUser.Create(this, State, data.User), guild).ConfigureAwait(false);
SocketUser user = guild.GetUser(data.User.Id);
if (user == null)
user = SocketUnknownUser.Create(this, State, data.User);
await _userBannedEvent.InvokeAsync(user, guild).ConfigureAwait(false);
}
else
{
@@ -1071,7 +1074,7 @@ namespace Discord.WebSocket
SocketUser user = State.GetUser(data.User.Id);
if (user == null)
user = SocketSimpleUser.Create(this, State, data.User);
user = SocketUnknownUser.Create(this, State, data.User);
await _userUnbannedEvent.InvokeAsync(user, guild).ConfigureAwait(false);
}
else
@@ -1098,8 +1101,16 @@ namespace Discord.WebSocket
return;
}
var author = (guild != null ? guild.GetUser(data.Author.Value.Id) : (channel as SocketChannel).GetUser(data.Author.Value.Id)) ??
SocketSimpleUser.Create(this, State, data.Author.Value);
SocketUser author;
if (guild != null)
{
if (data.WebhookId.IsSpecified)
author = SocketWebhookUser.Create(guild, State, data.Author.Value, data.WebhookId.Value);
else
author = guild.GetUser(data.Author.Value.Id);
}
else
author = (channel as SocketChannel).GetUser(data.Author.Value.Id);
if (author != null)
{
@@ -1153,7 +1164,7 @@ namespace Discord.WebSocket
else
author = (channel as SocketChannel).GetUser(data.Author.Value.Id);
if (author == null)
author = SocketSimpleUser.Create(this, State, data.Author.Value);
author = SocketUnknownUser.Create(this, State, data.Author.Value);
after = SocketMessage.Create(this, State, author, channel, data);
}

View File

@@ -14,6 +14,7 @@ namespace Discord.WebSocket
public SocketUser Author { get; }
public ISocketMessageChannel Channel { get; }
public MessageSource Source { get; }
public string Content { get; private set; }
@@ -27,16 +28,15 @@ namespace Discord.WebSocket
public virtual IReadOnlyCollection<SocketRole> MentionedRoles => ImmutableArray.Create<SocketRole>();
public virtual IReadOnlyCollection<SocketUser> MentionedUsers => ImmutableArray.Create<SocketUser>();
public virtual IReadOnlyCollection<ITag> Tags => ImmutableArray.Create<ITag>();
public virtual ulong? WebhookId => null;
public bool IsWebhook => WebhookId != null;
public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks);
internal SocketMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author)
internal SocketMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source)
: base(discord, id)
{
Channel = channel;
Author = author;
Source = source;
}
internal static SocketMessage Create(DiscordSocketClient discord, ClientState state, SocketUser author, ISocketMessageChannel channel, Model model)
{

View File

@@ -9,7 +9,7 @@ namespace Discord.WebSocket
public MessageType Type { get; private set; }
internal SocketSystemMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author)
: base(discord, id, channel, author)
: base(discord, id, channel, author, MessageSource.System)
{
}
internal new static SocketSystemMessage Create(DiscordSocketClient discord, ClientState state, SocketUser author, ISocketMessageChannel channel, Model model)

View File

@@ -14,7 +14,6 @@ namespace Discord.WebSocket
{
private bool _isMentioningEveryone, _isTTS, _isPinned;
private long? _editedTimestampTicks;
private ulong? _webhookId;
private ImmutableArray<Attachment> _attachments;
private ImmutableArray<Embed> _embeds;
private ImmutableArray<ITag> _tags;
@@ -22,7 +21,6 @@ namespace Discord.WebSocket
public override bool IsTTS => _isTTS;
public override bool IsPinned => _isPinned;
public override ulong? WebhookId => _webhookId;
public override DateTimeOffset? EditedTimestamp => DateTimeUtils.FromTicks(_editedTimestampTicks);
public override IReadOnlyCollection<Attachment> Attachments => _attachments;
public override IReadOnlyCollection<Embed> Embeds => _embeds;
@@ -32,13 +30,13 @@ namespace Discord.WebSocket
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) });
internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author)
: base(discord, id, channel, author)
internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source)
: base(discord, id, channel, author, source)
{
}
internal new static SocketUserMessage Create(DiscordSocketClient discord, ClientState state, SocketUser author, ISocketMessageChannel channel, Model model)
internal static new SocketUserMessage Create(DiscordSocketClient discord, ClientState state, SocketUser author, ISocketMessageChannel channel, Model model)
{
var entity = new SocketUserMessage(discord, model.Id, channel, author);
var entity = new SocketUserMessage(discord, model.Id, channel, author, MessageHelper.GetSource(model));
entity.Update(state, model);
return entity;
}
@@ -55,8 +53,6 @@ namespace Discord.WebSocket
_editedTimestampTicks = model.EditedTimestamp.Value?.UtcTicks;
if (model.MentionEveryone.IsSpecified)
_isMentioningEveryone = model.MentionEveryone.Value;
if (model.WebhookId.IsSpecified)
_webhookId = model.WebhookId.Value;
if (model.Attachments.IsSpecified)
{
@@ -86,18 +82,18 @@ namespace Discord.WebSocket
_embeds = ImmutableArray.Create<Embed>();
}
ImmutableArray<IUser> mentions = ImmutableArray.Create<IUser>();
IReadOnlyCollection<IUser> mentions = ImmutableArray.Create<SocketUnknownUser>(); //Is passed to ParseTags to get real mention collection
if (model.UserMentions.IsSpecified)
{
var value = model.UserMentions.Value;
if (value.Length > 0)
{
var newMentions = ImmutableArray.CreateBuilder<IUser>(value.Length);
var newMentions = ImmutableArray.CreateBuilder<SocketUnknownUser>(value.Length);
for (int i = 0; i < value.Length; i++)
{
var val = value[i];
if (val.Object != null)
newMentions.Add(SocketSimpleUser.Create(Discord, Discord.State, val.Object));
newMentions.Add(SocketUnknownUser.Create(Discord, state, val.Object));
}
mentions = newMentions.ToImmutable();
}

View File

@@ -11,10 +11,11 @@ namespace Discord.WebSocket
public override ushort DiscriminatorValue { get; internal set; }
public override string AvatarId { get; internal set; }
public SocketDMChannel DMChannel { get; internal set; }
internal override SocketGlobalUser GlobalUser => this;
internal override SocketPresence Presence { get; set; }
public override bool IsWebhook => false;
internal override SocketGlobalUser GlobalUser => this;
private readonly object _lockObj = new object();
private ushort _references;

View File

@@ -15,6 +15,8 @@ namespace Discord.WebSocket
public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } }
internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } }
public override bool IsWebhook => false;
internal SocketGroupUser(SocketGroupChannel channel, SocketGlobalUser globalUser)
: base(channel.Discord, globalUser.Id)
{

View File

@@ -28,6 +28,7 @@ namespace Discord.WebSocket
public GuildPermissions GuildPermissions => new GuildPermissions(Permissions.ResolveGuild(Guild, this));
internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } }
public override bool IsWebhook => false;
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;

View File

@@ -20,6 +20,8 @@ namespace Discord.WebSocket
public override string AvatarId { get { return GlobalUser.AvatarId; } internal set { GlobalUser.AvatarId = value; } }
internal override SocketPresence Presence { get { return GlobalUser.Presence; } set { GlobalUser.Presence = value; } }
public override bool IsWebhook => false;
internal SocketSelfUser(DiscordSocketClient discord, SocketGlobalUser globalUser)
: base(discord, globalUser.Id)
{

View File

@@ -6,23 +6,25 @@ using PresenceModel = Discord.API.Presence;
namespace Discord.WebSocket
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketSimpleUser : SocketUser
public class SocketUnknownUser : SocketUser
{
public override bool IsBot { get; internal set; }
public override string Username { get; internal set; }
public override ushort DiscriminatorValue { get; internal set; }
public override string AvatarId { get; internal set; }
public override bool IsBot { get; internal set; }
public override bool IsWebhook => false;
internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null); } set { } }
internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } }
internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } }
internal SocketSimpleUser(DiscordSocketClient discord, ulong id)
internal SocketUnknownUser(DiscordSocketClient discord, ulong id)
: base(discord, id)
{
}
internal static SocketSimpleUser Create(DiscordSocketClient discord, ClientState state, Model model)
internal static SocketUnknownUser Create(DiscordSocketClient discord, ClientState state, Model model)
{
var entity = new SocketSimpleUser(discord, model.Id);
var entity = new SocketUnknownUser(discord, model.Id);
entity.Update(state, model);
return entity;
}
@@ -39,6 +41,6 @@ namespace Discord.WebSocket
Username = model.User.Username.Value;
}
internal new SocketSimpleUser Clone() => MemberwiseClone() as SocketSimpleUser;
internal new SocketUnknownUser Clone() => MemberwiseClone() as SocketUnknownUser;
}
}

View File

@@ -12,11 +12,10 @@ namespace Discord.WebSocket
public abstract string Username { get; internal set; }
public abstract ushort DiscriminatorValue { get; internal set; }
public abstract string AvatarId { get; internal set; }
public abstract bool IsWebhook { get; }
internal abstract SocketGlobalUser GlobalUser { get; }
internal abstract SocketPresence Presence { get; set; }
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
public DateTimeOffset CreatedAt => DateTimeUtils.FromSnowflake(Id);
public string Discriminator => DiscriminatorValue.ToString("D4");
public string Mention => MentionUtils.MentionUser(Id);
@@ -47,6 +46,9 @@ namespace Discord.WebSocket
public Task<RestDMChannel> CreateDMChannelAsync(RequestOptions options = null)
=> UserHelper.CreateDMChannelAsync(this, Discord, options);
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
public override string ToString() => $"{Username}#{Discriminator}";
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")})";
internal SocketUser Clone() => MemberwiseClone() as SocketUser;

View File

@@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Threading.Tasks;
using Model = Discord.API.User;
using PresenceModel = Discord.API.Presence;
namespace Discord.WebSocket
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketWebhookUser : SocketUser, IWebhookUser
{
public SocketGuild Guild { get; }
public ulong WebhookId { get; }
public override string Username { get; internal set; }
public override ushort DiscriminatorValue { get; internal set; }
public override string AvatarId { get; internal set; }
public override bool IsBot { get; internal set; }
public override bool IsWebhook => true;
internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null); } set { } }
internal override SocketGlobalUser GlobalUser { get { throw new NotSupportedException(); } }
internal SocketWebhookUser(SocketGuild guild, ulong id, ulong webhookId)
: base(guild.Discord, id)
{
WebhookId = webhookId;
}
internal static SocketWebhookUser Create(SocketGuild guild, ClientState state, Model model, ulong webhookId)
{
var entity = new SocketWebhookUser(guild, model.Id, webhookId);
entity.Update(state, model);
return entity;
}
internal override void Update(ClientState state, PresenceModel model)
{
if (model.User.Avatar.IsSpecified)
AvatarId = model.User.Avatar.Value;
if (model.User.Discriminator.IsSpecified)
DiscriminatorValue = ushort.Parse(model.User.Discriminator.Value);
if (model.User.Bot.IsSpecified)
IsBot = model.User.Bot.Value;
if (model.User.Username.IsSpecified)
Username = model.User.Username.Value;
}
internal new SocketWebhookUser Clone() => MemberwiseClone() as SocketWebhookUser;
//IGuildUser
IGuild IGuildUser.Guild => Guild;
ulong IGuildUser.GuildId => Guild.Id;
IReadOnlyCollection<ulong> IGuildUser.RoleIds => ImmutableArray.Create<ulong>();
DateTimeOffset? IGuildUser.JoinedAt => null;
string IGuildUser.Nickname => null;
GuildPermissions IGuildUser.GuildPermissions => GuildPermissions.Webhook;
ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) => Permissions.ToChannelPerms(channel, GuildPermissions.Webhook.RawValue);
Task IGuildUser.KickAsync(RequestOptions options)
{
throw new NotSupportedException("Webhook users cannot be kicked.");
}
Task IGuildUser.ModifyAsync(Action<GuildUserProperties> func, RequestOptions options)
{
throw new NotSupportedException("Webhook users cannot be modified.");
}
Task IGuildUser.AddRoleAsync(IRole role, RequestOptions options)
{
throw new NotSupportedException("Roles are not supported on webhook users.");
}
Task IGuildUser.AddRolesAsync(IEnumerable<IRole> roles, RequestOptions options)
{
throw new NotSupportedException("Roles are not supported on webhook users.");
}
Task IGuildUser.RemoveRoleAsync(IRole role, RequestOptions options)
{
throw new NotSupportedException("Roles are not supported on webhook users.");
}
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options)
{
throw new NotSupportedException("Roles are not supported on webhook users.");
}
//IVoiceState
bool IVoiceState.IsDeafened => false;
bool IVoiceState.IsMuted => false;
bool IVoiceState.IsSelfDeafened => false;
bool IVoiceState.IsSelfMuted => false;
bool IVoiceState.IsSuppressed => false;
IVoiceChannel IVoiceState.VoiceChannel => null;
string IVoiceState.VoiceSessionId => null;
}
}