fix: persist server mute/deafen state across reloads and prevent client bypass

Server-side: add DB persistence for voice restrictions (schema, migration,
ready payload, cleanup on leave). Client-side: fix four bugs that wiped or
bypassed server restriction state — leaveVoice() no longer clears global
restriction Sets, voice_state_update leave no longer drops amber icons,
toggleMic/toggleDeafen now guard against server restrictions, and force-mute/
deafen uses direct setState instead of fragile toggle calls.
This commit is contained in:
Jannis Braun
2026-03-09 18:36:17 +01:00
parent f6cdfe993f
commit c2ddfe0cb7
7 changed files with 236 additions and 28 deletions
+13
View File
@@ -890,6 +890,19 @@ function buildReadyPayload(userId: string): {
}
}
// Also include the connecting user's own DB-persisted restrictions
// (covers reconnect after disconnect timeout cleared in-memory state)
const myRestrictions = db.select()
.from(schema.voiceRestrictions)
.where(eq(schema.voiceRestrictions.userId, userId))
.all();
for (const r of myRestrictions) {
const existing = serverVoiceStates[userId] ?? { serverMuted: false, serverDeafened: false };
if (r.restrictionType === 'mute') existing.serverMuted = true;
if (r.restrictionType === 'deafen') existing.serverDeafened = true;
serverVoiceStates[userId] = existing;
}
// Fetch read states for unread tracking
const readStateRows = db.select()
.from(schema.readStates)