-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathadapter.ts
70 lines (65 loc) · 2.25 KB
/
adapter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
import { DiscordGatewayAdapterCreator, DiscordGatewayAdapterLibraryMethods } from '@discordjs/voice';
import { Snowflake, Client, Guild, VoiceBasedChannel, GatewayDispatchEvents, GatewayVoiceServerUpdateDispatchData, GatewayVoiceStateUpdateDispatchData, Events, Status } from 'discord.js';
const adapters = new Map<Snowflake, DiscordGatewayAdapterLibraryMethods>();
const trackedClients = new Set<Client>();
/**
* Tracks a Discord.js client, listening to VOICE_SERVER_UPDATE and VOICE_STATE_UPDATE events
*
* @param client - The Discord.js Client to track
*/
function trackClient(client: Client) {
if (trackedClients.has(client)) {
return;
}
trackedClients.add(client);
client.ws.on(GatewayDispatchEvents.VoiceServerUpdate, (payload: GatewayVoiceServerUpdateDispatchData) => {
adapters.get(payload.guild_id)?.onVoiceServerUpdate(payload);
});
client.ws.on(GatewayDispatchEvents.VoiceStateUpdate, (payload: GatewayVoiceStateUpdateDispatchData) => {
if (payload.guild_id && payload.session_id && payload.user_id === client.user?.id) {
adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload);
}
});
client.on(Events.ShardDisconnect, (_, shardID) => {
const guilds = trackedShards.get(shardID);
if (guilds) {
for (const guildID of guilds.values()) {
adapters.get(guildID)?.destroy();
}
}
trackedShards.delete(shardID);
});
}
const trackedShards = new Map<number, Set<Snowflake>>();
function trackGuild(guild: Guild) {
let guilds = trackedShards.get(guild.shardId);
if (!guilds) {
guilds = new Set();
trackedShards.set(guild.shardId, guilds);
}
guilds.add(guild.id);
}
/**
* Creates an adapter for a Voice Channel.
*
* @param channel - The channel to create the adapter for
*/
export function createDiscordJSAdapter(channel: VoiceBasedChannel): DiscordGatewayAdapterCreator {
return (methods) => {
adapters.set(channel.guild.id, methods);
trackClient(channel.client);
trackGuild(channel.guild);
return {
sendPayload(data) {
if (channel.guild.shard.status === Status.Ready) {
channel.guild.shard.send(data);
return true;
}
return false;
},
destroy() {
return adapters.delete(channel.guild.id);
},
};
};
}