diff --git a/src/Discord.Net.Net45/Discord.Net.csproj b/src/Discord.Net.Net45/Discord.Net.csproj index 25a0596dc..e1e21fecb 100644 --- a/src/Discord.Net.Net45/Discord.Net.csproj +++ b/src/Discord.Net.Net45/Discord.Net.csproj @@ -199,6 +199,9 @@ Models\Message.cs + + Models\PackedColor.cs + Models\PackedPermissions.cs diff --git a/src/Discord.Net/DiscordAPIClient.cs b/src/Discord.Net/DiscordAPIClient.cs index 5e0dd6fa4..852c445f6 100644 --- a/src/Discord.Net/DiscordAPIClient.cs +++ b/src/Discord.Net/DiscordAPIClient.cs @@ -270,7 +270,7 @@ namespace Discord return _rest.Delete(Endpoints.ServerRole(serverId, roleId)); } - public Task EditRole(string serverId, string roleId, string name = null, uint? permissions = null, bool? hoist = null, uint? color = null) + public Task EditRole(string serverId, string roleId, string name = null, uint? permissions = null, uint? color = null, bool? hoist = null) { if (serverId == null) throw new ArgumentNullException(nameof(serverId)); if (roleId == null) throw new ArgumentNullException(nameof(roleId)); diff --git a/src/Discord.Net/DiscordClient.API.cs b/src/Discord.Net/DiscordClient.API.cs index 509c13874..758a6614c 100644 --- a/src/Discord.Net/DiscordClient.API.cs +++ b/src/Discord.Net/DiscordClient.API.cs @@ -654,13 +654,13 @@ namespace Discord public Task EditRole(Role role, string newName) => EditRole(role?.ServerId, role?.Id, newName); - public Task EditRole(string serverId, string roleId, string name = null, PackedServerPermissions permissions = null, bool? hoist = null, uint? color = null) + public Task EditRole(string serverId, string roleId, string name = null, PackedServerPermissions permissions = null, PackedColor color = null, bool? hoist = null) { CheckReady(); if (serverId == null) throw new NullReferenceException(nameof(serverId)); if (roleId == null) throw new NullReferenceException(nameof(roleId)); - return _api.EditRole(serverId, roleId, name: name, permissions: permissions?.RawValue, hoist: hoist, color: color); + return _api.EditRole(serverId, roleId, name: name, permissions: permissions?.RawValue, color: color?.RawValue, hoist: hoist); } public Task DeleteRole(Role role) diff --git a/src/Discord.Net/Models/PackedColor.cs b/src/Discord.Net/Models/PackedColor.cs new file mode 100644 index 000000000..1ed9687c1 --- /dev/null +++ b/src/Discord.Net/Models/PackedColor.cs @@ -0,0 +1,46 @@ +using System; + +namespace Discord +{ + public class PackedColor + { + private bool _isLocked; + private uint _rawValue; + public uint RawValue + { + get { return _rawValue; } + set + { + if (_isLocked) + throw new InvalidOperationException("Unable to edit cached permissions directly, use Copy() to make an editable copy."); + _rawValue = value; + } + } + + public PackedColor(uint rawValue) { _rawValue = rawValue; } + + /// If True, a user may join channels. + public byte Red { get { return GetByte(3); } set { SetByte(3, value); } } + /// If True, a user may send messages. + public byte Green { get { return GetByte(2); } set { SetByte(2, value); } } + /// If True, a user may send text-to-speech messages. + public byte Blue { 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 permissions directly, use Copy() to make an editable copy."); + + int bit = 8 * (pos - 1); + uint mask = (uint)((1 << bit) - 1); + _rawValue = ((uint)value << bit) | (_rawValue & mask); + } + } +} diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs index 38140a658..985e687f0 100644 --- a/src/Discord.Net/Models/Role.cs +++ b/src/Discord.Net/Models/Role.cs @@ -15,7 +15,7 @@ namespace Discord /// If true, this role is displayed isolated from other users. public bool Hoist { get; private set; } /// Returns the color of this role. - public uint Color { get; private set; } + public PackedColor Color { get; private set; } /// Returns the the permissions contained by this role. public PackedServerPermissions Permissions { get; } @@ -38,9 +38,11 @@ namespace Discord _client = client; Id = id; ServerId = serverId; + IsEveryone = isEveryone; Permissions = new PackedServerPermissions(0); Permissions.Lock(); - IsEveryone = isEveryone; + Color = new PackedColor(0); + Color.Lock(); } internal void Update(API.RoleInfo model) @@ -50,7 +52,7 @@ namespace Discord if (model.Hoist != null) Hoist = model.Hoist.Value; if (model.Color != null) - Color = model.Color.Value; + Color.SetRawValue(model.Color.Value); if (model.Permissions != null) Permissions.SetRawValue(model.Permissions.Value);