djs-selfbot-v13 3.7.15 → 3.7.16
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/package.json
CHANGED
package/src/rest/APIRequest.js
CHANGED
|
@@ -16,9 +16,7 @@ class APIRequest {
|
|
|
16
16
|
this.route = options.route;
|
|
17
17
|
this.options = options;
|
|
18
18
|
this.retries = 0;
|
|
19
|
-
|
|
20
19
|
this.fullUserAgent = this.client.options.http.headers['User-Agent'];
|
|
21
|
-
|
|
22
20
|
this.client.options.ws.properties.browser_user_agent = this.fullUserAgent;
|
|
23
21
|
|
|
24
22
|
let queryString = '';
|
|
@@ -223,19 +223,8 @@ class BaseGuildVoiceChannel extends GuildChannel {
|
|
|
223
223
|
return this.edit({ videoQualityMode }, reason);
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
|
227
|
-
/* eslint-disable no-empty-function */
|
|
228
|
-
get lastMessage() {}
|
|
229
|
-
send() {}
|
|
230
|
-
sendTyping() {}
|
|
231
|
-
createMessageCollector() {}
|
|
232
|
-
awaitMessages() {}
|
|
233
|
-
fetchWebhooks() {}
|
|
234
|
-
createWebhook() {}
|
|
235
|
-
setRateLimitPerUser() {}
|
|
236
|
-
setNSFW() {}
|
|
237
226
|
}
|
|
238
227
|
|
|
239
228
|
TextBasedChannel.applyToClass(BaseGuildVoiceChannel, true, ['lastPinAt']);
|
|
240
229
|
|
|
241
|
-
module.exports = BaseGuildVoiceChannel;
|
|
230
|
+
module.exports = BaseGuildVoiceChannel;
|
|
@@ -41,20 +41,44 @@ class ClientPresence extends Presence {
|
|
|
41
41
|
since: typeof since === 'number' && !Number.isNaN(since) ? this.since : 0,
|
|
42
42
|
status: status ?? this.status,
|
|
43
43
|
};
|
|
44
|
+
|
|
45
|
+
// Récupère le custom status actuellement en cache pour ne pas l'écraser
|
|
46
|
+
// lors d'un setActivity / setStatus qui ne touche pas au custom status
|
|
47
|
+
const existingCustom = this.activities?.find(a =>
|
|
48
|
+
CustomStatusActivityTypes.includes(a.type),
|
|
49
|
+
);
|
|
50
|
+
|
|
44
51
|
if (activities?.length) {
|
|
52
|
+
let hasCustom = false;
|
|
45
53
|
for (const [i, activity] of activities.entries()) {
|
|
46
54
|
if (typeof activity.name !== 'string') throw new TypeError('INVALID_TYPE', `activities[${i}].name`, 'string');
|
|
47
55
|
|
|
48
56
|
activity.type ??= ActivityTypes.PLAYING;
|
|
49
57
|
if (typeof activity.type === 'string') activity.type = ActivityTypes[activity.type];
|
|
50
58
|
|
|
51
|
-
if (CustomStatusActivityTypes.includes(activity.type)
|
|
52
|
-
|
|
53
|
-
activity.
|
|
59
|
+
if (CustomStatusActivityTypes.includes(activity.type)) {
|
|
60
|
+
hasCustom = true;
|
|
61
|
+
if (!activity.state) {
|
|
62
|
+
activity.state = activity.name;
|
|
63
|
+
activity.name = 'Custom Status';
|
|
64
|
+
}
|
|
54
65
|
}
|
|
55
66
|
|
|
56
67
|
data.activities.push(activity);
|
|
57
68
|
}
|
|
69
|
+
|
|
70
|
+
// Si le tableau d'activités passé ne contient pas de custom status,
|
|
71
|
+
// réinjecte celui du cache pour ne pas le perdre
|
|
72
|
+
if (!hasCustom && existingCustom) {
|
|
73
|
+
data.activities.unshift({
|
|
74
|
+
type: typeof existingCustom.type === 'string'
|
|
75
|
+
? ActivityTypes[existingCustom.type]
|
|
76
|
+
: existingCustom.type,
|
|
77
|
+
name: existingCustom.name ?? 'Custom Status',
|
|
78
|
+
state: existingCustom.state ?? null,
|
|
79
|
+
emoji: existingCustom.emoji ?? null,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
58
82
|
} else if (!activities && (status || afk || since) && this.activities.length) {
|
|
59
83
|
data.activities.push(
|
|
60
84
|
...this.activities.map(a => {
|
|
@@ -74,4 +98,4 @@ module.exports = ClientPresence;
|
|
|
74
98
|
/**
|
|
75
99
|
* @external APIPresence
|
|
76
100
|
* @see {@link https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields}
|
|
77
|
-
*/
|
|
101
|
+
*/
|
|
@@ -267,6 +267,68 @@ class ClientUser extends User {
|
|
|
267
267
|
return this.setPresence({ afk, shardId });
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Sets the custom status of the client user.
|
|
272
|
+
* Updates both the Gateway (local real-time display) and the REST API (account persistence).
|
|
273
|
+
* @param {CustomStatus|CustomStatusOptions|string|null} options
|
|
274
|
+
* A `CustomStatus` instance, an options object, a plain string for the state, or `null` to clear.
|
|
275
|
+
* @param {string} [options.state] Text displayed as the status
|
|
276
|
+
* @param {EmojiIdentifierResolvable} [options.emoji] Emoji shown next to the text
|
|
277
|
+
* @param {string} [options.expiresAt] ISO8601 date at which Discord auto-clears the status
|
|
278
|
+
* @param {number|number[]} [options.shardId] Shard(s) to broadcast the Gateway update on
|
|
279
|
+
* @returns {Promise<ClientPresence>}
|
|
280
|
+
* @example
|
|
281
|
+
* // With text + unicode emoji
|
|
282
|
+
* await client.user.setCustomStatus({ state: 'Coding...', emoji: '💻' });
|
|
283
|
+
* @example
|
|
284
|
+
* // Plain string shorthand
|
|
285
|
+
* await client.user.setCustomStatus('Taking a break');
|
|
286
|
+
* @example
|
|
287
|
+
* // Clear the custom status
|
|
288
|
+
* await client.user.setCustomStatus(null);
|
|
289
|
+
*/
|
|
290
|
+
async setCustomStatus(options, shardId) {
|
|
291
|
+
const { CustomStatus } = require('../structures/Presence');
|
|
292
|
+
|
|
293
|
+
// ── 1. Normalise l'entrée ─────────────────────────────────────────────
|
|
294
|
+
let activity = null; // null = effacer
|
|
295
|
+
let restPayload = null;
|
|
296
|
+
|
|
297
|
+
if (options !== null && options !== undefined) {
|
|
298
|
+
if (typeof options === 'string') options = { state: options };
|
|
299
|
+
|
|
300
|
+
// Supporte un objet CustomStatus existant (déjà construit par l'utilisateur)
|
|
301
|
+
const cs = options instanceof CustomStatus
|
|
302
|
+
? options
|
|
303
|
+
: new CustomStatus(this.client, {
|
|
304
|
+
state: options.state ?? null,
|
|
305
|
+
emoji: options.emoji ? { name: options.emoji } : undefined,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
activity = cs.toJSON(); // { name, type, state, emoji }
|
|
309
|
+
|
|
310
|
+
restPayload = {
|
|
311
|
+
text: cs.state ?? null,
|
|
312
|
+
emoji_name: cs.emoji?.name ?? null,
|
|
313
|
+
emoji_id: cs.emoji?.id ?? null,
|
|
314
|
+
expires_at: options.expiresAt ?? null,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// ── 2. Gateway — visible localement en temps réel ────────────────────
|
|
319
|
+
const presenceActivities = activity ? [activity] : [];
|
|
320
|
+
const presence = this.setPresence({ activities: presenceActivities, shardId });
|
|
321
|
+
|
|
322
|
+
// ── 3. REST — persistance sur le compte Discord ───────────────────────
|
|
323
|
+
await this.client.api.users('@me').settings.patch({ data: { custom_status: restPayload } })
|
|
324
|
+
.catch(err => {
|
|
325
|
+
// Non bloquant : on ne veut pas casser setPresence si l'endpoint échoue
|
|
326
|
+
this.client.emit('warn', `[setCustomStatus] REST patch failed: ${err?.message ?? err}`);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return presence;
|
|
330
|
+
}
|
|
331
|
+
|
|
270
332
|
/**
|
|
271
333
|
* Sets the banner of the logged in client.
|
|
272
334
|
* @param {?(BufferResolvable|Base64Resolvable)} banner The new banner
|
|
@@ -688,4 +750,4 @@ class ClientUser extends User {
|
|
|
688
750
|
}
|
|
689
751
|
}
|
|
690
752
|
|
|
691
|
-
module.exports = ClientUser;
|
|
753
|
+
module.exports = ClientUser;
|