docs(reference): import Dune: Awakening server-manager references
Phase 2 references for the host-agent Dune adapter, moved out of volatile /tmp
into docs/reference-repos/ (per Commander). Three upstream projects, .git +
node_modules + compiled binaries stripped (16MB source). Nested AI-instruction
files (.claude/, CLAUDE.md) removed so they don't pollute Corrosion sessions.
- icehunter/ dune-admin (Go+React) — 4 control planes; SETUP_DOCKER.md is the
closest analog to our agent's Dune docker control plane (compose
lifecycle, docker logs, RabbitMQ-via-exec, dune Postgres schema)
- adainrivers/ Rust/Tauri desktop — SSH+k8s BattleGroup control, maintenance
daemon, in-game admin console (Rust idiom reference)
- the4rchangel/ Node web UI replacing battlegroup.bat — matches the Commander's
Hyper-V self-host path + game-config schema
See docs/reference-repos/README.md for the full index + how we use each.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
-- landsraad_cast_vote(in_term_id bigint, in_player_id bigint, in_decree_name text) -> void
|
||||
-- oid: 58399 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_cast_vote(in_term_id bigint, in_player_id bigint, in_decree_name text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
term_winning_faction_id SMALLINT = NULL;
|
||||
elected_decree_id BIGINT = NULL;
|
||||
player_guild_id BIGINT = NULL;
|
||||
guild_faction_id SMALLINT = NULL;
|
||||
voting_decree_id BIGINT = NULL;
|
||||
voting_influence INTEGER = 0;
|
||||
guild_ids_json JSON = NULL;
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decree_votes IN EXCLUSIVE MODE;
|
||||
|
||||
SELECT term.winning_faction_id, term.elected_decree_id FROM landsraad_decree_term AS term WHERE term.term_id = in_term_id INTO term_winning_faction_id, elected_decree_id;
|
||||
|
||||
IF term_winning_faction_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, term % has no winning faction yet', in_term_id;
|
||||
END IF;
|
||||
|
||||
IF elected_decree_id IS NOT NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, term % already has an elected decree', in_term_id;
|
||||
END IF;
|
||||
|
||||
SELECT guilds.guild_id, guilds.guild_faction FROM guild_members
|
||||
JOIN guilds ON guild_members.guild_id = guilds.guild_id WHERE guild_members.player_id = in_player_id INTO player_guild_id, guild_faction_id;
|
||||
|
||||
IF player_guild_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, player % not in guild', in_player_id;
|
||||
END IF;
|
||||
|
||||
IF guild_faction_id != term_winning_faction_id THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, guild % not alligned to winning faction %', player_guild_id, term_winning_faction_id;
|
||||
END IF;
|
||||
|
||||
IF is_player_guild_admin(in_player_id, player_guild_id) = FALSE THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, player % is not guild admin of guild %', in_player_id, player_guild_id;
|
||||
END IF;
|
||||
|
||||
IF EXISTS (SELECT FROM landsraad_decree_votes AS votes WHERE votes.guild_id = player_guild_id) THEN
|
||||
RAISE WARNING 'Cannot insert landsraad vote, guild % has voted already', player_guild_id;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
SELECT decrees.id FROM landsraad_decree_rotation AS rotation
|
||||
INNER JOIN landsraad_decrees AS decrees ON rotation.decree_id = decrees.id
|
||||
WHERE decrees.decree_name = in_decree_name INTO voting_decree_id;
|
||||
|
||||
IF voting_decree_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad vote, decree % not for election', in_decree_name;
|
||||
END IF;
|
||||
|
||||
SELECT FLOOR(landsraad_load_guild_contribution(in_term_id, player_guild_id, term_winning_faction_id))::INTEGER INTO voting_influence;
|
||||
|
||||
IF voting_influence IS NULL THEN
|
||||
RAISE WARNING 'Cannot insert landsraad vote, guild % has no contribution', player_guild_id;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
INSERT INTO landsraad_decree_votes VALUES(voting_decree_id, player_guild_id, in_player_id, voting_influence);
|
||||
|
||||
SELECT json_agg(player_guild_id) INTO guild_ids_json;
|
||||
PERFORM pg_notify('landsraad_notify_channel', format('guild_vote_changed#{"GuildIds": %s}', guild_ids_json));
|
||||
|
||||
END $function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- landsraad_change_term_end_time(end_term_id bigint, new_end_time timestamp without time zone, in_test_term boolean) -> void
|
||||
-- oid: 58400 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_change_term_end_time(end_term_id bigint, new_end_time timestamp without time zone, in_test_term boolean)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decree_term IN EXCLUSIVE MODE;
|
||||
UPDATE landsraad_decree_term SET test_term = in_test_term WHERE term_id = end_term_id AND test_term = false;
|
||||
UPDATE landsraad_decree_term SET end_time = new_end_time AT TIME ZONE 'UTC' WHERE term_id = end_term_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,25 @@
|
||||
-- landsraad_check_task_completion() -> trigger
|
||||
-- oid: 58401 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_check_task_completion()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
task_completed BOOLEAN = FALSE;
|
||||
BEGIN
|
||||
-- if a faction reached the tasks's goal amount set the task as completed
|
||||
WITH faction_progress AS (SELECT landsraad_task_faction_contributions.task_id, SUM(landsraad_task_faction_contributions.amount) AS amount FROM landsraad_task_faction_contributions
|
||||
WHERE landsraad_task_faction_contributions.task_id = NEW.task_id AND faction_id = NEW.faction_id GROUP BY faction_id, landsraad_task_faction_contributions.task_id)
|
||||
SELECT COALESCE (faction_progress.amount, 0) >= landsraad_tasks.goal_amount
|
||||
FROM landsraad_tasks LEFT JOIN faction_progress ON landsraad_tasks.id = faction_progress.task_id
|
||||
WHERE landsraad_tasks.id = NEW.task_id
|
||||
INTO task_completed;
|
||||
|
||||
IF task_completed THEN
|
||||
UPDATE landsraad_tasks SET completed = TRUE, winning_faction_id = NEW.faction_id, completion_time = NOW() WHERE id = NEW.task_id AND completed = FALSE;
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'state_changed');
|
||||
END IF;
|
||||
|
||||
RETURN NULL;
|
||||
END $function$
|
||||
@@ -0,0 +1,32 @@
|
||||
-- landsraad_check_term_won() -> trigger
|
||||
-- oid: 58402 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_check_term_won()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
row_completed BIGINT[] = NULL;
|
||||
column_completed BIGINT[] = NULL;
|
||||
diagonal_1_completed BIGINT[] = NULL;
|
||||
diagonal_2_completed BIGINT[] = NULL;
|
||||
sysselraad_amount INTEGER = 0;
|
||||
BEGIN
|
||||
-- check for sysselrad rule (a row, a column or a diagonal completed by a faction)
|
||||
WITH board AS (SELECT task.id as task_id, task.winning_faction_id, task.board_index / 5 AS row, task.board_index % 5 AS col, task.sysselraad FROM landsraad_tasks task WHERE task.term_id = NEW.term_id)
|
||||
SELECT
|
||||
(SELECT array_agg(board.task_id) FROM board WHERE board.row = ANY(SELECT board.row FROM board WHERE board.winning_faction_id = NEW.winning_faction_id GROUP BY (board.row) HAVING COUNT(board.col) = 5)),
|
||||
(SELECT array_agg(board.task_id) FROM board WHERE board.col = ANY(SELECT board.col FROM board WHERE board.winning_faction_id = NEW.winning_faction_id GROUP BY (board.col) HAVING COUNT(board.row) = 5)),
|
||||
(SELECT CASE WHEN COUNT(board.winning_faction_id) = 5 THEN array_agg(board.task_id) END FROM ( VALUES (0, 0), (1, 1), (2, 2), (3, 3), (4, 4) ) AS t(row, col) JOIN board ON board.row = t.row AND board.col = t.col WHERE board.winning_faction_id = NEW.winning_faction_id),
|
||||
(SELECT CASE WHEN COUNT(board.winning_faction_id) = 5 THEN array_agg(board.task_id) END FROM ( VALUES (0, 4), (1, 3), (2, 2), (3, 1), (4, 0) ) AS t(row, col) JOIN board ON board.row = t.row AND board.col = t.col WHERE board.winning_faction_id = NEW.winning_faction_id),
|
||||
(SELECT COUNT(*) FROM board WHERE board.sysselraad)
|
||||
INTO row_completed, column_completed, diagonal_1_completed, diagonal_2_completed, sysselraad_amount;
|
||||
|
||||
IF sysselraad_amount = 0 AND (row_completed IS NOT NULL OR column_completed IS NOT NULL OR diagonal_1_completed IS NOT NULL OR diagonal_2_completed IS NOT NULL) THEN
|
||||
UPDATE landsraad_tasks SET sysselraad = TRUE WHERE id = ANY(row_completed || column_completed || diagonal_1_completed || diagonal_2_completed);
|
||||
UPDATE landsraad_decree_term SET winning_faction_id = NEW.winning_faction_id WHERE term_id = NEW.term_id AND winning_faction_id IS NULL;
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'state_changed');
|
||||
END IF;
|
||||
|
||||
RETURN NULL;
|
||||
END $function$
|
||||
@@ -0,0 +1,21 @@
|
||||
-- landsraad_collect_task_telemetry_for_faction(in_term_id bigint, in_faction_name text) -> TABLE(task_telemetry dune.landsraadtermtasktelemetry[])
|
||||
-- oid: 58403 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_collect_task_telemetry_for_faction(in_term_id bigint, in_faction_name text)
|
||||
RETURNS TABLE(task_telemetry dune.landsraadtermtasktelemetry[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_faction_id SMALLINT = NULL;
|
||||
BEGIN
|
||||
SELECT id FROM factions WHERE factions.name = in_faction_name INTO current_faction_id;
|
||||
|
||||
RETURN query SELECT ARRAY_AGG((in_faction_name, landsraad_tasks.house_name, task_reveal.revealed, (CASE WHEN winning_faction_id = current_faction_id THEN TRUE ELSE FALSE END), task_progress.participant_count, CAST(landsraad_tasks.board_index AS INTEGER), landsraad_tasks.completion_time)::LandsraadTermTaskTelemetry)
|
||||
FROM landsraad_tasks
|
||||
LEFT JOIN landsraad_task_reveal_state task_reveal
|
||||
ON task_reveal.task_id = landsraad_tasks.id AND task_reveal.faction_id = current_faction_id
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT COUNT(DISTINCT ltpc.player_id) AS participant_count FROM landsraad_task_player_contributions ltpc WHERE ltpc.task_id = landsraad_tasks.id and ltpc.faction_id = current_faction_id GROUP BY task_id
|
||||
) AS task_progress ON true
|
||||
WHERE landsraad_tasks.term_id = in_term_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,20 @@
|
||||
-- landsraad_collect_term_telemetry(in_term_id bigint, in_faction_names text[]) -> TABLE(term_telemetry dune.landsraadtermtelemetry[], task_telemetry dune.landsraadtermtasktelemetry[])
|
||||
-- oid: 58404 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_collect_term_telemetry(in_term_id bigint, in_faction_names text[])
|
||||
RETURNS TABLE(term_telemetry dune.landsraadtermtelemetry[], task_telemetry dune.landsraadtermtasktelemetry[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
faction_name TEXT = NULL;
|
||||
term_telemetry LandsraadTermTelemetry[];
|
||||
task_telemetry LandsraadTermTaskTelemetry[];
|
||||
BEGIN
|
||||
FOREACH faction_name IN ARRAY in_faction_names
|
||||
LOOP
|
||||
term_telemetry = ARRAY_APPEND(term_telemetry, landsraad_collect_term_telemetry_for_faction(in_term_id, faction_name));
|
||||
task_telemetry = ARRAY_CAT(task_telemetry, landsraad_collect_task_telemetry_for_faction(in_term_id, faction_name));
|
||||
END LOOP;
|
||||
|
||||
RETURN query SELECT term_telemetry, task_telemetry;
|
||||
END $function$
|
||||
@@ -0,0 +1,54 @@
|
||||
-- landsraad_collect_term_telemetry_for_faction(in_term_id bigint, in_faction_name text) -> dune.landsraadtermtelemetry
|
||||
-- oid: 58405 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_collect_term_telemetry_for_faction(in_term_id bigint, in_faction_name text)
|
||||
RETURNS dune.landsraadtermtelemetry
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_faction_id SMALLINT = NULL;
|
||||
winning_faction_id SMALLINT = NULL;
|
||||
start_time TIMESTAMPTZ = NULL;
|
||||
end_time TIMESTAMPTZ = NULL;
|
||||
sysselraad_count INTEGER = NULL;
|
||||
term_result TEXT = NULL;
|
||||
faction_won BOOLEAN = FALSE;
|
||||
participants_num_faction INTEGER = NULL;
|
||||
tasks_completed INTEGER = NULL;
|
||||
tasks_revealed INTEGER = NULL;
|
||||
BEGIN
|
||||
SELECT id FROM factions WHERE factions.name = in_faction_name INTO current_faction_id;
|
||||
|
||||
SELECT term.winning_faction_id, term.start_time, term.end_time FROM landsraad_decree_term AS term WHERE term_id = in_term_id INTO winning_faction_id, start_time, end_time;
|
||||
|
||||
IF winning_faction_id IS NULL THEN
|
||||
term_result = 'TIE';
|
||||
ELSE
|
||||
SELECT COUNT(id) FROM landsraad_tasks WHERE term_id = in_term_id AND sysselraad = true INTO sysselraad_count;
|
||||
IF sysselraad_count = 5 THEN
|
||||
term_result = 'SYSSELRAAD';
|
||||
ELSE
|
||||
term_result = 'TASK_COUNT';
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF winning_faction_id = current_faction_id THEN
|
||||
faction_won = true;
|
||||
END IF;
|
||||
|
||||
SELECT COUNT(DISTINCT player_id) FROM landsraad_task_player_contributions LEFT JOIN landsraad_tasks ON
|
||||
landsraad_task_player_contributions.task_id = landsraad_tasks.id
|
||||
WHERE landsraad_tasks.term_id = in_term_id AND landsraad_task_player_contributions.faction_id = current_faction_id
|
||||
INTO participants_num_faction;
|
||||
|
||||
SELECT COUNT(id) FROM landsraad_tasks WHERE landsraad_tasks.term_id = in_term_id
|
||||
AND landsraad_tasks.winning_faction_id = current_faction_id AND landsraad_tasks.completed = true
|
||||
INTO tasks_completed;
|
||||
|
||||
SELECT COUNT(DISTINCT landsraad_tasks.id) FROM landsraad_task_reveal_state LEFT JOIN landsraad_tasks ON
|
||||
landsraad_task_reveal_state.task_id = landsraad_tasks.id
|
||||
WHERE landsraad_tasks.term_id = in_term_id AND landsraad_task_reveal_state.faction_id = current_faction_id AND landsraad_task_reveal_state.revealed = true
|
||||
INTO tasks_revealed;
|
||||
|
||||
RETURN (in_faction_name, term_result, faction_won, participants_num_faction, tasks_completed, tasks_revealed, start_time, end_time)::LandsraadTermTelemetry;
|
||||
END $function$
|
||||
@@ -0,0 +1,18 @@
|
||||
-- landsraad_collect_vote_telemetry(in_term_id bigint, in_winning_faction_id integer) -> TABLE(guild_id bigint, decree_name text, voting_influence integer)
|
||||
-- oid: 58406 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_collect_vote_telemetry(in_term_id bigint, in_winning_faction_id integer)
|
||||
RETURNS TABLE(guild_id bigint, decree_name text, voting_influence integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query SELECT guild_contribution.guild_id, landsraad_decrees.decree_name, FLOOR(SUM(guild_contribution.amount))::INTEGER
|
||||
FROM landsraad_tasks AS tasks
|
||||
INNER JOIN landsraad_task_guild_contributions AS guild_contribution
|
||||
ON guild_contribution.task_id = tasks.id AND guild_contribution.faction_id = tasks.winning_faction_id AND tasks.term_id = in_term_id AND guild_contribution.faction_id = in_winning_faction_id
|
||||
LEFT JOIN landsraad_decree_votes
|
||||
ON landsraad_decree_votes.guild_id = guild_contribution.guild_id
|
||||
LEFT JOIN landsraad_decrees
|
||||
ON landsraad_decree_votes.decree_id = landsraad_decrees.id
|
||||
GROUP BY (guild_contribution.guild_id, landsraad_decrees.decree_name);
|
||||
END $function$
|
||||
@@ -0,0 +1,56 @@
|
||||
-- landsraad_collect_votes(in_term_id bigint) -> TABLE(elected_decree text, winning_faction_name text, available_decrees text[], guild_votes dune.landsraadguildvotetelemetry[])
|
||||
-- oid: 58407 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_collect_votes(in_term_id bigint)
|
||||
RETURNS TABLE(elected_decree text, winning_faction_name text, available_decrees text[], guild_votes dune.landsraadguildvotetelemetry[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
has_elected_decree BOOL = FALSE;
|
||||
has_winning_faction BOOL = FALSE;
|
||||
winning_decree_id BIGINT = NULL;
|
||||
winning_decree_name TEXT = NULL;
|
||||
winning_faction_name TEXT = NULL;
|
||||
winning_faction_id INT = NULL;
|
||||
available_decrees TEXT[];
|
||||
vote_telemetry LandsraadGuildVoteTelemetry[];
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decree_term, landsraad_decree_rotation, landsraad_decree_votes IN EXCLUSIVE MODE;
|
||||
|
||||
SELECT CASE WHEN landsraad_decree_term.elected_decree_id IS NULL THEN FALSE ELSE TRUE END,
|
||||
CASE WHEN landsraad_decree_term.winning_faction_id IS NULL THEN FALSE ELSE TRUE END
|
||||
FROM landsraad_decree_term WHERE term_id = in_term_id INTO has_elected_decree, has_winning_faction;
|
||||
|
||||
IF has_winning_faction IS FALSE THEN
|
||||
RETURN query SELECT NULL, NULL, available_decrees, vote_telemetry;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
SELECT factions.name, term.winning_faction_id FROM landsraad_decree_term AS term LEFT JOIN factions ON term.winning_faction_id = factions.id WHERE term.term_id = in_term_id INTO winning_faction_name, winning_faction_id;
|
||||
|
||||
SELECT ARRAY_AGG(landsraad_decrees.decree_name) FROM landsraad_decree_rotation INNER JOIN landsraad_decrees ON landsraad_decree_rotation.decree_id = landsraad_decrees.id INTO available_decrees;
|
||||
|
||||
SELECT ARRAY_AGG((guild_id, decree_name, voting_influence)::LandsraadGuildVoteTelemetry) FROM landsraad_collect_vote_telemetry(in_term_id, winning_faction_id) INTO vote_telemetry;
|
||||
|
||||
-- Only resolve votes if the latest term has no elected decree
|
||||
IF has_elected_decree IS FALSE THEN
|
||||
WITH
|
||||
votes AS (SELECT decree_id, SUM(influence) AS amount FROM landsraad_decree_votes GROUP BY decree_id),
|
||||
max_votes AS (SELECT MAX(amount) AS amount FROM votes)
|
||||
UPDATE landsraad_decree_term
|
||||
SET elected_decree_id =
|
||||
CASE WHEN (SELECT amount FROM max_votes) IS NOT NULL THEN
|
||||
(SELECT decree_id FROM votes WHERE amount = (SELECT amount FROM max_votes) ORDER BY RANDOM() LIMIT 1)
|
||||
ELSE
|
||||
(SELECT decree_id FROM landsraad_decree_rotation ORDER BY RANDOM() LIMIT 1)
|
||||
END
|
||||
WHERE term_id = in_term_id
|
||||
returning elected_decree_id INTO winning_decree_id;
|
||||
ELSE
|
||||
SELECT term.elected_decree_id FROM landsraad_decree_term term ORDER BY term_id DESC LIMIT 1 INTO winning_decree_id;
|
||||
END IF;
|
||||
|
||||
SELECT decree_name FROM landsraad_decrees WHERE id = winning_decree_id INTO winning_decree_name;
|
||||
|
||||
RETURN query SELECT winning_decree_name, winning_faction_name, available_decrees, vote_telemetry;
|
||||
END $function$
|
||||
@@ -0,0 +1,26 @@
|
||||
-- landsraad_determine_winner(in_term_id bigint) -> text
|
||||
-- oid: 58408 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_determine_winner(in_term_id bigint)
|
||||
RETURNS text
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
has_winning_faction BOOLEAN = FALSE;
|
||||
winning_faction_name TEXT = NULL;
|
||||
BEGIN
|
||||
SELECT CASE WHEN winning_faction_id IS NULL THEN FALSE ELSE TRUE END FROM landsraad_decree_term WHERE term_id = in_term_id INTO has_winning_faction;
|
||||
|
||||
-- only set winning faction if not set already (sysselraad has been secured)
|
||||
IF NOT has_winning_faction THEN
|
||||
WITH tasks_completed_by_faction AS (SELECT winning_faction_id AS faction, COUNT(id) AS num_tasks FROM landsraad_tasks WHERE term_id = in_term_id AND winning_faction_id IS NOT NULL GROUP BY (winning_faction_id)),
|
||||
winner_count AS (SELECT COUNT(faction) AS amount FROM tasks_completed_by_faction WHERE num_tasks = (SELECT MAX(num_tasks) FROM tasks_completed_by_faction) GROUP BY(num_tasks)),
|
||||
winner AS (SELECT faction FROM tasks_completed_by_faction ORDER BY num_tasks DESC LIMIT 1)
|
||||
UPDATE landsraad_decree_term SET winning_faction_id = CASE WHEN winner_count.amount = 1 THEN winner.faction ELSE NULL END FROM winner, winner_count;
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'state_changed');
|
||||
END IF;
|
||||
|
||||
SELECT factions.name FROM landsraad_decree_term AS term LEFT JOIN factions ON term.winning_faction_id = factions.id WHERE term.term_id = in_term_id INTO winning_faction_name;
|
||||
|
||||
RETURN winning_faction_name;
|
||||
END $function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- landsraad_force_end_term(end_term_id bigint) -> void
|
||||
-- oid: 58409 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_force_end_term(end_term_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
PERFORM landsraad_change_term_end_time(end_term_id, now() AT TIME ZONE 'UTC', false);
|
||||
END $function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- landsraad_has_term_of_task_ended(in_task_id bigint) -> boolean
|
||||
-- oid: 58410 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_has_term_of_task_ended(in_task_id bigint)
|
||||
RETURNS boolean
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
term_ended BOOLEAN = FALSE;
|
||||
BEGIN
|
||||
SELECT NOW() > term.end_time FROM landsraad_tasks AS task LEFT JOIN landsraad_decree_term AS term ON task.term_id = term.term_id WHERE task.id = in_task_id INTO term_ended;
|
||||
RETURN term_ended;
|
||||
END $function$
|
||||
@@ -0,0 +1,30 @@
|
||||
-- landsraad_initialize_system(number_of_weeks_term_retention integer, number_of_nominated_decrees integer, in_end_time timestamp without time zone, in_test_term boolean, faction_names text[], decrees dune.landsraaddecree[], tasks dune.landsraadtask[], task_rewards dune.landsraadtaskreward[]) -> TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone)
|
||||
-- oid: 58411 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_initialize_system(number_of_weeks_term_retention integer, number_of_nominated_decrees integer, in_end_time timestamp without time zone, in_test_term boolean, faction_names text[], decrees dune.landsraaddecree[], tasks dune.landsraadtask[], task_rewards dune.landsraadtaskreward[])
|
||||
RETURNS TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_term_id BIGINT = NULL;
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decree_term, landsraad_decree_rotation, landsraad_decrees, landsraad_decree_votes IN EXCLUSIVE MODE;
|
||||
|
||||
CALL landsraad_update_decrees(decrees);
|
||||
|
||||
CALL landsraad_update_factions(faction_names);
|
||||
|
||||
SELECT term.term_id FROM landsraad_decree_term term ORDER BY term.term_id DESC LIMIT 1 INTO current_term_id;
|
||||
IF FOUND THEN
|
||||
RETURN query SELECT term.term_id, reigning_faction.name, active_decree.decree_name, winning_faction.name, elected_decree.decree_name, (term.start_time AT TIME ZONE 'UTC')::TIMESTAMP, (term.end_time AT TIME ZONE 'UTC')::TIMESTAMP
|
||||
FROM landsraad_decree_term term
|
||||
LEFT JOIN factions reigning_faction ON term.reigning_faction_id = reigning_faction.id
|
||||
LEFT JOIN landsraad_decrees active_decree ON term.active_decree_id = active_decree.id
|
||||
LEFT JOIN factions winning_faction ON term.winning_faction_id = winning_faction.id
|
||||
LEFT JOIN landsraad_decrees elected_decree ON term.elected_decree_id = elected_decree.id
|
||||
WHERE term.term_id = current_term_id;
|
||||
ELSE
|
||||
RETURN query SELECT term.term_id, term.reigning_faction_name, term.active_decree_name, term.winning_faction_name, term.elected_decree_name, term.start_time, term.end_time
|
||||
FROM landsraad_initialize_term(number_of_weeks_term_retention, number_of_nominated_decrees, in_end_time, in_test_term, tasks, task_rewards) AS term;
|
||||
END IF;
|
||||
END $function$
|
||||
@@ -0,0 +1,41 @@
|
||||
-- landsraad_initialize_term(number_of_weeks_term_retention integer, number_of_nominated_decrees integer, in_end_time timestamp without time zone, in_test_term boolean, tasks dune.landsraadtask[], task_rewards dune.landsraadtaskreward[]) -> TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone)
|
||||
-- oid: 58412 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_initialize_term(number_of_weeks_term_retention integer, number_of_nominated_decrees integer, in_end_time timestamp without time zone, in_test_term boolean, tasks dune.landsraadtask[], task_rewards dune.landsraadtaskreward[])
|
||||
RETURNS TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
reigning_faction_id SMALLINT = NULL;
|
||||
active_decree_id BIGINT = NULL;
|
||||
last_active_decree_id BIGINT = NULL;
|
||||
current_term_id BIGINT = NULL;
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decrees, landsraad_decree_term, landsraad_decree_rotation, landsraad_decree_votes IN EXCLUSIVE MODE;
|
||||
|
||||
-- read winning faction, elected and active decree from previous term
|
||||
SELECT term.winning_faction_id, term.elected_decree_id, term.active_decree_id INTO reigning_faction_id, active_decree_id, last_active_decree_id FROM landsraad_decree_term term ORDER BY term.term_id DESC LIMIT 1;
|
||||
|
||||
-- insert new term
|
||||
INSERT INTO landsraad_decree_term (reigning_faction_id, active_decree_id, start_time, end_time, test_term) VALUES(reigning_faction_id, active_decree_id, now(), in_end_time AT TIME ZONE 'UTC', in_test_term) RETURNING landsraad_decree_term.term_id INTO current_term_id;
|
||||
|
||||
-- cleanup old terms, except for previous one
|
||||
DELETE FROM landsraad_decree_term term WHERE term.end_time < (now() - MAKE_INTERVAL(weeks => number_of_weeks_term_retention)) AND term.term_id < current_term_id - 1;
|
||||
|
||||
-- insert tasks for new term
|
||||
CALL landsraad_insert_tasks(current_term_id, tasks, task_rewards);
|
||||
|
||||
-- insert decrees for voting
|
||||
CALL landsraad_nominate_decrees_for_voting(last_active_decree_id, number_of_nominated_decrees);
|
||||
|
||||
-- clean expired landsraad contracts
|
||||
PERFORM journey_story_node_cooldown_delete_expired(now() at time zone 'utc');
|
||||
|
||||
RETURN query SELECT term.term_id, reigning_faction.name, active_decree.decree_name, winning_faction.name, elected_decree.decree_name, (term.start_time AT TIME ZONE 'UTC')::TIMESTAMP, (term.end_time AT TIME ZONE 'UTC')::TIMESTAMP
|
||||
FROM landsraad_decree_term term
|
||||
LEFT JOIN factions reigning_faction ON term.reigning_faction_id = reigning_faction.id
|
||||
LEFT JOIN landsraad_decrees active_decree ON term.active_decree_id = active_decree.id
|
||||
LEFT JOIN factions winning_faction ON term.winning_faction_id = winning_faction.id
|
||||
LEFT JOIN landsraad_decrees elected_decree ON term.elected_decree_id = elected_decree.id
|
||||
WHERE term.term_id = current_term_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,49 @@
|
||||
-- landsraad_insert_task_progress(in_term_id bigint, in_player_id bigint, in_guild_id bigint, in_house_name text, in_faction_progress integer, in_guild_progress real, in_player_progress real, in_timestamp timestamp without time zone) -> void
|
||||
-- oid: 58413 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_insert_task_progress(in_term_id bigint, in_player_id bigint, in_guild_id bigint, in_house_name text, in_faction_progress integer, in_guild_progress real, in_player_progress real, in_timestamp timestamp without time zone)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
guild_id BIGINT = NULL;
|
||||
faction_id BIGINT = NULL;
|
||||
faction_name TEXT = NULL;
|
||||
progress_id BIGINT = NULL;
|
||||
BEGIN
|
||||
|
||||
IF in_player_id IS NULL THEN
|
||||
-- use guild_id
|
||||
SELECT guilds.guild_id, factions.id, factions.name FROM guild_members
|
||||
INNER JOIN guilds ON guild_members.guild_id = guilds.guild_id
|
||||
LEFT JOIN factions ON guilds.guild_faction = factions.id
|
||||
WHERE guild_members.guild_id = in_guild_id INTO guild_id, faction_id, faction_name;
|
||||
ELSE
|
||||
-- use player_id
|
||||
SELECT guilds.guild_id, factions.id, factions.name FROM guild_members
|
||||
INNER JOIN guilds ON guild_members.guild_id = guilds.guild_id
|
||||
LEFT JOIN factions ON guilds.guild_faction = factions.id
|
||||
WHERE guild_members.player_id = in_player_id INTO guild_id, faction_id, faction_name;
|
||||
END IF;
|
||||
|
||||
IF guild_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad task progress, player % not in guild', in_player_id;
|
||||
END IF;
|
||||
|
||||
IF faction_id IS NULL OR faction_name = 'None' THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad task progress, guild % not aligned to faction', guild_id;
|
||||
END IF;
|
||||
|
||||
INSERT INTO landsraad_task_progress (faction_id, task_id, faction_progress, guild_progress, player_progress, timestamp)
|
||||
SELECT faction_id, tasks.id, in_faction_progress, in_guild_progress, in_player_progress, in_timestamp AT TIME ZONE 'UTC'
|
||||
FROM landsraad_tasks AS tasks
|
||||
WHERE tasks.term_id = in_term_id AND tasks.house_name = in_house_name
|
||||
RETURNING id INTO progress_id;
|
||||
|
||||
IF in_player_id IS NOT NULL THEN
|
||||
INSERT INTO landsraad_task_progress_player (progress_id, player_id) VALUES (progress_id, in_player_id);
|
||||
END IF;
|
||||
|
||||
INSERT INTO landsraad_task_progress_guild (progress_id, guild_id) VALUES (progress_id, guild_id);
|
||||
|
||||
END $function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- landsraad_insert_task_progress_batched(in_term_id bigint, in_task_progress dune.landsraadtaskprogress[]) -> void
|
||||
-- oid: 58414 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_insert_task_progress_batched(in_term_id bigint, in_task_progress dune.landsraadtaskprogress[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
task_progress record = NULL;
|
||||
BEGIN
|
||||
FOREACH task_progress IN ARRAY in_task_progress
|
||||
LOOP
|
||||
PERFORM landsraad_insert_task_progress(in_term_id, task_progress.player_id, task_progress.guild_id ,task_progress.house_name, task_progress.faction_progress, task_progress.guild_progress, task_progress.player_progress, task_progress.timestamp);
|
||||
END LOOP;
|
||||
END $function$
|
||||
@@ -0,0 +1,23 @@
|
||||
-- landsraad_insert_task_progress_faction(in_term_id bigint, in_faction_name text, in_house_name text, in_faction_progress integer, in_guild_progress real, in_player_progress real) -> void
|
||||
-- oid: 58415 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_insert_task_progress_faction(in_term_id bigint, in_faction_name text, in_house_name text, in_faction_progress integer, in_guild_progress real, in_player_progress real)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
player_id BIGINT = NULL;
|
||||
guild_id BIGINT = NULL;
|
||||
BEGIN
|
||||
SELECT guild_members.player_id, guilds.guild_id FROM guilds
|
||||
LEFT JOIN factions ON guilds.guild_faction = factions.id
|
||||
RIGHT JOIN guild_members ON guild_members.guild_id = guilds.guild_id
|
||||
WHERE factions.name = in_faction_name
|
||||
ORDER BY random() LIMIT 1 INTO player_id, guild_id;
|
||||
|
||||
IF player_id IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot insert landsraad task progress for faction %, no guild member found', in_faction_name;
|
||||
END IF;
|
||||
|
||||
PERFORM landsraad_insert_task_progress(in_term_id, player_id, guild_id, in_house_name, in_faction_progress, in_guild_progress, in_player_progress, now() AT TIME ZONE 'UTC');
|
||||
END $function$
|
||||
@@ -0,0 +1,29 @@
|
||||
-- landsraad_insert_task_progress_random(in_term_id bigint, in_faction_names text[], in_num_rows integer) -> void
|
||||
-- oid: 58416 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_insert_task_progress_random(in_term_id bigint, in_faction_names text[], in_num_rows integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
player_id BIGINT = NULL;
|
||||
guild_id BIGINT = NULL;
|
||||
house_name TEXT = NULL;
|
||||
random_amount INTEGER = NULL;
|
||||
BEGIN
|
||||
FOR r IN 1..in_num_rows
|
||||
LOOP
|
||||
SELECT guild_members.player_id, guilds.guild_id FROM guilds
|
||||
LEFT JOIN factions ON guilds.guild_faction = factions.id
|
||||
RIGHT JOIN guild_members ON guild_members.guild_id = guilds.guild_id
|
||||
WHERE factions.name = ANY(in_faction_names)
|
||||
ORDER BY random() LIMIT 1 INTO player_id, guild_id;
|
||||
SELECT tasks.house_name FROM landsraad_tasks tasks
|
||||
WHERE tasks.term_id = in_term_id
|
||||
ORDER BY random() LIMIT 1 INTO house_name;
|
||||
SELECT (floor(random() * 5) + 1)::INTEGER * 10 INTO random_amount;
|
||||
IF player_id IS NOT NULL AND house_name IS NOT NULL THEN
|
||||
PERFORM landsraad_insert_task_progress(in_term_id, player_id, guild_id, house_name, random_amount * 10, (random_amount * 0.1)::REAL, (random_amount * 10)::REAL, now() AT TIME ZONE 'UTC');
|
||||
END IF;
|
||||
END LOOP;
|
||||
END $function$
|
||||
@@ -0,0 +1,31 @@
|
||||
-- landsraad_load_current_rotation(in_term_id bigint) -> TABLE(decree_name text, received_votes integer, open_votes integer)
|
||||
-- oid: 58418 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_current_rotation(in_term_id bigint)
|
||||
RETURNS TABLE(decree_name text, received_votes integer, open_votes integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
open_votes INTEGER = 0;
|
||||
BEGIN
|
||||
WITH open_guild_votes AS (
|
||||
SELECT guild_contribution.guild_id, FLOOR(SUM(guild_contribution.amount))::INTEGER AS voting_influence
|
||||
FROM landsraad_tasks AS tasks
|
||||
INNER JOIN landsraad_task_guild_contributions AS guild_contribution
|
||||
ON guild_contribution.task_id = tasks.id AND guild_contribution.faction_id = tasks.winning_faction_id
|
||||
LEFT JOIN landsraad_decree_votes
|
||||
ON guild_contribution.guild_id = landsraad_decree_votes.guild_id
|
||||
WHERE tasks.term_id = in_term_id AND tasks.winning_faction_id = (SELECT winning_faction_id FROM landsraad_decree_term WHERE term_id = in_term_id)
|
||||
AND landsraad_decree_votes.guild_id IS NULL
|
||||
GROUP BY (guild_contribution.guild_id, guild_contribution.faction_id)
|
||||
)
|
||||
SELECT SUM(voting_influence)::INTEGER FROM open_guild_votes INTO open_votes;
|
||||
|
||||
RETURN query (
|
||||
SELECT decrees.decree_name, SUM(decree_votes.influence)::INTEGER AS received_votes, open_votes
|
||||
FROM landsraad_decree_rotation AS rotation
|
||||
INNER JOIN landsraad_decrees AS decrees ON rotation.decree_id = decrees.id
|
||||
LEFT JOIN landsraad_decree_votes AS decree_votes ON decree_votes.decree_id = rotation.decree_id
|
||||
GROUP BY rotation.decree_id, decrees.decree_name
|
||||
);
|
||||
END $function$
|
||||
@@ -0,0 +1,55 @@
|
||||
-- landsraad_load_current_term() -> TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone, tasks dune.landsraadtask[], term_task_rewards dune.landsraadtaskreward[], winner_history text[], testterm boolean)
|
||||
-- oid: 58419 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_current_term()
|
||||
RETURNS TABLE(term_id bigint, reigning_faction_name text, active_decree_name text, winning_faction_name text, elected_decree_name text, start_time timestamp without time zone, end_time timestamp without time zone, tasks dune.landsraadtask[], term_task_rewards dune.landsraadtaskreward[], winner_history text[], testterm boolean)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_term_id BIGINT = NULL;
|
||||
reigning_faction_name TEXT = NULL;
|
||||
active_decree_name TEXT = NULL;
|
||||
winning_faction_name TEXT = NULL;
|
||||
elected_decree_name TEXT = NULL;
|
||||
start_time TIMESTAMP = NULL;
|
||||
end_time TIMESTAMP = NULL;
|
||||
test_term BOOL = NULL;
|
||||
term_tasks LandsraadTask[];
|
||||
term_task_rewards LandsraadTaskReward[];
|
||||
term_winner_history TEXT[];
|
||||
BEGIN
|
||||
SELECT term.term_id, reigning_faction.name, active_decree.decree_name, winning_faction.name, elected_decree.decree_name, (term.start_time AT TIME ZONE 'UTC')::TIMESTAMP, (term.end_time AT TIME ZONE 'UTC')::TIMESTAMP, term.test_term
|
||||
INTO current_term_id, reigning_faction_name, active_decree_name, winning_faction_name, elected_decree_name, start_time, end_time, test_term
|
||||
FROM landsraad_decree_term AS term
|
||||
LEFT JOIN factions AS reigning_faction ON term.reigning_faction_id = reigning_faction.id
|
||||
LEFT JOIN landsraad_decrees AS active_decree ON term.active_decree_id = active_decree.id
|
||||
LEFT JOIN factions AS winning_faction ON term.winning_faction_id = winning_faction.id
|
||||
LEFT JOIN landsraad_decrees AS elected_decree ON term.elected_decree_id = elected_decree.id
|
||||
ORDER BY term.start_time DESC LIMIT 1;
|
||||
|
||||
SELECT ARRAY_AGG((tasks.board_index, tasks.house_name, tasks.completed, COALESCE(factions_winner.name, ''), tasks.sysselraad, tasks.goal_amount)::LandsraadTask)
|
||||
INTO term_tasks
|
||||
FROM landsraad_tasks AS tasks
|
||||
LEFT JOIN factions AS factions_winner ON tasks.winning_faction_id = factions_winner.id
|
||||
WHERE tasks.term_id = current_term_id;
|
||||
|
||||
WITH task_rewards AS (
|
||||
SELECT tasks.house_name AS house_name, rewards.threshold AS threshold, rewards.template_id AS template_id, rewards.amount AS amount
|
||||
FROM landsraad_task_rewards AS rewards
|
||||
LEFT JOIN landsraad_tasks AS tasks ON rewards.task_id = tasks.id
|
||||
WHERE tasks.term_id = current_term_id ORDER BY rewards.task_id ASC, rewards.threshold ASC
|
||||
)
|
||||
SELECT ARRAY_AGG((house_name, threshold, template_id, amount)::LandsraadTaskReward) FROM task_rewards INTO term_task_rewards;
|
||||
|
||||
SELECT ARRAY_AGG(winning_factions.name::TEXT)
|
||||
INTO term_winner_history
|
||||
FROM
|
||||
(SELECT factions.name
|
||||
FROM landsraad_decree_term
|
||||
LEFT JOIN factions ON landsraad_decree_term.reigning_faction_id = factions.id
|
||||
ORDER BY landsraad_decree_term.term_id DESC) AS winning_factions;
|
||||
|
||||
IF current_term_id IS NOT NULL THEN
|
||||
RETURN query SELECT current_term_id, reigning_faction_name, active_decree_name, winning_faction_name, elected_decree_name, start_time, end_time, term_tasks, term_task_rewards, term_winner_history, test_term;
|
||||
END IF;
|
||||
END $function$
|
||||
@@ -0,0 +1,17 @@
|
||||
-- landsraad_load_guild_contribution(in_term_id bigint, in_guild_id bigint, in_faction_id bigint) -> TABLE(voting_influence real)
|
||||
-- oid: 58420 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_guild_contribution(in_term_id bigint, in_guild_id bigint, in_faction_id bigint)
|
||||
RETURNS TABLE(voting_influence real)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query (
|
||||
SELECT SUM(guild_contribution.amount)::REAL
|
||||
FROM landsraad_tasks AS tasks
|
||||
INNER JOIN landsraad_task_guild_contributions AS guild_contribution
|
||||
ON guild_contribution.task_id = tasks.id
|
||||
WHERE tasks.term_id = in_term_id AND guild_contribution.guild_id = in_guild_id AND guild_contribution.faction_id = in_faction_id
|
||||
GROUP BY (guild_contribution.guild_id, guild_contribution.faction_id)
|
||||
);
|
||||
END $function$
|
||||
@@ -0,0 +1,24 @@
|
||||
-- landsraad_load_guild_contributions(in_term_id bigint, in_num_guilds integer, in_faction_names text[]) -> TABLE(faction_name text, guild_name text, voting_influence real)
|
||||
-- oid: 58421 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_guild_contributions(in_term_id bigint, in_num_guilds integer, in_faction_names text[])
|
||||
RETURNS TABLE(faction_name text, guild_name text, voting_influence real)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query (
|
||||
SELECT factions.name, top_guilds.guild_name, top_guilds.influence FROM factions
|
||||
CROSS JOIN LATERAL (
|
||||
SELECT guilds.guild_name as guild_name, SUM(guild_contribution.amount)::REAL AS influence
|
||||
FROM landsraad_tasks AS tasks
|
||||
INNER JOIN landsraad_task_guild_contributions AS guild_contribution
|
||||
ON guild_contribution.task_id = tasks.id AND guild_contribution.faction_id = factions.id
|
||||
JOIN guilds
|
||||
ON guild_contribution.guild_id = guilds.guild_id
|
||||
WHERE tasks.term_id = in_term_id
|
||||
GROUP BY (guilds.guild_id, guilds.guild_name)
|
||||
ORDER BY influence DESC LIMIT in_num_guilds
|
||||
) AS top_guilds
|
||||
WHERE factions.name = ANY(in_faction_names)
|
||||
);
|
||||
END $function$
|
||||
@@ -0,0 +1,28 @@
|
||||
-- landsraad_load_guild_vote(in_term_id bigint, in_player_id bigint) -> TABLE(decree_name text, voting_influence real)
|
||||
-- oid: 58422 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_guild_vote(in_term_id bigint, in_player_id bigint)
|
||||
RETURNS TABLE(decree_name text, voting_influence real)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
term_winning_faction_id SMALLINT = NULL;
|
||||
player_guild_id BIGINT = NULL;
|
||||
guild_faction_id SMALLINT = NULL;
|
||||
BEGIN
|
||||
SELECT guilds.guild_id, guilds.guild_faction FROM guild_members JOIN guilds ON guild_members.guild_id = guilds.guild_id WHERE guild_members.player_id = in_player_id INTO player_guild_id, guild_faction_id;
|
||||
|
||||
RETURN query (
|
||||
SELECT
|
||||
CASE WHEN player_guild_id IS NOT NULL AND guild_faction_id IS NOT NULL THEN
|
||||
(SELECT COALESCE(decrees.decree_name, '') FROM landsraad_decree_votes AS votes LEFT JOIN landsraad_decrees AS decrees ON votes.decree_id = decrees.id WHERE votes.guild_id = player_guild_id)
|
||||
ELSE
|
||||
''
|
||||
END,
|
||||
CASE WHEN player_guild_id IS NOT NULL AND guild_faction_id IS NOT NULL THEN
|
||||
(SELECT landsraad_load_guild_contribution(in_term_id, player_guild_id, guild_faction_id))
|
||||
ELSE
|
||||
0
|
||||
END
|
||||
);
|
||||
END $function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- landsraad_load_house_rewards(in_player_id bigint) -> TABLE(house_name text, template_id text, amount integer, last_updated timestamp without time zone)
|
||||
-- oid: 58423 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_house_rewards(in_player_id bigint)
|
||||
RETURNS TABLE(house_name text, template_id text, amount integer, last_updated timestamp without time zone)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query (SELECT rewards.house_name, rewards.template_id, rewards.amount, (rewards.last_updated AT TIME ZONE 'UTC')::TIMESTAMP FROM landsraad_house_rewards AS rewards WHERE player_id = in_player_id AND rewards.amount > 0);
|
||||
END $function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- landsraad_load_player_contributions(in_term_id bigint, in_player_ids bigint[]) -> TABLE(player_id bigint, board_index smallint, amount integer)
|
||||
-- oid: 58424 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_player_contributions(in_term_id bigint, in_player_ids bigint[])
|
||||
RETURNS TABLE(player_id bigint, board_index smallint, amount integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query (
|
||||
SELECT contributions.player_id, tasks.board_index, FLOOR(SUM(contributions.amount))::INTEGER FROM landsraad_task_player_contributions AS contributions
|
||||
INNER JOIN landsraad_tasks AS tasks ON contributions.task_id = tasks.id
|
||||
WHERE tasks.term_id = in_term_id AND contributions.player_id = ANY(in_player_ids)
|
||||
GROUP BY contributions.player_id, tasks.board_index
|
||||
);
|
||||
END $function$
|
||||
@@ -0,0 +1,18 @@
|
||||
-- landsraad_load_task_faction_progress(in_term_id bigint) -> TABLE(task_board_index integer, faction_name text, progress integer)
|
||||
-- oid: 58425 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_task_faction_progress(in_term_id bigint)
|
||||
RETURNS TABLE(task_board_index integer, faction_name text, progress integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query SELECT CAST(faction_progress.board_index AS INTEGER), faction_progress.name, CAST(faction_progress.progress AS INTEGER) FROM
|
||||
(SELECT tasks.id, tasks.board_index, factions.name, SUM(faction_contribution.amount) AS progress
|
||||
FROM landsraad_tasks tasks
|
||||
INNER JOIN landsraad_task_faction_contributions faction_contribution
|
||||
ON faction_contribution.task_id = tasks.id
|
||||
LEFT JOIN factions factions
|
||||
ON factions.id = faction_contribution.faction_id
|
||||
WHERE tasks.term_id = in_term_id
|
||||
GROUP BY (tasks.id, tasks.board_index, factions.name)) AS faction_progress;
|
||||
END $function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- landsraad_load_task_faction_reveal_state(in_term_id bigint) -> TABLE(task_board_index integer, faction_name text, reveal_state boolean, time_stamp timestamp without time zone)
|
||||
-- oid: 58426 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_task_faction_reveal_state(in_term_id bigint)
|
||||
RETURNS TABLE(task_board_index integer, faction_name text, reveal_state boolean, time_stamp timestamp without time zone)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN query SELECT CAST(tasks.board_index AS INTEGER), factions.name, reveal_state.revealed, (reveal_state.timestamp AT TIME ZONE 'UTC')::TIMESTAMP
|
||||
FROM landsraad_tasks tasks
|
||||
INNER JOIN landsraad_task_reveal_state reveal_state
|
||||
ON reveal_state.task_id = tasks.id
|
||||
INNER JOIN factions factions
|
||||
ON factions.id = reveal_state.faction_id
|
||||
WHERE tasks.term_id = in_term_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,20 @@
|
||||
-- landsraad_load_term_progress(in_term_id bigint, in_num_guilds integer, in_faction_names text[], in_player_ids bigint[]) -> TABLE(faction_progress dune.landsraadtaskfactionprogress[], faction_reveal_state dune.landsraadtaskfactionrevealstate[], guild_contributions dune.landsraadguildcontribution[], player_contributions dune.landsraadplayercontribution[])
|
||||
-- oid: 58427 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_load_term_progress(in_term_id bigint, in_num_guilds integer, in_faction_names text[], in_player_ids bigint[])
|
||||
RETURNS TABLE(faction_progress dune.landsraadtaskfactionprogress[], faction_reveal_state dune.landsraadtaskfactionrevealstate[], guild_contributions dune.landsraadguildcontribution[], player_contributions dune.landsraadplayercontribution[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
term_faction_progress LandsraadTaskFactionProgress[];
|
||||
term_faction_reveal_state LandsraadTaskFactionRevealState[];
|
||||
term_guild_contributions LandsraadGuildContribution[];
|
||||
term_player_contributions LandsraadPlayerContribution[];
|
||||
BEGIN
|
||||
SELECT ARRAY_AGG((task_board_index, faction_name, progress)::LandsraadTaskFactionProgress) FROM landsraad_load_task_faction_progress(in_term_id) INTO term_faction_progress;
|
||||
SELECT ARRAY_AGG((task_board_index, faction_name, reveal_state, time_stamp)::LandsraadTaskFactionRevealState) FROM landsraad_load_task_faction_reveal_state(in_term_id) INTO term_faction_reveal_state;
|
||||
SELECT ARRAY_AGG((faction_name, guild_name, voting_influence)::LandsraadGuildContribution) FROM landsraad_load_guild_contributions(in_term_id, in_num_guilds, in_faction_names) INTO term_guild_contributions;
|
||||
SELECT ARRAY_AGG((player_id, board_index, amount)::LandsraadPlayerContribution) FROM landsraad_load_player_contributions(in_term_id, in_player_ids) INTO term_player_contributions;
|
||||
|
||||
RETURN query SELECT term_faction_progress, term_faction_reveal_state, term_guild_contributions, term_player_contributions;
|
||||
END $function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- landsraad_notify_house_rewards_changed() -> trigger
|
||||
-- oid: 58429 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_notify_house_rewards_changed()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
PERFORM pg_notify('landsraad_notify_channel', format('house_rewards_changed#{"PlayerId" : %s}', NEW.player_id));
|
||||
RETURN NULL;
|
||||
END $function$
|
||||
@@ -0,0 +1,48 @@
|
||||
-- landsraad_perform_daily_task_reveal(in_term_id bigint, in_faction_names text[], in_house_names_to_reveal text[], in_reveal_day integer) -> TABLE(faction_name text, house_name text, board_index integer)
|
||||
-- oid: 58430 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_perform_daily_task_reveal(in_term_id bigint, in_faction_names text[], in_house_names_to_reveal text[], in_reveal_day integer)
|
||||
RETURNS TABLE(faction_name text, house_name text, board_index integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
last_processed_reveal_day INTEGER = NULL;
|
||||
faction_ids BIGINT[];
|
||||
newly_revealed_task_ids BIGINT[];
|
||||
newly_revealed_house_names TEXT[];
|
||||
newly_revealed_task_board_indices INTEGER[];
|
||||
faction_of_newly_revealed_task BIGINT[];
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_decree_term IN EXCLUSIVE MODE;
|
||||
|
||||
SELECT landsraad_decree_term.last_processed_reveal_day FROM landsraad_decree_term WHERE term_id = in_term_id INTO last_processed_reveal_day;
|
||||
|
||||
IF last_processed_reveal_day < in_reveal_day THEN
|
||||
SELECT ARRAY_AGG(factions.id) FROM factions WHERE factions.name = ANY(in_faction_names) INTO faction_ids;
|
||||
|
||||
WITH revealed_task(id, faction_id) AS (
|
||||
SELECT task.id, faction.id FROM landsraad_tasks AS task
|
||||
CROSS JOIN UNNEST(faction_ids) AS faction(id)
|
||||
WHERE task.house_name = ANY (in_house_names_to_reveal) AND task.term_id = in_term_id)
|
||||
--filter out tasks already revealed from data to not stomp reveal date or send duplicate reveal event in telemetry
|
||||
SELECT ARRAY_AGG(task.id), ARRAY_AGG(task.house_name), ARRAY_AGG(task.board_index), ARRAY_AGG(revealed_task.faction_id) FROM revealed_task
|
||||
INNER JOIN landsraad_tasks AS task ON task.id = revealed_task.id
|
||||
LEFT JOIN landsraad_task_reveal_state AS reveal_state ON task.id = reveal_state.task_id AND revealed_task.faction_id = reveal_state.faction_id
|
||||
WHERE reveal_state.revealed IS NULL OR reveal_state.revealed IS FALSE
|
||||
INTO newly_revealed_task_ids, newly_revealed_house_names, newly_revealed_task_board_indices, faction_of_newly_revealed_task;
|
||||
|
||||
INSERT INTO landsraad_task_reveal_state (task_id, faction_id, revealed, timestamp) SELECT UNNEST(newly_revealed_task_ids), UNNEST(faction_of_newly_revealed_task), TRUE, now()
|
||||
ON CONFLICT(task_id, faction_id) DO UPDATE SET revealed = TRUE, timestamp = now();
|
||||
|
||||
UPDATE landsraad_decree_term SET last_processed_reveal_day = in_reveal_day WHERE term_id = in_term_id;
|
||||
|
||||
IF cardinality(newly_revealed_task_ids) > 0 THEN
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'progress_updated#{"changed": true}');
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
RETURN query
|
||||
WITH newly_revealed_tasks (house_name, board_index, faction_id) AS (
|
||||
SELECT UNNEST(newly_revealed_house_names), UNNEST(newly_revealed_task_board_indices), UNNEST(faction_of_newly_revealed_task))
|
||||
SELECT factions.name, newly_revealed_tasks.house_name, newly_revealed_tasks.board_index FROM newly_revealed_tasks JOIN factions ON newly_revealed_tasks.faction_id = factions.id;
|
||||
END $function$
|
||||
@@ -0,0 +1,27 @@
|
||||
-- landsraad_process_house_rewards() -> trigger
|
||||
-- oid: 58431 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_process_house_rewards()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
WITH
|
||||
task_player_contribution_threshold_passed (player_id, house_name, template_id, amount) AS (
|
||||
SELECT NEW.player_id, tasks.house_name, task_rewards.template_id, task_rewards.amount
|
||||
FROM landsraad_task_rewards as task_rewards
|
||||
INNER JOIN landsraad_tasks AS tasks
|
||||
ON task_rewards.task_id = tasks.id
|
||||
LEFT JOIN landsraad_task_player_contributions AS player_contributions
|
||||
ON player_contributions.task_id = tasks.id
|
||||
WHERE task_rewards.task_id = NEW.task_id
|
||||
AND tasks.id = NEW.task_id
|
||||
AND player_contributions.player_id = NEW.player_id
|
||||
AND COALESCE(OLD.amount, 0) < task_rewards.threshold
|
||||
AND NEW.amount >= task_rewards.threshold)
|
||||
INSERT INTO landsraad_house_rewards (player_id, house_name, template_id, amount, last_updated)
|
||||
SELECT player_id, house_name, template_id, SUM(amount), CURRENT_TIMESTAMP FROM task_player_contribution_threshold_passed GROUP BY player_id, house_name, template_id
|
||||
ON CONFLICT (player_id, house_name, template_id) DO UPDATE SET amount = landsraad_house_rewards.amount + excluded.amount, last_updated = CURRENT_TIMESTAMP;
|
||||
|
||||
RETURN NULL;
|
||||
END $function$
|
||||
@@ -0,0 +1,103 @@
|
||||
-- landsraad_process_task_progress(max_rows integer) -> void
|
||||
-- oid: 58432 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_process_task_progress(max_rows integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
task_progress RECORD = NULL;
|
||||
current_term_id BIGINT = NULL;
|
||||
last_progress_id BIGINT = NULL;
|
||||
old_processed_id BIGINT = NULL;
|
||||
new_processed_id BIGINT = NULL;
|
||||
new_amount INTEGER = 0;
|
||||
player BIGINT = NULL;
|
||||
guild BIGINT = NULL;
|
||||
notify_guild_ids BIGINT[];
|
||||
guild_ids_json JSON = NULL;
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_task_progress_processed IN EXCLUSIVE MODE;
|
||||
|
||||
SELECT term_id FROM landsraad_decree_term ORDER BY start_time DESC LIMIT 1 INTO current_term_id;
|
||||
|
||||
SELECT id FROM landsraad_task_progress ORDER BY id DESC LIMIT 1 INTO last_progress_id;
|
||||
|
||||
SELECT last_processed_id FROM landsraad_task_progress_processed INTO old_processed_id;
|
||||
|
||||
-- read batch of rows sorted by id, process ordered by timestamp
|
||||
FOR task_progress IN
|
||||
WITH progress_batch AS (
|
||||
SELECT landsraad_task_progress.id, landsraad_task_progress.faction_id, landsraad_task_progress.task_id,
|
||||
landsraad_task_progress.faction_progress, landsraad_task_progress.guild_progress, landsraad_task_progress.player_progress, landsraad_task_progress.timestamp,
|
||||
task_progress_players.players, task_progress_guilds.guilds
|
||||
FROM landsraad_task_progress,
|
||||
LATERAL (SELECT ARRAY_AGG(player_id) AS players FROM landsraad_task_progress_player WHERE landsraad_task_progress_player.progress_id = landsraad_task_progress.id) AS task_progress_players,
|
||||
LATERAL (SELECT ARRAY_AGG(guild_id) AS guilds FROM landsraad_task_progress_guild WHERE landsraad_task_progress_guild.progress_id = landsraad_task_progress.id) AS task_progress_guilds
|
||||
WHERE CASE WHEN old_processed_id IS NOT NULL THEN id > old_processed_id ELSE TRUE END
|
||||
ORDER BY id LIMIT MAX_ROWS
|
||||
)
|
||||
SELECT id, faction_id, task_id, players, guilds, faction_progress, guild_progress, player_progress FROM progress_batch ORDER BY timestamp
|
||||
LOOP
|
||||
IF NOT (SELECT landsraad_has_term_of_task_ended(task_progress.task_id)) THEN
|
||||
-- player progress is allowed to happen even if the task was already completed
|
||||
IF task_progress.players IS NOT NULL THEN
|
||||
FOREACH player IN ARRAY task_progress.players
|
||||
LOOP
|
||||
INSERT INTO landsraad_task_player_contributions AS player_contribution (player_id, faction_id, task_id, amount)
|
||||
VALUES (player, task_progress.faction_id, task_progress.task_id, task_progress.player_progress)
|
||||
ON CONFLICT (player_id, faction_id, task_id)
|
||||
DO UPDATE SET amount = player_contribution.amount + task_progress.player_progress;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
IF NOT (SELECT landsraad_task_has_been_completed(task_progress.task_id)) THEN
|
||||
IF task_progress.guilds IS NOT NULL THEN
|
||||
FOREACH guild IN ARRAY task_progress.guilds
|
||||
LOOP
|
||||
-- only insert to guild contribution if no vote has been placed
|
||||
IF (SELECT NOT EXISTS (SELECT 1 FROM landsraad_decree_votes WHERE landsraad_decree_votes.guild_id = guild)) THEN
|
||||
INSERT INTO landsraad_task_guild_contributions AS guild_contribution (guild_id, faction_id, task_id, amount)
|
||||
VALUES (guild, task_progress.faction_id, task_progress.task_id, task_progress.guild_progress)
|
||||
ON CONFLICT (guild_id, faction_id, task_id)
|
||||
DO UPDATE SET amount = guild_contribution.amount + task_progress.guild_progress;
|
||||
notify_guild_ids = notify_guild_ids || guild;
|
||||
END IF;
|
||||
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
INSERT INTO landsraad_task_faction_contributions AS faction_contribution (faction_id, task_id, amount)
|
||||
VALUES (task_progress.faction_id, task_progress.task_id, task_progress.faction_progress)
|
||||
ON CONFLICT (faction_id, task_id)
|
||||
DO UPDATE SET amount = faction_contribution.amount + task_progress.faction_progress;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
new_processed_id = task_progress.id;
|
||||
END LOOP;
|
||||
|
||||
IF new_processed_id IS NOT NULL THEN
|
||||
IF old_processed_id IS NULL THEN
|
||||
INSERT INTO landsraad_task_progress_processed (last_processed_id) VALUES (new_processed_id);
|
||||
ELSE
|
||||
UPDATE landsraad_task_progress_processed SET last_processed_id = new_processed_id;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
IF last_progress_id > new_processed_id THEN
|
||||
PERFORM pg_notify('landsraad_notify_channel', format('progress_pressure#{"UnprocessedCount": %s}', last_progress_id - new_processed_id));
|
||||
END IF;
|
||||
|
||||
IF new_processed_id > old_processed_id THEN
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'progress_updated#{"changed": true}');
|
||||
ELSE
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'progress_updated#{"changed": false}');
|
||||
END IF;
|
||||
|
||||
IF cardinality(notify_guild_ids) > 0 THEN
|
||||
SELECT json_agg(DISTINCT guild_id) FROM (SELECT unnest(notify_guild_ids) guild_id) guilds INTO guild_ids_json;
|
||||
PERFORM pg_notify('landsraad_notify_channel', format('guild_vote_changed#{"GuildIds": %s}', guild_ids_json));
|
||||
END IF;
|
||||
|
||||
END $function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- landsraad_task_has_been_completed(in_task_id bigint) -> boolean
|
||||
-- oid: 58433 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_task_has_been_completed(in_task_id bigint)
|
||||
RETURNS boolean
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
task_completed BOOLEAN = FALSE;
|
||||
BEGIN
|
||||
SELECT task.completed FROM landsraad_tasks AS task WHERE task.id = in_task_id INTO task_completed;
|
||||
RETURN task_completed;
|
||||
END $function$
|
||||
@@ -0,0 +1,28 @@
|
||||
-- landsraad_update_task_faction_reveal_state(in_term_id bigint, in_task_board_index integer, faction_name text, reveal_state boolean) -> void
|
||||
-- oid: 58436 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_update_task_faction_reveal_state(in_term_id bigint, in_task_board_index integer, faction_name text, reveal_state boolean)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
taskid BIGINT = NULL;
|
||||
factionid BIGINT = NULL;
|
||||
BEGIN
|
||||
SELECT id FROM landsraad_tasks tasks WHERE tasks.board_index = in_task_board_index AND tasks.term_id = in_term_id INTO taskid;
|
||||
|
||||
IF taskid IS NULL THEN
|
||||
RAISE EXCEPTION 'Cannot update landsraad task reveal state, no task id for index % term %', in_task_board_index, in_term_id;
|
||||
END IF;
|
||||
|
||||
SELECT id FROM factions WHERE factions.name = faction_name INTO factionid;
|
||||
|
||||
IF factionid IS NULL OR faction_name = 'None' THEN
|
||||
RAISE EXCEPTION 'Cannot update landsraad task reveal state, invalid faction (%)', faction_name;
|
||||
END IF;
|
||||
|
||||
INSERT INTO landsraad_task_reveal_state (task_id, faction_id, revealed, timestamp) VALUES (taskid, factionid, reveal_state, now()) ON CONFLICT(task_id, faction_id) DO UPDATE
|
||||
SET revealed = reveal_state, timestamp = now();
|
||||
|
||||
PERFORM pg_notify('landsraad_notify_channel', 'progress_updated#{"changed": true}');
|
||||
END $function$
|
||||
@@ -0,0 +1,32 @@
|
||||
-- landsraad_withdraw_house_reward(in_player_id bigint, in_house_rewards dune.landsraadplayerhousereward[]) -> void
|
||||
-- oid: 58437 kind: FUNCTION category: landsraad
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.landsraad_withdraw_house_reward(in_player_id bigint, in_house_rewards dune.landsraadplayerhousereward[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_amount INTEGER = NULL;
|
||||
house_reward record = NULL;
|
||||
grouped_house_rewards LandsraadPlayerHouseReward[];
|
||||
BEGIN
|
||||
LOCK TABLE landsraad_house_rewards IN EXCLUSIVE MODE;
|
||||
--group rewards to make sure multiple entries of the same item do not slip by amount verfication below
|
||||
WITH grouped_rewards AS (SELECT house_name, template_id, SUM(amount) as amount FROM UNNEST(in_house_rewards) GROUP BY house_name, template_id)
|
||||
SELECT ARRAY_AGG((grouped_rewards.house_name, grouped_rewards.template_id, grouped_rewards.amount)::LandsraadPlayerHouseReward) INTO grouped_house_rewards FROM grouped_rewards;
|
||||
|
||||
FOREACH house_reward in ARRAY grouped_house_rewards
|
||||
LOOP
|
||||
SELECT lhr.amount INTO current_amount FROM landsraad_house_rewards AS lhr WHERE lhr.player_id = in_player_id AND lhr.house_name = house_reward.house_name AND lhr.template_id = house_reward.template_id;
|
||||
|
||||
IF current_amount IS NULL OR current_amount < house_reward.amount THEN
|
||||
RAISE EXCEPTION 'Cannot withdraw house reward %s for player % and house %s', house_reward.template_id, in_player_id, house_reward.house_name;
|
||||
RETURN;
|
||||
END IF;
|
||||
END LOOP;
|
||||
-- finish full loop of checks first, all rewards need to be withdrawable before updating
|
||||
FOREACH house_reward in ARRAY grouped_house_rewards
|
||||
LOOP
|
||||
UPDATE landsraad_house_rewards SET amount = amount - house_reward.amount, last_updated = CURRENT_TIMESTAMP WHERE player_id = in_player_id AND house_name = house_reward.house_name AND template_id = house_reward.template_id;
|
||||
END LOOP;
|
||||
END $function$
|
||||
Reference in New Issue
Block a user