refactor: use eslint-config-neon for packages. (#8579)

Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
Suneet Tipirneni
2022-09-01 14:50:16 -04:00
committed by GitHub
parent 4bdb0593ae
commit edadb9fe5d
219 changed files with 2608 additions and 2053 deletions

View File

@@ -1,15 +1,19 @@
/* eslint-disable jsdoc/check-param-names */
/* eslint-disable id-length */
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/method-signature-style */
import { Buffer } from 'node:buffer';
import { EventEmitter } from 'node:events';
import { VoiceOpcodes } from 'discord-api-types/voice/v4';
import type { CloseEvent } from 'ws';
import { VoiceUDPSocket } from './VoiceUDPSocket';
import { VoiceWebSocket } from './VoiceWebSocket';
import * as secretbox from '../util/Secretbox';
import { noop } from '../util/util';
import { VoiceUDPSocket } from './VoiceUDPSocket';
import { VoiceWebSocket } from './VoiceWebSocket';
// The number of audio channels required by Discord
const CHANNELS = 2;
const TIMESTAMP_INC = (48000 / 100) * CHANNELS;
const TIMESTAMP_INC = (48_000 / 100) * CHANNELS;
const MAX_NONCE_SIZE = 2 ** 32 - 1;
export const SUPPORTED_ENCRYPTION_MODES = ['xsalsa20_poly1305_lite', 'xsalsa20_poly1305_suffix', 'xsalsa20_poly1305'];
@@ -35,8 +39,8 @@ export enum NetworkingStatusCode {
*/
export interface NetworkingOpeningWsState {
code: NetworkingStatusCode.OpeningWs;
ws: VoiceWebSocket;
connectionOptions: ConnectionOptions;
ws: VoiceWebSocket;
}
/**
@@ -44,8 +48,8 @@ export interface NetworkingOpeningWsState {
*/
export interface NetworkingIdentifyingState {
code: NetworkingStatusCode.Identifying;
ws: VoiceWebSocket;
connectionOptions: ConnectionOptions;
ws: VoiceWebSocket;
}
/**
@@ -54,10 +58,10 @@ export interface NetworkingIdentifyingState {
*/
export interface NetworkingUdpHandshakingState {
code: NetworkingStatusCode.UdpHandshaking;
ws: VoiceWebSocket;
udp: VoiceUDPSocket;
connectionOptions: ConnectionOptions;
connectionData: Pick<ConnectionData, 'ssrc'>;
connectionOptions: ConnectionOptions;
udp: VoiceUDPSocket;
ws: VoiceWebSocket;
}
/**
@@ -65,10 +69,10 @@ export interface NetworkingUdpHandshakingState {
*/
export interface NetworkingSelectingProtocolState {
code: NetworkingStatusCode.SelectingProtocol;
ws: VoiceWebSocket;
udp: VoiceUDPSocket;
connectionOptions: ConnectionOptions;
connectionData: Pick<ConnectionData, 'ssrc'>;
connectionOptions: ConnectionOptions;
udp: VoiceUDPSocket;
ws: VoiceWebSocket;
}
/**
@@ -77,11 +81,11 @@ export interface NetworkingSelectingProtocolState {
*/
export interface NetworkingReadyState {
code: NetworkingStatusCode.Ready;
ws: VoiceWebSocket;
udp: VoiceUDPSocket;
connectionOptions: ConnectionOptions;
connectionData: ConnectionData;
connectionOptions: ConnectionOptions;
preparedPacket?: Buffer | undefined;
udp: VoiceUDPSocket;
ws: VoiceWebSocket;
}
/**
@@ -90,11 +94,11 @@ export interface NetworkingReadyState {
*/
export interface NetworkingResumingState {
code: NetworkingStatusCode.Resuming;
ws: VoiceWebSocket;
udp: VoiceUDPSocket;
connectionOptions: ConnectionOptions;
connectionData: ConnectionData;
connectionOptions: ConnectionOptions;
preparedPacket?: Buffer | undefined;
udp: VoiceUDPSocket;
ws: VoiceWebSocket;
}
/**
@@ -109,13 +113,13 @@ export interface NetworkingClosedState {
* The various states that a networking instance can be in.
*/
export type NetworkingState =
| NetworkingOpeningWsState
| NetworkingClosedState
| NetworkingIdentifyingState
| NetworkingUdpHandshakingState
| NetworkingSelectingProtocolState
| NetworkingOpeningWsState
| NetworkingReadyState
| NetworkingResumingState
| NetworkingClosedState;
| NetworkingSelectingProtocolState
| NetworkingUdpHandshakingState;
/**
* Details required to connect to the Discord voice gateway. These details
@@ -123,11 +127,11 @@ export type NetworkingState =
* and VOICE_STATE_UPDATE packets.
*/
interface ConnectionOptions {
endpoint: string;
serverId: string;
userId: string;
sessionId: string;
token: string;
endpoint: string;
userId: string;
}
/**
@@ -135,15 +139,15 @@ interface ConnectionOptions {
* the connection, timing information for playback of streams.
*/
export interface ConnectionData {
ssrc: number;
encryptionMode: string;
secretKey: Uint8Array;
sequence: number;
timestamp: number;
packetsPlayed: number;
nonce: number;
nonceBuffer: Buffer;
packetsPlayed: number;
secretKey: Uint8Array;
sequence: number;
speaking: boolean;
ssrc: number;
timestamp: number;
}
/**
@@ -186,16 +190,17 @@ function chooseEncryptionMode(options: string[]): string {
if (!option) {
throw new Error(`No compatible encryption modes. Available include: ${options.join(', ')}`);
}
return option;
}
/**
* Returns a random number that is in the range of n bits.
*
* @param n - The number of bits
* @param numberOfBits - The number of bits
*/
function randomNBit(n: number) {
return Math.floor(Math.random() * 2 ** n);
function randomNBit(numberOfBits: number) {
return Math.floor(Math.random() * 2 ** numberOfBits);
}
/**
@@ -207,7 +212,7 @@ export class Networking extends EventEmitter {
/**
* The debug logger function, if debugging is enabled.
*/
private readonly debug: null | ((message: string) => void);
private readonly debug: ((message: string) => void) | null;
/**
* Creates a new Networking instance.
@@ -287,7 +292,6 @@ export class Networking extends EventEmitter {
* Creates a new WebSocket to a Discord Voice gateway.
*
* @param endpoint - The endpoint to connect to
* @param debug - Whether to enable debug logging
*/
private createWebSocket(endpoint: string) {
const ws = new VoiceWebSocket(`wss://${endpoint}?v=4`, Boolean(this.debug));
@@ -351,7 +355,7 @@ export class Networking extends EventEmitter {
* @param code - The close code
*/
private onWsClose({ code }: CloseEvent) {
const canResume = code === 4015 || code < 4000;
const canResume = code === 4_015 || code < 4_000;
if (canResume && this.state.code === NetworkingStatusCode.Ready) {
this.state = {
...this.state,
@@ -400,6 +404,7 @@ export class Networking extends EventEmitter {
udp
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
.performIPDiscovery(ssrc)
// eslint-disable-next-line promise/prefer-await-to-then
.then((localConfig) => {
if (this.state.code !== NetworkingStatusCode.UdpHandshaking) return;
this.state.ws.sendPacket({
@@ -419,6 +424,7 @@ export class Networking extends EventEmitter {
code: NetworkingStatusCode.SelectingProtocol,
};
})
// eslint-disable-next-line promise/prefer-await-to-then, promise/prefer-await-to-callbacks
.catch((error: Error) => this.emit('error', error));
this.state = {
@@ -489,15 +495,14 @@ export class Networking extends EventEmitter {
* @remarks
* Calling this method while there is already a prepared audio packet that has not yet been dispatched
* will overwrite the existing audio packet. This should be avoided.
*
* @param opusPacket - The Opus packet to encrypt
*
* @returns The audio packet that was prepared
*/
public prepareAudioPacket(opusPacket: Buffer) {
const state = this.state;
if (state.code !== NetworkingStatusCode.Ready) return;
state.preparedPacket = this.createAudioPacket(opusPacket, state.connectionData);
// eslint-disable-next-line consistent-return
return state.preparedPacket;
}
@@ -513,6 +518,7 @@ export class Networking extends EventEmitter {
state.preparedPacket = undefined;
return true;
}
return false;
}
@@ -598,6 +604,7 @@ export class Networking extends EventEmitter {
const random = secretbox.methods.random(24, connectionData.nonceBuffer);
return [secretbox.methods.close(opusPacket, random, secretKey), random];
}
return [secretbox.methods.close(opusPacket, nonce, secretKey)];
}
}

View File

@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/method-signature-style */
import { createSocket, Socket } from 'node:dgram';
import { Buffer } from 'node:buffer';
import { createSocket, type Socket } from 'node:dgram';
import { EventEmitter } from 'node:events';
import { isIPv4 } from 'node:net';
@@ -13,8 +14,8 @@ export interface SocketConfig {
}
interface KeepAlive {
value: number;
timestamp: number;
value: number;
}
/**
@@ -25,7 +26,7 @@ interface KeepAlive {
export function parseLocalPacket(message: Buffer): SocketConfig {
const packet = Buffer.from(message);
const ip = packet.slice(8, packet.indexOf(0, 8)).toString('utf-8');
const ip = packet.slice(8, packet.indexOf(0, 8)).toString('utf8');
if (!isIPv4(ip)) {
throw new Error('Malformed IP address');
@@ -100,7 +101,7 @@ export class VoiceUDPSocket extends EventEmitter {
/**
* The debug logger function, if debugging is enabled.
*/
private readonly debug: null | ((message: string) => void);
private readonly debug: ((message: string) => void) | null;
/**
* Creates a new VoiceUDPSocket.
@@ -137,6 +138,7 @@ export class VoiceUDPSocket extends EventEmitter {
// Delete all keep alives up to and including the received one
this.keepAlives.splice(0, index);
}
// Propagate the message
this.emit('message', buffer);
}
@@ -169,7 +171,7 @@ export class VoiceUDPSocket extends EventEmitter {
* @param buffer - The buffer to send
*/
public send(buffer: Buffer) {
return this.socket.send(buffer, this.remote.port, this.remote.ip);
this.socket.send(buffer, this.remote.port, this.remote.ip);
}
/**
@@ -179,6 +181,7 @@ export class VoiceUDPSocket extends EventEmitter {
try {
this.socket.close();
} catch {}
clearInterval(this.keepAliveInterval);
}
@@ -187,7 +190,7 @@ export class VoiceUDPSocket extends EventEmitter {
*
* @param ssrc - The SSRC received from Discord
*/
public performIPDiscovery(ssrc: number): Promise<SocketConfig> {
public async performIPDiscovery(ssrc: number): Promise<SocketConfig> {
return new Promise((resolve, reject) => {
const listener = (message: Buffer) => {
try {

View File

@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/method-signature-style */
import { EventEmitter } from 'node:events';
import { VoiceOpcodes } from 'discord-api-types/voice/v4';
import WebSocket, { MessageEvent } from 'ws';
import WebSocket, { type MessageEvent } from 'ws';
export interface VoiceWebSocket extends EventEmitter {
on(event: 'error', listener: (error: Error) => void): this;
@@ -56,7 +56,7 @@ export class VoiceWebSocket extends EventEmitter {
/**
* The debug logger function, if debugging is enabled.
*/
private readonly debug: null | ((message: string) => void);
private readonly debug: ((message: string) => void) | null;
/**
* The underlying WebSocket of this wrapper.
@@ -71,11 +71,11 @@ export class VoiceWebSocket extends EventEmitter {
public constructor(address: string, debug: boolean) {
super();
this.ws = new WebSocket(address);
this.ws.onmessage = (e) => this.onMessage(e);
this.ws.onopen = (e) => this.emit('open', e);
this.ws.onmessage = (err) => this.onMessage(err);
this.ws.onopen = (err) => this.emit('open', err);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
this.ws.onerror = (e: Error | WebSocket.ErrorEvent) => this.emit('error', e instanceof Error ? e : e.error);
this.ws.onclose = (e) => this.emit('close', e);
this.ws.onerror = (err: Error | WebSocket.ErrorEvent) => this.emit('error', err instanceof Error ? err : err.error);
this.ws.onclose = (err) => this.emit('close', err);
this.lastHeartbeatAck = 0;
this.lastHeartbeatSend = 0;
@@ -90,10 +90,10 @@ export class VoiceWebSocket extends EventEmitter {
try {
this.debug?.('destroyed');
this.setHeartbeatInterval(-1);
this.ws.close(1000);
this.ws.close(1_000);
} catch (error) {
const e = error as Error;
this.emit('error', e);
const err = error as Error;
this.emit('error', err);
}
}
@@ -113,8 +113,8 @@ export class VoiceWebSocket extends EventEmitter {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
packet = JSON.parse(event.data);
} catch (error) {
const e = error as Error;
this.emit('error', e);
const err = error as Error;
this.emit('error', err);
return;
}
@@ -137,10 +137,11 @@ export class VoiceWebSocket extends EventEmitter {
try {
const stringified = JSON.stringify(packet);
this.debug?.(`>> ${stringified}`);
return this.ws.send(stringified);
this.ws.send(stringified);
return;
} catch (error) {
const e = error as Error;
this.emit('error', e);
const err = error as Error;
this.emit('error', err);
}
}
@@ -151,8 +152,9 @@ export class VoiceWebSocket extends EventEmitter {
this.lastHeartbeatSend = Date.now();
this.missedHeartbeats++;
const nonce = this.lastHeartbeatSend;
return this.sendPacket({
this.sendPacket({
op: VoiceOpcodes.Heartbeat,
// eslint-disable-next-line id-length
d: nonce,
});
}
@@ -171,6 +173,7 @@ export class VoiceWebSocket extends EventEmitter {
this.ws.close();
this.setHeartbeatInterval(-1);
}
this.sendHeartbeat();
}, ms);
}