diff --git a/gateway/src/Server.ts b/gateway/src/Server.ts
index cf4f906c..7e1489be 100644
--- a/gateway/src/Server.ts
+++ b/gateway/src/Server.ts
@@ -32,7 +32,6 @@ export class Server {
}
this.server.on("upgrade", (request, socket, head) => {
- console.log("socket requests upgrade", request.url);
// @ts-ignore
this.ws.handleUpgrade(request, socket, head, (socket) => {
this.ws.emit("connection", socket, request);
diff --git a/gateway/src/events/Close.ts b/gateway/src/events/Close.ts
index 1299ad5c..5c1bd292 100644
--- a/gateway/src/events/Close.ts
+++ b/gateway/src/events/Close.ts
@@ -1,10 +1,13 @@
import { WebSocket } from "@fosscord/gateway";
-import { Message } from "./Message";
import { Session } from "@fosscord/util";
export async function Close(this: WebSocket, code: number, reason: string) {
console.log("[WebSocket] closed", code, reason);
if (this.session_id) await Session.delete({ session_id: this.session_id });
- // @ts-ignore
- this.off("message", Message);
+ if (this.heartbeatTimeout) clearTimeout(this.heartbeatTimeout);
+ if (this.readyTimeout) clearTimeout(this.readyTimeout);
+
+ this.deflate?.close();
+
+ this.removeAllListeners();
}
diff --git a/gateway/src/events/Connection.ts b/gateway/src/events/Connection.ts
index c1a6b618..9bb034f0 100644
--- a/gateway/src/events/Connection.ts
+++ b/gateway/src/events/Connection.ts
@@ -24,9 +24,11 @@ export async function Connection(
request: IncomingMessage
) {
try {
+ // @ts-ignore
socket.on("close", Close);
// @ts-ignore
socket.on("message", Message);
+ console.log(`[Gateway] Connections: ${this.clients.size}`);
const { searchParams } = new URL(`http://localhost${request.url}`);
// @ts-ignore
@@ -68,12 +70,10 @@ export async function Connection(
});
socket.readyTimeout = setTimeout(() => {
- Session.delete({ session_id: socket.session_id }); //should we await?
return socket.close(CLOSECODES.Session_timed_out);
}, 1000 * 30);
} catch (error) {
console.error(error);
- Session.delete({ session_id: socket.session_id }); //should we await?
return socket.close(CLOSECODES.Unknown_error);
}
}
diff --git a/gateway/src/events/Message.ts b/gateway/src/events/Message.ts
index af318bfd..acc39bb9 100644
--- a/gateway/src/events/Message.ts
+++ b/gateway/src/events/Message.ts
@@ -37,8 +37,6 @@ export async function Message(this: WebSocket, buffer: WS.Data) {
return;
}
- console.log("[Gateway] Opcode " + OPCODES[data.op]);
-
try {
return await OPCodeHandler.call(this, data);
} catch (error) {
diff --git a/gateway/src/listener/listener.ts b/gateway/src/listener/listener.ts
index ee640f38..c5b1a576 100644
--- a/gateway/src/listener/listener.ts
+++ b/gateway/src/listener/listener.ts
@@ -178,7 +178,7 @@ async function consume(this: WebSocket, opts: EventOpts) {
case "CHANNEL_CREATE":
case "CHANNEL_DELETE":
case "CHANNEL_UPDATE":
- case "GUILD_EMOJI_UPDATE":
+ case "GUILD_EMOJIS_UPDATE":
case "READY": // will be sent by the gateway
case "USER_UPDATE":
case "APPLICATION_COMMAND_CREATE":
diff --git a/gateway/src/opcodes/Identify.ts b/gateway/src/opcodes/Identify.ts
index 6decf21c..c91ca5dd 100644
--- a/gateway/src/opcodes/Identify.ts
+++ b/gateway/src/opcodes/Identify.ts
@@ -11,6 +11,7 @@ import {
PublicMember,
PublicUser,
PrivateUserProjection,
+ ReadState,
} from "@fosscord/util";
import { Send } from "../util/Send";
import { CLOSECODES, OPCODES } from "../util/Constants";
@@ -40,7 +41,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
return this.close(CLOSECODES.Authentication_failed);
}
this.user_id = decoded.id;
- if (!identify.intents) identify.intents = 0b11111111111111n;
+ if (!identify.intents) identify.intents = BigInt("0b11111111111111");
this.intents = new Intents(identify.intents);
if (identify.shard) {
this.shard_id = identify.shard[0];
@@ -64,6 +65,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
"guild",
"guild.channels",
"guild.emojis",
+ "guild.emojis.user",
"guild.roles",
"guild.stickers",
"user",
@@ -92,7 +94,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
// @ts-ignore
x.channel.recipients = x.channel.recipients?.map((x) => x.user);
//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);
+ users = users.concat(x.channel.recipients as unknown as User[]);
if (x.channel.isDm()) {
x.channel.recipients = x.channel.recipients!.filter(
(x) => x.id !== this.user_id
@@ -138,6 +140,13 @@ export async function onIdentify(this: WebSocket, data: Payload) {
//We save the session and we delete it when the websocket is closed
await session.save();
+ const read_states = await ReadState.find({ user_id: this.user_id });
+ read_states.forEach((s: any) => {
+ s.id = s.channel_id;
+ delete s.user_id;
+ delete s.channel_id;
+ });
+
const privateUser = {
avatar: user.avatar,
mobile: user.mobile,
@@ -176,8 +185,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
geo_ordered_rtc_regions: [], // TODO
relationships: user.relationships.map((x) => x.toPublicRelationship()),
read_state: {
- // TODO
- entries: [],
+ entries: read_states,
partial: false,
version: 304128,
},
@@ -200,14 +208,12 @@ export async function onIdentify(this: WebSocket, data: Payload) {
// @ts-ignore
experiments: experiments, // TODO
guild_join_requests: [], // TODO what is this?
- users: users.unique(),
+ users: users.filter((x) => x).unique(),
merged_members: merged_members,
// shard // TODO: only for bots sharding
// application // TODO for applications
};
- console.log("Send ready");
-
// TODO: send real proper data structure
await Send(this, {
op: OPCODES.Dispatch,
diff --git a/gateway/src/opcodes/LazyRequest.ts b/gateway/src/opcodes/LazyRequest.ts
index d37e32da..f5fd561a 100644
--- a/gateway/src/opcodes/LazyRequest.ts
+++ b/gateway/src/opcodes/LazyRequest.ts
@@ -41,6 +41,7 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
const items = [];
for (const role of roles) {
+ // @ts-ignore
const [role_members, other_members] = partition(members, (m: Member) =>
m.roles.find((r) => r.id === role.id)
);
@@ -53,9 +54,12 @@ export async function onLazyRequest(this: WebSocket, { d }: Payload) {
groups.push(group);
for (const member of role_members) {
- member.roles = member.roles.filter((x) => x.id !== guild_id);
+ member.roles = member.roles.filter((x: Role) => x.id !== guild_id);
items.push({
- member: { ...member, roles: member.roles.map((x) => x.id) },
+ member: {
+ ...member,
+ roles: member.roles.map((x: Role) => x.id),
+ },
});
}
members = other_members;
@@ -84,7 +88,9 @@ 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]
diff --git a/gateway/src/util/Send.ts b/gateway/src/util/Send.ts
index 4defa898..196d4205 100644
--- a/gateway/src/util/Send.ts
+++ b/gateway/src/util/Send.ts
@@ -18,6 +18,9 @@ export async function Send(socket: WebSocket, data: Payload) {
}
return new Promise((res, rej) => {
+ if (socket.readyState !== 1) {
+ return rej("socket not open");
+ }
socket.send(buffer, (err: any) => {
if (err) return rej(err);
return res(null);
|