Files
MineGeo/supabase/migrations/20261019044542_shared_tournament_deadline.sql
pavel444-byte 425b0e0805
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 2m20s
Test and document shared tournament deadlines
2026-10-19 10:16:23 +05:00

51 lines
2.9 KiB
PL/PgSQL

-- Every playable mini-round uses the remaining shared tournament budget.
-- The regular room engine caps its individual timer at 600 seconds; keeping
-- that deadline would cut a longer shared budget short. Reuse the persisted
-- budget so polling and transitions never extend the tournament round.
create or replace function public.tournament_room_tick(p_tournament uuid,p_room uuid) returns void
language plpgsql security invoker set search_path='' as $$
declare t public.tournaments; room public.multiplayer_rooms; budget timestamptz; first_deadline timestamptz; i integer;
begin
select * into t from public.tournaments where id=p_tournament;
if t.timer_mode='perMini' then perform public.multiplayer_tick(p_room); return; end if;
select deadline into budget from public.tournament_rounds where room_id=p_room;
if budget is null then
select deadline into first_deadline from public.multiplayer_rounds where room_id=p_room and round_number=0;
if first_deadline is not null then
budget:=first_deadline-make_interval(secs=>(t.difficulty_settings->>'seconds')::integer)+make_interval(secs=>t.round_time_seconds);
update public.tournament_rounds set deadline=budget where room_id=p_room;
end if;
end if;
if budget is not null and budget<=clock_timestamp() then
-- Finish every remaining mini round now, without results/loading delays.
for i in 0..4 loop
select * into room from public.multiplayer_rooms where id=p_room for update;
exit when room.status in('finished','closed');
if room.status='results' then
update public.multiplayer_rooms set current_round=current_round+1,status='playing',transition_at=null where id=p_room;
else update public.multiplayer_rooms set status='playing',transition_at=null where id=p_room; end if;
update public.multiplayer_rounds mr set deadline=budget where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room);
perform public.multiplayer_tick(p_room);
end loop;
return;
end if;
if budget is not null then
update public.multiplayer_rounds mr set deadline=budget
where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room) and mr.deadline is not null;
end if;
perform public.multiplayer_tick(p_room);
if budget is null then
select deadline into first_deadline from public.multiplayer_rounds where room_id=p_room and round_number=0;
if first_deadline is not null then
budget:=first_deadline-make_interval(secs=>(t.difficulty_settings->>'seconds')::integer)+make_interval(secs=>t.round_time_seconds);
update public.tournament_rounds set deadline=budget where room_id=p_room;
end if;
end if;
if budget is not null then
update public.multiplayer_rounds mr set deadline=budget
where mr.room_id=p_room and mr.round_number=(select current_round from public.multiplayer_rooms where id=p_room) and mr.deadline is not null;
end if;
end; $$;
notify pgrst,'reload schema';