mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 02:09:41 +00:00
@@ -72,9 +72,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "say", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>SAY:</u> - <span style=\"color:#32cd32\">[text]</span>"
|
||||
//CHOMPEdit End
|
||||
|
||||
@@ -85,9 +89,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "ooc", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>OOC:</u> - <span style=\"color:blue\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_aooc(text, client/user)
|
||||
@@ -97,9 +105,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "aooc", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>AOOC:</u> - <span style=\"color:red\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_looc(text, client/user)
|
||||
@@ -109,9 +121,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = user.ckey, "sender_mob" = user.mob.real_name, "message_type" = "looc", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[user]</b>) <u>LOOC:</u> - <span style=\"color:orange\"><b>[text]</b></span>"
|
||||
|
||||
/proc/log_whisper(text, mob/speaker)
|
||||
@@ -125,9 +141,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "whisper", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
|
||||
|
||||
/proc/log_emote(text, mob/speaker)
|
||||
@@ -141,9 +161,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "emote", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_attack(attacker, defender, message)
|
||||
@@ -171,9 +195,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "deadsay", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>DEADSAY:</u> - <span style=\"color:green\">[text]</span>"
|
||||
//GLOB.round_text_log += "<font size=1><span style=\"color:#7e668c\"><b>([time_stamp()])</b> (<b>[src]/[speaker.client]</b>) <u>DEADSAY:</u> - [text]</span></font>"
|
||||
//CHOMPEdit End
|
||||
@@ -187,9 +215,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "deademote", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_adminwarn(text)
|
||||
@@ -205,9 +237,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "pda", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
|
||||
//speaker.dialogue_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
//GLOB.round_text_log += "<b>([time_stamp()])</b> (<b>[speaker]/[speaker.client]</b>) <u>MSG:</u> - <span style=\"color:[COLOR_GREEN]\">[text]</span>"
|
||||
|
||||
@@ -7,9 +7,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "nsay", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_nme(text, inside, mob/speaker)
|
||||
@@ -21,9 +25,13 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "nme", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
/proc/log_subtle(text, mob/speaker)
|
||||
@@ -35,7 +43,11 @@
|
||||
establish_db_connection()
|
||||
if(!SSdbcore.IsConnected())
|
||||
return null
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_dialog (mid, time, ckey, mob, type, message) VALUES (null, NOW(), :sender_ckey, :sender_mob, :message_type, :message_content)", \
|
||||
list("sender_ckey" = speaker.ckey, "sender_mob" = speaker.real_name, "message_type" = "subtle", "message_content" = text))
|
||||
//SSdbcore.QuerySelect(list(query_insert), warn = FALSE, qdel = TRUE)
|
||||
if(!query_insert.Execute())
|
||||
log_debug("Error during logging: "+query_insert.ErrorMsg())
|
||||
qdel(query_insert)
|
||||
return
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
|
||||
@@ -122,10 +122,14 @@ Proc for attack log creation, because really why not
|
||||
|
||||
if(ismob(user)) //CHOMPEdit Begin
|
||||
//user.attack_log += text("\[[time_stamp()]\] <font color='red'>Attacked [target_str]: [what_done]</font>")
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :t_ckey, :t_mob, :t_content)", list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "<font color='red'>Attacked [target_str]: [what_done]</font>"))
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = user.ckey, "t_mob" = user.real_name, "t_content" = "<font color='red'>Attacked [target_str]: [what_done]</font>"))
|
||||
query_insert.Execute(async=use_async)
|
||||
qdel(query_insert)
|
||||
if(ismob(target))
|
||||
//target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Attacked by [user_str]: [what_done]</font>")
|
||||
SSdbcore.ReturnlessQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, '[time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]', :t_ckey, :t_mob, :t_content)", list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "<font color='orange'>Attacked by [user_str]: [what_done]</font>"))
|
||||
var/DBQuery/query_insert = SSdbcore.NewQuery("INSERT INTO erro_attacklog (id, time, ckey, mob, message) VALUES (null, NOW(), :t_ckey, :t_mob, :t_content)", list("t_ckey" = target.ckey, "t_mob" = target.real_name, "t_content" = "<font color='orange'>Attacked by [user_str]: [what_done]</font>"))
|
||||
query_insert.Execute(async=use_async)
|
||||
qdel(query_insert)
|
||||
//CHOMPEdit End
|
||||
log_attack(user_str,target_str,what_done)
|
||||
if(admin_notify)
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
#define RQUERY_NOTSTARTED -1
|
||||
|
||||
//I ported most of this subsystem directly from TGstation, however ReturnlessQueries are my own little creation, and SQL logging is also my baby, so come screech at me if shit is breaking -- Cadyn 2/4/2021
|
||||
|
||||
SUBSYSTEM_DEF(dbcore)
|
||||
name = "Database"
|
||||
flags = SS_BACKGROUND
|
||||
wait = 2 SECONDS
|
||||
wait = 1 MINUTES
|
||||
init_order = INIT_ORDER_DBCORE
|
||||
var/failed_connection_timeout = 0
|
||||
|
||||
@@ -15,90 +11,14 @@ SUBSYSTEM_DEF(dbcore)
|
||||
var/failed_connections = 0
|
||||
|
||||
var/last_error
|
||||
var/rquery_count = 0
|
||||
var/running_rqueries = 0
|
||||
var/list/active_queries = list()
|
||||
var/list/returnless_queries = list()
|
||||
var/list/currentrun = list()
|
||||
|
||||
var/connection // Arbitrary handle returned from rust_g.
|
||||
|
||||
/datum/controller/subsystem/dbcore/Initialize()
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/dbcore/stat_entry(msg_prefix)
|
||||
var/list/msg = list(msg_prefix)
|
||||
msg += "A:[active_queries.len]|"
|
||||
msg += "R:[returnless_queries.len]"
|
||||
..(msg.Join())
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/ReturnlessQuery(sql_query, arguments) //Adding this for logging, pretty much it allows queries that don't need to have anything returned handled in the background.
|
||||
returnless_queries["[rquery_count]"] = list("sql_query" = sql_query, "arguments" = arguments, "status" = RQUERY_NOTSTARTED)
|
||||
rquery_count++
|
||||
|
||||
/datum/controller/subsystem/dbcore/fire(resumed = 0)
|
||||
if(!resumed)
|
||||
src.currentrun = returnless_queries.Copy()
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
|
||||
for(var/rquery_id in currentrun)
|
||||
var/list/query = returnless_queries[rquery_id]
|
||||
if(!SSdbcore.IsConnected())
|
||||
last_error = "No connection!"
|
||||
log_debug(ErrorMsg())
|
||||
return
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
if(query["status"] == RQUERY_NOTSTARTED)
|
||||
if(running_rqueries + active_queries.len < 45)
|
||||
query["status"] = rustg_sql_query_async(connection, query["sql_query"], json_encode(query["arguments"]))
|
||||
running_rqueries++
|
||||
currentrun -= rquery_id
|
||||
continue
|
||||
var/job_result_str = rustg_sql_check_query(query["status"])
|
||||
if(job_result_str != RUSTG_JOB_NO_RESULTS_YET)
|
||||
if (job_result_str == RUSTG_JOB_ERROR)
|
||||
last_error = job_result_str
|
||||
log_debug("SQL JOB ERROR: [job_result_str] | Query used: [query["sql_query"]] | Arguments: [json_encode(query["arguments"])]")
|
||||
returnless_queries -= rquery_id
|
||||
currentrun -= rquery_id
|
||||
running_rqueries--
|
||||
del(query)
|
||||
continue
|
||||
var/result = json_decode(job_result_str)
|
||||
switch (result["status"])
|
||||
if ("ok")
|
||||
returnless_queries -= rquery_id
|
||||
currentrun -= rquery_id
|
||||
running_rqueries--
|
||||
del(query)
|
||||
continue
|
||||
if ("err")
|
||||
last_error = result["data"]
|
||||
log_debug("SQL QUERY ERROR: [last_error] | Query used: [query["sql_query"]] | Arguments: [json_encode(query["arguments"])]")
|
||||
returnless_queries -= rquery_id
|
||||
currentrun -= rquery_id
|
||||
running_rqueries--
|
||||
del(query)
|
||||
continue
|
||||
if ("offline")
|
||||
last_error = "offline"
|
||||
log_debug("SQL QUERY OFFLINE: Query used: [query["sql_query"]] | Arguments: [json_encode(query["arguments"])]")
|
||||
returnless_queries -= rquery_id
|
||||
currentrun -= rquery_id
|
||||
running_rqueries--
|
||||
del(query)
|
||||
continue
|
||||
else
|
||||
log_debug("SQL QUERY UNKNOWN STATUS: [result["status"]] | [last_error] | [result["data"]] | Query used: [query["sql_query"]] | Arguments: [json_encode(query["arguments"])]")
|
||||
returnless_queries -= rquery_id
|
||||
currentrun -= rquery_id
|
||||
running_rqueries--
|
||||
del(query)
|
||||
continue
|
||||
currentrun -= rquery_id
|
||||
continue
|
||||
|
||||
/datum/controller/subsystem/dbcore/fire()
|
||||
for(var/I in active_queries)
|
||||
var/DBQuery/Q = I
|
||||
if(world.time - Q.last_activity_time > (5 MINUTES))
|
||||
@@ -108,8 +28,6 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/datum/controller/subsystem/dbcore/Recover()
|
||||
connection = SSdbcore.connection
|
||||
|
||||
@@ -224,7 +142,7 @@ SUBSYSTEM_DEF(dbcore)
|
||||
/datum/controller/subsystem/dbcore/proc/ErrorMsg()
|
||||
if(!config.sql_enabled)
|
||||
return "Database disabled by configuration"
|
||||
return "SQL SUBSYSTEM ERROR: [last_error]"
|
||||
return last_error
|
||||
|
||||
/datum/controller/subsystem/dbcore/proc/ReportError(error)
|
||||
last_error = error
|
||||
|
||||
Reference in New Issue
Block a user