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

Contents of /branches/5.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: 11720 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(guild: Guild, { reason, moderator, channels = [], channelMode = "include", ignorePrivateChannels = true }: ChannelLockOptions) {
45 let countSuccess = 0,
46 countFailed = 0,
47 countSkipped = 0,
48 countInvalidChannel = 0;
49
50 const originalPermissions = [];
51
52 for (const [, channel] of guild.channels.cache) {
53 log(channel.name);
54
55 if (
56 !this.shouldLock(channels, channel, channelMode) ||
57 ![
58 ChannelType.GuildAnnouncement,
59 ChannelType.GuildCategory,
60 ChannelType.GuildText,
61 ChannelType.GuildVoice,
62 ChannelType.GuildStageVoice,
63 ChannelType.GuildForum
64 ].includes(channel.type)
65 ) {
66 countInvalidChannel++;
67 continue;
68 }
69
70 try {
71 const options = {
72 Connect: false,
73 SendMessages: false,
74 SendMessagesInThreads: false,
75 AddReactions: false
76 };
77
78 const permissionOverwrites = (channel as TextChannel).permissionOverwrites?.cache.get(guild.id);
79
80 if (ignorePrivateChannels) {
81 if (permissionOverwrites?.deny.has(PermissionFlagsBits.ViewChannel, true)) {
82 log("Private channel, skipping lock");
83 countSkipped++;
84 continue;
85 }
86 }
87
88 const permissionJson = {
89 Connect: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.Connect, permissionOverwrites) : null,
90 SendMessages: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.SendMessages, permissionOverwrites) : null,
91 SendMessagesInThreads: permissionOverwrites
92 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessagesInThreads, permissionOverwrites)
93 : null,
94 AddReactions: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.AddReactions, permissionOverwrites) : null
95 };
96
97 originalPermissions.push({
98 channel_id: channel.id,
99 guild_id: guild.id,
100 permissions: permissionJson
101 });
102
103 await (channel as TextChannel).permissionOverwrites?.edit(guild.id, options);
104
105 countSuccess++;
106 } catch (e) {
107 logError(e);
108 countFailed++;
109 }
110 }
111
112 await this.client.prisma.channelLock.createMany({
113 data: originalPermissions
114 });
115
116 log(originalPermissions);
117
118 await this.client.logger.logServerLockOrUnlock({
119 guild,
120 action: "Locked",
121 moderator,
122 countSuccess,
123 countFailed,
124 countInvalidChannel,
125 countSkipped,
126 reason
127 });
128
129 return {
130 countSuccess,
131 countFailed,
132 countInvalidChannel,
133 countSkipped
134 };
135 }
136
137 async unlockGuild(
138 guild: Guild,
139 { channels = [], channelMode = "include", ignorePrivateChannels = true, force, moderator, reason }: ChannelLockOptions & { force?: boolean }
140 ) {
141 let countSuccess = 0,
142 countFailed = 0,
143 countSkipped = 0,
144 countInvalidChannel = 0;
145
146 const originalPermissions = force
147 ? guild.channels.cache.map(c => ({ channel_id: c.id, permissions: {}, id: 0 }))
148 : await this.client.prisma.channelLock.findMany({
149 where: {
150 guild_id: guild.id
151 }
152 });
153
154 for (const originalPermission of originalPermissions) {
155 const channel = guild.channels.cache.get(originalPermission.channel_id);
156
157 if (!channel) continue;
158
159 if (
160 !this.shouldLock(channels, channel, channelMode) ||
161 ![
162 ChannelType.GuildAnnouncement,
163 ChannelType.GuildCategory,
164 ChannelType.GuildText,
165 ChannelType.GuildVoice,
166 ChannelType.GuildStageVoice,
167 ChannelType.GuildForum
168 ].includes(channel.type)
169 ) {
170 countInvalidChannel++;
171 continue;
172 }
173
174 try {
175 const options = {
176 Connect: force ? true : (originalPermission.permissions! as any).Connect,
177 SendMessages: force ? true : (originalPermission.permissions! as any).SendMessages,
178 SendMessagesInThreads: force ? true : (originalPermission.permissions! as any).SendMessagesInThreads,
179 AddReactions: force ? true : (originalPermission.permissions! as any).AddReactions
180 };
181
182 const permissionOverwrites = (channel as TextChannel).permissionOverwrites?.cache.get(guild.id);
183
184 if (ignorePrivateChannels && !force) {
185 if (permissionOverwrites?.deny.has(PermissionFlagsBits.ViewChannel, true)) {
186 log("Private channel, skipping lock");
187 countSkipped++;
188 continue;
189 }
190 }
191
192 if (permissionOverwrites) await (channel as TextChannel).permissionOverwrites?.edit(guild.id, options);
193 else await (channel as TextChannel).permissionOverwrites?.create(guild.id, options);
194
195 countSuccess++;
196 } catch (e) {
197 logError(e);
198 countFailed++;
199 }
200 }
201
202 log(originalPermissions);
203
204 if (!force)
205 await this.client.prisma.channelLock.deleteMany({
206 where: {
207 id: {
208 in: originalPermissions.map(permission => permission.id)
209 }
210 }
211 });
212
213 await this.client.logger.logServerLockOrUnlock({
214 guild,
215 action: "Unlocked",
216 moderator,
217 countSuccess,
218 countFailed,
219 countInvalidChannel,
220 countSkipped,
221 reason
222 });
223
224 return {
225 countSuccess,
226 countFailed,
227 countInvalidChannel,
228 countSkipped
229 };
230 }
231
232 async lock(channel: TextChannel, moderator: User, reason?: string) {
233 try {
234 const options = {
235 Connect: false,
236 SendMessages: false,
237 SendMessagesInThreads: false,
238 AddReactions: false
239 };
240
241 const permissionOverwrites = channel.permissionOverwrites?.cache.get(channel.guild.id);
242
243 const permissionJson = {
244 Connect: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.Connect, permissionOverwrites) : null,
245 SendMessages: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.SendMessages, permissionOverwrites) : null,
246 SendMessagesInThreads: permissionOverwrites
247 ? getChannelPermissionOverride(PermissionFlagsBits.SendMessagesInThreads, permissionOverwrites)
248 : null,
249 AddReactions: permissionOverwrites ? getChannelPermissionOverride(PermissionFlagsBits.AddReactions, permissionOverwrites) : null
250 };
251
252 if (permissionOverwrites) await channel.permissionOverwrites?.edit(channel.guild.id, options);
253 else await channel.permissionOverwrites?.create(channel.guild.id, options);
254
255 this.client.logger
256 .logChannelLockOrUnlock({
257 guild: channel.guild,
258 action: "Locked",
259 channel,
260 moderator,
261 reason
262 })
263 .catch(logError);
264
265 return await this.client.prisma.channelLock.create({
266 data: {
267 channel_id: channel.id,
268 guild_id: channel.guild.id,
269 permissions: permissionJson
270 }
271 });
272 } catch (e) {
273 logError(e);
274 return null;
275 }
276 }
277
278 async unlock(channel: TextChannel, moderator: User, reason?: string, force?: boolean) {
279 try {
280 const channelLock = await this.client.prisma.channelLock.findFirst({
281 where: {
282 channel_id: channel.id,
283 guild_id: channel.guild.id
284 }
285 });
286
287 if (!channelLock) return null;
288
289 const options = {
290 Connect: force ? true : (channelLock.permissions as any).Connect,
291 SendMessages: force ? true : (channelLock.permissions as any).SendMessages,
292 SendMessagesInThreads: force ? true : (channelLock.permissions as any).SendMessagesInThreads,
293 AddReactions: force ? true : (channelLock.permissions as any).AddReactions
294 };
295
296 const permissionOverwrites = channel.permissionOverwrites?.cache.get(channel.guild.id);
297
298 if (permissionOverwrites) await channel.permissionOverwrites?.edit(channel.guild.id, options);
299 else await channel.permissionOverwrites?.create(channel.guild.id, options);
300
301 this.client.logger
302 .logChannelLockOrUnlock({
303 guild: channel.guild,
304 action: "Unlocked",
305 channel,
306 moderator,
307 reason
308 })
309 .catch(logError);
310
311 return true;
312 } catch (e) {
313 logError(e);
314 return false;
315 }
316 }
317 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26