diff options
| author | Rapptz <[email protected]> | 2015-08-26 21:20:18 -0400 |
|---|---|---|
| committer | Rapptz <[email protected]> | 2015-08-26 21:20:18 -0400 |
| commit | 0e4ccad32ae45a660d0670548e70299a416c5f78 (patch) | |
| tree | 6230b873a0ec598fa6b3eabc5998a0d81fc041ba | |
| parent | Documentation update. (diff) | |
| download | discord.py-0e4ccad32ae45a660d0670548e70299a416c5f78.tar.xz discord.py-0e4ccad32ae45a660d0670548e70299a416c5f78.zip | |
Parse permission_overwrites in every Channel instance.
| -rw-r--r-- | discord/channel.py | 7 | ||||
| -rw-r--r-- | discord/client.py | 34 |
2 files changed, 37 insertions, 4 deletions
diff --git a/discord/channel.py b/discord/channel.py index 734ad64a..a7f04ad7 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -46,15 +46,20 @@ class Channel(object): .. attribute:: type The channel type. Usually ``'voice'`` or ``'text'``. + .. attribute:: changed_roles + + An array of :class:`Roles` that have been overridden from their default + values in the :attr:`Server.roles` attribute. """ - def __init__(self, name, server, id, position, type, **kwargs): + def __init__(self, name, server, id, position, type, permission_overwrites=None, **kwargs): self.name = name self.server = server self.id = id self.is_private = False self.position = position self.type = type + self.changed_roles = permission_overwrites if permission_overwrites is not None else [] class PrivateChannel(object): """Represents a Discord private channel. diff --git a/discord/client.py b/discord/client.py index d2a1abe1..f3d12b07 100644 --- a/discord/client.py +++ b/discord/client.py @@ -151,9 +151,37 @@ class Client(object): guild['roles'] = [Role(**role) for role in guild['roles']] guild['members'] = [Member(**member) for member in guild['members']] - self.servers.append(Server(**guild)) - channels = [Channel(server=self.servers[-1], **channel) for channel in guild['channels']] - self.servers[-1].channels = channels + server = Server(**guild) + for channel in guild['channels']: + changed_roles = [] + permission_overwrites = channel['permission_overwrites'] + + for overridden in permission_overwrites: + # this is pretty inefficient due to the deep nested loops unfortunately + role = next((role for role in guild['roles'] if role.id == overridden['id']), None) + if role is None: + continue + denied = overridden.get('deny', 0) + allowed = overridden.get('allow', 0) + override = copy.deepcopy(role) + + # Basically this is what's happening here. + # We have an original bit array, e.g. 1010 + # Then we have another bit array that is 'denied', e.g. 1111 + # And then we have the last one which is 'allowed', e.g. 0101 + # We want original OP denied to end up resulting in whatever is in denied to be set to 0. + # So 1010 OP 1111 -> 0000 + # Then we take this value and look at the allowed values. And whatever is allowed is set to 1. + # So 0000 OP2 0101 -> 0101 + # The OP is (base ^ denied) & ~denied. + # The OP2 is base | allowed. + override.permissions.value = ((override.permissions.value ^ denied) & ~denied) | allowed + changed_roles.append(override) + + channel['permission_overwrites'] = changed_roles + channels = [Channel(server=server, **channel) for channel in guild['channels']] + server.channels = channels + self.servers.append(server) for pm in data.get('private_channels'): self.private_channels.append(PrivateChannel(id=pm['id'], user=User(**pm['recipient']))) |