proper versioning and v6 guilds

This commit is contained in:
murdle 2026-01-04 14:54:46 +02:00
parent 5d13edf1be
commit fc40a3757d
5 changed files with 88 additions and 67 deletions

Binary file not shown.

Binary file not shown.

BIN
package-lock.json generated

Binary file not shown.

View File

@ -111,8 +111,8 @@ export async function Connection(
if (socket.encoding === "etf" && !erlpack)
throw new Error("Erlpack is not installed: 'npm i @yukikaze-bot/erlpack'");
socket.version = Number(searchParams.get("version")) || 8;
if (socket.version != 8)
socket.version = Number(searchParams.get("v")) || 9;
if (socket.version != 9 && socket.version != 6)
return socket.close(CLOSECODES.Invalid_API_version);
// @ts-ignore

View File

@ -409,23 +409,47 @@ export async function onIdentify(this: WebSocket, data: Payload) {
const pending_guilds: Guild[] = [];
// Generate guilds list ( make them unavailable if user is bot )
const guilds: GuildOrUnavailable[] = members.map((member) => {
member.guild.channels = member.guild.channels
/*
//TODO maybe implement this correctly, by causing create and delete events for users who can newly view and not view the channels, along with doing these checks correctly, as they don't currently take into account that the owner of the guild is always able to view channels, with potentially other issues
.filter((channel) => {
const perms = Permissions.finalPermission({
user: {
id: member.id,
roles: member.roles.map((x) => x.id),
},
guild: member.guild,
channel,
});
let guilds: GuildOrUnavailable[];
return perms.has("VIEW_CHANNEL");
})
*/
if (this.version === 6) {
const membersByGuild = new Map<string, any[]>();
for (const member of members) {
if (!membersByGuild.has(member.guild_id)) {
membersByGuild.set(member.guild_id, []);
}
membersByGuild.get(member.guild_id)!.push({
...member.toPublicMember(),
roles: member.roles
.filter((r) => r.id !== member.guild.id)
.map((r) => r.id),
user: user.toPublicUser(),
});
}
guilds = members.map((member) => {
const g = member.guild;
return {
...g.toJSON(),
joined_at: member.joined_at,
channels: g.channels,
roles: g.roles,
emojis: g.emojis,
stickers: g.stickers,
voice_states: g.voice_states ?? [],
members: membersByGuild.get(g.id) ?? [],
member_count: membersByGuild.get(g.id)?.length ?? 1,
presences: [],
guild_scheduled_events: [],
threads: [],
large: false,
};
});
} else {
guilds = members.map((member) => {
member.guild.channels = member.guild.channels
.map((channel) => {
channel.position = member.guild.channel_ordering.indexOf(channel.id);
return channel;
@ -444,6 +468,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
threads: [],
};
});
}
const generateGuildsListTime = taskSw.getElapsedAndReset();
// Generate user_guild_settings
@ -555,7 +580,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
d = {
v: 6,
...base,
heartbeat_interval: 45_000,
heartbeat_interval: 45000,
guilds,
private_channels: channels,
presences: [],
@ -745,8 +770,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
}),
);
const pendingGuildsTime = Date.now();
if (this.version == 9) {
const readySupplementalGuilds = (guilds.filter((guild) => !guild.unavailable) as Guild[]).map((guild) => {
return {
voice_states: guild.voice_states.map((state) => {
@ -780,15 +804,12 @@ export async function onIdentify(this: WebSocket, data: Payload) {
disclose: [], // Config.get().general.uniqueUsernames ? ["pomelo"] : []
},
});
const readySupplementalTime = Date.now();
}
//TODO send GUILD_MEMBER_LIST_UPDATE
//TODO send VOICE_STATE_UPDATE to let the client know if another device is already connected to a voice channel
await setupListener.call(this);
const setupListenerTime = Date.now();
console.log(`[Gateway] IDENTIFY ${this.user_id} in ${totalSw.elapsed().totalMilliseconds}ms`, process.env.LOG_GATEWAY_TRACES ? JSON.stringify(d._trace, null, 2) : "");
}