1 |
/** |
2 |
* This file is part of SudoBot. |
3 |
* |
4 |
* Copyright (C) 2021-2022 OSN Inc. |
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 { Client, ClientOptions, Collection, Interaction, Message } from 'discord.js'; |
21 |
import BaseEvent from '../utils/structures/BaseEvent'; |
22 |
import BaseCommand from '../utils/structures/BaseCommand'; |
23 |
import { Config } from './Config'; |
24 |
import Database from './Database'; |
25 |
import path from 'path'; |
26 |
import Logger from '../automod/Logger'; |
27 |
import SnippetManager from '../services/SnippetManager'; |
28 |
import AFKEngine from '../services/AFKEngine'; |
29 |
import Auth from '../services/Auth'; |
30 |
import MessageFilter from '../automod/MessageFilter'; |
31 |
import AntiRaid from '../automod/AntiRaid'; |
32 |
import Starboard from '../services/Starboard'; |
33 |
import Server from '../api/Server'; |
34 |
import StartupManager from '../services/StartupManager'; |
35 |
import AutoClear from '../automod/AutoClear'; |
36 |
import RandomStatus from '../services/RandomStatus'; |
37 |
import DebugLogger, { LogLevel } from '../services/DebugLogger'; |
38 |
import BaseCLICommand from '../utils/structures/BaseCLICommand'; |
39 |
import discordModals from 'discord-modals'; |
40 |
import SpamFilter from '../automod/SpamFilter'; |
41 |
import Verification from '../services/Verification'; |
42 |
import Welcomer from '../services/Welcomer'; |
43 |
import Antijoin from '../automod/Antijoin'; |
44 |
import Automute from '../automod/Automute'; |
45 |
import ServiceManager from './ServiceManager'; |
46 |
import ChannelLockManager from '../services/ChannelLockManager'; |
47 |
import Cooldown from '../services/Cooldown'; |
48 |
import ProfileFilter from '../automod/ProfileFilter'; |
49 |
import QueueManager from '../services/QueueManager'; |
50 |
import Common from '../automod/Common'; |
51 |
import AutoResponder from '../automod/AutoResponder'; |
52 |
import InteractionRoleManager from '../services/InteractionRoleManager'; |
53 |
import MessageRules from '../automod/MessageRules'; |
54 |
import InviteTracker from '../services/InviteTracker'; |
55 |
import Autobackup from '../services/Autobackup'; |
56 |
import AIMessageFilter from '../automod/AIMessageFilter'; |
57 |
import Utilities from '../services/Utilities'; |
58 |
import Translator from '../services/Translator'; |
59 |
import AIChat from '../services/AIChat'; |
60 |
|
61 |
export default class DiscordClient extends Client { |
62 |
private _commands = new Collection<string, BaseCommand>(); |
63 |
private _cliCommands = new Collection<string, BaseCLICommand>(); |
64 |
private _events = new Collection<string, BaseEvent>(); |
65 |
|
66 |
rootdir: string; |
67 |
msg: Message | Interaction | null = null; |
68 |
|
69 |
config: Config; |
70 |
db: Database; |
71 |
server: Server; |
72 |
serviceManager: ServiceManager; |
73 |
|
74 |
logger: Logger = {} as Logger; |
75 |
snippetManager: SnippetManager = {} as SnippetManager; |
76 |
afkEngine: AFKEngine = {} as AFKEngine; |
77 |
auth: Auth = {} as Auth; |
78 |
spamFilter: SpamFilter = {} as SpamFilter; |
79 |
messageFilter: MessageFilter = {} as MessageFilter; |
80 |
antiraid: AntiRaid = {} as AntiRaid; |
81 |
starboard: Starboard = {} as Starboard; |
82 |
startupManager: StartupManager = {} as StartupManager; |
83 |
autoClear: AutoClear = {} as AutoClear; |
84 |
randomStatus: RandomStatus = {} as RandomStatus; |
85 |
debugLogger: DebugLogger = {} as DebugLogger; |
86 |
verification: Verification = {} as Verification; |
87 |
welcomer: Welcomer = {} as Welcomer; |
88 |
antijoin: Antijoin = {} as Antijoin; |
89 |
automute: Automute = {} as Automute; |
90 |
channelLock: ChannelLockManager = {} as ChannelLockManager; |
91 |
cooldown: Cooldown = {} as Cooldown; |
92 |
profileFilter: ProfileFilter = {} as ProfileFilter; |
93 |
queueManager: QueueManager = {} as QueueManager; |
94 |
commonService: Common = {} as Common; |
95 |
autoResponder: AutoResponder = {} as AutoResponder; |
96 |
interactionRoleManager: InteractionRoleManager = {} as InteractionRoleManager; |
97 |
messageRules: MessageRules = {} as MessageRules; |
98 |
inviteTracker: InviteTracker = {} as InviteTracker; |
99 |
autobackup: Autobackup = {} as Autobackup; |
100 |
aiMessageFilter: AIMessageFilter = {} as AIMessageFilter; |
101 |
utils: Utilities = {} as Utilities; |
102 |
translator: Translator = {} as Translator; |
103 |
aiChat: AIChat = {} as AIChat; |
104 |
|
105 |
aliases = { |
106 |
automod: path.resolve(__dirname, '..', 'automod'), |
107 |
services: path.resolve(__dirname, '..', 'services'), |
108 |
}; |
109 |
|
110 |
services = { |
111 |
"@services/DebugLogger": "debugLogger", |
112 |
"@automod/Logger": "logger", |
113 |
"@services/SnippetManager": "snippetManager", |
114 |
"@services/AFKEngine": "afkEngine", |
115 |
"@services/Auth": "auth", |
116 |
"@automod/SpamFilter": "spamFilter", |
117 |
"@automod/MessageFilter": "messageFilter", |
118 |
"@automod/AntiRaid": "antiraid", |
119 |
"@services/Starboard": "starboard", |
120 |
"@services/StartupManager": "startupManager", |
121 |
"@automod/AutoClear": "autoClear", |
122 |
"@services/RandomStatus": "randomStatus", |
123 |
"@services/Verification": "verification", |
124 |
"@services/Welcomer": "welcomer", |
125 |
"@services/ChannelLockManager": "channelLock", |
126 |
"@automod/Antijoin": "antijoin", |
127 |
"@automod/Automute": "automute", |
128 |
"@services/Cooldown": "cooldown", |
129 |
"@automod/ProfileFilter": "profileFilter", |
130 |
"@services/QueueManager": "queueManager", |
131 |
"@services/InteractionRoleManager": "interactionRoleManager", |
132 |
"@automod/Common": "commonService", |
133 |
"@automod/AutoResponder": "autoResponder", |
134 |
"@automod/MessageRules": "messageRules", |
135 |
"@services/InviteTracker": "inviteTracker", |
136 |
"@services/Autobackup": "autobackup", |
137 |
"@automod/AIMessageFilter": "aiMessageFilter", |
138 |
"@services/Utilities": "utils", |
139 |
"@services/Translator": "translator", |
140 |
"@services/AIChat": "aiChat", |
141 |
}; |
142 |
|
143 |
static client: DiscordClient; |
144 |
|
145 |
constructor(options: ClientOptions, rootdir: string = __dirname) { |
146 |
super({ |
147 |
ws: { |
148 |
properties: { |
149 |
browser: "Discord iOS" |
150 |
} |
151 |
}, |
152 |
...options |
153 |
}); |
154 |
|
155 |
process.on('uncaughtException', (error, origin) => { |
156 |
console.log('Uncaught', error); |
157 |
|
158 |
this.handleCrash(error, origin).then(() => process.exit(-1)).catch(err => { |
159 |
console.log(err); |
160 |
process.exit(-1); |
161 |
}); |
162 |
}); |
163 |
|
164 |
this.rootdir = rootdir; |
165 |
|
166 |
DiscordClient.client = this; |
167 |
|
168 |
this.config = new Config(this); |
169 |
this.db = new Database(this); |
170 |
this.serviceManager = new ServiceManager(this, this.aliases); |
171 |
this.serviceManager.load(this.services); |
172 |
this.server = new Server(this); |
173 |
|
174 |
discordModals(this); |
175 |
} |
176 |
|
177 |
get commands(): Collection<string, BaseCommand> { |
178 |
return this._commands; |
179 |
} |
180 |
|
181 |
get cliCommands(): Collection<string, BaseCLICommand> { |
182 |
return this._cliCommands; |
183 |
} |
184 |
|
185 |
get events(): Collection<string, BaseEvent> { |
186 |
return this._events; |
187 |
} |
188 |
|
189 |
setMessage(msg: Message | Interaction) { |
190 |
this.msg = msg; |
191 |
} |
192 |
|
193 |
async handleCrash(error: Error, origin: NodeJS.UncaughtExceptionOrigin) { |
194 |
// await appendFile(path.join(process.env.SUDO_PREFIX ?? (__dirname + "/../../"), "logs", "error.log"), `Uncaught ${error.name}: ${error.message}\n+ ${error.stack}`); |
195 |
await this.debugLogger.logApp(LogLevel.CRITICAL, "An internal error was occurred"); |
196 |
await this.debugLogger.logApp(LogLevel.ERROR, `Uncaught ${error.name}: ${error.message}\n+ ${error.stack}`); |
197 |
await this.debugLogger.logToHomeServer(`Uncaught ${error.name}: ${error.message}\n${error.stack}`); |
198 |
} |
199 |
} |