mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
* fix(ws): 1 defect(s) (OC-0001) * fix(db): 1 defect(s) (OC-0002) sanitizeFTSQuery filtered only characters, so FTS5's bareword boolean keywords (AND, OR, NOT) reached MATCH as operators; a query in an invalid operator position raised "fts5: syntax error" instead of returning results. Drop those bareword tokens after sanitizing. * fix(dm): 1 defect(s) (OC-0004) * fix(ws): 1 defect(s) (OC-0005) * fix(voice): 1 defect(s) (OC-0006) Count the shared voice_max_video budget in streams rather than rows: a single user publishing both camera and screenshare consumed one slot while producing two live streams, letting a channel over-admit up to 2N streams against an N-stream cap. * fix(client): 2 defect(s) (OC-0007, OC-0009) OC-0007: mark the active channel loading before invalidating its message window on a full-ready resync, so MessageList shows the spinner instead of the empty-channel state for the duration of the refetch. OC-0009: fan USER_UPDATE renames out to voiceStore.voiceUsers, which keeps its own frozen username copy, so the voice roster no longer shows a stale name for the rest of the call. * fix(admin): 1 defect(s) (OC-0010) * fix(identity): 1 defect(s) (OC-0011) * fix(ws): 1 defect(s) (OC-0003) The public half of an invisible user's presence (PresenceOthersEvent, and BroadcastPresence's own mapped payload) went out via broadcastExcludeLow on the low-priority queue - the ephemeral, unsequenced, drop-on-overflow transport built for typing indicators - while every other source of the same user's presence shares the normal-priority queue. That split one user's presence across two per-client FIFOs with different durability and different drain order (writePump drains normal strictly before low), so a frame could land out of order against a later connect/disconnect presence frame, or be silently dropped with no replay recovery. Adds Hub.BroadcastToAllExcept, which routes through the same h.broadcast channel and seqMu-serialized deliverBroadcast as BroadcastToAll, carrying an excludeUserID that deliverBroadcast applies via pubsub.Publish(TopicGlobal, msg, excludeUserID). * fix(ws): 1 defect(s) (OC-0008) --------- Co-authored-by: Claude <noreply@anthropic.com>
123 lines
4.9 KiB
SQL
123 lines
4.9 KiB
SQL
-- server_muted / server_deafened are deliberately absent from both upserts'
|
|
-- reset lists: a moderator-imposed mute must survive a channel switch, which
|
|
-- reaches the ON CONFLICT branch. It is scoped to the voice session:
|
|
-- leaving voice deletes the row, so a rejoin starts clean.
|
|
|
|
-- name: JoinVoiceChannel :exec
|
|
INSERT INTO voice_states (user_id, channel_id, muted, deafened, speaking, camera, screenshare, joined_at)
|
|
VALUES (?, ?, 0, 0, 0, 0, 0, ?)
|
|
ON CONFLICT(user_id) DO UPDATE SET
|
|
channel_id = excluded.channel_id,
|
|
muted = 0,
|
|
deafened = 0,
|
|
speaking = 0,
|
|
camera = 0,
|
|
screenshare = 0,
|
|
joined_at = excluded.joined_at;
|
|
|
|
-- name: JoinVoiceChannelIfCapacity :execresult
|
|
INSERT INTO voice_states (user_id, channel_id, muted, deafened, speaking, camera, screenshare, joined_at)
|
|
SELECT ?, ?, 0, 0, 0, 0, 0, ?
|
|
WHERE (SELECT COUNT(*) FROM voice_states AS vs2 WHERE vs2.channel_id = ?) < ?
|
|
ON CONFLICT(user_id) DO UPDATE SET
|
|
channel_id = excluded.channel_id,
|
|
muted = 0,
|
|
deafened = 0,
|
|
speaking = 0,
|
|
camera = 0,
|
|
screenshare = 0,
|
|
joined_at = excluded.joined_at;
|
|
|
|
-- name: LeaveVoiceChannel :exec
|
|
DELETE FROM voice_states WHERE user_id = ?;
|
|
|
|
-- name: LeaveVoiceChannelIfMatch :execresult
|
|
DELETE FROM voice_states WHERE user_id = ? AND channel_id = ? AND joined_at = ?;
|
|
|
|
-- name: GetUserVoiceState :one
|
|
SELECT vs.user_id, vs.channel_id, u.username,
|
|
vs.muted, vs.deafened, vs.speaking,
|
|
vs.camera, vs.screenshare,
|
|
vs.server_muted, vs.server_deafened, vs.joined_at
|
|
FROM voice_states vs
|
|
JOIN users u ON u.id = vs.user_id
|
|
WHERE vs.user_id = ?;
|
|
|
|
-- name: GetChannelVoiceStates :many
|
|
SELECT vs.user_id, vs.channel_id, u.username,
|
|
vs.muted, vs.deafened, vs.speaking,
|
|
vs.camera, vs.screenshare,
|
|
vs.server_muted, vs.server_deafened, vs.joined_at
|
|
FROM voice_states vs
|
|
JOIN users u ON u.id = vs.user_id
|
|
WHERE vs.channel_id = ?
|
|
ORDER BY vs.joined_at ASC;
|
|
|
|
-- name: GetAllVoiceStates :many
|
|
SELECT vs.user_id, vs.channel_id, u.username,
|
|
vs.muted, vs.deafened, vs.speaking,
|
|
vs.camera, vs.screenshare,
|
|
vs.server_muted, vs.server_deafened, vs.joined_at
|
|
FROM voice_states vs
|
|
JOIN users u ON u.id = vs.user_id
|
|
ORDER BY vs.channel_id, vs.joined_at ASC;
|
|
|
|
-- name: UpdateVoiceMute :exec
|
|
UPDATE voice_states SET muted = ? WHERE user_id = ?;
|
|
|
|
-- name: UpdateVoiceDeafen :exec
|
|
UPDATE voice_states SET deafened = ? WHERE user_id = ?;
|
|
|
|
-- name: UpdateVoiceCamera :exec
|
|
UPDATE voice_states SET camera = ? WHERE user_id = ?;
|
|
|
|
-- name: UpdateVoiceScreenshare :exec
|
|
UPDATE voice_states SET screenshare = ? WHERE user_id = ?;
|
|
|
|
-- Scoped to channel_id as well as user_id: the moderator's authorization is
|
|
-- checked against a channel snapshot several round trips before this write
|
|
-- lands, so an unscoped `WHERE user_id = ?` would follow the target onto
|
|
-- whatever channel their row points at by then -- including a DM call the
|
|
-- moderator was never authorized against (OC-0005). :execresult so the
|
|
-- caller can tell a real no-op (target moved) from a normal apply.
|
|
|
|
-- name: ApplyVoiceServerMute :execresult
|
|
UPDATE voice_states SET server_muted = 1, muted = 1 WHERE user_id = ? AND channel_id = ?;
|
|
|
|
-- name: ClearVoiceServerMute :execresult
|
|
UPDATE voice_states SET server_muted = 0 WHERE user_id = ? AND channel_id = ?;
|
|
|
|
-- name: ApplyVoiceServerDeafen :execresult
|
|
UPDATE voice_states SET server_deafened = 1, deafened = 1 WHERE user_id = ? AND channel_id = ?;
|
|
|
|
-- name: ClearVoiceServerDeafen :execresult
|
|
UPDATE voice_states SET server_deafened = 0 WHERE user_id = ? AND channel_id = ?;
|
|
|
|
-- Camera and screenshare share one voice_max_video budget, counted in
|
|
-- STREAMS, not rows: a channel capped at N simultaneous video streams must
|
|
-- not let a camera publish ignore screenshare occupants (or vice versa,
|
|
-- OC-0023), and a single user with both flags set must consume two of the N
|
|
-- slots, not one (OC-0006) -- so both gates sum `vs2.camera + vs2.screenshare`
|
|
-- across the channel's rows rather than counting rows where either is set.
|
|
-- The enabling user's own bit is still 0 at gate time, so no self-exclusion
|
|
-- term is needed.
|
|
|
|
-- name: EnableCameraIfUnderLimit :execresult
|
|
UPDATE voice_states SET camera = 1
|
|
WHERE voice_states.user_id = ? AND voice_states.channel_id = ?
|
|
AND (SELECT COALESCE(SUM(vs2.camera), 0) + COALESCE(SUM(vs2.screenshare), 0) FROM voice_states AS vs2 WHERE vs2.channel_id = ?) < sqlc.arg(max_video);
|
|
|
|
-- name: EnableScreenshareIfUnderLimit :execresult
|
|
UPDATE voice_states SET screenshare = 1
|
|
WHERE voice_states.user_id = ? AND voice_states.channel_id = ?
|
|
AND (SELECT COALESCE(SUM(vs2.camera), 0) + COALESCE(SUM(vs2.screenshare), 0) FROM voice_states AS vs2 WHERE vs2.channel_id = ?) < sqlc.arg(max_video);
|
|
|
|
-- name: ClearVoiceState :exec
|
|
DELETE FROM voice_states WHERE user_id = ?;
|
|
|
|
-- name: ClearAllVoiceStates :exec
|
|
DELETE FROM voice_states;
|
|
|
|
-- name: CountActiveCameras :one
|
|
SELECT COUNT(*) FROM voice_states WHERE channel_id = ? AND camera = 1;
|