Moved more presence properties from User to Member. Now caching CurrentMember for each server.
This commit is contained in:
@@ -17,12 +17,18 @@ namespace Discord.Collections
|
|||||||
protected override void OnCreated(Member item)
|
protected override void OnCreated(Member item)
|
||||||
{
|
{
|
||||||
item.Server.AddMember(item.UserId);
|
item.Server.AddMember(item.UserId);
|
||||||
|
item.User.AddServer(item.ServerId);
|
||||||
item.User.AddRef();
|
item.User.AddRef();
|
||||||
|
if (item.UserId == _client.CurrentUserId)
|
||||||
|
item.Server.CurrentMember = item;
|
||||||
}
|
}
|
||||||
protected override void OnRemoved(Member item)
|
protected override void OnRemoved(Member item)
|
||||||
{
|
{
|
||||||
item.Server.RemoveMember(item.UserId);
|
item.Server.RemoveMember(item.UserId);
|
||||||
|
item.User.RemoveServer(item.ServerId);
|
||||||
item.User.RemoveRef();
|
item.User.RemoveRef();
|
||||||
|
if (item.UserId == _client.CurrentUserId)
|
||||||
|
item.Server.CurrentMember = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Member this[string userId, string serverId]
|
internal Member this[string userId, string serverId]
|
||||||
@@ -63,5 +69,20 @@ namespace Discord.Collections
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal Member Find(string username, string discriminator)
|
||||||
|
{
|
||||||
|
if (username == null) throw new ArgumentNullException(nameof(username));
|
||||||
|
if (discriminator == null) throw new ArgumentNullException(nameof(discriminator));
|
||||||
|
|
||||||
|
if (username.StartsWith("@"))
|
||||||
|
username = username.Substring(1);
|
||||||
|
|
||||||
|
return this.Where(x =>
|
||||||
|
string.Equals(x.Name, username, StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
x.Discriminator == discriminator
|
||||||
|
)
|
||||||
|
.FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,26 +15,9 @@ namespace Discord.Collections
|
|||||||
protected override void OnCreated(User item) { }
|
protected override void OnCreated(User item) { }
|
||||||
protected override void OnRemoved(User item) { }
|
protected override void OnRemoved(User item) { }
|
||||||
|
|
||||||
public User this[string id] => Get(id);
|
internal User this[string id] => Get(id);
|
||||||
public User this[string name, string discriminator]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
|
||||||
if (discriminator == null) throw new ArgumentNullException(nameof(discriminator));
|
|
||||||
|
|
||||||
if (name.StartsWith("@"))
|
internal IEnumerable<User> Find(string name)
|
||||||
name = name.Substring(1);
|
|
||||||
|
|
||||||
return this.Where(x =>
|
|
||||||
string.Equals(x.Name, name, StringComparison.OrdinalIgnoreCase) &&
|
|
||||||
x.Discriminator == discriminator
|
|
||||||
)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<User> Find(string name)
|
|
||||||
{
|
{
|
||||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||||
|
|
||||||
|
|||||||
@@ -241,14 +241,14 @@ namespace Discord
|
|||||||
=> SendMessage(channelId, text, new string[0]);
|
=> SendMessage(channelId, text, new string[0]);
|
||||||
/// <summary> Sends a message to the provided channel, mentioning certain users. </summary>
|
/// <summary> Sends a message to the provided channel, mentioning certain users. </summary>
|
||||||
/// <remarks> While not required, it is recommended to include a mention reference in the text (see User.Mention). </remarks>
|
/// <remarks> While not required, it is recommended to include a mention reference in the text (see User.Mention). </remarks>
|
||||||
public Task<Message[]> SendMessage(Channel channel, string text, string[] mentions)
|
public Task<Message[]> SendMessage(string channelId, string text, string[] mentions)
|
||||||
=> SendMessage(channel?.Id, text, mentions);
|
=> SendMessage(_channels[channelId], text, mentions);
|
||||||
/// <summary> Sends a message to the provided channel, mentioning certain users. </summary>
|
/// <summary> Sends a message to the provided channel, mentioning certain users. </summary>
|
||||||
/// <remarks> While not required, it is recommended to include a mention reference in the text (see User.Mention). </remarks>
|
/// <remarks> While not required, it is recommended to include a mention reference in the text (see User.Mention). </remarks>
|
||||||
public async Task<Message[]> SendMessage(string channelId, string text, string[] mentions, bool isTextToSpeech = false)
|
public async Task<Message[]> SendMessage(Channel channel, string text, string[] mentions, bool isTextToSpeech = false)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
if (channelId == null) throw new ArgumentNullException(nameof(channelId));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||||
if (mentions == null) throw new ArgumentNullException(nameof(mentions));
|
if (mentions == null) throw new ArgumentNullException(nameof(mentions));
|
||||||
|
|
||||||
@@ -261,13 +261,14 @@ namespace Discord
|
|||||||
var nonce = GenerateNonce();
|
var nonce = GenerateNonce();
|
||||||
if (_config.UseMessageQueue)
|
if (_config.UseMessageQueue)
|
||||||
{
|
{
|
||||||
var msg = _messages.GetOrAdd("nonce_" + nonce, channelId, _currentUserId);
|
var msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _currentUserId);
|
||||||
|
var currentMember = _members[msg.UserId, channel.ServerId];
|
||||||
msg.Update(new Net.API.Message
|
msg.Update(new Net.API.Message
|
||||||
{
|
{
|
||||||
Content = blockText,
|
Content = blockText,
|
||||||
Timestamp = DateTime.UtcNow,
|
Timestamp = DateTime.UtcNow,
|
||||||
Author = new UserReference { Avatar = _currentUser.AvatarId, Discriminator = _currentUser.Discriminator, Id = _currentUser.Id, Username = _currentUser.Name },
|
Author = new UserReference { Avatar = currentMember.AvatarId, Discriminator = currentMember.Discriminator, Id = _currentUserId, Username = currentMember.Name },
|
||||||
ChannelId = channelId,
|
ChannelId = channel.Id,
|
||||||
IsTextToSpeech = isTextToSpeech
|
IsTextToSpeech = isTextToSpeech
|
||||||
});
|
});
|
||||||
msg.IsQueued = true;
|
msg.IsQueued = true;
|
||||||
@@ -277,8 +278,8 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var model = await _api.SendMessage(channelId, blockText, mentions, nonce, isTextToSpeech).ConfigureAwait(false);
|
var model = await _api.SendMessage(channel.Id, blockText, mentions, nonce, isTextToSpeech).ConfigureAwait(false);
|
||||||
var msg = _messages.GetOrAdd(model.Id, channelId, model.Author.Id);
|
var msg = _messages.GetOrAdd(model.Id, channel.Id, model.Author.Id);
|
||||||
msg.Update(model);
|
msg.Update(model);
|
||||||
RaiseMessageSent(msg);
|
RaiseMessageSent(msg);
|
||||||
}
|
}
|
||||||
@@ -718,7 +719,8 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await _api.ChangeUsername(newName, currentEmail, currentPassword).ConfigureAwait(false);
|
var response = await _api.ChangeUsername(newName, currentEmail, currentPassword).ConfigureAwait(false);
|
||||||
_currentUser.Update(response);
|
foreach (var membership in _currentUser.Memberships)
|
||||||
|
membership.Update(response);
|
||||||
}
|
}
|
||||||
/// <summary> Changes your email to newEmail. </summary>
|
/// <summary> Changes your email to newEmail. </summary>
|
||||||
public async Task ChangeEmail(string newEmail, string currentPassword)
|
public async Task ChangeEmail(string newEmail, string currentPassword)
|
||||||
@@ -731,8 +733,7 @@ namespace Discord
|
|||||||
public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword)
|
public async Task ChangePassword(string newPassword, string currentEmail, string currentPassword)
|
||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await _api.ChangePassword(newPassword, currentEmail, currentPassword).ConfigureAwait(false);
|
await _api.ChangePassword(newPassword, currentEmail, currentPassword).ConfigureAwait(false);
|
||||||
_currentUser.Update(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Changes your avatar. </summary>
|
/// <summary> Changes your avatar. </summary>
|
||||||
@@ -741,7 +742,8 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
CheckReady();
|
CheckReady();
|
||||||
var response = await _api.ChangeAvatar(imageType, bytes, currentEmail, currentPassword).ConfigureAwait(false);
|
var response = await _api.ChangeAvatar(imageType, bytes, currentEmail, currentPassword).ConfigureAwait(false);
|
||||||
_currentUser.Update(response);
|
foreach (var membership in _currentUser.Memberships)
|
||||||
|
membership.Update(response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ namespace Discord
|
|||||||
public User GetUser(string id) => _users[id];
|
public User GetUser(string id) => _users[id];
|
||||||
/// <summary> Returns the user with the specified name and discriminator, or null if none was found. </summary>
|
/// <summary> Returns the user with the specified name and discriminator, or null if none was found. </summary>
|
||||||
/// <remarks> Name formats supported: Name and @Name. Search is case-insensitive. </remarks>
|
/// <remarks> Name formats supported: Name and @Name. Search is case-insensitive. </remarks>
|
||||||
public User GetUser(string name, string discriminator) => _users[name, discriminator];
|
public User GetUser(string name, string discriminator) => _members[name, discriminator]?.User;
|
||||||
/// <summary> Returns all users with the specified name across all servers. </summary>
|
/// <summary> Returns all users with the specified name across all servers. </summary>
|
||||||
/// <remarks> Name formats supported: Name and @Name. Search is case-insensitive. </remarks>
|
/// <remarks> Name formats supported: Name and @Name. Search is case-insensitive. </remarks>
|
||||||
public IEnumerable<User> FindUsers(string name) => _users.Find(name);
|
public IEnumerable<User> FindUsers(string name) => _users.Find(name);
|
||||||
|
|||||||
@@ -353,8 +353,6 @@ namespace Discord
|
|||||||
case "GUILD_MEMBER_ADD":
|
case "GUILD_MEMBER_ADD":
|
||||||
{
|
{
|
||||||
var data = e.Payload.ToObject<Events.GuildMemberAdd>(_serializer);
|
var data = e.Payload.ToObject<Events.GuildMemberAdd>(_serializer);
|
||||||
var user = _users.GetOrAdd(data.User.Id);
|
|
||||||
user.Update(data.User);
|
|
||||||
var member = _members.GetOrAdd(data.User.Id, data.GuildId);
|
var member = _members.GetOrAdd(data.User.Id, data.GuildId);
|
||||||
member.Update(data);
|
member.Update(data);
|
||||||
if (_config.TrackActivity)
|
if (_config.TrackActivity)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Newtonsoft.Json;
|
using Discord.Net.API;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,6 +10,14 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
|
/// <summary> Returns the name of this user on this server. </summary>
|
||||||
|
public string Name { get; internal set; }
|
||||||
|
/// <summary> Returns the unique identifier for this user's current avatar. </summary>
|
||||||
|
public string AvatarId { get; internal set; }
|
||||||
|
/// <summary> Returns the URL to this user's current avatar. </summary>
|
||||||
|
public string AvatarUrl => Endpoints.UserAvatar(UserId, AvatarId);
|
||||||
|
/// <summary> Returns a by-name unique identifier separating this user from others with the same name. </summary>
|
||||||
|
public string Discriminator { get; internal set; }
|
||||||
public DateTime JoinedAt { get; internal set; }
|
public DateTime JoinedAt { get; internal set; }
|
||||||
|
|
||||||
public bool IsMuted { get; internal set; }
|
public bool IsMuted { get; internal set; }
|
||||||
@@ -62,19 +71,30 @@ namespace Discord
|
|||||||
|
|
||||||
public override string ToString() => UserId;
|
public override string ToString() => UserId;
|
||||||
|
|
||||||
internal void Update(Net.API.MemberInfo model)
|
internal void Update(UserReference model)
|
||||||
{
|
{
|
||||||
|
if (model.Avatar != null)
|
||||||
|
AvatarId = model.Avatar;
|
||||||
|
if (model.Discriminator != null)
|
||||||
|
Discriminator = model.Discriminator;
|
||||||
|
if (model.Username != null)
|
||||||
|
Name = model.Username;
|
||||||
|
}
|
||||||
|
internal void Update(MemberInfo model)
|
||||||
|
{
|
||||||
|
if (model.User != null)
|
||||||
|
Update(model.User);
|
||||||
RoleIds = model.Roles;
|
RoleIds = model.Roles;
|
||||||
if (model.JoinedAt.HasValue)
|
if (model.JoinedAt.HasValue)
|
||||||
JoinedAt = model.JoinedAt.Value;
|
JoinedAt = model.JoinedAt.Value;
|
||||||
}
|
}
|
||||||
internal void Update(Net.API.ExtendedMemberInfo model)
|
internal void Update(ExtendedMemberInfo model)
|
||||||
{
|
{
|
||||||
Update(model as Net.API.MemberInfo);
|
Update(model as MemberInfo);
|
||||||
IsDeafened = model.IsDeafened;
|
IsDeafened = model.IsDeafened;
|
||||||
IsMuted = model.IsMuted;
|
IsMuted = model.IsMuted;
|
||||||
}
|
}
|
||||||
internal void Update(Net.API.PresenceMemberInfo model)
|
internal void Update(PresenceMemberInfo model)
|
||||||
{
|
{
|
||||||
if (Status != model.Status)
|
if (Status != model.Status)
|
||||||
{
|
{
|
||||||
@@ -86,7 +106,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
GameId = model.GameId;
|
GameId = model.GameId;
|
||||||
}
|
}
|
||||||
internal void Update(Net.API.VoiceMemberInfo model)
|
internal void Update(VoiceMemberInfo model)
|
||||||
{
|
{
|
||||||
IsDeafened = model.IsDeafened;
|
IsDeafened = model.IsDeafened;
|
||||||
IsMuted = model.IsMuted;
|
IsMuted = model.IsMuted;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ namespace Discord
|
|||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
/// <summary> Returns the name of this channel. </summary>
|
/// <summary> Returns the name of this channel. </summary>
|
||||||
public string Name { get; internal set; }
|
public string Name { get; internal set; }
|
||||||
|
/// <summary> Returns the current logged-in user's data for this server. </summary>
|
||||||
|
public Member CurrentMember { get; internal set; }
|
||||||
|
|
||||||
/// <summary> Returns the amount of time (in seconds) a user must be inactive for until they are automatically moved to the AFK channel (see AFKChannel). </summary>
|
/// <summary> Returns the amount of time (in seconds) a user must be inactive for until they are automatically moved to the AFK channel (see AFKChannel). </summary>
|
||||||
public int AFKTimeout { get; internal set; }
|
public int AFKTimeout { get; internal set; }
|
||||||
@@ -130,9 +132,8 @@ namespace Discord
|
|||||||
var members = _client.Members;
|
var members = _client.Members;
|
||||||
foreach (var subModel in model.Members)
|
foreach (var subModel in model.Members)
|
||||||
{
|
{
|
||||||
var user = users.GetOrAdd(subModel.User.Id);
|
users.GetOrAdd(subModel.User.Id);
|
||||||
var member = members.GetOrAdd(subModel.User.Id, Id);
|
var member = members.GetOrAdd(subModel.User.Id, Id);
|
||||||
user.Update(subModel.User);
|
|
||||||
member.Update(subModel);
|
member.Update(subModel);
|
||||||
}
|
}
|
||||||
foreach (var subModel in model.VoiceStates)
|
foreach (var subModel in model.VoiceStates)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Discord.Net.API;
|
using Discord.Net.API;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -12,18 +13,13 @@ namespace Discord
|
|||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private int _refs;
|
private int _refs;
|
||||||
private DateTime? _lastPrivateActivity;
|
private DateTime? _lastPrivateActivity;
|
||||||
|
private ConcurrentDictionary<string, bool> _servers;
|
||||||
|
|
||||||
/// <summary> Returns the unique identifier for this user. </summary>
|
/// <summary> Returns the unique identifier for this user. </summary>
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
/// <summary> Returns the name of this channel. </summary>
|
/// <summary> Returns the name of this user. </summary>
|
||||||
public string Name { get; internal set; }
|
public string Name => Memberships.Where(x => x.GameId != null).Select(x => x.GameId).FirstOrDefault();
|
||||||
|
|
||||||
/// <summary> Returns the unique identifier for this user's current avatar. </summary>
|
|
||||||
public string AvatarId { get; internal set; }
|
|
||||||
/// <summary> Returns the URL to this user's current avatar. </summary>
|
|
||||||
public string AvatarUrl => Endpoints.UserAvatar(Id, AvatarId);
|
|
||||||
/// <summary> Returns a by-name unique identifier separating this user from others with the same name. </summary>
|
|
||||||
public string Discriminator { get; internal set; }
|
|
||||||
/// <summary> Returns the email for this user. </summary>
|
/// <summary> Returns the email for this user. </summary>
|
||||||
/// <remarks> This field is only ever populated for the current logged in user. </remarks>
|
/// <remarks> This field is only ever populated for the current logged in user. </remarks>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@@ -40,9 +36,11 @@ namespace Discord
|
|||||||
public Channel PrivateChannel => _client.Channels[PrivateChannelId];
|
public Channel PrivateChannel => _client.Channels[PrivateChannelId];
|
||||||
|
|
||||||
/// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary>
|
/// <summary> Returns a collection of all server-specific data for every server this user is a member of. </summary>
|
||||||
public IEnumerable<Member> Memberships => _client.Servers.Where(x => x.HasMember(Id)).Select(x => _client.Members[Id, x?.Id]);
|
public IEnumerable<Member> Memberships => _servers.Select(x => _client.GetMember(x.Key, Id));
|
||||||
/// <summary> Returns a collection of all servers this user is a member of. </summary>
|
/// <summary> Returns a collection of all servers this user is a member of. </summary>
|
||||||
public IEnumerable<Server> Servers => _client.Servers.Where(x => x.HasMember(Id));
|
public IEnumerable<Server> Servers => _servers.Select(x => _client.GetServer(x.Key));
|
||||||
|
/// <summary> Returns a collection of the ids of all servers this user is a member of. </summary>
|
||||||
|
public IEnumerable<string> ServersIds => _servers.Select(x => x.Key);
|
||||||
/// <summary> Returns a collection of all messages this user has sent that are still in cache. </summary>
|
/// <summary> Returns a collection of all messages this user has sent that are still in cache. </summary>
|
||||||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.UserId == Id);
|
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.UserId == Id);
|
||||||
|
|
||||||
@@ -71,17 +69,11 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
Id = id;
|
Id = id;
|
||||||
|
_servers = new ConcurrentDictionary<string, bool>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update(UserReference model)
|
|
||||||
{
|
|
||||||
AvatarId = model.Avatar;
|
|
||||||
Discriminator = model.Discriminator;
|
|
||||||
Name = model.Username;
|
|
||||||
}
|
|
||||||
internal void Update(SelfUserInfo model)
|
internal void Update(SelfUserInfo model)
|
||||||
{
|
{
|
||||||
Update(model as UserReference);
|
|
||||||
Email = model.Email;
|
Email = model.Email;
|
||||||
IsVerified = model.IsVerified;
|
IsVerified = model.IsVerified;
|
||||||
}
|
}
|
||||||
@@ -93,6 +85,16 @@ namespace Discord
|
|||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
|
|
||||||
|
internal void AddServer(string serverId)
|
||||||
|
{
|
||||||
|
_servers.TryAdd(serverId, true);
|
||||||
|
}
|
||||||
|
internal bool RemoveServer(string serverId)
|
||||||
|
{
|
||||||
|
bool ignored;
|
||||||
|
return _servers.TryRemove(serverId, out ignored);
|
||||||
|
}
|
||||||
|
|
||||||
public void AddRef()
|
public void AddRef()
|
||||||
{
|
{
|
||||||
Interlocked.Increment(ref _refs);
|
Interlocked.Increment(ref _refs);
|
||||||
|
|||||||
Reference in New Issue
Block a user