xernerx 0.1.120-beta.2 → 0.1.120-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/main.cjs +1269 -266
- package/dist/main.cjs.map +1 -1
- package/dist/main.d.cts +651 -116
- package/dist/main.d.ts +651 -116
- package/dist/main.js +1257 -247
- package/dist/main.js.map +1 -1
- package/package.json +31 -18
- package/src/build/XernerxBaseBuilder.ts +21 -0
- package/src/build/XernerxEventBuilder.ts +39 -0
- package/src/build/XernerxMessageCommandBuilder.ts +60 -0
- package/src/build/XernerxSlashCommandBuilder.ts +290 -0
- package/src/client/XernerxClient.ts +173 -151
- package/src/client/XernerxShardClient.ts +89 -0
- package/src/events/clientReady.ts +96 -0
- package/src/events/entitlementCreate.ts +15 -0
- package/src/events/interactionCreate.ts +36 -0
- package/src/events/messageCreate.ts +60 -0
- package/src/events/messageDelete.ts +41 -0
- package/src/events/messageUpdate.ts +60 -0
- package/src/events/slashCommandInteraction.ts +55 -0
- package/src/handler/CommandHandler.ts +132 -0
- package/src/handler/EventHandler.ts +45 -0
- package/src/handler/Handler.ts +98 -0
- package/src/interfaces/XernerxClientOptions.ts +13 -0
- package/src/interfaces/XernerxClientStats.ts +15 -0
- package/src/interfaces/XernerxEventBuilderOptions.ts +9 -0
- package/src/interfaces/XernerxMessageCommandBuilderOptions.ts +8 -0
- package/src/interfaces/XernerxMessageCommandHandlerOptions.ts +15 -0
- package/src/interfaces/XernerxShardClientOptions.ts +5 -0
- package/src/interfaces/XernerxSlashCommand.ts +19 -0
- package/src/interfaces/XernerxSlashCommandBuilderOptions.ts +70 -0
- package/src/interfaces/XernerxSlashCommandHandlerOptions.ts +5 -0
- package/src/main.ts +21 -7
- package/src/model/XernerxGuild.ts +13 -0
- package/src/model/XernerxInteractionArguments.ts +92 -0
- package/src/model/XernerxMonitisation.ts +73 -0
- package/src/model/XernerxUser.ts +82 -0
- package/src/tools/XernerxBase.ts +16 -0
- package/src/tools/XernerxError.ts +16 -0
- package/src/tools/XernerxInfo.ts +13 -0
- package/src/tools/XernerxInitial.ts +28 -0
- package/src/tools/XernerxSuccess.ts +13 -0
- package/src/tools/XernerxWarn.ts +13 -0
- package/src/types/Events.d.ts +21 -0
- package/src/types/Interaction.d.ts +90 -0
- package/src/types/Message.d.ts +16 -0
- package/src/util/XernerxInteractionUtil.ts +82 -0
- package/src/util/XernerxMessageUtil.ts +105 -0
- package/src/util/XernerxUtil.ts +47 -0
- package/src/validators/XernerxBaseValidator.ts +82 -0
- package/src/validators/XernerxSlashCommandValidator.ts +11 -0
- package/dist/main.global.js +0 -88544
- package/dist/main.global.js.map +0 -1
- package/src/base/XernerxContextCommand.ts +0 -24
- package/src/base/XernerxEvent.ts +0 -21
- package/src/base/XernerxInhibitor.ts +0 -21
- package/src/base/XernerxMessageCommand.ts +0 -24
- package/src/base/XernerxSlashCommand.ts +0 -26
- package/src/handlers/CommandHandler.ts +0 -31
- package/src/handlers/Handler.ts +0 -57
- package/src/tools/XernerxLog.ts +0 -58
- package/src/types/interfaces.ts +0 -25
- package/src/types/types.ts +0 -29
- package/src/util/ClientUtil.ts +0 -29
- package/src/util/Util.ts +0 -11
- package/src/util/prompts.ts +0 -120
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/** @format */
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import {
|
|
5
|
+
ApplicationIntegrationType,
|
|
6
|
+
ChannelType,
|
|
7
|
+
InteractionContextType,
|
|
8
|
+
Locale,
|
|
9
|
+
PermissionFlags,
|
|
10
|
+
PermissionFlagsBits,
|
|
11
|
+
Permissions,
|
|
12
|
+
RestOrArray,
|
|
13
|
+
SlashCommandBooleanOption,
|
|
14
|
+
SlashCommandBuilder,
|
|
15
|
+
SlashCommandChannelOption,
|
|
16
|
+
SlashCommandIntegerOption,
|
|
17
|
+
SlashCommandMentionableOption,
|
|
18
|
+
SlashCommandNumberOption,
|
|
19
|
+
SlashCommandRoleOption,
|
|
20
|
+
SlashCommandStringOption,
|
|
21
|
+
SlashCommandSubcommandBuilder,
|
|
22
|
+
SlashCommandSubcommandGroupBuilder,
|
|
23
|
+
SlashCommandUserOption,
|
|
24
|
+
} from 'discord.js';
|
|
25
|
+
|
|
26
|
+
import { XernerxWarn } from '../tools/XernerxWarn.js';
|
|
27
|
+
import {
|
|
28
|
+
XernerxSlashCommandBuilderGroup,
|
|
29
|
+
XernerxSlashCommandBuilderOption,
|
|
30
|
+
XernerxSlashCommandBuilderOptions,
|
|
31
|
+
XernerxSlashCommandBuilderSubcommand,
|
|
32
|
+
} from '../interfaces/XernerxSlashCommandBuilderOptions.js';
|
|
33
|
+
import { XernerxBaseBuilder } from './XernerxBaseBuilder.js';
|
|
34
|
+
import { XernerxSlashCommand, XernerxSlashCommandAutocomplete } from '../interfaces/XernerxSlashCommand.js';
|
|
35
|
+
|
|
36
|
+
export class XernerxSlashCommandBuilder extends XernerxBaseBuilder {
|
|
37
|
+
// Discord
|
|
38
|
+
declare public readonly name: string;
|
|
39
|
+
declare public readonly description: string;
|
|
40
|
+
declare public readonly integration: RestOrArray<InteractionContextType>;
|
|
41
|
+
declare public readonly data: SlashCommandBuilder;
|
|
42
|
+
declare public readonly options: Array<XernerxSlashCommandBuilderOption>;
|
|
43
|
+
declare public readonly subcommands: Array<XernerxSlashCommandBuilderSubcommand>;
|
|
44
|
+
declare public readonly groups: Array<XernerxSlashCommandBuilderGroup>;
|
|
45
|
+
|
|
46
|
+
// Xernerx
|
|
47
|
+
declare public readonly premium?: boolean;
|
|
48
|
+
declare public readonly defer?: boolean;
|
|
49
|
+
declare public readonly deploy?: { global?: boolean; guilds?: Array<string> | string };
|
|
50
|
+
declare public readonly info?: string;
|
|
51
|
+
declare public readonly usage?: string;
|
|
52
|
+
declare public readonly category?: string;
|
|
53
|
+
declare public readonly cooldown?: number;
|
|
54
|
+
declare public readonly permissions: { client: Permissions | number | bigint | null; user: Permissions | number | bigint | null };
|
|
55
|
+
declare public readonly strict?: { owner?: boolean; users?: Array<string>; channels?: Array<string>; guilds?: Array<string>; types?: ChannelType };
|
|
56
|
+
declare public readonly ignore?: { owner?: boolean; users?: Array<string>; channels?: Array<string>; guilds?: Array<string>; types?: ChannelType };
|
|
57
|
+
|
|
58
|
+
// Static
|
|
59
|
+
declare public readonly filetype: 'XernerxSlashCommand';
|
|
60
|
+
|
|
61
|
+
constructor(id: string, options: XernerxSlashCommandBuilderOptions) {
|
|
62
|
+
super(id, options);
|
|
63
|
+
|
|
64
|
+
options = z
|
|
65
|
+
.object({
|
|
66
|
+
// Discord
|
|
67
|
+
name: z.string(),
|
|
68
|
+
locales: z.record(z.string(), z.object({ name: z.string(), description: z.string() })).optional(),
|
|
69
|
+
description: z.string(),
|
|
70
|
+
contexts: z.array(z.custom<keyof typeof InteractionContextType>()).default(['Guild']),
|
|
71
|
+
integration: z.array(z.custom<keyof typeof ApplicationIntegrationType>()).default(['GuildInstall']),
|
|
72
|
+
nsfw: z.boolean().default(false),
|
|
73
|
+
options: z.any(),
|
|
74
|
+
subcommands: z.any(),
|
|
75
|
+
groups: z.any(),
|
|
76
|
+
|
|
77
|
+
// Xernerx
|
|
78
|
+
premium: z.boolean().default(false),
|
|
79
|
+
defer: z.boolean().default(false),
|
|
80
|
+
deploy: z.object({ global: z.boolean().default(true), guilds: z.string().or(z.array(z.string())).default([]) }).optional(),
|
|
81
|
+
info: z.string().optional(),
|
|
82
|
+
usage: z.string().optional(),
|
|
83
|
+
category: z.string().optional(),
|
|
84
|
+
cooldown: z.number().min(0).default(0),
|
|
85
|
+
strict: z
|
|
86
|
+
.object({
|
|
87
|
+
owner: z.boolean().default(false),
|
|
88
|
+
users: z.array(z.string()).default([]),
|
|
89
|
+
channels: z.array(z.string()).default([]),
|
|
90
|
+
guilds: z.array(z.string()).default([]),
|
|
91
|
+
types: z.enum(ChannelType).optional(),
|
|
92
|
+
})
|
|
93
|
+
.optional(),
|
|
94
|
+
ignore: z
|
|
95
|
+
.object({
|
|
96
|
+
owner: z.boolean().default(false),
|
|
97
|
+
users: z.array(z.string()).default([]),
|
|
98
|
+
channels: z.array(z.string()).default([]),
|
|
99
|
+
guilds: z.array(z.string()).default([]),
|
|
100
|
+
types: z.enum(ChannelType).optional(),
|
|
101
|
+
})
|
|
102
|
+
.optional(),
|
|
103
|
+
permissions: z
|
|
104
|
+
.object({
|
|
105
|
+
client: z
|
|
106
|
+
.union([z.array(z.custom<keyof PermissionFlags>()), z.number(), z.bigint()])
|
|
107
|
+
.nullable()
|
|
108
|
+
.default(null),
|
|
109
|
+
user: z
|
|
110
|
+
.union([z.array(z.custom<keyof PermissionFlags>()), z.number(), z.bigint()])
|
|
111
|
+
.nullable()
|
|
112
|
+
.default(null),
|
|
113
|
+
})
|
|
114
|
+
.default({ client: null, user: null }),
|
|
115
|
+
})
|
|
116
|
+
.parse(options);
|
|
117
|
+
|
|
118
|
+
this.name = options.name;
|
|
119
|
+
|
|
120
|
+
this.description = options.description;
|
|
121
|
+
|
|
122
|
+
this.info = options.info;
|
|
123
|
+
|
|
124
|
+
this.usage = options.usage;
|
|
125
|
+
|
|
126
|
+
this.category = options.category;
|
|
127
|
+
|
|
128
|
+
this.cooldown = options.cooldown;
|
|
129
|
+
|
|
130
|
+
this.premium = options.premium || false;
|
|
131
|
+
|
|
132
|
+
this.defer = options.defer;
|
|
133
|
+
|
|
134
|
+
this.deploy = {
|
|
135
|
+
global: options.deploy?.global ?? true,
|
|
136
|
+
guilds: typeof options.deploy?.guilds == 'string' ? [options.deploy.guilds] : options.deploy?.guilds || [],
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
this.filetype = 'XernerxSlashCommand';
|
|
140
|
+
|
|
141
|
+
this.permissions = options.permissions as typeof this.permissions;
|
|
142
|
+
|
|
143
|
+
this.strict = options.strict;
|
|
144
|
+
|
|
145
|
+
this.ignore = options.ignore;
|
|
146
|
+
|
|
147
|
+
this.data = new SlashCommandBuilder();
|
|
148
|
+
|
|
149
|
+
this.data.setName(this.name);
|
|
150
|
+
|
|
151
|
+
this.data.setDescription(this.description);
|
|
152
|
+
|
|
153
|
+
this.data.setContexts(...(options.contexts?.map((context) => InteractionContextType[context as keyof typeof InteractionContextType]) || [InteractionContextType.Guild]));
|
|
154
|
+
|
|
155
|
+
this.data.setIntegrationTypes(
|
|
156
|
+
...(options.integration?.map((integration) => ApplicationIntegrationType[integration as keyof typeof ApplicationIntegrationType]) || [ApplicationIntegrationType.GuildInstall])
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
if (Array.isArray(options.permissions?.user))
|
|
160
|
+
this.data.setDefaultMemberPermissions(options.permissions?.user?.map((permission) => PermissionFlagsBits[permission as keyof PermissionFlags]).reduce((a, b) => (a += b)));
|
|
161
|
+
else this.data.setDefaultMemberPermissions(options.permissions?.user || null);
|
|
162
|
+
|
|
163
|
+
this.data.setNSFW(options.nsfw || false);
|
|
164
|
+
|
|
165
|
+
for (const locale of Object.entries(options.locales || [])) {
|
|
166
|
+
this.data.setNameLocalization(locale[0] as Locale, locale[1].name);
|
|
167
|
+
this.data.setDescriptionLocalization(locale[0] as Locale, locale[1].description);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (options.options && options?.options?.length > 0) {
|
|
171
|
+
this.addArguments(this.data, options.options);
|
|
172
|
+
|
|
173
|
+
this.options = options.options;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (options.subcommands && options?.subcommands?.length > 0) {
|
|
177
|
+
this.addSubcommands(this.data, options.subcommands);
|
|
178
|
+
|
|
179
|
+
this.subcommands = options.subcommands;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (options.groups && options?.groups?.length > 0) {
|
|
183
|
+
this.addSubcommandGroups(options.groups);
|
|
184
|
+
|
|
185
|
+
this.groups = options.groups;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this.client = this.client;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Handles the autocomplete functionality for a slash command.
|
|
193
|
+
*
|
|
194
|
+
* @param args - The arguments for the autocomplete function, which include the context and options for the command.
|
|
195
|
+
* @returns A promise that resolves to either void or any value, depending on the implementation.
|
|
196
|
+
*/
|
|
197
|
+
public async autocomplete(args: XernerxSlashCommandAutocomplete): Promise<void | any> {}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Evaluates conditions for executing a slash command.
|
|
201
|
+
*
|
|
202
|
+
* @param args - The arguments for the conditions function, which include the context and options for the command.
|
|
203
|
+
* @returns A promise that resolves to either void or any value, depending on the implementation.
|
|
204
|
+
*/
|
|
205
|
+
public async conditions(args: XernerxSlashCommand): Promise<void | any> {}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Executes the slash command.
|
|
209
|
+
*
|
|
210
|
+
* @param args - The arguments for the exec function, which include the context and options for the command.
|
|
211
|
+
* @returns A promise that resolves to either void or any value, depending on the implementation.
|
|
212
|
+
*/
|
|
213
|
+
public async exec(args: XernerxSlashCommand): Promise<void | any> {
|
|
214
|
+
new XernerxWarn(`${this.id} has no exec function, command will not respond.`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
private addArguments(command: SlashCommandBuilder | SlashCommandSubcommandBuilder, args: Array<XernerxSlashCommandBuilderOption>) {
|
|
218
|
+
for (const argument of args) {
|
|
219
|
+
let slashCommandArgumentType: string = `${argument.type.charAt(0).toUpperCase()}${argument.type.slice(1).toLowerCase()}`;
|
|
220
|
+
|
|
221
|
+
(command[`add${slashCommandArgumentType as UpperCasedSlashCommandArgumentOptions}Option`] as Function)((option: SlashCommandOption) => {
|
|
222
|
+
option
|
|
223
|
+
.setName(argument.name)
|
|
224
|
+
.setDescription(argument.description)
|
|
225
|
+
.setRequired(argument.required || false);
|
|
226
|
+
|
|
227
|
+
for (const locale of Object.entries(argument.locales || [])) {
|
|
228
|
+
option.setNameLocalization(locale[0] as Locale, locale[1].name);
|
|
229
|
+
option.setDescriptionLocalization(locale[0] as Locale, locale[1].description);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (slashCommandArgumentType === 'String') {
|
|
233
|
+
if (argument.choices) {
|
|
234
|
+
for (const choice of argument.choices) {
|
|
235
|
+
const locales = choice?.locales;
|
|
236
|
+
|
|
237
|
+
(option as SlashCommandStringOption).addChoices({ ...choice, name_localizations: locales });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (argument.maxLength) (option as SlashCommandStringOption).setMaxLength(argument.maxLength);
|
|
242
|
+
if (argument.minLength) (option as SlashCommandStringOption).setMinLength(argument.minLength);
|
|
243
|
+
|
|
244
|
+
(option as SlashCommandStringOption).setAutocomplete(argument.autocomplete || false);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return option;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private addSubcommands(method: SlashCommandBuilder | SlashCommandSubcommandGroupBuilder, subcommands: Array<XernerxSlashCommandBuilderSubcommand>) {
|
|
253
|
+
for (const subcommand of subcommands) {
|
|
254
|
+
let sub = new SlashCommandSubcommandBuilder().setName(subcommand.name).setDescription(subcommand.description);
|
|
255
|
+
|
|
256
|
+
for (const locale of Object.entries(subcommand.locales || [])) {
|
|
257
|
+
sub.setNameLocalization(locale[0] as Locale, locale[1].name);
|
|
258
|
+
sub.setDescriptionLocalization(locale[0] as Locale, locale[1].description);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (subcommand.options && subcommand?.options?.length > 0) this.addArguments(sub, subcommand.options);
|
|
262
|
+
|
|
263
|
+
method.addSubcommand(sub);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Adds subcommand groups to the slash command builder.
|
|
269
|
+
*
|
|
270
|
+
* @param groups - An array of subcommand groups to be added. Each group contains a name, description, locales, and subcommands.
|
|
271
|
+
*/
|
|
272
|
+
private addSubcommandGroups(groups: Array<XernerxSlashCommandBuilderGroup>) {
|
|
273
|
+
for (const group of groups) {
|
|
274
|
+
let subcommandGroup = new SlashCommandSubcommandGroupBuilder().setName(group.name).setDescription(group.description);
|
|
275
|
+
|
|
276
|
+
for (const locale of Object.entries(group.locales || [])) {
|
|
277
|
+
subcommandGroup.setNameLocalization(locale[0] as Locale, locale[1].name);
|
|
278
|
+
subcommandGroup.setDescriptionLocalization(locale[0] as Locale, locale[1].description);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (group.subcommands?.length > 0) this.addSubcommands(subcommandGroup, group.subcommands);
|
|
282
|
+
|
|
283
|
+
this.data.addSubcommandGroup(subcommandGroup);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
type UpperCasedSlashCommandArgumentOptions = 'Attachment' | 'Boolean' | 'Channel' | 'Integer' | 'Mentionable' | 'Number' | 'Role' | 'String' | 'User';
|
|
289
|
+
type SlashCommandOption = SlashCommandOptionChoices | SlashCommandBooleanOption | SlashCommandUserOption | SlashCommandChannelOption | SlashCommandRoleOption | SlashCommandMentionableOption;
|
|
290
|
+
type SlashCommandOptionChoices = SlashCommandStringOption | SlashCommandNumberOption | SlashCommandIntegerOption;
|
|
@@ -1,151 +1,173 @@
|
|
|
1
|
-
/** @format */
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
1
|
+
/** @format */
|
|
2
|
+
|
|
3
|
+
import { Client, ClientOptions, Collection, RESTGetAPISKUsResult } from 'discord.js';
|
|
4
|
+
import sharpyy from 'sharpyy';
|
|
5
|
+
import { ClusterClient, DjsDiscordClient, getInfo } from 'discord-hybrid-sharding';
|
|
6
|
+
import z from 'zod';
|
|
7
|
+
|
|
8
|
+
import { XernerxClientOptions } from '../interfaces/XernerxClientOptions.js';
|
|
9
|
+
import { XernerxInfo } from '../tools/XernerxInfo.js';
|
|
10
|
+
import { XernerxClientStats } from '../interfaces/XernerxClientStats.js';
|
|
11
|
+
import { XernerxInitial } from '../tools/XernerxInitial.js';
|
|
12
|
+
import { XernerxError } from '../tools/XernerxError.js';
|
|
13
|
+
import { XernerxSuccess } from '../tools/XernerxSuccess.js';
|
|
14
|
+
import { XernerxMonitisation } from '../model/XernerxMonitisation.js';
|
|
15
|
+
import { EventHandler } from '../handler/EventHandler.js';
|
|
16
|
+
import { XernerxEventBuilder } from '../build/XernerxEventBuilder.js';
|
|
17
|
+
import { CommandHandler } from '../handler/CommandHandler.js';
|
|
18
|
+
import { XernerxMessageCommandBuilder } from '../build/XernerxMessageCommandBuilder.js';
|
|
19
|
+
import { XernerxMessageCommandHandlerOptions } from '../interfaces/XernerxMessageCommandHandlerOptions.js';
|
|
20
|
+
import { XernerxSlashCommandHandlerOptions } from '../interfaces/XernerxSlashCommandHandlerOptions.js';
|
|
21
|
+
import { XernerxSlashCommandBuilder } from '../build/XernerxSlashCommandBuilder.js';
|
|
22
|
+
|
|
23
|
+
export class XernerxClient extends Client {
|
|
24
|
+
// Config
|
|
25
|
+
declare public readonly token: string;
|
|
26
|
+
declare public readonly sharded: boolean;
|
|
27
|
+
declare public readonly settings: XernerxClientOptions;
|
|
28
|
+
declare public readonly premium: {
|
|
29
|
+
owners?: boolean;
|
|
30
|
+
consume?: boolean;
|
|
31
|
+
synchronize?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Setup
|
|
35
|
+
declare public readonly monitisation: { skus: RESTGetAPISKUsResult };
|
|
36
|
+
declare public readonly stats: XernerxClientStats;
|
|
37
|
+
declare public readonly cluster: ClusterClient | null;
|
|
38
|
+
declare public readonly cache: { messages: Collection<string, string>; slash: Collection<string, string> };
|
|
39
|
+
declare public readonly handler: { message: XernerxMessageCommandHandlerOptions; slash: XernerxSlashCommandHandlerOptions };
|
|
40
|
+
|
|
41
|
+
// Collections
|
|
42
|
+
declare public readonly commands: {
|
|
43
|
+
message: Collection<string, XernerxMessageCommandBuilder>;
|
|
44
|
+
slash: Collection<string, XernerxSlashCommandBuilder>;
|
|
45
|
+
};
|
|
46
|
+
declare public readonly events: Collection<string, XernerxEventBuilder>;
|
|
47
|
+
|
|
48
|
+
// Handlers
|
|
49
|
+
declare public readonly modules: { eventHandler: EventHandler; commandHandler: CommandHandler };
|
|
50
|
+
|
|
51
|
+
constructor(options: ClientOptions & XernerxClientOptions) {
|
|
52
|
+
try {
|
|
53
|
+
options.shards = getInfo().SHARD_LIST;
|
|
54
|
+
options.shardCount = getInfo().TOTAL_SHARDS;
|
|
55
|
+
} catch {
|
|
56
|
+
new XernerxInitial('Client');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
super(options);
|
|
60
|
+
|
|
61
|
+
this.settings = z
|
|
62
|
+
.object({
|
|
63
|
+
token: z.string(),
|
|
64
|
+
global: z.boolean().default(false),
|
|
65
|
+
guildId: z.string().or(z.array(z.string()).max(5)).default([]),
|
|
66
|
+
owners: z.string().or(z.array(z.string()).max(5)).default([]),
|
|
67
|
+
premium: z
|
|
68
|
+
.object({
|
|
69
|
+
owners: z.boolean().default(true),
|
|
70
|
+
consume: z.boolean().default(true),
|
|
71
|
+
synchronize: z.boolean().default(true),
|
|
72
|
+
})
|
|
73
|
+
.optional(),
|
|
74
|
+
})
|
|
75
|
+
.parse(options);
|
|
76
|
+
|
|
77
|
+
this.sharded = options.shardCount ? true : false;
|
|
78
|
+
this.token = options.token as string;
|
|
79
|
+
|
|
80
|
+
this.settings.guildId = typeof this.settings.guildId == 'string' ? [this.settings.guildId] : this.settings.guildId;
|
|
81
|
+
this.settings.owners = typeof this.settings.owners == 'string' ? [this.settings.owners] : this.settings.owners;
|
|
82
|
+
|
|
83
|
+
this.premium = this.settings.premium || {
|
|
84
|
+
owners: true,
|
|
85
|
+
consume: true,
|
|
86
|
+
synchronize: true,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
delete this.settings.premium;
|
|
90
|
+
|
|
91
|
+
this.monitisation = { skus: [] };
|
|
92
|
+
|
|
93
|
+
this.stats = {
|
|
94
|
+
onlineSince: Number(new Date()),
|
|
95
|
+
guildCount: null,
|
|
96
|
+
userCount: null,
|
|
97
|
+
shardCount: null,
|
|
98
|
+
voteCount: null,
|
|
99
|
+
shard: null,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
this.cache = { messages: new Collection(), slash: new Collection() };
|
|
103
|
+
|
|
104
|
+
this.handler = {
|
|
105
|
+
message: { directory: null },
|
|
106
|
+
slash: { directory: null },
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
this.commands = { message: new Collection(), slash: new Collection() };
|
|
110
|
+
|
|
111
|
+
this.events = new Collection();
|
|
112
|
+
|
|
113
|
+
if (this.sharded) this.cluster = new ClusterClient(this as unknown as DjsDiscordClient);
|
|
114
|
+
|
|
115
|
+
this.modules = { eventHandler: new EventHandler(this), commandHandler: new CommandHandler(this) };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Connects the client to Discord and initializes various client statistics and handlers.
|
|
120
|
+
*
|
|
121
|
+
* @returns A promise that resolves when the client successfully logs in, or rejects with an error message if the login fails.
|
|
122
|
+
*/
|
|
123
|
+
async connect() {
|
|
124
|
+
new XernerxInfo(`${this.cluster ? `${sharpyy(`Shard ${this.cluster.id}`, 'txCyan')} | ` : ''}Connecting...`);
|
|
125
|
+
|
|
126
|
+
this.on('clientReady', async (client) => {
|
|
127
|
+
this.monitisation.skus = await new XernerxMonitisation(client).sku();
|
|
128
|
+
|
|
129
|
+
/** When the client is sharded */
|
|
130
|
+
if (this.sharded && this.cluster) {
|
|
131
|
+
this.stats.shard = {
|
|
132
|
+
shardId: this.cluster.id,
|
|
133
|
+
onlineSince: Number(new Date()),
|
|
134
|
+
guildCount: null,
|
|
135
|
+
userCount: null,
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
setInterval(async () => {
|
|
139
|
+
if (!this.cluster || !this.stats.shard) return;
|
|
140
|
+
|
|
141
|
+
this.stats.guildCount = (await this.cluster.broadcastEval('this.guilds.cache.size')).reduce((a, b) => a + b, 0);
|
|
142
|
+
this.stats.userCount = (await this.cluster.broadcastEval('this.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0)')).reduce((a, b) => a + b, 0);
|
|
143
|
+
this.stats.shardCount = getInfo().TOTAL_SHARDS;
|
|
144
|
+
this.stats.shard.guildCount = client.guilds.cache.size;
|
|
145
|
+
this.stats.voteCount = 0;
|
|
146
|
+
this.stats.shard.userCount = client.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0);
|
|
147
|
+
}, 1000);
|
|
148
|
+
|
|
149
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
150
|
+
|
|
151
|
+
new XernerxSuccess(
|
|
152
|
+
`${sharpyy(`Shard ${this.cluster.id}`, 'txCyan')} | Signed in as ${sharpyy(client.user?.tag, 'txBlue')}, watching ${sharpyy(String(this.stats.shard?.guildCount?.toLocaleString()), 'txCyan')} guilds and users: ${sharpyy(String(this.stats.shard?.userCount?.toLocaleString()), 'txCyan')}`
|
|
153
|
+
);
|
|
154
|
+
} else {
|
|
155
|
+
/** When the client is standalone */
|
|
156
|
+
setInterval(() => {
|
|
157
|
+
this.stats.guildCount = client.guilds.cache.size;
|
|
158
|
+
this.stats.userCount = client.guilds.cache.map((a) => a.memberCount).reduce((a, b) => a + b, 0);
|
|
159
|
+
this.stats.voteCount = 0;
|
|
160
|
+
this.stats.shardCount = 0;
|
|
161
|
+
}, 1000);
|
|
162
|
+
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
164
|
+
|
|
165
|
+
new XernerxSuccess(
|
|
166
|
+
`Signed in as ${sharpyy(client.user?.tag, 'txBlue')}, watching ${sharpyy(String(this.stats.guildCount?.toLocaleString()), 'txCyan')} guilds and users: ${sharpyy(String(this.stats.userCount?.toLocaleString()), 'txCyan')}`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return await this.login(this.token).catch((error) => new XernerxError(error.message, 1));
|
|
172
|
+
}
|
|
173
|
+
}
|