diff --git a/src/Discord.Net/DiscordClient.API.cs b/src/Discord.Net/DiscordClient.API.cs
index de9e94125..038f017c1 100644
--- a/src/Discord.Net/DiscordClient.API.cs
+++ b/src/Discord.Net/DiscordClient.API.cs
@@ -547,8 +547,8 @@ namespace Discord
await _api.SetChannelPermissions(channel.Id, targetId, targetType, allowValue, denyValue);
if (perms != null)
{
- perms.Allow.SetRawValue(allowValue);
- perms.Deny.SetRawValue(denyValue);
+ perms.Allow.SetRawValueInternal(allowValue);
+ perms.Deny.SetRawValueInternal(denyValue);
}
else
{
diff --git a/src/Discord.Net/Models/Member.cs b/src/Discord.Net/Models/Member.cs
index 57b85229d..2b313510e 100644
--- a/src/Discord.Net/Models/Member.cs
+++ b/src/Discord.Net/Models/Member.cs
@@ -177,7 +177,7 @@ namespace Discord
if (!_permissions.TryGetValue(channelId, out permissions)) return;
uint newPermissions = 0x0;
uint oldPermissions = permissions.RawValue;
-
+
if (UserId == server.OwnerId)
newPermissions = PackedChannelPermissions.All.RawValue;
else
@@ -199,12 +199,12 @@ namespace Discord
}
- permissions.SetRawValue(newPermissions);
+ permissions.SetRawValueInternal(newPermissions);
if (permissions.General_ManagePermissions)
- permissions.SetRawValue(PackedChannelPermissions.All.RawValue);
+ permissions.SetRawValueInternal(PackedChannelPermissions.All.RawValue);
else if (server.DefaultChannelId == channelId)
- permissions.Text_ReadMessages = true;
+ permissions.SetBitInternal(PackedPermissions.Text_ReadMessagesBit, true);
if (permissions.RawValue != oldPermissions)
channel.InvalidMembersCache();
diff --git a/src/Discord.Net/Models/PackedPermissions.cs b/src/Discord.Net/Models/PackedPermissions.cs
index 6bdc0a49f..4ddc579e1 100644
--- a/src/Discord.Net/Models/PackedPermissions.cs
+++ b/src/Discord.Net/Models/PackedPermissions.cs
@@ -17,15 +17,15 @@ namespace Discord
public PackedServerPermissions(uint rawValue = 0) : base(rawValue) { }
/// If True, a user may ban users from the server.
- public bool General_BanMembers { get { return GetBit(2); } set { SetBit(2, value); } }
+ public bool General_BanMembers { get { return GetBit(General_BanMembersBit); } set { SetBit(General_BanMembersBit, value); } }
/// If True, a user may kick users from the server.
- public bool General_KickMembers { get { return GetBit(3); } set { SetBit(3, value); } }
+ public bool General_KickMembers { get { return GetBit(General_KickMembersBit); } set { SetBit(General_KickMembersBit, value); } }
/// If True, a user may adjust roles. This also implictly grants all other permissions.
- public bool General_ManageRoles { get { return GetBit(4); } set { SetBit(4, value); } }
+ public bool General_ManageRoles { get { return GetBit(General_ManagePermissionsBit); } set { SetBit(General_ManagePermissionsBit, value); } }
/// If True, a user may create, delete and modify channels.
- public bool General_ManageChannels { get { return GetBit(5); } set { SetBit(5, value); } }
+ public bool General_ManageChannels { get { return GetBit(General_ManageChannelBit); } set { SetBit(General_ManageChannelBit, value); } }
/// If True, a user may adjust server properties.
- public bool General_ManageServer { get { return GetBit(6); } set { SetBit(6, value); } }
+ public bool General_ManageServer { get { return GetBit(General_ManageServerBit); } set { SetBit(General_ManageServerBit, value); } }
public PackedServerPermissions Copy() => new PackedServerPermissions(RawValue);
}
@@ -45,15 +45,36 @@ namespace Discord
public PackedChannelPermissions(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(4); } set { SetBit(4, value); } }
+ 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(5); } set { SetBit(5, value); } }
+ public bool General_ManageChannel { get { return GetBit(General_ManageChannelBit); } set { SetBit(General_ManageChannelBit, value); } }
public PackedChannelPermissions Copy() => new PackedChannelPermissions(RawValue);
}
public abstract class PackedPermissions
{
+ internal const byte General_CreateInstantInviteBit = 0;
+ internal const byte General_BanMembersBit = 1;
+ internal const byte General_KickMembersBit = 2;
+ internal const byte General_ManagePermissionsBit = 3;
+ internal const byte General_ManageChannelBit = 4;
+ internal const byte General_ManageServerBit = 5;
+ internal const byte Text_ReadMessagesBit = 10;
+ internal const byte Text_SendMessagesBit = 11;
+ internal const byte Text_SendTTSMessagesBit = 12;
+ internal const byte Text_ManageMessagesBit = 13;
+ internal const byte Text_EmbedLinksBit = 14;
+ internal const byte Text_AttachFilesBit = 15;
+ internal const byte Text_ReadMessageHistoryBit = 16;
+ internal const byte Text_MentionEveryoneBit = 17;
+ internal const byte Voice_ConnectBit = 20;
+ internal const byte Voice_SpeakBit = 21;
+ internal const byte Voice_MuteMembersBit = 22;
+ internal const byte Voice_DeafenMembersBit = 23;
+ internal const byte Voice_MoveMembersBit = 24;
+ internal const byte Voice_UseVoiceActivationBit = 25;
+
private bool _isLocked;
private uint _rawValue;
public uint RawValue
@@ -70,64 +91,61 @@ namespace Discord
protected PackedPermissions(uint rawValue) { _rawValue = rawValue; }
/// If True, a user may create invites.
- public bool General_CreateInstantInvite { get { return GetBit(1); } set { SetBit(1, value); } }
- //Bit 2 = BanMembers/???
- //Bit 3 = KickMembers/???
- //Bit 4 = ManageRoles/ManagePermissions
- //Bit 5 = ManageChannels/ManageChannel
- //Bit 6 = ManageServer/???
-
- //4 Unused
+ public bool General_CreateInstantInvite { get { return GetBit(General_CreateInstantInviteBit); } set { SetBit(General_CreateInstantInviteBit, value); } }
/// If True, a user may join channels.
- public bool Text_ReadMessages { get { return GetBit(11); } set { SetBit(11, value); } }
+ public bool Text_ReadMessages { get { return GetBit(Text_ReadMessagesBit); } set { SetBit(Text_ReadMessagesBit, value); } }
/// If True, a user may send messages.
- public bool Text_SendMessages { get { return GetBit(12); } set { SetBit(12, value); } }
+ public bool Text_SendMessages { get { return GetBit(Text_SendMessagesBit); } set { SetBit(Text_SendMessagesBit, value); } }
/// If True, a user may send text-to-speech messages.
- public bool Text_SendTTSMessages { get { return GetBit(13); } set { SetBit(13, value); } }
+ public bool Text_SendTTSMessages { get { return GetBit(Text_SendTTSMessagesBit); } set { SetBit(Text_SendTTSMessagesBit, value); } }
/// If True, a user may delete messages.
- public bool Text_ManageMessages { get { return GetBit(14); } set { SetBit(14, value); } }
+ public bool Text_ManageMessages { get { return GetBit(Text_ManageMessagesBit); } set { SetBit(Text_ManageMessagesBit, value); } }
/// If True, Discord will auto-embed links sent by this user.
- public bool Text_EmbedLinks { get { return GetBit(15); } set { SetBit(15, value); } }
+ public bool Text_EmbedLinks { get { return GetBit(Text_EmbedLinksBit); } set { SetBit(Text_EmbedLinksBit, value); } }
/// If True, a user may send files.
- public bool Text_AttachFiles { get { return GetBit(16); } set { SetBit(16, value); } }
+ public bool Text_AttachFiles { get { return GetBit(Text_AttachFilesBit); } set { SetBit(Text_AttachFilesBit, value); } }
/// If True, a user may read previous messages.
- public bool Text_ReadMessageHistory { get { return GetBit(17); } set { SetBit(17, value); } }
+ public bool Text_ReadMessageHistory { get { return GetBit(Text_ReadMessageHistoryBit); } set { SetBit(Text_ReadMessageHistoryBit, value); } }
/// If True, a user may mention @everyone.
- public bool Text_MentionEveryone { get { return GetBit(18); } set { SetBit(18, value); } }
-
- //2 Unused
+ public bool Text_MentionEveryone { get { return GetBit(Text_MentionEveryoneBit); } set { SetBit(Text_MentionEveryoneBit, value); } }
/// If True, a user may connect to a voice channel.
- public bool Voice_Connect { get { return GetBit(21); } set { SetBit(21, value); } }
+ public bool Voice_Connect { get { return GetBit(Voice_ConnectBit); } set { SetBit(Voice_ConnectBit, value); } }
/// If True, a user may speak in a voice channel.
- public bool Voice_Speak { get { return GetBit(22); } set { SetBit(22, value); } }
+ public bool Voice_Speak { get { return GetBit(Voice_SpeakBit); } set { SetBit(Voice_SpeakBit, value); } }
/// If True, a user may mute users.
- public bool Voice_MuteMembers { get { return GetBit(23); } set { SetBit(23, value); } }
+ public bool Voice_MuteMembers { get { return GetBit(Voice_MuteMembersBit); } set { SetBit(Voice_MuteMembersBit, value); } }
/// If True, a user may deafen users.
- public bool Voice_DeafenMembers { get { return GetBit(24); } set { SetBit(24, value); } }
+ public bool Voice_DeafenMembers { get { return GetBit(Voice_DeafenMembersBit); } set { SetBit(Voice_DeafenMembersBit, value); } }
/// If True, a user may move other users between voice channels.
- public bool Voice_MoveMembers { get { return GetBit(25); } set { SetBit(25, value); } }
+ public bool Voice_MoveMembers { get { return GetBit(Voice_MoveMembersBit); } set { SetBit(Voice_MoveMembersBit, value); } }
/// If True, a user may use voice activation rather than push-to-talk.
- public bool Voice_UseVoiceActivation { get { return GetBit(26); } set { SetBit(26, value); } }
-
- //6 Unused
+ public bool Voice_UseVoiceActivation { get { return GetBit(Voice_UseVoiceActivationBit); } set { SetBit(Voice_UseVoiceActivationBit, value); } }
internal void Lock() => _isLocked = true;
- internal void SetRawValue(uint rawValue)
- {
- //Bypasses isLocked for API changes.
- _rawValue = rawValue;
- }
- protected bool GetBit(int pos) => ((_rawValue >> (pos - 1)) & 1U) == 1;
+ protected bool GetBit(int pos) => ((_rawValue >> pos) & 1U) == 1;
protected void SetBit(int pos, bool value)
{
if (_isLocked)
throw new InvalidOperationException("Unable to edit cached permissions directly, use Copy() to make an editable copy.");
if (value)
- _rawValue |= (1U << (pos - 1));
+ _rawValue |= (1U << pos);
else
- _rawValue &= ~(1U << (pos - 1));
+ _rawValue &= ~(1U << pos);
+ }
+
+ //Bypasses isLocked for API changes.
+ internal void SetBitInternal(int pos, bool value)
+ {
+ if (value)
+ _rawValue |= (1U << pos);
+ else
+ _rawValue &= ~(1U << pos);
+ }
+ internal void SetRawValueInternal(uint rawValue)
+ {
+ _rawValue = rawValue;
}
}
}
diff --git a/src/Discord.Net/Models/Role.cs b/src/Discord.Net/Models/Role.cs
index 106945fc1..50c889e06 100644
--- a/src/Discord.Net/Models/Role.cs
+++ b/src/Discord.Net/Models/Role.cs
@@ -65,7 +65,7 @@ namespace Discord
if (model.Color != null)
Color.SetRawValue(model.Color.Value);
if (model.Permissions != null)
- Permissions.SetRawValue(model.Permissions.Value);
+ Permissions.SetRawValueInternal(model.Permissions.Value);
foreach (var member in Members)
member.UpdatePermissions();