diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 960a597f9..954c2e920 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -235,6 +235,9 @@ Models\Channel.cs + + Models\Color.cs + Models\Invite.cs @@ -244,11 +247,8 @@ Models\Message.cs - - Models\PackedColor.cs - - - Models\PackedPermissions.cs + + Models\Permissions.cs Models\Role.cs diff --git a/src/Discord.Net/DiscordClient.Permissions.cs b/src/Discord.Net/DiscordClient.Permissions.cs index 9727c04df..32052e900 100644 --- a/src/Discord.Net/DiscordClient.Permissions.cs +++ b/src/Discord.Net/DiscordClient.Permissions.cs @@ -8,29 +8,29 @@ namespace Discord { public partial class DiscordClient { - public Task SetChannelUserPermissions(Channel channel, Member member, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(Channel channel, Member member, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(channel, member?.UserId, PermissionTarget.Member, allow, deny); - public Task SetChannelUserPermissions(string channelId, Member member, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(string channelId, Member member, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(_channels[channelId], member?.UserId, PermissionTarget.Member, allow, deny); - public Task SetChannelUserPermissions(Channel channel, User user, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(Channel channel, User user, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(channel, user?.Id, PermissionTarget.Member, allow, deny); - public Task SetChannelUserPermissions(string channelId, User user, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(string channelId, User user, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(_channels[channelId], user?.Id, PermissionTarget.Member, allow, deny); - public Task SetChannelUserPermissions(Channel channel, string userId, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(Channel channel, string userId, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(channel, userId, PermissionTarget.Member, allow, deny); - public Task SetChannelUserPermissions(string channelId, string userId, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelUserPermissions(string channelId, string userId, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(_channels[channelId], userId, PermissionTarget.Member, allow, deny); - public Task SetChannelRolePermissions(Channel channel, Role role, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelRolePermissions(Channel channel, Role role, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(channel, role?.Id, PermissionTarget.Role, allow, deny); - public Task SetChannelRolePermissions(string channelId, Role role, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelRolePermissions(string channelId, Role role, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(_channels[channelId], role?.Id, PermissionTarget.Role, allow, deny); - public Task SetChannelRolePermissions(Channel channel, string userId, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelRolePermissions(Channel channel, string userId, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(channel, userId, PermissionTarget.Role, allow, deny); - public Task SetChannelRolePermissions(string channelId, string userId, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + public Task SetChannelRolePermissions(string channelId, string userId, ChannelPermissions allow = null, ChannelPermissions deny = null) => SetChannelPermissions(_channels[channelId], userId, PermissionTarget.Role, allow, deny); - private async Task SetChannelPermissions(Channel channel, string targetId, string targetType, PackedChannelPermissions allow = null, PackedChannelPermissions deny = null) + private async Task SetChannelPermissions(Channel channel, string targetId, string targetType, ChannelPermissions allow = null, ChannelPermissions deny = null) { CheckReady(); if (channel == null) throw new ArgumentNullException(nameof(channel)); diff --git a/src/Discord.Net/DiscordClient.Roles.cs b/src/Discord.Net/DiscordClient.Roles.cs index 7065b02c9..eb431c788 100644 --- a/src/Discord.Net/DiscordClient.Roles.cs +++ b/src/Discord.Net/DiscordClient.Roles.cs @@ -91,9 +91,9 @@ namespace Discord return role; } - public Task EditRole(string roleId, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null, int? position = null) + public Task EditRole(string roleId, string name = null, ServerPermissions permissions = null, Color color = null, bool? hoist = null, int? position = null) => EditRole(_roles[roleId], name: name, permissions: permissions, color: color, hoist: hoist, position: position); - public async Task EditRole(Role role, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null, int? position = null) + public async Task EditRole(Role role, string name = null, ServerPermissions permissions = null, Color color = null, bool? hoist = null, int? position = null) { CheckReady(); if (role == null) throw new ArgumentNullException(nameof(role)); diff --git a/src/Discord.Net/DiscordClient.Servers.cs b/src/Discord.Net/DiscordClient.Servers.cs index 5b21be955..45a0465b4 100644 --- a/src/Discord.Net/DiscordClient.Servers.cs +++ b/src/Discord.Net/DiscordClient.Servers.cs @@ -8,8 +8,17 @@ namespace Discord { internal sealed class Servers : AsyncCollection { + private const string PMServerId = "Private"; + + Server PMServer { get; } + public Servers(DiscordClient client, object writerLock) - : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) { } + : base(client, writerLock, x => x.OnCached(), x => x.OnUncached()) + { + PMServer = new Server(client, PMServerId) { IsVirtual = true }; + PMServer.Update(new API.ExtendedGuildInfo { Id = PMServerId, Name = PMServerId }); + _dictionary[PMServerId] = PMServer; + } public Server GetOrAdd(string id) => GetOrAdd(id, () => new Server(_client, id)); @@ -57,10 +66,12 @@ namespace Discord } /// Returns a collection of all servers this client is a member of. - public IEnumerable AllServers => _servers; + public IEnumerable AllServers => _servers.Where(x => !x.IsVirtual); internal Servers Servers => _servers; private readonly Servers _servers; + public Server PMServer { get; } + /// Returns the server with the specified id, or null if none was found. public Server GetServer(string id) => _servers[id]; diff --git a/src/Discord.Net/Models/Channel.cs b/src/Discord.Net/Models/Channel.cs index 0b6a2bf07..78593d623 100644 --- a/src/Discord.Net/Models/Channel.cs +++ b/src/Discord.Net/Models/Channel.cs @@ -13,15 +13,15 @@ namespace Discord { public string TargetType { get; } public string TargetId { get; } - public PackedChannelPermissions Allow { get; } - public PackedChannelPermissions Deny { get; } + public ChannelPermissions Allow { get; } + public ChannelPermissions Deny { get; } internal PermissionOverwrite(string type, string targetId, uint allow, uint deny) { TargetType = type; TargetId = targetId; - Allow = new PackedChannelPermissions(allow); - Deny = new PackedChannelPermissions( deny); + Allow = new ChannelPermissions(allow); + Deny = new ChannelPermissions( deny); Allow.Lock(); Deny.Lock(); } diff --git a/src/Discord.Net/Models/Color.cs b/src/Discord.Net/Models/Color.cs new file mode 100644 index 000000000..5b5972d48 --- /dev/null +++ b/src/Discord.Net/Models/Color.cs @@ -0,0 +1,81 @@ +using System; + +namespace Discord +{ + public class Color + { + public static readonly Color Default = PresetColor(0); + + public static readonly Color Cyan = PresetColor(0x1abc9c); + public static readonly Color DarkCyan = PresetColor(0x11806a); + public static readonly Color Green = PresetColor(0x2ecc71); + public static readonly Color DarkGreen = PresetColor(0x1f8b4c); + public static readonly Color Blue = PresetColor(0x3498db); + public static readonly Color DarkBlue = PresetColor(0x206694); + public static readonly Color Purple = PresetColor(0x9b59b6); + public static readonly Color DarkPurple = PresetColor(0x71368a); + public static readonly Color Red = PresetColor(0xe74c3c); + public static readonly Color DarkRed = PresetColor(0x992d22); + public static readonly Color Orange = PresetColor(0xe67e22); + public static readonly Color DarkOrange = PresetColor(0xa84300); + public static readonly Color Navy = PresetColor(0x34495e); + public static readonly Color DarkNavy = PresetColor(0x2c3e50); + public static readonly Color Gold = PresetColor(0xf1c40f); + public static readonly Color DarkGold = PresetColor(0xc27c0e); + + public static readonly Color LighterGrey = PresetColor(0xbcc0c0); + public static readonly Color LightGrey = PresetColor(0x95a5a6); + public static readonly Color DarkGrey = PresetColor(0x979c9f); + public static readonly Color DarkerGrey = PresetColor(0x7f8c8d); + + + private static Color PresetColor(uint packedValue) + { + Color color = new Color(packedValue); + color.Lock(); + return color; + } + + private bool _isLocked; + private uint _rawValue; + public uint RawValue + { + get { return _rawValue; } + set + { + if (_isLocked) + throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy."); + _rawValue = value; + } + } + + public Color(uint rawValue) { _rawValue = rawValue; } + public Color(byte r, byte g, byte b) : this(((uint)r << 16) | ((uint)g << 8) | b) { } + public Color(float r, float g, float b) : this((byte)(r * 255.0f), (byte)(g * 255.0f), (byte)(b * 255.0f)) { } + + /// Gets or sets the red component for this color. + public byte R { get { return GetByte(3); } set { SetByte(3, value); } } + /// Gets or sets the green component for this color. + public byte G { get { return GetByte(2); } set { SetByte(2, value); } } + /// Gets or sets the blue component for this color. + public byte B { get { return GetByte(1); } set { SetByte(1, value); } } + + internal void Lock() => _isLocked = true; + internal void SetRawValue(uint rawValue) + { + //Bypasses isLocked for API changes. + _rawValue = rawValue; + } + protected byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF); + protected void SetByte(int pos, byte value) + { + if (_isLocked) + throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy."); + + uint original = _rawValue; + int bit = 8 * (pos - 1); + uint mask = (uint)~(0xFF << bit); + _rawValue = (_rawValue & mask) | ((uint)value << bit); + } + } +} diff --git a/src/Discord.Net/Models/Member.cs b/src/Discord.Net/Models/Member.cs index 3012de7d9..1e14a675e 100644 --- a/src/Discord.Net/Models/Member.cs +++ b/src/Discord.Net/Models/Member.cs @@ -10,7 +10,7 @@ namespace Discord public class Member { private readonly DiscordClient _client; - private ConcurrentDictionary _permissions; + private ConcurrentDictionary _permissions; private bool _hasRef; /// Returns the name of this user on this server. @@ -76,7 +76,7 @@ namespace Discord ServerId = serverId; Status = UserStatus.Offline; RoleIds = _initialRoleIds; - _permissions = new ConcurrentDictionary(); + _permissions = new ConcurrentDictionary(); } internal void OnCached() { @@ -210,13 +210,13 @@ namespace Discord if (server == null) return; var channel = _client.Channels[channelId]; - PackedChannelPermissions permissions; + ChannelPermissions permissions; if (!_permissions.TryGetValue(channelId, out permissions)) return; uint newPermissions = 0x0; uint oldPermissions = permissions.RawValue; if (UserId == server.OwnerId) - newPermissions = PackedChannelPermissions.All.RawValue; + newPermissions = ChannelPermissions.All.RawValue; else { if (channel == null) return; @@ -239,7 +239,7 @@ namespace Discord permissions.SetRawValueInternal(newPermissions); if (permissions.General_ManagePermissions) - permissions.SetRawValueInternal(PackedChannelPermissions.All.RawValue); + permissions.SetRawValueInternal(ChannelPermissions.All.RawValue); /*else if (server.DefaultChannelId == channelId) permissions.SetBitInternal(PackedPermissions.Text_ReadMessagesBit, true);*/ @@ -247,13 +247,13 @@ namespace Discord channel.InvalidMembersCache(); } //TODO: Add GetServerPermissions - public PackedChannelPermissions GetPermissions(Channel channel) + public ChannelPermissions GetPermissions(Channel channel) => GetPermissions(channel?.Id); - public PackedChannelPermissions GetPermissions(string channelId) + public ChannelPermissions GetPermissions(string channelId) { if (channelId == null) throw new ArgumentNullException(nameof(channelId)); - PackedChannelPermissions perms; + ChannelPermissions perms; if (_permissions.TryGetValue(channelId, out perms)) return perms; return null; @@ -261,14 +261,14 @@ namespace Discord internal void AddChannel(string channelId) { - var perms = new PackedChannelPermissions(); + var perms = new ChannelPermissions(); perms.Lock(); _permissions.TryAdd(channelId, perms); UpdatePermissions(channelId); } internal bool RemoveChannel(string channelId) { - PackedChannelPermissions ignored; + ChannelPermissions ignored; return _permissions.TryRemove(channelId, out ignored); } diff --git a/src/Discord.Net/Models/PackedColor.cs b/src/Discord.Net/Models/PackedColor.cs deleted file mode 100644 index b94cb7548..000000000 --- a/src/Discord.Net/Models/PackedColor.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; - -namespace Discord -{ - public class PackedColor - { - public static readonly PackedColor Default = PresetColor(0); - - public static readonly PackedColor Cyan = PresetColor(0x1abc9c); - public static readonly PackedColor DarkCyan = PresetColor(0x11806a); - public static readonly PackedColor Green = PresetColor(0x2ecc71); - public static readonly PackedColor DarkGreen = PresetColor(0x1f8b4c); - public static readonly PackedColor Blue = PresetColor(0x3498db); - public static readonly PackedColor DarkBlue = PresetColor(0x206694); - public static readonly PackedColor Purple = PresetColor(0x9b59b6); - public static readonly PackedColor DarkPurple = PresetColor(0x71368a); - public static readonly PackedColor Red = PresetColor(0xe74c3c); - public static readonly PackedColor DarkRed = PresetColor(0x992d22); - public static readonly PackedColor Orange = PresetColor(0xe67e22); - public static readonly PackedColor DarkOrange = PresetColor(0xa84300); - public static readonly PackedColor Navy = PresetColor(0x34495e); - public static readonly PackedColor DarkNavy = PresetColor(0x2c3e50); - public static readonly PackedColor Gold = PresetColor(0xf1c40f); - public static readonly PackedColor DarkGold = PresetColor(0xc27c0e); - - public static readonly PackedColor LighterGrey = PresetColor(0xbcc0c0); - public static readonly PackedColor LightGrey = PresetColor(0x95a5a6); - public static readonly PackedColor DarkGrey = PresetColor(0x979c9f); - public static readonly PackedColor DarkerGrey = PresetColor(0x7f8c8d); - - - private static PackedColor PresetColor(uint packedValue) - { - PackedColor color = new PackedColor(packedValue); - color.Lock(); - return color; - } - - private bool _isLocked; - private uint _rawValue; - public uint RawValue - { - get { return _rawValue; } - set - { - if (_isLocked) - throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy."); - _rawValue = value; - } - } - - public PackedColor(uint rawValue) { _rawValue = rawValue; } - public PackedColor(byte r, byte g, byte b) : this(((uint)r << 16) | ((uint)g << 8) | b) { } - public PackedColor(float r, float g, float b) : this((byte)(r * 255.0f), (byte)(g * 255.0f), (byte)(b * 255.0f)) { } - - /// Gets or sets the red component for this color. - public byte R { get { return GetByte(3); } set { SetByte(3, value); } } - /// Gets or sets the green component for this color. - public byte G { get { return GetByte(2); } set { SetByte(2, value); } } - /// Gets or sets the blue component for this color. - public byte B { get { return GetByte(1); } set { SetByte(1, value); } } - - internal void Lock() => _isLocked = true; - internal void SetRawValue(uint rawValue) - { - //Bypasses isLocked for API changes. - _rawValue = rawValue; - } - protected byte GetByte(int pos) => (byte)((_rawValue >> (8 * (pos - 1))) & 0xFF); - protected void SetByte(int pos, byte value) - { - if (_isLocked) - throw new InvalidOperationException("Unable to edit cached colors directly, use Copy() to make an editable copy."); - - uint original = _rawValue; - int bit = 8 * (pos - 1); - uint mask = (uint)~(0xFF << bit); - _rawValue = (_rawValue & mask) | ((uint)value << bit); - } - } -} diff --git a/src/Discord.Net/Models/PackedPermissions.cs b/src/Discord.Net/Models/Permissions.cs similarity index 85% rename from src/Discord.Net/Models/PackedPermissions.cs rename to src/Discord.Net/Models/Permissions.cs index 4ddc579e1..64efeebaf 100644 --- a/src/Discord.Net/Models/PackedPermissions.cs +++ b/src/Discord.Net/Models/Permissions.cs @@ -2,19 +2,19 @@ namespace Discord { - public sealed class PackedServerPermissions : PackedPermissions + public sealed class ServerPermissions : Permissions { - public static PackedServerPermissions None { get; } - public static PackedServerPermissions All { get; } - static PackedServerPermissions() + public static ServerPermissions None { get; } + public static ServerPermissions All { get; } + static ServerPermissions() { - None = new PackedServerPermissions(); + None = new ServerPermissions(); None.Lock(); - All = new PackedServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); + All = new ServerPermissions(Convert.ToUInt32("00000011111100111111110000111111", 2)); All.Lock(); } - public PackedServerPermissions(uint rawValue = 0) : base(rawValue) { } + public ServerPermissions(uint rawValue = 0) : base(rawValue) { } /// If True, a user may ban users from the server. public bool General_BanMembers { get { return GetBit(General_BanMembersBit); } set { SetBit(General_BanMembersBit, value); } } @@ -27,32 +27,32 @@ namespace Discord /// If True, a user may adjust server properties. public bool General_ManageServer { get { return GetBit(General_ManageServerBit); } set { SetBit(General_ManageServerBit, value); } } - public PackedServerPermissions Copy() => new PackedServerPermissions(RawValue); + public ServerPermissions Copy() => new ServerPermissions(RawValue); } - public sealed class PackedChannelPermissions : PackedPermissions + public sealed class ChannelPermissions : Permissions { - public static PackedChannelPermissions None { get; } - public static PackedChannelPermissions All { get; } - static PackedChannelPermissions() + public static ChannelPermissions None { get; } + public static ChannelPermissions All { get; } + static ChannelPermissions() { - None = new PackedChannelPermissions(); + None = new ChannelPermissions(); None.Lock(); - All = new PackedChannelPermissions(Convert.ToUInt32("00000011111100111111110000011001", 2)); + All = new ChannelPermissions(Convert.ToUInt32("00000011111100111111110000011001", 2)); All.Lock(); } - public PackedChannelPermissions(uint rawValue = 0) : base(rawValue) { } + public ChannelPermissions(uint rawValue = 0) : base(rawValue) { } /// If True, a user may adjust permissions. This also implictly grants all other permissions. public bool General_ManagePermissions { get { return GetBit(General_ManagePermissionsBit); } set { SetBit(General_ManagePermissionsBit, value); } } /// If True, a user may create, delete and modify this channel. public bool General_ManageChannel { get { return GetBit(General_ManageChannelBit); } set { SetBit(General_ManageChannelBit, value); } } - public PackedChannelPermissions Copy() => new PackedChannelPermissions(RawValue); + public ChannelPermissions Copy() => new ChannelPermissions(RawValue); } - public abstract class PackedPermissions + public abstract class Permissions { internal const byte General_CreateInstantInviteBit = 0; internal const byte General_BanMembersBit = 1; @@ -88,7 +88,7 @@ namespace Discord } } - protected PackedPermissions(uint rawValue) { _rawValue = rawValue; } + protected Permissions(uint rawValue) { _rawValue = rawValue; } /// If True, a user may create invites. public bool General_CreateInstantInvite { get { return GetBit(General_CreateInstantInviteBit); } set { SetBit(General_CreateInstantInviteBit, value); } } diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 399fa5d4b..95099a029 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -18,12 +18,12 @@ namespace Discord /// Returns the position of this channel in the role list for this server. public int Position { get; private set; } /// Returns the color of this role. - public PackedColor Color { get; private set; } + public Color Color { get; private set; } /// Returns whether this role is managed by server (e.g. for Twitch integration) public bool IsManaged { get; private set; } /// Returns the the permissions contained by this role. - public PackedServerPermissions Permissions { get; } + public ServerPermissions Permissions { get; } /// Returns the id of the server this role is a member of. public string ServerId { get; } @@ -45,9 +45,9 @@ namespace Discord _client = client; Id = id; ServerId = serverId; - Permissions = new PackedServerPermissions(0); + Permissions = new ServerPermissions(0); Permissions.Lock(); - Color = new PackedColor(0); + Color = new Color(0); Color.Lock(); if (IsEveryone) diff --git a/src/Discord.Net/Models/Server.cs b/src/Discord.Net/Models/Server.cs index b99cc8d48..c1d50a2e9 100644 --- a/src/Discord.Net/Models/Server.cs +++ b/src/Discord.Net/Models/Server.cs @@ -18,6 +18,8 @@ namespace Discord public string Name { get; private set; } /// Returns the current logged-in user's data for this server. public Member CurrentMember { get; internal set; } + /// Returns true if this is a virtual server used by Discord.Net and not a real Discord server. + public bool IsVirtual { get; internal set; } /// Returns the amount of time (in seconds) a user must be inactive for until they are automatically moved to the AFK channel (see AFKChannel). public int AFKTimeout { get; private set; }