From fe57757fd72e462a2cc5dd27bd66f0854be6cfd7 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 15 Apr 2017 13:41:36 -0500 Subject: [PATCH] Adds a proc to check if the current thread is from an admin advanced proc call (#400) --- code/datums/callback.dm | 4 ++++ code/modules/admin/verbs/SDQL2/SDQL_2.dm | 8 +++---- code/modules/admin/verbs/debug.dm | 27 +++++++++++++++++++++--- code/modules/admin/verbs/debug.dm.rej | 24 +++++++++++++++++++++ code/orphaned_procs/dbcore.dm | 5 ++++- 5 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 code/modules/admin/verbs/debug.dm.rej diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 66c3e67406..1b5c25fe18 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -78,6 +78,8 @@ calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean else calling_arguments = args + if(var_edited) + return WrapAdminProcCall(object, delegate, calling_arguments) if (object == GLOBAL_PROC) return call(delegate)(arglist(calling_arguments)) return call(object, delegate)(arglist(calling_arguments)) @@ -93,6 +95,8 @@ calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean else calling_arguments = args + if(var_edited) + return WrapAdminProcCall(object, delegate, calling_arguments) if (object == GLOBAL_PROC) return call(delegate)(arglist(calling_arguments)) return call(object, delegate)(arglist(calling_arguments)) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 3e3db4172c..7375fac466 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -179,12 +179,12 @@ /proc/SDQL_callproc_global(procname,args_list) set waitfor = FALSE - call(procname)(arglist(args_list)) + WrapAdminProcCall(GLOBAL_PROC, procname, args_list) /proc/SDQL_callproc(thing, procname, args_list) set waitfor = FALSE if(hascall(thing, procname)) - call(thing, procname)(arglist(args_list)) + WrapAdminProcCall(thing, procname, args_list) /proc/SDQL_parse(list/query_list) var/datum/SDQL_parser/parser = new() @@ -479,8 +479,8 @@ new_args += SDQL_expression(source, arg) if(object == world) // Global proc. procname = "/proc/[procname]" - return call(procname)(arglist(new_args)) - return call(object, procname)(arglist(new_args)) // Spawn in case the function sleeps. + return WrapAdminProcCall(GLOBAL_PROC, procname, new_args) + return WrapAdminProcCall(object, procname, new_args) /proc/SDQL2_tokenize(query_text) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 92c36347f5..432c1a4075 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -70,17 +70,38 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that return log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") message_admins("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc + returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc else //this currently has no hascall protection. wasn't able to get it working. log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = call(procname)(arglist(lst)) // Pass the lst as an argument list to the proc + returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc . = get_callproc_returnval(returnval, procname) if(.) to_chat(usr, .) feedback_add_details("admin_verb","Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +GLOBAL_VAR_INIT(AdminProcCall, null) +GLOBAL_PROTECT(AdminProcCall) + +/proc/WrapAdminProcCall(target, procname, list/arguments) + if(GLOB.AdminProcCall) + to_chat(usr, "Another admin called proc is still running, your proc will be run after theirs finishes") + UNTIL(!GLOB.AdminProcCall) + to_chat(usr, "Running your proc") + GLOB.AdminProcCall = usr.client.ckey //if this runtimes, too bad for you + try + if(target == GLOBAL_PROC) + . = call(procname)(arglist(arguments)) + else + . = call(procname)(arglist(arguments)) + catch() + //intentionally left blank + GLOB.AdminProcCall = null + +/proc/IsAdminAdvancedProcCall() + return usr && usr.client && GLOB.AdminProcCall == usr.client.ckey + /client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) set category = "Debug" set name = "Atom ProcCall" @@ -106,7 +127,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that message_admins("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") feedback_add_details("admin_verb","Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - var/returnval = call(A,procname)(arglist(lst)) // Pass the lst as an argument list to the proc + var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc . = get_callproc_returnval(returnval,procname) if(.) to_chat(usr, .) diff --git a/code/modules/admin/verbs/debug.dm.rej b/code/modules/admin/verbs/debug.dm.rej new file mode 100644 index 0000000000..eb7a3a41ef --- /dev/null +++ b/code/modules/admin/verbs/debug.dm.rej @@ -0,0 +1,24 @@ +diff a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm (rejected hunks) +@@ -90,14 +90,16 @@ GLOBAL_PROTECT(AdminProcCall) + UNTIL(!GLOB.AdminProcCall) + to_chat(usr, "Running your proc") + GLOB.AdminProcCall = usr.client.ckey //if this runtimes, too bad for you +- try +- if(target == GLOBAL_PROC) +- . = call(procname)(arglist(arguments)) +- else +- . = call(procname)(arglist(arguments)) +- catch(exception/E) ++ world.WrapAdminProcCall(target, procname, arguments) + GLOB.AdminProcCall = null + ++//adv proc call this, ya nerds ++/world/proc/WrapAdminProcCall(target, procname, list/arguments) ++ if(target == GLOBAL_PROC) ++ return call(procname)(arglist(arguments)) ++ else ++ return call(procname)(arglist(arguments)) ++ + /proc/IsAdminAdvancedProcCall() + return usr && usr.client && GLOB.AdminProcCall == usr.client.ckey + diff --git a/code/orphaned_procs/dbcore.dm b/code/orphaned_procs/dbcore.dm index 23b4fd0eb1..e1758204bd 100644 --- a/code/orphaned_procs/dbcore.dm +++ b/code/orphaned_procs/dbcore.dm @@ -99,7 +99,10 @@ DBConnection/proc/SelectDB(database_name,dbi) if(IsConnected()) Disconnect() //return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[DB_SERVER]:[DB_PORT]"]",user,password) return Connect("[dbi?"[dbi]":"dbi:mysql:[database_name]:[global.sqladdress]:[global.sqlport]"]",user,password) -DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) return new/DBQuery(sql_query,src,cursor_handler) +DBConnection/proc/NewQuery(sql_query,cursor_handler=src.default_cursor) + if(IsAdminAdvancedProcCall()) + log_admin_private("WARNING: Advanced admin proc call DB query created!: [sql_query]") + return new/DBQuery(sql_query,src,cursor_handler) DBQuery/New(sql_query,DBConnection/connection_handler,cursor_handler)