summary refs log tree commit diff
path: root/src/gateway
diff options
context:
space:
mode:
authorMadeline <46743919+MaddyUnderStars@users.noreply.github.com>2023-01-20 18:10:47 +1100
committerGitHub <noreply@github.com>2023-01-20 18:10:47 +1100
commit084dc0be08555891cad4c2bb984822a62ec5ec9f (patch)
treeed2ca0fafefa2224ae32761f955f63935422a97d /src/gateway
parentfix: route file regex (#956) (diff)
downloadserver-084dc0be08555891cad4c2bb984822a62ec5ec9f.tar.xz
Add ESLint (#941)
* Add eslint, switch to lint-staged for precommit

* Fix all ESLint errors

* Update GH workflow to check prettier and eslint
Diffstat (limited to 'src/gateway')
-rw-r--r--src/gateway/Server.ts1
-rw-r--r--src/gateway/events/Close.ts2
-rw-r--r--src/gateway/events/Connection.ts7
-rw-r--r--src/gateway/events/Message.ts15
-rw-r--r--src/gateway/listener/listener.ts22
-rw-r--r--src/gateway/opcodes/Heartbeat.ts4
-rw-r--r--src/gateway/opcodes/Identify.ts46
-rw-r--r--src/gateway/opcodes/LazyRequest.ts67
-rw-r--r--src/gateway/opcodes/RequestGuildMembers.ts4
-rw-r--r--src/gateway/opcodes/Resume.ts4
-rw-r--r--src/gateway/opcodes/VoiceStateUpdate.ts1
-rw-r--r--src/gateway/opcodes/index.ts4
-rw-r--r--src/gateway/opcodes/instanceOf.ts2
-rw-r--r--src/gateway/start.ts2
-rw-r--r--src/gateway/util/Constants.ts1
-rw-r--r--src/gateway/util/Send.ts4
-rw-r--r--src/gateway/util/WebSocket.ts8
17 files changed, 102 insertions, 92 deletions
diff --git a/src/gateway/Server.ts b/src/gateway/Server.ts
index f1ef7a27..81e4b7f4 100644
--- a/src/gateway/Server.ts
+++ b/src/gateway/Server.ts
@@ -56,7 +56,6 @@ export class Server {
 		}
 
 		this.server.on("upgrade", (request, socket, head) => {
-			// @ts-ignore
 			this.ws.handleUpgrade(request, socket, head, (socket) => {
 				this.ws.emit("connection", socket, request);
 			});
diff --git a/src/gateway/events/Close.ts b/src/gateway/events/Close.ts
index 6b069d0b..296ab5ee 100644
--- a/src/gateway/events/Close.ts
+++ b/src/gateway/events/Close.ts
@@ -26,7 +26,7 @@ import {
 	User,
 } from "@fosscord/util";
 
-export async function Close(this: WebSocket, code: number, reason: string) {
+export async function Close(this: WebSocket, code: number, reason: Buffer) {
 	console.log("[WebSocket] closed", code, reason.toString());
 	if (this.heartbeatTimeout) clearTimeout(this.heartbeatTimeout);
 	if (this.readyTimeout) clearTimeout(this.readyTimeout);
diff --git a/src/gateway/events/Connection.ts b/src/gateway/events/Connection.ts
index 85ffb1ed..82081266 100644
--- a/src/gateway/events/Connection.ts
+++ b/src/gateway/events/Connection.ts
@@ -16,6 +16,7 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
+/* eslint-disable @typescript-eslint/ban-ts-comment */
 import WS from "ws";
 import { genSessionId, WebSocket } from "@fosscord/gateway";
 import { Send } from "../util/Send";
@@ -27,10 +28,12 @@ import { Message } from "./Message";
 import { Deflate, Inflate } from "fast-zlib";
 import { URL } from "url";
 import { Config } from "@fosscord/util";
-var erlpack: any;
+let erlpack: unknown;
 try {
 	erlpack = require("@yukikaze-bot/erlpack");
-} catch (error) {}
+} catch (error) {
+	/* empty */
+}
 
 // TODO: check rate limit
 // TODO: specify rate limit in config
diff --git a/src/gateway/events/Message.ts b/src/gateway/events/Message.ts
index 57899a23..b949f273 100644
--- a/src/gateway/events/Message.ts
+++ b/src/gateway/events/Message.ts
@@ -27,14 +27,16 @@ import path from "path";
 import fs from "fs/promises";
 const bigIntJson = BigIntJson({ storeAsString: true });
 
-var erlpack: any;
+let erlpack: { unpack: (buffer: Buffer) => Payload };
 try {
 	erlpack = require("@yukikaze-bot/erlpack");
-} catch (error) {}
+} catch (error) {
+	/* empty */
+}
 
 export async function Message(this: WebSocket, buffer: WS.Data) {
 	// TODO: compression
-	var data: Payload;
+	let data: Payload;
 
 	if (
 		(buffer instanceof Buffer && buffer[0] === 123) || // ASCII 123 = `{`. Bad check for JSON
@@ -44,9 +46,9 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
 	} else if (this.encoding === "json" && buffer instanceof Buffer) {
 		if (this.inflate) {
 			try {
-				buffer = this.inflate.process(buffer) as any;
+				buffer = this.inflate.process(buffer);
 			} catch {
-				buffer = buffer.toString() as any;
+				buffer = buffer.toString();
 			}
 		}
 		data = bigIntJson.parse(buffer as string);
@@ -78,7 +80,6 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
 
 	check.call(this, PayloadSchema, data);
 
-	// @ts-ignore
 	const OPCodeHandler = OPCodeHandlers[data.op];
 	if (!OPCodeHandler) {
 		console.error("[Gateway] Unkown opcode " + data.op);
@@ -100,7 +101,7 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
 			: undefined;
 
 	try {
-		var ret = await OPCodeHandler.call(this, data);
+		const ret = await OPCodeHandler.call(this, data);
 		Sentry.withScope((scope) => {
 			scope.setSpan(transaction);
 			scope.setUser({ id: this.user_id });
diff --git a/src/gateway/listener/listener.ts b/src/gateway/listener/listener.ts
index 9bdee86a..824341f9 100644
--- a/src/gateway/listener/listener.ts
+++ b/src/gateway/listener/listener.ts
@@ -79,7 +79,10 @@ export async function setupListener(this: WebSocket) {
 	const guilds = members.map((x) => x.guild);
 	const dm_channels = recipients.map((x) => x.channel);
 
-	const opts: { acknowledge: boolean; channel?: AMQChannel } = {
+	const opts: {
+		acknowledge: boolean;
+		channel?: AMQChannel & { queues?: unknown };
+	} = {
 		acknowledge: true,
 	};
 	this.listen_options = opts;
@@ -87,7 +90,6 @@ export async function setupListener(this: WebSocket) {
 
 	if (RabbitMQ.connection) {
 		opts.channel = await RabbitMQ.connection.createChannel();
-		// @ts-ignore
 		opts.channel.queues = {};
 	}
 
@@ -113,7 +115,7 @@ export async function setupListener(this: WebSocket) {
 		guild.channels.forEach(async (channel) => {
 			if (
 				permission
-					.overwriteChannel(channel.permission_overwrites!)
+					.overwriteChannel(channel.permission_overwrites ?? [])
 					.has("VIEW_CHANNEL")
 			) {
 				this.events[channel.id] = await listenEvent(
@@ -128,7 +130,7 @@ export async function setupListener(this: WebSocket) {
 	this.once("close", () => {
 		if (opts.channel) opts.channel.close();
 		else {
-			Object.values(this.events).forEach((x) => x());
+			Object.values(this.events).forEach((x) => x?.());
 			Object.values(this.member_events).forEach((x) => x());
 		}
 	});
@@ -137,7 +139,7 @@ export async function setupListener(this: WebSocket) {
 // TODO: only subscribe for events that are in the connection intents
 async function consume(this: WebSocket, opts: EventOpts) {
 	const { data, event } = opts;
-	let id = data.id as string;
+	const id = data.id as string;
 	const permission = this.permissions[id] || new Permissions("ADMINISTRATOR"); // default permission for dm
 
 	const consumer = consume.bind(this);
@@ -150,6 +152,7 @@ async function consume(this: WebSocket, opts: EventOpts) {
 		case "GUILD_MEMBER_REMOVE":
 			this.member_events[data.user.id]?.();
 			delete this.member_events[data.user.id];
+			break;
 		case "GUILD_MEMBER_ADD":
 			if (this.member_events[data.user.id]) break; // already subscribed
 			this.member_events[data.user.id] = await listenEvent(
@@ -158,7 +161,7 @@ async function consume(this: WebSocket, opts: EventOpts) {
 				this.listen_options,
 			);
 			break;
-		case "GUILD_MEMBER_REMOVE":
+		case "GUILD_MEMBER_UPDATE":
 			if (!this.member_events[data.user.id]) break;
 			this.member_events[data.user.id]();
 			break;
@@ -188,9 +191,8 @@ async function consume(this: WebSocket, opts: EventOpts) {
 		case "GUILD_CREATE":
 			this.events[id] = await listenEvent(id, consumer, listenOpts);
 			break;
-		case "CHANNEL_UPDATE":
+		case "CHANNEL_UPDATE": {
 			const exists = this.events[id];
-			// @ts-ignore
 			if (
 				permission
 					.overwriteChannel(data.permission_overwrites)
@@ -204,6 +206,7 @@ async function consume(this: WebSocket, opts: EventOpts) {
 				delete this.events[id];
 			}
 			break;
+		}
 	}
 
 	// permission checking
@@ -218,8 +221,7 @@ async function consume(this: WebSocket, opts: EventOpts) {
 			break;
 		case "GUILD_MEMBER_ADD":
 		case "GUILD_MEMBER_REMOVE":
-		case "GUILD_MEMBER_UPDATE":
-		// only send them, if the user subscribed for this part of the member list, or is a bot
+		case "GUILD_MEMBER_UPDATE": // only send them, if the user subscribed for this part of the member list, or is a bot
 		case "PRESENCE_UPDATE": // exception if user is friend
 			break;
 		case "GUILD_BAN_ADD":
diff --git a/src/gateway/opcodes/Heartbeat.ts b/src/gateway/opcodes/Heartbeat.ts
index b7f21a56..77c8671f 100644
--- a/src/gateway/opcodes/Heartbeat.ts
+++ b/src/gateway/opcodes/Heartbeat.ts
@@ -16,11 +16,11 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { Payload, WebSocket } from "@fosscord/gateway";
+import { WebSocket } from "@fosscord/gateway";
 import { setHeartbeat } from "../util/Heartbeat";
 import { Send } from "../util/Send";
 
-export async function onHeartbeat(this: WebSocket, data: Payload) {
+export async function onHeartbeat(this: WebSocket) {
 	// TODO: validate payload
 
 	setHeartbeat(this);
diff --git a/src/gateway/opcodes/Identify.ts b/src/gateway/opcodes/Identify.ts
index 8d762967..030ca66e 100644
--- a/src/gateway/opcodes/Identify.ts
+++ b/src/gateway/opcodes/Identify.ts
@@ -42,13 +42,13 @@ import {
 	UserGuildSettings,
 	ReadyGuildDTO,
 	Guild,
+	UserTokenData,
 } from "@fosscord/util";
 import { Send } from "../util/Send";
 import { CLOSECODES, OPCODES } from "../util/Constants";
-import { genSessionId } from "../util/SessionUtils";
 import { setupListener } from "../listener/listener";
 // import experiments from "./experiments.json";
-const experiments: any = [];
+const experiments: unknown[] = [];
 import { check } from "./instanceOf";
 import { Recipient } from "@fosscord/util";
 
@@ -56,6 +56,8 @@ import { Recipient } from "@fosscord/util";
 // TODO: check privileged intents, if defined in the config
 // TODO: check if already identified
 
+// TODO: Refactor identify ( and lazyrequest, tbh )
+
 export async function onIdentify(this: WebSocket, data: Payload) {
 	clearTimeout(this.readyTimeout);
 	// TODO: is this needed now that we use `json-bigint`?
@@ -65,15 +67,16 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 
 	const identify: IdentifySchema = data.d;
 
+	let decoded: UserTokenData["decoded"];
 	try {
 		const { jwtSecret } = Config.get().security;
-		var { decoded } = await checkToken(identify.token, jwtSecret); // will throw an error if invalid
+		decoded = (await checkToken(identify.token, jwtSecret)).decoded; // will throw an error if invalid
 	} catch (error) {
 		console.error("invalid token", error);
 		return this.close(CLOSECODES.Authentication_failed);
 	}
 	this.user_id = decoded.id;
-	let session_id = this.session_id;
+	const session_id = this.session_id;
 
 	const [user, read_states, members, recipients, session, application] =
 		await Promise.all([
@@ -144,7 +147,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 			return this.close(CLOSECODES.Invalid_shard);
 		}
 	}
-	var users: PublicUser[] = [];
+	let users: PublicUser[] = [];
 
 	const merged_members = members.map((x: Member) => {
 		return [
@@ -156,18 +159,18 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 			},
 		];
 	}) as PublicMember[][];
-	let guilds = members.map((x) => ({ ...x.guild, joined_at: x.joined_at }));
+	// TODO: This type is bad.
+	let guilds: Partial<Guild>[] = members.map((x) => ({
+		...x.guild,
+		joined_at: x.joined_at,
+	}));
 
 	const pending_guilds: typeof guilds = [];
-	// @ts-ignore
-	guilds = guilds.map((guild) => {
-		if (user.bot) {
+	if (user.bot)
+		guilds = guilds.map((guild) => {
 			pending_guilds.push(guild);
 			return { id: guild.id, unavailable: true };
-		}
-
-		return guild;
-	});
+		});
 
 	// TODO: Rewrite this. Perhaps a DTO?
 	const user_guild_settings_entries = members.map((x) => ({
@@ -180,24 +183,25 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 			...y[1],
 			channel_id: y[0],
 		})),
-	})) as any as UserGuildSettings[];
+	})) as unknown as UserGuildSettings[];
 
 	const channels = recipients.map((x) => {
+		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 		//@ts-ignore
-		x.channel.recipients = x.channel.recipients?.map((x) =>
+		x.channel.recipients = x.channel.recipients.map((x) =>
 			x.user.toPublicUser(),
 		);
 		//TODO is this needed? check if users in group dm that are not friends are sent in the READY event
 		users = users.concat(x.channel.recipients as unknown as User[]);
 		if (x.channel.isDm()) {
-			x.channel.recipients = x.channel.recipients!.filter(
+			x.channel.recipients = x.channel.recipients?.filter(
 				(x) => x.id !== this.user_id,
 			);
 		}
 		return x.channel;
 	});
 
-	for (let relation of user.relationships) {
+	for (const relation of user.relationships) {
 		const related_user = relation.to;
 		const public_related_user = {
 			username: related_user.username,
@@ -236,7 +240,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 		} as PresenceUpdateEvent);
 	});
 
-	read_states.forEach((s: any) => {
+	read_states.forEach((s: Partial<ReadState>) => {
 		s.id = s.channel_id;
 		delete s.user_id;
 		delete s.channel_id;
@@ -275,10 +279,11 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 		}, //TODO: check this code!
 		user: privateUser,
 		user_settings: user.settings,
+		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 		// @ts-ignore
-		guilds: guilds.map((x) => {
+		guilds: guilds.map((x: Guild & { joined_at: Date }) => {
 			return {
-				...new ReadyGuildDTO(x as Guild & { joined_at: Date }).toJSON(),
+				...new ReadyGuildDTO(x).toJSON(),
 				guild_hashes: {},
 				joined_at: x.joined_at,
 			};
@@ -307,6 +312,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
 		},
 		country_code: user.settings.locale,
 		friend_suggestion_count: 0, // TODO
+		// eslint-disable-next-line @typescript-eslint/ban-ts-comment
 		// @ts-ignore
 		experiments: experiments, // TODO
 		guild_join_requests: [], // TODO what is this?
diff --git a/src/gateway/opcodes/LazyRequest.ts b/src/gateway/opcodes/LazyRequest.ts
index d4b612b8..93524058 100644
--- a/src/gateway/opcodes/LazyRequest.ts
+++ b/src/gateway/opcodes/LazyRequest.ts
@@ -46,24 +46,25 @@ async function getMembers(guild_id: string, range: [number, number]) {
 
 	let members: Member[] = [];
 	try {
-		members = await getDatabase()!
-			.getRepository(Member)
-			.createQueryBuilder("member")
-			.where("member.guild_id = :guild_id", { guild_id })
-			.leftJoinAndSelect("member.roles", "role")
-			.leftJoinAndSelect("member.user", "user")
-			.leftJoinAndSelect("user.sessions", "session")
-			.addSelect("user.settings")
-			.addSelect(
-				"CASE WHEN session.status = 'offline' THEN 0 ELSE 1 END",
-				"_status",
-			)
-			.orderBy("role.position", "DESC")
-			.addOrderBy("_status", "DESC")
-			.addOrderBy("user.username", "ASC")
-			.offset(Number(range[0]) || 0)
-			.limit(Number(range[1]) || 100)
-			.getMany();
+		members =
+			(await getDatabase()
+				?.getRepository(Member)
+				.createQueryBuilder("member")
+				.where("member.guild_id = :guild_id", { guild_id })
+				.leftJoinAndSelect("member.roles", "role")
+				.leftJoinAndSelect("member.user", "user")
+				.leftJoinAndSelect("user.sessions", "session")
+				.addSelect("user.settings")
+				.addSelect(
+					"CASE WHEN session.status = 'offline' THEN 0 ELSE 1 END",
+					"_status",
+				)
+				.orderBy("role.position", "DESC")
+				.addOrderBy("_status", "DESC")
+				.addOrderBy("user.username", "ASC")
+				.offset(Number(range[0]) || 0)
+				.limit(Number(range[1]) || 100)
+				.getMany()) ?? [];
 	} catch (e) {
 		console.error(`LazyRequest`, e);
 	}
@@ -77,7 +78,7 @@ async function getMembers(guild_id: string, range: [number, number]) {
 		};
 	}
 
-	const groups = [] as any[];
+	const groups = [];
 	const items = [];
 	const member_roles = members
 		.map((m) => m.roles)
@@ -93,10 +94,9 @@ async function getMembers(guild_id: string, range: [number, number]) {
 	const offlineItems = [];
 
 	for (const role of member_roles) {
-		// @ts-ignore
-		const [role_members, other_members]: Member[][] = partition(
+		const [role_members, other_members] = partition(
 			members,
-			(m: Member) => m.roles.find((r) => r.id === role.id),
+			(m: Member) => !!m.roles.find((r) => r.id === role.id),
 		);
 		const group = {
 			count: role_members.length,
@@ -126,7 +126,7 @@ async function getMembers(guild_id: string, range: [number, number]) {
 					(a.activities.length - b.activities.length) * 2
 				);
 			});
-			var session: Session | undefined = sessions.first();
+			const session: Session | undefined = sessions.first();
 
 			if (session?.status == "offline") {
 				session.status = member?.user?.settings?.status || "online";
@@ -189,7 +189,9 @@ async function getMembers(guild_id: string, range: [number, number]) {
 export async function onLazyRequest(this: WebSocket, { d }: Payload) {
 	// TODO: check data
 	check.call(this, LazyRequestSchema, d);
+	// eslint-disable-next-line @typescript-eslint/no-unused-vars
 	const { guild_id, typing, channels, activities } = d as LazyRequestSchema;
+	if (!channels) throw new Error("Must provide channel ranges");
 
 	const channel_id = Object.keys(channels || {}).first();
 	if (!channel_id) return;
@@ -197,7 +199,7 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
 	const permissions = await getPermission(this.user_id, guild_id, channel_id);
 	permissions.hasThrow("VIEW_CHANNEL");
 
-	const ranges = channels![channel_id];
+	const ranges = channels[channel_id];
 	if (!Array.isArray(ranges)) throw new Error("Not a valid Array");
 
 	const member_count = await Member.count({ where: { guild_id } });
@@ -244,15 +246,10 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
 	});
 }
 
-function partition<T>(array: T[], isValid: Function) {
-	// @ts-ignore
-	return array.reduce(
-		// @ts-ignore
-		([pass, fail], elem) => {
-			return isValid(elem)
-				? [[...pass, elem], fail]
-				: [pass, [...fail, elem]];
-		},
-		[[], []],
-	);
+/* https://stackoverflow.com/a/50636286 */
+function partition<T>(array: T[], filter: (elem: T) => boolean) {
+	const pass: T[] = [],
+		fail: T[] = [];
+	array.forEach((e) => (filter(e) ? pass : fail).push(e));
+	return [pass, fail];
 }
diff --git a/src/gateway/opcodes/RequestGuildMembers.ts b/src/gateway/opcodes/RequestGuildMembers.ts
index d669b30e..7822813b 100644
--- a/src/gateway/opcodes/RequestGuildMembers.ts
+++ b/src/gateway/opcodes/RequestGuildMembers.ts
@@ -16,8 +16,8 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { Payload, WebSocket } from "@fosscord/gateway";
+import { WebSocket } from "@fosscord/gateway";
 
-export function onRequestGuildMembers(this: WebSocket, data: Payload) {
+export function onRequestGuildMembers(this: WebSocket) {
 	// return this.close(CLOSECODES.Unknown_error);
 }
diff --git a/src/gateway/opcodes/Resume.ts b/src/gateway/opcodes/Resume.ts
index d4bd5320..a8650cc4 100644
--- a/src/gateway/opcodes/Resume.ts
+++ b/src/gateway/opcodes/Resume.ts
@@ -16,10 +16,10 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { WebSocket, Payload } from "@fosscord/gateway";
+import { WebSocket } from "@fosscord/gateway";
 import { Send } from "../util/Send";
 
-export async function onResume(this: WebSocket, data: Payload) {
+export async function onResume(this: WebSocket) {
 	console.log("Got Resume -> cancel not implemented");
 	await Send(this, {
 		op: 9,
diff --git a/src/gateway/opcodes/VoiceStateUpdate.ts b/src/gateway/opcodes/VoiceStateUpdate.ts
index 5ee02e82..d300d7b7 100644
--- a/src/gateway/opcodes/VoiceStateUpdate.ts
+++ b/src/gateway/opcodes/VoiceStateUpdate.ts
@@ -99,6 +99,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
 		voiceState.token = genVoiceToken();
 	voiceState.session_id = this.session_id;
 
+	// eslint-disable-next-line @typescript-eslint/no-unused-vars
 	const { id, ...newObj } = voiceState;
 
 	await Promise.all([
diff --git a/src/gateway/opcodes/index.ts b/src/gateway/opcodes/index.ts
index 05e8964b..1e32f1e6 100644
--- a/src/gateway/opcodes/index.ts
+++ b/src/gateway/opcodes/index.ts
@@ -25,7 +25,7 @@ import { onRequestGuildMembers } from "./RequestGuildMembers";
 import { onResume } from "./Resume";
 import { onVoiceStateUpdate } from "./VoiceStateUpdate";
 
-export type OPCodeHandler = (this: WebSocket, data: Payload) => any;
+export type OPCodeHandler = (this: WebSocket, data: Payload) => unknown;
 
 export default {
 	1: onHeartbeat,
@@ -40,4 +40,4 @@ export default {
 	// 10: Hello
 	// 13: Dm_update
 	14: onLazyRequest,
-};
+} as { [key: number]: OPCodeHandler };
diff --git a/src/gateway/opcodes/instanceOf.ts b/src/gateway/opcodes/instanceOf.ts
index 17de0a67..6c23cb08 100644
--- a/src/gateway/opcodes/instanceOf.ts
+++ b/src/gateway/opcodes/instanceOf.ts
@@ -20,7 +20,7 @@ import { instanceOf } from "lambert-server";
 import { WebSocket } from "@fosscord/gateway";
 import { CLOSECODES } from "../util/Constants";
 
-export function check(this: WebSocket, schema: any, data: any) {
+export function check(this: WebSocket, schema: unknown, data: unknown) {
 	try {
 		const error = instanceOf(schema, data, { path: "body" });
 		if (error !== true) {
diff --git a/src/gateway/start.ts b/src/gateway/start.ts
index b86c3eca..79448f91 100644
--- a/src/gateway/start.ts
+++ b/src/gateway/start.ts
@@ -24,7 +24,7 @@ import { Server } from "./Server";
 import { config } from "dotenv";
 config();
 
-var port = Number(process.env.PORT);
+let port = Number(process.env.PORT);
 if (isNaN(port)) port = 3002;
 
 const server = new Server({
diff --git a/src/gateway/util/Constants.ts b/src/gateway/util/Constants.ts
index cc67ed0f..cb60005c 100644
--- a/src/gateway/util/Constants.ts
+++ b/src/gateway/util/Constants.ts
@@ -64,6 +64,7 @@ export enum CLOSECODES {
 
 export interface Payload {
 	op: OPCODES /*  | VoiceOPCodes */;
+	// eslint-disable-next-line @typescript-eslint/no-explicit-any
 	d?: any;
 	s?: number;
 	t?: string;
diff --git a/src/gateway/util/Send.ts b/src/gateway/util/Send.ts
index 1ca143b6..a89d92d7 100644
--- a/src/gateway/util/Send.ts
+++ b/src/gateway/util/Send.ts
@@ -16,7 +16,7 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-var erlpack: any;
+let erlpack: { pack: (data: Payload) => Buffer };
 try {
 	erlpack = require("@yukikaze-bot/erlpack");
 } catch (error) {
@@ -63,7 +63,7 @@ export function Send(socket: WebSocket, data: Payload) {
 			return;
 		}
 
-		socket.send(buffer, (err: any) => {
+		socket.send(buffer, (err) => {
 			if (err) return rej(err);
 			return res(null);
 		});
diff --git a/src/gateway/util/WebSocket.ts b/src/gateway/util/WebSocket.ts
index d4a4b8b3..14917f21 100644
--- a/src/gateway/util/WebSocket.ts
+++ b/src/gateway/util/WebSocket.ts
@@ -16,7 +16,7 @@
 	along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
 
-import { Intents, Permissions } from "@fosscord/util";
+import { Intents, ListenEventOpts, Permissions } from "@fosscord/util";
 import WS from "ws";
 import { Deflate, Inflate } from "fast-zlib";
 // import { Client } from "@fosscord/webrtc";
@@ -37,8 +37,8 @@ export interface WebSocket extends WS {
 	intents: Intents;
 	sequence: number;
 	permissions: Record<string, Permissions>;
-	events: Record<string, Function>;
-	member_events: Record<string, Function>;
-	listen_options: any;
+	events: Record<string, undefined | (() => unknown)>;
+	member_events: Record<string, () => unknown>;
+	listen_options: ListenEventOpts;
 	// client?: Client;
 }