Allow null guild/channel ids for voice states

This commit is contained in:
Rory& committed 2026-10-17 10:35:47 +02:00
1 parent 91bfce71ee
commit 0a04fdd91f
10 files changed
+23 -24

No files matched your search

Binary file not shown.
Binary file not shown.
@@ -47,7 +47,7 @@ router.patch(
const { guild_id } = req.params as { [key: string]: string };
const user_id = req.params.user_id === "@me" ? req.user_id : (req.params.user_id as string);
const perms = await getPermission(req.user_id, guild_id, body.channel_id);
const perms = await getPermission(req.user_id, guild_id, body.channel_id!);
/*
From https://discord.com/developers/docs/resources/guild#modify-current-user-voice-state
@@ -63,7 +63,7 @@ router.patch(
const voiceState = await VoiceState.findOne({
where: {
guild_id,
channel_id: body.channel_id,
channel_id: body.channel_id!,
user_id,
},
});
@@ -71,7 +71,7 @@ router.patch(
voiceState.assign(body);
const channel = await Channel.findOneOrFail({
where: { guild_id, id: body.channel_id },
where: { guild_id, id: body.channel_id! },
});
if (channel.type !== ChannelType.GUILD_STAGE_VOICE) {
throw DiscordApiErrors.CANNOT_EXECUTE_ON_THIS_CHANNEL_TYPE;
@@ -80,7 +80,7 @@ router.patch(
voiceState.member = await Member.findOneOrFail({
where: {
id: voiceState.user_id,
guild_id: voiceState.guild_id,
guild_id: voiceState.guild_id!,
},
});
+2 -2
View File
@@ -31,7 +31,7 @@ import { PublicVoiceState, PublicVoiceStateProjection } from "@spacebar/schemas"
export class VoiceState extends BaseClass {
@Column({ nullable: true })
@RelationId((voice_state: VoiceState) => voice_state.guild)
guild_id: string;
guild_id: string | null;
@JoinColumn({ name: "guild_id", foreignKeyConstraintName: "FK_voice_state_guild_id" })
@ManyToOne(() => Guild, (guild) => guild.voice_states, {
@@ -41,7 +41,7 @@ export class VoiceState extends BaseClass {
@Column({ nullable: true })
@RelationId((voice_state: VoiceState) => voice_state.channel)
channel_id: string;
channel_id: string | null;
@JoinColumn({ name: "channel_id", foreignKeyConstraintName: "FK_voice_state_channel_id" })
@ManyToOne(() => Channel, {
+2 -4
View File
@@ -76,9 +76,7 @@ export async function Close(this: WebSocket, code: number, reason: Buffer) {
const prevGuildId = voiceState.guild_id;
const prevChannelId = voiceState.channel_id;
// @ts-expect-error channel_id is nullable
voiceState.channel_id = null;
// @ts-expect-error guild_id is nullable
voiceState.guild_id = null;
voiceState.self_stream = false;
voiceState.self_video = false;
@@ -87,7 +85,7 @@ export async function Close(this: WebSocket, code: number, reason: Buffer) {
voiceState.member = await Member.findOneOrFail({
where: {
id: voiceState.user_id,
guild_id: prevGuildId,
guild_id: prevGuildId!,
},
});
// let the users in previous guild/channel know that user disconnected
@@ -98,7 +96,7 @@ export async function Close(this: WebSocket, code: number, reason: Buffer) {
guild_id: prevGuildId, // have to send the previous guild_id because that's what client expects for disconnect messages
member: voiceState.member.toPublicMember(),
},
guild_id: prevGuildId,
guild_id: prevGuildId!,
channel_id: prevChannelId,
} satisfies VoiceStateUpdateEvent);
}
+2 -2
View File
@@ -52,7 +52,7 @@ export async function onStreamCreate(this: WebSocket, data: Payload) {
if (body.guild_id) {
voiceState.member = await Member.findOneOrFail({
where: { id: voiceState.user_id, guild_id: voiceState.guild_id },
where: { id: voiceState.user_id, guild_id: voiceState.guild_id! }, // TODO: dm calls?
relations: { user: true, roles: true },
});
}
@@ -133,7 +133,7 @@ export async function onStreamCreate(this: WebSocket, data: Payload) {
...voiceState.toPublicVoiceState(),
member: voiceState.member.toPublicMember(),
},
guild_id: voiceState.guild_id,
guild_id: voiceState.guild_id!, // TODO: figure out how this works for DM calls
channel_id: voiceState.channel_id,
} satisfies VoiceStateUpdateEvent);
+1 -1
View File
@@ -89,7 +89,7 @@ export async function onStreamDelete(this: WebSocket, data: Payload) {
voiceState.member = await Member.findOneOrFail({
where: {
id: voiceState.user_id,
guild_id: voiceState.guild_id,
guild_id: voiceState.guild_id!, // TODO: DM calls?
},
});
+9 -8
View File
@@ -46,8 +46,8 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
const body = data.d as VoiceStateUpdateSchema;
// TODO: should this be null?
if (body.channel_id == "") body.channel_id = undefined;
if (body.guild_id == "") body.guild_id = undefined;
if (body.channel_id === "") body.channel_id = null;
if (body.guild_id === "") body.guild_id = null;
const isNew = body.channel_id === null && body.guild_id === null;
let isChanged = false;
@@ -100,8 +100,8 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
channel_id: null,
guild_id: null,
},
guild_id: prevState?.guild_id,
channel_id: prevState?.channel_id,
guild_id: prevState?.guild_id ?? undefined, // should this be null?
channel_id: prevState?.channel_id ?? undefined, // should this be null?
});
}
@@ -110,7 +110,7 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
//TODO this may fail
if (body.guild_id) {
const member = await Member.findOne({
where: { id: voiceState.user_id, guild_id: voiceState.guild_id },
where: { id: voiceState.user_id, guild_id: voiceState.guild_id! },
relations: { user: true, roles: true },
});
@@ -133,16 +133,17 @@ export async function onVoiceStateUpdate(this: WebSocket, data: Payload) {
...voiceState.toPublicVoiceState(),
member: member?.toPublicMember(),
},
guild_id: voiceState.guild_id,
channel_id: voiceState.channel_id,
guild_id: voiceState.guild_id || undefined, // TODO: should this be null?
channel_id: voiceState.channel_id || undefined, // TODO: should this be null?
user_id: voiceState.user_id,
} satisfies VoiceStateUpdateEvent),
]);
//If it's null it means that we are leaving the channel and this event is not needed
if ((isNew || isChanged) && voiceState.channel_id !== null) {
// TODO: DM calls?
const guild = await Guild.findOne({
where: { id: voiceState.guild_id },
where: { id: voiceState.guild_id! },
});
const regions = Config.get().regions;
let guildRegion: ConfigVoiceRegion | undefined;
@@ -18,8 +18,8 @@
//TODO need more testing when community guild and voice stage channel are working
export interface VoiceStateUpdateSchema {
guild_id?: string;
channel_id?: string;
guild_id?: string | null;
channel_id?: string | null;
self_mute: boolean;
self_deaf: boolean;
self_video?: boolean;
+1 -1
View File
@@ -80,7 +80,7 @@ export async function onIdentify(this: WebRtcWebSocket, data: VoicePayload) {
const voiceRoomId = type === "stream" ? server_id : voiceState!.channel_id;
try {
this.webRtcClient = await mediaServer.join(voiceRoomId, this.user_id, this, type!);
this.webRtcClient = await mediaServer.join(voiceRoomId!, this.user_id, this, type!);
} catch (e) {
return this.close(4013);
}