mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-02 04:56:07 +00:00
feat: shard#requestGuildMember
This commit is contained in:
parent
d0c7438465
commit
ed9c63fb11
26
src/cache/index.ts
vendored
26
src/cache/index.ts
vendored
@ -92,7 +92,8 @@ export type CachedEvents =
|
||||
| 'VOICE_STATE_UPDATE'
|
||||
| 'STAGE_INSTANCE_CREATE'
|
||||
| 'STAGE_INSTANCE_UPDATE'
|
||||
| 'STAGE_INSTANCE_DELETE';
|
||||
| 'STAGE_INSTANCE_DELETE'
|
||||
| 'GUILD_MEMBERS_CHUNK';
|
||||
|
||||
export type DisabledCache = {
|
||||
[P in NonGuildBased | GuildBased | GuildRelated | SeyfertBased]?: boolean;
|
||||
@ -554,6 +555,29 @@ export class Cache {
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 'GUILD_MEMBERS_CHUNK': {
|
||||
const data: Parameters<Cache['bulkSet']>[0] = [];
|
||||
|
||||
if (this.members) {
|
||||
for (const member of event.d.members) {
|
||||
data.push(
|
||||
[CacheFrom.Gateway, 'members', member, member.user.id, event.d.guild_id],
|
||||
[CacheFrom.Gateway, 'users', member.user, member.user.id],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.presences && event.d.presences) {
|
||||
for (const presence of event.d.presences) {
|
||||
data.push([CacheFrom.Gateway, 'presences', presence, presence.user.id, event.d.guild_id]);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.length) {
|
||||
await this.bulkSet(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'GUILD_MEMBER_ADD':
|
||||
case 'GUILD_MEMBER_UPDATE':
|
||||
if (event.d.user) await this.members?.set(CacheFrom.Gateway, event.d.user.id, event.d.guild_id, event.d);
|
||||
|
@ -4,7 +4,7 @@ import { WorkerAdapter } from '../cache';
|
||||
import { type DeepPartial, LogLevels, type MakeRequired, type When, lazyLoadPackage } from '../common';
|
||||
import { EventHandler } from '../events';
|
||||
import type { GatewayDispatchPayload, GatewaySendPayload } from '../types';
|
||||
import { Shard, type ShardManagerOptions, type WorkerData, properties } from '../websocket';
|
||||
import { Shard, type ShardManagerOptions, ShardSocketCloseCodes, type WorkerData, properties } from '../websocket';
|
||||
import type {
|
||||
WorkerDisconnectedAllShardsResharding,
|
||||
WorkerMessages,
|
||||
@ -350,7 +350,7 @@ export class WorkerClient<Ready extends boolean = boolean> extends BaseClient {
|
||||
case 'DISCONNECT_ALL_SHARDS_RESHARDING':
|
||||
{
|
||||
for (const i of this.shards.values()) {
|
||||
await i.disconnect();
|
||||
await i.disconnect(ShardSocketCloseCodes.Resharding);
|
||||
}
|
||||
this.postMessage({
|
||||
type: 'DISCONNECTED_ALL_SHARDS_RESHARDING',
|
||||
|
@ -1,13 +1,19 @@
|
||||
import { inflateSync } from 'node:zlib';
|
||||
import { LogLevels, Logger, type MakeRequired, MergeOptions, hasIntent } from '../../common';
|
||||
import {
|
||||
type APIGuildMember,
|
||||
GatewayCloseCodes,
|
||||
GatewayDispatchEvents,
|
||||
type GatewayDispatchPayload,
|
||||
type GatewayGuildMembersChunkPresence,
|
||||
GatewayOpcodes,
|
||||
type GatewayReceivePayload,
|
||||
type GatewaySendPayload,
|
||||
} from '../../types';
|
||||
import type {
|
||||
GatewayRequestGuildMembersDataWithQuery,
|
||||
GatewayRequestGuildMembersDataWithUserIds,
|
||||
} from '../../types/gateway';
|
||||
import { properties } from '../constants';
|
||||
import { DynamicBucket } from '../structures';
|
||||
import { ConnectTimeout } from '../structures/timeout';
|
||||
@ -42,6 +48,18 @@ export class Shard {
|
||||
pendingGuilds = new Set<string>();
|
||||
options: MakeRequired<ShardOptions, 'properties' | 'ratelimitOptions'>;
|
||||
isReady = false;
|
||||
private requestGuildMembersChunk = new Map<
|
||||
string,
|
||||
{
|
||||
members: APIGuildMember[];
|
||||
presences: GatewayGuildMembersChunkPresence[];
|
||||
resolve: (value: {
|
||||
members: APIGuildMember[];
|
||||
presences: GatewayGuildMembersChunkPresence[];
|
||||
}) => void;
|
||||
reject: (reason?: any) => void;
|
||||
}
|
||||
>();
|
||||
|
||||
constructor(
|
||||
public id: number,
|
||||
@ -198,14 +216,14 @@ export class Shard {
|
||||
);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
disconnect(code = ShardSocketCloseCodes.Shutdown) {
|
||||
this.debugger?.info(`[Shard #${this.id}] Disconnecting`);
|
||||
this.close(ShardSocketCloseCodes.Shutdown, 'Shard down request');
|
||||
this.close(code, 'Shard down request');
|
||||
}
|
||||
|
||||
async reconnect() {
|
||||
this.debugger?.info(`[Shard #${this.id}] Reconnecting`);
|
||||
this.disconnect();
|
||||
this.disconnect(ShardSocketCloseCodes.Reconnect);
|
||||
await this.connect();
|
||||
}
|
||||
|
||||
@ -300,6 +318,29 @@ export class Shard {
|
||||
this.options.handlePayload(this.id, packet);
|
||||
}
|
||||
break;
|
||||
case GatewayDispatchEvents.GuildMembersChunk:
|
||||
{
|
||||
if (!packet.d.nonce) {
|
||||
this.options.handlePayload(this.id, packet);
|
||||
break;
|
||||
}
|
||||
const guildMemberChunk = this.requestGuildMembersChunk.get(packet.d.nonce);
|
||||
if (!guildMemberChunk) {
|
||||
this.options.handlePayload(this.id, packet);
|
||||
break;
|
||||
}
|
||||
guildMemberChunk.members.push(...packet.d.members);
|
||||
if (packet.d.presences) guildMemberChunk.presences.push(...packet.d.presences);
|
||||
if (packet.d.chunk_index + 1 === packet.d.chunk_count) {
|
||||
this.requestGuildMembersChunk.delete(packet.d.nonce);
|
||||
guildMemberChunk.resolve({
|
||||
members: guildMemberChunk.members,
|
||||
presences: guildMemberChunk.presences,
|
||||
});
|
||||
}
|
||||
this.options.handlePayload(this.id, packet);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.options.handlePayload(this.id, packet);
|
||||
break;
|
||||
@ -309,6 +350,48 @@ export class Shard {
|
||||
}
|
||||
}
|
||||
|
||||
async requestGuildMember(
|
||||
options:
|
||||
| Omit<GatewayRequestGuildMembersDataWithQuery, 'nonce'>
|
||||
| Omit<GatewayRequestGuildMembersDataWithUserIds, 'nonce'>,
|
||||
) {
|
||||
const nonce = Date.now().toString() + Math.random().toString(36);
|
||||
|
||||
let resolve: (value: {
|
||||
members: APIGuildMember[];
|
||||
presences: GatewayGuildMembersChunkPresence[];
|
||||
}) => void = () => {
|
||||
//
|
||||
};
|
||||
let reject: (reason?: any) => void = () => {
|
||||
//
|
||||
};
|
||||
|
||||
const promise = new Promise<{
|
||||
members: APIGuildMember[];
|
||||
presences: GatewayGuildMembersChunkPresence[];
|
||||
}>((res, rej) => {
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
this.requestGuildMembersChunk.set(nonce, {
|
||||
members: [],
|
||||
presences: [],
|
||||
reject,
|
||||
resolve,
|
||||
});
|
||||
|
||||
this.send(false, {
|
||||
op: GatewayOpcodes.RequestGuildMembers,
|
||||
d: {
|
||||
...options,
|
||||
nonce,
|
||||
},
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
protected async handleClosed(close: { code: number; reason: string }) {
|
||||
this.isReady = false;
|
||||
clearInterval(this.heart.nodeInterval);
|
||||
|
@ -19,7 +19,7 @@ import { ShardManagerDefaults } from '../constants';
|
||||
import { DynamicBucket } from '../structures';
|
||||
import { ConnectQueue } from '../structures/timeout';
|
||||
import { Shard } from './shard';
|
||||
import type { ShardData, ShardManagerOptions, WorkerData } from './shared';
|
||||
import { type ShardData, type ShardManagerOptions, ShardSocketCloseCodes, type WorkerData } from './shared';
|
||||
|
||||
let parentPort: import('node:worker_threads').MessagePort;
|
||||
let workerData: WorkerData;
|
||||
@ -159,7 +159,7 @@ export class ShardManager extends Map<number, Shard> {
|
||||
handlePayload = () => {
|
||||
//
|
||||
};
|
||||
this.disconnectAll();
|
||||
this.disconnectAll(ShardSocketCloseCodes.Resharding);
|
||||
this.clear();
|
||||
|
||||
this.options.totalShards = this.options.shardEnd = this.options.info.shards = info.shards;
|
||||
@ -220,14 +220,14 @@ export class ShardManager extends Map<number, Shard> {
|
||||
return this.create(shardId).identify();
|
||||
}
|
||||
|
||||
disconnect(shardId: number) {
|
||||
disconnect(shardId: number, code?: ShardSocketCloseCodes) {
|
||||
this.debugger?.info(`Shard #${shardId} force disconnect`);
|
||||
return this.get(shardId)?.disconnect();
|
||||
return this.get(shardId)?.disconnect(code);
|
||||
}
|
||||
|
||||
disconnectAll() {
|
||||
disconnectAll(code = ShardSocketCloseCodes.ShutdownAll) {
|
||||
this.debugger?.info('Disconnect all shards');
|
||||
this.forEach(shard => shard.disconnect());
|
||||
this.forEach(shard => shard.disconnect(code));
|
||||
}
|
||||
|
||||
setShardPresence(shardId: number, payload: GatewayUpdatePresence['d']) {
|
||||
|
@ -133,6 +133,9 @@ export interface ShardOptions extends ShardDetails {
|
||||
export enum ShardSocketCloseCodes {
|
||||
Shutdown = 3000,
|
||||
ZombiedConnection = 3010,
|
||||
Reconnect = 3020,
|
||||
Resharding = 3030,
|
||||
ShutdownAll = 3040,
|
||||
}
|
||||
|
||||
export interface WorkerData {
|
||||
|
Loading…
x
Reference in New Issue
Block a user