@@ -12,66 +12,63 @@ public static async Task Lock(SlashCommandContext ctx)
1212 {
1313 await ctx . DeferResponseAsync ( true ) ;
1414
15- var existingOverwrites = ctx . Channel . PermissionOverwrites . ToArray ( ) ;
16- var invokerExistingAllowedOverwrites = existingOverwrites . FirstOrDefault ( o => o . Id == ctx . Member . Id ) ;
17- var botAllowedOverwrites = existingOverwrites . FirstOrDefault ( o => o . Id == Program . Discord . CurrentUser . Id ) ;
18-
19- try
20- {
21- // Add initial overwrites for failsafes (bot & user who called /lockdown), deny everyone else Send Messages
22- if ( invokerExistingAllowedOverwrites is null )
23- {
24- await ctx . Channel . AddOverwriteAsync ( ctx . Member , DiscordPermission . SendMessages , DiscordPermissions . None ,
25- "Failsafe for lockdown" ) ;
26- }
27- else
28- {
29- await ctx . Channel . AddOverwriteAsync ( ctx . Member ,
30- invokerExistingAllowedOverwrites . Allowed | DiscordPermission . SendMessages ,
31- invokerExistingAllowedOverwrites . Denied , "Failsafe for lockdown" ) ;
32- }
33-
34- if ( botAllowedOverwrites is null )
35- {
36- await ctx . Channel . AddOverwriteAsync ( await ctx . Guild . GetMemberAsync ( ctx . Client . CurrentUser . Id ) ,
37- DiscordPermission . SendMessages , DiscordPermissions . None , "Failsafe for lockdown" ) ;
38- }
39- else
40- {
41- await ctx . Channel . AddOverwriteAsync ( await ctx . Guild . GetMemberAsync ( ctx . Client . CurrentUser . Id ) ,
42- botAllowedOverwrites . Allowed | DiscordPermission . SendMessages , botAllowedOverwrites . Denied ,
43- "Failsafe for lockdown" ) ;
44- }
45-
46- await ctx . Channel . AddOverwriteAsync ( ctx . Guild . EveryoneRole , DiscordPermissions . None , DiscordPermission . SendMessages ,
47- "Lockdown" ) ;
48-
49- // Restore overwrites that may have been present before the lockdown
50-
51- foreach ( var overwrite in existingOverwrites )
52- if ( overwrite . Type == DiscordOverwriteType . Role )
53- {
54- if ( await overwrite . GetRoleAsync ( ) == ctx . Guild . EveryoneRole )
55- await ctx . Channel . AddOverwriteAsync ( await overwrite . GetRoleAsync ( ) , overwrite . Allowed ,
56- DiscordPermission . SendMessages | overwrite . Denied ,
57- "Restoring previous overrides for lockdown" ) ;
58- else
59- await ctx . Channel . AddOverwriteAsync ( await overwrite . GetRoleAsync ( ) , overwrite . Allowed ,
60- overwrite . Denied , "Restoring previous overrides for lockdown" ) ;
61- }
62- else if ( overwrite . Id != ctx . Member . Id && overwrite . Id != Program . Discord . CurrentUser . Id )
63- {
64- await ctx . Channel . AddOverwriteAsync ( await overwrite . GetMemberAsync ( ) , overwrite . Allowed ,
65- overwrite . Denied , "Restoring previous overrides for lockdown" ) ;
66- }
67- }
68- catch ( UnauthorizedException )
69- {
70- await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( ) . WithContent (
71- "I don't have permission to lock this channel! Make sure I have the \" Manage Roles\" server permission, or the \" Manage Permissions\" permission on each channel you want me to be able to lock or unlock." ) ) ;
72- return ;
73- }
15+ // Get the permissions that are already on the channel, so that we can make sure they are kept when we adjust overwrites for lockdown
16+ DiscordOverwrite [ ] existingOverwrites = ctx . Channel . PermissionOverwrites . ToArray ( ) ;
17+
18+ // Get the bot's permission set from before the lockdown
19+ var botOverwritesBeforeLockdown = existingOverwrites . Where ( x => x . Id == Program . Discord . CurrentUser . Id ) . FirstOrDefault ( ) ;
7420
21+ // Get the bot's allowed permission set
22+ var botAllowedPermissionsBeforeLockdown = DiscordPermissions . None ;
23+ if ( botOverwritesBeforeLockdown is not null )
24+ botAllowedPermissionsBeforeLockdown = botOverwritesBeforeLockdown . Allowed ;
25+
26+ // Get the bot's denied permission set
27+ var botDeniedPermissionsBeforeLockdown = DiscordPermissions . None ;
28+ if ( botOverwritesBeforeLockdown is not null )
29+ botDeniedPermissionsBeforeLockdown = botOverwritesBeforeLockdown . Denied ;
30+
31+ // Get the invoker's permission set from before the lockdown
32+ var invokerOverwritesBeforeLockdown = existingOverwrites . Where ( x => x . Id == ctx . User . Id ) . FirstOrDefault ( ) ;
33+
34+ // Get the invoker's allowed permission set
35+ var invokerAllowedPermissionsBeforeLockdown = DiscordPermissions . None ;
36+ if ( invokerOverwritesBeforeLockdown is not null )
37+ invokerAllowedPermissionsBeforeLockdown = invokerOverwritesBeforeLockdown . Allowed ;
38+
39+ // Get the invoker's denied permission set
40+ var invokerDeniedPermissionsBeforeLockdown = DiscordPermissions . None ;
41+ if ( invokerOverwritesBeforeLockdown is not null )
42+ invokerDeniedPermissionsBeforeLockdown = invokerOverwritesBeforeLockdown . Denied ;
43+
44+ // Construct failsafe permission sets
45+ // Grant Send Messages to the bot and to the invoker in addition to any permissions they might already have,
46+ var botAllowedPermissions = botAllowedPermissionsBeforeLockdown . Add ( DiscordPermission . SendMessages ) ;
47+ var invokerAllowedPermissions = invokerAllowedPermissionsBeforeLockdown . Add ( DiscordPermission . SendMessages ) ;
48+
49+ // Apply failsafes for lockdown
50+ await ctx . Channel . AddOverwriteAsync ( ctx . Channel . Guild . CurrentMember , botAllowedPermissions , botDeniedPermissionsBeforeLockdown , "Failsafe 1 for Lockdown" ) ;
51+ await ctx . Channel . AddOverwriteAsync ( ctx . Member , invokerAllowedPermissions , invokerDeniedPermissionsBeforeLockdown , "Failsafe 2 for Lockdown" ) ;
52+
53+ // Get the @everyone role's permission set from before the lockdown
54+ var everyoneOverwritesBeforeLockdown = existingOverwrites . Where ( x => x . Id == ctx . Channel . Guild . EveryoneRole . Id ) . FirstOrDefault ( ) ;
55+
56+ // Get the @everyone role's allowed permission set
57+ var everyoneAllowedPermissionsBeforeLockdown = DiscordPermissions . None ;
58+ if ( everyoneOverwritesBeforeLockdown is not null )
59+ everyoneAllowedPermissionsBeforeLockdown = everyoneOverwritesBeforeLockdown . Allowed ;
60+
61+ // Get the @everyone role's denied permission set
62+ var everyoneDeniedPermissionsBeforeLockdown = DiscordPermissions . None ;
63+ if ( everyoneOverwritesBeforeLockdown is not null )
64+ everyoneDeniedPermissionsBeforeLockdown = everyoneOverwritesBeforeLockdown . Denied ;
65+
66+ // Construct new @everyone permission set
67+ var everyoneDeniedPermissions = everyoneDeniedPermissionsBeforeLockdown . Add ( DiscordPermission . SendMessages ) ;
68+
69+ // Lock the channel
70+ await ctx . Channel . AddOverwriteAsync ( ctx . Channel . Guild . EveryoneRole , everyoneAllowedPermissionsBeforeLockdown , everyoneDeniedPermissions , $ "Lockdown by { ctx . User . Username } ") ;
71+
7572 await ctx . Channel . SendMessageAsync ( "This channel has been locked." ) ;
7673
7774 await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( ) . WithContent ( "Channel locked successfully." )
@@ -84,61 +81,83 @@ public static async Task Unlock(SlashCommandContext ctx)
8481 {
8582 await ctx . DeferResponseAsync ( true ) ;
8683
87- try
88- {
89- // Checking <2 because there will always be 1 overwrite for @everyone permissions
90- if ( ctx . Channel . PermissionOverwrites . ToArray ( ) . Length < 2
91- || ctx . Channel . PermissionOverwrites . Any ( o => o . Id == ctx . Guild . EveryoneRole . Id &&
92- ! o . Denied . HasPermission ( DiscordPermission . SendMessages ) ) )
93- {
94- await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( )
95- . WithContent ( "This channel is not locked!" ) . AsEphemeral ( ) ) ;
96- return ;
97- }
98-
99- foreach ( var permission in ctx . Channel . PermissionOverwrites . ToArray ( ) )
100- if ( permission . Type == DiscordOverwriteType . Role )
101- {
102- // Don't touch roles that aren't @everyone
103- if ( await permission . GetRoleAsync ( ) != ctx . Guild . EveryoneRole ) continue ;
104-
105- // Construct new @everyone overwrite; keep it the same but remove denial for Send Messages
106- DiscordOverwriteBuilder newOverwrite = new ( ctx . Guild . EveryoneRole )
107- {
108- Allowed = permission . Allowed ,
109- Denied = ( DiscordPermissions ) ( permission . Denied - DiscordPermission . SendMessages )
110- } ;
111-
112- await ctx . Channel . AddOverwriteAsync ( ctx . Guild . EveryoneRole , newOverwrite . Allowed ,
113- newOverwrite . Denied , "Lockdown cleared" ) ;
114- }
115- else
116- {
117- // Filter to user overrides that have Send Messages allowed (failsafes) so we can remove
118- if ( ! permission . Allowed . HasPermission ( DiscordPermission . SendMessages ) ) continue ;
119-
120- // Remove failsafe Send Message overrides
121- DiscordOverwriteBuilder newOverwrite = new ( await permission . GetMemberAsync ( ) )
122- {
123- Allowed = ( DiscordPermissions ) ( permission . Allowed - DiscordPermission . SendMessages ) ,
124- Denied = permission . Denied
125- } ;
126-
127- // Check new permission set; if it's totally empty, just drop the override
128- if ( newOverwrite . Allowed == DiscordPermissions . None && newOverwrite . Denied == DiscordPermissions . None )
129- await ctx . Channel . DeleteOverwriteAsync ( await permission . GetMemberAsync ( ) , "Lockdown cleared" ) ;
130- else
131- await ctx . Channel . AddOverwriteAsync ( await permission . GetMemberAsync ( ) , newOverwrite . Allowed ,
132- newOverwrite . Denied , "Lockdown cleared" ) ;
133- }
134- }
135- catch ( UnauthorizedException )
84+ // Checking <2 because there will always be 1 overwrite for @everyone permissions
85+ if ( ctx . Channel . PermissionOverwrites . ToArray ( ) . Length < 2
86+ || ctx . Channel . PermissionOverwrites . Any ( o => o . Id == ctx . Guild . EveryoneRole . Id &&
87+ ! o . Denied . HasPermission ( DiscordPermission . SendMessages ) ) )
13688 {
137- await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( ) . WithContent (
138- "I don't have permission to unlock this channel! Make sure I have the \" Manage Roles \" server permission, or the \" Manage Permissions \" permission on each channel you want me to be able to lock or unlock." ) ) ;
89+ await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( )
90+ . WithContent ( "This channel is not locked!" ) . AsEphemeral ( ) ) ;
13991 return ;
14092 }
141-
93+
94+ // Get the permissions that are already on the channel, so that we can make sure they are kept when we adjust overwrites for the unlock
95+ var permissions = ctx . Channel . PermissionOverwrites . ToArray ( ) ;
96+
97+ // Get bot's permission set from before the unlock
98+ var botOverwritesBeforeUnlock = permissions . Where ( x => x . Id == Program . Discord . CurrentUser . Id ) . FirstOrDefault ( ) ;
99+
100+ // Get bot's allowed permission set
101+ var botAllowedPermissionsBeforeUnlock = DiscordPermissions . None ;
102+ if ( botOverwritesBeforeUnlock is not null )
103+ botAllowedPermissionsBeforeUnlock = botOverwritesBeforeUnlock . Allowed ;
104+
105+ // Get bot's denied permission set
106+ var botDeniedPermissionsBeforeUnlock = DiscordPermissions . None ;
107+ if ( botOverwritesBeforeUnlock is not null )
108+ botDeniedPermissionsBeforeUnlock = botOverwritesBeforeUnlock . Denied ;
109+
110+ // Get the invoker role's permission set from before the unlock
111+ var invokerOverwritesBeforeUnlock = permissions . Where ( x => x . Id == ctx . User . Id ) . FirstOrDefault ( ) ;
112+
113+ // Get the invoker role's allowed permission set
114+ var invokerAllowedPermissionsBeforeUnlock = DiscordPermissions . None ;
115+ if ( invokerOverwritesBeforeUnlock is not null )
116+ invokerAllowedPermissionsBeforeUnlock = invokerOverwritesBeforeUnlock . Allowed ;
117+
118+ // Get the invoker role's denied permission set
119+ var invokerDeniedPermissionsBeforeUnlock = DiscordPermissions . None ;
120+ if ( invokerOverwritesBeforeUnlock is not null )
121+ invokerDeniedPermissionsBeforeUnlock = invokerOverwritesBeforeUnlock . Denied ;
122+
123+ // Construct new permission sets for bot and invoker
124+ // Resets Send Messages and Send Messages in Threads for bot and invoker, while preserving other permissions
125+ var botAllowedPermissions = botAllowedPermissionsBeforeUnlock . Remove ( DiscordPermission . SendMessages ) . Remove ( DiscordPermission . SendThreadMessages ) ;
126+ var invokerAllowedPermissions = invokerAllowedPermissionsBeforeUnlock . Remove ( DiscordPermission . SendMessages ) . Remove ( DiscordPermission . SendThreadMessages ) ;
127+
128+ // Get the @everyone role's permission set from before the unlock
129+ var everyoneOverwritesBeforeUnlock = permissions . Where ( x => x . Id == ctx . Channel . Guild . EveryoneRole . Id ) . FirstOrDefault ( ) ;
130+
131+ // Get the @everyone role's allowed permission set
132+ var everyoneAllowedPermissionsBeforeUnlock = DiscordPermissions . None ;
133+ if ( everyoneOverwritesBeforeUnlock is not null )
134+ everyoneAllowedPermissionsBeforeUnlock = everyoneOverwritesBeforeUnlock . Allowed ;
135+
136+ // Get the @everyone role's denied permission set
137+ var everyoneDeniedPermissionsBeforeUnlock = DiscordPermissions . None ;
138+ if ( everyoneOverwritesBeforeUnlock is not null )
139+ everyoneDeniedPermissionsBeforeUnlock = everyoneOverwritesBeforeUnlock . Denied ;
140+
141+ // Construct new permission set for @everyone
142+ // Resets Send Messages while preserving other permissions
143+ var everyoneDeniedPermissions = everyoneDeniedPermissionsBeforeUnlock . Remove ( DiscordPermission . SendMessages ) ;
144+
145+ // Unlock the channel
146+ await ctx . Channel . AddOverwriteAsync ( ctx . Channel . Guild . EveryoneRole , everyoneAllowedPermissionsBeforeUnlock , everyoneDeniedPermissions , $ "Unlock by { ctx . User . Username } ") ;
147+
148+ // Remove failsafes
149+ // For any failsafes where the after-unlock permission set is completely empty, delete the override entirely
150+
151+ if ( botAllowedPermissions == DiscordPermissions . None && botDeniedPermissionsBeforeUnlock == DiscordPermissions . None )
152+ await ctx . Channel . DeleteOverwriteAsync ( ctx . Channel . Guild . CurrentMember , "Resetting Lockdown failsafe 1 for unlock" ) ;
153+ else
154+ await ctx . Channel . AddOverwriteAsync ( ctx . Channel . Guild . CurrentMember , botAllowedPermissions , botDeniedPermissionsBeforeUnlock , "Resetting Lockdown failsafe 1 for unlock" ) ;
155+
156+ if ( invokerAllowedPermissions == DiscordPermissions . None && invokerDeniedPermissionsBeforeUnlock == DiscordPermissions . None )
157+ await ctx . Channel . DeleteOverwriteAsync ( ctx . Member , "Resetting Lockdown failsafe 2 for unlock" ) ;
158+ else
159+ await ctx . Channel . AddOverwriteAsync ( ctx . Member , invokerAllowedPermissions , invokerDeniedPermissionsBeforeUnlock , "Resetting Lockdown failsafe 2 for unlock" ) ;
160+
142161 await ctx . Channel . SendMessageAsync ( "This channel has been unlocked." ) ;
143162 await ctx . FollowupAsync ( new DiscordFollowupMessageBuilder ( )
144163 . WithContent ( "Channel unlocked successfully." ) . AsEphemeral ( ) ) ;
0 commit comments