chore: run format

This commit is contained in:
Vlad Frangu
2025-10-05 16:13:56 +03:00
parent 2a712d4909
commit 8dc1692d87
189 changed files with 3172 additions and 916 deletions

View File

@@ -343,7 +343,10 @@ describe('State transitions', () => {
// Run through a few packet cycles
for (let index = 1; index <= 5; index++) {
expect(player.state.status).toEqual(AudioPlayerStatus.Playing);
if (player.state.status !== AudioPlayerStatus.Playing) throw new Error('Error');
if (player.state.status !== AudioPlayerStatus.Playing) {
throw new Error('Error');
}
expect(player.state.playbackDuration).toStrictEqual((index - 1) * 20);
expect(player.state.missedFrames).toEqual(index - 1);
player['_stepDispatch']();

View File

@@ -79,7 +79,9 @@ describe('demuxProbe', () => {
test('Detects WebM', async () => {
const stream = Readable.from(gen(10), { objectMode: false });
webmWrite.mockImplementation(function mock(data: Buffer) {
if (data[0] === 5) this.emit('head', validHead);
if (data[0] === 5) {
this.emit('head', validHead);
}
} as any);
const probe = await demuxProbe(stream);
expect(probe.type).toEqual(StreamType.WebmOpus);
@@ -89,7 +91,9 @@ describe('demuxProbe', () => {
test('Detects Ogg', async () => {
const stream = Readable.from(gen(10), { objectMode: false });
oggWrite.mockImplementation(function mock(data: Buffer) {
if (data[0] === 5) this.emit('head', validHead);
if (data[0] === 5) {
this.emit('head', validHead);
}
} as any);
const probe = await demuxProbe(stream);
expect(probe.type).toEqual(StreamType.OggOpus);
@@ -99,7 +103,9 @@ describe('demuxProbe', () => {
test('Rejects invalid OpusHead', async () => {
const stream = Readable.from(gen(10), { objectMode: false });
oggWrite.mockImplementation(function mock(data: Buffer) {
if (data[0] === 5) this.emit('head', invalidHead);
if (data[0] === 5) {
this.emit('head', invalidHead);
}
} as any);
const probe = await demuxProbe(stream);
expect(probe.type).toEqual(StreamType.Arbitrary);

View File

@@ -35,7 +35,10 @@ groups.set('default', new Map());
function getOrCreateGroup(group: string) {
const existing = groups.get(group);
if (existing) return existing;
if (existing) {
return existing;
}
const map = new Map<string, VoiceConnection>();
groups.set(group, map);
return map;
@@ -114,7 +117,9 @@ const audioPlayers: AudioPlayer[] = [];
* the next audio frame.
*/
function audioCycleStep() {
if (nextTime === -1) return;
if (nextTime === -1) {
return;
}
nextTime += FRAME_LENGTH;
const available = audioPlayers.filter((player) => player.checkPlayable());
@@ -165,7 +170,10 @@ export function hasAudioPlayer(target: AudioPlayer) {
* @param player - The player to track
*/
export function addAudioPlayer(player: AudioPlayer) {
if (hasAudioPlayer(player)) return player;
if (hasAudioPlayer(player)) {
return player;
}
audioPlayers.push(player);
if (audioPlayers.length === 1) {
nextTime = Date.now();
@@ -180,10 +188,15 @@ export function addAudioPlayer(player: AudioPlayer) {
*/
export function deleteAudioPlayer(player: AudioPlayer) {
const index = audioPlayers.indexOf(player);
if (index === -1) return;
if (index === -1) {
return;
}
audioPlayers.splice(index, 1);
if (audioPlayers.length === 0) {
nextTime = -1;
if (audioCycleInterval !== undefined) clearTimeout(audioCycleInterval);
if (audioCycleInterval !== undefined) {
clearTimeout(audioCycleInterval);
}
}
}

View File

@@ -312,14 +312,18 @@ export class VoiceConnection extends EventEmitter {
oldNetworking.destroy();
}
if (newNetworking) this.updateReceiveBindings(newNetworking.state, oldNetworking?.state);
if (newNetworking) {
this.updateReceiveBindings(newNetworking.state, oldNetworking?.state);
}
}
if (newState.status === VoiceConnectionStatus.Ready) {
this.rejoinAttempts = 0;
} else if (newState.status === VoiceConnectionStatus.Destroyed) {
for (const stream of this.receiver.subscriptions.values()) {
if (!stream.destroyed) stream.destroy();
if (!stream.destroyed) {
stream.destroy();
}
}
}
@@ -368,9 +372,17 @@ export class VoiceConnection extends EventEmitter {
private addStatePacket(packet: GatewayVoiceStateUpdateDispatchData) {
this.packets.state = packet;
if (packet.self_deaf !== undefined) this.joinConfig.selfDeaf = packet.self_deaf;
if (packet.self_mute !== undefined) this.joinConfig.selfMute = packet.self_mute;
if (packet.channel_id) this.joinConfig.channelId = packet.channel_id;
if (packet.self_deaf !== undefined) {
this.joinConfig.selfDeaf = packet.self_deaf;
}
if (packet.self_mute !== undefined) {
this.joinConfig.selfMute = packet.self_mute;
}
if (packet.channel_id) {
this.joinConfig.channelId = packet.channel_id;
}
/*
the channel_id being null doesn't necessarily mean it was intended for the client to leave the voice channel
as it may have disconnected due to network failure. This will be gracefully handled once the voice websocket
@@ -417,7 +429,9 @@ export class VoiceConnection extends EventEmitter {
*/
public configureNetworking() {
const { server, state } = this.packets;
if (!server || !state || this.state.status === VoiceConnectionStatus.Destroyed || !server.endpoint) return;
if (!server || !state || this.state.status === VoiceConnectionStatus.Destroyed || !server.endpoint) {
return;
}
const networking = new Networking(
{
@@ -460,7 +474,10 @@ export class VoiceConnection extends EventEmitter {
* @param code - The close code
*/
private onNetworkingClose(code: number) {
if (this.state.status === VoiceConnectionStatus.Destroyed) return;
if (this.state.status === VoiceConnectionStatus.Destroyed) {
return;
}
// If networking closes, try to connect to the voice channel again.
if (code === 4_014) {
// Disconnected - networking is already destroyed here
@@ -494,9 +511,13 @@ export class VoiceConnection extends EventEmitter {
*/
private onNetworkingStateChange(oldState: NetworkingState, newState: NetworkingState) {
this.updateReceiveBindings(newState, oldState);
if (oldState.code === newState.code) return;
if (this.state.status !== VoiceConnectionStatus.Connecting && this.state.status !== VoiceConnectionStatus.Ready)
if (oldState.code === newState.code) {
return;
}
if (this.state.status !== VoiceConnectionStatus.Connecting && this.state.status !== VoiceConnectionStatus.Ready) {
return;
}
if (newState.code === NetworkingStatusCode.Ready) {
this.state = {
@@ -545,7 +566,10 @@ export class VoiceConnection extends EventEmitter {
*/
public prepareAudioPacket(buffer: Buffer) {
const state = this.state;
if (state.status !== VoiceConnectionStatus.Ready) return;
if (state.status !== VoiceConnectionStatus.Ready) {
return;
}
return state.networking.prepareAudioPacket(buffer);
}
@@ -554,7 +578,10 @@ export class VoiceConnection extends EventEmitter {
*/
public dispatchAudio() {
const state = this.state;
if (state.status !== VoiceConnectionStatus.Ready) return;
if (state.status !== VoiceConnectionStatus.Ready) {
return;
}
return state.networking.dispatchAudio();
}
@@ -565,7 +592,10 @@ export class VoiceConnection extends EventEmitter {
*/
public playOpusPacket(buffer: Buffer) {
const state = this.state;
if (state.status !== VoiceConnectionStatus.Ready) return;
if (state.status !== VoiceConnectionStatus.Ready) {
return;
}
state.networking.prepareAudioPacket(buffer);
return state.networking.dispatchAudio();
}
@@ -644,7 +674,10 @@ export class VoiceConnection extends EventEmitter {
const notReady = this.state.status !== VoiceConnectionStatus.Ready;
if (notReady) this.rejoinAttempts++;
if (notReady) {
this.rejoinAttempts++;
}
Object.assign(this.joinConfig, joinConfig);
if (this.state.adapter.sendPayload(createJoinVoiceChannelPayload(this.joinConfig))) {
if (notReady) {
@@ -673,7 +706,10 @@ export class VoiceConnection extends EventEmitter {
* @param enabled - Whether or not to show as speaking
*/
public setSpeaking(enabled: boolean) {
if (this.state.status !== VoiceConnectionStatus.Ready) return false;
if (this.state.status !== VoiceConnectionStatus.Ready) {
return false;
}
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
return this.state.networking.setSpeaking(enabled);
}
@@ -685,7 +721,9 @@ export class VoiceConnection extends EventEmitter {
* @returns The created subscription
*/
public subscribe(player: AudioPlayer) {
if (this.state.status === VoiceConnectionStatus.Destroyed) return;
if (this.state.status === VoiceConnectionStatus.Destroyed) {
return;
}
// eslint-disable-next-line @typescript-eslint/dot-notation
const subscription = player['subscribe'](this);

View File

@@ -458,7 +458,10 @@ export class AudioPlayer extends EventEmitter {
* @returns `true` if the player was successfully paused, otherwise `false`
*/
public pause(interpolateSilence = true) {
if (this.state.status !== AudioPlayerStatus.Playing) return false;
if (this.state.status !== AudioPlayerStatus.Playing) {
return false;
}
this.state = {
...this.state,
status: AudioPlayerStatus.Paused,
@@ -473,7 +476,10 @@ export class AudioPlayer extends EventEmitter {
* @returns `true` if the player was successfully unpaused, otherwise `false`
*/
public unpause() {
if (this.state.status !== AudioPlayerStatus.Paused) return false;
if (this.state.status !== AudioPlayerStatus.Paused) {
return false;
}
this.state = {
...this.state,
status: AudioPlayerStatus.Playing,
@@ -490,7 +496,10 @@ export class AudioPlayer extends EventEmitter {
* @returns `true` if the player will come to a stop, otherwise `false`
*/
public stop(force = false) {
if (this.state.status === AudioPlayerStatus.Idle) return false;
if (this.state.status === AudioPlayerStatus.Idle) {
return false;
}
if (force || this.state.resource.silencePaddingFrames === 0) {
this.state = {
status: AudioPlayerStatus.Idle,
@@ -509,7 +518,9 @@ export class AudioPlayer extends EventEmitter {
*/
public checkPlayable() {
const state = this._state;
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) return false;
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) {
return false;
}
// If the stream has been destroyed or is no longer readable, then transition to the Idle state.
if (!state.resource.readable) {
@@ -531,7 +542,9 @@ export class AudioPlayer extends EventEmitter {
const state = this._state;
// Guard against the Idle state
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) return;
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) {
return;
}
// Dispatch any audio packets that were prepared in the previous cycle
for (const connection of this.playable) {
@@ -549,7 +562,9 @@ export class AudioPlayer extends EventEmitter {
const state = this._state;
// Guard against the Idle state
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) return;
if (state.status === AudioPlayerStatus.Idle || state.status === AudioPlayerStatus.Buffering) {
return;
}
// List of connections that can receive the packet
const playable = this.playable;

View File

@@ -123,10 +123,16 @@ export class AudioResource<Metadata = unknown> {
* while there are silence padding frames left to play.
*/
public get readable() {
if (this.silenceRemaining === 0) return false;
if (this.silenceRemaining === 0) {
return false;
}
const real = this.playStream.readable;
if (!real) {
if (this.silenceRemaining === -1) this.silenceRemaining = this.silencePaddingFrames;
if (this.silenceRemaining === -1) {
this.silenceRemaining = this.silencePaddingFrames;
}
return this.silenceRemaining !== 0;
}
@@ -274,7 +280,10 @@ export function createAudioResource<Metadata>(
const transformerPipeline = findPipeline(inputType, needsInlineVolume ? VOLUME_CONSTRAINT : NO_CONSTRAINT);
if (transformerPipeline.length === 0) {
if (typeof input === 'string') throw new Error(`Invalid pipeline constructed for string resource '${input}'`);
if (typeof input === 'string') {
throw new TypeError(`Invalid pipeline constructed for string resource '${input}'`);
}
// No adjustments required
return new AudioResource<Metadata>(
[],
@@ -285,7 +294,9 @@ export function createAudioResource<Metadata>(
}
const streams = transformerPipeline.map((edge) => edge.transformer(input));
if (typeof input !== 'string') streams.unshift(input);
if (typeof input !== 'string') {
streams.unshift(input);
}
return new AudioResource<Metadata>(
transformerPipeline,

View File

@@ -110,7 +110,10 @@ let NODES: Map<StreamType, Node> | null = null;
*/
export function getNode(type: StreamType) {
const node = (NODES ??= initializeNodes()).get(type);
if (!node) throw new Error(`Node type '${type}' does not exist!`);
if (!node) {
throw new Error(`Node type '${type}' does not exist!`);
}
return node;
}
@@ -243,7 +246,10 @@ function findPath(
let currentBest: Step | undefined;
for (const edge of from.edges) {
if (currentBest && edge.cost > currentBest.cost) continue;
if (currentBest && edge.cost > currentBest.cost) {
continue;
}
const next = findPath(edge.to, constraints, goal, [...path, edge], depth - 1);
const cost = edge.cost + next.cost;
if (!currentBest || cost < currentBest.cost) {

View File

@@ -135,11 +135,12 @@ export class DAVESession extends EventEmitter {
public session: SessionMethods | undefined;
public constructor(protocolVersion: number, userId: string, channelId: string, options: DAVESessionOptions) {
if (Davey === null)
if (Davey === null) {
throw new Error(
`Cannot utilize the DAVE protocol as the @snazzah/davey package has not been installed.
- Use the generateDependencyReport() function for more information.\n`,
);
}
super();
@@ -166,7 +167,10 @@ export class DAVESession extends EventEmitter {
* @throws Will throw if there is not an active session or the user id provided is invalid or not in the session.
*/
public async getVerificationCode(userId: string): Promise<string> {
if (!this.session) throw new Error('Session not available');
if (!this.session) {
throw new Error('Session not available');
}
return this.session.getVerificationCode(userId);
}
@@ -197,7 +201,10 @@ export class DAVESession extends EventEmitter {
* @param externalSender - The external sender
*/
public setExternalSender(externalSender: Buffer) {
if (!this.session) throw new Error('No session available');
if (!this.session) {
throw new Error('No session available');
}
this.session.setExternalSender(externalSender);
this.emit('debug', 'Set MLS external sender');
}
@@ -216,7 +223,10 @@ export class DAVESession extends EventEmitter {
if (data.transition_id === 0) {
this.executeTransition(data.transition_id);
} else {
if (data.protocol_version === 0) this.session?.setPassthroughMode(true, TRANSITION_EXPIRY_PENDING_DOWNGRADE);
if (data.protocol_version === 0) {
this.session?.setPassthroughMode(true, TRANSITION_EXPIRY_PENDING_DOWNGRADE);
}
return true;
}
@@ -285,7 +295,10 @@ export class DAVESession extends EventEmitter {
* @param transitionId - The transition id to invalidate
*/
public recoverFromInvalidTransition(transitionId: number) {
if (this.reinitializing) return;
if (this.reinitializing) {
return;
}
this.emit('debug', `Invalidating transition ${transitionId}`);
this.reinitializing = true;
this.consecutiveFailures = 0;
@@ -301,7 +314,10 @@ export class DAVESession extends EventEmitter {
* @returns The payload to send back to the voice server, if there is one
*/
public processProposals(payload: Buffer, connectedClients: Set<string>): Buffer | undefined {
if (!this.session) throw new Error('No session available');
if (!this.session) {
throw new Error('No session available');
}
const optype = payload.readUInt8(0) as 0 | 1;
const { commit, welcome } = this.session.processProposals(
optype,
@@ -309,7 +325,10 @@ export class DAVESession extends EventEmitter {
Array.from(connectedClients),
);
this.emit('debug', 'MLS proposals processed');
if (!commit) return;
if (!commit) {
return;
}
return welcome ? Buffer.concat([commit, welcome]) : commit;
}
@@ -320,7 +339,10 @@ export class DAVESession extends EventEmitter {
* @returns The transaction id and whether it was successful
*/
public processCommit(payload: Buffer): TransitionResult {
if (!this.session) throw new Error('No session available');
if (!this.session) {
throw new Error('No session available');
}
const transitionId = payload.readUInt16BE(0);
try {
this.session.processCommit(payload.subarray(2));
@@ -347,7 +369,10 @@ export class DAVESession extends EventEmitter {
* @returns The transaction id and whether it was successful
*/
public processWelcome(payload: Buffer): TransitionResult {
if (!this.session) throw new Error('No session available');
if (!this.session) {
throw new Error('No session available');
}
const transitionId = payload.readUInt16BE(0);
try {
this.session.processWelcome(payload.subarray(2));
@@ -373,7 +398,10 @@ export class DAVESession extends EventEmitter {
* @param packet - The packet to encrypt
*/
public encrypt(packet: Buffer) {
if (this.protocolVersion === 0 || !this.session?.ready || packet.equals(SILENCE_FRAME)) return packet;
if (this.protocolVersion === 0 || !this.session?.ready || packet.equals(SILENCE_FRAME)) {
return packet;
}
return this.session.encryptOpus(packet);
}
@@ -386,7 +414,10 @@ export class DAVESession extends EventEmitter {
*/
public decrypt(packet: Buffer, userId: string) {
const canDecrypt = this.session?.ready && (this.protocolVersion !== 0 || this.session?.canPassthrough(userId));
if (packet.equals(SILENCE_FRAME) || !canDecrypt || !this.session) return packet;
if (packet.equals(SILENCE_FRAME) || !canDecrypt || !this.session) {
return packet;
}
try {
const buffer = this.session.decrypt(userId, Davey.MediaType.AUDIO, packet);
this.consecutiveFailures = 0;
@@ -396,8 +427,11 @@ export class DAVESession extends EventEmitter {
this.consecutiveFailures++;
this.emit('debug', `Failed to decrypt a packet (${this.consecutiveFailures} consecutive fails)`);
if (this.consecutiveFailures > this.failureTolerance) {
if (this.lastTransitionId) this.recoverFromInvalidTransition(this.lastTransitionId);
else throw error;
if (this.lastTransitionId) {
this.recoverFromInvalidTransition(this.lastTransitionId);
} else {
throw error;
}
}
} else if (this.reinitializing) {
this.emit('debug', 'Failed to decrypt a packet (reinitializing session)');

View File

@@ -487,7 +487,10 @@ export class Networking extends EventEmitter {
.performIPDiscovery(ssrc)
// eslint-disable-next-line promise/prefer-await-to-then
.then((localConfig) => {
if (this.state.code !== NetworkingStatusCode.UdpHandshaking) return;
if (this.state.code !== NetworkingStatusCode.UdpHandshaking) {
return;
}
this.state.ws.sendPacket({
op: VoiceOpcodes.SelectProtocol,
d: {
@@ -551,9 +554,11 @@ export class Networking extends EventEmitter {
this.state.code === NetworkingStatusCode.Resuming)
) {
const { connectionData } = this.state;
if (packet.op === VoiceOpcodes.ClientsConnect)
for (const id of packet.d.user_ids) connectionData.connectedClients.add(id);
else {
if (packet.op === VoiceOpcodes.ClientsConnect) {
for (const id of packet.d.user_ids) {
connectionData.connectedClients.add(id);
}
} else {
connectionData.connectedClients.delete(packet.d.user_id);
}
} else if (
@@ -562,18 +567,24 @@ export class Networking extends EventEmitter {
) {
if (packet.op === VoiceOpcodes.DavePrepareTransition) {
const sendReady = this.state.dave.prepareTransition(packet.d);
if (sendReady)
if (sendReady) {
this.state.ws.sendPacket({
op: VoiceOpcodes.DaveTransitionReady,
d: { transition_id: packet.d.transition_id },
});
}
if (packet.d.transition_id === 0) {
this.emit('transitioned', 0);
}
} else if (packet.op === VoiceOpcodes.DaveExecuteTransition) {
const transitioned = this.state.dave.executeTransition(packet.d.transition_id);
if (transitioned) this.emit('transitioned', packet.d.transition_id);
} else if (packet.op === VoiceOpcodes.DavePrepareEpoch) this.state.dave.prepareEpoch(packet.d);
if (transitioned) {
this.emit('transitioned', packet.d.transition_id);
}
} else if (packet.op === VoiceOpcodes.DavePrepareEpoch) {
this.state.dave.prepareEpoch(packet.d);
}
}
}
@@ -588,26 +599,32 @@ export class Networking extends EventEmitter {
this.state.dave.setExternalSender(message.payload);
} else if (message.op === VoiceOpcodes.DaveMlsProposals) {
const payload = this.state.dave.processProposals(message.payload, this.state.connectionData.connectedClients);
if (payload) this.state.ws.sendBinaryMessage(VoiceOpcodes.DaveMlsCommitWelcome, payload);
if (payload) {
this.state.ws.sendBinaryMessage(VoiceOpcodes.DaveMlsCommitWelcome, payload);
}
} else if (message.op === VoiceOpcodes.DaveMlsAnnounceCommitTransition) {
const { transitionId, success } = this.state.dave.processCommit(message.payload);
if (success) {
if (transitionId === 0) this.emit('transitioned', transitionId);
else
if (transitionId === 0) {
this.emit('transitioned', transitionId);
} else {
this.state.ws.sendPacket({
op: VoiceOpcodes.DaveTransitionReady,
d: { transition_id: transitionId },
});
}
}
} else if (message.op === VoiceOpcodes.DaveMlsWelcome) {
const { transitionId, success } = this.state.dave.processWelcome(message.payload);
if (success) {
if (transitionId === 0) this.emit('transitioned', transitionId);
else
if (transitionId === 0) {
this.emit('transitioned', transitionId);
} else {
this.state.ws.sendPacket({
op: VoiceOpcodes.DaveTransitionReady,
d: { transition_id: transitionId },
});
}
}
}
}
@@ -619,8 +636,9 @@ export class Networking extends EventEmitter {
* @param keyPackage - The new key package
*/
private onDaveKeyPackage(keyPackage: Buffer) {
if (this.state.code === NetworkingStatusCode.SelectingProtocol || this.state.code === NetworkingStatusCode.Ready)
if (this.state.code === NetworkingStatusCode.SelectingProtocol || this.state.code === NetworkingStatusCode.Ready) {
this.state.ws.sendBinaryMessage(VoiceOpcodes.DaveMlsKeyPackage, keyPackage);
}
}
/**
@@ -629,11 +647,12 @@ export class Networking extends EventEmitter {
* @param transitionId - The transition to invalidate
*/
private onDaveInvalidateTransition(transitionId: number) {
if (this.state.code === NetworkingStatusCode.SelectingProtocol || this.state.code === NetworkingStatusCode.Ready)
if (this.state.code === NetworkingStatusCode.SelectingProtocol || this.state.code === NetworkingStatusCode.Ready) {
this.state.ws.sendPacket({
op: VoiceOpcodes.DaveMlsInvalidCommitWelcome,
d: { transition_id: transitionId },
});
}
}
/**
@@ -675,7 +694,10 @@ export class Networking extends EventEmitter {
*/
public prepareAudioPacket(opusPacket: Buffer) {
const state = this.state;
if (state.code !== NetworkingStatusCode.Ready) return;
if (state.code !== NetworkingStatusCode.Ready) {
return;
}
state.preparedPacket = this.createAudioPacket(opusPacket, state.connectionData, state.dave);
return state.preparedPacket;
}
@@ -686,7 +708,10 @@ export class Networking extends EventEmitter {
*/
public dispatchAudio() {
const state = this.state;
if (state.code !== NetworkingStatusCode.Ready) return false;
if (state.code !== NetworkingStatusCode.Ready) {
return false;
}
if (state.preparedPacket !== undefined) {
this.playAudioPacket(state.preparedPacket);
state.preparedPacket = undefined;
@@ -703,13 +728,22 @@ export class Networking extends EventEmitter {
*/
private playAudioPacket(audioPacket: Buffer) {
const state = this.state;
if (state.code !== NetworkingStatusCode.Ready) return;
if (state.code !== NetworkingStatusCode.Ready) {
return;
}
const { connectionData } = state;
connectionData.packetsPlayed++;
connectionData.sequence++;
connectionData.timestamp += TIMESTAMP_INC;
if (connectionData.sequence >= 2 ** 16) connectionData.sequence = 0;
if (connectionData.timestamp >= 2 ** 32) connectionData.timestamp = 0;
if (connectionData.sequence >= 2 ** 16) {
connectionData.sequence = 0;
}
if (connectionData.timestamp >= 2 ** 32) {
connectionData.timestamp = 0;
}
this.setSpeaking(true);
state.udp.send(audioPacket);
}
@@ -722,8 +756,14 @@ export class Networking extends EventEmitter {
*/
public setSpeaking(speaking: boolean) {
const state = this.state;
if (state.code !== NetworkingStatusCode.Ready) return;
if (state.connectionData.speaking === speaking) return;
if (state.code !== NetworkingStatusCode.Ready) {
return;
}
if (state.connectionData.speaking === speaking) {
return;
}
state.connectionData.speaking = speaking;
state.ws.sendPacket({
op: VoiceOpcodes.Speaking,
@@ -777,7 +817,10 @@ export class Networking extends EventEmitter {
// Both supported encryption methods want the nonce to be an incremental integer
connectionData.nonce++;
if (connectionData.nonce > MAX_NONCE_SIZE) connectionData.nonce = 0;
if (connectionData.nonce > MAX_NONCE_SIZE) {
connectionData.nonce = 0;
}
connectionData.nonceBuffer.writeUInt32BE(connectionData.nonce, 0);
// 4 extra bytes of padding on the end of the encrypted packet

View File

@@ -152,7 +152,10 @@ export class VoiceUDPSocket extends EventEmitter {
return new Promise((resolve, reject) => {
const listener = (message: Buffer) => {
try {
if (message.readUInt16BE(0) !== 2) return;
if (message.readUInt16BE(0) !== 2) {
return;
}
const packet = parseLocalPacket(message);
this.socket.off('message', listener);
resolve(packet);

View File

@@ -220,7 +220,10 @@ export class VoiceWebSocket extends EventEmitter {
* @param ms - The interval in milliseconds. If negative, the interval will be unset
*/
public setHeartbeatInterval(ms: number) {
if (this.heartbeatInterval !== undefined) clearInterval(this.heartbeatInterval);
if (this.heartbeatInterval !== undefined) {
clearInterval(this.heartbeatInterval);
}
if (ms > 0) {
this.heartbeatInterval = setInterval(() => {
if (this.lastHeartbeatSend !== 0 && this.missedHeartbeats >= 3) {

View File

@@ -55,7 +55,10 @@ export class SSRCMap extends EventEmitter {
};
this.map.set(data.audioSSRC, newValue);
if (!existing) this.emit('create', newValue);
if (!existing) {
this.emit('create', newValue);
}
this.emit('update', existing, newValue);
}

View File

@@ -84,7 +84,9 @@ export class VoiceReceiver {
let headerSize = 12;
const first = buffer.readUint8();
if ((first >> 4) & 0x01) headerSize += 4;
if ((first >> 4) & 0x01) {
headerSize += 4;
}
// The unencrypted RTP header contains 12 bytes, HEADER_EXTENSION and the extension size
const header = buffer.subarray(0, headerSize);
@@ -135,7 +137,9 @@ export class VoiceReceiver {
*/
private parsePacket(buffer: Buffer, mode: string, nonce: Buffer, secretKey: Uint8Array, userId: string) {
let packet: Buffer = this.decrypt(buffer, mode, nonce, secretKey);
if (!packet) throw new Error('Failed to parse packet');
if (!packet) {
throw new Error('Failed to parse packet');
}
// Strip decrypted RTP Header Extension if present
// The header is only indicated in the original data, so compare with buffer first
@@ -151,7 +155,9 @@ export class VoiceReceiver {
this.voiceConnection.state.networking.state.code === NetworkingStatusCode.Resuming)
) {
const daveSession = this.voiceConnection.state.networking.state.dave;
if (daveSession) packet = daveSession.decrypt(packet, userId)!;
if (daveSession) {
packet = daveSession.decrypt(packet, userId)!;
}
}
return packet;
@@ -164,16 +170,23 @@ export class VoiceReceiver {
* @internal
*/
public onUdpMessage(msg: Buffer) {
if (msg.length <= 8) return;
if (msg.length <= 8) {
return;
}
const ssrc = msg.readUInt32BE(8);
const userData = this.ssrcMap.get(ssrc);
if (!userData) return;
if (!userData) {
return;
}
this.speaking.onPacket(userData.userId);
const stream = this.subscriptions.get(userData.userId);
if (!stream) return;
if (!stream) {
return;
}
if (this.connectionData.encryptionMode && this.connectionData.nonceBuffer && this.connectionData.secretKey) {
try {
@@ -184,7 +197,9 @@ export class VoiceReceiver {
this.connectionData.secretKey,
userData.userId,
);
if (packet) stream.push(packet);
if (packet) {
stream.push(packet);
}
} catch (error) {
stream.destroy(error as Error);
}
@@ -199,7 +214,9 @@ export class VoiceReceiver {
*/
public subscribe(userId: string, options?: Partial<AudioReceiveStreamOptions>) {
const existing = this.subscriptions.get(userId);
if (existing) return existing;
if (existing) {
return existing;
}
const stream = new AudioReceiveStream({
...createDefaultAudioReceiveStreamOptions(),

View File

@@ -16,11 +16,17 @@ function findPackageJSON(
packageName: string,
depth: number,
): { name: string; version: string } | undefined {
if (depth === 0) return undefined;
if (depth === 0) {
return undefined;
}
const attemptedPath = resolve(dir, './package.json');
try {
const pkg = require(attemptedPath);
if (pkg.name !== packageName) throw new Error('package.json does not match');
if (pkg.name !== packageName) {
throw new Error('package.json does not match');
}
return pkg;
} catch {
return findPackageJSON(resolve(dir, '..'), packageName, depth - 1);