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,16 @@
|
||||
-- assign_actor_id(in_class text) -> bigint
|
||||
-- oid: 58140 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.assign_actor_id(in_class text)
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
new_id BIGINT;
|
||||
BEGIN
|
||||
INSERT INTO actors(id) VALUES(DEFAULT) RETURNING id INTO new_id;
|
||||
PERFORM add_actor_audit(new_id, in_class);
|
||||
|
||||
RETURN new_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- delete_actor_states_travel(in_actor_id bigint) -> void
|
||||
-- oid: 58199 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_actor_states_travel(in_actor_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
WITH
|
||||
traveling_actor_ids AS (
|
||||
SELECT t.id FROM get_traveling_non_player_actor_ids(in_actor_id) AS t
|
||||
)
|
||||
DELETE FROM actor_state WHERE (actor_id IN (SELECT t.id FROM traveling_actor_ids AS t(id)) OR actor_id = in_actor_id) AND state = 'Travel';
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- delete_actors(in_ids bigint[]) -> void
|
||||
-- oid: 58200 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_actors(in_ids bigint[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM actors WHERE id = ANY(in_ids);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,47 @@
|
||||
-- delete_actors_and_respawns_on_server(in_server_info dune.serverinfo, in_vehicle_classes_spawned_on_map text[], in_allow_vehicle_recovery boolean) -> void
|
||||
-- oid: 58201 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_actors_and_respawns_on_server(in_server_info dune.serverinfo, in_vehicle_classes_spawned_on_map text[], in_allow_vehicle_recovery boolean)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
WITH actors_to_delete AS (
|
||||
SELECT a.id
|
||||
FROM actors a
|
||||
LEFT JOIN actor_state s ON a.id = s.actor_id
|
||||
WHERE owner_account_id IS NULL
|
||||
AND s.state IS DISTINCT FROM 'Travel'
|
||||
AND s.state IS DISTINCT FROM 'VehicleBackup'
|
||||
AND s.state IS DISTINCT FROM 'VehicleRecovery'
|
||||
AND server_info_match(a, in_server_info)
|
||||
AND (
|
||||
-- Actors that are not vehicles should always be deleted
|
||||
NOT EXISTS (SELECT 1 FROM vehicles v WHERE v.id = a.id)
|
||||
-- Only vehicles that are allowed to be spawned on this map should be deleted
|
||||
OR in_vehicle_classes_spawned_on_map IS NULL -- If the list is NULL all vehicles are allowed
|
||||
OR a.class = ANY(in_vehicle_classes_spawned_on_map) -- Vehicle type is explicitly allowed on this map
|
||||
)
|
||||
ORDER BY a.id FOR UPDATE OF a
|
||||
),
|
||||
vehicles_to_recover AS (
|
||||
SELECT COALESCE(ARRAY_AGG(v.id), ARRAY[]::BIGINT[]) AS ids FROM actors_to_delete a JOIN vehicles v ON (a.id = v.id)
|
||||
WHERE in_allow_vehicle_recovery
|
||||
),
|
||||
recovered_vehicles AS (
|
||||
SELECT ids, store_recovered_vehicles_wiped_before_spawn(ids) FROM vehicles_to_recover
|
||||
)
|
||||
DELETE FROM actors a USING recovered_vehicles rv
|
||||
WHERE a.id = ANY(SELECT id FROM actors_to_delete)
|
||||
AND NOT a.id = ANY(rv.ids);
|
||||
|
||||
with
|
||||
deleted_ids as (
|
||||
DELETE from player_respawn_locations
|
||||
WHERE map = in_server_info.map AND dimension = in_server_info.dimension_index
|
||||
returning id
|
||||
)
|
||||
update player_state set pending_respawn_location_id=null
|
||||
where pending_respawn_location_id in (select * from deleted_ids);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,35 @@
|
||||
-- delete_markers_return_actor_ids(in_dimension_index integer, in_map_name text, in_marker_ids integer[]) -> TABLE(actor_id bigint, marker_id integer)
|
||||
-- oid: 58226 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_markers_return_actor_ids(in_dimension_index integer, in_map_name text, in_marker_ids integer[])
|
||||
RETURNS TABLE(actor_id bigint, marker_id integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
-- Lock markers matching query
|
||||
WITH affected_markers AS (
|
||||
SELECT * FROM markers JOIN map_names USING(map_name_id)
|
||||
WHERE (dimension_index = in_dimension_index OR dimension_index = -1)
|
||||
AND map_names.map_name = in_map_name
|
||||
AND marker_hash_id = ANY(in_marker_ids)
|
||||
ORDER BY marker_hash_id, dimension_index FOR UPDATE -- Ordering to avoid deadlocks
|
||||
),
|
||||
-- Lock player_markers to be deleted on cascade
|
||||
referencing_player_markers AS (
|
||||
SELECT player_id, player_markers.marker_hash_id FROM player_markers, affected_markers
|
||||
WHERE affected_markers.marker_hash_id = player_markers.marker_hash_id
|
||||
AND affected_markers.dimension_index = player_markers.dimension_index
|
||||
AND affected_markers.map_name_id = player_markers.map_name_id
|
||||
ORDER BY player_id, player_markers.marker_hash_id, player_markers.dimension_index FOR UPDATE -- Ordering to avoid deadlocks
|
||||
),
|
||||
-- Delete markers
|
||||
deleted_markers AS (
|
||||
DELETE FROM markers USING affected_markers
|
||||
WHERE affected_markers.marker_hash_id = markers.marker_hash_id
|
||||
AND affected_markers.dimension_index = markers.dimension_index
|
||||
AND affected_markers.map_name_id = markers.map_name_id
|
||||
)
|
||||
SELECT * FROM referencing_player_markers;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- find_actor_by_id(in_id bigint) -> dune.actorspawninfo
|
||||
-- oid: 58263 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.find_actor_by_id(in_id bigint)
|
||||
RETURNS dune.actorspawninfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
return (select (id, class, transform, partition_id, dimension_index)::ActorSpawnInfo
|
||||
FROM actors WHERE actors.id = in_id
|
||||
LIMIT 1);
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- gather_ownerless_actors_on_server(in_server_info dune.serverinfo) -> SETOF dune.actorspawninfo
|
||||
-- oid: 58266 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.gather_ownerless_actors_on_server(in_server_info dune.serverinfo)
|
||||
RETURNS SETOF dune.actorspawninfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT a.id, a.class as class_name, a.transform, a.partition_id, a.dimension_index FROM actors as a
|
||||
WHERE a.owner_account_id is null AND server_info_match(a, in_server_info);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- gather_player_linked_actors(in_player_pawn_id bigint) -> SETOF dune.actorspawninfo
|
||||
-- oid: 58267 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.gather_player_linked_actors(in_player_pawn_id bigint)
|
||||
RETURNS SETOF dune.actorspawninfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
return query
|
||||
select actors.id, actors.class as class_name, actors.transform, actors.partition_id, actors.dimension_index
|
||||
from actors
|
||||
left join actor_state on actor_state.actor_id = actors.id
|
||||
where actors.id in (select id from get_traveling_non_player_actor_ids(in_player_pawn_id)) and actor_state.state = 'Travel' and actors.owner_account_id is null
|
||||
order by actors.id;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,25 @@
|
||||
-- gather_removed_accounts_that_left_orphaned_actors_on_server(in_server_info dune.serverinfo) -> TABLE(account_id bigint, removal_reason text, actors_left dune.orphanedplayeractorinfo[])
|
||||
-- oid: 58268 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.gather_removed_accounts_that_left_orphaned_actors_on_server(in_server_info dune.serverinfo)
|
||||
RETURNS TABLE(account_id bigint, removal_reason text, actors_left dune.orphanedplayeractorinfo[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
return query with
|
||||
orphaned_actors_per_account as (
|
||||
SELECT
|
||||
a.owner_account_id as account_id,
|
||||
array_agg((a.id, a.class)::OrphanedPlayerActorInfo) as actors_left
|
||||
FROM actors as a
|
||||
WHERE
|
||||
-- not is null instead of is not null to match the index expression
|
||||
not a.owner_account_id is null
|
||||
AND NOT EXISTS(select 1 from accounts where id=owner_account_id)
|
||||
AND server_info_match(a, in_server_info)
|
||||
GROUP BY a.owner_account_id
|
||||
)
|
||||
select orphans.account_id, log.reason, orphans.actors_left
|
||||
from orphaned_actors_per_account as orphans left join account_removal_log as log using (account_id);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- get_account_actor_ids(in_account_id bigint) -> dune.playeractorids
|
||||
-- oid: 58269 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_account_actor_ids(in_account_id bigint)
|
||||
RETURNS dune.playeractorids
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
return (
|
||||
select (player_controller_id, player_state_id, player_pawn_id)::PlayerActorIds from player_state
|
||||
where account_id = in_account_id
|
||||
limit 1
|
||||
);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- get_actor_server_info(in_id bigint) -> dune.serverinfo
|
||||
-- oid: 58271 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_actor_server_info(in_id bigint)
|
||||
RETURNS dune.serverinfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
return (select (map, partition_id, dimension_index)::ServerInfo from actors where id=in_id limit 1);
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- get_registered_spawned_actor(in_spawner_id bigint) -> SETOF bigint
|
||||
-- oid: 58348 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_registered_spawned_actor(in_spawner_id bigint)
|
||||
RETURNS SETOF bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT actor_id FROM actor_spawner_actors WHERE spawner_id = in_spawner_id;
|
||||
END; $function$
|
||||
@@ -0,0 +1,54 @@
|
||||
-- load_actors(in_actor_ids bigint[], in_actor_state dune.actorstate) -> TABLE(ord bigint, actor_id bigint, generic_data dune.actorgenericdata, serial bigint)
|
||||
-- oid: 58438 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_actors(in_actor_ids bigint[], in_actor_state dune.actorstate DEFAULT 'Default'::dune.actorstate)
|
||||
RETURNS TABLE(ord bigint, actor_id bigint, generic_data dune.actorgenericdata, serial bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
return query
|
||||
with
|
||||
ids as (
|
||||
select * from unnest(in_actor_ids) with ordinality as t(id, ord)
|
||||
),
|
||||
entities as (
|
||||
select
|
||||
fgl_bridge.actor_id,
|
||||
(fgl_bridge.entity_id, fgl_bridge.slot_name, entity_data.components)::FglEntity as data
|
||||
from
|
||||
ids
|
||||
left join actor_fgl_entities as fgl_bridge on ids.id=fgl_bridge.actor_id
|
||||
left join fgl_entities as entity_data on fgl_bridge.entity_id = entity_data.entity_id
|
||||
)
|
||||
select
|
||||
ids.ord, actors.id,
|
||||
(
|
||||
coalesce(array_agg(entities.data) filter (where entities.data is not null), array[]::FglEntity[]),
|
||||
actors.properties,
|
||||
actors.gas_attributes,
|
||||
case
|
||||
when exists(select 1 from buildings where actors.id = buildings.id) then load_building(actors.id)
|
||||
end
|
||||
,
|
||||
case
|
||||
when exists(select 1 from placeables where actors.id = placeables.id) then load_placeable(actors.id)
|
||||
end
|
||||
,
|
||||
case
|
||||
when exists(select 1 from totems where actors.id = totems.id) then load_totem(actors.id)
|
||||
end
|
||||
)::ActorGenericData, actors.serial
|
||||
from
|
||||
ids
|
||||
join actors using (id)
|
||||
left join entities on actors.id = entities.actor_id
|
||||
where
|
||||
case when (in_actor_state = 'Default') then
|
||||
not exists(select 1 from actor_state where actors.id = actor_state.actor_id)
|
||||
else
|
||||
exists(select 1 from actor_state where actors.id = actor_state.actor_id and actor_state.state = in_actor_state)
|
||||
end
|
||||
group by ids.ord, actors.id, actors.properties, actors.gas_attributes, actors.serial
|
||||
order by ids.ord;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,48 @@
|
||||
-- load_full_actors(in_ids bigint[]) -> SETOF dune.actordescription
|
||||
-- oid: 58454 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_full_actors(in_ids bigint[])
|
||||
RETURNS SETOF dune.actordescription
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
return query
|
||||
with
|
||||
ids as (
|
||||
select * from unnest(in_ids) with ordinality as t(id, ord)
|
||||
),
|
||||
entities as (
|
||||
select
|
||||
actor_id,
|
||||
(fgl_bridge.entity_id, fgl_bridge.slot_name, entity_data.components)::FglEntity as data
|
||||
from
|
||||
ids
|
||||
left join actor_fgl_entities as fgl_bridge on ids.id=fgl_bridge.actor_id
|
||||
left join fgl_entities as entity_data using (entity_id)
|
||||
)
|
||||
select
|
||||
id, "class", "transform", (
|
||||
coalesce(array_agg(entities.data) filter (where entities.data is not null), array[]::FglEntity[]),
|
||||
actors.properties,
|
||||
actors.gas_attributes,
|
||||
case
|
||||
when exists(select 1 from buildings where ids.id = buildings.id) then load_building(id)
|
||||
else null
|
||||
end,
|
||||
case
|
||||
when exists(select 1 from placeables where ids.id = placeables.id) then load_placeable(id)
|
||||
else null
|
||||
end
|
||||
,
|
||||
case
|
||||
when exists(select 1 from totems where id = totems.id) then load_totem(id)
|
||||
end
|
||||
)::ActorGenericData, actors.serial
|
||||
from
|
||||
ids
|
||||
join actors using (id)
|
||||
left join entities on id=entities.actor_id
|
||||
group by ids.ord, id, class, "transform", actors.properties, actors.gas_attributes, actors.serial
|
||||
order by ids.ord;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,32 @@
|
||||
-- ownership_handle_actor_delete(in_player_id bigint) -> void
|
||||
-- oid: 58482 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.ownership_handle_actor_delete(in_player_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
owned_totem_ids BIGINT[];
|
||||
actors_with_permission BIGINT[];
|
||||
BEGIN
|
||||
|
||||
-- Get owner entity ids (totems) where in_player_id is the owner
|
||||
SELECT ARRAY_AGG(owner_entity_id) into owned_totem_ids
|
||||
FROM permission_actor_rank
|
||||
JOIN permission_actor ON actor_id = permission_actor_id
|
||||
JOIN placeables on placeables.id = permission_actor_id
|
||||
WHERE player_id = in_player_id AND rank = 1::smallint; -- 1:owner
|
||||
|
||||
-- Get actors where in_player_id is the owner
|
||||
SELECT ARRAY_AGG(permission_actor_id) into actors_with_permission
|
||||
FROM permission_actor_rank WHERE player_id = in_player_id AND rank = 1::smallint; -- 1:owner
|
||||
|
||||
-- Remove all permissions for those actors
|
||||
IF cardinality(actors_with_permission) > 0 THEN
|
||||
DELETE FROM permission_actor_rank WHERE permission_actor_id = ANY(actors_with_permission);
|
||||
DELETE FROM MARKERS WHERE marker_hash_id = ANY(actors_with_permission);
|
||||
|
||||
PERFORM pg_notify('permission_notify_channel', format('owner_delete#{"PlayerId" : %s}', in_player_id));
|
||||
END IF;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- register_spawned_actor(in_spawner_id bigint, in_actor_id bigint) -> void
|
||||
-- oid: 58511 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.register_spawned_actor(in_spawner_id bigint, in_actor_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO actor_spawner_actors(spawner_id, actor_id) VALUES(in_spawner_id, in_actor_id);
|
||||
END $function$
|
||||
@@ -0,0 +1,19 @@
|
||||
-- remove_aborted_authority_transfer_actors(in_partition_id bigint) -> SETOF dune.actorspawninfo
|
||||
-- oid: 58515 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.remove_aborted_authority_transfer_actors(in_partition_id bigint)
|
||||
RETURNS SETOF dune.actorspawninfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
WITH removed_actors AS (
|
||||
DELETE FROM actor_state WHERE actor_state.state = 'AbortedAuthorityTransfer'
|
||||
RETURNING actor_state.actor_id
|
||||
)
|
||||
SELECT a.id, a.class AS class_name, a.transform, a.partition_id, a.dimension_index
|
||||
FROM actors AS a
|
||||
INNER JOIN removed_actors ON a.id = removed_actors.actor_id
|
||||
WHERE a.partition_id = in_partition_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,30 @@
|
||||
-- remove_recipes_from_actor_properties(recipes_to_remove text[]) -> void
|
||||
-- oid: 58525 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.remove_recipes_from_actor_properties(recipes_to_remove text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
with actors_properties as (
|
||||
select id, properties->'CraftingRecipesLibraryActorComponent'->'m_KnownItemRecipes' as recipes
|
||||
from actors
|
||||
),
|
||||
modified_actors_properties as (
|
||||
select id, (
|
||||
select jsonb_agg(recipe)
|
||||
from jsonb_array_elements(actors_properties.recipes) as recipe
|
||||
where not (recipe->'BaseRecipeId'->>'Name' = any(recipes_to_remove))
|
||||
) as filtered_recipes
|
||||
from actors_properties
|
||||
)
|
||||
update actors
|
||||
set properties = jsonb_set(
|
||||
actors.properties,
|
||||
'{CraftingRecipesLibraryActorComponent,m_KnownItemRecipes}',
|
||||
coalesce(modified_actors_properties.filtered_recipes, '[]'::jsonb)
|
||||
)
|
||||
from modified_actors_properties
|
||||
where actors.id = modified_actors_properties.id;
|
||||
end;
|
||||
$function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- save_aborted_authority_transfer_actors(in_actor_ids bigint[], in_partition_id bigint) -> void
|
||||
-- oid: 58539 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_aborted_authority_transfer_actors(in_actor_ids bigint[], in_partition_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO actor_state(actor_id, state)
|
||||
SELECT a.id, 'AbortedAuthorityTransfer'
|
||||
FROM actors AS a
|
||||
WHERE a.id = ANY(in_actor_ids) AND a.partition_id = in_partition_id
|
||||
ON CONFLICT DO NOTHING;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,23 @@
|
||||
-- save_actor_dislocation(in_actor_id bigint, in_current_server_info dune.serverinfo, in_target_location dune.vector, in_target_dimension_index integer) -> void
|
||||
-- oid: 58540 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_actor_dislocation(in_actor_id bigint, in_current_server_info dune.serverinfo, in_target_location dune.vector, in_target_dimension_index integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
update actors
|
||||
set
|
||||
transform = (in_target_location, (transform).rotation),
|
||||
dimension_index = in_target_dimension_index,
|
||||
partition_id = null
|
||||
where id = in_actor_id
|
||||
and map = (in_current_server_info).map
|
||||
and dimension_index = (in_current_server_info).dimension_index
|
||||
and (
|
||||
partition_id is null
|
||||
or (in_current_server_info).partition_id is null
|
||||
or partition_id = (in_current_server_info).partition_id
|
||||
);
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,132 @@
|
||||
-- save_actors(in_server_info dune.serverinfo, in_actors dune.actordescription[], in_actor_state dune.actorstate) -> TABLE(actor_id bigint, current_saved_serial bigint, saved boolean)
|
||||
-- oid: 58541 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_actors(in_server_info dune.serverinfo, in_actors dune.actordescription[], in_actor_state dune.actorstate DEFAULT 'Default'::dune.actorstate)
|
||||
RETURNS TABLE(actor_id bigint, current_saved_serial bigint, saved boolean)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
return query with
|
||||
input_actors as (
|
||||
select * from unnest(in_actors)
|
||||
),
|
||||
valid_input_actors as (
|
||||
select input_actors.id from input_actors
|
||||
left join actor_state on input_actors.id = actor_state.actor_id
|
||||
where actor_state.state = in_actor_state or (in_actor_state = 'Default' and actor_state.actor_id is null)
|
||||
),
|
||||
serial_checks as (
|
||||
select
|
||||
input.id,
|
||||
input.serial as input_serial,
|
||||
coalesce(actors.serial, 0) as saved_serial,
|
||||
input.serial >= coalesce(actors.serial, 0) and input.id in (select id from valid_input_actors) as should_save
|
||||
from
|
||||
input_actors as input left join actors using (id)
|
||||
),
|
||||
actors_to_save as (
|
||||
select i.* from input_actors as i join serial_checks as c using (id) where c.should_save
|
||||
),
|
||||
upsert_actors as (
|
||||
insert into actors(
|
||||
"id", "class", "transform",
|
||||
"gas_attributes",
|
||||
"properties",
|
||||
"map", "partition_id", "dimension_index",
|
||||
"serial"
|
||||
)
|
||||
select
|
||||
i.id, i.class_name, i.transform,
|
||||
(i.generic_data).gas_attribute_sets_json, (i.generic_data).properties_json,
|
||||
in_server_info.map, in_server_info.partition_id, coalesce(in_server_info.dimension_index, 0),
|
||||
i.serial
|
||||
from actors_to_save as i
|
||||
on conflict (id) do update
|
||||
set
|
||||
"class" = EXCLUDED.class, "transform" = case when EXCLUDED.transform is null or (EXCLUDED.transform).location = (zero_transform()).location then actors.transform else EXCLUDED.transform end,
|
||||
|
||||
"gas_attributes" = EXCLUDED.gas_attributes, "properties" = EXCLUDED.properties,
|
||||
|
||||
"map" = EXCLUDED.map, "partition_id" = EXCLUDED.partition_id, "dimension_index" = EXCLUDED.dimension_index,
|
||||
"serial" = EXCLUDED.serial
|
||||
returning id
|
||||
),
|
||||
fgl_entity_data as (
|
||||
select id as actor_id, (u).entity_id, (u).slot_name, (u).components_json as components
|
||||
from (select id, unnest((generic_data).entities) as u from actors_to_save) q
|
||||
),
|
||||
missing_entities as (
|
||||
select entity_id
|
||||
from actors_to_save join actor_fgl_entities as existing on (actors_to_save.id = existing.actor_id)
|
||||
where not exists(select 1 from fgl_entity_data as updated where updated.entity_id=existing.entity_id)
|
||||
),
|
||||
delete_missing_entity_links as (
|
||||
delete from actor_fgl_entities as existing using missing_entities
|
||||
where existing.entity_id=missing_entities.entity_id
|
||||
returning existing.entity_id as deleted_entity_id
|
||||
),
|
||||
delete_missing_entities as (
|
||||
delete from fgl_entities as existing using missing_entities
|
||||
where existing.entity_id=missing_entities.entity_id
|
||||
),
|
||||
upsert_entities as (
|
||||
insert into fgl_entities("entity_id", "components")
|
||||
select entity_id, components from fgl_entity_data
|
||||
on conflict (entity_id) do update
|
||||
set components=EXCLUDED.components
|
||||
returning entity_id
|
||||
),
|
||||
upsert_entity_links as (
|
||||
insert into actor_fgl_entities("actor_id", "entity_id", "slot_name")
|
||||
select fgl_entity_data.actor_id, fgl_entity_data.entity_id, fgl_entity_data.slot_name
|
||||
from fgl_entity_data left join upsert_entities using (entity_id)
|
||||
-- HACK: this is a temporary fix until we do TECH-23063
|
||||
where not entity_id in (select deleted_entity_id from delete_missing_entity_links)
|
||||
on conflict (entity_id) do update
|
||||
set
|
||||
actor_id=EXCLUDED.actor_id,
|
||||
slot_name=EXCLUDED.slot_name
|
||||
returning actor_fgl_entities.actor_id, actor_fgl_entities.entity_id
|
||||
),
|
||||
all_actor_entities as (
|
||||
select fgl_entity_data.actor_id as id, array_agg(entity_id) as entity_ids
|
||||
from fgl_entity_data
|
||||
left join upsert_entities using (entity_id)
|
||||
left join upsert_entity_links using (entity_id)
|
||||
group by fgl_entity_data.actor_id
|
||||
),
|
||||
extra_data as (
|
||||
select
|
||||
input_actors.id,
|
||||
serial_checks.saved_serial,
|
||||
(serial_checks.should_save) as saved,
|
||||
(input_actors.generic_data).building_actor_data as building_data,
|
||||
(input_actors.generic_data).placeable_actor_data as placeable_data,
|
||||
(input_actors.generic_data).totem_actor_data as totem_data,
|
||||
coalesce(all_actor_entities.entity_ids, array[]::int[]) as entity_ids
|
||||
from
|
||||
serial_checks
|
||||
left join input_actors using(id)
|
||||
left join upsert_actors using(id) -- this is needed for dependency
|
||||
left join all_actor_entities using(id) -- this is needed for dependency only
|
||||
),
|
||||
save_extras as (
|
||||
select
|
||||
extra_data.id,
|
||||
extra_data.saved_serial,
|
||||
extra_data.saved,
|
||||
case when extra_data.saved and building_data is not null then
|
||||
save_building(id, building_data)
|
||||
end,
|
||||
case when extra_data.saved and placeable_data is not null then
|
||||
save_placeable(id, placeable_data)
|
||||
end,
|
||||
case when extra_data.saved and totem_data is not null then
|
||||
save_totem(id, totem_data)
|
||||
end,
|
||||
entity_ids
|
||||
from extra_data
|
||||
)
|
||||
select id, saved_serial, save_extras.saved from save_extras;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,47 @@
|
||||
-- update_traveling_actor_dependencies(in_dep dune.traveldependency[]) -> void
|
||||
-- oid: 58640 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_traveling_actor_dependencies(in_dep dune.traveldependency[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
with valid_ids as (
|
||||
with d as (select * from unnest(in_dep))
|
||||
select d.id from d where d.id is not null
|
||||
union
|
||||
select d.parent_id from d where d.parent_id is not null
|
||||
),
|
||||
valid_ids_plus_dep as (
|
||||
select * from valid_ids
|
||||
union
|
||||
select tap.id from travel_actor_parent as tap where tap.parent_id in (select * from valid_ids)
|
||||
),
|
||||
-- remove valid ids and connected dependencies from actor_state
|
||||
delete_actor_state_ids AS (
|
||||
delete from actor_state as acs
|
||||
where acs.actor_id in (select * from valid_ids_plus_dep) and acs.state = 'Travel'
|
||||
)
|
||||
-- remove valid ids and connected dependencies from any other dependency tree
|
||||
delete from travel_actor_parent
|
||||
where id in (select * from valid_ids_plus_dep);
|
||||
|
||||
-- add/update dependencies with valid parent and child ids
|
||||
with valid_dep as (
|
||||
select a1.id as id, a2.id as parent_id, d.is_instigator
|
||||
from unnest(in_dep) d
|
||||
left join actors as a1
|
||||
on d.id = a1.id
|
||||
left join actors as a2
|
||||
on d.parent_id = a2.id
|
||||
where
|
||||
a1.id is not null
|
||||
and a2.id is not null
|
||||
)
|
||||
insert into travel_actor_parent (id, parent_id, is_instigator)
|
||||
select * from valid_dep
|
||||
on conflict (id) do update set
|
||||
"parent_id" = excluded.parent_id,
|
||||
"is_instigator" = excluded.is_instigator;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,39 @@
|
||||
-- update_traveling_actor_tree(in_actor_id bigint, in_target_transform dune.transform, in_target_map text, in_target_dimension_index integer, in_target_partition_id bigint) -> TABLE(out_id bigint, out_actor_state text)
|
||||
-- oid: 58641 kind: FUNCTION category: actors
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_traveling_actor_tree(in_actor_id bigint, in_target_transform dune.transform, in_target_map text, in_target_dimension_index integer, in_target_partition_id bigint)
|
||||
RETURNS TABLE(out_id bigint, out_actor_state text)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
RETURN query WITH
|
||||
traveling_actor_ids AS (
|
||||
SELECT t.id FROM get_traveling_actor_ids(in_actor_id) AS t
|
||||
),
|
||||
invalid_traveling_actor_ids AS (
|
||||
SELECT id, actor_state.state::TEXT FROM traveling_actor_ids
|
||||
INNER JOIN actor_state ON actor_state.actor_id = traveling_actor_ids.id
|
||||
WHERE actor_state.state != 'Travel'
|
||||
),
|
||||
valid_traveling_actor_ids AS (
|
||||
SELECT id FROM traveling_actor_ids
|
||||
WHERE NOT EXISTS (SELECT 1 FROM invalid_traveling_actor_ids)
|
||||
),
|
||||
insert_actor_state AS (
|
||||
INSERT INTO actor_state(actor_id, state)
|
||||
SELECT id, 'Travel' FROM valid_traveling_actor_ids
|
||||
ON CONFLICT DO NOTHING
|
||||
),
|
||||
update_actors AS (
|
||||
UPDATE actors
|
||||
SET
|
||||
transform = in_target_transform,
|
||||
dimension_index = in_target_dimension_index,
|
||||
map = in_target_map,
|
||||
partition_id = in_target_partition_id
|
||||
FROM valid_traveling_actor_ids
|
||||
WHERE actors.id = valid_traveling_actor_ids.id
|
||||
)
|
||||
SELECT * FROM invalid_traveling_actor_ids;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- add_actor_audit(in_id bigint, in_class text) -> void
|
||||
-- oid: 58118 kind: FUNCTION category: anticheat
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.add_actor_audit(in_id bigint, in_class text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO actor_audit("id", "class") VALUES(in_id, in_class) ON CONFLICT(id) DO NOTHING;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,19 @@
|
||||
-- flag_player_as_cheater(in_account_id bigint, in_cheat_type dune.cheat_type_enum) -> void
|
||||
-- oid: 58265 kind: FUNCTION category: anticheat
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.flag_player_as_cheater(in_account_id bigint, in_cheat_type dune.cheat_type_enum)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
v_FLS_id TEXT;
|
||||
BEGIN
|
||||
SELECT acc."user"
|
||||
INTO v_FLS_id
|
||||
FROM accounts acc
|
||||
WHERE acc.id = in_account_id
|
||||
LIMIT 1;
|
||||
|
||||
PERFORM log_cheating(v_FLS_id, in_cheat_type);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,21 @@
|
||||
-- log_cheating(in_fls_id text, in_cheat_type dune.cheat_type_enum, in_event_time timestamp with time zone) -> void
|
||||
-- oid: 58469 kind: FUNCTION category: anticheat
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.log_cheating(in_fls_id text, in_cheat_type dune.cheat_type_enum, in_event_time timestamp with time zone DEFAULT now())
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
|
||||
-- Insert into suspicious_be
|
||||
INSERT INTO cheater_tracking (
|
||||
event_time,
|
||||
fls_id,
|
||||
cheat_type
|
||||
) VALUES (
|
||||
in_event_time,
|
||||
in_fls_id,
|
||||
in_cheat_type
|
||||
);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,19 @@
|
||||
-- base_backup_delete(in_base_backup_id bigint) -> void
|
||||
-- oid: 58141 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_delete(in_base_backup_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
actors_to_destroy BIGINT[];
|
||||
BEGIN
|
||||
DELETE FROM actors a WHERE id = ANY(
|
||||
SELECT actor_id
|
||||
FROM base_backup_linked_actors bbla
|
||||
WHERE bbla.id = in_base_backup_id
|
||||
);
|
||||
|
||||
DELETE FROM base_backups WHERE id = in_base_backup_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- base_backup_find_totems_from_player_owner(in_player_id bigint) -> TABLE(totem_id bigint)
|
||||
-- oid: 58142 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_find_totems_from_player_owner(in_player_id bigint)
|
||||
RETURNS TABLE(totem_id bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT t.id
|
||||
FROM totems t
|
||||
JOIN permission_actor_rank par ON par.permission_actor_id = t.id
|
||||
WHERE par.player_id = in_player_id AND par.rank = 1;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,42 @@
|
||||
-- base_backup_finish_placing(in_base_backup_id bigint) -> void
|
||||
-- oid: 58143 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_finish_placing(in_base_backup_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
WITH base_info AS (
|
||||
SELECT
|
||||
bb.id AS base_backup_id,
|
||||
a.partition_id,
|
||||
a.dimension_index,
|
||||
a.map
|
||||
FROM
|
||||
base_backups bb
|
||||
JOIN actors a on bb.player_id = a.id
|
||||
WHERE
|
||||
bb.id = in_base_backup_id
|
||||
)
|
||||
UPDATE actors
|
||||
SET
|
||||
partition_id = base_info.partition_id,
|
||||
dimension_index = base_info.dimension_index,
|
||||
map = base_info.map
|
||||
FROM
|
||||
base_backup_linked_actors bbl
|
||||
JOIN base_info ON bbl.id = base_info.base_backup_id
|
||||
WHERE
|
||||
actors.id = bbl.actor_id;
|
||||
|
||||
DELETE FROM actor_state a
|
||||
WHERE actor_id = ANY(
|
||||
SELECT actor_id
|
||||
FROM base_backup_linked_actors bbla
|
||||
WHERE bbla.id = in_base_backup_id
|
||||
);
|
||||
|
||||
DELETE FROM base_backups
|
||||
WHERE id = in_base_backup_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- base_backup_get_actors_to_spawn(in_base_backup_id bigint) -> SETOF dune.actorspawninfo
|
||||
-- oid: 58144 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_actors_to_spawn(in_base_backup_id bigint)
|
||||
RETURNS SETOF dune.actorspawninfo
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT a.id, a.class as class_name, a.transform, a.partition_id, a.dimension_index
|
||||
FROM actors as a
|
||||
WHERE a.id IN (
|
||||
SELECT actor_id FROM base_backup_linked_actors as bbla WHERE bbla.id = in_base_backup_id
|
||||
);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,24 @@
|
||||
-- base_backup_get_available_backups(in_player_id bigint) -> TABLE(id bigint, base_backup_name text, totem_id bigint, totem_buildable_type text, landclaim_original_global_location real[], base_backup_map text)
|
||||
-- oid: 58145 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_available_backups(in_player_id bigint)
|
||||
RETURNS TABLE(id bigint, base_backup_name text, totem_id bigint, totem_buildable_type text, landclaim_original_global_location real[], base_backup_map text)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
bb.id,
|
||||
bb.base_backup_name,
|
||||
t.id AS totem_id,
|
||||
p.building_type,
|
||||
t.landclaim_original_global_location,
|
||||
a.map
|
||||
FROM base_backups bb
|
||||
JOIN base_backup_linked_actors bbla ON bbla.id = bb.id
|
||||
JOIN totems t ON bbla.actor_id = t.id
|
||||
JOIN actors a ON a.id = t.id
|
||||
JOIN placeables p ON p.id = a.id
|
||||
WHERE bb.player_id = in_player_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,30 @@
|
||||
-- base_backup_get_buildable_data(in_base_backup_id bigint) -> TABLE(buildable_type text, total_count integer)
|
||||
-- oid: 58146 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_buildable_data(in_base_backup_id bigint)
|
||||
RETURNS TABLE(buildable_type text, total_count integer)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT t.buildable_type, SUM(t.cnt)::INT AS total_count
|
||||
FROM (
|
||||
SELECT bi.building_type AS buildable_type, COUNT(*) AS cnt
|
||||
FROM base_backup_linked_actors bla
|
||||
JOIN building_instances bi ON bla.actor_id = bi.building_id
|
||||
WHERE
|
||||
bla.id = in_base_backup_id AND
|
||||
(bi.building_flags IS NULL OR (bi.building_flags & (1 << 2) = 0 AND bi.building_flags & (1 << 7) = 0)) -- flag 2 and 7 not enabled, which relates to holograms and extensions
|
||||
GROUP BY bi.building_type
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT p.building_type AS buildable_type, COUNT(*) AS cnt
|
||||
FROM base_backup_linked_actors bla
|
||||
JOIN placeables p ON bla.actor_id = p.id
|
||||
WHERE bla.id = in_base_backup_id AND p.is_hologram = FALSE
|
||||
GROUP BY p.building_type
|
||||
) t
|
||||
GROUP BY t.buildable_type;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,42 @@
|
||||
-- base_backup_get_data(in_base_backup_id bigint) -> dune.getbasebackupdata
|
||||
-- oid: 58147 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_data(in_base_backup_id bigint)
|
||||
RETURNS dune.getbasebackupdata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
base_backup_name TEXT;
|
||||
totem_data BaseBackupTotemData;
|
||||
buildings_array BaseBackupBuildingItem[];
|
||||
placeables_array BaseBackupPlaceableItem[];
|
||||
BEGIN
|
||||
|
||||
SELECT bb.base_backup_name
|
||||
INTO base_backup_name
|
||||
FROM base_backups bb
|
||||
WHERE bb.id = in_base_backup_id;
|
||||
|
||||
totem_data := base_backup_get_totem_data(in_base_backup_id);
|
||||
|
||||
-- building pieces
|
||||
SELECT array_agg((bi.building_id, bi.instance_id, bi.building_type, bi.transform, bi.building_flags)::BaseBackupBuildingItem)
|
||||
into buildings_array
|
||||
FROM
|
||||
building_instances bi
|
||||
JOIN base_backup_linked_actors bbla ON bi.building_id = bbla.actor_id
|
||||
WHERE bbla.id = in_base_backup_id;
|
||||
|
||||
-- placeables
|
||||
SELECT array_agg((p.building_type, a.transform)::BaseBackupPlaceableItem)
|
||||
into placeables_array
|
||||
FROM
|
||||
placeables p
|
||||
JOIN actors a ON p.id = a.id
|
||||
JOIN base_backup_linked_actors bbla ON a.id = bbla.actor_id
|
||||
WHERE
|
||||
bbla.id = in_base_backup_id;
|
||||
|
||||
return ROW(base_backup_name, totem_data, buildings_array, placeables_array)::GetBaseBackupData;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,26 @@
|
||||
-- base_backup_get_totem_data(in_base_backup_id bigint) -> dune.basebackuptotemdata
|
||||
-- oid: 58148 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_totem_data(in_base_backup_id bigint)
|
||||
RETURNS dune.basebackuptotemdata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
totem_id BIGINT;
|
||||
result BaseBackupTotemData;
|
||||
BEGIN
|
||||
SELECT t.id
|
||||
INTO totem_id
|
||||
FROM totems t JOIN base_backup_linked_actors bbla ON t.id = bbla.actor_id
|
||||
WHERE bbla.id = in_base_backup_id
|
||||
LIMIT 1;
|
||||
|
||||
IF totem_id IS NULL THEN
|
||||
RAISE EXCEPTION 'No totem found for base_backup id %', in_base_backup_id;
|
||||
END IF;
|
||||
|
||||
result := base_backup_get_totem_data_from_totem_id(totem_id);
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,42 @@
|
||||
-- base_backup_get_totem_data_from_totem_id(in_totem_id bigint) -> dune.basebackuptotemdata
|
||||
-- oid: 58149 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_totem_data_from_totem_id(in_totem_id bigint)
|
||||
RETURNS dune.basebackuptotemdata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
result BaseBackupTotemData;
|
||||
BEGIN
|
||||
SELECT
|
||||
t.id,
|
||||
p.building_type,
|
||||
a.map,
|
||||
t.landclaim_original_global_location,
|
||||
t.landclaim_original_global_yaw_rotation,
|
||||
t.landclaim_vertical_level
|
||||
INTO
|
||||
result.totem_actor_id,
|
||||
result.totem_building_type,
|
||||
result.totem_map,
|
||||
result.landclaim_original_global_location,
|
||||
result.landclaim_original_global_yaw_rotation,
|
||||
result.landclaim_vertical_level
|
||||
FROM totems t
|
||||
JOIN placeables p ON p.id = t.id
|
||||
JOIN actors a ON a.id = t.id
|
||||
WHERE t.id = in_totem_id
|
||||
LIMIT 1;
|
||||
|
||||
IF result.totem_actor_id IS NULL THEN
|
||||
RAISE EXCEPTION 'No totem found for totem_id %', in_totem_id;
|
||||
END IF;
|
||||
|
||||
SELECT array_agg(ROW(grid_location_x, grid_location_y)::SMALLINTPOINT)
|
||||
INTO result.landclaim_grid
|
||||
FROM landclaim_segments s
|
||||
WHERE s.totem_id = result.totem_actor_id;
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,24 @@
|
||||
-- base_backup_get_totem_id(backup_id bigint) -> bigint
|
||||
-- oid: 58150 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_get_totem_id(backup_id bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
result BIGINT;
|
||||
BEGIN
|
||||
SELECT t.id
|
||||
INTO result
|
||||
FROM totems t
|
||||
JOIN base_backup_linked_actors bbla ON t.id = bbla.actor_id
|
||||
WHERE bbla.id = backup_id
|
||||
LIMIT 1;
|
||||
|
||||
IF result IS NULL THEN
|
||||
RAISE EXCEPTION 'No totem found for base_backup id %', backup_id;
|
||||
END IF;
|
||||
|
||||
RETURN result;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,38 @@
|
||||
-- base_backup_recycle(in_base_backup_id bigint, in_target_inventory_id bigint) -> integer
|
||||
-- oid: 58151 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_recycle(in_base_backup_id bigint, in_target_inventory_id bigint)
|
||||
RETURNS integer
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
base_backup_items_moved INT;
|
||||
BEGIN
|
||||
UPDATE items
|
||||
SET inventory_id = in_target_inventory_id
|
||||
FROM
|
||||
inventories inv
|
||||
JOIN base_backup_linked_actors bbla ON inv.actor_id = bbla.actor_id
|
||||
WHERE
|
||||
items.inventory_id = inv.id
|
||||
AND bbla.id = in_base_backup_id;
|
||||
|
||||
get diagnostics base_backup_items_moved = ROW_COUNT;
|
||||
|
||||
-- Re-organize the index of all the items
|
||||
UPDATE items
|
||||
SET position_index = new_index
|
||||
FROM (
|
||||
SELECT
|
||||
id,
|
||||
ROW_NUMBER() OVER (ORDER BY position_index) - 1 AS new_index
|
||||
FROM items
|
||||
WHERE inventory_id = in_target_inventory_id
|
||||
) AS sub
|
||||
WHERE items.id = sub.id;
|
||||
|
||||
PERFORM base_backup_delete(in_base_backup_id);
|
||||
|
||||
return base_backup_items_moved;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,58 @@
|
||||
-- base_backup_save(in_player_actor_id bigint, in_base_backup_name text, in_building_pieces_to_link dune.basebackupbuildingitem[], in_placeables_to_link bigint[], in_placeables_to_remove_totem_owner bigint[]) -> bigint
|
||||
-- oid: 58152 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_save(in_player_actor_id bigint, in_base_backup_name text, in_building_pieces_to_link dune.basebackupbuildingitem[], in_placeables_to_link bigint[], in_placeables_to_remove_totem_owner bigint[])
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
v_backup_id BIGINT;
|
||||
totem_id BIGINT;
|
||||
BEGIN
|
||||
-- Find and Validate the Totem exists in the list
|
||||
SELECT t.id INTO totem_id
|
||||
FROM totems t
|
||||
JOIN unnest(in_placeables_to_link) AS ai(actor_id) ON t.id = ai.actor_id
|
||||
LIMIT 1;
|
||||
|
||||
IF totem_id IS NULL THEN
|
||||
RAISE EXCEPTION 'No totem found for base_backup_save';
|
||||
END IF;
|
||||
|
||||
INSERT INTO base_backups(player_id, base_backup_name)
|
||||
VALUES (in_player_actor_id, in_base_backup_name) RETURNING id INTO v_backup_id;
|
||||
|
||||
-- for each building_id, create a new actor for those building pieces and then assign that new building_id to the building pieces.
|
||||
with
|
||||
input as (select DISTINCT building_id from unnest(in_building_pieces_to_link)),
|
||||
instances_input as (select building_id, instance_id from unnest(in_building_pieces_to_link)),
|
||||
new_actor_ids as (select nextval('actors_id_seq') as new_id, building_id as old_id from input),
|
||||
_copy_building_actors as (
|
||||
insert into actors("id", "class", "map", "transform", "partition_id", "dimension_index")
|
||||
select i.new_id, a."class", a."map", a."transform", a."partition_id", a."dimension_index"
|
||||
from new_actor_ids i join actors a on (i.old_id = a.id)),
|
||||
_insert_actor_states as (insert into actor_state(actor_id, state) select new_id, 'BaseBackup' from new_actor_ids),
|
||||
_insert_buildings as (insert into buildings("id") select new_id from new_actor_ids),
|
||||
_insert_base_backup_linked_actors as (insert into base_backup_linked_actors("id", "actor_id") select v_backup_id, new_id from new_actor_ids)
|
||||
update building_instances bi set building_id = ids.new_id from new_actor_ids ids join instances_input i on (ids.old_id = i.building_id) where bi.building_id = ids.old_id and bi.instance_id = i.instance_id;
|
||||
|
||||
-- Link all placeables to the linked_base_backup_id and set them to BaseBackup ActorState in actor_state
|
||||
INSERT INTO base_backup_linked_actors(id, actor_id)
|
||||
SELECT v_backup_id, unnest(in_placeables_to_link);
|
||||
|
||||
INSERT INTO actor_state(actor_id, state)
|
||||
SELECT unnest(in_placeables_to_link), 'BaseBackup'::ActorState;
|
||||
|
||||
UPDATE placeables
|
||||
SET owner_entity_id = NULL
|
||||
WHERE id = ANY(in_placeables_to_remove_totem_owner);
|
||||
|
||||
-- We need to remove permissions for the Totem
|
||||
PERFORM permission_actor_destroy(totem_id);
|
||||
|
||||
-- Remove all invoices from the totem
|
||||
PERFORM taxation_remove_invoices_from_totem(totem_id);
|
||||
|
||||
RETURN v_backup_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- base_backup_save_all_totems_from_player_owner(in_player_id bigint) -> TABLE(base_backup_id bigint)
|
||||
-- oid: 58153 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_save_all_totems_from_player_owner(in_player_id bigint)
|
||||
RETURNS TABLE(base_backup_id bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT base_backup_save_from_totem(in_player_id, totem_id)
|
||||
FROM base_backup_find_totems_from_player_owner(in_player_id);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,47 @@
|
||||
-- base_backup_save_from_totem(in_player_id bigint, totem_id bigint) -> bigint
|
||||
-- oid: 58154 kind: FUNCTION category: base_backup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.base_backup_save_from_totem(in_player_id bigint, totem_id bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
totem_entity_id BIGINT;
|
||||
totem_name TEXT;
|
||||
building_pieces_to_link BaseBackupBuildingItem[];
|
||||
placeables_to_link BIGINT[];
|
||||
placeables_to_remove_totem_owner BIGINT[];
|
||||
BEGIN
|
||||
SELECT entity_id INTO totem_entity_id
|
||||
FROM actor_fgl_entities
|
||||
WHERE actor_id = totem_id;
|
||||
|
||||
SELECT COALESCE(actor_name, '') INTO totem_name
|
||||
FROM permission_actor
|
||||
WHERE actor_id = totem_id
|
||||
LIMIT 1;
|
||||
|
||||
SELECT array_agg((bi.building_id, bi.instance_id, bi.building_type, bi.transform, bi.building_flags)::BaseBackupBuildingItem)
|
||||
INTO building_pieces_to_link
|
||||
FROM building_instances bi
|
||||
WHERE bi.owner_entity_id = totem_entity_id;
|
||||
|
||||
SELECT array_agg(p.id)
|
||||
INTO placeables_to_link
|
||||
FROM placeables p
|
||||
WHERE (p.owner_entity_id = totem_entity_id AND p.has_buildable_support = TRUE) OR p.id = totem_id;
|
||||
|
||||
SELECT array_agg(p.id)
|
||||
INTO placeables_to_remove_totem_owner
|
||||
FROM placeables p
|
||||
WHERE p.owner_entity_id = totem_entity_id AND p.has_buildable_support = FALSE AND p.id != totem_id;
|
||||
|
||||
RETURN base_backup_save(
|
||||
in_player_id,
|
||||
totem_name,
|
||||
building_pieces_to_link,
|
||||
placeables_to_link,
|
||||
placeables_to_remove_totem_owner
|
||||
);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- get_battlegroup_close_date() -> timestamp without time zone
|
||||
-- oid: 58286 kind: FUNCTION category: battlegroup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_battlegroup_close_date()
|
||||
RETURNS timestamp without time zone
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN (SELECT farm_variables.battlegroup_close_date from farm_variables);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- set_battlegroup_close_date(in_close_date timestamp without time zone) -> timestamp without time zone
|
||||
-- oid: 58589 kind: FUNCTION category: battlegroup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.set_battlegroup_close_date(in_close_date timestamp without time zone)
|
||||
RETURNS timestamp without time zone
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO farm_variables (one_row, battlegroup_close_date) VALUES (true,in_close_date)
|
||||
ON CONFLICT (one_row) DO UPDATE SET battlegroup_close_date = in_close_date;
|
||||
RETURN (select * from get_battlegroup_close_date());
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- _building_validate_totem_owner_id(in_totem_owner_id bigint) -> bigint
|
||||
-- oid: 58094 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune._building_validate_totem_owner_id(in_totem_owner_id bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE sql
|
||||
BEGIN ATOMIC
|
||||
SELECT
|
||||
CASE
|
||||
WHEN (in_totem_owner_id = 0) THEN NULL::bigint
|
||||
WHEN (EXISTS ( SELECT 1
|
||||
FROM dune.fgl_entities
|
||||
WHERE (fgl_entities.entity_id = _building_validate_totem_owner_id.in_totem_owner_id))) THEN in_totem_owner_id
|
||||
ELSE NULL::bigint
|
||||
END AS "case";
|
||||
END
|
||||
@@ -0,0 +1,16 @@
|
||||
-- _placeable_validate_totem_owner_id(in_totem_owner_id bigint) -> bigint
|
||||
-- oid: 58112 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune._placeable_validate_totem_owner_id(in_totem_owner_id bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE sql
|
||||
BEGIN ATOMIC
|
||||
SELECT
|
||||
CASE
|
||||
WHEN (in_totem_owner_id = 0) THEN NULL::bigint
|
||||
WHEN (EXISTS ( SELECT 1
|
||||
FROM dune.fgl_entities
|
||||
WHERE (fgl_entities.entity_id = _placeable_validate_totem_owner_id.in_totem_owner_id))) THEN in_totem_owner_id
|
||||
ELSE NULL::bigint
|
||||
END AS "case";
|
||||
END
|
||||
@@ -0,0 +1,11 @@
|
||||
-- delete_building_blueprint(in_building_item_id bigint) -> void
|
||||
-- oid: 58209 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_building_blueprint(in_building_item_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM building_blueprints WHERE id = in_building_item_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,33 @@
|
||||
-- get_building_blueprint_copy_data(in_building_blueprint_id bigint) -> dune.buildingblueprintgetcopydata
|
||||
-- oid: 58289 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_building_blueprint_copy_data(in_building_blueprint_id bigint)
|
||||
RETURNS dune.buildingblueprintgetcopydata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
buildings_array BuildingBlueprintItem[];
|
||||
placeables_array BuildingBlueprintPlaceableItem[];
|
||||
pentashields_array BuildingBlueprintPentashieldItem[];
|
||||
BEGIN
|
||||
-- All Building Pieces
|
||||
SELECT array_agg((instance_id, building_type, transform, provides_stability, health, hologram)::BuildingBlueprintItem)
|
||||
into buildings_array
|
||||
FROM building_blueprint_instances
|
||||
WHERE building_blueprint_id = in_building_blueprint_id;
|
||||
|
||||
-- All Placeables
|
||||
SELECT array_agg((placeable_id, building_type, transform, hologram)::BuildingBlueprintPlaceableItem)
|
||||
into placeables_array
|
||||
FROM building_blueprint_placeables
|
||||
WHERE building_blueprint_id = in_building_blueprint_id;
|
||||
|
||||
-- Pentashields
|
||||
SELECT array_agg((placeable_id, scale)::BuildingBlueprintPentashieldItem)
|
||||
into pentashields_array
|
||||
FROM building_blueprint_pentashields
|
||||
WHERE building_blueprint_id = in_building_blueprint_id;
|
||||
|
||||
return ROW(buildings_array, placeables_array, pentashields_array)::BuildingBlueprintGetCopyData;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- get_building_favorites(in_account_id bigint) -> TABLE(building_types text[])
|
||||
-- oid: 58290 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_building_favorites(in_account_id bigint)
|
||||
RETURNS TABLE(building_types text[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT building_favorites.building_types FROM building_favorites WHERE account_id = in_account_id;
|
||||
END; $function$
|
||||
@@ -0,0 +1,19 @@
|
||||
-- get_building_id(in_actor_id bigint, in_class text) -> dune.buildinggetidcomposite
|
||||
-- oid: 58291 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_building_id(in_actor_id bigint, in_class text)
|
||||
RETURNS dune.buildinggetidcomposite
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
IF not exists(select 1 from buildings where "id" = in_actor_id) THEN
|
||||
if in_actor_id is null or in_actor_id = 0 then
|
||||
in_actor_id := (SELECT assign_actor_id(in_class));
|
||||
end if;
|
||||
|
||||
INSERT INTO buildings("id") VALUES(in_actor_id);
|
||||
END IF;
|
||||
|
||||
return ROW(in_actor_id)::BuildingGetIdComposite;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,20 @@
|
||||
-- get_placeable_id(in_actor_id bigint, in_class text, in_building_type text) -> dune.placeablegetidcomposite
|
||||
-- oid: 58330 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_placeable_id(in_actor_id bigint, in_class text, in_building_type text)
|
||||
RETURNS dune.placeablegetidcomposite
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
placeable_id BIGINT;
|
||||
BEGIN
|
||||
SELECT INTO placeable_id id FROM placeables WHERE "id" = in_actor_id;
|
||||
|
||||
IF placeable_id IS NULL THEN
|
||||
SELECT assign_actor_id(in_class) id INTO placeable_id;
|
||||
INSERT INTO placeables("id", "building_type") VALUES(placeable_id, in_building_type);
|
||||
END IF;
|
||||
|
||||
return ROW(placeable_id)::PlaceableGetIdComposite;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- load_building(in_building_id bigint) -> dune.buildingsavedata
|
||||
-- oid: 58449 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_building(in_building_id bigint)
|
||||
RETURNS dune.buildingsavedata
|
||||
LANGUAGE sql
|
||||
BEGIN ATOMIC
|
||||
RETURN ( SELECT ROW(array_agg(ROW(building_instances.instance_id, building_instances.building_type, building_instances.transform, building_instances.owner_entity_id, building_instances.building_flags, building_instances.health, building_instances.shelter, building_instances.stabilization_begin_timespan, building_instances.stabilization_end_timespan, building_instances.stabilization_state, building_instances.sand_buildup)::dune.buildinginstance), ARRAY[]::integer[], ARRAY[]::dune.buildinginstanceupdateowner[], ARRAY[]::dune.buildinginstanceupdatestabilization[], ARRAY[]::dune.buildinginstanceupdatehealth[], ARRAY[]::dune.buildinginstanceupdateshelter[], ARRAY[]::dune.buildinginstanceupdatesandbuildup[], ARRAY[]::dune.buildinginstanceupdatebuildingflags[], ARRAY[]::dune.buildinginstanceupdatetransform[])::dune.buildingsavedata AS "row"
|
||||
FROM dune.building_instances
|
||||
WHERE (building_instances.building_id = load_building.in_building_id));
|
||||
END
|
||||
@@ -0,0 +1,23 @@
|
||||
-- load_placeable(in_placeable_id bigint) -> dune.placeablesavedata
|
||||
-- oid: 58460 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_placeable(in_placeable_id bigint)
|
||||
RETURNS dune.placeablesavedata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
result PlaceableSaveData;
|
||||
BEGIN
|
||||
SELECT
|
||||
owner_entity_id as in_owner_entity_id,
|
||||
health as in_health,
|
||||
building_type as in_building_type,
|
||||
has_hit_ground as in_has_hit_ground,
|
||||
has_buildable_support as in_has_buildable_support,
|
||||
is_hologram as in_is_hologram
|
||||
INTO result
|
||||
FROM placeables
|
||||
WHERE id = in_placeable_id;
|
||||
return result;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,21 @@
|
||||
-- load_totem(in_id bigint) -> dune.totemsavedata
|
||||
-- oid: 58464 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_totem(in_id bigint)
|
||||
RETURNS dune.totemsavedata
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
result TotemSaveData;
|
||||
BEGIN
|
||||
SELECT
|
||||
landclaim_vertical_level,
|
||||
last_backup_timestamp,
|
||||
landclaim_original_global_location,
|
||||
landclaim_original_global_yaw_rotation
|
||||
INTO result
|
||||
FROM totems
|
||||
WHERE id = in_id;
|
||||
return result;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,143 @@
|
||||
-- save_building(in_building_id bigint, in_data dune.buildingsavedata) -> void
|
||||
-- oid: 58543 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_building(in_building_id bigint, in_data dune.buildingsavedata)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
instance BUILDINGINSTANCE;
|
||||
instance_to_remove INTEGER;
|
||||
instance_owner BuildingInstanceUpdateOwner;
|
||||
BEGIN
|
||||
-- ADD
|
||||
IF array_length(in_data.in_add_building_data, 1) > 0 THEN
|
||||
INSERT INTO building_instances(
|
||||
"building_id",
|
||||
"instance_id",
|
||||
"building_type",
|
||||
"transform",
|
||||
"owner_entity_id",
|
||||
"building_flags",
|
||||
"health",
|
||||
"shelter",
|
||||
"stabilization_begin_timespan",
|
||||
"stabilization_end_timespan",
|
||||
"stabilization_state",
|
||||
"sand_buildup"
|
||||
)
|
||||
SELECT
|
||||
in_building_id,
|
||||
add_data.instance_id,
|
||||
add_data.building_type,
|
||||
add_data.transform,
|
||||
_building_validate_totem_owner_id(add_data.owner_entity_id),
|
||||
add_data.building_flags,
|
||||
add_data.health,
|
||||
add_data.shelter,
|
||||
add_data.stabilization_begin_timespan,
|
||||
add_data.stabilization_end_timespan,
|
||||
add_data.stabilization_state,
|
||||
add_data.sand_buildup
|
||||
FROM unnest(in_data.in_add_building_data) as add_data
|
||||
ON CONFLICT ("building_id", "instance_id")
|
||||
DO UPDATE SET
|
||||
"building_type" = (instance).building_type,
|
||||
"transform" = (instance).transform,
|
||||
"owner_entity_id" = _building_validate_totem_owner_id((instance).owner_entity_id),
|
||||
"building_flags" = (instance).building_flags,
|
||||
"health" = (instance).health,
|
||||
"shelter" = (instance).shelter,
|
||||
"stabilization_begin_timespan" = (instance).stabilization_begin_timespan,
|
||||
"stabilization_end_timespan" = (instance).stabilization_end_timespan,
|
||||
"stabilization_state" = (instance).stabilization_state,
|
||||
"sand_buildup" = (instance).sand_buildup;
|
||||
END IF;
|
||||
|
||||
-- REMOVE
|
||||
IF array_length(in_data.in_remove_building_data, 1) > 0 THEN
|
||||
DELETE FROM building_instances
|
||||
WHERE building_instances."building_id" = in_building_id AND building_instances."instance_id" = ANY(in_data.in_remove_building_data);
|
||||
END IF;
|
||||
|
||||
-- OWNER. 99.99% of the time, this will only have 1 Owner Array.
|
||||
IF array_length(in_data.in_building_owner_data, 1) > 0 THEN
|
||||
FOREACH instance_owner IN ARRAY in_data.in_building_owner_data LOOP
|
||||
WITH owner_changes_table AS
|
||||
(
|
||||
SELECT unnest(instance_owner.instances) AS instance_id, instance_owner.owner_entity_id AS owner_entity_id
|
||||
)
|
||||
UPDATE building_instances
|
||||
SET owner_entity_id = _building_validate_totem_owner_id(owner_changes_table.owner_entity_id)
|
||||
FROM owner_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = owner_changes_table.instance_id;
|
||||
END LOOP;
|
||||
END IF;
|
||||
|
||||
-- STABILIZATION
|
||||
IF array_length(in_data.in_building_stabilization_data, 1) > 0 THEN
|
||||
WITH stabilization_changes_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_stabilization_data)
|
||||
)
|
||||
UPDATE building_instances SET stabilization_begin_timespan = stabilization_changes_table.stabilization_begin_timespan, stabilization_end_timespan = stabilization_changes_table.stabilization_end_timespan, stabilization_state = stabilization_changes_table.stabilization_state
|
||||
FROM stabilization_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = stabilization_changes_table.instance_id;
|
||||
END IF;
|
||||
|
||||
-- HEALTH
|
||||
IF array_length(in_data.in_building_health_data, 1) > 0 THEN
|
||||
WITH health_changes_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_health_data)
|
||||
)
|
||||
UPDATE building_instances SET health = health_changes_table.health
|
||||
FROM health_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = health_changes_table.instance_id;
|
||||
END IF;
|
||||
|
||||
-- SHELTER
|
||||
IF array_length(in_data.in_building_shelter_data, 1) > 0 THEN
|
||||
WITH shelter_changes_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_shelter_data)
|
||||
)
|
||||
UPDATE building_instances SET shelter = shelter_changes_table.shelter
|
||||
FROM shelter_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = shelter_changes_table.instance_id;
|
||||
END IF;
|
||||
|
||||
-- SAND BUILDUP
|
||||
IF array_length(in_data.in_building_sand_buildup_data, 1) > 0 THEN
|
||||
WITH sand_buildup_changes_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_sand_buildup_data)
|
||||
)
|
||||
UPDATE building_instances SET sand_buildup = sand_buildup_changes_table.sand_buildup
|
||||
FROM sand_buildup_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = sand_buildup_changes_table.instance_id;
|
||||
END IF;
|
||||
|
||||
-- BUILDING FLAGS
|
||||
IF array_length(in_data.in_building_building_flags_data, 1) > 0 THEN
|
||||
WITH building_flags_changes_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_building_flags_data)
|
||||
)
|
||||
UPDATE building_instances SET building_flags = building_flags_changes_table.building_flags
|
||||
FROM building_flags_changes_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = building_flags_changes_table.instance_id;
|
||||
END IF;
|
||||
|
||||
-- BUILDING TRANSFORM
|
||||
IF array_length(in_data.in_building_building_transform_data, 1) > 0 THEN
|
||||
WITH building_flags_transform_table AS
|
||||
(
|
||||
select * FROM unnest(in_data.in_building_building_transform_data)
|
||||
)
|
||||
UPDATE building_instances SET transform = building_flags_transform_table.transform
|
||||
FROM building_flags_transform_table
|
||||
WHERE building_instances.building_id = in_building_id AND building_instances.instance_id = building_flags_transform_table.instance_id;
|
||||
END IF;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,50 @@
|
||||
-- save_building_blueprint_copy(in_building_item_id bigint, in_building_blueprint_id bigint, in_building_blueprint_building_data dune.buildingblueprintpiecesaveitemcontainer[], in_building_blueprint_placeable_data dune.buildingblueprintplaceablesaveitemcontainer[], in_building_blueprint_pentashield_data dune.buildingblueprintpentashielditem[]) -> bigint
|
||||
-- oid: 58544 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_building_blueprint_copy(in_building_item_id bigint, in_building_blueprint_id bigint, in_building_blueprint_building_data dune.buildingblueprintpiecesaveitemcontainer[], in_building_blueprint_placeable_data dune.buildingblueprintplaceablesaveitemcontainer[], in_building_blueprint_pentashield_data dune.buildingblueprintpentashielditem[])
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
return_id BIGINT;
|
||||
BEGIN
|
||||
IF in_building_blueprint_id != 0 THEN
|
||||
DELETE FROM building_blueprints WHERE id = in_building_blueprint_id;
|
||||
END IF;
|
||||
|
||||
INSERT INTO building_blueprints(id, item_id, player_id, building_blueprint_map)
|
||||
VALUES(DEFAULT, in_building_item_id, NULL, '') RETURNING id INTO return_id;
|
||||
|
||||
-- All Building Pieces
|
||||
INSERT INTO building_blueprint_instances(building_blueprint_id, instance_id, building_type, transform, provides_stability, health, hologram)
|
||||
SELECT
|
||||
return_id,
|
||||
piece_data.instance_id,
|
||||
container_data.building_type,
|
||||
piece_data.transform,
|
||||
piece_data.provides_stability,
|
||||
piece_data.health,
|
||||
True
|
||||
FROM
|
||||
unnest(in_building_blueprint_building_data) AS container_data
|
||||
CROSS JOIN LATERAL unnest(container_data.building_pieces) AS piece_data;
|
||||
|
||||
-- All Placeables
|
||||
INSERT INTO building_blueprint_placeables(building_blueprint_id, placeable_id, building_type, transform, hologram)
|
||||
SELECT
|
||||
return_id,
|
||||
placeable_data.placeable_id,
|
||||
container_data.building_type,
|
||||
placeable_data.transform,
|
||||
True
|
||||
FROM
|
||||
unnest(in_building_blueprint_placeable_data) AS container_data
|
||||
CROSS JOIN LATERAL unnest(container_data.placeables) AS placeable_data;
|
||||
|
||||
-- Pentashields
|
||||
INSERT INTO building_blueprint_pentashields("building_blueprint_id", "placeable_id", "scale")
|
||||
SELECT return_id as building_blueprint_id, placeable_id, scale FROM unnest(in_building_blueprint_pentashield_data);
|
||||
|
||||
RETURN return_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- save_placeable(in_placeable_id bigint, in_data dune.placeablesavedata) -> void
|
||||
-- oid: 58561 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_placeable(in_placeable_id bigint, in_data dune.placeablesavedata)
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
BEGIN ATOMIC
|
||||
INSERT INTO dune.placeables (id, owner_entity_id, health, building_type, has_hit_ground, has_buildable_support, is_hologram)
|
||||
VALUES (save_placeable.in_placeable_id, dune._placeable_validate_totem_owner_id((save_placeable.in_data).in_owner_entity_id), (save_placeable.in_data).in_health, (save_placeable.in_data).in_building_type, (save_placeable.in_data).in_has_hit_ground, (save_placeable.in_data).in_has_buildable_support, (save_placeable.in_data).in_is_hologram) ON CONFLICT(id) DO UPDATE SET owner_entity_id = excluded.owner_entity_id, health = excluded.health, building_type = excluded.building_type, has_hit_ground = excluded.has_hit_ground, has_buildable_support = excluded.has_buildable_support, is_hologram = excluded.is_hologram;
|
||||
END
|
||||
@@ -0,0 +1,10 @@
|
||||
-- save_totem(in_id bigint, in_data dune.totemsavedata) -> void
|
||||
-- oid: 58571 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.save_totem(in_id bigint, in_data dune.totemsavedata)
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
BEGIN ATOMIC
|
||||
INSERT INTO dune.totems (id, landclaim_vertical_level, last_backup_timestamp, landclaim_original_global_location, landclaim_original_global_yaw_rotation)
|
||||
VALUES (save_totem.in_id, (save_totem.in_data).landclaim_vertical_level, (save_totem.in_data).last_backup_timestamp, (save_totem.in_data).landclaim_original_global_location, (save_totem.in_data).landclaim_original_global_yaw_rotation) ON CONFLICT(id) DO UPDATE SET landclaim_vertical_level = excluded.landclaim_vertical_level, last_backup_timestamp = excluded.last_backup_timestamp, landclaim_original_global_location = excluded.landclaim_original_global_location, landclaim_original_global_yaw_rotation = excluded.landclaim_original_global_yaw_rotation;
|
||||
END
|
||||
@@ -0,0 +1,12 @@
|
||||
-- update_server_building_favorites(in_account_id bigint, in_building_types text[]) -> void
|
||||
-- oid: 58635 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_server_building_favorites(in_account_id bigint, in_building_types text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO building_favorites(account_id, building_types)
|
||||
VALUES(in_account_id, in_building_types)
|
||||
ON CONFLICT(account_id) DO UPDATE SET building_types = in_building_types WHERE building_favorites.account_id = in_account_id;
|
||||
END; $function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- update_server_learned_building_sets(in_account_id bigint, in_learned_building_sets text[]) -> void
|
||||
-- oid: 58636 kind: FUNCTION category: building_blueprint
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_server_learned_building_sets(in_account_id bigint, in_learned_building_sets text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO building_progression(account_id, learned_building_sets)
|
||||
VALUES(in_account_id, in_learned_building_sets)
|
||||
ON CONFLICT(account_id) DO UPDATE SET learned_building_sets = in_learned_building_sets WHERE building_progression.account_id = in_account_id;
|
||||
END; $function$
|
||||
@@ -0,0 +1,14 @@
|
||||
-- delete_character(in_actor_id bigint) -> void
|
||||
-- oid: 58210 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.delete_character(in_actor_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM actors WHERE id = in_actor_id;
|
||||
DELETE FROM properties WHERE object_id = in_actor_id;
|
||||
DELETE FROM fgl_data WHERE object_id = in_actor_id;
|
||||
DELETE FROM actor_transform WHERE actor_id = in_actor_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- initialize_specialization_keystones(in_keystones text[]) -> TABLE(keystone_id smallint, keystone_name text)
|
||||
-- oid: 58388 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.initialize_specialization_keystones(in_keystones text[])
|
||||
RETURNS TABLE(keystone_id smallint, keystone_name text)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
LOCK TABLE specialization_keystones_map IN SHARE ROW EXCLUSIVE MODE;
|
||||
|
||||
-- Note: we filter the existing values before the insert, otherwise it bumps the generated id in specialization_keystones_map
|
||||
INSERT INTO specialization_keystones_map (name)
|
||||
SELECT in_keystone_name FROM UNNEST(in_keystones) in_keystone_name LEFT JOIN specialization_keystones_map k ON in_keystone_name = k.name
|
||||
WHERE name IS NULL;
|
||||
RETURN QUERY SELECT * from specialization_keystones_map;
|
||||
END $function$
|
||||
@@ -0,0 +1,166 @@
|
||||
-- login_account(in_user_id text, in_funcom_id text, in_platform_id text, in_platform_name text, in_minimum_returning_player_time_seconds integer, in_character_name text, in_return_dimension_index integer, in_home_dimension_index integer) -> SETOF dune.playerdescription
|
||||
-- oid: 58471 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.login_account(in_user_id text, in_funcom_id text, in_platform_id text, in_platform_name text, in_minimum_returning_player_time_seconds integer, in_character_name text, in_return_dimension_index integer, in_home_dimension_index integer)
|
||||
RETURNS SETOF dune.playerdescription
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
user_account_id BigInt;
|
||||
BEGIN
|
||||
PERFORM update_returning_player_status(in_user_id, in_minimum_returning_player_time_seconds);
|
||||
|
||||
return query with
|
||||
acc as (
|
||||
INSERT INTO encrypted_accounts("id", "user", "platform_id", "platform_name", "encrypted_funcom_id")
|
||||
VALUES (default, in_user_id, in_platform_id, in_platform_name, encrypt_user_data(in_funcom_id))
|
||||
ON CONFLICT ("user") DO UPDATE SET
|
||||
encrypted_funcom_id = excluded.encrypted_funcom_id,
|
||||
platform_id = excluded.platform_id,
|
||||
platform_name = excluded.platform_name
|
||||
RETURNING id, encrypted_accounts.user
|
||||
),
|
||||
actor_ids as (
|
||||
-- TODO: unite this with accounts. One table to rule them all (until we want multiple chars per account)
|
||||
SELECT
|
||||
coalesce(player_controller_id, nextval('actors_id_seq')) as controller,
|
||||
coalesce(player_state_id, nextval('actors_id_seq')) as state,
|
||||
coalesce(player_pawn_id, nextval('actors_id_seq')) as pawn
|
||||
from acc left join player_state on player_state.account_id = acc.id
|
||||
),
|
||||
actors_insert as (
|
||||
INSERT INTO actors("id", "owner_account_id")
|
||||
select unnest(array[controller, pawn, state]), acc.id from actor_ids, acc
|
||||
ON CONFLICT DO NOTHING
|
||||
returning id
|
||||
),
|
||||
insert_actor_audit_log as (
|
||||
insert into actor_audit("id", "class")
|
||||
select
|
||||
unnest(array[controller, pawn, state]) as id,
|
||||
unnest(array['Controller', 'Pawn', 'State']) as clas
|
||||
from actor_ids
|
||||
on conflict do nothing
|
||||
),
|
||||
demo as (
|
||||
UPDATE demo_users
|
||||
SET demo_state = CASE
|
||||
WHEN demo_playtime_seconds IS NOT NULL THEN 'Demo'::DemoState
|
||||
ELSE demo_state
|
||||
END
|
||||
WHERE fls_id = in_user_id
|
||||
RETURNING fls_id, demo_playtime_seconds, demo_state
|
||||
),
|
||||
player_state_insert as (
|
||||
INSERT INTO encrypted_player_state(
|
||||
"account_id", "encrypted_character_name", "online_status",
|
||||
"player_controller_id", "player_pawn_id", "player_state_id",
|
||||
"return_dimension_index", "home_dimension_index", "last_login_time"
|
||||
)
|
||||
select
|
||||
id, case
|
||||
when in_character_name is not null then encrypt_user_data(in_character_name)
|
||||
when encrypted_player_state.encrypted_character_name is null then encrypt_user_data('<TEMP>')
|
||||
else encrypted_player_state.encrypted_character_name
|
||||
end,
|
||||
'Online', controller, pawn, state, in_return_dimension_index, in_home_dimension_index, now()
|
||||
from acc left join encrypted_player_state on acc.id = encrypted_player_state.account_id, actor_ids
|
||||
ON CONFLICT ("account_id")
|
||||
DO UPDATE SET
|
||||
online_status = 'Online',
|
||||
"return_dimension_index" = coalesce(in_return_dimension_index, encrypted_player_state.return_dimension_index),
|
||||
"home_dimension_index" = coalesce(in_home_dimension_index, encrypted_player_state.home_dimension_index),
|
||||
"last_login_time" = now()
|
||||
RETURNING
|
||||
account_id,
|
||||
"return_dimension_index",
|
||||
"home_dimension_index"
|
||||
),
|
||||
inserted_count_dummy as (
|
||||
select count(*) from actors_insert
|
||||
),
|
||||
player_actors as (
|
||||
select array_agg(full_actors.*) as actors
|
||||
from
|
||||
-- We need to refer 'returning' from inserts to ensure order of with statements
|
||||
inserted_count_dummy,
|
||||
actor_ids,
|
||||
load_full_actors(array[actor_ids.controller, actor_ids.state, actor_ids.pawn]) as full_actors
|
||||
),
|
||||
pawn_info as (
|
||||
select id, (map, partition_id, dimension_index)::ServerInfo as server_info
|
||||
from actor_ids join actors on actors.id=actor_ids.pawn
|
||||
),
|
||||
respawn_locations as (
|
||||
SELECT acc.id as account_id, get_respawn_locations(acc.id) as locations
|
||||
FROM acc
|
||||
),
|
||||
this_player_tags as (
|
||||
select
|
||||
acc.id as account_id,
|
||||
array_agg(tag) as tags
|
||||
from acc join player_tags as tgs on tgs.account_id=acc.id
|
||||
group by acc.id
|
||||
),
|
||||
keystones as (
|
||||
select player_id, array_agg(keystone_id) as purchased_keystones
|
||||
from purchased_specialization_keystones
|
||||
group by player_id
|
||||
),
|
||||
tracks as (
|
||||
select player_id, array_agg(track_info) as progression_tracks
|
||||
from (
|
||||
select player_id, (track_type, xp_amount, level)::SpecializationTrackInfo as track_info
|
||||
from specialization_tracks
|
||||
)
|
||||
group by player_id
|
||||
),
|
||||
journey_nodes as (
|
||||
SELECT acc.id as account_id, get_login_journey_nodes(acc.id) as journey_nodes_data
|
||||
FROM acc
|
||||
),
|
||||
journey_nodes_cooldown as (
|
||||
SELECT acc.id as account_id, get_login_journey_nodes_cooldown(acc.id) as journey_nodes_cooldown_data
|
||||
FROM acc
|
||||
)
|
||||
select
|
||||
acc.id,
|
||||
player_actors.actors[1], player_actors.actors[2], player_actors.actors[3],
|
||||
coalesce(pawn_info.server_info, (null, null, null)::ServerInfo),
|
||||
(
|
||||
coalesce(respawn_locations.locations, array[]::RespawnLocation[]),
|
||||
player_state.pending_respawn_location_id
|
||||
)::RespawnInfo,
|
||||
coalesce(player_state.life_state, 'Alive'),
|
||||
coalesce(this_player_tags.tags, array[]::Text[]),
|
||||
player_state_insert.return_dimension_index,
|
||||
player_state.death_location,
|
||||
player_state_insert.home_dimension_index,
|
||||
demo.demo_state,
|
||||
demo.demo_playtime_seconds,
|
||||
(progression_tracks, purchased_keystones, refund_id)::SpecializationInfo,
|
||||
(
|
||||
coalesce(journey_nodes.journey_nodes_data, array[]::JourneyNodeInfo[]),
|
||||
coalesce(journey_nodes_cooldown.journey_nodes_cooldown_data, array[]::JourneyNodeCooldownInfo[]),
|
||||
coalesce(journey_tracked_cards.tracked_journey_card, ''),
|
||||
coalesce(journey_tracked_cards.tracked_landsraad_card, '')
|
||||
)::JourneyInfo,
|
||||
(player_state.last_returning_player_event_time AT TIME ZONE 'UTC')::TIMESTAMP,
|
||||
(player_state.last_returning_player_awarded_time AT TIME ZONE 'UTC')::TIMESTAMP
|
||||
from
|
||||
acc left join player_state on player_state.account_id = acc.id
|
||||
left join respawn_locations on respawn_locations.account_id = acc.id
|
||||
left join this_player_tags on this_player_tags.account_id = acc.id
|
||||
left join player_state_insert on player_state_insert.account_id = acc.id
|
||||
left join demo on demo.fls_id = acc.user
|
||||
left join journey_nodes on journey_nodes.account_id = acc.id
|
||||
left join journey_nodes_cooldown on journey_nodes_cooldown.account_id = acc.id
|
||||
left join journey_tracked_cards on journey_tracked_cards.player_id = player_state.player_controller_id
|
||||
left join keystones on keystones.player_id = player_state.player_controller_id
|
||||
left join tracks on tracks.player_id = player_state.player_controller_id
|
||||
left join specialization_refund_id on specialization_refund_id.player_id = player_state.player_controller_id,
|
||||
|
||||
player_actors left join pawn_info on (player_actors.actors[3].id = pawn_info.id)
|
||||
limit 1;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,28 @@
|
||||
-- permission_set_player_rank(in_actor_id bigint, in_player_id bigint, in_rank smallint, in_map_id text) -> void
|
||||
-- oid: 58493 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.permission_set_player_rank(in_actor_id bigint, in_player_id bigint, in_rank smallint, in_map_id text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
found_actor_id BIGINT;
|
||||
found_guild_id BIGINT;
|
||||
BEGIN
|
||||
SELECT permission_actor_id FROM permission_actor_rank WHERE permission_actor_id = in_actor_id AND player_id = in_player_id INTO found_actor_id;
|
||||
IF NOT FOUND THEN
|
||||
INSERT INTO permission_actor_rank("permission_actor_id", "player_id", "rank") VALUES(in_actor_id, in_player_id, in_rank);
|
||||
ELSE
|
||||
UPDATE permission_actor_rank SET rank = in_rank WHERE permission_actor_rank.permission_actor_id = in_actor_id AND player_id = in_player_id;
|
||||
END IF;
|
||||
|
||||
SELECT guild_id FROM guild_members WHERE player_id = in_actor_id INTO found_guild_id;
|
||||
IF NOT FOUND THEN
|
||||
found_guild_id := 0;
|
||||
END IF;
|
||||
|
||||
PERFORM permission_actor_create_or_update_base_marker(in_actor_id, in_player_id, in_rank);
|
||||
|
||||
PERFORM pg_notify('permission_notify_channel', format('set_rank#{"ActorId" : %s , "PlayerId" : %s, "PlayerGuildId" : %s, "Rank" : %s, "Map" : %s}', in_actor_id, in_player_id, found_guild_id, in_rank, in_map_id));
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,47 @@
|
||||
-- player_state_update(in_data dune.playerstateupdatedata[]) -> void
|
||||
-- oid: 58495 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.player_state_update(in_data dune.playerstateupdatedata[])
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
-- online -> offline
|
||||
with
|
||||
update_data as (select * from unnest(in_data))
|
||||
update encrypted_player_state as ps
|
||||
set online_status = update_data.online_status
|
||||
from update_data
|
||||
where ps.player_controller_id = update_data.player_controller_id
|
||||
and ps.server_id = update_data.current_server_id -- make sure we don't update if the player is already online somewhere else
|
||||
and update_data.online_status != 'Online'
|
||||
and ps.online_status != update_data.online_status; -- avoid unnecessary data changes
|
||||
|
||||
-- offline -> online
|
||||
with
|
||||
update_data as (select * from unnest(in_data))
|
||||
update encrypted_player_state as ps
|
||||
set online_status = update_data.online_status,
|
||||
server_id = update_data.current_server_id
|
||||
from update_data
|
||||
where ps.player_controller_id = update_data.player_controller_id
|
||||
and update_data.online_status = 'Online'
|
||||
and (ps.server_id is null or ps.server_id != update_data.current_server_id or ps.online_status != update_data.online_status); -- avoid unnecessary data changes
|
||||
|
||||
with
|
||||
update_data as (select * from unnest(in_data))
|
||||
update encrypted_player_state as ps
|
||||
set reconnect_grace_period_end = update_data.reconnect_grace_period_end
|
||||
from update_data
|
||||
where ps.player_controller_id = update_data.player_controller_id
|
||||
and not update_data.reconnect_grace_period_end is null;
|
||||
|
||||
with
|
||||
update_data as (select * from unnest(in_data))
|
||||
update encrypted_player_state as ps
|
||||
set
|
||||
last_avatar_activity = (update_data.on_disconnect).last_online_time AT TIME ZONE 'UTC',
|
||||
previous_server_partition_id = (update_data.on_disconnect).previous_server_partition_id
|
||||
from update_data
|
||||
where ps.player_controller_id = update_data.player_controller_id
|
||||
and not update_data.on_disconnect is null;
|
||||
$function$
|
||||
@@ -0,0 +1,26 @@
|
||||
-- purchase_specialization_keystone(in_player_id bigint, in_keystone text) -> boolean
|
||||
-- oid: 58501 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.purchase_specialization_keystone(in_player_id bigint, in_keystone text)
|
||||
RETURNS boolean
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
found_id SMALLINT;
|
||||
inserted_id SMALLINT;
|
||||
BEGIN
|
||||
SELECT id FROM specialization_keystones_map INTO found_id WHERE name = in_keystone;
|
||||
IF found_id IS NULL THEN
|
||||
RETURN FALSE;
|
||||
END IF;
|
||||
|
||||
INSERT INTO purchased_specialization_keystones (player_id, keystone_id) VALUES (in_player_id, found_id)
|
||||
ON CONFLICT DO NOTHING
|
||||
RETURNING keystone_id INTO inserted_id;
|
||||
|
||||
IF inserted_id IS NULL THEN
|
||||
RETURN FALSE;
|
||||
END IF;
|
||||
|
||||
RETURN TRUE;
|
||||
END $function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- reset_specialization_keystones(in_player_id bigint) -> void
|
||||
-- oid: 58532 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.reset_specialization_keystones(in_player_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM purchased_specialization_keystones WHERE player_id = in_player_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- reset_specialization_tracks(in_player_id bigint) -> void
|
||||
-- oid: 58533 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.reset_specialization_tracks(in_player_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM specialization_tracks WHERE player_id = in_player_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,9 @@
|
||||
-- returning_player_award_given(in_account_id bigint) -> void
|
||||
-- oid: 58537 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.returning_player_award_given(in_account_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
UPDATE player_state SET last_returning_player_awarded_time=now(), last_returning_player_event_time=NULL WHERE account_id=in_account_id;
|
||||
$function$
|
||||
@@ -0,0 +1,15 @@
|
||||
-- set_character_import_state(in_fls_id text, in_state dune.transferimportstate) -> void
|
||||
-- oid: 58590 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.set_character_import_state(in_fls_id text, in_state dune.transferimportstate)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO character_transfer_imports (fls_id, last_update, transfer_state)
|
||||
VALUES (in_fls_id, now(), in_state)
|
||||
ON CONFLICT (fls_id) DO UPDATE
|
||||
SET last_update = now(),
|
||||
transfer_state = EXCLUDED.transfer_state;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,9 @@
|
||||
-- set_character_name(in_account_id bigint, in_name text) -> void
|
||||
-- oid: 58591 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.set_character_name(in_account_id bigint, in_name text)
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
update encrypted_player_state set encrypted_character_name=encrypt_user_data(in_name) where account_id=in_account_id;
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- set_players_from_server_ids_offline(in_server_ids text[]) -> void
|
||||
-- oid: 58595 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.set_players_from_server_ids_offline(in_server_ids text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
UPDATE player_state SET online_status = 'Offline', last_avatar_activity = current_timestamp WHERE online_status <> 'Offline' AND server_id = ANY(in_server_ids);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- set_specialization_xp_and_level(in_player_id bigint, in_track_type dune.specializationtracktype, in_xp_amount integer, in_level real) -> void
|
||||
-- oid: 58596 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.set_specialization_xp_and_level(in_player_id bigint, in_track_type dune.specializationtracktype, in_xp_amount integer, in_level real)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO specialization_tracks (player_id, track_type, xp_amount, level) VALUES (in_player_id, in_track_type, in_xp_amount, in_level)
|
||||
ON CONFLICT(player_id, track_type) DO UPDATE SET xp_amount = in_xp_amount, level = in_level;
|
||||
END $function$
|
||||
@@ -0,0 +1,10 @@
|
||||
-- update_player_tags(in_account_id bigint, tags_to_add text[], tags_to_remove text[]) -> void
|
||||
-- oid: 58629 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_player_tags(in_account_id bigint, tags_to_add text[], tags_to_remove text[])
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
insert into player_tags("account_id", "tag") select in_account_id, unnest(tags_to_add) on conflict do nothing;
|
||||
delete from player_tags where account_id = in_account_id and tag = ANY(tags_to_remove);
|
||||
$function$
|
||||
@@ -0,0 +1,26 @@
|
||||
-- update_returning_player_status(in_user_id text, in_minimum_returning_player_time_seconds integer) -> void
|
||||
-- oid: 58633 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_returning_player_status(in_user_id text, in_minimum_returning_player_time_seconds integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
user_account_id BigInt;
|
||||
last_login_time TIMESTAMPTZ;
|
||||
last_award_time TIMESTAMPTZ;
|
||||
BEGIN
|
||||
SELECT INTO user_account_id, last_login_time, last_award_time id, ps.last_login_time, ps.last_returning_player_awarded_time
|
||||
FROM accounts acc
|
||||
JOIN player_state ps ON ps.account_id = acc.id
|
||||
WHERE acc.user=in_user_id;
|
||||
|
||||
IF user_account_id IS NOT NULL THEN
|
||||
IF last_award_time + INTERVAL '1 second' * in_minimum_returning_player_time_seconds > CURRENT_TIMESTAMP THEN
|
||||
UPDATE player_state SET last_returning_player_event_time=NULL WHERE account_id=user_account_id;
|
||||
ELSIF last_login_time + INTERVAL '1 second' * in_minimum_returning_player_time_seconds < CURRENT_TIMESTAMP THEN
|
||||
UPDATE player_state SET last_returning_player_event_time=now() WHERE account_id=user_account_id;
|
||||
END IF;
|
||||
END IF;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- update_specialization_refund_id(in_player_id bigint, in_refund_id smallint, in_removed_keystones smallint[]) -> void
|
||||
-- oid: 58638 kind: FUNCTION category: character_mod
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_specialization_refund_id(in_player_id bigint, in_refund_id smallint, in_removed_keystones smallint[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM purchased_specialization_keystones WHERE player_id = in_player_id AND keystone_id = ANY(in_removed_keystones);
|
||||
|
||||
INSERT INTO specialization_refund_id (player_id, refund_id) VALUES(in_player_id, in_refund_id)
|
||||
ON conflict (player_id) DO UPDATE SET refund_id = in_refund_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- cleanup_orphaned_entities() -> trigger
|
||||
-- oid: 58173 kind: FUNCTION category: cleanup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.cleanup_orphaned_entities()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM fgl_entities WHERE fgl_entities.entity_id = OLD.entity_id;
|
||||
RETURN NULL;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- reset_all_players_from_server_ids_grace_period_and_logoff_timer(in_server_id text, in_reset_time timestamp without time zone) -> void
|
||||
-- oid: 58528 kind: FUNCTION category: cleanup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.reset_all_players_from_server_ids_grace_period_and_logoff_timer(in_server_id text, in_reset_time timestamp without time zone)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
UPDATE encrypted_player_state SET reconnect_grace_period_end = in_reset_time WHERE server_id = in_server_id AND reconnect_grace_period_end > in_reset_time;
|
||||
UPDATE encrypted_player_state SET logoff_persistence_end_time = in_reset_time WHERE server_id = in_server_id AND logoff_persistence_end_time > in_reset_time;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- reset_server_all_player_access_codes(in_account_id bigint) -> void
|
||||
-- oid: 58531 kind: FUNCTION category: cleanup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.reset_server_all_player_access_codes(in_account_id bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM player_access_codes
|
||||
WHERE account_id = in_account_id
|
||||
AND is_resettable = true;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- wipe_old_events_log(in_days_limit integer) -> void
|
||||
-- oid: 58650 kind: FUNCTION category: cleanup
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.wipe_old_events_log(in_days_limit integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM game_events WHERE universe_time < to_timestamp(in_days_limit);
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,14 @@
|
||||
-- load_communinet_player_data(in_account_id bigint) -> TABLE(is_active boolean, selected_channel_name text, channel_name text, is_tuned boolean)
|
||||
-- oid: 58450 kind: FUNCTION category: communinet
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.load_communinet_player_data(in_account_id bigint)
|
||||
RETURNS TABLE(is_active boolean, selected_channel_name text, channel_name text, is_tuned boolean)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT cp.is_active, cp.selected_channel_name, cpc.channel_name, cpc.is_tuned
|
||||
FROM communinet_player AS cp JOIN communinet_player_channels as cpc
|
||||
ON cp.account_id = cpc.account_id
|
||||
WHERE cpc.account_id = in_account_id;
|
||||
END; $function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- remove_communinet_player_channel(in_account_id bigint, in_channel_name text) -> void
|
||||
-- oid: 58517 kind: FUNCTION category: communinet
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.remove_communinet_player_channel(in_account_id bigint, in_channel_name text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM communinet_player_channels WHERE account_id = in_account_id AND channel_name = in_channel_name;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- update_communinet_player_channel(in_account_id bigint, in_channel_name text, in_is_tuned boolean) -> void
|
||||
-- oid: 58615 kind: FUNCTION category: communinet
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_communinet_player_channel(in_account_id bigint, in_channel_name text, in_is_tuned boolean)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO communinet_player_channels(account_id, channel_name, is_tuned) VALUES (in_account_id, in_channel_name, in_is_tuned)
|
||||
ON CONFLICT(account_id, channel_name) DO UPDATE SET is_tuned = in_is_tuned WHERE communinet_player_channels.account_id = in_account_id AND communinet_player_channels.channel_name = in_channel_name;
|
||||
END $function$
|
||||
@@ -0,0 +1,11 @@
|
||||
-- update_communinet_player_data(in_account_id bigint, in_is_active boolean, in_selected_channel_name text) -> void
|
||||
-- oid: 58616 kind: FUNCTION category: communinet
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.update_communinet_player_data(in_account_id bigint, in_is_active boolean, in_selected_channel_name text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
INSERT INTO communinet_player(account_id, is_active, selected_channel_name) VALUES (in_account_id, in_is_active, in_selected_channel_name)
|
||||
ON CONFLICT(account_id) DO UPDATE SET is_active = in_is_active, selected_channel_name = in_selected_channel_name WHERE communinet_player.account_id = in_account_id;
|
||||
END $function$
|
||||
@@ -0,0 +1,46 @@
|
||||
-- adjust_player_virtual_currency_balance(in_controller_id bigint, in_currency_id smallint, in_delta bigint) -> bigint
|
||||
-- oid: 58129 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.adjust_player_virtual_currency_balance(in_controller_id bigint, in_currency_id smallint, in_delta bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_balance BIGINT;
|
||||
current_delta BIGINT;
|
||||
new_delta BIGINT;
|
||||
fls_id TEXT;
|
||||
function_oid oid;
|
||||
BEGIN
|
||||
SELECT INTO current_balance balance from player_virtual_currency_balances WHERE player_controller_id = in_controller_id AND currency_id = in_currency_id;
|
||||
INSERT INTO player_virtual_currency_balances("player_controller_id", "currency_id", "balance")
|
||||
VALUES (in_controller_id, in_currency_id, in_delta)
|
||||
ON CONFLICT (player_controller_id, currency_id) DO UPDATE SET balance = (player_virtual_currency_balances.balance + in_delta)
|
||||
RETURNING balance INTO current_balance;
|
||||
|
||||
IF in_currency_id = get_solaris_id() THEN
|
||||
GET DIAGNOSTICS function_oid = PG_ROUTINE_OID;
|
||||
PERFORM log_event_solaris(function_oid, 'update_solaris', in_controller_id, current_balance, in_delta);
|
||||
END IF;
|
||||
|
||||
current_delta = 0;
|
||||
IF current_balance < 0 THEN
|
||||
SELECT acc."user"
|
||||
INTO fls_id
|
||||
FROM accounts acc
|
||||
JOIN player_state ps on ps.account_id = acc.id
|
||||
WHERE ps.account_id = in_player_id
|
||||
LIMIT 1;
|
||||
|
||||
PERFORM log_cheating(COALESCE(fls_id, in_player_id::text), 'negative_solaris');
|
||||
|
||||
INSERT INTO player_virtual_currency_balances("player_controller_id", "currency_id", "balance")
|
||||
VALUES (in_controller_id, in_currency_id, 0)
|
||||
ON CONFLICT (player_controller_id, currency_id) DO UPDATE SET balance = 0;
|
||||
current_delta = current_balance;
|
||||
END IF;
|
||||
|
||||
new_delta = in_delta + current_delta;
|
||||
RETURN new_delta;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,43 @@
|
||||
-- dune_exchange_modify_user_solari_balance(in_controller_id bigint, in_solari_delta bigint) -> void
|
||||
-- oid: 58248 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.dune_exchange_modify_user_solari_balance(in_controller_id bigint, in_solari_delta bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
user_id BIGINT;
|
||||
current_balance BIGINT;
|
||||
new_balance BIGINT;
|
||||
delta_balance BIGINT;
|
||||
fls_id TEXT;
|
||||
function_oid oid;
|
||||
BEGIN
|
||||
SELECT INTO user_id dune_exchange_get_user_id(in_controller_id);
|
||||
SELECT INTO current_balance balance from player_virtual_currency_balances WHERE currency_id = get_solaris_id() AND player_controller_id = in_controller_id;
|
||||
|
||||
IF current_balance < 0 THEN
|
||||
SELECT acc."user"
|
||||
INTO fls_id
|
||||
FROM accounts acc
|
||||
JOIN player_state ps on ps.account_id = acc.id
|
||||
WHERE ps.player_controller_id = in_controller_id
|
||||
LIMIT 1;
|
||||
|
||||
PERFORM log_cheating(COALESCE(fls_id, in_controller_id::text), 'exchange_negative_solaris');
|
||||
UPDATE player_virtual_currency_balances SET balance = 0 WHERE currency_id = get_solaris_id() AND player_controller_id = in_controller_id;
|
||||
current_balance = 0;
|
||||
END IF;
|
||||
|
||||
delta_balance = in_solari_delta;
|
||||
IF current_balance < in_solari_delta THEN
|
||||
delta_balance = current_balance;
|
||||
END IF;
|
||||
|
||||
UPDATE dune_exchange_users SET solari_balance = solari_balance + delta_balance WHERE id = user_id;
|
||||
|
||||
UPDATE player_virtual_currency_balances SET balance = balance - delta_balance WHERE currency_id = get_solaris_id() AND player_controller_id = in_controller_id RETURNING player_virtual_currency_balances.balance INTO new_balance;
|
||||
|
||||
GET DIAGNOSTICS function_oid = PG_ROUTINE_OID;
|
||||
PERFORM log_event_solaris(function_oid, 'update_solaris', in_controller_id, new_balance, delta_balance);
|
||||
END $function$
|
||||
@@ -0,0 +1,27 @@
|
||||
-- dune_exchange_retrieve_solari_balance(in_owner_id bigint) -> bigint
|
||||
-- oid: 58253 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.dune_exchange_retrieve_solari_balance(in_owner_id bigint)
|
||||
RETURNS bigint
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
current_balance BIGINT;
|
||||
fls_id TEXT;
|
||||
BEGIN
|
||||
SELECT INTO current_balance solari_balance from dune_exchange_users WHERE owner_id = in_owner_id LIMIT 1;
|
||||
|
||||
IF current_balance < 0 THEN
|
||||
SELECT acc."user"
|
||||
INTO fls_id
|
||||
FROM accounts acc
|
||||
JOIN player_state ps on ps.account_id = acc.id
|
||||
WHERE ps.player_controller_id = in_owner_id
|
||||
LIMIT 1;
|
||||
|
||||
PERFORM log_cheating(COALESCE(fls_id, in_owner_id::text), 'exchange_negative_solaris');
|
||||
|
||||
UPDATE dune_exchange_users SET solari_balance = 0 WHERE owner_id = in_owner_id;
|
||||
END IF;
|
||||
RETURN (SELECT solari_balance FROM dune_exchange_users WHERE owner_id = in_owner_id LIMIT 1);
|
||||
END; $function$
|
||||
@@ -0,0 +1,41 @@
|
||||
-- dune_exchange_retrieve_solaris_from_item(in_controller_id bigint, in_order_id bigint) -> dune.duneexchangeretrievesolarisfromitemresult
|
||||
-- oid: 58254 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.dune_exchange_retrieve_solaris_from_item(in_controller_id bigint, in_order_id bigint)
|
||||
RETURNS dune.duneexchangeretrievesolarisfromitemresult
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
result DuneExchangeRetrieveSolarisFromItemResult;
|
||||
new_balance BIGINT;
|
||||
function_oid oid;
|
||||
BEGIN
|
||||
WITH
|
||||
delete_orders_prices AS (
|
||||
DELETE FROM dune_exchange_orders
|
||||
USING dune_exchange_fulfilled_orders
|
||||
WHERE (dune_exchange_orders.id = dune_exchange_fulfilled_orders.order_id)
|
||||
AND id = in_order_id AND (item_id IS NULL OR item_id = 0)
|
||||
RETURNING item_price * dune_exchange_fulfilled_orders.stack_size AS total_price
|
||||
),
|
||||
total_price AS (
|
||||
SELECT SUM(total_price) AS delta FROM delete_orders_prices
|
||||
)
|
||||
UPDATE player_virtual_currency_balances
|
||||
SET balance = balance + total_price.delta
|
||||
FROM total_price
|
||||
WHERE currency_id = get_solaris_id() AND player_controller_id = in_controller_id
|
||||
RETURNING
|
||||
player_virtual_currency_balances.balance,
|
||||
total_price.delta,
|
||||
(SELECT original_order_id FROM dune_exchange_fulfilled_orders WHERE order_id = in_order_id)
|
||||
INTO
|
||||
new_balance,
|
||||
result.total_item_value,
|
||||
result.original_order_id;
|
||||
|
||||
GET DIAGNOSTICS function_oid = PG_ROUTINE_OID;
|
||||
PERFORM log_event_solaris(function_oid, 'update_solaris', in_controller_id, new_balance, result.total_item_value);
|
||||
|
||||
RETURN result;
|
||||
END $function$
|
||||
@@ -0,0 +1,23 @@
|
||||
-- edit_guild_description(in_guild_id bigint, in_guild_desc text) -> void
|
||||
-- oid: 58258 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.edit_guild_description(in_guild_id bigint, in_guild_desc text)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
out_guild_description TEXT;
|
||||
BEGIN
|
||||
PERFORM guilds_get_exclusive_operation_lock();
|
||||
|
||||
-- check if guild exists
|
||||
SELECT guild_description INTO out_guild_description FROM guilds WHERE guild_id = in_guild_id;
|
||||
IF NOT FOUND THEN
|
||||
RAISE EXCEPTION 'Trying to add invite to non existing guild %.', in_guild_id;
|
||||
END IF;
|
||||
|
||||
UPDATE guilds SET guild_description = in_guild_desc WHERE guilds.guild_id = in_guild_id;
|
||||
|
||||
PERFORM pg_notify('guild_notify_channel', format('edit_guild_description#{"GuildId" : %s}', in_guild_id));
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,18 @@
|
||||
-- get_player_virtual_currency_balances(in_controller_id bigint) -> TABLE(out_currency_id smallint, out_currency_balance bigint)
|
||||
-- oid: 58345 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_player_virtual_currency_balances(in_controller_id bigint)
|
||||
RETURNS TABLE(out_currency_id smallint, out_currency_balance bigint)
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
return query (
|
||||
with currencies as (select currency_id, balance from player_virtual_currency_balances where player_controller_id = in_controller_id),
|
||||
bad_currencies as (select * from currencies where balance < 0),
|
||||
target_account_id as (select account_id from player_state where player_controller_id = in_controller_id limit 1),
|
||||
report_cheaters as (select currency_id, flag_player_as_cheater(target_account_id.account_id, 'negative_solaris') from bad_currencies, target_account_id),
|
||||
fix_bad_currencies as (update player_virtual_currency_balances set balance = 0 from report_cheaters where player_controller_id = in_controller_id and player_virtual_currency_balances.currency_id = report_cheaters.currency_id)
|
||||
select currency_id, balance from currencies
|
||||
);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,14 @@
|
||||
-- get_solaris_id() -> smallint
|
||||
-- oid: 58351 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.get_solaris_id()
|
||||
RETURNS smallint
|
||||
LANGUAGE plpgsql
|
||||
IMMUTABLE
|
||||
AS $function$
|
||||
DECLARE
|
||||
solaris_id CONSTANT SMALLINT := 0;
|
||||
BEGIN
|
||||
return solaris_id;
|
||||
END
|
||||
$function$
|
||||
@@ -0,0 +1,48 @@
|
||||
-- log_event_solaris(in_function_oid oid, in_message dune.logmessagetype, in_controller_id bigint, in_solaris_balance bigint, in_solaris_delta bigint) -> void
|
||||
-- oid: 58470 kind: FUNCTION category: currency
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.log_event_solaris(in_function_oid oid, in_message dune.logmessagetype, in_controller_id bigint, in_solaris_balance bigint, in_solaris_delta bigint)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
DECLARE
|
||||
partition_id BIGINT = 0;
|
||||
calling_function_name LogFunctionType;
|
||||
fls_id TEXT;
|
||||
fc_id BYTEA;
|
||||
char_name BYTEA;
|
||||
BEGIN
|
||||
|
||||
partition_id := coalesce(current_setting('dune.partition_id', true)::BIGINT, 0);
|
||||
|
||||
-- map calling function name to LogFunctionType (each calling function must be added to LogFunctionType)
|
||||
SELECT proname::text::LogFunctionType
|
||||
INTO calling_function_name
|
||||
FROM pg_proc
|
||||
WHERE oid = in_function_oid;
|
||||
|
||||
-- get the fls_id for the user performing the acction
|
||||
SELECT acc."user"
|
||||
INTO fls_id
|
||||
FROM accounts acc
|
||||
JOIN player_state ps on ps.account_id = acc.id
|
||||
WHERE ps.player_controller_id = in_controller_id
|
||||
LIMIT 1;
|
||||
|
||||
INSERT INTO event_log (
|
||||
partition_id,
|
||||
category,
|
||||
function_name,
|
||||
message,
|
||||
event_time,
|
||||
meta
|
||||
) VALUES (
|
||||
partition_id,
|
||||
'solaris',
|
||||
calling_function_name,
|
||||
in_message,
|
||||
now(),
|
||||
json_build_object('fls_id', fls_id, 'event', calling_function_name::text, 'solaris_balance', in_solaris_balance, 'solaris_delta', in_solaris_delta)
|
||||
);
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,9 @@
|
||||
-- debug_add_test_table_data(in_entry text) -> void
|
||||
-- oid: 58187 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_add_test_table_data(in_entry text)
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
insert into debug_test_table("entry") VALUES (in_entry);
|
||||
$function$
|
||||
@@ -0,0 +1,9 @@
|
||||
-- debug_collect_test_table_data() -> SETOF text
|
||||
-- oid: 58188 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_collect_test_table_data()
|
||||
RETURNS SETOF text
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
select entry from debug_test_table;
|
||||
$function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- debug_echo(in_text text, in_notices text[]) -> text
|
||||
-- oid: 58189 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_echo(in_text text, in_notices text[])
|
||||
RETURNS text
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
perform debug_raise_notices(in_notices);
|
||||
return in_text;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,42 @@
|
||||
-- debug_get_coriolis_seeds() -> TABLE(farm_seed integer, map_names text[], map_seeds integer[], partitions_ids bigint[], partitions_map text[], partitions_seeds integer[])
|
||||
-- oid: 58190 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_get_coriolis_seeds()
|
||||
RETURNS TABLE(farm_seed integer, map_names text[], map_seeds integer[], partitions_ids bigint[], partitions_map text[], partitions_seeds integer[])
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
RETURN QUERY
|
||||
WITH
|
||||
map_seeds as (
|
||||
SELECT array_agg(map_name) as map_name, array_agg(seed) as seed
|
||||
FROM (
|
||||
SELECT COALESCE(map_seed.map, partition.map) AS map_name, COALESCE(map_seed.world_reset_seed, -1) AS seed
|
||||
FROM world_map_reset_seed AS map_seed FULL JOIN world_partition as partition ON map_seed.map = partition.map
|
||||
GROUP BY map_seed.map, partition.map, map_seed.world_reset_seed
|
||||
ORDER BY map_name ASC
|
||||
) as maps_temp
|
||||
|
||||
),
|
||||
partitions_seeds as (
|
||||
SELECT array_agg(partition_id) as partition_id, array_agg(map_name) as map_name, array_agg(seed) as seed
|
||||
FROM (
|
||||
SELECT partition.partition_id as partition_id, partition.map as map_name, COALESCE(partition_seed.world_reset_seed, -1) AS seed
|
||||
FROM world_partition_reset_seed AS partition_seed FULL JOIN world_partition as partition ON partition_seed.partition_id = partition.partition_id
|
||||
GROUP BY partition.map, partition.partition_id, partition_seed.world_reset_seed
|
||||
ORDER BY partition.partition_id ASC
|
||||
) as partitions_temp
|
||||
)
|
||||
SELECT
|
||||
COALESCE(world_reset_seed, -1),
|
||||
COALESCE(map_seeds.map_name, array[]::TEXT[]),
|
||||
COALESCE(map_seeds.seed, array[]::Integer[]),
|
||||
COALESCE(partitions_seeds.partition_id, array[]::BigInt[]),
|
||||
COALESCE(partitions_seeds.map_name, array[]::TEXT[]),
|
||||
COALESCE(partitions_seeds.seed, array[]::Integer[])
|
||||
FROM
|
||||
world_farm_reset_seed,
|
||||
map_seeds,
|
||||
partitions_seeds;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,12 @@
|
||||
-- debug_raise_exception(in_exception text, in_notices text[]) -> void
|
||||
-- oid: 58191 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_raise_exception(in_exception text, in_notices text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
perform debug_raise_notices(in_notices);
|
||||
RAISE EXCEPTION '%', in_exception;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,16 @@
|
||||
-- debug_raise_notices(in_notices text[]) -> void
|
||||
-- oid: 58192 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_raise_notices(in_notices text[])
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
BEGIN
|
||||
IF array_length(in_notices, 1) IS NOT NULL THEN
|
||||
FOR i IN 0..array_length(in_notices, 1)-1
|
||||
LOOP
|
||||
RAISE NOTICE '%', in_notices[i];
|
||||
END LOOP;
|
||||
END IF;
|
||||
END;
|
||||
$function$
|
||||
@@ -0,0 +1,9 @@
|
||||
-- debug_reset_test_table() -> void
|
||||
-- oid: 58193 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_reset_test_table()
|
||||
RETURNS void
|
||||
LANGUAGE sql
|
||||
AS $function$
|
||||
truncate debug_test_table;
|
||||
$function$
|
||||
@@ -0,0 +1,21 @@
|
||||
-- debug_set_farm_seed(in_new_coriolis_seed integer) -> void
|
||||
-- oid: 58194 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_set_farm_seed(in_new_coriolis_seed integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
UPDATE world_farm_reset_seed SET world_reset_seed = in_new_coriolis_seed WHERE onerow_id = TRUE;
|
||||
|
||||
UPDATE world_map_reset_seed SET world_reset_seed = in_new_coriolis_seed;
|
||||
INSERT INTO world_map_reset_seed SELECT map, in_new_coriolis_seed FROM world_partition GROUP BY map
|
||||
ON CONFLICT(map) DO
|
||||
UPDATE SET world_reset_seed = in_new_coriolis_seed;
|
||||
|
||||
UPDATE world_partition_reset_seed SET world_reset_seed = in_new_coriolis_seed;
|
||||
INSERT INTO world_partition_reset_seed SELECT partition_id, in_new_coriolis_seed FROM world_partition GROUP BY partition_id
|
||||
ON CONFLICT(partition_id) DO
|
||||
UPDATE SET world_reset_seed = in_new_coriolis_seed;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,18 @@
|
||||
-- debug_set_map_seed(in_map text, in_new_coriolis_seed integer) -> void
|
||||
-- oid: 58195 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_set_map_seed(in_map text, in_new_coriolis_seed integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
INSERT INTO world_map_reset_seed (map, world_reset_seed) Values(in_server_info.map, in_new_coriolis_seed)
|
||||
ON CONFLICT(map) DO
|
||||
UPDATE SET world_reset_seed = in_new_coriolis_seed;
|
||||
|
||||
UPDATE world_partition_reset_seed SET world_reset_seed = in_new_coriolis_seed WHERE map = in_map;
|
||||
INSERT INTO world_partition_reset_seed SELECT partition_id, in_new_coriolis_seed FROM world_partition WHERE map = in_map GROUP BY partition_id
|
||||
ON CONFLICT(partition_id) DO
|
||||
UPDATE SET world_reset_seed = in_new_coriolis_seed;
|
||||
end
|
||||
$function$
|
||||
@@ -0,0 +1,13 @@
|
||||
-- debug_set_partition_seed(in_partition_id bigint, in_new_coriolis_seed integer) -> void
|
||||
-- oid: 58196 kind: FUNCTION category: debug
|
||||
|
||||
CREATE OR REPLACE FUNCTION dune.debug_set_partition_seed(in_partition_id bigint, in_new_coriolis_seed integer)
|
||||
RETURNS void
|
||||
LANGUAGE plpgsql
|
||||
AS $function$
|
||||
begin
|
||||
INSERT INTO world_partition_reset_seed (partition_id, world_reset_seed) Values(in_server_info.partition_id, in_new_coriolis_seed)
|
||||
ON CONFLICT(partition_id) DO
|
||||
UPDATE SET world_reset_seed = in_new_coriolis_seed;
|
||||
end
|
||||
$function$
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user