You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
7.7 KiB

  1. /client/proc/callproc()
  2. set category = "Debug"
  3. set name = "Advanced ProcCall"
  4. set waitfor = FALSE
  5. callproc_blocking()
  6. /client/proc/callproc_blocking(list/get_retval)
  7. if(!check_rights(R_DEBUG))
  8. return
  9. var/datum/target
  10. var/targetselected = FALSE
  11. var/returnval
  12. switch(alert("Proc owned by something?",,"Yes","No"))
  13. if("Yes")
  14. targetselected = TRUE
  15. var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT, VV_MARKED_DATUM, VV_TEXT_LOCATE, VV_PROCCALL_RETVAL))
  16. if (!value["class"] || !value["value"])
  17. return
  18. target = value["value"]
  19. if(!istype(target))
  20. to_chat(usr, "<span class='danger'>Invalid target.</span>", confidential = TRUE)
  21. return
  22. if("No")
  23. target = null
  24. targetselected = FALSE
  25. var/procpath = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
  26. if(!procpath)
  27. return
  28. //strip away everything but the proc name
  29. var/list/proclist = splittext(procpath, "/")
  30. if (!length(proclist))
  31. return
  32. var/procname = proclist[proclist.len]
  33. var/proctype = ("verb" in proclist) ? "verb" :"proc"
  34. if(targetselected)
  35. if(!hascall(target, procname))
  36. to_chat(usr, "<span class='warning'>Error: callproc(): type [target.type] has no [proctype] named [procpath].</span>", confidential = TRUE)
  37. return
  38. else
  39. procpath = "/[proctype]/[procname]"
  40. if(!text2path(procpath))
  41. to_chat(usr, "<span class='warning'>Error: callproc(): [procpath] does not exist.</span>", confidential = TRUE)
  42. return
  43. var/list/lst = get_callproc_args()
  44. if(!lst)
  45. return
  46. if(targetselected)
  47. if(!target)
  48. to_chat(usr, "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>", confidential = TRUE)
  49. return
  50. var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
  51. log_admin(msg)
  52. message_admins(msg) //Proccall announce removed.
  53. admin_ticket_log(target, msg)
  54. returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
  55. else
  56. //this currently has no hascall protection. wasn't able to get it working.
  57. log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
  58. message_admins("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") //Proccall announce removed.
  59. returnval = WrapAdminProcCall(GLOBAL_PROC, procname, lst) // Pass the lst as an argument list to the proc
  60. SSblackbox.record_feedback("tally", "admin_verb", 1, "Advanced ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
  61. if(get_retval)
  62. get_retval += returnval
  63. . = get_callproc_returnval(returnval, procname)
  64. if(.)
  65. to_chat(usr, ., confidential = TRUE)
  66. GLOBAL_VAR(AdminProcCaller)
  67. GLOBAL_PROTECT(AdminProcCaller)
  68. GLOBAL_VAR_INIT(AdminProcCallCount, 0)
  69. GLOBAL_PROTECT(AdminProcCallCount)
  70. GLOBAL_VAR(LastAdminCalledTargetRef)
  71. GLOBAL_PROTECT(LastAdminCalledTargetRef)
  72. GLOBAL_VAR(LastAdminCalledTarget)
  73. GLOBAL_PROTECT(LastAdminCalledTarget)
  74. GLOBAL_VAR(LastAdminCalledProc)
  75. GLOBAL_PROTECT(LastAdminCalledProc)
  76. GLOBAL_LIST_EMPTY(AdminProcCallSpamPrevention)
  77. GLOBAL_PROTECT(AdminProcCallSpamPrevention)
  78. /// Wrapper for proccalls where the datum is flagged as vareditted
  79. /proc/WrapAdminProcCall(datum/target, procname, list/arguments)
  80. if(target && procname == "Del")
  81. to_chat(usr, "Calling Del() is not allowed", confidential = TRUE)
  82. return
  83. if(target != GLOBAL_PROC && !target.CanProcCall(procname))
  84. to_chat(usr, "Proccall on [target.type]/proc/[procname] is disallowed!", confidential = TRUE)
  85. return
  86. var/current_caller = GLOB.AdminProcCaller
  87. var/ckey = usr ? usr.client.ckey : GLOB.AdminProcCaller
  88. if(!ckey)
  89. CRASH("WrapAdminProcCall with no ckey: [target] [procname] [english_list(arguments)]")
  90. if(current_caller && current_caller != ckey)
  91. if(!GLOB.AdminProcCallSpamPrevention[ckey])
  92. to_chat(usr, "<span class='adminnotice'>Another set of admin called procs are still running, your proc will be run after theirs finish.</span>", confidential = TRUE)
  93. GLOB.AdminProcCallSpamPrevention[ckey] = TRUE
  94. UNTIL(!GLOB.AdminProcCaller)
  95. to_chat(usr, "<span class='adminnotice'>Running your proc</span>", confidential = TRUE)
  96. GLOB.AdminProcCallSpamPrevention -= ckey
  97. else
  98. UNTIL(!GLOB.AdminProcCaller)
  99. GLOB.LastAdminCalledProc = procname
  100. if(target != GLOBAL_PROC)
  101. GLOB.LastAdminCalledTargetRef = REF(target)
  102. GLOB.AdminProcCaller = ckey //if this runtimes, too bad for you
  103. ++GLOB.AdminProcCallCount
  104. . = world.WrapAdminProcCall(target, procname, arguments)
  105. if(--GLOB.AdminProcCallCount == 0)
  106. GLOB.AdminProcCaller = null
  107. //adv proc call this, ya nerds
  108. /world/proc/WrapAdminProcCall(datum/target, procname, list/arguments)
  109. if(target == GLOBAL_PROC)
  110. return call(procname)(arglist(arguments))
  111. else if(target != world)
  112. return call(target, procname)(arglist(arguments))
  113. else
  114. log_admin("[key_name(usr)] attempted to call world/proc/[procname] with arguments: [english_list(arguments)]")
  115. /proc/IsAdminAdvancedProcCall()
  116. #ifdef TESTING
  117. return FALSE
  118. #else
  119. return usr && usr.client && GLOB.AdminProcCaller == usr.client.ckey
  120. #endif
  121. /client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
  122. set category = "Debug"
  123. set name = "Atom ProcCall"
  124. set waitfor = 0
  125. if(!check_rights(R_DEBUG))
  126. return
  127. var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null
  128. if(!procname)
  129. return
  130. if(!hascall(A,procname))
  131. to_chat(usr, "<font color='red'>Error: callproc_datum(): type [A.type] has no proc named [procname].</font>", confidential = TRUE)
  132. return
  133. var/list/lst = get_callproc_args()
  134. if(!lst)
  135. return
  136. if(!A || !IsValidSrc(A))
  137. to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>", confidential = TRUE)
  138. return
  139. log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
  140. var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
  141. message_admins(msg)
  142. admin_ticket_log(A, msg)
  143. SSblackbox.record_feedback("tally", "admin_verb", 1, "Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
  144. var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
  145. . = get_callproc_returnval(returnval,procname)
  146. if(.)
  147. to_chat(usr, ., confidential = TRUE)
  148. /client/proc/get_callproc_args()
  149. var/argnum = input("Number of arguments","Number:",0) as num|null
  150. if(isnull(argnum))
  151. return
  152. . = list()
  153. var/list/named_args = list()
  154. while(argnum--)
  155. var/named_arg = input("Leave blank for positional argument. Positional arguments will be considered as if they were added first.", "Named argument") as text|null
  156. var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
  157. if (!value["class"])
  158. return
  159. if(named_arg)
  160. named_args[named_arg] = value["value"]
  161. else
  162. . += value["value"]
  163. if(LAZYLEN(named_args))
  164. . += named_args
  165. /client/proc/get_callproc_returnval(returnval,procname)
  166. . = ""
  167. if(islist(returnval))
  168. var/list/returnedlist = returnval
  169. . = "<font color='blue'>"
  170. if(returnedlist.len)
  171. var/assoc_check = returnedlist[1]
  172. if(istext(assoc_check) && (returnedlist[assoc_check] != null))
  173. . += "[procname] returned an associative list:"
  174. for(var/key in returnedlist)
  175. . += "\n[key] = [returnedlist[key]]"
  176. else
  177. . += "[procname] returned a list:"
  178. for(var/elem in returnedlist)
  179. . += "\n[elem]"
  180. else
  181. . = "[procname] returned an empty list"
  182. . += "</font>"
  183. else
  184. . = "<font color='blue'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</font>"