mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-29 16:10:02 +01:00
# Summary This PR adds a new admin panel for persistence. ## Contents - The panel features information about the current round and detailed tracking of objects, records and generics. - The previously introduced toggle-persistence verb has been removed and integrated into the new panel. - The panel can be seen by admins, mods and devs, but the toggle-persistence is still locked to admin permissions only. ## Preview The images are WIP and subject to change. <img width="918" height="229" alt="image" src="https://github.com/user-attachments/assets/16d3d73d-32e6-4907-bdff-d96699c27d49" /> <img width="919" height="253" alt="image" src="https://github.com/user-attachments/assets/92e7f4d9-ccd4-4e79-949d-b8a35039da01" /> <img width="923" height="285" alt="image" src="https://github.com/user-attachments/assets/e3796504-4cc6-4fce-b5f1-4df3486bfbee" /> <img width="923" height="270" alt="image" src="https://github.com/user-attachments/assets/9fbb185d-181a-40ec-b89b-58eafcd47e4d" />
126 lines
5.2 KiB
Plaintext
126 lines
5.2 KiB
Plaintext
/*
|
|
* Persistence subsystem
|
|
* Subsytem for managing any form of persistent content across rounds.
|
|
*
|
|
* This subsystem consists of multiple partial files, split into different responsibilities:
|
|
* persistence.dm - Subsystem define and related code
|
|
* Objects and types (with Generics and History respectively), each containing:
|
|
* Base file (no suffix), public procs (_public.dm suffix), SQL code (_sql.dm suffix)
|
|
*/
|
|
|
|
SUBSYSTEM_DEF(persistence)
|
|
name = "Persistence"
|
|
init_order = INIT_ORDER_PERSISTENCE // The order is tied with the init and maploading subsystem.
|
|
flags = SS_NO_FIRE // This subsystem has no continues workload, it's init and shutdown only.
|
|
/// Sanity check to confirm init was a success before finalizing.
|
|
var/init_success = FALSE
|
|
/// Global toggle to prevent saving at round end, changed by toggle_persistence proc, used for admin purposes.
|
|
var/prevent_saving = FALSE
|
|
/// In-memory register of all persistent objects that were loaded or created during the round, used for tracking and finalization purposes.
|
|
var/object_track_register = list()
|
|
/// Dictionary<"[type](+[attribute])" cache of persistent history records.
|
|
var/history_cache = alist()
|
|
/// Manual record counter of cache containers.
|
|
var/history_cache_count = 0
|
|
/// ID of last found history record.
|
|
/// Higher found IDs mean the record is not yet found in the database, lower or equal found ID means the are record that are already in the database.
|
|
/// Used during history_virtual_id init and read-through cache hits.
|
|
var/history_last_database_id = 0
|
|
/// ID used for instanciating new history records during the round, used for cache tracking.
|
|
/// Their database ID will be set during insert/finalization.
|
|
var/history_virtual_id = 0
|
|
/// Dictionary<char_id, charname> cache of Character name by ID for history/character helper.
|
|
var/char_cache = alist()
|
|
/// Dictionary<"[type](+[attribute])", container> cache of persistent generics.
|
|
var/generic_cache = alist()
|
|
|
|
/**
|
|
* Subsystem info stub message generation.
|
|
*/
|
|
/datum/controller/subsystem/persistence/stat_entry(msg)
|
|
msg = ("[init_success ? "" : "INIT FAILED!!!|"][prevent_saving ? "SAVING DISABLED!|" : ""]Objects:[length(object_track_register)]|Containers:[length(history_cache)];Records:[history_cache_count]|Generics:[length(generic_cache)]")
|
|
return msg
|
|
|
|
/**
|
|
* Helper method to check and log database connection.
|
|
* RETURN: True if connection is scuccessful, false if not.
|
|
* PARAMS:
|
|
* action = Custom string of the action being performed written to log.
|
|
*/
|
|
/datum/controller/subsystem/persistence/proc/databaseCheckConnection(action = "unlabeled action")
|
|
PRIVATE_PROC(TRUE)
|
|
if(!SSdbcore.Connect())
|
|
log_subsystem_persistence_error("SQL error during [action], connection failed.")
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/**
|
|
* Helper method to check the SQL query result and log possible errors.
|
|
* RETURN: True if no error occured, false if an error was found.
|
|
*/
|
|
/datum/controller/subsystem/persistence/proc/databaseCheckQueryResult(datum/db_query/query, action = "unlabeled action")
|
|
PRIVATE_PROC(TRUE)
|
|
if (!query)
|
|
log_subsystem_persistence_error("SQL error during [action], in addition query object provided to check was null.")
|
|
return FALSE
|
|
if (query.ErrorMsg())
|
|
log_subsystem_persistence_error("SQL error during [action]. " + query.ErrorMsg())
|
|
return FALSE
|
|
return TRUE
|
|
|
|
/**
|
|
* Initialization of the persistence subsystem.
|
|
* Includes generic startup checks and init of the different persistent data types.
|
|
*/
|
|
/datum/controller/subsystem/persistence/Initialize()
|
|
. = ..()
|
|
if(!GLOB.config.sql_enabled)
|
|
log_subsystem_persistence_warning("SQL configuration not enabled. Persistence subsystem requires SQL. Skipping init.")
|
|
return SS_INIT_SUCCESS
|
|
|
|
if(!databaseCheckConnection("subsystem init"))
|
|
log_subsystem_persistence_error("SQL connection unavailable. Init not possible.")
|
|
return SS_INIT_FAILURE
|
|
|
|
try
|
|
objectsInitialize()
|
|
catch(var/exception/e_objects)
|
|
log_subsystem_persistence_panic("Unhandled exception during persistent objects initialization!", e_objects)
|
|
return SS_INIT_FAILURE
|
|
|
|
try
|
|
typesInitialize()
|
|
catch(var/exception/e_types)
|
|
log_subsystem_persistence_panic("Unhandled exception during persistent type initialization!", e_types)
|
|
return SS_INIT_FAILURE
|
|
|
|
init_success = TRUE
|
|
return SS_INIT_SUCCESS
|
|
|
|
/**
|
|
* Shutdown of the persistence subsystem.
|
|
* The shutdown consists of finalization steps for each persistent data type.
|
|
*/
|
|
/datum/controller/subsystem/persistence/Shutdown()
|
|
if(!init_success)
|
|
log_subsystem_persistence_panic("Init success flag is FALSE. Something went wrong during subsystem init! Aborting finalization to prevent corrupt data!")
|
|
return
|
|
|
|
if(prevent_saving)
|
|
log_subsystem_persistence_warning("Persistence subsystem was toggled to not save. Skipping subsystem finalization.")
|
|
return
|
|
|
|
if(!databaseCheckConnection("subsystem shutdown"))
|
|
log_subsystem_persistence_panic("SQL error during persistence subsystem shutdown. Cannot finalise persistence of the round.")
|
|
return
|
|
|
|
try
|
|
objectsFinalize()
|
|
catch(var/exception/e_objects)
|
|
log_subsystem_persistence_panic("Unhandled exception during persistent objects finalization!", e_objects)
|
|
|
|
try
|
|
typesFinalize()
|
|
catch(var/exception/e_types)
|
|
log_subsystem_persistence_panic("Unhandled exception during persistent types finalization!", e_types)
|