From 146542b0771521fb78fd15389d30b119bdaec0af Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Fri, 12 Jun 2020 16:33:36 -0700 Subject: [PATCH] sdql2 --- code/__DEFINES/is_helpers.dm | 3 + code/modules/admin/verbs/SDQL2/SDQL_2.dm | 108 +++++++++++++---------- 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 28ec3383ae..1bd18776af 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -1,3 +1,6 @@ +/// Checks if something is a BYOND object datatype rather than a primitive, or whatever's closest to one. +#define is_object_datatype(object) (!istext(object) && !isnum(object)) + // simple is_type and similar inline helpers #define in_range(source, user) (get_dist(source, user) <= 1 && (get_step(source, 0)?:z) == (get_step(user, 0)?:z)) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index df54df5c7d..e0eb878b68 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -346,7 +346,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null //print the key if(islist(key)) recursive_list_print(output, key, datum_handler, atom_handler) - else if(is_proper_datum(key) && (datum_handler || (isatom(key) && atom_handler))) + else if(is_object_datatype(key) && (datum_handler || (isatom(key) && atom_handler))) if(isatom(key) && atom_handler) output += atom_handler.Invoke(key) else @@ -360,7 +360,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null var/value = input[key] if(islist(value)) recursive_list_print(output, value, datum_handler, atom_handler) - else if(is_proper_datum(value) && (datum_handler || (isatom(value) && atom_handler))) + else if(is_object_datatype(value) && (datum_handler || (isatom(value) && atom_handler))) if(isatom(value) && atom_handler) output += atom_handler.Invoke(value) else @@ -486,7 +486,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null end_time = REALTIMEOFDAY state = SDQL2_STATE_IDLE finished = TRUE - . = TRUE + text_list += TRUE if(show_next_to_key) var/client/C = GLOB.directory[show_next_to_key] if(C) @@ -511,9 +511,9 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null state = SDQL2_STATE_HALTING return if("call") - . = query_tree["on"] + text_list += query_tree["on"] if("select", "delete", "update") - . = query_tree[query_tree[1]] + text_list += query_tree[query_tree[1]] state = SDQL2_STATE_SWITCHING /datum/SDQL2_query/proc/Search(list/tree) @@ -554,7 +554,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null obj_count_eligible = objs.len else obj_count_eligible = obj_count_all - . = objs + text_list += objs state = SDQL2_STATE_SWITCHING /datum/SDQL2_query/proc/SDQL_from_objs(list/tree) @@ -646,7 +646,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null switch(query_tree[1]) if("call") for(var/i in found) - if(!is_proper_datum(i)) + if(!is_object_datatype(i)) continue world.SDQL_var(i, query_tree["call"][1], null, i, superuser, src) obj_count_finished++ @@ -664,7 +664,10 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null var/list/text_list = list() var/print_nulls = !(options & SDQL2_OPTION_SELECT_OUTPUT_SKIP_NULLS) obj_count_finished = select_refs + var/n = 0 for(var/i in found) + if(++n == 20000) + text_list += "
TRUNCATED - 20000 OBJECT LIMIT HIT" SDQL_print(i, text_list, print_nulls) select_refs[REF(i)] = TRUE SDQL2_TICK_CHECK @@ -675,7 +678,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null if("set" in query_tree) var/list/set_list = query_tree["set"] for(var/d in found) - if(!is_proper_datum(d)) + if(!is_object_datatype(d)) continue SDQL_internal_vv(d, set_list) obj_count_finished++ @@ -685,47 +688,61 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null obj_count_finished = length(obj_count_finished) state = SDQL2_STATE_SWITCHING -/datum/SDQL2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE) - if(is_proper_datum(object)) - text_list += "[REF(object)] : [object]" - if(istype(object, /atom)) - var/atom/A = object - var/turf/T = A.loc - var/area/a - if(istype(T)) - text_list += " at [T] [ADMIN_COORDJMP(T)]" - a = T.loc - else - var/turf/final = get_turf(T) //Recursive, hopefully? - if(istype(final)) - text_list += " at [final] [ADMIN_COORDJMP(final)]" - a = final.loc +/** + * Recursively prints out an object to text list for SDQL2 output to admins, with VV links and all. + * Recursion limit: 50 + * Limit imposed by callers should be around 10000 objects + * Seriously, if you hit those limits, you're doing something wrong. + */ +/datum/SDQL2_query/proc/SDQL_print(object, list/text_list, print_nulls = TRUE, recursion = 0, linebreak = TRUE) + if(recursion > 50) + text_list += "RECURSION LIMIT REACHED." + if(is_object_datatype(object)) + if(!islist(object)) + text_list += "[REF(object)]([object.type]): [object]" + if(istype(object, /atom)) + var/atom/A = object + var/atom/container = A.loc + if(isturf(container)) + text_list += " in [container] [ADMIN_COORDJMP(container)] at [container.loc]" + else if(container) + var/turf/T = get_turf(container) + var/cref = REF(container) + text_list += " in [container]([cref])" + if(T) + text_list += " on [T] [ADMIN_COORDJMP(T)] at[T.loc]" else - text_list += " at nonexistant location" - if(a) - text_list += " in area [a]" - if(T.loc != a) - text_list += " inside [T]" - text_list += "
" - else if(islist(object)) - var/list/L = object - var/first = TRUE - text_list += "\[" - for (var/x in L) - if (!first) - text_list += ", " - first = FALSE - SDQL_print(x, text_list) - if (!isnull(x) && !isnum(x) && L[x] != null) - text_list += " -> " - SDQL_print(L[L[x]], text_list) - text_list += "]
" + text_list += " in nullspace" + if(linebreak) + text_list += "
" + return + else // lists are snowflake and get special treatment. + for(var/t in 1 to recursion) + text_list += "\t" + text_list += "[REF(object)] \[" + var/first = TRUE + var/list/L = object + for(var/key in object) + if(!first) + text_list += ", " + first = FALSE + SDQL_print(key, text_list, TRUE, recursion + 1, FALSE) + if(IS_VALID_ASSOC_KEY(key) && !isnull(L[key])) + text_list += " --> " + SDQL_print(L[key], text_list, TRUE, recursion + 1, FALSE) + text_list += "\]" else if(isnull(object)) if(print_nulls) text_list += "NULL
" + else if(istext(object)) + text_list += "STRING: [object]
" + else if(isnum(object)) + text_list += "NUM: [object]
" else - text_list += "[object]
" + text_list += "UNKNOWN: [object]
" + if(linebreak) + text_list += "
" /datum/SDQL2_query/CanProcCall() if(!allow_admin_interact) @@ -957,7 +974,7 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null var/static/list/exclude = list("usr", "src", "marked", "global") var/long = start < expression.len var/datum/D - if(is_proper_datum(object)) + if(is_object_datatype(object)) D = object if (object == world && (!long || expression[start + 1] == ".") && !(expression[start] in exclude)) //3 == length("SS") + 1 @@ -1161,9 +1178,6 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null query_list += word return query_list -/proc/is_proper_datum(thing) - return istype(thing, /datum) || istype(thing, /client) - /obj/effect/statclick/SDQL2_delete/Click() var/datum/SDQL2_query/Q = target Q.delete_click()