/[sudobot]/branches/6.x/src/services/ChannelLockManager.ts
ViewVC logotype

Contents of /branches/6.x/src/services/ChannelLockManager.ts

Parent Directory Parent Directory | Revision Log Revision Log


Revision 577 - (show annotations)
Mon Jul 29 18:52:37 2024 UTC (8 months ago) by rakinar2
File MIME type: application/typescript
File size: 12254 byte(s)
chore: add old version archive branches (2.x to 9.x-dev)
1 /**
2 * This file is part of SudoBot.
3 *
4 * Copyright (C) 2021-2023 OSN Developers.
5 *
6 * SudoBot is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * SudoBot is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with SudoBot. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 import { ChannelType, Guild, GuildBasedChannel, PermissionFlagsBits, Snowflake, TextChannel, User } from "discord.js";
21 import Service from "../core/Service";
22 import { log, logError } from "../utils/logger";
23 import { getChannelPermissionOverride } from "../utils/utils";
24
25 export const name = "channelLockManager";
26
27 type ChannelLockOptions = {
28 channels?: Snowflake[];
29 channelMode?: "exclude" | "include";
30 ignorePrivateChannels?: boolean;
31 moderator: User;
32 reason?: string;
33 };
34
35 export default class ChannelLockManager extends Service {
36 async shouldLock(channels: Snowflake[], channel: GuildBasedChannel, channelMode: "exclude" | "include") {
37 return (
38 channels.length === 0 ||
39 (channelMode === "include" && channels.includes(channel.id)) ||
40 (channelMode === "exclude" && !channels.includes(channel.id))
41 );
42 }
43
44 async lockGuild(
45 guild: Guild,
46 { reason, moderator, channels = [], channelMode = "include", ignorePrivateChannels = true }: ChannelLockOptions
47 ) {
48 let countSuccess = 0,
49 countFailed = 0,
50 countSkipped = 0,
51 countInvalidChannel = 0;
52
53 const originalPermissions = [];
54
55 for (const [, channel] of guild.channels.cache) {
56 log(channel.name);
57
58 if (
59 !this.shouldLock(channels, channel, channelMode) ||
60 ![
61 ChannelType.GuildAnnouncement,
62 ChannelType.GuildCategory,
63 ChannelType.GuildText,
64 ChannelType.GuildVoice,
65 ChannelType.GuildStageVoice,
66 ChannelType.GuildForum
67 ].includes(channel.type)
68 ) {
69 countInvalidChannel++;
70 continue;
71 }
72
73 try {
74 const permissionOverwrites = (channel as TextChannel).permissionOverwrites?.cache.get(guild.id);
75
76 if (ignorePrivateChannels) {
77 if (permissionOverwrites?.deny.has(PermissionFlagsBits.ViewChannel, true)) {
78 log("Private channel, skipping lock");
79 countSkipped++;
80 continue;
81 }
82 }
83
84 if (permissionOverwrites?.deny.has(PermissionFlagsBits.SendMessages, true)) {
85 log("Already locked channel, skipping lock");
86 countSkipped++;
87 continue;
88 }
89
90 const permissionJson = {
91 Connect: permissionOverwrites
92 ? getChannelPermissionOverride(PermissionFlagsBits.Connect, permissionOverwrites)
93 : null,
94 SendMessages: permissionOverwrites
95 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessages, permissionOverwrites)
96 : null,
97 SendMessagesInThreads: permissionOverwrites
98 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessagesInThreads, permissionOverwrites)
99 : null,
100 AddReactions: permissionOverwrites
101 ? getChannelPermissionOverride(PermissionFlagsBits.AddReactions, permissionOverwrites)
102 : null
103 };
104
105 originalPermissions.push({
106 channel_id: channel.id,
107 guild_id: guild.id,
108 permissions: permissionJson
109 });
110
111 await (channel as TextChannel).permissionOverwrites?.edit(guild.id, {
112 Connect: false,
113 SendMessages: false,
114 SendMessagesInThreads: false,
115 AddReactions: false
116 });
117
118 countSuccess++;
119 } catch (e) {
120 logError(e);
121 countFailed++;
122 }
123 }
124
125 await this.client.prisma.channelLock.createMany({
126 data: originalPermissions
127 });
128
129 await this.client.logger.logServerLockOrUnlock({
130 guild,
131 action: "Locked",
132 moderator,
133 countSuccess,
134 countFailed,
135 countInvalidChannel,
136 countSkipped,
137 reason
138 });
139
140 return {
141 countSuccess,
142 countFailed,
143 countInvalidChannel,
144 countSkipped
145 };
146 }
147
148 async unlockGuild(
149 guild: Guild,
150 {
151 channels = [],
152 channelMode = "include",
153 ignorePrivateChannels = true,
154 force,
155 moderator,
156 reason
157 }: ChannelLockOptions & { force?: boolean }
158 ) {
159 let countSuccess = 0,
160 countFailed = 0,
161 countSkipped = 0,
162 countInvalidChannel = 0;
163
164 const originalPermissions = force
165 ? guild.channels.cache.map(c => ({ channel_id: c.id, permissions: {}, id: 0 }))
166 : await this.client.prisma.channelLock.findMany({
167 where: {
168 guild_id: guild.id
169 }
170 });
171
172 for (const originalPermission of originalPermissions) {
173 const channel = guild.channels.cache.get(originalPermission.channel_id);
174
175 if (!channel) continue;
176
177 if (
178 !this.shouldLock(channels, channel, channelMode) ||
179 ![
180 ChannelType.GuildAnnouncement,
181 ChannelType.GuildCategory,
182 ChannelType.GuildText,
183 ChannelType.GuildVoice,
184 ChannelType.GuildStageVoice,
185 ChannelType.GuildForum
186 ].includes(channel.type)
187 ) {
188 countInvalidChannel++;
189 continue;
190 }
191
192 try {
193 const options = {
194 Connect: force ? true : (originalPermission.permissions! as any).Connect,
195 SendMessages: force ? true : (originalPermission.permissions! as any).SendMessages,
196 SendMessagesInThreads: force ? true : (originalPermission.permissions! as any).SendMessagesInThreads,
197 AddReactions: force ? true : (originalPermission.permissions! as any).AddReactions
198 };
199
200 const permissionOverwrites = (channel as TextChannel).permissionOverwrites?.cache.get(guild.id);
201
202 if (ignorePrivateChannels && !force) {
203 if (permissionOverwrites?.deny.has(PermissionFlagsBits.ViewChannel, true)) {
204 log("Private channel, skipping lock");
205 countSkipped++;
206 continue;
207 }
208 }
209
210 if (permissionOverwrites) await (channel as TextChannel).permissionOverwrites?.edit(guild.id, options);
211 else await (channel as TextChannel).permissionOverwrites?.create(guild.id, options);
212
213 countSuccess++;
214 } catch (e) {
215 logError(e);
216 countFailed++;
217 }
218 }
219
220 log(originalPermissions);
221
222 if (!force)
223 await this.client.prisma.channelLock.deleteMany({
224 where: {
225 id: {
226 in: originalPermissions.map(permission => permission.id)
227 }
228 }
229 });
230
231 await this.client.logger.logServerLockOrUnlock({
232 guild,
233 action: "Unlocked",
234 moderator,
235 countSuccess,
236 countFailed,
237 countInvalidChannel,
238 countSkipped,
239 reason
240 });
241
242 return {
243 countSuccess,
244 countFailed,
245 countInvalidChannel,
246 countSkipped
247 };
248 }
249
250 async lock(channel: TextChannel, moderator: User, reason?: string) {
251 try {
252 const options = {
253 Connect: false,
254 SendMessages: false,
255 SendMessagesInThreads: false,
256 AddReactions: false
257 };
258
259 const permissionOverwrites = channel.permissionOverwrites?.cache.get(channel.guild.id);
260
261 const permissionJson = {
262 Connect: permissionOverwrites
263 ? getChannelPermissionOverride(PermissionFlagsBits.Connect, permissionOverwrites)
264 : null,
265 SendMessages: permissionOverwrites
266 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessages, permissionOverwrites)
267 : null,
268 SendMessagesInThreads: permissionOverwrites
269 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessagesInThreads, permissionOverwrites)
270 : null,
271 AddReactions: permissionOverwrites
272 ? getChannelPermissionOverride(PermissionFlagsBits.AddReactions, permissionOverwrites)
273 : null
274 };
275
276 if (permissionOverwrites) await channel.permissionOverwrites?.edit(channel.guild.id, options);
277 else await channel.permissionOverwrites?.create(channel.guild.id, options);
278
279 this.client.logger
280 .logChannelLockOrUnlock({
281 guild: channel.guild,
282 action: "Locked",
283 channel,
284 moderator,
285 reason
286 })
287 .catch(logError);
288
289 return await this.client.prisma.channelLock.create({
290 data: {
291 channel_id: channel.id,
292 guild_id: channel.guild.id,
293 permissions: permissionJson
294 }
295 });
296 } catch (e) {
297 logError(e);
298 return null;
299 }
300 }
301
302 async unlock(channel: TextChannel, moderator: User, reason?: string, force?: boolean) {
303 try {
304 const channelLock = await this.client.prisma.channelLock.findFirst({
305 where: {
306 channel_id: channel.id,
307 guild_id: channel.guild.id
308 }
309 });
310
311 if (!channelLock) return null;
312
313 const options = {
314 Connect: force ? true : (channelLock.permissions as any).Connect,
315 SendMessages: force ? true : (channelLock.permissions as any).SendMessages,
316 SendMessagesInThreads: force ? true : (channelLock.permissions as any).SendMessagesInThreads,
317 AddReactions: force ? true : (channelLock.permissions as any).AddReactions
318 };
319
320 const permissionOverwrites = channel.permissionOverwrites?.cache.get(channel.guild.id);
321
322 if (permissionOverwrites) await channel.permissionOverwrites?.edit(channel.guild.id, options);
323 else await channel.permissionOverwrites?.create(channel.guild.id, options);
324
325 this.client.logger
326 .logChannelLockOrUnlock({
327 guild: channel.guild,
328 action: "Unlocked",
329 channel,
330 moderator,
331 reason
332 })
333 .catch(logError);
334
335 return true;
336 } catch (e) {
337 logError(e);
338 return false;
339 }
340 }
341 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26