Started rename of member -> user, added server permission resolving, added channel message cache options.
This commit is contained in:
@@ -12,7 +12,7 @@ namespace Discord.Commands
|
|||||||
public int? Permissions { get; }
|
public int? Permissions { get; }
|
||||||
public string[] Args { get; }
|
public string[] Args { get; }
|
||||||
|
|
||||||
public Member Member => Message.Member;
|
public User Member => Message.Member;
|
||||||
public Channel Channel => Message.Channel;
|
public Channel Channel => Message.Channel;
|
||||||
public Server Server => Message.Channel.Server;
|
public Server Server => Message.Channel.Server;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Discord.Commands
|
|||||||
{
|
{
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
private List<Command> _commands;
|
private List<Command> _commands;
|
||||||
private Func<Member, int> _getPermissions;
|
private Func<User, int> _getPermissions;
|
||||||
|
|
||||||
public IEnumerable<Command> Commands => _commands;
|
public IEnumerable<Command> Commands => _commands;
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ namespace Discord.Commands
|
|||||||
public bool RequireCommandCharInPublic { get; set; }
|
public bool RequireCommandCharInPublic { get; set; }
|
||||||
public bool RequireCommandCharInPrivate { get; set; }
|
public bool RequireCommandCharInPrivate { get; set; }
|
||||||
|
|
||||||
public CommandsPlugin(DiscordClient client, Func<Member, int> getPermissions = null)
|
public CommandsPlugin(DiscordClient client, Func<User, int> getPermissions = null)
|
||||||
{
|
{
|
||||||
_client = client;
|
_client = client;
|
||||||
_getPermissions = getPermissions;
|
_getPermissions = getPermissions;
|
||||||
|
|||||||
@@ -208,6 +208,9 @@
|
|||||||
<Compile Include="..\Discord.Net\Helpers\AsyncCollection.cs">
|
<Compile Include="..\Discord.Net\Helpers\AsyncCollection.cs">
|
||||||
<Link>Helpers\AsyncCollection.cs</Link>
|
<Link>Helpers\AsyncCollection.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\Discord.Net\Helpers\BitHelper.cs">
|
||||||
|
<Link>Helpers\BitHelper.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\Discord.Net\Helpers\EpochTime.cs">
|
<Compile Include="..\Discord.Net\Helpers\EpochTime.cs">
|
||||||
<Link>Helpers\EpochTime.cs</Link>
|
<Link>Helpers\EpochTime.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Bans a user from the provided server. </summary>
|
/// <summary> Bans a user from the provided server. </summary>
|
||||||
public Task Ban(Member member)
|
public Task Ban(User member)
|
||||||
{
|
{
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
@@ -42,7 +42,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Unbans a user from the provided server. </summary>
|
/// <summary> Unbans a user from the provided server. </summary>
|
||||||
public async Task Unban(Member member)
|
public async Task Unban(User member)
|
||||||
{
|
{
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
/// <summary> Returns the private channel with the provided user, creating one if it does not currently exist. </summary>
|
||||||
public async Task<Channel> CreatePMChannel(Member member)
|
public async Task<Channel> CreatePMChannel(User member)
|
||||||
{
|
{
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|||||||
@@ -5,36 +5,36 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
internal sealed class Members : AsyncCollection<Member>
|
internal sealed class Members : AsyncCollection<User>
|
||||||
{
|
{
|
||||||
public Members(DiscordClient client, object writerLock)
|
public Members(DiscordClient client, object writerLock)
|
||||||
: base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
|
: base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { }
|
||||||
private string GetKey(string userId, string serverId)
|
private string GetKey(string userId, string serverId)
|
||||||
=> serverId + '_' + userId;
|
=> serverId + '_' + userId;
|
||||||
|
|
||||||
public Member this[string userId, string serverId]
|
public User this[string userId, string serverId]
|
||||||
=> this[GetKey(userId, serverId)];
|
=> this[GetKey(userId, serverId)];
|
||||||
public Member GetOrAdd(string userId, string serverId)
|
public User GetOrAdd(string userId, string serverId)
|
||||||
=> GetOrAdd(GetKey(userId, serverId), () => new Member(_client, userId, serverId));
|
=> GetOrAdd(GetKey(userId, serverId), () => new User(_client, userId, serverId));
|
||||||
public Member TryRemove(string userId, string serverId)
|
public User TryRemove(string userId, string serverId)
|
||||||
=> TryRemove(GetKey(userId, serverId));
|
=> TryRemove(GetKey(userId, serverId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MemberEventArgs : EventArgs
|
public class MemberEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Member Member { get; }
|
public User Member { get; }
|
||||||
public string UserId => Member.Id;
|
public string UserId => Member.Id;
|
||||||
public Server Server => Member.Server;
|
public Server Server => Member.Server;
|
||||||
public string ServerId => Member.ServerId;
|
public string ServerId => Member.ServerId;
|
||||||
|
|
||||||
internal MemberEventArgs(Member member) { Member = member; }
|
internal MemberEventArgs(User member) { Member = member; }
|
||||||
}
|
}
|
||||||
public class MemberChannelEventArgs : MemberEventArgs
|
public class MemberChannelEventArgs : MemberEventArgs
|
||||||
{
|
{
|
||||||
public Channel Channel { get; }
|
public Channel Channel { get; }
|
||||||
public string ChannelId => Channel.Id;
|
public string ChannelId => Channel.Id;
|
||||||
|
|
||||||
internal MemberChannelEventArgs(Member member, Channel channel)
|
internal MemberChannelEventArgs(User member, Channel channel)
|
||||||
: base(member)
|
: base(member)
|
||||||
{
|
{
|
||||||
Channel = channel;
|
Channel = channel;
|
||||||
@@ -44,7 +44,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public bool IsSpeaking { get; }
|
public bool IsSpeaking { get; }
|
||||||
|
|
||||||
internal MemberIsSpeakingEventArgs(Member member, Channel channel, bool isSpeaking)
|
internal MemberIsSpeakingEventArgs(User member, Channel channel, bool isSpeaking)
|
||||||
: base(member, channel)
|
: base(member, channel)
|
||||||
{
|
{
|
||||||
IsSpeaking = isSpeaking;
|
IsSpeaking = isSpeaking;
|
||||||
@@ -54,25 +54,25 @@ namespace Discord
|
|||||||
public partial class DiscordClient
|
public partial class DiscordClient
|
||||||
{
|
{
|
||||||
public event EventHandler<MemberChannelEventArgs> UserIsTyping;
|
public event EventHandler<MemberChannelEventArgs> UserIsTyping;
|
||||||
private void RaiseUserIsTyping(Member member, Channel channel)
|
private void RaiseUserIsTyping(User member, Channel channel)
|
||||||
{
|
{
|
||||||
if (UserIsTyping != null)
|
if (UserIsTyping != null)
|
||||||
RaiseEvent(nameof(UserIsTyping), () => UserIsTyping(this, new MemberChannelEventArgs(member, channel)));
|
RaiseEvent(nameof(UserIsTyping), () => UserIsTyping(this, new MemberChannelEventArgs(member, channel)));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberIsSpeakingEventArgs> UserIsSpeaking;
|
public event EventHandler<MemberIsSpeakingEventArgs> UserIsSpeaking;
|
||||||
private void RaiseUserIsSpeaking(Member member, Channel channel, bool isSpeaking)
|
private void RaiseUserIsSpeaking(User member, Channel channel, bool isSpeaking)
|
||||||
{
|
{
|
||||||
if (UserIsSpeaking != null)
|
if (UserIsSpeaking != null)
|
||||||
RaiseEvent(nameof(UserIsSpeaking), () => UserIsSpeaking(this, new MemberIsSpeakingEventArgs(member, channel, isSpeaking)));
|
RaiseEvent(nameof(UserIsSpeaking), () => UserIsSpeaking(this, new MemberIsSpeakingEventArgs(member, channel, isSpeaking)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Member _currentUser;
|
private User _currentUser;
|
||||||
|
|
||||||
internal Members Members => _members;
|
internal Members Members => _members;
|
||||||
private readonly Members _members;
|
private readonly Members _members;
|
||||||
|
|
||||||
/// <summary> Returns the user with the specified id, along with their server-specific data, or null if none was found. </summary>
|
/// <summary> Returns the user with the specified id, along with their server-specific data, or null if none was found. </summary>
|
||||||
public Member GetMember(Server server, string userId)
|
public User GetMember(Server server, string userId)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
if (userId == null) throw new ArgumentNullException(nameof(userId));
|
||||||
@@ -82,26 +82,26 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
/// <summary> Returns the user with the specified name and discriminator, along withtheir server-specific data, or null if they couldn't be found. </summary>
|
/// <summary> Returns the user with the specified name and discriminator, along withtheir server-specific data, or null if they couldn't be 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 Member GetMember(Server server, string username, string discriminator)
|
public User GetMember(Server server, string username, string discriminator)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
if (username == null) throw new ArgumentNullException(nameof(username));
|
if (username == null) throw new ArgumentNullException(nameof(username));
|
||||||
if (discriminator == null) throw new ArgumentNullException(nameof(discriminator));
|
if (discriminator == null) throw new ArgumentNullException(nameof(discriminator));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
Member member = FindMembers(server, username, discriminator, true).FirstOrDefault();
|
User member = FindMembers(server, username, discriminator, true).FirstOrDefault();
|
||||||
return _members[member?.Id, server.Id];
|
return _members[member?.Id, server.Id];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns all users in with the specified server and name, along with their server-specific data. </summary>
|
/// <summary> Returns all users in with the specified server and name, along with their server-specific data. </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<Member> FindMembers(Server server, string name, string discriminator = null, bool exactMatch = false)
|
public IEnumerable<User> FindMembers(Server server, string name, string discriminator = null, bool exactMatch = false)
|
||||||
{
|
{
|
||||||
if (server == null) throw new ArgumentNullException(nameof(server));
|
if (server == null) throw new ArgumentNullException(nameof(server));
|
||||||
if (name == null) throw new ArgumentNullException(nameof(name));
|
if (name == null) throw new ArgumentNullException(nameof(name));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|
||||||
IEnumerable<Member> query;
|
IEnumerable<User> query;
|
||||||
if (!exactMatch && name.StartsWith("@"))
|
if (!exactMatch && name.StartsWith("@"))
|
||||||
{
|
{
|
||||||
string name2 = name.Substring(1);
|
string name2 = name.Substring(1);
|
||||||
@@ -118,7 +118,7 @@ namespace Discord
|
|||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task EditMember(Member member, bool? mute = null, bool? deaf = null, IEnumerable<Role> roles = null)
|
public Task EditMember(User member, bool? mute = null, bool? deaf = null, IEnumerable<Role> roles = null)
|
||||||
{
|
{
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
CheckReady();
|
CheckReady();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Discord
|
|||||||
public class MessageEventArgs : EventArgs
|
public class MessageEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public Message Message { get; }
|
public Message Message { get; }
|
||||||
public Member Member => Message.Member;
|
public User Member => Message.Member;
|
||||||
public Channel Channel => Message.Channel;
|
public Channel Channel => Message.Channel;
|
||||||
public Server Server => Message.Server;
|
public Server Server => Message.Server;
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ namespace Discord
|
|||||||
return SendMessage(channel, text, false);
|
return SendMessage(channel, text, false);
|
||||||
}
|
}
|
||||||
/// <summary> Sends a private message to the provided user. </summary>
|
/// <summary> Sends a private message to the provided user. </summary>
|
||||||
public async Task<Message> SendPrivateMessage(Member member, string text)
|
public async Task<Message> SendPrivateMessage(User member, string text)
|
||||||
{
|
{
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
if (text == null) throw new ArgumentNullException(nameof(text));
|
if (text == null) throw new ArgumentNullException(nameof(text));
|
||||||
@@ -103,8 +103,11 @@ namespace Discord
|
|||||||
if (Config.UseMessageQueue)
|
if (Config.UseMessageQueue)
|
||||||
{
|
{
|
||||||
var nonce = GenerateNonce();
|
var nonce = GenerateNonce();
|
||||||
msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _userId);
|
if (_messages != null)
|
||||||
var currentUser = msg.Member;
|
msg = _messages.GetOrAdd("nonce_" + nonce, channel.Id, _userId);
|
||||||
|
else
|
||||||
|
msg = new Message(this, "nonce_" + nonce, channel.Id, _userId);
|
||||||
|
var currentUser = msg.Member;
|
||||||
msg.Update(new MessageInfo
|
msg.Update(new MessageInfo
|
||||||
{
|
{
|
||||||
Content = text,
|
Content = text,
|
||||||
@@ -121,7 +124,10 @@ namespace Discord
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var model = await _api.SendMessage(channel.Id, text, userIds, null, isTextToSpeech).ConfigureAwait(false);
|
var model = await _api.SendMessage(channel.Id, text, userIds, null, isTextToSpeech).ConfigureAwait(false);
|
||||||
msg = _messages.GetOrAdd(model.Id, channel.Id, model.Author.Id);
|
if (_messages != null)
|
||||||
|
msg = _messages.GetOrAdd(model.Id, channel.Id, model.Author.Id);
|
||||||
|
else
|
||||||
|
msg = new Message(this, model.Id, channel.Id, _userId);
|
||||||
msg.Update(model);
|
msg.Update(model);
|
||||||
RaiseMessageSent(msg);
|
RaiseMessageSent(msg);
|
||||||
}
|
}
|
||||||
@@ -197,27 +203,29 @@ namespace Discord
|
|||||||
var msgs = await _api.GetMessages(channel.Id, count).ConfigureAwait(false);
|
var msgs = await _api.GetMessages(channel.Id, count).ConfigureAwait(false);
|
||||||
return msgs.Select(x =>
|
return msgs.Select(x =>
|
||||||
{
|
{
|
||||||
Message msg;
|
Message msg = null;
|
||||||
if (cache)
|
if (_messages != null)
|
||||||
msg = _messages.GetOrAdd(x.Id, x.ChannelId, x.Author.Id);
|
|
||||||
else
|
|
||||||
msg = _messages[x.Id] ?? new Message(this, x.Id, x.ChannelId, x.Author.Id);
|
|
||||||
if (msg != null)
|
|
||||||
{
|
{
|
||||||
msg.Update(x);
|
if (cache && _messages != null)
|
||||||
if (Config.TrackActivity)
|
msg = _messages.GetOrAdd(x.Id, x.ChannelId, x.Author.Id);
|
||||||
|
else
|
||||||
|
msg = _messages[x.Id];
|
||||||
|
}
|
||||||
|
if (msg == null)
|
||||||
|
msg = new Message(this, x.Id, x.ChannelId, x.Author.Id);
|
||||||
|
msg.Update(x);
|
||||||
|
if (Config.TrackActivity)
|
||||||
|
{
|
||||||
|
if (!channel.IsPrivate)
|
||||||
{
|
{
|
||||||
if (!channel.IsPrivate)
|
var member = msg.Member;
|
||||||
{
|
if (member != null)
|
||||||
var member = msg.Member;
|
member.UpdateActivity(msg.EditedTimestamp ?? msg.Timestamp);
|
||||||
if (member != null)
|
|
||||||
member.UpdateActivity(msg.EditedTimestamp ?? msg.Timestamp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
})
|
})
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
catch (HttpException) { } //Bad Permissions?
|
catch (HttpException) { } //Bad Permissions?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public partial class DiscordClient
|
public partial class DiscordClient
|
||||||
{
|
{
|
||||||
public Task SetChannelUserPermissions(Channel channel, Member member, ChannelPermissions allow = null, ChannelPermissions deny = null)
|
public Task SetChannelUserPermissions(Channel channel, User member, ChannelPermissions allow = null, ChannelPermissions deny = null)
|
||||||
{
|
{
|
||||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
@@ -15,7 +15,7 @@ namespace Discord
|
|||||||
|
|
||||||
return SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, allow, deny);
|
return SetChannelPermissions(channel, member?.Id, PermissionTarget.Member, allow, deny);
|
||||||
}
|
}
|
||||||
public Task SetChannelUserPermissions(Channel channel, Member member, DualChannelPermissions permissions = null)
|
public Task SetChannelUserPermissions(Channel channel, User member, DualChannelPermissions permissions = null)
|
||||||
{
|
{
|
||||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
@@ -56,11 +56,11 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var oldPerms = channel._permissionOverwrites;
|
var oldPerms = channel.PermissionOverwrites.ToArray();
|
||||||
var newPerms = new Channel.PermissionOverwrite[oldPerms.Length + 1];
|
var newPerms = new Channel.PermissionOverwrite[oldPerms.Length + 1];
|
||||||
Array.Copy(oldPerms, newPerms, oldPerms.Length);
|
Array.Copy(oldPerms, newPerms, oldPerms.Length);
|
||||||
newPerms[oldPerms.Length] = new Channel.PermissionOverwrite(targetType, targetId, allowValue, denyValue);
|
newPerms[oldPerms.Length] = new Channel.PermissionOverwrite(targetType, targetId, allowValue, denyValue);
|
||||||
channel._permissionOverwrites = newPerms;
|
channel.PermissionOverwrites = newPerms;
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ namespace Discord
|
|||||||
await _api.DeleteChannelPermissions(channel.Id, targetId);
|
await _api.DeleteChannelPermissions(channel.Id, targetId);
|
||||||
if (perms != null)
|
if (perms != null)
|
||||||
{
|
{
|
||||||
channel._permissionOverwrites = channel.PermissionOverwrites.Where(x => x.TargetType != targetType || x.TargetId != targetId).ToArray();
|
channel.PermissionOverwrites = channel.PermissionOverwrites.Where(x => x.TargetType != targetType || x.TargetId != targetId).ToArray();
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task RemoveChannelUserPermissions(Channel channel, Member member)
|
public Task RemoveChannelUserPermissions(Channel channel, User member)
|
||||||
{
|
{
|
||||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
if (member == null) throw new ArgumentNullException(nameof(member));
|
if (member == null) throw new ArgumentNullException(nameof(member));
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ namespace Discord
|
|||||||
public partial class DiscordClient
|
public partial class DiscordClient
|
||||||
{
|
{
|
||||||
public event EventHandler<MemberEventArgs> UserAdded;
|
public event EventHandler<MemberEventArgs> UserAdded;
|
||||||
private void RaiseUserAdded(Member member)
|
private void RaiseUserAdded(User member)
|
||||||
{
|
{
|
||||||
if (UserAdded != null)
|
if (UserAdded != null)
|
||||||
RaiseEvent(nameof(UserAdded), () => UserAdded(this, new MemberEventArgs(member)));
|
RaiseEvent(nameof(UserAdded), () => UserAdded(this, new MemberEventArgs(member)));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> UserRemoved;
|
public event EventHandler<MemberEventArgs> UserRemoved;
|
||||||
private void RaiseUserRemoved(Member member)
|
private void RaiseUserRemoved(User member)
|
||||||
{
|
{
|
||||||
if (UserRemoved != null)
|
if (UserRemoved != null)
|
||||||
RaiseEvent(nameof(UserRemoved), () => UserRemoved(this, new MemberEventArgs(member)));
|
RaiseEvent(nameof(UserRemoved), () => UserRemoved(this, new MemberEventArgs(member)));
|
||||||
@@ -35,19 +35,19 @@ namespace Discord
|
|||||||
RaiseEvent(nameof(ProfileUpdated), () => ProfileUpdated(this, EventArgs.Empty));
|
RaiseEvent(nameof(ProfileUpdated), () => ProfileUpdated(this, EventArgs.Empty));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> MemberUpdated;
|
public event EventHandler<MemberEventArgs> MemberUpdated;
|
||||||
private void RaiseMemberUpdated(Member member)
|
private void RaiseMemberUpdated(User member)
|
||||||
{
|
{
|
||||||
if (MemberUpdated != null)
|
if (MemberUpdated != null)
|
||||||
RaiseEvent(nameof(MemberUpdated), () => MemberUpdated(this, new MemberEventArgs(member)));
|
RaiseEvent(nameof(MemberUpdated), () => MemberUpdated(this, new MemberEventArgs(member)));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> UserPresenceUpdated;
|
public event EventHandler<MemberEventArgs> UserPresenceUpdated;
|
||||||
private void RaiseUserPresenceUpdated(Member member)
|
private void RaiseUserPresenceUpdated(User member)
|
||||||
{
|
{
|
||||||
if (UserPresenceUpdated != null)
|
if (UserPresenceUpdated != null)
|
||||||
RaiseEvent(nameof(UserPresenceUpdated), () => UserPresenceUpdated(this, new MemberEventArgs(member)));
|
RaiseEvent(nameof(UserPresenceUpdated), () => UserPresenceUpdated(this, new MemberEventArgs(member)));
|
||||||
}
|
}
|
||||||
public event EventHandler<MemberEventArgs> UserVoiceStateUpdated;
|
public event EventHandler<MemberEventArgs> UserVoiceStateUpdated;
|
||||||
private void RaiseUserVoiceStateUpdated(Member member)
|
private void RaiseUserVoiceStateUpdated(User member)
|
||||||
{
|
{
|
||||||
if (UserVoiceStateUpdated != null)
|
if (UserVoiceStateUpdated != null)
|
||||||
RaiseEvent(nameof(UserVoiceStateUpdated), () => UserVoiceStateUpdated(this, new MemberEventArgs(member)));
|
RaiseEvent(nameof(UserVoiceStateUpdated), () => UserVoiceStateUpdated(this, new MemberEventArgs(member)));
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace Discord
|
|||||||
public DiscordAPIClient API => _api;
|
public DiscordAPIClient API => _api;
|
||||||
|
|
||||||
/// <summary> Returns the current logged-in user. </summary>
|
/// <summary> Returns the current logged-in user. </summary>
|
||||||
public Member CurrentUser => _currentUser;
|
public User CurrentUser => _currentUser;
|
||||||
|
|
||||||
/// <summary> Initializes a new instance of the DiscordClient class. </summary>
|
/// <summary> Initializes a new instance of the DiscordClient class. </summary>
|
||||||
public DiscordClient(DiscordClientConfig config = null)
|
public DiscordClient(DiscordClientConfig config = null)
|
||||||
@@ -495,7 +495,12 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg == null)
|
if (msg == null)
|
||||||
msg = _messages.GetOrAdd(data.Id, data.ChannelId, data.Author.Id);
|
{
|
||||||
|
if (_messages != null)
|
||||||
|
msg = _messages.GetOrAdd(data.Id, data.ChannelId, data.Author.Id);
|
||||||
|
else
|
||||||
|
msg = new Message(this, data.Id, data.ChannelId, data.Author.Id);
|
||||||
|
}
|
||||||
msg.Update(data);
|
msg.Update(data);
|
||||||
if (Config.TrackActivity)
|
if (Config.TrackActivity)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
/// <summary> Gets or sets the time (in milliseconds) to wait when the message queue is empty before checking again. </summary>
|
/// <summary> Gets or sets the time (in milliseconds) to wait when the message queue is empty before checking again. </summary>
|
||||||
public int MessageQueueInterval { get { return _messageQueueInterval; } set { SetValue(ref _messageQueueInterval, value); } }
|
public int MessageQueueInterval { get { return _messageQueueInterval; } set { SetValue(ref _messageQueueInterval, value); } }
|
||||||
private int _messageQueueInterval = 100;
|
private int _messageQueueInterval = 100;
|
||||||
|
/// <summary> Gets or sets the number of messages per channel that should be kept in cache. Setting this to zero disables the message cache entirely. </summary>
|
||||||
|
public int MessageCacheLength { get { return _messageCacheLength; } set { SetValue(ref _messageCacheLength, value); } }
|
||||||
|
private int _messageCacheLength = 100;
|
||||||
|
|
||||||
//Experimental Features
|
//Experimental Features
|
||||||
/// <summary> (Experimental) Enables the client to be simultaneously connected to multiple channels at once (Discord still limits you to one channel per server). </summary>
|
/// <summary> (Experimental) Enables the client to be simultaneously connected to multiple channels at once (Discord still limits you to one channel per server). </summary>
|
||||||
|
|||||||
20
src/Discord.Net/Helpers/BitHelper.cs
Normal file
20
src/Discord.Net/Helpers/BitHelper.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Discord
|
||||||
|
{
|
||||||
|
internal static class BitHelper
|
||||||
|
{
|
||||||
|
public static bool GetBit(uint value, int pos) => ((value >> (byte)pos) & 1U) == 1;
|
||||||
|
public static void SetBit(ref uint value, int pos, bool bitValue)
|
||||||
|
{
|
||||||
|
if (bitValue)
|
||||||
|
value |= (1U << pos);
|
||||||
|
else
|
||||||
|
value &= ~(1U << pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ namespace Discord
|
|||||||
private static readonly Regex _channelRegex = new Regex(@"<#(\d+?)>", RegexOptions.Compiled);
|
private static readonly Regex _channelRegex = new Regex(@"<#(\d+?)>", RegexOptions.Compiled);
|
||||||
|
|
||||||
/// <summary> Returns the string used to create a user mention. </summary>
|
/// <summary> Returns the string used to create a user mention. </summary>
|
||||||
public static string User(Member member)
|
public static string User(User member)
|
||||||
=> $"<@{member.Id}>";
|
=> $"<@{member.Id}>";
|
||||||
/// <summary> Returns the string used to create a channel mention. </summary>
|
/// <summary> Returns the string used to create a channel mention. </summary>
|
||||||
public static string Channel(Channel channel)
|
public static string Channel(Channel channel)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Discord.API;
|
using Discord.API;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -26,14 +25,7 @@ namespace Discord
|
|||||||
Deny.Lock();
|
Deny.Lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, bool> _messages;
|
|
||||||
private bool _areMembersStale;
|
|
||||||
|
|
||||||
private readonly string _serverId, _recipientId;
|
|
||||||
private Server _server;
|
|
||||||
private Member _recipient;
|
|
||||||
|
|
||||||
/// <summary> Returns the name of this channel. </summary>
|
/// <summary> Returns the name of this channel. </summary>
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
/// <summary> Returns the topic associated with this channel. </summary>
|
/// <summary> Returns the topic associated with this channel. </summary>
|
||||||
@@ -47,41 +39,40 @@ namespace Discord
|
|||||||
|
|
||||||
/// <summary> Returns the server containing this channel. </summary>
|
/// <summary> Returns the server containing this channel. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Server Server => _client.Servers[_serverId];
|
public Server Server { get; private set; }
|
||||||
|
private readonly string _serverId;
|
||||||
|
|
||||||
/// For private chats, returns the target user, otherwise null.
|
/// For private chats, returns the target user, otherwise null.
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Member Recipient => _client.Members[_recipientId, _serverId];
|
public User Recipient { get; private set; }
|
||||||
|
private readonly string _recipientId;
|
||||||
/// <summary> Returns a collection of the IDs of all users with read access to this channel. </summary>
|
|
||||||
public IEnumerable<string> UserIds
|
/// <summary> Returns a collection of all users with read access to this channel. </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public IEnumerable<User> Members
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!_areMembersStale)
|
if (!_areMembersStale)
|
||||||
return _userIds;
|
return _members;
|
||||||
|
|
||||||
_userIds = Server.Members.Where(x => x.GetPermissions(this)?.ReadMessages ?? false).Select(x => x.Id).ToArray();
|
_members = Server.Members.Where(x => x.GetPermissions(this)?.ReadMessages ?? false).ToArray();
|
||||||
_areMembersStale = false;
|
_areMembersStale = false;
|
||||||
return _userIds;
|
return _members;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string[] _userIds;
|
private User[] _members;
|
||||||
/// <summary> Returns a collection of all users with read access to this channel. </summary>
|
private bool _areMembersStale;
|
||||||
[JsonIgnore]
|
|
||||||
public IEnumerable<Member> Members => UserIds.Select(x => _client.Members[x, _serverId]);
|
|
||||||
|
|
||||||
/// <summary> Returns a collection of the ids of all messages the client has seen posted in this channel. This collection does not guarantee any ordering. </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
public IEnumerable<string> MessageIds => _messages.Select(x => x.Key);
|
|
||||||
/// <summary> Returns a collection of all messages the client has seen posted in this channel. This collection does not guarantee any ordering. </summary>
|
/// <summary> Returns a collection of all messages the client has seen posted in this channel. This collection does not guarantee any ordering. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Message> Messages => _messages.Select(x => _client.Messages[x.Key]);
|
public IEnumerable<Message> Messages => _messages.Values;
|
||||||
|
private readonly ConcurrentDictionary<string, Message> _messages;
|
||||||
|
|
||||||
/// <summary> Returns a collection of all custom permissions used for this channel. </summary>
|
/// <summary> Returns a collection of all custom permissions used for this channel. </summary>
|
||||||
private static readonly PermissionOverwrite[] _initialPermissionsOverwrites = new PermissionOverwrite[0];
|
private static readonly PermissionOverwrite[] _initialPermissionsOverwrites = new PermissionOverwrite[0];
|
||||||
internal PermissionOverwrite[] _permissionOverwrites;
|
private PermissionOverwrite[] _permissionOverwrites;
|
||||||
public IEnumerable<PermissionOverwrite> PermissionOverwrites => _permissionOverwrites;
|
public IEnumerable<PermissionOverwrite> PermissionOverwrites { get { return _permissionOverwrites; } internal set { _permissionOverwrites = value.ToArray(); } }
|
||||||
|
|
||||||
internal Channel(DiscordClient client, string id, string serverId, string recipientId)
|
internal Channel(DiscordClient client, string id, string serverId, string recipientId)
|
||||||
: base(client, id)
|
: base(client, id)
|
||||||
@@ -92,31 +83,35 @@ namespace Discord
|
|||||||
_areMembersStale = true;
|
_areMembersStale = true;
|
||||||
|
|
||||||
//Local Cache
|
//Local Cache
|
||||||
_messages = new ConcurrentDictionary<string, bool>();
|
_messages = new ConcurrentDictionary<string, Message>();
|
||||||
}
|
}
|
||||||
internal override void OnCached()
|
internal override void OnCached()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (IsPrivate)
|
if (IsPrivate)
|
||||||
{
|
{
|
||||||
_recipient = _client.Members[_recipientId, _serverId];
|
var recipient = _client.Members[_recipientId, _serverId];
|
||||||
Name = "@" + _recipient.Name;
|
Name = "@" + recipient.Name;
|
||||||
|
Recipient = recipient;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_server = _client.Servers[_serverId];
|
var server = _client.Servers[_serverId];
|
||||||
_server.AddChannel(this);
|
server.AddChannel(this);
|
||||||
|
Server = server;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void OnUncached()
|
||||||
{
|
{
|
||||||
if (_server != null)
|
var server = Server;
|
||||||
_server.RemoveChannel(this);
|
if (server != null)
|
||||||
_server = null;
|
server.RemoveChannel(this);
|
||||||
|
Server = null;
|
||||||
|
|
||||||
if (_recipient != null)
|
var recipient = Recipient;
|
||||||
_recipient.GlobalUser.PrivateChannel = null;
|
if (recipient != null)
|
||||||
_recipient = null;
|
recipient.GlobalUser.PrivateChannel = null;
|
||||||
|
Recipient = recipient;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update(ChannelReference model)
|
internal void Update(ChannelReference model)
|
||||||
@@ -146,15 +141,21 @@ namespace Discord
|
|||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
|
|
||||||
internal void AddMessage(string messageId)
|
internal void AddMessage(Message message)
|
||||||
{
|
{
|
||||||
_messages.TryAdd(messageId, true);
|
var cacheLength = _client.Config.MessageCacheLength;
|
||||||
}
|
if (cacheLength > 0)
|
||||||
internal bool RemoveMessage(string messageId)
|
{
|
||||||
{
|
while (_messages.Count > cacheLength - 1)
|
||||||
bool ignored;
|
{
|
||||||
return _messages.TryRemove(messageId, out ignored);
|
var oldest = _messages.Select(x => x.Value.Id).OrderBy(x => x).FirstOrDefault();
|
||||||
|
if (oldest != null)
|
||||||
|
_client.Messages.TryRemove(oldest);
|
||||||
|
}
|
||||||
|
_messages.TryAdd(message.Id, message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
internal void RemoveMessage(Message message) => _messages.TryRemove(message.Id, out message);
|
||||||
|
|
||||||
internal void InvalidMembersCache()
|
internal void InvalidMembersCache()
|
||||||
{
|
{
|
||||||
@@ -164,14 +165,14 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
_areMembersStale = true;
|
_areMembersStale = true;
|
||||||
foreach (var member in Members)
|
foreach (var member in Members)
|
||||||
member.UpdatePermissions(this);
|
member.UpdateChannelPermissions(this);
|
||||||
}
|
}
|
||||||
internal void InvalidatePermissionsCache(string userId)
|
internal void InvalidatePermissionsCache(string userId)
|
||||||
{
|
{
|
||||||
_areMembersStale = true;
|
_areMembersStale = true;
|
||||||
var member = _client.Members[userId, _serverId];
|
var member = _client.Members[userId, _serverId];
|
||||||
if (member != null)
|
if (member != null)
|
||||||
member.UpdatePermissions(this);
|
member.UpdateChannelPermissions(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Discord
|
|||||||
|
|
||||||
/// <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>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Member> Memberships => _servers.Select(x => _client.Members[Id, x.Key]);
|
public IEnumerable<User> Memberships => _servers.Select(x => _client.Members[Id, x.Key]);
|
||||||
/// <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>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Server> Servers => _servers.Select(x => _client.Servers[x.Key]);
|
public IEnumerable<Server> Servers => _servers.Select(x => _client.Servers[x.Key]);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace Discord
|
|||||||
|
|
||||||
/// <summary> Returns the user that created this invite. </summary>
|
/// <summary> Returns the user that created this invite. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Member Inviter => _client.Members[_inviterId, _serverId];
|
public User Inviter => _client.Members[_inviterId, _serverId];
|
||||||
|
|
||||||
/// <summary> Returns the server this invite is to. </summary>
|
/// <summary> Returns the server this invite is to. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ namespace Discord
|
|||||||
public string[] MentionIds { get; private set; }
|
public string[] MentionIds { get; private set; }
|
||||||
/// <summary> Returns a collection of all users mentioned in this message. </summary>
|
/// <summary> Returns a collection of all users mentioned in this message. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Member> Mentions { get; internal set; }
|
public IEnumerable<User> Mentions { get; internal set; }
|
||||||
|
|
||||||
/// <summary> Returns the server containing the channel this message was sent to. </summary>
|
/// <summary> Returns the server containing the channel this message was sent to. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@@ -144,7 +144,7 @@ namespace Discord
|
|||||||
public string UserId { get; }
|
public string UserId { get; }
|
||||||
/// <summary> Returns the author of this message. </summary>
|
/// <summary> Returns the author of this message. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Member Member => _client.Members[_userId, Channel.Server.Id];
|
public User Member => _client.Members[_userId, Channel.Server.Id];
|
||||||
|
|
||||||
internal Message(DiscordClient client, string id, string channelId, string userId)
|
internal Message(DiscordClient client, string id, string channelId, string userId)
|
||||||
: base(client, id)
|
: base(client, id)
|
||||||
@@ -158,14 +158,14 @@ namespace Discord
|
|||||||
internal override void OnCached()
|
internal override void OnCached()
|
||||||
{
|
{
|
||||||
var channel = _client.Channels[_channelId];
|
var channel = _client.Channels[_channelId];
|
||||||
channel.AddMessage(Id);
|
channel.AddMessage(this);
|
||||||
Channel = channel;
|
Channel = channel;
|
||||||
}
|
}
|
||||||
internal override void OnUncached()
|
internal override void OnUncached()
|
||||||
{
|
{
|
||||||
var channel = Channel;
|
var channel = Channel;
|
||||||
if (channel != null)
|
if (channel != null)
|
||||||
channel.RemoveMessage(Id);
|
channel.RemoveMessage(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update(MessageInfo model)
|
internal void Update(MessageInfo model)
|
||||||
|
|||||||
@@ -127,15 +127,9 @@ namespace Discord
|
|||||||
_rawValue = rawValue;
|
_rawValue = rawValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool GetBit(PermissionsBits pos) => ((_rawValue >> (byte)pos) & 1U) == 1;
|
internal bool GetBit(PermissionsBits pos) => BitHelper.GetBit(_rawValue, (int)pos);
|
||||||
internal void SetBit(PermissionsBits pos, bool value) { CheckLock(); SetBitInternal((byte)pos, value); }
|
internal void SetBit(PermissionsBits pos, bool value) { CheckLock(); SetBitInternal((byte)pos, value); }
|
||||||
internal void SetBitInternal(int pos, bool value)
|
internal void SetBitInternal(int pos, bool value) => BitHelper.SetBit(ref _rawValue, pos, value);
|
||||||
{
|
|
||||||
if (value)
|
|
||||||
_rawValue |= (1U << pos);
|
|
||||||
else
|
|
||||||
_rawValue &= ~(1U << pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Lock() => _isLocked = true;
|
internal void Lock() => _isLocked = true;
|
||||||
protected void CheckLock()
|
protected void CheckLock()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace Discord
|
|||||||
public bool IsEveryone => Id == _serverId;
|
public bool IsEveryone => Id == _serverId;
|
||||||
/// <summary> Returns a list of all members in this role. </summary>
|
/// <summary> Returns a list of all members in this role. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Member> Members => IsEveryone ? Server.Members : Server.Members.Where(x => x.HasRole(this));
|
public IEnumerable<User> Members => IsEveryone ? Server.Members : Server.Members.Where(x => x.HasRole(this));
|
||||||
|
|
||||||
internal Role(DiscordClient client, string id, string serverId)
|
internal Role(DiscordClient client, string id, string serverId)
|
||||||
: base(client, id)
|
: base(client, id)
|
||||||
@@ -75,7 +75,7 @@ namespace Discord
|
|||||||
Permissions.SetRawValueInternal(model.Permissions.Value);
|
Permissions.SetRawValueInternal(model.Permissions.Value);
|
||||||
|
|
||||||
foreach (var member in Members)
|
foreach (var member in Members)
|
||||||
member.UpdatePermissions();
|
member.UpdateServerPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
private readonly ConcurrentDictionary<string, bool> _bans;
|
private readonly ConcurrentDictionary<string, bool> _bans;
|
||||||
private readonly ConcurrentDictionary<string, Channel> _channels;
|
private readonly ConcurrentDictionary<string, Channel> _channels;
|
||||||
private readonly ConcurrentDictionary<string, Member> _members;
|
private readonly ConcurrentDictionary<string, User> _members;
|
||||||
private readonly ConcurrentDictionary<string, Role> _roles;
|
private readonly ConcurrentDictionary<string, Role> _roles;
|
||||||
private readonly ConcurrentDictionary<string, Invite> _invites;
|
private readonly ConcurrentDictionary<string, Invite> _invites;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace Discord
|
|||||||
/// <summary> Returns the name of this channel. </summary>
|
/// <summary> Returns the name of this channel. </summary>
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
/// <summary> Returns the current logged-in user's data for this server. </summary>
|
/// <summary> Returns the current logged-in user's data for this server. </summary>
|
||||||
public Member CurrentMember { get; internal set; }
|
public User CurrentMember { get; internal set; }
|
||||||
/// <summary> Returns true if this is a virtual server used by Discord.Net and not a real Discord server. </summary>
|
/// <summary> Returns true if this is a virtual server used by Discord.Net and not a real Discord server. </summary>
|
||||||
public bool IsVirtual { get; internal set; }
|
public bool IsVirtual { get; internal set; }
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ namespace Discord
|
|||||||
public bool IsOwner => _client.CurrentUserId == _ownerId;
|
public bool IsOwner => _client.CurrentUserId == _ownerId;
|
||||||
/// <summary> Returns the user that first created this server. </summary>
|
/// <summary> Returns the user that first created this server. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Member Owner { get; private set; }
|
public User Owner { get; private set; }
|
||||||
|
|
||||||
/// <summary> Returns the id of the AFK voice channel for this server (see AFKTimeout). </summary>
|
/// <summary> Returns the id of the AFK voice channel for this server (see AFKTimeout). </summary>
|
||||||
public string AFKChannelId { get; private set; }
|
public string AFKChannelId { get; private set; }
|
||||||
@@ -71,7 +71,7 @@ namespace Discord
|
|||||||
|
|
||||||
/// <summary> Returns a collection of all users within this server with their server-specific data. </summary>
|
/// <summary> Returns a collection of all users within this server with their server-specific data. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Member> Members => _members.Select(x => _client.Members[x.Key, Id]);
|
public IEnumerable<User> Members => _members.Select(x => _client.Members[x.Key, Id]);
|
||||||
|
|
||||||
/// <summary> Return the id of the role representing all users in a server. </summary>
|
/// <summary> Return the id of the role representing all users in a server. </summary>
|
||||||
public string EveryoneRoleId => Id;
|
public string EveryoneRoleId => Id;
|
||||||
@@ -87,7 +87,7 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
//Global Cache
|
//Global Cache
|
||||||
_channels = new ConcurrentDictionary<string, Channel>();
|
_channels = new ConcurrentDictionary<string, Channel>();
|
||||||
_members = new ConcurrentDictionary<string, Member>();
|
_members = new ConcurrentDictionary<string, User>();
|
||||||
_roles = new ConcurrentDictionary<string, Role>();
|
_roles = new ConcurrentDictionary<string, Role>();
|
||||||
|
|
||||||
//Local Cache
|
//Local Cache
|
||||||
@@ -207,7 +207,7 @@ namespace Discord
|
|||||||
internal void AddInvite(Invite invite) => _invites.TryAdd(invite.Id, invite);
|
internal void AddInvite(Invite invite) => _invites.TryAdd(invite.Id, invite);
|
||||||
internal void RemoveInvite(Invite invite) => _invites.TryRemove(invite.Id, out invite);
|
internal void RemoveInvite(Invite invite) => _invites.TryRemove(invite.Id, out invite);
|
||||||
|
|
||||||
internal void AddMember(Member member)
|
internal void AddMember(User member)
|
||||||
{
|
{
|
||||||
_members.TryAdd(member.Id, member);
|
_members.TryAdd(member.Id, member);
|
||||||
foreach (var channel in Channels)
|
foreach (var channel in Channels)
|
||||||
@@ -216,7 +216,7 @@ namespace Discord
|
|||||||
channel.InvalidatePermissionsCache(member.Id);
|
channel.InvalidatePermissionsCache(member.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal void RemoveMember(Member member)
|
internal void RemoveMember(User member)
|
||||||
{
|
{
|
||||||
foreach (var channel in Channels)
|
foreach (var channel in Channels)
|
||||||
{
|
{
|
||||||
@@ -225,7 +225,7 @@ namespace Discord
|
|||||||
}
|
}
|
||||||
_members.TryRemove(member.Id, out member);
|
_members.TryRemove(member.Id, out member);
|
||||||
}
|
}
|
||||||
internal void HasMember(Member user) => _members.ContainsKey(user.Id);
|
internal void HasMember(User user) => _members.ContainsKey(user.Id);
|
||||||
|
|
||||||
internal void AddRole(Role role) => _roles.TryAdd(role.Id, role);
|
internal void AddRole(Role role) => _roles.TryAdd(role.Id, role);
|
||||||
internal void RemoveRole(Role role) => _roles.TryRemove(role.Id, out role);
|
internal void RemoveRole(Role role) => _roles.TryRemove(role.Id, out role);
|
||||||
|
|||||||
@@ -7,13 +7,14 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
public class Member : CachedObject
|
public class User : CachedObject
|
||||||
{
|
{
|
||||||
private static readonly string[] _initialRoleIds = new string[0];
|
private static readonly string[] _initialRoleIds = new string[0];
|
||||||
|
|
||||||
private ConcurrentDictionary<string, Channel> _channels;
|
private ConcurrentDictionary<string, Channel> _channels;
|
||||||
private ConcurrentDictionary<string, ChannelPermissions> _permissions;
|
private ConcurrentDictionary<string, ChannelPermissions> _permissions;
|
||||||
private bool _hasRef;
|
private ServerPermissions _serverPermissions;
|
||||||
|
private bool _hasRef;
|
||||||
private string[] _roleIds;
|
private string[] _roleIds;
|
||||||
|
|
||||||
/// <summary> Returns the name of this user on this server. </summary>
|
/// <summary> Returns the name of this user on this server. </summary>
|
||||||
@@ -65,9 +66,9 @@ namespace Discord
|
|||||||
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.UserId == Id && x.Server.Id == ServerId);
|
public IEnumerable<Message> Messages => _client.Messages.Where(x => x.UserId == Id && x.Server.Id == ServerId);
|
||||||
/// <summary> Returns a collection of all channels this user is a member of. </summary>
|
/// <summary> Returns a collection of all channels this user is a member of. </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IEnumerable<Channel> Channels => _client.Channels.Where(x => x.Server.Id == ServerId && x.UserIds.Contains(Id));
|
public IEnumerable<Channel> Channels => _client.Channels.Where(x => x.Server.Id == ServerId && x.Members == this);
|
||||||
|
|
||||||
internal Member(DiscordClient client, string id, string serverId)
|
internal User(DiscordClient client, string id, string serverId)
|
||||||
: base(client, id)
|
: base(client, id)
|
||||||
{
|
{
|
||||||
ServerId = serverId;
|
ServerId = serverId;
|
||||||
@@ -75,7 +76,8 @@ namespace Discord
|
|||||||
_roleIds = _initialRoleIds;
|
_roleIds = _initialRoleIds;
|
||||||
_channels = new ConcurrentDictionary<string, Channel>();
|
_channels = new ConcurrentDictionary<string, Channel>();
|
||||||
_permissions = new ConcurrentDictionary<string, ChannelPermissions>();
|
_permissions = new ConcurrentDictionary<string, ChannelPermissions>();
|
||||||
}
|
_serverPermissions = new ServerPermissions();
|
||||||
|
}
|
||||||
internal override void OnCached()
|
internal override void OnCached()
|
||||||
{
|
{
|
||||||
var server = Server;
|
var server = Server;
|
||||||
@@ -133,7 +135,7 @@ namespace Discord
|
|||||||
if (model.Roles != null)
|
if (model.Roles != null)
|
||||||
UpdateRoles(model.Roles);
|
UpdateRoles(model.Roles);
|
||||||
|
|
||||||
UpdatePermissions();
|
UpdateServerPermissions();
|
||||||
}
|
}
|
||||||
internal void Update(ExtendedMemberInfo model)
|
internal void Update(ExtendedMemberInfo model)
|
||||||
{
|
{
|
||||||
@@ -195,35 +197,27 @@ namespace Discord
|
|||||||
if (LastActivityAt == null || activity > LastActivityAt.Value)
|
if (LastActivityAt == null || activity > LastActivityAt.Value)
|
||||||
LastActivityAt = activity ?? DateTime.UtcNow;
|
LastActivityAt = activity ?? DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdatePermissions()
|
internal void UpdateChannelPermissions(Channel channel)
|
||||||
{
|
|
||||||
foreach (var channel in _channels)
|
|
||||||
UpdatePermissions(channel.Value);
|
|
||||||
}
|
|
||||||
internal void UpdatePermissions(Channel channel)
|
|
||||||
{
|
{
|
||||||
if (_roleIds == null) return; // We don't have all our data processed yet, this will be called again soon
|
if (_roleIds == null) return; // We don't have all our data processed yet, this will be called again soon
|
||||||
|
|
||||||
var server = Server;
|
var server = Server;
|
||||||
if (server == null || channel.Server != server) return;
|
if (server == null || channel.Server != server) return;
|
||||||
|
|
||||||
ChannelPermissions permissions;
|
ChannelPermissions permissions;
|
||||||
if (!_permissions.TryGetValue(channel.Id, out permissions)) return;
|
if (!_permissions.TryGetValue(channel.Id, out permissions)) return;
|
||||||
uint newPermissions = 0x0;
|
uint newPermissions = _serverPermissions.RawValue;
|
||||||
uint oldPermissions = permissions.RawValue;
|
uint oldPermissions = permissions.RawValue;
|
||||||
|
|
||||||
if (server.Owner == this)
|
if (server.Owner == this)
|
||||||
newPermissions = ChannelPermissions.All(channel).RawValue;
|
newPermissions = ChannelPermissions.All(channel).RawValue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (channel == null) return;
|
|
||||||
var channelOverwrites = channel.PermissionOverwrites;
|
var channelOverwrites = channel.PermissionOverwrites;
|
||||||
|
|
||||||
//var roles = Roles.OrderBy(x => x.Id);
|
//var roles = Roles.OrderBy(x => x.Id);
|
||||||
var roles = Roles;
|
var roles = Roles;
|
||||||
foreach (var serverRole in roles)
|
|
||||||
newPermissions |= serverRole.Permissions.RawValue;
|
|
||||||
foreach (var denyRole in channelOverwrites.Where(x => x.TargetType == PermissionTarget.Role && x.Deny.RawValue != 0 && roles.Any(y => y.Id == x.TargetId)))
|
foreach (var denyRole in channelOverwrites.Where(x => x.TargetType == PermissionTarget.Role && x.Deny.RawValue != 0 && roles.Any(y => y.Id == x.TargetId)))
|
||||||
newPermissions &= ~denyRole.Deny.RawValue;
|
newPermissions &= ~denyRole.Deny.RawValue;
|
||||||
foreach (var allowRole in channelOverwrites.Where(x => x.TargetType == PermissionTarget.Role && x.Allow.RawValue != 0 && roles.Any(y => y.Id == x.TargetId)))
|
foreach (var allowRole in channelOverwrites.Where(x => x.TargetType == PermissionTarget.Role && x.Allow.RawValue != 0 && roles.Any(y => y.Id == x.TargetId)))
|
||||||
@@ -234,18 +228,49 @@ namespace Discord
|
|||||||
newPermissions |= allowMembers.Allow.RawValue;
|
newPermissions |= allowMembers.Allow.RawValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
permissions.SetRawValueInternal(newPermissions);
|
if (BitHelper.GetBit(newPermissions, (int)PermissionsBits.ManageRolesOrPermissions))
|
||||||
|
newPermissions = ChannelPermissions.All(channel).RawValue;
|
||||||
|
|
||||||
if (permissions.ManagePermissions)
|
if (newPermissions != oldPermissions)
|
||||||
permissions.SetRawValueInternal(ChannelPermissions.All(channel).RawValue);
|
{
|
||||||
/*else if (server.DefaultChannelId == channelId)
|
permissions.SetRawValueInternal(newPermissions);
|
||||||
permissions.SetBitInternal(PackedPermissions.Text_ReadMessagesBit, true);*/
|
|
||||||
|
|
||||||
if (permissions.RawValue != oldPermissions)
|
|
||||||
channel.InvalidMembersCache();
|
channel.InvalidMembersCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions.SetRawValueInternal(newPermissions);
|
||||||
}
|
}
|
||||||
//TODO: Add GetServerPermissions
|
internal void UpdateServerPermissions()
|
||||||
public ChannelPermissions GetPermissions(Channel channel)
|
{
|
||||||
|
if (_roleIds == null) return; // We don't have all our data processed yet, this will be called again soon
|
||||||
|
|
||||||
|
var server = Server;
|
||||||
|
if (server == null) return;
|
||||||
|
|
||||||
|
uint newPermissions = 0x0;
|
||||||
|
uint oldPermissions = _serverPermissions.RawValue;
|
||||||
|
|
||||||
|
if (server.Owner == this)
|
||||||
|
newPermissions = ServerPermissions.All.RawValue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//var roles = Roles.OrderBy(x => x.Id);
|
||||||
|
var roles = Roles;
|
||||||
|
foreach (var serverRole in roles)
|
||||||
|
newPermissions |= serverRole.Permissions.RawValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BitHelper.GetBit(newPermissions, (int)PermissionsBits.ManageRolesOrPermissions))
|
||||||
|
newPermissions = ServerPermissions.All.RawValue;
|
||||||
|
|
||||||
|
if (newPermissions != oldPermissions)
|
||||||
|
{
|
||||||
|
_serverPermissions.SetRawValueInternal(newPermissions);
|
||||||
|
foreach (var channel in _channels)
|
||||||
|
UpdateChannelPermissions(channel.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ServerPermissions GetPermissions() => _serverPermissions;
|
||||||
|
public ChannelPermissions GetPermissions(Channel channel)
|
||||||
{
|
{
|
||||||
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
if (channel == null) throw new ArgumentNullException(nameof(channel));
|
||||||
|
|
||||||
@@ -261,7 +286,7 @@ namespace Discord
|
|||||||
perms.Lock();
|
perms.Lock();
|
||||||
_channels.TryAdd(channel.Id, channel);
|
_channels.TryAdd(channel.Id, channel);
|
||||||
_permissions.TryAdd(channel.Id, perms);
|
_permissions.TryAdd(channel.Id, perms);
|
||||||
UpdatePermissions(channel);
|
UpdateChannelPermissions(channel);
|
||||||
}
|
}
|
||||||
internal void RemoveChannel(Channel channel)
|
internal void RemoveChannel(Channel channel)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user