djs-selfbot-v13 3.1.5 → 3.1.7
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 +674 -0
- package/README.md +42 -15
- package/package.json +24 -9
- package/src/client/BaseClient.js +3 -2
- package/src/client/Client.js +539 -187
- package/src/client/actions/Action.js +13 -18
- package/src/client/actions/ActionsManager.js +1 -7
- package/src/client/actions/AutoModerationActionExecution.js +0 -1
- package/src/client/actions/AutoModerationRuleCreate.js +0 -1
- package/src/client/actions/AutoModerationRuleDelete.js +0 -1
- package/src/client/actions/AutoModerationRuleUpdate.js +0 -1
- package/src/client/actions/GuildMemberRemove.js +1 -1
- package/src/client/actions/GuildMemberUpdate.js +1 -1
- package/src/client/actions/InteractionCreate.js +115 -0
- package/src/client/actions/MessageCreate.js +4 -0
- package/src/client/actions/PresenceUpdate.js +16 -17
- package/src/client/websocket/WebSocketManager.js +31 -11
- package/src/client/websocket/WebSocketShard.js +38 -39
- package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
- package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
- package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
- package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +13 -16
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
- package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
- package/src/client/websocket/handlers/GUILD_CREATE.js +0 -7
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +1 -1
- package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
- package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +0 -1
- package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
- package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
- package/src/client/websocket/handlers/READY.js +137 -47
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +5 -7
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +4 -6
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +9 -32
- package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +8 -2
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -1
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
- package/src/client/websocket/handlers/index.js +20 -15
- package/src/errors/Messages.js +69 -24
- package/src/index.js +43 -12
- package/src/managers/ApplicationCommandManager.js +12 -9
- package/src/managers/ApplicationCommandPermissionsManager.js +11 -3
- package/src/managers/ChannelManager.js +4 -2
- package/src/managers/ClientUserSettingManager.js +279 -161
- package/src/managers/DeveloperPortalManager.js +104 -0
- package/src/managers/GuildApplicationCommandManager.js +28 -0
- package/src/managers/GuildBanManager.js +1 -1
- package/src/managers/GuildChannelManager.js +0 -2
- package/src/managers/GuildFolderManager.js +24 -0
- package/src/managers/GuildForumThreadManager.js +28 -22
- package/src/managers/GuildMemberManager.js +216 -40
- package/src/managers/GuildSettingManager.js +15 -22
- package/src/managers/MessageManager.js +44 -42
- package/src/managers/PermissionOverwriteManager.js +1 -1
- package/src/managers/ReactionUserManager.js +5 -5
- package/src/managers/RelationshipManager.js +74 -81
- package/src/managers/SessionManager.js +57 -0
- package/src/managers/ThreadManager.js +45 -12
- package/src/managers/ThreadMemberManager.js +1 -1
- package/src/managers/UserManager.js +10 -6
- package/src/rest/APIRequest.js +20 -42
- package/src/rest/CaptchaSolver.js +132 -0
- package/src/rest/DiscordAPIError.js +16 -17
- package/src/rest/RESTManager.js +21 -1
- package/src/rest/RequestHandler.js +21 -35
- package/src/structures/ApplicationCommand.js +456 -19
- package/src/structures/ApplicationRoleConnectionMetadata.js +0 -3
- package/src/structures/AutoModerationRule.js +5 -5
- package/src/structures/AutocompleteInteraction.js +0 -1
- package/src/structures/BaseGuildTextChannel.js +12 -10
- package/src/structures/BaseGuildVoiceChannel.js +18 -16
- package/src/structures/{CallState.js → Call.js} +12 -17
- package/src/structures/CategoryChannel.js +0 -2
- package/src/structures/Channel.js +3 -2
- package/src/structures/ClientApplication.js +204 -0
- package/src/structures/ClientPresence.js +8 -12
- package/src/structures/ClientUser.js +338 -117
- package/src/structures/ContextMenuInteraction.js +1 -1
- package/src/structures/DMChannel.js +92 -29
- package/src/structures/DeveloperPortalApplication.js +520 -0
- package/src/structures/ForumChannel.js +10 -0
- package/src/structures/Guild.js +271 -135
- package/src/structures/GuildAuditLogs.js +5 -0
- package/src/structures/GuildChannel.js +2 -16
- package/src/structures/GuildFolder.js +75 -0
- package/src/structures/GuildMember.js +145 -27
- package/src/structures/Interaction.js +62 -1
- package/src/structures/InteractionResponse.js +114 -0
- package/src/structures/Invite.js +52 -35
- package/src/structures/Message.js +202 -222
- package/src/structures/MessageAttachment.js +0 -11
- package/src/structures/MessageButton.js +67 -1
- package/src/structures/MessageEmbed.js +1 -1
- package/src/structures/MessageMentions.js +2 -3
- package/src/structures/MessagePayload.js +46 -4
- package/src/structures/MessageReaction.js +1 -1
- package/src/structures/MessageSelectMenu.js +252 -1
- package/src/structures/Modal.js +180 -75
- package/src/structures/PartialGroupDMChannel.js +433 -0
- package/src/structures/Presence.js +2 -2
- package/src/structures/RichPresence.js +34 -14
- package/src/structures/Role.js +2 -18
- package/src/structures/SelectMenuInteraction.js +151 -2
- package/src/structures/Session.js +81 -0
- package/src/structures/Team.js +49 -0
- package/src/structures/TextInputComponent.js +70 -0
- package/src/structures/ThreadChannel.js +19 -0
- package/src/structures/User.js +345 -117
- package/src/structures/UserContextMenuInteraction.js +2 -2
- package/src/structures/VoiceState.js +39 -74
- package/src/structures/WebEmbed.js +52 -38
- package/src/structures/Webhook.js +11 -17
- package/src/structures/interfaces/Application.js +23 -146
- package/src/structures/interfaces/TextBasedChannel.js +256 -411
- package/src/util/ApplicationFlags.js +1 -1
- package/src/util/Constants.js +284 -106
- package/src/util/Formatters.js +2 -16
- package/src/util/LimitedCollection.js +1 -1
- package/src/util/Options.js +68 -48
- package/src/util/Permissions.js +0 -5
- package/src/util/PurchasedFlags.js +0 -2
- package/src/util/RemoteAuth.js +356 -221
- package/src/util/Sweepers.js +1 -1
- package/src/util/Util.js +36 -76
- package/src/util/Voice.js +1456 -0
- package/src/util/arRPC/index.js +229 -0
- package/src/util/arRPC/process/detectable.json +1 -0
- package/src/util/arRPC/process/index.js +102 -0
- package/src/util/arRPC/process/native/index.js +5 -0
- package/src/util/arRPC/process/native/linux.js +37 -0
- package/src/util/arRPC/process/native/win32.js +25 -0
- package/src/util/arRPC/transports/ipc.js +281 -0
- package/src/util/arRPC/transports/websocket.js +128 -0
- package/typings/enums.d.ts +73 -18
- package/typings/index.d.ts +1250 -898
- package/typings/rawDataTypes.d.ts +9 -68
- package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +0 -78
- package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +0 -12
- package/src/managers/UserNoteManager.js +0 -53
- package/src/structures/GroupDMChannel.js +0 -387
- package/src/util/AttachmentFlags.js +0 -38
- package/src/util/InviteFlags.js +0 -29
- package/src/util/RoleFlags.js +0 -37
|
@@ -130,7 +130,7 @@ class GuildBanManager extends CachedManager {
|
|
|
130
130
|
* @typedef {Object} BanOptions
|
|
131
131
|
* @property {number} [days=0] Number of days of messages to delete, must be between 0 and 7, inclusive
|
|
132
132
|
* <warn>This property is deprecated. Use `deleteMessageSeconds` instead.</warn>
|
|
133
|
-
* @property {number} [deleteMessageSeconds] Number of seconds of messages to delete,
|
|
133
|
+
* @property {number} [deleteMessageSeconds=0] Number of seconds of messages to delete,
|
|
134
134
|
* must be between 0 and 604800 (7 days), inclusive
|
|
135
135
|
* @property {string} [reason] The reason for the ban
|
|
136
136
|
*/
|
|
@@ -150,7 +150,6 @@ class GuildChannelManager extends CachedManager {
|
|
|
150
150
|
defaultReactionEmoji,
|
|
151
151
|
defaultSortOrder,
|
|
152
152
|
defaultForumLayout,
|
|
153
|
-
defaultThreadRateLimitPerUser,
|
|
154
153
|
reason,
|
|
155
154
|
} = {},
|
|
156
155
|
) {
|
|
@@ -192,7 +191,6 @@ class GuildChannelManager extends CachedManager {
|
|
|
192
191
|
default_reaction_emoji: defaultReactionEmoji && transformGuildDefaultReaction(defaultReactionEmoji),
|
|
193
192
|
default_sort_order: sortMode,
|
|
194
193
|
default_forum_layout: layoutMode,
|
|
195
|
-
default_thread_rate_limit_per_user: defaultThreadRateLimitPerUser,
|
|
196
194
|
},
|
|
197
195
|
reason,
|
|
198
196
|
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { Collection } = require('@discordjs/collection');
|
|
4
|
+
const BaseManager = require('./BaseManager');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Manages API methods for users and stores their cache.
|
|
8
|
+
* @extends {BaseManager}
|
|
9
|
+
*/
|
|
10
|
+
class GuildFolderManager extends BaseManager {
|
|
11
|
+
constructor(client) {
|
|
12
|
+
super(client);
|
|
13
|
+
/**
|
|
14
|
+
* The guild folder cache (Index, GuildFolder)
|
|
15
|
+
* @type {Collection<number, GuildFolder>}
|
|
16
|
+
*/
|
|
17
|
+
this.cache = new Collection();
|
|
18
|
+
}
|
|
19
|
+
_refresh() {
|
|
20
|
+
this.cache.clear();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = GuildFolderManager;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const ThreadManager = require('./ThreadManager');
|
|
4
4
|
const { TypeError } = require('../errors');
|
|
5
5
|
const MessagePayload = require('../structures/MessagePayload');
|
|
6
|
-
const { resolveAutoArchiveMaxLimit,
|
|
6
|
+
const { resolveAutoArchiveMaxLimit, getAttachments, uploadFile } = require('../util/Util');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Manages API methods for threads in forum channels and stores their cache.
|
|
@@ -20,7 +20,7 @@ class GuildForumThreadManager extends ThreadManager {
|
|
|
20
20
|
* @typedef {BaseMessageOptions} GuildForumThreadMessageCreateOptions
|
|
21
21
|
* @property {StickerResolvable} [stickers] The stickers to send with the message
|
|
22
22
|
* @property {BitFieldResolvable} [flags] The flags to send with the message.
|
|
23
|
-
* Only `SUPPRESS_EMBEDS` and `
|
|
23
|
+
* Only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS` and `IS_VOICE_MESSAGE` can be set.
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -63,29 +63,35 @@ class GuildForumThreadManager extends ThreadManager {
|
|
|
63
63
|
let messagePayload;
|
|
64
64
|
|
|
65
65
|
if (message instanceof MessagePayload) {
|
|
66
|
-
messagePayload = message.resolveData();
|
|
66
|
+
messagePayload = await message.resolveData();
|
|
67
67
|
} else {
|
|
68
|
-
messagePayload = MessagePayload.create(this, message).resolveData();
|
|
68
|
+
messagePayload = await MessagePayload.create(this, message).resolveData();
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
let { data: body, files } = await messagePayload.resolveFiles();
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
73
|
+
if (typeof message == 'object' && typeof message.usingNewAttachmentAPI !== 'boolean') {
|
|
74
|
+
message.usingNewAttachmentAPI = this.client.options.usingNewAttachmentAPI;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (message?.usingNewAttachmentAPI === true) {
|
|
78
|
+
const attachments = await getAttachments(this.client, this.channel.id, ...files);
|
|
79
|
+
const requestPromises = attachments.map(async attachment => {
|
|
80
|
+
await uploadFile(files[attachment.id].file, attachment.upload_url);
|
|
81
|
+
return {
|
|
82
|
+
id: attachment.id,
|
|
83
|
+
filename: files[attachment.id].name,
|
|
84
|
+
uploaded_filename: attachment.upload_filename,
|
|
85
|
+
description: files[attachment.id].description,
|
|
86
|
+
duration_secs: files[attachment.id].duration_secs,
|
|
87
|
+
waveform: files[attachment.id].waveform,
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
const attachmentsData = await Promise.all(requestPromises);
|
|
91
|
+
attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
|
|
92
|
+
body.attachments = attachmentsData;
|
|
93
|
+
files = [];
|
|
94
|
+
}
|
|
89
95
|
|
|
90
96
|
if (autoArchiveDuration === 'MAX') autoArchiveDuration = resolveAutoArchiveMaxLimit(this.channel.guild);
|
|
91
97
|
|
|
@@ -97,7 +103,7 @@ class GuildForumThreadManager extends ThreadManager {
|
|
|
97
103
|
applied_tags: appliedTags,
|
|
98
104
|
message: body,
|
|
99
105
|
},
|
|
100
|
-
files
|
|
106
|
+
files,
|
|
101
107
|
reason,
|
|
102
108
|
});
|
|
103
109
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
/* eslint-disable newline-per-chained-call */
|
|
2
1
|
'use strict';
|
|
3
2
|
|
|
4
3
|
const { Buffer } = require('node:buffer');
|
|
5
4
|
const { setTimeout } = require('node:timers');
|
|
6
5
|
const { Collection } = require('@discordjs/collection');
|
|
6
|
+
require('lodash.permutations');
|
|
7
|
+
const _ = require('lodash');
|
|
7
8
|
const CachedManager = require('./CachedManager');
|
|
8
9
|
const { Error, TypeError, RangeError } = require('../errors');
|
|
9
10
|
const BaseGuildVoiceChannel = require('../structures/BaseGuildVoiceChannel');
|
|
@@ -190,17 +191,26 @@ class GuildMemberManager extends CachedManager {
|
|
|
190
191
|
* guild.members.fetch({ query: 'hydra', limit: 1 })
|
|
191
192
|
* .then(console.log)
|
|
192
193
|
* .catch(console.error);
|
|
194
|
+
* @see {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md}
|
|
193
195
|
*/
|
|
194
196
|
fetch(options) {
|
|
195
|
-
if (!options) {
|
|
197
|
+
if (!options || (typeof options === 'object' && !('user' in options) && !('query' in options))) {
|
|
196
198
|
if (
|
|
197
|
-
this.me.permissions.has('KICK_MEMBERS') ||
|
|
198
|
-
this.me.permissions.has('BAN_MEMBERS') ||
|
|
199
|
-
this.me.permissions.has('MANAGE_ROLES')
|
|
199
|
+
this.guild.members.me.permissions.has('KICK_MEMBERS') ||
|
|
200
|
+
this.guild.members.me.permissions.has('BAN_MEMBERS') ||
|
|
201
|
+
this.guild.members.me.permissions.has('MANAGE_ROLES')
|
|
200
202
|
) {
|
|
201
203
|
return this._fetchMany();
|
|
202
204
|
} else {
|
|
203
205
|
return this.fetchByMemberSafety();
|
|
206
|
+
/*
|
|
207
|
+
NOTE: This is a very slow method, and can take up to 999+ minutes to complete.
|
|
208
|
+
this.fetchBruteforce({
|
|
209
|
+
delay: 50,
|
|
210
|
+
skipWarn: true,
|
|
211
|
+
depth: 1,
|
|
212
|
+
});
|
|
213
|
+
*/
|
|
204
214
|
}
|
|
205
215
|
}
|
|
206
216
|
const user = this.client.users.resolveId(options);
|
|
@@ -463,60 +473,92 @@ class GuildMemberManager extends CachedManager {
|
|
|
463
473
|
}
|
|
464
474
|
|
|
465
475
|
/**
|
|
466
|
-
*
|
|
467
|
-
* @
|
|
468
|
-
* @
|
|
469
|
-
* @
|
|
470
|
-
* @
|
|
476
|
+
* Options used to fetch multiple members from a guild.
|
|
477
|
+
* @typedef {Object} BruteforceOptions
|
|
478
|
+
* @property {number} [limit=100] Maximum number of members per request
|
|
479
|
+
* @property {number} [delay=500] Timeout for new requests in ms
|
|
480
|
+
* @property {number} [depth=1] Permutations length
|
|
471
481
|
*/
|
|
472
|
-
async addRole(user, role, reason) {
|
|
473
|
-
const userId = this.guild.members.resolveId(user);
|
|
474
|
-
const roleId = this.guild.roles.resolveId(role);
|
|
475
|
-
|
|
476
|
-
await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).put({ reason });
|
|
477
|
-
|
|
478
|
-
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
|
|
479
|
-
}
|
|
480
482
|
|
|
481
483
|
/**
|
|
482
|
-
*
|
|
483
|
-
* @param {
|
|
484
|
-
* @
|
|
485
|
-
* @
|
|
486
|
-
* @
|
|
484
|
+
* Fetches multiple members from the guild.
|
|
485
|
+
* @param {BruteforceOptions} options Options for the bruteforce
|
|
486
|
+
* @returns {Collection<Snowflake, GuildMember>} (All) members in the guild
|
|
487
|
+
* @see https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md
|
|
488
|
+
* @example
|
|
489
|
+
* guild.members.fetchBruteforce()
|
|
490
|
+
* .then(members => console.log(`Fetched ${members.size} members`))
|
|
491
|
+
* .catch(console.error);
|
|
487
492
|
*/
|
|
488
|
-
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
493
|
+
fetchBruteforce(options = {}) {
|
|
494
|
+
const defaultQuery = 'abcdefghijklmnopqrstuvwxyz0123456789!"#$%&\'()*+,-./:;<=>?@[]^_`{|}~ ';
|
|
495
|
+
let dictionary;
|
|
496
|
+
let limit = 100;
|
|
497
|
+
let delay = 500;
|
|
498
|
+
let depth = 1;
|
|
499
|
+
if (options?.limit) limit = options?.limit;
|
|
500
|
+
if (options?.delay) delay = options?.delay;
|
|
501
|
+
if (options?.depth) depth = options?.depth;
|
|
502
|
+
if (typeof limit !== 'number') throw new TypeError('INVALID_TYPE', 'limit', 'Number');
|
|
503
|
+
if (limit < 1 || limit > 100) throw new RangeError('INVALID_RANGE_QUERY_MEMBER');
|
|
504
|
+
if (typeof delay !== 'number') throw new TypeError('INVALID_TYPE', 'delay', 'Number');
|
|
505
|
+
if (typeof depth !== 'number') throw new TypeError('INVALID_TYPE', 'depth', 'Number');
|
|
506
|
+
if (depth < 1) throw new RangeError('INVALID_RANGE_QUERY_MEMBER');
|
|
507
|
+
if (depth > 2) {
|
|
508
|
+
console.warn(`[WARNING] GuildMemberManager#fetchBruteforce: depth greater than 2, can lead to very slow speeds`);
|
|
509
|
+
}
|
|
510
|
+
if (delay < 500 && !options?.skipWarn) {
|
|
511
|
+
console.warn(
|
|
512
|
+
`[WARNING] GuildMemberManager#fetchBruteforce: delay is less than 500ms, this may cause rate limits.`,
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
let skipValues = [];
|
|
516
|
+
// eslint-disable-next-line no-async-promise-executor
|
|
517
|
+
return new Promise(async (resolve, reject) => {
|
|
518
|
+
for (let i = 1; i <= depth; i++) {
|
|
519
|
+
dictionary = _(defaultQuery)
|
|
520
|
+
.permutations(i)
|
|
521
|
+
.map(v => _.join(v, ''))
|
|
522
|
+
.value();
|
|
523
|
+
for (const query of dictionary) {
|
|
524
|
+
if (this.guild.members.cache.size >= this.guild.memberCount) break;
|
|
525
|
+
this.client.emit(
|
|
526
|
+
'debug',
|
|
527
|
+
`[INFO] GuildMemberManager#fetchBruteforce: Querying ${query}, Skip: [${skipValues.join(', ')}]`,
|
|
528
|
+
);
|
|
529
|
+
if (skipValues.some(v => query.startsWith(v))) continue;
|
|
530
|
+
await this._fetchMany({ query, limit })
|
|
531
|
+
.then(members => {
|
|
532
|
+
if (members.size === 0) skipValues.push(query);
|
|
533
|
+
})
|
|
534
|
+
.catch(reject);
|
|
535
|
+
await this.guild.client.sleep(delay);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
resolve(this.guild.members.cache);
|
|
539
|
+
});
|
|
495
540
|
}
|
|
496
541
|
|
|
497
542
|
/**
|
|
498
|
-
* Experimental method to fetch members from the guild.
|
|
499
|
-
*
|
|
500
|
-
* @param {number} [timeout=15_000] Timeout for receipt of members in ms
|
|
543
|
+
* Experimental method to fetch all members from the guild.
|
|
544
|
+
* @param {number} [timeout=120000] Timeout for receipt of members in ms
|
|
501
545
|
* @returns {Promise<Collection<Snowflake, GuildMember>>}
|
|
502
546
|
*/
|
|
503
|
-
fetchByMemberSafety(timeout =
|
|
547
|
+
fetchByMemberSafety(timeout = 120_000) {
|
|
504
548
|
return new Promise(resolve => {
|
|
505
|
-
const nonce = SnowflakeUtil.generate();
|
|
506
549
|
let timeout_ = setTimeout(() => {
|
|
507
550
|
this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
|
|
508
551
|
resolve(this.guild.members.cache);
|
|
509
552
|
}, timeout).unref();
|
|
510
553
|
const handler = (members, guild, raw) => {
|
|
511
|
-
if (guild.id == this.guild.id && raw.nonce ==
|
|
554
|
+
if (guild.id == this.guild.id && !raw.nonce && raw.index == 0 && raw.count == 1) {
|
|
512
555
|
if (members.size > 0) {
|
|
513
556
|
this.client.ws.broadcast({
|
|
514
|
-
op:
|
|
557
|
+
op: 35,
|
|
515
558
|
d: {
|
|
516
559
|
guild_id: this.guild.id,
|
|
517
560
|
query: '',
|
|
518
561
|
continuation_token: members.first()?.id,
|
|
519
|
-
nonce,
|
|
520
562
|
},
|
|
521
563
|
});
|
|
522
564
|
} else {
|
|
@@ -528,17 +570,151 @@ class GuildMemberManager extends CachedManager {
|
|
|
528
570
|
};
|
|
529
571
|
this.client.on('guildMembersChunk', handler);
|
|
530
572
|
this.client.ws.broadcast({
|
|
531
|
-
op:
|
|
573
|
+
op: 35,
|
|
532
574
|
d: {
|
|
533
575
|
guild_id: this.guild.id,
|
|
534
576
|
query: '',
|
|
535
577
|
continuation_token: null,
|
|
536
|
-
nonce,
|
|
537
578
|
},
|
|
538
579
|
});
|
|
539
580
|
});
|
|
540
581
|
}
|
|
541
582
|
|
|
583
|
+
/**
|
|
584
|
+
* Fetches multiple members from the guild in the channel.
|
|
585
|
+
* @param {GuildTextChannelResolvable} channel The channel to get members from (Members has VIEW_CHANNEL permission)
|
|
586
|
+
* @param {number} [offset=0] Start index of the members to get
|
|
587
|
+
* @param {boolean} [double=false] Whether to use double range
|
|
588
|
+
* @param {number} [retryMax=3] Number of retries
|
|
589
|
+
* @param {number} [time=10e3] Timeout for receipt of members
|
|
590
|
+
* @returns {Collection<Snowflake, GuildMember>} Members in the guild
|
|
591
|
+
* @see {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/blob/main/Document/FetchGuildMember.md}
|
|
592
|
+
* @example
|
|
593
|
+
* const guild = client.guilds.cache.get('id');
|
|
594
|
+
* const channel = guild.channels.cache.get('id');
|
|
595
|
+
* // Overlap (slow)
|
|
596
|
+
* for (let index = 0; index <= guild.memberCount; index += 100) {
|
|
597
|
+
* await guild.members.fetchMemberList(channel, index, index !== 100).catch(() => {});
|
|
598
|
+
* await client.sleep(500);
|
|
599
|
+
* }
|
|
600
|
+
* // Non-overlap (fast)
|
|
601
|
+
* for (let index = 0; index <= guild.memberCount; index += 200) {
|
|
602
|
+
* await guild.members.fetchMemberList(channel, index == 0 ? 100 : index, index !== 100).catch(() => {});
|
|
603
|
+
* await client.sleep(500);
|
|
604
|
+
* }
|
|
605
|
+
* console.log(guild.members.cache.size); // will print the number of members in the guild
|
|
606
|
+
*/
|
|
607
|
+
fetchMemberList(channel, offset = 0, double = false, retryMax = 3, time = 10_000) {
|
|
608
|
+
const channel_ = this.guild.channels.resolve(channel);
|
|
609
|
+
if (!channel_?.isText()) throw new TypeError('INVALID_TYPE', 'channel', 'GuildTextChannelResolvable');
|
|
610
|
+
if (typeof offset !== 'number') throw new TypeError('INVALID_TYPE', 'offset', 'Number');
|
|
611
|
+
if (typeof time !== 'number') throw new TypeError('INVALID_TYPE', 'time', 'Number');
|
|
612
|
+
if (typeof retryMax !== 'number') throw new TypeError('INVALID_TYPE', 'retryMax', 'Number');
|
|
613
|
+
if (retryMax < 1) throw new RangeError('INVALID_RANGE_RETRY');
|
|
614
|
+
if (typeof double !== 'boolean') throw new TypeError('INVALID_TYPE', 'double', 'Boolean');
|
|
615
|
+
// TODO: if (this.guild.large) throw new Error('GUILD_IS_LARGE');
|
|
616
|
+
return new Promise((resolve, reject) => {
|
|
617
|
+
const default_ = [[0, 99]];
|
|
618
|
+
const fetchedMembers = new Collection();
|
|
619
|
+
if (offset > 99) {
|
|
620
|
+
// eslint-disable-next-line no-unused-expressions
|
|
621
|
+
double
|
|
622
|
+
? default_.push([offset, offset + 99], [offset + 100, offset + 199])
|
|
623
|
+
: default_.push([offset, offset + 99]);
|
|
624
|
+
}
|
|
625
|
+
let retry = 0;
|
|
626
|
+
const handler = (members, guild, type, raw) => {
|
|
627
|
+
timeout.refresh();
|
|
628
|
+
if (guild.id !== this.guild.id) return;
|
|
629
|
+
if (type == 'INVALIDATE' && offset > 100) {
|
|
630
|
+
if (retry < retryMax) {
|
|
631
|
+
this.guild.shard.send({
|
|
632
|
+
op: Opcodes.GUILD_SUBSCRIPTIONS,
|
|
633
|
+
d: {
|
|
634
|
+
guild_id: this.guild.id,
|
|
635
|
+
typing: true,
|
|
636
|
+
threads: true,
|
|
637
|
+
activities: true,
|
|
638
|
+
channels: {
|
|
639
|
+
[channel_.id]: default_,
|
|
640
|
+
},
|
|
641
|
+
thread_member_lists: [],
|
|
642
|
+
members: [],
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
retry++;
|
|
646
|
+
} else {
|
|
647
|
+
clearTimeout(timeout);
|
|
648
|
+
this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
|
|
649
|
+
this.client.decrementMaxListeners();
|
|
650
|
+
reject(new Error('INVALIDATE_MEMBER', raw.ops[0].range));
|
|
651
|
+
}
|
|
652
|
+
} else {
|
|
653
|
+
for (const member of members.values()) {
|
|
654
|
+
fetchedMembers.set(member.id, member);
|
|
655
|
+
}
|
|
656
|
+
clearTimeout(timeout);
|
|
657
|
+
this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
|
|
658
|
+
this.client.decrementMaxListeners();
|
|
659
|
+
resolve(fetchedMembers);
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
const timeout = setTimeout(() => {
|
|
663
|
+
this.client.removeListener(Events.GUILD_MEMBER_LIST_UPDATE, handler);
|
|
664
|
+
this.client.decrementMaxListeners();
|
|
665
|
+
reject(new Error('GUILD_MEMBERS_TIMEOUT'));
|
|
666
|
+
}, time).unref();
|
|
667
|
+
this.client.incrementMaxListeners();
|
|
668
|
+
this.client.on(Events.GUILD_MEMBER_LIST_UPDATE, handler);
|
|
669
|
+
this.guild.shard.send({
|
|
670
|
+
op: Opcodes.GUILD_SUBSCRIPTIONS,
|
|
671
|
+
d: {
|
|
672
|
+
guild_id: this.guild.id,
|
|
673
|
+
typing: true,
|
|
674
|
+
threads: true,
|
|
675
|
+
activities: true,
|
|
676
|
+
channels: {
|
|
677
|
+
[channel_.id]: default_,
|
|
678
|
+
},
|
|
679
|
+
thread_member_lists: [],
|
|
680
|
+
members: [],
|
|
681
|
+
},
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Adds a role to a member.
|
|
688
|
+
* @param {GuildMemberResolvable} user The user to add the role from
|
|
689
|
+
* @param {RoleResolvable} role The role to add
|
|
690
|
+
* @param {string} [reason] Reason for adding the role
|
|
691
|
+
* @returns {Promise<GuildMember|User|Snowflake>}
|
|
692
|
+
*/
|
|
693
|
+
async addRole(user, role, reason) {
|
|
694
|
+
const userId = this.guild.members.resolveId(user);
|
|
695
|
+
const roleId = this.guild.roles.resolveId(role);
|
|
696
|
+
|
|
697
|
+
await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).put({ reason });
|
|
698
|
+
|
|
699
|
+
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Removes a role from a member.
|
|
704
|
+
* @param {UserResolvable} user The user to remove the role from
|
|
705
|
+
* @param {RoleResolvable} role The role to remove
|
|
706
|
+
* @param {string} [reason] Reason for removing the role
|
|
707
|
+
* @returns {Promise<GuildMember|User|Snowflake>}
|
|
708
|
+
*/
|
|
709
|
+
async removeRole(user, role, reason) {
|
|
710
|
+
const userId = this.guild.members.resolveId(user);
|
|
711
|
+
const roleId = this.guild.roles.resolveId(role);
|
|
712
|
+
|
|
713
|
+
await this.client.api.guilds(this.guild.id).members(userId).roles(roleId).delete({ reason });
|
|
714
|
+
|
|
715
|
+
return this.resolve(user) ?? this.client.users.resolve(user) ?? userId;
|
|
716
|
+
}
|
|
717
|
+
|
|
542
718
|
_fetchMany({
|
|
543
719
|
limit = 0,
|
|
544
720
|
withPresences: presences = true,
|
|
@@ -7,24 +7,19 @@ const BaseManager = require('./BaseManager');
|
|
|
7
7
|
* @see {@link https://luna.gitlab.io/discord-unofficial-docs/user_settings.html}
|
|
8
8
|
*/
|
|
9
9
|
class GuildSettingManager extends BaseManager {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
constructor(client, guildId = null) {
|
|
11
|
+
super(client);
|
|
12
|
+
/**
|
|
13
|
+
* Raw data
|
|
14
|
+
* @type {Object}
|
|
15
|
+
*/
|
|
16
|
+
this.rawSetting = {};
|
|
13
17
|
/**
|
|
14
18
|
* Guild Id
|
|
15
19
|
* @type {?Snowflake}
|
|
16
20
|
*/
|
|
17
|
-
this.guildId =
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Raw data
|
|
22
|
-
* @type {Object}
|
|
23
|
-
*/
|
|
24
|
-
get raw() {
|
|
25
|
-
return this.#rawSetting;
|
|
21
|
+
this.guildId = guildId;
|
|
26
22
|
}
|
|
27
|
-
|
|
28
23
|
/**
|
|
29
24
|
* Get the guild
|
|
30
25
|
* @type {?Guild}
|
|
@@ -33,15 +28,13 @@ class GuildSettingManager extends BaseManager {
|
|
|
33
28
|
get guild() {
|
|
34
29
|
return this.client.guilds.cache.get(this.guildId);
|
|
35
30
|
}
|
|
36
|
-
|
|
37
31
|
/**
|
|
38
32
|
* Patch data file
|
|
39
33
|
* @private
|
|
40
34
|
* @param {Object} data Raw Data to patch
|
|
41
35
|
*/
|
|
42
36
|
_patch(data = {}) {
|
|
43
|
-
this
|
|
44
|
-
this.client.emit('debug', `[SETTING > Guild ${this.guildId}] Sync setting`);
|
|
37
|
+
this.rawSetting = Object.assign(this.rawSetting, data);
|
|
45
38
|
if ('suppress_everyone' in data) {
|
|
46
39
|
/**
|
|
47
40
|
* Notification setting > Suppress `@everyone` and `@here`
|
|
@@ -66,9 +59,9 @@ class GuildSettingManager extends BaseManager {
|
|
|
66
59
|
if ('message_notifications' in data) {
|
|
67
60
|
/**
|
|
68
61
|
* Notification setting > Message notifications
|
|
69
|
-
* * `0
|
|
70
|
-
* * `1
|
|
71
|
-
* * `2
|
|
62
|
+
* * `0` = All messages
|
|
63
|
+
* * `1` = Only @mentions
|
|
64
|
+
* * `2` = Nothing
|
|
72
65
|
* @type {?number}
|
|
73
66
|
*/
|
|
74
67
|
this.messageNotifications = data.message_notifications;
|
|
@@ -125,9 +118,9 @@ class GuildSettingManager extends BaseManager {
|
|
|
125
118
|
if ('notify_highlights' in data) {
|
|
126
119
|
/**
|
|
127
120
|
* Notification setting > Suppress highlights
|
|
128
|
-
* * `0
|
|
129
|
-
* * `1
|
|
130
|
-
* * `2
|
|
121
|
+
* * `0` = ??? (unknown)
|
|
122
|
+
* * `1` = Enable
|
|
123
|
+
* * `2` = Disable
|
|
131
124
|
* @type {?number}
|
|
132
125
|
*/
|
|
133
126
|
this.notifyHighlights = data.notify_highlights;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { Collection } = require('@discordjs/collection');
|
|
4
4
|
const CachedManager = require('./CachedManager');
|
|
5
|
-
const { TypeError } = require('../errors');
|
|
5
|
+
const { TypeError, Error } = require('../errors');
|
|
6
6
|
const { Message } = require('../structures/Message');
|
|
7
7
|
const MessagePayload = require('../structures/MessagePayload');
|
|
8
8
|
const Util = require('../util/Util');
|
|
@@ -123,32 +123,38 @@ class MessageManager extends CachedManager {
|
|
|
123
123
|
const messageId = this.resolveId(message);
|
|
124
124
|
if (!messageId) throw new TypeError('INVALID_TYPE', 'message', 'MessageResolvable');
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
.resolveData()
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
id: attachment.id,
|
|
139
|
-
filename: files[attachment.id].name,
|
|
140
|
-
uploaded_filename: attachment.upload_filename,
|
|
141
|
-
description: files[attachment.id].description,
|
|
142
|
-
duration_secs: files[attachment.id].duration_secs,
|
|
143
|
-
waveform: files[attachment.id].waveform,
|
|
144
|
-
};
|
|
145
|
-
});
|
|
146
|
-
const attachmentsData = await Promise.all(requestPromises);
|
|
147
|
-
attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
|
|
148
|
-
data.attachments = attachmentsData;
|
|
149
|
-
// Empty Files
|
|
126
|
+
let messagePayload;
|
|
127
|
+
if (options instanceof MessagePayload) {
|
|
128
|
+
messagePayload = await options.resolveData();
|
|
129
|
+
} else {
|
|
130
|
+
messagePayload = await MessagePayload.create(message instanceof Message ? message : this, options).resolveData();
|
|
131
|
+
}
|
|
132
|
+
let { data, files } = await messagePayload.resolveFiles();
|
|
133
|
+
|
|
134
|
+
if (typeof options == 'object' && typeof options.usingNewAttachmentAPI !== 'boolean') {
|
|
135
|
+
options.usingNewAttachmentAPI = this.client.options.usingNewAttachmentAPI;
|
|
136
|
+
}
|
|
150
137
|
|
|
151
|
-
|
|
138
|
+
if (options?.usingNewAttachmentAPI === true) {
|
|
139
|
+
const attachments = await Util.getAttachments(this.client, this.channel.id, ...files);
|
|
140
|
+
const requestPromises = attachments.map(async attachment => {
|
|
141
|
+
await Util.uploadFile(files[attachment.id].file, attachment.upload_url);
|
|
142
|
+
return {
|
|
143
|
+
id: attachment.id,
|
|
144
|
+
filename: files[attachment.id].name,
|
|
145
|
+
uploaded_filename: attachment.upload_filename,
|
|
146
|
+
description: files[attachment.id].description,
|
|
147
|
+
duration_secs: files[attachment.id].duration_secs,
|
|
148
|
+
waveform: files[attachment.id].waveform,
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
const attachmentsData = await Promise.all(requestPromises);
|
|
152
|
+
attachmentsData.sort((a, b) => parseInt(a.id) - parseInt(b.id));
|
|
153
|
+
data.attachments = attachmentsData;
|
|
154
|
+
files = [];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const d = await this.client.api.channels[this.channel.id].messages[messageId].patch({ data, files });
|
|
152
158
|
|
|
153
159
|
const existing = this.cache.get(messageId);
|
|
154
160
|
if (existing) {
|
|
@@ -245,16 +251,12 @@ class MessageManager extends CachedManager {
|
|
|
245
251
|
const existing = this.cache.get(messageId);
|
|
246
252
|
if (existing && !existing.partial) return existing;
|
|
247
253
|
}
|
|
248
|
-
|
|
249
254
|
// https://discord.com/api/v9/channels/:id/messages?limit=50&around=:msgid
|
|
250
255
|
return new Promise((resolve, reject) => {
|
|
251
|
-
this._fetchMany(
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
},
|
|
256
|
-
cache,
|
|
257
|
-
)
|
|
256
|
+
this._fetchMany({
|
|
257
|
+
around: messageId,
|
|
258
|
+
limit: 50,
|
|
259
|
+
})
|
|
258
260
|
.then(data_ =>
|
|
259
261
|
data_.has(messageId) ? resolve(data_.get(messageId)) : reject(new Error('MESSAGE_ID_NOT_FOUND')),
|
|
260
262
|
)
|
|
@@ -262,6 +264,13 @@ class MessageManager extends CachedManager {
|
|
|
262
264
|
});
|
|
263
265
|
}
|
|
264
266
|
|
|
267
|
+
async _fetchMany(options = {}, cache) {
|
|
268
|
+
const data = await this.client.api.channels[this.channel.id].messages.get({ query: options });
|
|
269
|
+
const messages = new Collection();
|
|
270
|
+
for (const message of data) messages.set(message.id, this._add(message, cache));
|
|
271
|
+
return messages;
|
|
272
|
+
}
|
|
273
|
+
|
|
265
274
|
/**
|
|
266
275
|
* @typedef {object} MessageSearchOptions
|
|
267
276
|
* @property {Array<UserResolvable>} [authors] An array of author to filter by
|
|
@@ -372,20 +381,13 @@ class MessageManager extends CachedManager {
|
|
|
372
381
|
stringQuery = stringQuery.filter(v => !v.startsWith('channel_id') && !v.startsWith('include_nsfw'));
|
|
373
382
|
data = await this.client.api.channels[this.channel.id].messages[`search?${stringQuery.join('&')}`].get();
|
|
374
383
|
}
|
|
375
|
-
|
|
384
|
+
console.log(stringQuery);
|
|
376
385
|
for await (const message of data.messages) result.set(message[0].id, new Message(this.client, message[0]));
|
|
377
386
|
return {
|
|
378
387
|
messages: result,
|
|
379
388
|
total: data.total_results,
|
|
380
389
|
};
|
|
381
390
|
}
|
|
382
|
-
|
|
383
|
-
async _fetchMany(options = {}, cache) {
|
|
384
|
-
const data = await this.client.api.channels[this.channel.id].messages.get({ query: options });
|
|
385
|
-
const messages = new Collection();
|
|
386
|
-
for (const message of data) messages.set(message.id, this._add(message, cache));
|
|
387
|
-
return messages;
|
|
388
|
-
}
|
|
389
391
|
}
|
|
390
392
|
|
|
391
393
|
module.exports = MessageManager;
|
|
@@ -89,7 +89,7 @@ class PermissionOverwriteManager extends CachedManager {
|
|
|
89
89
|
* @private
|
|
90
90
|
*/
|
|
91
91
|
async upsert(userOrRole, options, overwriteOptions = {}, existing) {
|
|
92
|
-
|
|
92
|
+
const userOrRoleId = this.channel.guild.roles.resolveId(userOrRole) ?? this.client.users.resolveId(userOrRole);
|
|
93
93
|
let { type, reason } = overwriteOptions;
|
|
94
94
|
if (typeof type !== 'number') {
|
|
95
95
|
userOrRole = this.channel.guild.roles.resolve(userOrRole) ?? this.client.users.resolve(userOrRole);
|