Skip to content

Commit

Permalink
fix(voiceUpdate): race condittion bug (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
KagChi authored Apr 19, 2022
1 parent 70634b4 commit a498373
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
50 changes: 37 additions & 13 deletions src/Structures/Base/BasePlayer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { GatewayVoiceServerUpdateDispatch, GatewayVoiceStateUpdateDispatch } from 'discord-api-types/gateway/v9';
import { Snowflake } from 'discord-api-types/globals';
import { WebsocketOpEnum } from 'lavalink-api-types';
import { KirishimaPlayerOptions, KirishimaNode, createVoiceChannelJoinPayload, Kirishima } from '../..';

export class BasePlayer {
public voiceServer: GatewayVoiceServerUpdateDispatch['d'] | undefined;
public voiceState: GatewayVoiceStateUpdateDispatch['d'] | undefined;
public get voiceState() {
return this.node.voiceStates.get(this.options.guildId);
}

public get voiceServer() {
return this.node.voiceServers.get(this.options.guildId);
}

public constructor(public options: KirishimaPlayerOptions, public kirishima: Kirishima, public node: KirishimaNode) {}

Expand All @@ -19,18 +25,36 @@ export class BasePlayer {
}

public async setServerUpdate(packet: GatewayVoiceServerUpdateDispatch) {
this.voiceServer = packet.d;
if (!this.voiceState?.session_id) return;

await this.node.ws.send({
op: WebsocketOpEnum.VOICE_UPDATE,
guildId: this.voiceServer.guild_id,
sessionId: this.voiceState.session_id,
event: this.voiceServer
});
this.node.voiceServers.set(packet.d.guild_id, packet.d);
return this.sendVoiceUpdate(packet.d.guild_id);
}

public async setStateUpdate(packet: GatewayVoiceStateUpdateDispatch) {
if (packet.d.user_id !== this.kirishima.options.clientId) return;

if (packet.d.channel_id && packet.d.guild_id) {
this.node.voiceStates.set(packet.d.guild_id, packet.d);
return this.sendVoiceUpdate(packet.d.guild_id);
}

if (packet.d.guild_id) {
this.node.voiceServers.delete(packet.d.guild_id);
this.node.voiceStates.delete(packet.d.guild_id);
await this.connect();
}
}

public setStateUpdate(packet: GatewayVoiceStateUpdateDispatch) {
this.voiceState = packet.d;
public async sendVoiceUpdate(guildId: Snowflake) {
const voiceState = this.node.voiceStates.get(guildId);
const event = this.node.voiceServers.get(guildId);

if (event && voiceState) {
await this.node.ws.send({
op: WebsocketOpEnum.VOICE_UPDATE,
guildId,
sessionId: voiceState.session_id,
event
});
}
}
}
6 changes: 5 additions & 1 deletion src/Structures/KirishimaNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import type { Kirishima } from './Kirishima';
import { GatewayVoiceServerUpdateDispatch, GatewayVoiceStateUpdateDispatch } from 'discord-api-types/gateway/v9';
import { LavalinkStatsPayload, WebsocketOpEnum } from 'lavalink-api-types';
import { BasePlayer } from './Base/BasePlayer';
import Collection from '@discordjs/collection';
import { Snowflake } from 'discord-api-types/globals';

export class KirishimaNode {
public ws!: Gateway;
public rest!: REST;
public stats: LavalinkStatsPayload | undefined;
public reconnect: { attempts: number; timeout?: NodeJS.Timeout } = { attempts: 0 };
public voiceServers: Collection<Snowflake, GatewayVoiceServerUpdateDispatch['d']> = new Collection();
public voiceStates: Collection<Snowflake, GatewayVoiceStateUpdateDispatch['d']> = new Collection();
public constructor(public options: KirishimaNodeOptions, public kirishima: Kirishima) {}

public get connected() {
Expand Down Expand Up @@ -107,7 +111,7 @@ export class KirishimaNode {
public async handleVoiceStateUpdate(packet: GatewayVoiceStateUpdateDispatch) {
const player = (await this.kirishima.options.fetchPlayer!(packet.d.guild_id!)) as BasePlayer;
if (player) {
player.setStateUpdate(packet);
await player.setStateUpdate(packet);
}
}
}

0 comments on commit a498373

Please sign in to comment.