diff --git a/discord/abc.py b/discord/abc.py index 3720fceac..6867505f1 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -538,6 +538,7 @@ class GuildChannel: - Guild roles - Channel overrides - Member overrides + - Member timeout If a :class:`~discord.Role` is passed, then it checks the permissions someone with that role would have, which is essentially: @@ -624,6 +625,12 @@ class GuildChannel: if base.administrator: return Permissions.all() + if obj.is_timed_out(): + # Timeout leads to every permission except VIEW_CHANNEL and READ_MESSAGE_HISTORY + # being explicitly denied + base.value &= Permissions._timeout_mask() + return base + # Apply @everyone allow/deny first since it's special try: maybe_everyone = self._overwrites[0] diff --git a/discord/member.py b/discord/member.py index 33196bd6b..31b29c274 100644 --- a/discord/member.py +++ b/discord/member.py @@ -649,8 +649,11 @@ class Member(discord.abc.Messageable, _UserTag): channel permission overwrites. For 100% accurate permission calculation, please use :meth:`abc.GuildChannel.permissions_for`. - This does take into consideration guild ownership and the - administrator implication. + This does take into consideration guild ownership, the + administrator implication, and whether the member is timed out. + + .. versionchanged:: 2.0 + Member timeouts are taken into consideration. """ if self.guild.owner_id == self.id: @@ -663,6 +666,9 @@ class Member(discord.abc.Messageable, _UserTag): if base.administrator: return Permissions.all() + if self.is_timed_out(): + base.value &= Permissions._timeout_mask() + return base @property diff --git a/discord/permissions.py b/discord/permissions.py index 652fabb93..df5e5ce13 100644 --- a/discord/permissions.py +++ b/discord/permissions.py @@ -151,6 +151,13 @@ class Permissions(BaseFlags): """ return cls(0b11111111111111111111111111111111111111111) + @classmethod + def _timeout_mask(cls) -> int: + p = cls.all() + p.view_channel = False + p.read_message_history = False + return ~p.value + @classmethod def all_channel(cls) -> Self: """A :class:`Permissions` with all channel-specific permissions set to