diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index e0947d2d420..56a93164143 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -15,7 +15,6 @@ #define DEADMIN_POSITION_SECURITY (1<<18) #define DEADMIN_POSITION_SILICON (1<<19) #define ADMIN_IGNORE_CULT_GHOST (1<<21) -#define SPLIT_ADMIN_TABS (1<<23) #define TOGGLES_DEFAULT (SOUND_ADMINHELP|MEMBER_PUBLIC|SOUND_PRAYERS) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index a35dab5dd89..e789597cfbb 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -135,12 +135,13 @@ #define INIT_ORDER_SERVER_MAINT 93 #define INIT_ORDER_INPUT 85 #define INIT_ORDER_SOUNDS 83 -#define INIT_ORDER_INSTRUMENTS 82 -#define INIT_ORDER_GREYSCALE 81 -#define INIT_ORDER_VIS 80 -#define INIT_ORDER_SECURITY_LEVEL 79 // We need to load before events so that it has a security level to choose from. -#define INIT_ORDER_DISCORD 78 -#define INIT_ORDER_ACHIEVEMENTS 77 +#define INIT_ORDER_ADMIN_VERBS 82 +#define INIT_ORDER_INSTRUMENTS 81 +#define INIT_ORDER_GREYSCALE 80 +#define INIT_ORDER_VIS 79 +#define INIT_ORDER_SECURITY_LEVEL 78 // We need to load before events so that it has a security level to choose from. +#define INIT_ORDER_DISCORD 77 +#define INIT_ORDER_ACHIEVEMENTS 76 #define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it. #define INIT_ORDER_QUIRKS 73 #define INIT_ORDER_REAGENTS 72 //HAS to be before mapping and assets - both create objects, which creates reagents, which relies on lists made in this subsystem diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 4a4bc828cf8..589693abd29 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -271,6 +271,20 @@ if(typecache_include[atom_checked.type] && !typecache_exclude[atom_checked.type]) . += atom_checked +/// Returns a typecache for the direct descendants of the path +/proc/typecache_next_level(path) + if(isnull(path)) + return + var/list/paths = list() + if(ispath(path)) + var/path_text = "[path]" + for(var/subtype in subtypesof(path)) + var/subtype_text = replacetext("[subtype]", path_text, "") + if(findlasttext(subtype_text, "/") != 1) + continue + paths[subtype] = TRUE + return paths + /** * Like typesof() or subtypesof(), but returns a typecache instead of a list. * diff --git a/code/__HELPERS/admin_verb.dm b/code/__HELPERS/admin_verb.dm new file mode 100644 index 00000000000..5862b41c11e --- /dev/null +++ b/code/__HELPERS/admin_verb.dm @@ -0,0 +1,56 @@ +/** + * Creates an admin verb with the specified module(category) name, desc, permissions, and parameters as needed. + */ +#define ADMIN_VERB(module, verb_name, verb_desc, permissions, params...) \ +/mob/admin_module_holder/##module/##verb_name/verb/invoke(##params){ \ + set src in usr.group; \ + set name = #verb_name; \ + set desc = verb_desc; \ + if(datum_flags & DF_VAR_EDITED) { \ + message_admins("[key_name_admin(usr)] attempted to elevate permissions by executing from a var edited admin verb holder!"); \ + del(src); \ + return; \ + } \ + if(IsAdminAdvancedProcCall()) { \ + message_admins("[key_name_admin(usr)] attempted to elevate permissions by executing an admin verb using ProcCall!"); \ + return; \ + } \ + if(check_rights_for(usr.client, permissions)) { \ + _##verb_name(arglist(args)); \ + SSblackbox.record_feedback("tally", "admin_verb", 1, "[#module]/[#verb_name]"); \ + } else { \ + to_chat(usr, span_warning("You lack the permissions ([rights2text(permissions, " ")]) for this verb!")); \ + } \ +} \ +/mob/admin_module_holder/##module/##verb_name/dynamic_map_generate(){ \ + return list(#module, #verb_name, verb_desc, permissions); \ +} \ +/mob/admin_module_holder/##module/##verb_name/proc/_##verb_name(##params) + +/** + * Creates a context menu entry for the client. The source of this proc will be the client! + */ +#define ADMIN_CONTEXT_ENTRY(context_id, context_name, permissions, params...) \ +/client/proc/admin_context_wrapper_##context_id(##params){ \ + if(check_rights_for(src, permissions)) { \ + __admin_context_verb_##context_id(arglist(args)); \ + SSblackbox.record_feedback("tally", "admin_context", 1, "[#context_id]/[context_name]"); \ + } else { \ + to_chat(usr, span_warning("You lack the permissions ([rights2text(permissions, " ")]) for this context menu action!")); \ + } \ +} \ +/datum/controller/subsystem/admin_verbs/populate_context_map(list/context_map){ \ + ..(); \ + context_map[/client/proc/admin_context_wrapper_##context_id] = list(context_name, permissions); \ +} \ +/client/proc/__admin_context_verb_##context_id(##params) + +// THIS IS DONE HERE TO ENSURE IT ALWAYS MATCHES THE ABOVE MACRO. +// IF YOU CHANGE THE MACRO MAKE SURE THIS STILL WORKS CORRECTLY!! -Zephyr + +/client/CanProcCall(procname) + if(findtext(procname, "admin_context_wrapper_") == 1) + return FALSE + if(findtext(procname, "__admin_context_verb") == 1) + return FALSE + return ..() diff --git a/code/__HELPERS/hallucinations.dm b/code/__HELPERS/hallucinations.dm index 809ff475fc9..b2c7ad6d9b5 100644 --- a/code/__HELPERS/hallucinations.dm +++ b/code/__HELPERS/hallucinations.dm @@ -113,50 +113,6 @@ GLOBAL_LIST_INIT(random_hallucination_weighted_list, generate_hallucination_weig to_chat(usr, span_boldnotice("The total weight of the hallucination weighted list is [total_weight].")) return total_weight -/// Debug verb for getting the weight of each distinct type within the random_hallucination_weighted_list -/client/proc/debug_hallucination_weighted_list_per_type() - set name = "Show Hallucination Weights" - set category = "Debug" - - var/header = "Type Weight Percent" - - var/total_weight = debug_hallucination_weighted_list() - var/list/all_weights = list() - var/datum/hallucination/last_type - var/last_type_weight = 0 - for(var/datum/hallucination/hallucination_type as anything in GLOB.random_hallucination_weighted_list) - var/this_weight = GLOB.random_hallucination_weighted_list[hallucination_type] - // Last_type is the abstract parent of the last hallucination type we iterated over - if(last_type) - // If this hallucination is the same path as the last type (subtype), add it to the total of the last type weight - if(ispath(hallucination_type, last_type)) - last_type_weight += this_weight - continue - - // Otherwise we moved onto the next hallucination subtype so we can stop - else - all_weights["[last_type] [last_type_weight] / [total_weight] [round(100 * (last_type_weight / total_weight), 0.01)]% chance"] = last_type_weight - - // Set last_type to the abstract parent of this hallucination - last_type = initial(hallucination_type.abstract_hallucination_parent) - // If last_type is the base hallucination it has no distinct subtypes so we can total it up immediately - if(last_type == /datum/hallucination) - all_weights["[hallucination_type] [this_weight] / [total_weight] [round(100 * (this_weight / total_weight), 0.01)]% chance"] = this_weight - last_type = null - - // Otherwise we start the weight sum for the next entry here - else - last_type_weight = this_weight - - // Sort by weight descending, where weight is the values (not the keys). We assoc_to_keys later to get JUST the text - all_weights = sortTim(all_weights, GLOBAL_PROC_REF(cmp_numeric_dsc), associative = TRUE) - - var/page_style = "" - var/page_contents = "[page_style][header][jointext(assoc_to_keys(all_weights), "")]
" - var/datum/browser/popup = new(mob, "hallucinationdebug", "Hallucination Weights", 600, 400) - popup.set_content(page_contents) - popup.open() - /// Gets a random subtype of the passed hallucination type that has a random_hallucination_weight > 0. /// If no subtype is passed, it will get any random hallucination subtype that is not abstract and has weight > 0. /// This can be used instead of picking from the global weighted list to just get a random valid hallucination. diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index b1f40f76294..2d2a92388d4 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -43,41 +43,3 @@ offset[1] += x_off offset[2] += y_off return offset_to_screen_loc(offset[1], offset[2], our_client?.view) - -//Debug procs -/client/proc/test_movable_UI() - set category = "Debug" - set name = "Spawn Movable UI Object" - - var/atom/movable/screen/movable/M = new() - M.name = "Movable UI Object" - M.icon_state = "block" - M.maptext = MAPTEXT("Movable") - M.maptext_width = 64 - - var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") as text|null - if(!screen_l) - return - - M.screen_loc = screen_l - - screen += M - - -/client/proc/test_snap_UI() - set category = "Debug" - set name = "Spawn Snap UI Object" - - var/atom/movable/screen/movable/snap/S = new() - S.name = "Snap UI Object" - S.icon_state = "block" - S.maptext = MAPTEXT("Snap") - S.maptext_width = 64 - - var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") as text|null - if(!screen_l) - return - - S.screen_loc = screen_l - - screen += S diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm index 0d90319f863..618e0c80da9 100644 --- a/code/controllers/admin.dm +++ b/code/controllers/admin.dm @@ -41,51 +41,5 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick) else class = "unknown" - usr.client.debug_variables(target) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, target) message_admins("Admin [key_name_admin(usr)] is debugging the [target] [class].") - - -// Debug verbs. -/client/proc/restart_controller(controller in list("Master", "Failsafe")) - set category = "Debug" - set name = "Restart Controller" - set desc = "Restart one of the various periodic loop controllers for the game (be careful!)" - - if(!holder) - return - switch(controller) - if("Master") - Recreate_MC() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Master Controller") - if("Failsafe") - new /datum/controller/failsafe() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe Controller") - - message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") - -/client/proc/debug_controller() - set category = "Debug" - set name = "Debug Controller" - set desc = "Debug the various periodic loop controllers for the game (be careful!)" - - if(!holder) - return - - var/list/controllers = list() - var/list/controller_choices = list() - - for (var/datum/controller/controller in world) - if (istype(controller, /datum/controller/subsystem)) - continue - controllers["[controller] (controller.type)"] = controller //we use an associated list to ensure clients can't hold references to controllers - controller_choices += "[controller] (controller.type)" - - var/datum/controller/controller_string = input("Select controller to debug", "Debug Controller") as null|anything in controller_choices - var/datum/controller/controller = controllers[controller_string] - - if (!istype(controller)) - return - debug_variables(controller) - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe Controller") - message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") diff --git a/code/controllers/subsystem/admin_verbs.dm b/code/controllers/subsystem/admin_verbs.dm new file mode 100644 index 00000000000..99d7bfaec2d --- /dev/null +++ b/code/controllers/subsystem/admin_verbs.dm @@ -0,0 +1,197 @@ +#define VERB_MAP_MODULE 1 +#define VERB_MAP_NAME 2 +#define VERB_MAP_DESCRIPTION 3 +#define VERB_MAP_PERMISSIONS 4 + +#define CONTEXT_MAP_NAME 1 +#define CONTEXT_MAP_PERMISSIONS 2 + +#define LINKUPMAP_LOGOUT 1 +#define LINKUPMAP_LOGIN 2 +#define LINKUPMAP_CONTEXT_MAP 3 + +SUBSYSTEM_DEF(admin_verbs) + name = "Admin Verbs" + flags = SS_NO_FIRE + init_order = INIT_ORDER_ADMIN_VERBS + VAR_PRIVATE/list/admin_verb_map + VAR_PRIVATE/list/holder_map + VAR_PRIVATE/list/context_map + VAR_PRIVATE/list/admin_linkup_map + + var/list/waiting_to_assosciate = list() + var/list/assosciations_by_ckey + +// DO NOT MERGE BEFORE UNCOMMENTING -- GENERAL_PROTECT_DATUM(/datum/controller/subsystem/admin_verbs) + +/datum/controller/subsystem/admin_verbs/Recover() + admin_verb_map = SSadmin_verbs.admin_verb_map + holder_map = SSadmin_verbs.holder_map + context_map = SSadmin_verbs.context_map + admin_linkup_map = SSadmin_verbs.admin_linkup_map + assosciations_by_ckey = SSadmin_verbs.assosciations_by_ckey + +/datum/controller/subsystem/admin_verbs/Initialize() + RegisterSignal(src, COMSIG_SUBSYSTEM_POST_INITIALIZE, PROC_REF(assosciate_with_waiting)) + admin_verb_map = list() + admin_linkup_map = list() + generate_holder_map() + context_map = list() + populate_context_map(context_map) + assosciations_by_ckey = list() + return SS_INIT_SUCCESS + +/datum/controller/subsystem/admin_verbs/proc/generate_stat_data(client/target) + var/static/list/abbreviations = list( + "ERT" + ) + var/static/list/cached_formats = list() + + if(!initialized || !target.holder) + return list() + + var/list/stat_data = list() + for(var/verb_type in assosciations_by_ckey[target.ckey]) + var/list/verb_information = admin_verb_map[verb_type] + var/verb_permissions = verb_information[VERB_MAP_PERMISSIONS] + if(!check_rights_for(target, verb_permissions)) + continue + + var/verb_module = lowertext(verb_information[VERB_MAP_MODULE]) + if(!verb_module || verb_module == "null") + continue + + if(!cached_formats[verb_module]) + var/verb_module_formatted = "" + for(var/verb_module_part in splittext(verb_module, "_")) + if(verb_module_part in abbreviations) + verb_module_formatted += "[uppertext(verb_module_part)] " + else + verb_module_formatted += "[capitalize(verb_module_part)] " + verb_module_formatted = copytext(verb_module_formatted, 1, -1) + cached_formats[verb_module] = verb_module_formatted + + var/original_name = verb_information[VERB_MAP_NAME] + if(!cached_formats[original_name]) + var/formatted_name = "" + for(var/name_part in splittext(original_name, "_")) + if(name_part in abbreviations) + formatted_name += "[uppertext(name_part)] " + else + formatted_name += "[capitalize(name_part)] " + formatted_name = copytext(formatted_name, 1, -1) + cached_formats[original_name] = formatted_name + + var/verb_desc = verb_information[VERB_MAP_DESCRIPTION] + if(!stat_data[cached_formats[verb_module]]) + stat_data[cached_formats[verb_module]] = list() + stat_data[cached_formats[verb_module]] += list(list(cached_formats[original_name], verb_desc, original_name)) + var/sorted_stat_data = list() + for(var/verb_category in stat_data) + sorted_stat_data[verb_category] = sort_list(stat_data[verb_category], GLOBAL_PROC_REF(cmp_admin_verb_name)) + return sorted_stat_data + +/proc/cmp_admin_verb_name(list/info_left, list/info_right) + return sorttext(info_right[1], info_left[1]) + +/datum/controller/subsystem/admin_verbs/proc/populate_context_map(list/context_map) + return + +/datum/controller/subsystem/admin_verbs/proc/generate_holder_map() + admin_verb_map = list() + holder_map = list() + var/list/processing = typecacheof(sort_list(subtypesof(/mob/admin_module_holder), GLOBAL_PROC_REF(cmp_typepaths_asc))) + processing -= typecache_next_level(/mob/admin_module_holder) + for(var/mob/admin_module_holder/holder_type as anything in processing) + var/mob/admin_module_holder/holder = new holder_type + holder_map[holder_type] = holder + admin_verb_map[holder_type] = holder.dynamic_map_generate() + +/datum/controller/subsystem/admin_verbs/proc/dynamic_invoke_admin_verb(mob/target, verb_type, ...) + if(IsAdminAdvancedProcCall()) + return + + var/mob/admin_module_holder/holder = holder_map[verb_type] + if(!istype(holder)) + to_chat(usr, span_big("Attempted to dynamic invoke an admin verb that didnt exist, this is a really bad problem!")) + CRASH("Admin Verb Holder '[verb_type]' did not exist when an attempt to access the dynmap occured.") + + if(IS_CLIENT_OR_MOCK(target)) + var/client/clientele = target + target = clientele.mob + + usr = target + var/holder_proc = text2path("[verb_type]/verb/invoke") + var/list/arguments = args.Copy(3) + call(holder, holder_proc)(arglist(arguments)) + +/datum/controller/subsystem/admin_verbs/proc/link_admin(mob/admin) + assosciations_by_ckey[admin.ckey] = list() + for(var/mob/admin_module_holder/holder as anything in holder_map) + holder = holder_map[holder] + if(check_rights_for(admin.client, admin_verb_map[holder.type][VERB_MAP_PERMISSIONS])) + admin.group |= holder + assosciations_by_ckey[admin.ckey] |= list(holder.type) + + var/list/client_context_verbs = admin_linkup_map[admin.ckey][LINKUPMAP_CONTEXT_MAP] + for(var/context_entry in context_map) + var/list/context_information = context_map[context_entry] + + var/procpath/existing = client_context_verbs[context_entry] + if(existing) + admin.client.verbs -= existing + + if(!check_rights_for(admin.client, context_information[CONTEXT_MAP_PERMISSIONS])) + continue + client_context_verbs[context_entry] = new context_entry(admin.client, context_information[CONTEXT_MAP_NAME]) + +/datum/controller/subsystem/admin_verbs/proc/unlink_admin(mob/adwas) + for(var/mob/admin_module_holder/holder as anything in holder_map) + holder = holder_map[holder] + adwas.group -= holder + assosciations_by_ckey -= adwas.canon_client.ckey + + // we use canon_client here because ckey will already have moved when this is called + var/list/client_context_verbs = admin_linkup_map[adwas.canon_client.ckey][LINKUPMAP_CONTEXT_MAP] + for(var/context_entry in context_map) + adwas.canon_client.verbs -= client_context_verbs[context_entry] + +/datum/controller/subsystem/admin_verbs/proc/assosciate_admin(client/admin) + if(!initialized) + to_chat_immediate(admin, span_admin("SSadmin_verbs has either not begun or has not finished initialization procedures, please wait!")) + waiting_to_assosciate |= admin.ckey + return + + var/list/existing_map = admin_linkup_map[admin.ckey] + if(existing_map) + admin.player_details.post_login_callbacks -= existing_map[LINKUPMAP_LOGIN] + + var/datum/callback/old_logout = existing_map[LINKUPMAP_LOGOUT] + admin.player_details.post_logout_callbacks -= old_logout + old_logout.Invoke(admin.mob) + + var/on_login = CALLBACK(src, PROC_REF(link_admin)) + var/on_logout = CALLBACK(src, PROC_REF(unlink_admin)) + admin_linkup_map[admin.ckey] = list(on_logout, on_login, list()) + + admin.player_details.post_login_callbacks += list(on_login) + admin.player_details.post_logout_callbacks += list(on_logout) + link_admin(admin.mob) + SSstatpanels.set_admin_verb_tab(admin) + +/datum/controller/subsystem/admin_verbs/proc/deassosciate_admin(client/adwas) + unlink_admin(adwas.mob) // we unlink before clearing the linkup map because unlink checks the map for context entries to remove + admin_linkup_map -= list(adwas.ckey) + SSstatpanels.set_admin_verb_tab(adwas) + +/datum/controller/subsystem/admin_verbs/proc/assosciate_with_waiting() + for(var/waiting in waiting_to_assosciate) + if(waiting in GLOB.directory) + assosciate_admin(GLOB.directory[waiting]) + waiting_to_assosciate.Cut() + +/datum/controller/subsystem/admin_verbs/proc/handle_admin_holder_topic(client/user, href, href_list) + if(href_list["adminchecklaws"]) + dynamic_invoke_admin_verb(user, /mob/admin_module_holder/game/check_ai_laws) + return TRUE + return FALSE diff --git a/code/controllers/subsystem/explosions.dm b/code/controllers/subsystem/explosions.dm index ef14d078fb4..42621b534d2 100644 --- a/code/controllers/subsystem/explosions.dm +++ b/code/controllers/subsystem/explosions.dm @@ -81,12 +81,9 @@ SUBSYSTEM_DEF(explosions) flameturf -= T throwturf -= T -/client/proc/check_bomb_impacts() - set name = "Check Bomb Impact" - set category = "Debug" - +ADMIN_VERB(debug, check_bomb_impact, "", R_DEBUG) var/newmode = tgui_alert(usr, "Use reactionary explosions?","Check Bomb Impact", list("Yes", "No")) - var/turf/epicenter = get_turf(mob) + var/turf/epicenter = get_turf(usr) if(!epicenter) return diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 80beabfcbe9..4312087b7f1 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -603,15 +603,7 @@ GLOBAL_LIST_EMPTY(the_station_areas) holodeck_templates[holo_template.template_id] = holo_template -//Manual loading of away missions. -/client/proc/admin_away() - set name = "Load Away Mission" - set category = "Admin.Events" - - if(!holder || !check_rights(R_FUN)) - return - - +ADMIN_VERB(events, load_away_mission, "", R_FUN) if(!GLOB.the_gateway) if(tgui_alert(usr, "There's no home gateway on the station. You sure you want to continue ?", "Uh oh", list("Yes", "No")) != "Yes") return @@ -622,14 +614,14 @@ GLOBAL_LIST_EMPTY(the_station_areas) var/secret = FALSE if(tgui_alert(usr, "Do you want your mission secret? (This will prevent ghosts from looking at your map in any way other than through a living player's eyes.)", "Are you $$$ekret?", list("Yes", "No")) == "Yes") secret = TRUE - var/answer = input("What kind?","Away") as null|anything in possible_options + var/answer = input(usr, "What kind?","Away") as null|anything in possible_options switch(answer) if("Custom") - var/mapfile = input("Pick file:", "File") as null|file + var/mapfile = input(usr, "Pick file:", "File") as null|file if(!mapfile) return away_name = "[mapfile] custom" - to_chat(usr,span_notice("Loading [away_name]...")) + to_chat(usr, span_notice("Loading [away_name]...")) var/datum/map_template/template = new(mapfile, "Away Mission") away_level = template.load_new_z(secret) else @@ -645,7 +637,6 @@ GLOBAL_LIST_EMPTY(the_station_areas) log_admin("Admin [key_name(usr)] has loaded [away_name] away mission.") if(!away_level) message_admins("Loading [away_name] failed!") - return /datum/controller/subsystem/mapping/proc/RequestBlockReservation(width, height, z, type = /datum/turf_reservation, turf_type_override) UNTIL((!z || reservation_ready["[z]"]) && !clearing_reserved_turfs) diff --git a/code/controllers/subsystem/statpanel.dm b/code/controllers/subsystem/statpanel.dm index 8c56e601f2b..fd6caa550aa 100644 --- a/code/controllers/subsystem/statpanel.dm +++ b/code/controllers/subsystem/statpanel.dm @@ -54,8 +54,6 @@ SUBSYSTEM_DEF(statpanels) if(!target.holder) target.stat_panel.send_message("remove_admin_tabs") else - target.stat_panel.send_message("update_split_admin_tabs", !!(target.prefs.toggles & SPLIT_ADMIN_TABS)) - if(!("MC" in target.panel_tabs) || !("Tickets" in target.panel_tabs)) target.stat_panel.send_message("add_admin_tabs", target.holder.href_token) @@ -146,6 +144,13 @@ SUBSYSTEM_DEF(statpanels) // Push update target.stat_panel.send_message("update_interviews", data) +/datum/controller/subsystem/statpanels/proc/set_admin_verb_tab(client/target) + var/list/admin_verb_stat_data = SSadmin_verbs.generate_stat_data(target) + if(length(admin_verb_stat_data)) + target.stat_panel.send_message("update_admin_verbs", admin_verb_stat_data) + else + target.stat_panel.send_message("remove_admin_verbs") + /datum/controller/subsystem/statpanels/proc/set_SDQL2_tab(client/target) var/list/sdql2A = list() sdql2A[++sdql2A.len] = list("", "Access Global SDQL2 List", REF(GLOB.sdql2_vv_statobj)) @@ -293,6 +298,9 @@ SUBSYSTEM_DEF(statpanels) set_tickets_tab(target) return TRUE + if(target.stat_tab == "Admin Verbs") + set_admin_verb_tab(target) + if(!length(GLOB.sdql2_queries) && ("SDQL2" in target.panel_tabs)) target.stat_panel.send_message("remove_sdql2") diff --git a/code/controllers/subsystem/tcgsetup.dm b/code/controllers/subsystem/tcgsetup.dm index e52474adac5..511837cf075 100644 --- a/code/controllers/subsystem/tcgsetup.dm +++ b/code/controllers/subsystem/tcgsetup.dm @@ -118,10 +118,10 @@ SUBSYSTEM_DEF(trading_card_game) ///Prints all the cards names /datum/controller/subsystem/trading_card_game/proc/printAllCards() for(var/card_set in cached_cards) - message_admins("Printing the [card_set] set") + to_chat(usr, span_admin("Printing the [card_set] set")) for(var/card in cached_cards[card_set]["ALL"]) var/datum/card/toPrint = cached_cards[card_set]["ALL"][card] - message_admins(toPrint.name) + to_chat(usr, span_admin("[toPrint.name]")) ///Checks the passed type list for missing raritys, or raritys out of bounds /datum/controller/subsystem/trading_card_game/proc/check_cardpacks(card_pack_list) @@ -186,5 +186,5 @@ SUBSYSTEM_DEF(trading_card_game) if(id) var/datum/card/template = cached_cards[pack.series]["ALL"][id] toSend += "\nID:[id] [template.name] [(cardsByCount[id] * 100) / totalCards]% Total:[cardsByCount[id]]" - message_admins(toSend) + to_chat(usr, toSend) qdel(pack) diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 3d2af7012b9..4dd2188e767 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -203,11 +203,11 @@ message = capitalize(message) if(message_mods[RADIO_EXTENSION] == MODE_ADMIN) - client?.cmd_admin_say(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/admin/admin_say, message) return if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN) - client?.dsay(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/game/dead_say, message) return if(check_emote(message, forced)) diff --git a/code/datums/components/puzzgrid.dm b/code/datums/components/puzzgrid.dm index 0f54fce9929..4324101e3cc 100644 --- a/code/datums/components/puzzgrid.dm +++ b/code/datums/components/puzzgrid.dm @@ -276,10 +276,7 @@ /// Debug verb for validating that all puzzgrids can be created successfully. /// Locked behind a verb because it's fairly slow and memory intensive. -/client/proc/validate_puzzgrids() - set name = "Validate Puzzgrid Config" - set category = "Debug" - +ADMIN_VERB(debug, validate_puzzgrids, "", R_DEBUG) var/line_number = 0 for (var/line in world.file2list(PUZZGRID_CONFIG)) @@ -290,16 +287,16 @@ var/line_json_decoded = safe_json_decode(line) if (isnull(line_json_decoded)) - to_chat(src, span_warning("Line [line_number] in puzzgrids.txt is not a JSON: [line]")) + to_chat(usr, span_warning("Line [line_number] in puzzgrids.txt is not a JSON: [line]")) continue var/datum/puzzgrid/puzzgrid = new var/populate_result = puzzgrid.populate(line_json_decoded) if (populate_result != TRUE) - to_chat(src, span_warning("Line [line_number] in puzzgrids.txt is not formatted correctly: [populate_result]")) + to_chat(usr, span_warning("Line [line_number] in puzzgrids.txt is not formatted correctly: [populate_result]")) - to_chat(src, span_notice("Validated. If you did not see any errors, you're in the clear.")) + to_chat(usr, span_notice("Validated. If you did not see any errors, you're in the clear.")) #undef PUZZGRID_CONFIG #undef PUZZGRID_GROUP_COUNT diff --git a/code/datums/keybinding/admin.dm b/code/datums/keybinding/admin.dm index 39fa27f40c3..39165e68609 100644 --- a/code/datums/keybinding/admin.dm +++ b/code/datums/keybinding/admin.dm @@ -16,7 +16,7 @@ . = ..() if(.) return - user.get_admin_say() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/admin/admin_say) return TRUE /datum/keybinding/admin/admin_ghost @@ -30,7 +30,7 @@ . = ..() if(.) return - user.admin_ghost() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/game/aghost) return TRUE /datum/keybinding/admin/player_panel_new @@ -58,7 +58,7 @@ . = ..() if(.) return - user.togglebuildmodeself() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/build_mode/toggle_build_mode_self) return TRUE /datum/keybinding/admin/stealthmode @@ -72,7 +72,7 @@ . = ..() if(.) return - user.stealth() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/admin/stealth_mode) return TRUE /datum/keybinding/admin/invisimin @@ -86,7 +86,7 @@ . = ..() if(.) return - user.invisimin() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/game/invisimin) return TRUE /datum/keybinding/admin/deadsay @@ -100,7 +100,7 @@ . = ..() if(.) return - user.get_dead_say() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/game/dead_say) return TRUE /datum/keybinding/admin/deadmin @@ -114,7 +114,7 @@ . = ..() if(.) return - user.deadmin() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/admin/deadmin) return TRUE /datum/keybinding/admin/readmin diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index f0fe1db1e26..dfd3aa009a9 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -221,7 +221,7 @@ if(!istype(to_vv)) to_chat(usr, span_warning("Invalid antagonist ref to be vv'd.")) return - usr.client?.debug_variables(to_vv) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, to_vv) if (href_list["role_edit"]) var/new_role = input("Select new role", "Assigned role", assigned_role.title) as null|anything in sort_list(SSjob.name_occupations) diff --git a/code/datums/station_traits/admin_panel.dm b/code/datums/station_traits/admin_panel.dm index 02eca48b54f..e81f1455068 100644 --- a/code/datums/station_traits/admin_panel.dm +++ b/code/datums/station_traits/admin_panel.dm @@ -1,9 +1,9 @@ /// Opens the station traits admin panel -/datum/admins/proc/station_traits_panel() - set name = "Modify Station Traits" - set category = "Admin.Events" - var/static/datum/station_traits_panel/station_traits_panel = new +ADMIN_VERB(events, modify_station_traits, "", R_FUN) + var/static/datum/station_traits_panel/station_traits_panel + if(!station_traits_panel) + station_traits_panel = new station_traits_panel.ui_interact(usr) /datum/station_traits_panel diff --git a/code/datums/weakrefs.dm b/code/datums/weakrefs.dm index 27bd5d94330..f78019c3735 100644 --- a/code/datums/weakrefs.dm +++ b/code/datums/weakrefs.dm @@ -105,4 +105,4 @@ return var/datum/R = resolve() if(R) - usr.client.debug_variables(R) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, R) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 9ac44b4460d..f229b39a58c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1283,11 +1283,11 @@ log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to [src]") message_admins(span_notice("[key_name(usr)] has added [amount] units of [chosen_id] to [src]")) - if(href_list[VV_HK_TRIGGER_EXPLOSION] && check_rights(R_FUN)) - usr.client.cmd_admin_explosion(src) + if(href_list[VV_HK_TRIGGER_EXPLOSION]) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/explosion, src) - if(href_list[VV_HK_TRIGGER_EMP] && check_rights(R_FUN)) - usr.client.cmd_admin_emp(src) + if(href_list[VV_HK_TRIGGER_EMP]) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/emp, src) if(href_list[VV_HK_SHOW_HIDDENPRINTS] && check_rights(R_ADMIN)) usr.client.cmd_show_hiddenprints(src) diff --git a/code/game/gamemodes/dynamic/dynamic_simulations.dm b/code/game/gamemodes/dynamic/dynamic_simulations.dm index 63da54becee..7c64859c3ee 100644 --- a/code/game/gamemodes/dynamic/dynamic_simulations.dm +++ b/code/game/gamemodes/dynamic/dynamic_simulations.dm @@ -68,10 +68,8 @@ /// Optional, force this threat level instead of picking randomly through the lorentz distribution var/forced_threat_level -/client/proc/run_dynamic_simulations() - set name = "Run Dynamic Simulations" - set category = "Debug" - +#ifdef TESTING +ADMIN_VERB(debug, run_dynamic_simulations, "", R_DEBUG) var/simulations = input(usr, "Enter number of simulations") as num var/roundstart_players = input(usr, "Enter number of round start players") as num var/forced_threat_level = input(usr, "Enter forced threat level, if you want one") as num | null @@ -100,6 +98,7 @@ message_admins("Writing file...") WRITE_FILE(file("[GLOB.log_directory]/dynamic_simulations.json"), json_encode(outputs)) message_admins("Writing complete.") +#endif /proc/export_dynamic_json_of(ruleset_list) var/list/export = list() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 67c2ecae9c1..8d8aa1dceff 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -237,8 +237,7 @@ GLOBAL_LIST_EMPTY(objects_by_id_tag) if(!(. = ..())) return if(href_list[VV_HK_OSAY]) - if(check_rights(R_FUN, FALSE)) - usr.client.object_say(src) + return // AVD TODO if(href_list[VV_HK_MASS_DEL_TYPE]) if(check_rights(R_DEBUG|R_SERVER)) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 33431a5783b..c189a398b55 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -75,14 +75,7 @@ log_admin("[key_name(usr)] spawned [amount] x [chosen] at [AREACOORD(usr)]") SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/podspawn_atom(object as text) - set category = "Debug" - set desc = "(atom path) Spawn an atom via supply drop" - set name = "Podspawn" - - if(!check_rights(R_SPAWN)) - return - +ADMIN_VERB(debug, podspawn_atom, "Spawn an atom typepath via supply drop", R_SPAWN, object as text) var/chosen = pick_closest_path(object) if(!chosen) return @@ -98,27 +91,22 @@ //we need to set the admin spawn flag for the spawned items so we do it outside of the podspawn proc var/atom/A = new chosen(pod) A.flags_1 |= ADMIN_SPAWNED_1 - log_admin("[key_name(usr)] pod-spawned [chosen] at [AREACOORD(usr)]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Podspawn Atom") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/datum/admins/proc/spawn_cargo(object as text) - set category = "Debug" - set desc = "(atom path) Spawn a cargo crate" - set name = "Spawn Cargo" - - if(!check_rights(R_SPAWN)) - return +ADMIN_VERB(debug, spawn_cargo_crate, "Spawn a cargo crate", R_SPAWN, object as text) var/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/datum/supply_pack))) if(!chosen) return var/datum/supply_pack/S = new chosen S.admin_spawned = TRUE S.generate(get_turf(usr)) - log_admin("[key_name(usr)] spawned cargo pack [chosen] at [AREACOORD(usr)]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn Cargo") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +ADMIN_VERB(debug, toggle_tinted_welding_helmets, "Reduces view range when wearing welding helmets", R_DEBUG) + GLOB.tinted_weldhelh = !GLOB.tinted_weldhelh + to_chat(world, span_bold("Welding Helmet tinting has been [(GLOB.tinted_weldhelh ? "enabled" : "disabled")]")) + log_admin("[key_name(usr)] toggled tinted_weldhelh.") + message_admins("[key_name_admin(usr)] toggled tinted_weldhelh.") /datum/admins/proc/dynamic_mode_options(mob/user) var/dat = {" @@ -143,9 +131,7 @@ user << browse(dat, "window=dyn_mode_options;size=900x650") -/datum/admins/proc/create_or_modify_area() - set category = "Debug" - set name = "Create or modify area" +ADMIN_VERB(debug, create_or_modify_area, "", R_DEBUG) create_area(usr) //Kicks all the clients currently in the lobby. The second parameter (kick_only_afk) determins if an is_afk() check is ran, or if all clients are kicked diff --git a/code/modules/admin/admin_fax_panel.dm b/code/modules/admin/admin_fax_panel.dm index e4126d89c5d..af7fb248958 100644 --- a/code/modules/admin/admin_fax_panel.dm +++ b/code/modules/admin/admin_fax_panel.dm @@ -98,7 +98,7 @@ if("follow") if(!isobserver(usr)) - usr.client?.admin_ghost() + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/game/aghost) usr.client?.admin_follow(action_fax) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 94ea182891f..e69de29bb2d 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -1,67 +0,0 @@ -/atom/proc/investigate_log(message, subject) - if(!message || !subject) - return - var/F = file("[GLOB.log_directory]/[subject].html") - var/source = "[src]" - - if(isliving(src)) - var/mob/living/source_mob = src - source += " ([source_mob.ckey ? source_mob.ckey : "*no key*"])" - - WRITE_FILE(F, "[time_stamp(format = "YYYY-MM-DD hh:mm:ss")] [REF(src)] ([x],[y],[z]) || [source] [message]
") - -/client/proc/investigate_show() - set name = "Investigate" - set category = "Admin.Game" - if(!holder) - return - - var/list/investigates = list( - INVESTIGATE_ACCESSCHANGES, - INVESTIGATE_ATMOS, - INVESTIGATE_BOTANY, - INVESTIGATE_CARGO, - INVESTIGATE_CRAFTING, - INVESTIGATE_DEATHS, - INVESTIGATE_ENGINE, - INVESTIGATE_EXPERIMENTOR, - INVESTIGATE_GRAVITY, - INVESTIGATE_HALLUCINATIONS, - INVESTIGATE_HYPERTORUS, - INVESTIGATE_PORTAL, - INVESTIGATE_PRESENTS, - INVESTIGATE_RADIATION, - INVESTIGATE_RECORDS, - INVESTIGATE_RESEARCH, - INVESTIGATE_WIRES, - ) - - var/list/logs_present = list("notes, memos, watchlist") - var/list/logs_missing = list("---") - - for(var/subject in investigates) - var/temp_file = file("[GLOB.log_directory]/[subject].html") - if(fexists(temp_file)) - logs_present += subject - else - logs_missing += "[subject] (empty)" - - var/list/combined = sort_list(logs_present) + sort_list(logs_missing) - - var/selected = tgui_input_list(src, "Investigate what?", "Investigation", combined) - if(isnull(selected)) - return - if(!(selected in combined) || selected == "---") - return - - selected = replacetext(selected, " (empty)", "") - - if(selected == "notes, memos, watchlist" && check_rights(R_ADMIN)) - browse_messages() - return - - var/F = file("[GLOB.log_directory]/[selected].html") - if(!fexists(F)) - to_chat(src, span_danger("No [selected] logfile was found."), confidential = TRUE) - return - src << browse(F,"window=investigate[selected];size=800x300") diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c8aa474f15d..9ca15b2d2a9 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,304 +1,18 @@ -//admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless -//the procs are cause you can't put the comments in the GLOB var define -GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) -GLOBAL_PROTECT(admin_verbs_default) -/world/proc/AVerbsDefault() - return list( - /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ - /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ - /client/proc/cmd_admin_say, /*admin-only ooc chat*/ - /client/proc/deadmin, /*destroys our own admin datum so we can play as a regular player*/ - /client/proc/debugstatpanel, - /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ - /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ - /client/proc/fix_air, /*resets air in designated radius to its default atmos composition*/ - /client/proc/hide_verbs, /*hides all our adminverbs*/ - /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ - /client/proc/mark_datum_mapview, - /client/proc/reestablish_db_connection, /*reattempt a connection to the database*/ - /client/proc/reload_admins, - /client/proc/requests, - /client/proc/secrets, - /client/proc/stop_sounds, - /client/proc/tag_datum_mapview, - ) -GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) -GLOBAL_PROTECT(admin_verbs_admin) -/world/proc/AVerbsAdmin() - return list( -// Admin datums - /datum/admins/proc/access_news_network, /*allows access of newscasters*/ - /datum/admins/proc/announce, /*priority announce something to all clients.*/ - /datum/admins/proc/display_tags, - /datum/admins/proc/fishing_calculator, - /datum/admins/proc/known_alts_panel, - /datum/admins/proc/show_lag_switch_panel, - /datum/admins/proc/open_borgopanel, - /datum/admins/proc/open_shuttlepanel, /* Opens shuttle manipulator UI */ - /datum/admins/proc/paintings_manager, - /datum/admins/proc/set_admin_notice, /*announcement all clients see when joining the server.*/ - /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/ - /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ - /datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/ - /datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/ - /datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/ - /datum/admins/proc/trophy_manager, - /datum/admins/proc/view_all_circuits, - /datum/verbs/menu/Admin/verb/playerpanel, /* It isn't /datum/admin but it fits no less */ -// Client procs - /client/proc/admin_call_shuttle, /*allows us to call the emergency shuttle*/ - /client/proc/admin_cancel_shuttle, /*allows us to cancel the emergency shuttle, sending it back to centcom*/ - /client/proc/admin_disable_shuttle, /*allows us to disable the emergency shuttle admin-wise so that it cannot be called*/ - /client/proc/admin_enable_shuttle, /*undoes the above*/ - /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ - /client/proc/admin_hostile_environment, /*Allows admins to prevent the emergency shuttle from leaving, also lets admins clear hostile environments if theres one stuck*/ - /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ - /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ - /client/proc/cmd_admin_create_centcom_report, - /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ - /client/proc/cmd_admin_direct_narrate, /*send text directly to a player with no padding. Useful for narratives and fluff-text*/ - /client/proc/cmd_admin_headset_message, /*send a message to somebody through their headset as CentCom*/ - /client/proc/cmd_admin_local_narrate, /*sends text to all mobs within view of atom*/ - /client/proc/cmd_admin_subtle_message, /*send a message to somebody as a 'voice in their head'*/ - /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ - /client/proc/cmd_change_command_name, - /client/proc/centcom_podlauncher,/*Open a window to launch a Supplypod and configure it or it's contents*/ - /client/proc/check_ai_laws, /*shows AI and borg laws*/ - /client/proc/check_antagonists, /*shows all antags*/ - /client/proc/fax_panel, /*send a paper to fax*/ - /client/proc/force_load_lazy_template, - /client/proc/game_panel, /*game panel, allows to change game-mode etc*/ - /client/proc/Getmob, /*teleports a mob to our location*/ - /client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/ - /client/proc/getserverlogs, /*for accessing server logs*/ - /client/proc/getcurrentlogs, /*for accessing server logs for the current round*/ - /client/proc/ghost_pool_protection, /*opens a menu for toggling ghost roles*/ - /client/proc/invisimin, /*allows our mob to go invisible/visible*/ - /client/proc/jumptoarea, - /client/proc/jumptokey, /*allows us to jump to the location of a mob with a certain ckey*/ - /client/proc/jumptomob, /*allows us to jump to a specific mob*/ - /client/proc/jumptoturf, /*allows us to jump to a specific turf*/ - /client/proc/jumptocoord, /*we ghost and jump to a coordinate*/ - /client/proc/list_bombers, - /client/proc/list_dna, - /client/proc/list_fingerprints, - /client/proc/list_law_changes, - /client/proc/list_signalers, - /client/proc/message_pda, /*send a message to somebody on PDA*/ - /client/proc/respawn_character, - /client/proc/show_manifest, - /client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/ - /client/proc/toggle_combo_hud, /* toggle display of the combination pizza antag and taco sci/med/eng hud */ - /client/proc/toggle_view_range, /*changes how far we can see*/ - ) -GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/ban_panel, /client/proc/stickybanpanel)) -GLOBAL_PROTECT(admin_verbs_ban) -GLOBAL_LIST_INIT(admin_verbs_sounds, list(/client/proc/play_local_sound, /client/proc/play_direct_mob_sound, /client/proc/play_sound, /client/proc/set_round_end_sound)) -GLOBAL_PROTECT(admin_verbs_sounds) -GLOBAL_LIST_INIT(admin_verbs_fun, list( -// Admin datums - /datum/admins/proc/station_traits_panel, -// Client procs - /client/proc/admin_away, - /client/proc/add_mob_ability, - /client/proc/admin_change_sec_level, - /client/proc/cinematic, - /client/proc/cmd_admin_add_freeform_ai_law, - /client/proc/cmd_admin_gib_self, - /client/proc/cmd_select_equipment, - /client/proc/command_report_footnote, - /client/proc/delay_command_report, - /client/proc/drop_bomb, - /client/proc/drop_dynex_bomb, - /client/proc/forceEvent, - /client/proc/mass_zombie_cure, - /client/proc/mass_zombie_infection, - /client/proc/object_say, - /client/proc/polymorph_all, - /client/proc/remove_mob_ability, - /client/proc/reset_ooc, - /client/proc/run_weather, - /client/proc/set_dynex_scale, - /client/proc/set_ooc, - /client/proc/show_tip, - /client/proc/smite, - /client/proc/summon_ert, - /client/proc/toggle_nuke, - /client/proc/toggle_random_events, - )) -GLOBAL_PROTECT(admin_verbs_fun) -GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/podspawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character, /datum/admins/proc/beaker_panel)) -GLOBAL_PROTECT(admin_verbs_spawn) -GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) -GLOBAL_PROTECT(admin_verbs_server) -/world/proc/AVerbsServer() - return list( -// Admin datums - /datum/admins/proc/delay, - /datum/admins/proc/delay_round_end, - /datum/admins/proc/end_round, - /datum/admins/proc/restart, - /datum/admins/proc/startnow, - /datum/admins/proc/toggleaban, - /datum/admins/proc/toggleAI, -// Client procs - /client/proc/adminchangemap, - /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ - /client/proc/cmd_debug_del_all, - /client/proc/cmd_debug_force_del_all, - /client/proc/cmd_debug_hard_del_all, - /client/proc/everyone_random, - /client/proc/forcerandomrotate, - /client/proc/generate_job_config, - /client/proc/panicbunker, - /client/proc/toggle_cdn, - /client/proc/toggle_hub, - /client/proc/toggle_interviews, - /client/proc/toggle_random_events, - ) -GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug()) -GLOBAL_PROTECT(admin_verbs_debug) -/world/proc/AVerbsDebug() - return list( - #ifdef TESTING /* Keep these at the top to not make the list look fugly */ - /client/proc/check_missing_sprites, - /client/proc/run_dynamic_simulations, - #endif - /proc/machine_upgrade, - /datum/admins/proc/create_or_modify_area, - /client/proc/adventure_manager, - /client/proc/atmos_control, - /client/proc/callproc, - /client/proc/callproc_datum, - /client/proc/check_bomb_impacts, - /client/proc/check_timer_sources, - /client/proc/clear_dynamic_transit, - /client/proc/cmd_admin_debug_traitor_objectives, - /client/proc/cmd_admin_delete, - /client/proc/cmd_admin_list_open_jobs, - /client/proc/cmd_admin_toggle_fov, - /client/proc/cmd_debug_del_all, - /client/proc/cmd_debug_force_del_all, - /client/proc/cmd_debug_hard_del_all, - /client/proc/cmd_debug_make_powernets, - /client/proc/cmd_debug_mob_lists, - /client/proc/cmd_display_del_log, - /client/proc/cmd_display_init_log, - /client/proc/cmd_display_overlay_log, - /client/proc/Debug2, - /client/proc/debug_controller, - /client/proc/debug_hallucination_weighted_list_per_type, - /client/proc/debug_huds, - /client/proc/debugNatureMapGenerator, - /client/proc/debug_plane_masters, - /client/proc/debug_spell_requirements, - /client/proc/display_sendmaps, - /client/proc/enable_mapping_verbs, - /client/proc/generate_wikichem_list, - /client/proc/get_dynex_power, /*debug verbs for dynex explosions.*/ - /client/proc/get_dynex_range, /*debug verbs for dynex explosions.*/ - /client/proc/jump_to_ruin, - /client/proc/load_circuit, - /client/proc/map_template_load, - /client/proc/map_template_upload, - /client/proc/modify_goals, - /client/proc/open_colorblind_test, - /client/proc/open_lua_editor, - /client/proc/outfit_manager, - /client/proc/populate_world, - /client/proc/pump_random_event, - /client/proc/print_cards, - /client/proc/reload_cards, - /client/proc/reload_configuration, - /client/proc/restart_controller, - /client/proc/run_empty_query, - /client/proc/SDQL2_query, - /client/proc/set_dynex_scale, - /client/proc/spawn_debug_full_crew, - /client/proc/test_cardpack_distribution, - /client/proc/test_movable_UI, - /client/proc/test_snap_UI, - /client/proc/toggle_cdn, - /client/proc/toggle_medal_disable, - /client/proc/unload_ctf, - /client/proc/validate_cards, - /client/proc/validate_puzzgrids, - /client/proc/view_runtimes, - ) -GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release)) -GLOBAL_PROTECT(admin_verbs_possess) -GLOBAL_LIST_INIT(admin_verbs_permissions, list(/client/proc/edit_admin_permissions)) -GLOBAL_PROTECT(admin_verbs_permissions) -GLOBAL_LIST_INIT(admin_verbs_poll, list(/client/proc/poll_panel)) -GLOBAL_PROTECT(admin_verbs_poll) - /client/proc/add_admin_verbs() - if(holder) - control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS - - var/rights = holder.rank_flags() - add_verb(src, GLOB.admin_verbs_default) - if(rights & R_BUILD) - add_verb(src, /client/proc/togglebuildmodeself) - if(rights & R_ADMIN) - add_verb(src, GLOB.admin_verbs_admin) - if(rights & R_BAN) - add_verb(src, GLOB.admin_verbs_ban) - if(rights & R_FUN) - add_verb(src, GLOB.admin_verbs_fun) - if(rights & R_SERVER) - add_verb(src, GLOB.admin_verbs_server) - if(rights & R_DEBUG) - add_verb(src, GLOB.admin_verbs_debug) - if(rights & R_POSSESS) - add_verb(src, GLOB.admin_verbs_possess) - if(rights & R_PERMISSIONS) - add_verb(src, GLOB.admin_verbs_permissions) - if(rights & R_STEALTH) - add_verb(src, /client/proc/stealth) - if(rights & R_ADMIN) - add_verb(src, GLOB.admin_verbs_poll) - if(rights & R_SOUND) - add_verb(src, GLOB.admin_verbs_sounds) - if(CONFIG_GET(string/invoke_youtubedl)) - add_verb(src, /client/proc/play_web_sound) - if(rights & R_SPAWN) - add_verb(src, GLOB.admin_verbs_spawn) + if(!holder) + CRASH("called add_admin_verbs on a client without a holder?") + control_freak = CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS + SSadmin_verbs.assosciate_admin(src) /client/proc/remove_admin_verbs() - remove_verb(src, list( - GLOB.admin_verbs_default, - /client/proc/togglebuildmodeself, - GLOB.admin_verbs_admin, - GLOB.admin_verbs_ban, - GLOB.admin_verbs_fun, - GLOB.admin_verbs_server, - GLOB.admin_verbs_debug, - GLOB.admin_verbs_possess, - GLOB.admin_verbs_permissions, - /client/proc/stealth, - GLOB.admin_verbs_poll, - GLOB.admin_verbs_sounds, - /client/proc/play_web_sound, - GLOB.admin_verbs_spawn, - /*Debug verbs added by "show debug verbs"*/ - GLOB.admin_verbs_debug_mapping, - /client/proc/disable_mapping_verbs, - /client/proc/readmin - )) + SSadmin_verbs.deassosciate_admin(src) -/client/proc/hide_verbs() - set name = "Adminverbs - Hide All" - set category = "Admin" +ADMIN_VERB(admin, hide_all_verbs, "Hide all of your Admin Verbs", NONE) + usr.client.remove_admin_verbs() + add_verb(usr.client, /client/proc/show_verbs) + to_chat(usr, span_admin("Almost all of your adminverbs have been hidden.")) - remove_admin_verbs() - add_verb(src, /client/proc/show_verbs) - - to_chat(src, span_interface("Almost all of your adminverbs have been hidden."), confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide All Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - -/client/proc/show_verbs() +/client/proc/show_verbs() // This is not an ADMIN_VERB for a reason set name = "Adminverbs - Show" set category = "Admin" @@ -308,143 +22,75 @@ GLOBAL_PROTECT(admin_verbs_poll) to_chat(src, span_interface("All of your adminverbs are now visible."), confidential = TRUE) SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Adminverbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - - -/client/proc/admin_ghost() - set category = "Admin.Game" - set name = "Aghost" - if(!holder) +ADMIN_VERB(game, aghost, "Observe without leaving the game", R_ADMIN) + if(isnewplayer(usr)) + to_chat(usr, span_red("Error: AGhost: Cannot admin-ghost wile in the lobby. Join or Observe first.")) return - . = TRUE - if(isobserver(mob)) - //re-enter - var/mob/dead/observer/ghost = mob - if(!ghost.mind || !ghost.mind.current) //won't do anything if there is no body - return FALSE - if(!ghost.can_reenter_corpse) + + if(isobserver(usr)) + var/mob/dead/observer/admin_ghost = usr + if(!admin_ghost.mind?.current) + to_chat(usr, span_red("Error: AGhost: You do not have a body to return to!")) + return + if(!admin_ghost.can_reenter_corpse) log_admin("[key_name(usr)] re-entered corpse") message_admins("[key_name_admin(usr)] re-entered corpse") - ghost.can_reenter_corpse = 1 //force re-entering even when otherwise not possible - ghost.reenter_corpse() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Reenter") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - else if(isnewplayer(mob)) - to_chat(src, "Error: Aghost: Can't admin-ghost whilst in the lobby. Join or Observe first.", confidential = TRUE) - return FALSE + admin_ghost.can_reenter_corpse = TRUE + admin_ghost.reenter_corpse() + return + + log_admin("[key_name(usr)] admin ghosted.") + message_admins("[key_name_admin(usr)] admin ghosted.") + usr.ghostize(TRUE) + if(usr && !usr.key) + usr.key = "@[key]" // If the key starts with '@' it designates an admin ghost + +ADMIN_VERB(game, invisimin, "Toggles ghost-like invisibility", R_ADMIN) + if(initial(usr.invisibility) == INVISIBILITY_OBSERVER) + to_chat(usr, span_boldannounce("Invisimin toggle failed. You are already an invisible mob like a ghost."), confidential = TRUE) + return + if(usr.invisibility == INVISIBILITY_OBSERVER) + usr.invisibility = initial(usr.invisibility) + to_chat(usr, span_boldannounce("Invisimin off. Invisibility reset."), confidential = TRUE) else - //ghostize - log_admin("[key_name(usr)] admin ghosted.") - message_admins("[key_name_admin(usr)] admin ghosted.") - var/mob/body = mob - body.ghostize(TRUE) - init_verbs() - if(body && !body.key) - body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus - SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + usr.invisibility = INVISIBILITY_OBSERVER + to_chat(usr, span_adminnotice("Invisimin on. You are now as invisible as a ghost."), confidential = TRUE) -/client/proc/invisimin() - set name = "Invisimin" - set category = "Admin.Game" - set desc = "Toggles ghost-like invisibility (Don't abuse this)" - if(holder && mob) - if(initial(mob.invisibility) == INVISIBILITY_OBSERVER) - to_chat(mob, span_boldannounce("Invisimin toggle failed. You are already an invisible mob like a ghost."), confidential = TRUE) - return - if(mob.invisibility == INVISIBILITY_OBSERVER) - mob.invisibility = initial(mob.invisibility) - to_chat(mob, span_boldannounce("Invisimin off. Invisibility reset."), confidential = TRUE) - else - mob.invisibility = INVISIBILITY_OBSERVER - to_chat(mob, span_adminnotice("Invisimin on. You are now as invisible as a ghost."), confidential = TRUE) +ADMIN_VERB(game, check_antagonists, "", R_ADMIN) + usr.client.holder.check_antagonists() + log_admin("[key_name(usr)] checked antagonists.") //for tsar~ get a room you two + if(!isobserver(usr) && SSticker.HasRoundStarted()) + message_admins("[key_name_admin(usr)] checked antagonists.") -/client/proc/check_antagonists() - set name = "Check Antagonists" - set category = "Admin.Game" - if(holder) - holder.check_antagonists() - log_admin("[key_name(usr)] checked antagonists.") //for tsar~ - if(!isobserver(usr) && SSticker.HasRoundStarted()) - message_admins("[key_name_admin(usr)] checked antagonists.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Antagonists") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, list_bombers, "", R_ADMIN) + usr.client.holder.list_bombers() -/client/proc/list_bombers() - set name = "List Bombers" - set category = "Admin.Game" - if(!holder) - return - holder.list_bombers() - SSblackbox.record_feedback("tally", "admin_verb", 1, "List Bombers") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, list_signalers, "", R_ADMIN) + usr.client.holder.list_signalers() -/client/proc/list_signalers() - set name = "List Signalers" - set category = "Admin.Game" - if(!holder) - return - holder.list_signalers() - SSblackbox.record_feedback("tally", "admin_verb", 1, "List Signalers") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, list_law_changes, "", R_ADMIN) + usr.client.holder.list_law_changes() -/client/proc/list_law_changes() - set name = "List Law Changes" - set category = "Debug" - if(!holder) - return - holder.list_law_changes() - SSblackbox.record_feedback("tally", "admin_verb", 1, "List Law Changes") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, show_manifest, "", R_ADMIN) + usr.client.holder.show_manifest() -/client/proc/show_manifest() - set name = "Show Manifest" - set category = "Debug" - if(!holder) - return - holder.show_manifest() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Manifest") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, list_dna, "", R_ADMIN) + usr.client.holder.list_dna() -/client/proc/list_dna() - set name = "List DNA" - set category = "Debug" - if(!holder) - return - holder.list_dna() - SSblackbox.record_feedback("tally", "admin_verb", 1, "List DNA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, list_fingerprints, "", R_ADMIN) + usr.client.holder.list_fingerprints() -/client/proc/list_fingerprints() - set name = "List Fingerprints" - set category = "Debug" - if(!holder) - return - holder.list_fingerprints() - SSblackbox.record_feedback("tally", "admin_verb", 1, "List Fingerprints") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(admin, banning_panel, "", R_BAN) + usr.client.holder.ban_panel() -/client/proc/ban_panel() - set name = "Banning Panel" - set category = "Admin" - if(!check_rights(R_BAN)) - return - holder.ban_panel() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Banning Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(admin, unbanning_panel, "", R_BAN) + usr.client.holder.unban_panel() -/client/proc/unban_panel() - set name = "Unbanning Panel" - set category = "Admin" - if(!check_rights(R_BAN)) - return - holder.unban_panel() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Unbanning Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, game_panel, "", NONE) + usr.client.holder.Game() -/client/proc/game_panel() - set name = "Game Panel" - set category = "Admin.Game" - if(holder) - holder.Game() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Game Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/poll_panel() - set name = "Server Poll Management" - set category = "Admin" - if(!check_rights(R_POLL)) - return - holder.poll_list_panel() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Server Poll Management") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(admin, server_poll_management, "", R_POLL) + usr.client.holder.poll_list_panel() /// Returns this client's stealthed ckey /client/proc/getStealthKey() @@ -479,18 +125,11 @@ GLOBAL_PROTECT(admin_verbs_poll) /client/proc/createStealthKey() GLOB.stealthminID["[ckey]"] = generateStealthCkey() -/client/proc/stealth() - set category = "Admin" - set name = "Stealth Mode" - if(!holder) - return - - if(holder.fakekey) - disable_stealth_mode() +ADMIN_VERB(admin, stealth_mode, "Makes you unable to be seen through most means", R_STEALTH) + if(usr.client.holder.fakekey) + usr.client.disable_stealth_mode() else - enable_stealth_mode() - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Stealth Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + usr.client.enable_stealth_mode() #define STEALTH_MODE_TRAIT "stealth_mode" @@ -533,26 +172,22 @@ GLOBAL_PROTECT(admin_verbs_poll) #undef STEALTH_MODE_TRAIT -/client/proc/drop_bomb() - set category = "Admin.Fun" - set name = "Drop Bomb" - set desc = "Cause an explosion of varying strength at your location." - +ADMIN_VERB(fun, drop_bomb, "Cause an explosion of varying strength at your location", R_FUN) var/list/choices = list("Small Bomb (1, 2, 3, 3)", "Medium Bomb (2, 3, 4, 4)", "Big Bomb (3, 5, 7, 5)", "Maxcap", "Custom Bomb") - var/choice = tgui_input_list(src, "What size explosion would you like to produce? NOTE: You can do all this rapidly and in an IC manner (using cruise missiles!) with the Config/Launch Supplypod verb. WARNING: These ignore the maxcap", "Drop Bomb", choices) + var/choice = tgui_input_list(usr, "What size explosion would you like to produce? NOTE: You can do all this rapidly and in an IC manner (using cruise missiles!) with the Config/Launch Supplypod verb. WARNING: These ignore the maxcap", "Drop Bomb", choices) if(isnull(choice)) return - var/turf/epicenter = mob.loc + var/turf/epicenter = get_turf(usr) switch(choice) if("Small Bomb (1, 2, 3, 3)") - explosion(epicenter, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flash_range = 3, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob) + explosion(epicenter, devastation_range = 1, heavy_impact_range = 2, light_impact_range = 3, flash_range = 3, adminlog = TRUE, ignorecap = TRUE, explosion_cause = usr) if("Medium Bomb (2, 3, 4, 4)") - explosion(epicenter, devastation_range = 2, heavy_impact_range = 3, light_impact_range = 4, flash_range = 4, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob) + explosion(epicenter, devastation_range = 2, heavy_impact_range = 3, light_impact_range = 4, flash_range = 4, adminlog = TRUE, ignorecap = TRUE, explosion_cause = usr) if("Big Bomb (3, 5, 7, 5)") - explosion(epicenter, devastation_range = 3, heavy_impact_range = 5, light_impact_range = 7, flash_range = 5, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob) + explosion(epicenter, devastation_range = 3, heavy_impact_range = 5, light_impact_range = 7, flash_range = 5, adminlog = TRUE, ignorecap = TRUE, explosion_cause = usr) if("Maxcap") - explosion(epicenter, devastation_range = GLOB.MAX_EX_DEVESTATION_RANGE, heavy_impact_range = GLOB.MAX_EX_HEAVY_RANGE, light_impact_range = GLOB.MAX_EX_LIGHT_RANGE, flash_range = GLOB.MAX_EX_FLASH_RANGE, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob) + explosion(epicenter, devastation_range = GLOB.MAX_EX_DEVESTATION_RANGE, heavy_impact_range = GLOB.MAX_EX_HEAVY_RANGE, light_impact_range = GLOB.MAX_EX_LIGHT_RANGE, flash_range = GLOB.MAX_EX_FLASH_RANGE, adminlog = TRUE, ignorecap = TRUE, explosion_cause = usr) if("Custom Bomb") var/range_devastation = input("Devastation range (in tiles):") as null|num if(range_devastation == null) @@ -569,118 +204,85 @@ GLOBAL_PROTECT(admin_verbs_poll) if(range_devastation > GLOB.MAX_EX_DEVESTATION_RANGE || range_heavy > GLOB.MAX_EX_HEAVY_RANGE || range_light > GLOB.MAX_EX_LIGHT_RANGE || range_flash > GLOB.MAX_EX_FLASH_RANGE) if(tgui_alert(usr, "Bomb is bigger than the maxcap. Continue?",,list("Yes","No")) != "Yes") return - epicenter = mob.loc //We need to reupdate as they may have moved again - explosion(epicenter, devastation_range = range_devastation, heavy_impact_range = range_heavy, light_impact_range = range_light, flash_range = range_flash, adminlog = TRUE, ignorecap = TRUE, explosion_cause = mob) + epicenter = get_turf(usr) //We need to reupdate as they may have moved again + explosion(epicenter, devastation_range = range_devastation, heavy_impact_range = range_heavy, light_impact_range = range_light, flash_range = range_flash, adminlog = TRUE, ignorecap = TRUE, explosion_cause = usr) message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].") log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/drop_dynex_bomb() - set category = "Admin.Fun" - set name = "Drop DynEx Bomb" - set desc = "Cause an explosion of varying strength at your location." - - var/ex_power = input("Explosive Power:") as null|num - var/turf/epicenter = mob.loc +ADMIN_VERB(fun, drop_dynex_bomb, "Cause an explosion of varting strength at your location", R_FUN) + var/ex_power = input(usr, "Explosive Power:") as null|num + var/turf/epicenter = get_turf(usr) if(ex_power && epicenter) dyn_explosion(epicenter, ex_power) message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].") log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Dynamic Bomb") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/get_dynex_range() - set category = "Debug" - set name = "Get DynEx Range" - set desc = "Get the estimated range of a bomb, using explosive power." - - var/ex_power = input("Explosive Power:") as null|num +ADMIN_VERB(debug, get_dynex_range, "Get the estimated range of a bomb, using explosive power", R_FUN) + var/ex_power = input(usr, "Explosive Power:") as null|num if (isnull(ex_power)) return var/range = round((2 * ex_power)**GLOB.DYN_EX_SCALE) - to_chat(usr, "Estimated Explosive Range: (Devastation: [round(range*0.25)], Heavy: [round(range*0.5)], Light: [round(range)])", confidential = TRUE) + to_chat(usr, "Estimated Explosive Range: (Devastation: [round(range*0.25)], Heavy: [round(range*0.5)], Light: [round(range)])") -/client/proc/get_dynex_power() - set category = "Debug" - set name = "Get DynEx Power" - set desc = "Get the estimated required power of a bomb, to reach a specific range." - - var/ex_range = input("Light Explosion Range:") as null|num +ADMIN_VERB(debug, get_dynex_power, "Get the estimated power of a bomb, to reach the specific range", R_FUN) + var/ex_range = input(usr, "Light Explosion Range:") as null|num if (isnull(ex_range)) return var/power = (0.5 * ex_range)**(1/GLOB.DYN_EX_SCALE) - to_chat(usr, "Estimated Explosive Power: [power]", confidential = TRUE) - -/client/proc/set_dynex_scale() - set category = "Debug" - set name = "Set DynEx Scale" - set desc = "Set the scale multiplier of dynex explosions. The default is 0.5." + to_chat(usr, "Estimated Explosive Power: [power]") +ADMIN_VERB(debug, set_dynex_scale, "Set the scale multiplier on dynex explosions. Default of 0.5", R_FUN) var/ex_scale = input("New DynEx Scale:") as null|num - if(!ex_scale) + if(isnull(ex_scale)) return GLOB.DYN_EX_SCALE = ex_scale log_admin("[key_name(usr)] has modified Dynamic Explosion Scale: [ex_scale]") message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]") -/client/proc/atmos_control() - set name = "Atmos Control Panel" - set category = "Debug" - if(!check_rights(R_DEBUG)) - return - SSair.ui_interact(mob) +ADMIN_VERB(debug, atmos_control_panel, "", R_DEBUG) + SSair.ui_interact(usr) -/client/proc/reload_cards() - set name = "Reload Cards" - set category = "Debug" - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(trading_card_game, reload_cards, "", R_DEBUG) if(!SStrading_card_game.loaded) - message_admins("The card subsystem is not currently loaded") + to_chat(usr, span_admin("The card subsystem is not currently loaded!")) return + message_admins("[key_name_admin(usr)] manually reloaded SStrading_card_game.") SStrading_card_game.reloadAllCardFiles() -/client/proc/validate_cards() - set name = "Validate Cards" - set category = "Debug" - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(trading_card_game, validate_cards, "", R_DEBUG) if(!SStrading_card_game.loaded) - message_admins("The card subsystem is not currently loaded") + to_chat(usr, span_admin("The card subsystem is not currently loaded!")) return + var/message = SStrading_card_game.check_cardpacks(SStrading_card_game.card_packs) message += SStrading_card_game.check_card_datums() if(message) - message_admins(message) + to_chat(usr, span_admin(message)) else - message_admins("No errors found in card rarities or overrides.") + to_chat(usr, span_admin("No errors found in card rarities or overrides.")) -/client/proc/test_cardpack_distribution() - set name = "Test Cardpack Distribution" - set category = "Debug" - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(trading_card_game, test_cardpack_distribution, "", R_DEBUG) if(!SStrading_card_game.loaded) - message_admins("The card subsystem is not currently loaded") + to_chat(usr, span_admin("The card subsystem is not currently loaded!")) return + var/pack = tgui_input_list(usr, "Which pack should we test?", "You fucked it didn't you", sort_list(SStrading_card_game.card_packs)) if(!pack) return + var/batch_count = tgui_input_number(usr, "How many times should we open it?", "Don't worry, I understand") var/batch_size = tgui_input_number(usr, "How many cards per batch?", "I hope you remember to check the validation") var/guar = tgui_input_number(usr, "Should we use the pack's guaranteed rarity? If so, how many?", "We've all been there. Man you should have seen the old system") - SStrading_card_game.check_card_distribution(pack, batch_size, batch_count, guar) -/client/proc/print_cards() - set name = "Print Cards" - set category = "Debug" +ADMIN_VERB(trading_card_game, print_cards, "", R_DEBUG) + if(!SStrading_card_game.loaded) + to_chat(usr, span_admin("The card subsystem is not currently loaded!")) + return + SStrading_card_game.printAllCards() -/client/proc/give_spell(mob/spell_recipient in GLOB.mob_list) - set category = "Admin.Fun" - set name = "Give Spell" - set desc = "Gives a spell to a mob." - +ADMIN_VERB(fun, give_mob_spell, "", R_FUN, mob/spell_recipient in GLOB.mob_list) var/which = tgui_alert(usr, "Chose by name or by type path?", "Chose option", list("Name", "Typepath")) if(!which) return @@ -712,26 +314,18 @@ GLOBAL_PROTECT(admin_verbs_poll) to_chat(usr, span_warning("The intended spell recipient no longer exists.")) return - SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_admin("[key_name(usr)] gave [key_name(spell_recipient)] the spell [chosen_spell][robeless ? " (Forced robeless)" : ""].") message_admins("[key_name_admin(usr)] gave [key_name_admin(spell_recipient)] the spell [chosen_spell][robeless ? " (Forced robeless)" : ""].") - var/datum/action/cooldown/spell/new_spell = new spell_path(spell_recipient.mind || spell_recipient) - if(robeless) new_spell.spell_requirements &= ~SPELL_REQUIRES_WIZARD_GARB new_spell.Grant(spell_recipient) - if(!spell_recipient.mind) to_chat(usr, span_userdanger("Spells given to mindless mobs will belong to the mob and not their mind, \ and as such will not be transferred if their mind changes body (Such as from Mindswap).")) -/client/proc/remove_spell(mob/removal_target in GLOB.mob_list) - set category = "Admin.Fun" - set name = "Remove Spell" - set desc = "Remove a spell from the selected mob." - +ADMIN_VERB(fun, remove_spell, "", R_FUN, mob/removal_target in GLOB.mob_list) var/list/target_spell_list = list() for(var/datum/action/cooldown/spell/spell in removal_target.actions) target_spell_list[spell.name] = spell @@ -749,65 +343,57 @@ GLOBAL_PROTECT(admin_verbs_poll) qdel(to_remove) log_admin("[key_name(usr)] removed the spell [chosen_spell] from [key_name(removal_target)].") message_admins("[key_name_admin(usr)] removed the spell [chosen_spell] from [key_name_admin(removal_target)].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/give_disease(mob/living/T in GLOB.mob_living_list) - set category = "Admin.Fun" - set name = "Give Disease" - set desc = "Gives a Disease to a mob." - if(!istype(T)) - to_chat(src, span_notice("You can only give a disease to a mob of type /mob/living."), confidential = TRUE) +ADMIN_VERB(fun, give_disease, "Give Disease", R_FUN, mob/living/victim in GLOB.mob_living_list) + var/datum/disease/disease_type = input(usr, "Choose the disease to give to that guy", "ACHOO") as null|anything in sort_list(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc)) + if(!disease_type) return - var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in sort_list(SSdisease.diseases, GLOBAL_PROC_REF(cmp_typepaths_asc)) - if(!D) - return - T.ForceContractDisease(new D, FALSE, TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Disease") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(usr)] gave [key_name(T)] the disease [D].") - message_admins(span_adminnotice("[key_name_admin(usr)] gave [key_name_admin(T)] the disease [D].")) + victim.ForceContractDisease(new disease_type, FALSE, TRUE) -/client/proc/object_say(obj/O in world) - set category = "Admin.Events" - set name = "OSay" - set desc = "Makes an object say something." + log_admin("[key_name(usr)] gave [key_name(victim)] the disease [disease_type].") + message_admins(span_adminnotice("[key_name_admin(usr)] gave [key_name_admin(victim)] the disease [disease_type].")) + +ADMIN_CONTEXT_ENTRY(context_object_say, "Object Say", R_FUN, obj/target in world) var/message = tgui_input_text(usr, "What do you want the message to be?", "Make Sound", encode = FALSE) if(!message) return - O.say(message, sanitize = FALSE) - log_admin("[key_name(usr)] made [O] at [AREACOORD(O)] say \"[message]\"") - message_admins(span_adminnotice("[key_name_admin(usr)] made [O] at [AREACOORD(O)]. say \"[message]\"")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Object Say") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/togglebuildmodeself() - set name = "Toggle Build Mode Self" - set category = "Admin.Events" - if (!(holder.rank_flags() & R_BUILD)) - return - if(src.mob) - togglebuildmode(src.mob) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + target.say(message, sanitize = FALSE) + log_admin("[key_name(usr)] made [target] at [AREACOORD(target)] say \"[message]\"") + message_admins(span_adminnotice("[key_name_admin(usr)] made [target] at [AREACOORD(target)]. say \"[message]\"")) -/client/proc/check_ai_laws() - set name = "Check AI Laws" - set category = "Admin.Game" - if(holder) - src.holder.output_ai_laws() +ADMIN_VERB(build_mode, toggle_build_mode_self, "", R_BUILD) + togglebuildmode(usr) -/client/proc/deadmin() - set name = "Deadmin" - set category = "Admin" - set desc = "Shed your admin powers." +ADMIN_VERB(game, check_ai_laws, "", R_ADMIN) + var/law_bound_entities = 0 + for(var/mob/living/silicon/subject as anything in GLOB.silicon_mobs) + law_bound_entities++ - if(!holder) - return + var/message = "" - holder.deactivate() + if(isAI(subject)) + message += "AI [key_name(subject, usr)]'s laws:" + else if(iscyborg(subject)) + var/mob/living/silicon/robot/borg = subject + message += "CYBORG [key_name(subject, usr)] [borg.connected_ai?"(Slaved to: [key_name(borg.connected_ai)])":"(Independent)"]: laws:" + else if (ispAI(subject)) + message += "pAI [key_name(subject, usr)]'s laws:" + else + message += "SOMETHING SILICON [key_name(subject, usr)]'s laws:" - to_chat(src, span_interface("You are now a normal player.")) - log_admin("[src] deadminned themselves.") - message_admins("[src] deadminned themselves.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Deadmin") + message += "
" -/client/proc/readmin() + if (!subject.laws) + message += "[key_name(subject, usr)]'s laws are null?? Contact a coder." + else + message += jointext(subject.laws.get_law_list(include_zeroth = TRUE), "
") + + to_chat(usr, message, confidential = TRUE) + + if(!law_bound_entities) + to_chat(usr, "No law bound entities located", confidential = TRUE) + +/client/proc/readmin() // not an ADMIN_VERB for a reason set name = "Readmin" set category = "Admin" set desc = "Regain your admin powers." @@ -832,47 +418,30 @@ GLOBAL_PROTECT(admin_verbs_poll) log_admin("[src] re-adminned themselves.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Readmin") -/client/proc/populate_world(amount = 50) - set name = "Populate World" - set category = "Debug" - set desc = "(\"Amount of mobs to create\") Populate the world with test mobs." - +ADMIN_VERB(debug, populate_world, "Populate the world with the given number of test mobs", R_DEBUG, amount = 50 as num) for (var/i in 1 to amount) var/turf/tile = get_safe_random_station_turf() var/mob/living/carbon/human/hooman = new(tile) hooman.equipOutfit(pick(subtypesof(/datum/outfit))) testing("Spawned test mob at [get_area_name(tile, TRUE)] ([tile.x],[tile.y],[tile.z])") -/client/proc/toggle_AI_interact() - set name = "Toggle Admin AI Interact" - set category = "Admin.Game" - set desc = "Allows you to interact with most machines as an AI would as a ghost" +ADMIN_VERB(game, toggle_admin_ai_interaction, "Allows you to interact with most machines as an AI would as a ghost", R_ADMIN) + usr.client.AI_Interact = !usr.client.AI_Interact + if(usr && isAdminGhostAI(usr)) + usr.has_unlimited_silicon_privilege = usr.client.AI_Interact - AI_Interact = !AI_Interact - if(mob && isAdminGhostAI(mob)) - mob.has_unlimited_silicon_privilege = AI_Interact + log_admin("[key_name(usr)] has [usr.client.AI_Interact ? "activated" : "deactivated"] Admin AI Interact") + message_admins("[key_name_admin(usr)] has [usr.client.AI_Interact ? "activated" : "deactivated"] their AI interaction") - log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact") - message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction") - -/client/proc/debugstatpanel() - set name = "Debug Stat Panel" - set category = "Debug" - - src.stat_panel.send_message("create_debug") - -/client/proc/admin_2fa_verify() +/client/proc/admin_2fa_verify() // not an ADMIN_VERB for a reason set name = "Verify Admin" set category = "Admin" var/datum/admins/admin = GLOB.admin_datums[ckey] admin?.associate(src) -/client/proc/display_sendmaps() - set name = "Send Maps Profile" - set category = "Debug" - - src << link("?debug=profile&type=sendmaps&window=test") +ADMIN_VERB(debug, send_maps_profile, "", R_DEBUG) + usr.client << link("?debug=profile&type=sendmaps&window=test") /** * Debug verb that spawns human crewmembers @@ -882,32 +451,24 @@ GLOBAL_PROTECT(admin_verbs_poll) * This spawns humans with minds and jobs, but does NOT make them 'players'. * They're all clientles mobs with minds / jobs. */ -/client/proc/spawn_debug_full_crew() - set name = "Spawn Debug Full Crew" - set desc = "Creates a full crew for the station, filling the datacore and assigning them all minds / jobs. Don't do this on live" - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return - - var/mob/admin = usr +ADMIN_VERB(debug, spawn_debug_full_crew, "Creates a full crew for the station, filling the datacore and assigning them all minds/jobs. Don't do this on live", R_DEBUG) if(SSticker.current_state != GAME_STATE_PLAYING) - to_chat(admin, "You should only be using this after a round has setup and started.") + to_chat(usr, "You should only be using this after a round has setup and started.") return // Two input checks here to make sure people are certain when they're using this. - if(tgui_alert(admin, "This command will create a bunch of dummy crewmembers with minds, job, and datacore entries, which will take a while and fill the manifest.", "Spawn Crew", list("Yes", "Cancel")) != "Yes") + if(tgui_alert(usr, "This command will create a bunch of dummy crewmembers with minds, job, and datacore entries, which will take a while and fill the manifest.", "Spawn Crew", list("Yes", "Cancel")) != "Yes") return - if(tgui_alert(admin, "I sure hope you aren't doing this on live. Are you sure?", "Spawn Crew (Be certain)", list("Yes", "Cancel")) != "Yes") + if(tgui_alert(usr, "I sure hope you aren't doing this on live. Are you sure?", "Spawn Crew (Be certain)", list("Yes", "Cancel")) != "Yes") return // Find the observer spawn, so we have a place to dump the dummies. var/obj/effect/landmark/observer_start/observer_point = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list var/turf/destination = get_turf(observer_point) if(!destination) - to_chat(admin, "Failed to find the observer spawn to send the dummies.") + to_chat(usr, "Failed to find the observer spawn to send the dummies.") return // Okay, now go through all nameable occupations. @@ -929,7 +490,7 @@ GLOBAL_PROTECT(admin_verbs_poll) // Assign the rank to the new player dummy. if(!SSjob.AssignRole(new_guy, job)) qdel(new_guy) - to_chat(admin, "[rank] wasn't able to be spawned.") + to_chat(usr, "[rank] wasn't able to be spawned.") continue // It's got a job, spawn in a human and shove it in the human. @@ -950,13 +511,11 @@ GLOBAL_PROTECT(admin_verbs_poll) number_made++ CHECK_TICK - to_chat(admin, "[number_made] crewmembers have been created.") + to_chat(usr, "[number_made] crewmembers have been created.") /// Debug verb for seeing at a glance what all spells have as set requirements -/client/proc/debug_spell_requirements() - set name = "Show Spell Requirements" - set category = "Debug" +ADMIN_VERB(debug, show_spell_requirements, "seeing at a glance what all spells have as set requirements", R_DEBUG) var/header = "Name Requirements" var/all_requirements = list() for(var/datum/action/cooldown/spell/spell as anything in typesof(/datum/action/cooldown/spell)) @@ -986,16 +545,11 @@ GLOBAL_PROTECT(admin_verbs_poll) var/page_style = "" var/page_contents = "[page_style][header][jointext(all_requirements, "")]
" - var/datum/browser/popup = new(mob, "spellreqs", "Spell Requirements", 600, 400) + var/datum/browser/popup = new(usr, "spellreqs", "Spell Requirements", 600, 400) popup.set_content(page_contents) popup.open() -/client/proc/force_load_lazy_template() - set name = "Load/Jump Lazy Template" - set category = "Admin.Events" - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(events, load_jump_lazy_template, "", R_ADMIN) var/list/choices = LAZY_TEMPLATE_KEY_LIST_ALL() var/choice = tgui_input_list(usr, "Key?", "Lazy Loader", choices) if(!choice) @@ -1017,7 +571,7 @@ GLOBAL_PROTECT(admin_verbs_poll) return if(!isobserver(usr)) - admin_ghost() + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/game/aghost) usr.forceMove(coords2turf(reservation.bottom_left_coords)) message_admins("[key_name_admin(usr)] has loaded lazy template '[choice]'") diff --git a/code/modules/admin/adminmenu.dm b/code/modules/admin/adminmenu.dm deleted file mode 100644 index b7d85ccff51..00000000000 --- a/code/modules/admin/adminmenu.dm +++ /dev/null @@ -1,11 +0,0 @@ -/datum/verbs/menu/Admin/Generate_list(client/C) - if (C.holder) - . = ..() - -/datum/verbs/menu/Admin/verb/playerpanel() - set name = "Player Panel" - set desc = "Player Panel" - set category = "Admin.Game" - if(usr.client.holder) - usr.client.holder.player_panel_new() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index 25a2ee4a72c..5a765cb8f21 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -92,11 +92,8 @@ GLOBAL_PROTECT(AdminProcCallHandler) usr = lastusr handler.remove_caller(user) -/client/proc/callproc() - set category = "Debug" - set name = "Advanced ProcCall" - set waitfor = FALSE - callproc_blocking() +ADMIN_VERB(debug, advanced_proccall, "", R_DEBUG) + usr.client.callproc_blocking() /client/proc/callproc_blocking(list/get_retval) if(!check_rights(R_DEBUG)) @@ -230,34 +227,29 @@ GLOBAL_PROTECT(LastAdminCalledProc) return (GLOB.AdminProcCaller && GLOB.AdminProcCaller == usr?.client?.ckey) || (GLOB.AdminProcCallHandler && usr == GLOB.AdminProcCallHandler) #endif -/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf) - set category = "Debug" - set name = "Atom ProcCall" - set waitfor = FALSE - - if(!check_rights(R_DEBUG)) - return +ADMIN_CONTEXT_ENTRY(context_callproc, "Atom ProcCall", R_DEBUG, atom/target in world) + set waitfor = 0 var/procname = input("Proc name, eg: fake_blood","Proc:", null) as text|null if(!procname) return - if(!hascall(A,procname)) - to_chat(usr, "Error: callproc_datum(): type [A.type] has no proc named [procname].", confidential = TRUE) + if(!hascall(target, procname)) + to_chat(usr, "Error: callproc_datum(): type [target.type] has no proc named [procname].", confidential = TRUE) return var/list/lst = get_callproc_args() if(!lst) return - if(!A || !is_valid_src(A)) + if(!target || !is_valid_src(target)) to_chat(usr, span_warning("Error: callproc_datum(): owner of proc no longer exists."), confidential = TRUE) return - log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." - message_admins(msg) - admin_ticket_log(A, msg) - 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! - var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc + log_admin("[key_name(usr)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") + var/msg = "[key_name(usr)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]." + message_admins(msg) + admin_ticket_log(target, msg) + + var/returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc . = get_callproc_returnval(returnval,procname) if(.) to_chat(usr, ., confidential = TRUE) diff --git a/code/modules/admin/force_event.dm b/code/modules/admin/force_event.dm index d0d332b7d6c..13de1c0da7d 100644 --- a/code/modules/admin/force_event.dm +++ b/code/modules/admin/force_event.dm @@ -1,18 +1,9 @@ ///Allows an admin to force an event -/client/proc/forceEvent() - set name = "Trigger Event" - set category = "Admin.Events" - - if(!holder || !check_rights(R_FUN)) - return - - holder.forceEvent() +ADMIN_VERB(events, trigger_event, "", R_FUN) + usr.client.holder.forceEvent() ///Opens up the Force Event Panel /datum/admins/proc/forceEvent() - if(!check_rights(R_FUN)) - return - var/datum/force_event/ui = new(usr) ui.ui_interact(usr) diff --git a/code/modules/admin/known_alts.dm b/code/modules/admin/known_alts.dm index d6486f77bd7..75564269695 100644 --- a/code/modules/admin/known_alts.dm +++ b/code/modules/admin/known_alts.dm @@ -186,9 +186,3 @@ GLOBAL_DATUM_INIT(known_alts, /datum/known_alts, new) "} client << browse(html, "window=known_alts;size=700x400") - -/datum/admins/proc/known_alts_panel() - set name = "Known Alts Panel" - set category = "Admin" - - GLOB.known_alts.show_panel(usr.client) diff --git a/code/modules/admin/outfit_editor.dm b/code/modules/admin/outfit_editor.dm index 67196c54bd4..87a7275ea99 100644 --- a/code/modules/admin/outfit_editor.dm +++ b/code/modules/admin/outfit_editor.dm @@ -110,7 +110,7 @@ GLOB.custom_outfits -= drip SStgui.update_user_uis(owner.mob) if("vv") - owner.debug_variables(drip) + SSadmin_verbs.dynamic_invoke_admin_verb(owner, /mob/admin_module_holder/debug/view_variables, drip) /datum/outfit_editor/proc/set_item(slot, obj/item/choice) diff --git a/code/modules/admin/outfit_manager.dm b/code/modules/admin/outfit_manager.dm index fcb41b3f2f1..963af54e161 100644 --- a/code/modules/admin/outfit_manager.dm +++ b/code/modules/admin/outfit_manager.dm @@ -1,13 +1,7 @@ -/client/proc/outfit_manager() - set category = "Debug" - set name = "Outfit Manager" - - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(debug, outfit_manager, "", R_DEBUG) var/datum/outfit_manager/ui = new(usr) ui.ui_interact(usr) - /datum/outfit_manager var/client/owner diff --git a/code/modules/admin/permissionedit.dm b/code/modules/admin/permissionedit.dm index 5544f90fb74..477e8986073 100644 --- a/code/modules/admin/permissionedit.dm +++ b/code/modules/admin/permissionedit.dm @@ -1,9 +1,4 @@ -/client/proc/edit_admin_permissions() - set category = "Admin" - set name = "Permissions Panel" - set desc = "Edit admin permissions" - if(!check_rights(R_PERMISSIONS)) - return +ADMIN_VERB(admin, permissions_panel, "Edit/Set admin permissions", R_PERMISSIONS) usr.client.holder.edit_admin_permissions() /datum/admins/proc/edit_admin_permissions(action, target, operation, page) diff --git a/code/modules/admin/stickyban.dm b/code/modules/admin/stickyban.dm index 537e0b92acb..bd88cf10231 100644 --- a/code/modules/admin/stickyban.dm +++ b/code/modules/admin/stickyban.dm @@ -481,10 +481,5 @@ . = list2params(.) - -/client/proc/stickybanpanel() - set name = "Sticky Ban Panel" - set category = "Admin" - if (!holder) - return - holder.stickyban_show() +ADMIN_VERB(admin, sticky_ban_panel, "", R_BAN) + usr.client.holder.stickyban_show() diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index d3c2a4011fa..8d3413f3d71 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -13,7 +13,6 @@ /datum/admins/Topic(href, href_list) ..() - if(usr.client != src.owner || !check_rights(0)) message_admins("[usr.key] has attempted to override the admin panel!") log_admin("[key_name(usr)] tried to use the admin panel without authorization.") @@ -22,6 +21,9 @@ if(!CheckAdminHref(href, href_list)) return + if(SSadmin_verbs.handle_admin_holder_topic(usr.client, href, href_list)) + return + if(href_list["ahelp"]) if(!check_rights(R_ADMIN, TRUE)) return @@ -111,10 +113,7 @@ minor_announce("The emergency shuttle will reach its destination in [DisplayTimeText(timer SECONDS)].") message_admins(span_adminnotice("[key_name_admin(usr)] edited the Emergency Shuttle's timeleft to [timer] seconds.")) else if(href_list["trigger_centcom_recall"]) - if(!check_rights(R_ADMIN)) - return - - usr.client.trigger_centcom_recall() + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/events/recall_shuttle) else if(href_list["move_shuttle"]) if(!check_rights(R_ADMIN)) @@ -136,8 +135,7 @@ to_chat(usr, "[shuttle_console] was [shuttle_console.admin_controlled ? "locked" : "unlocked"].", confidential = TRUE) else if(href_list["delay_round_end"]) - // Permissions are checked in delay_round_end - delay_round_end() + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/server/delay_round_end) else if(href_list["undelay_round_end"]) if(!check_rights(R_SERVER)) @@ -709,12 +707,10 @@ if(iscyborg(our_mob)) to_chat(usr, "That's already a cyborg.", confidential = TRUE) return - - usr.client.cmd_admin_robotize(our_mob) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/debug/make_cyborg, our_mob) else if(href_list["adminplayeropts"]) - var/mob/M = locate(href_list["adminplayeropts"]) - show_player_panel(M) + usr.client.admin_context_wrapper_context_player_panel(locate(href_list["adminplayeropts"])) else if(href_list["ppbyckey"]) var/target_ckey = href_list["ppbyckey"] @@ -729,7 +725,7 @@ return to_chat(usr, span_notice("Jumping to [target_ckey]'s new mob: [target_mob]!")) - show_player_panel(target_mob) + usr.client.admin_context_wrapper_context_player_panel(target_mob) else if(href_list["adminplayerobservefollow"]) if(!isobserver(usr) && !check_rights(R_ADMIN)) @@ -757,14 +753,9 @@ var/client/C = usr.client if(!isobserver(usr)) - C.admin_ghost() + SSadmin_verbs.dynamic_invoke_admin_verb(C, /mob/admin_module_holder/game/aghost) sleep(0.2 SECONDS) - C.jumptocoord(x,y,z) - - else if(href_list["adminchecklaws"]) - if(!check_rights(R_ADMIN)) - return - output_ai_laws() + SSadmin_verbs.dynamic_invoke_admin_verb(C, /mob/admin_module_holder/game/jump_to_coordinate, x, y, z) else if(href_list["adminmoreinfo"]) var/mob/subject = locate(href_list["adminmoreinfo"]) in GLOB.mob_list @@ -968,28 +959,24 @@ to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human", confidential = TRUE) return - usr.client.smite(H) + usr.client.admin_context_wrapper_context_smite(H) else if(href_list["CentComReply"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["CentComReply"]) - usr.client.admin_headset_message(M, RADIO_CHANNEL_CENTCOM) + usr.client.admin_context_wrapper_contexxt_headset_message( + locate(href_list["CentComReply"]), + RADIO_CHANNEL_CENTCOM, + ) else if(href_list["SyndicateReply"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["SyndicateReply"]) - usr.client.admin_headset_message(M, RADIO_CHANNEL_SYNDICATE) + usr.client.admin_context_wrapper_contexxt_headset_message( + locate(href_list["SyndicateReply"]), + RADIO_CHANNEL_SYNDICATE, + ) else if(href_list["HeadsetMessage"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["HeadsetMessage"]) - usr.client.admin_headset_message(M) + usr.client.admin_context_wrapper_contexxt_headset_message( + locate(href_list["HeadsetMessage"]), + ) else if(href_list["reject_custom_name"]) if(!check_rights(R_ADMIN)) @@ -997,12 +984,12 @@ var/obj/item/station_charter/charter = locate(href_list["reject_custom_name"]) if(istype(charter)) charter.reject_proposed(usr) + else if(href_list["jumpto"]) if(!isobserver(usr) && !check_rights(R_ADMIN)) return - var/mob/M = locate(href_list["jumpto"]) - usr.client.jumptomob(M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/jump_to_mob, locate(href_list["jumpto"])) else if(href_list["getmob"]) if(!check_rights(R_ADMIN)) @@ -1010,38 +997,29 @@ if(tgui_alert(usr, "Confirm?", "Message", list("Yes", "No")) != "Yes") return - var/mob/M = locate(href_list["getmob"]) - usr.client.Getmob(M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/get_mob, locate(href_list["getmob"])) else if(href_list["sendmob"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["sendmob"]) - usr.client.sendmob(M) + usr.client.admin_context_wrapper_context_sendmob(locate(href_list["sendmob"])) else if(href_list["narrateto"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["narrateto"]) - usr.client.cmd_admin_direct_narrate(M) + usr.client.admin_context_wrapper_context_direct_narrate(locate(href_list["narrateto"])) else if(href_list["subtlemessage"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["subtlemessage"]) - usr.client.cmd_admin_subtle_message(M) + usr.client.admin_context_wrapper_context_subtle_message(locate(href_list["subtlemessage"])) else if(href_list["playsoundto"]) if(!check_rights(R_SOUND)) return var/mob/M = locate(href_list["playsoundto"]) + if(QDELETED(M)) + to_chat(usr, span_warning("target mob no longer exists!")) + return + var/S = input("", "Select a sound file",) as null|sound if(S) - usr.client.play_direct_mob_sound(S, M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/fun/play_direct_mob_sound, S, M) else if(href_list["individuallog"]) if(!check_rights(R_ADMIN)) @@ -1081,37 +1059,13 @@ else D.traitor_panel() else - show_traitor_panel(M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/traitor_panel, M) else if(href_list["skill"]) - if(!check_rights(R_ADMIN)) - return - - if(!SSticker.HasRoundStarted()) - tgui_alert(usr,"The game hasn't started yet!") - return - - var/target = locate(href_list["skill"]) - var/datum/mind/target_mind - if(ismob(target)) - var/mob/target_mob = target - target_mind = target_mob.mind - else if (istype(target, /datum/mind)) - target_mind = target - else - to_chat(usr, "This can only be used on instances of type /mob and /mind", confidential = TRUE) - return - show_skill_panel(target_mind) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/skill_panel, locate(href_list["skill"])) else if(href_list["borgpanel"]) - if(!check_rights(R_ADMIN)) - return - - var/mob/M = locate(href_list["borgpanel"]) - if(!iscyborg(M)) - to_chat(usr, "This can only be used on cyborgs", confidential = TRUE) - else - open_borgopanel(M) + usr.client.admin_context_wrapper_context_borg_panel(locate(href_list["borgpanel"])) else if(href_list["initmind"]) if(!check_rights(R_ADMIN)) @@ -1274,9 +1228,7 @@ return else if(href_list["check_antagonist"]) - if(!check_rights(R_ADMIN)) - return - usr.client.check_antagonists() + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/game/check_antagonists) else if(href_list["kick_all_from_lobby"]) if(!check_rights(R_ADMIN)) @@ -1324,7 +1276,7 @@ G.report_message = description message_admins("[key_name(usr)] created \"[G.name]\" station goal.") GLOB.station_goals += G - modify_goals() + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/) else if(href_list["change_lag_switch"]) if(!check_rights(R_ADMIN)) @@ -1347,7 +1299,7 @@ log_admin("[key_name(usr)] turned a Lag Switch measure at index ([switch_index]) [LAZYACCESS(SSlag_switch.measures, switch_index) ? "ON" : "OFF"]") message_admins("[key_name_admin(usr)] turned a Lag Switch measure [LAZYACCESS(SSlag_switch.measures, switch_index) ? "ON" : "OFF"]") - src.show_lag_switch_panel() + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/show_lag_switches) else if(href_list["change_lag_switch_option"]) if(!check_rights(R_ADMIN)) @@ -1376,7 +1328,7 @@ log_admin("[key_name(usr)] set the Lag Switch slowmode cooldown to [new_num] seconds.") message_admins("[key_name_admin(usr)] set the Lag Switch slowmode cooldown to [new_num] seconds.") - src.show_lag_switch_panel() + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/show_lag_switches) else if(href_list["viewruntime"]) var/datum/error_viewer/error_viewer = locate(href_list["viewruntime"]) @@ -1496,7 +1448,7 @@ if(confirm == "No") return if(confirm == "Yes") - restart() + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/server/reboot_world) else if(href_list["check_teams"]) if(!check_rights(R_ADMIN)) @@ -1748,3 +1700,5 @@ if(!paper_to_show) return paper_to_show.ui_interact(usr) + + stack_trace("Unknown admin topic [href]-'[list2params(href_list)]'") diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index bd5a3ea7b33..6f9be4ca45f 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -198,17 +198,11 @@ state = SDQL2_STATE_ERROR;\ CRASH("SDQL2 fatal error");}; -/client/proc/SDQL2_query(query_text as message) - set category = "Debug" - if(!check_rights(R_DEBUG)) //Shouldn't happen... but just to be safe. - message_admins(span_danger("ERROR: Non-admin [key_name(usr)] attempted to execute a SDQL query!")) - usr.log_message("non-admin attempted to execute a SDQL query!", LOG_ADMIN) - return FALSE +ADMIN_VERB(debug, query_text, "", R_DEBUG, query_text as message) var/list/results = world.SDQL2_query(query_text, key_name_admin(usr), "[key_name(usr)]") if(length(results) == 3) for(var/I in 1 to 3) to_chat(usr, results[I], confidential = TRUE) - SSblackbox.record_feedback("nested tally", "SDQL query", 1, list(ckey, query_text)) /world/proc/SDQL2_query(query_text, log_entry1, log_entry2, silent = FALSE) var/query_log = "executed SDQL query(s): \"[query_text]\"." @@ -1230,4 +1224,4 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/sdql2_vv_all, new(null message_admins("[key_name_admin(usr)] non-holder clicked on a statclick! ([src])") usr.log_message("non-holder clicked on a statclick! ([src])", LOG_ADMIN) return - usr.client.debug_variables(GLOB.sdql2_queries) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, GLOB.sdql2_queries) diff --git a/code/modules/admin/verbs/admin.dm b/code/modules/admin/verbs/admin.dm index 2558606499a..6480302e100 100644 --- a/code/modules/admin/verbs/admin.dm +++ b/code/modules/admin/verbs/admin.dm @@ -1,19 +1,12 @@ // Admin Tab - Admin Verbs -/client/proc/show_tip() - set category = "Admin" - set name = "Show Tip" - set desc = "Sends a tip (that you specify) to all players. After all \ - you're the experienced player here." - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(admin, show_tip, "Sends a tip, which you specify, to all players", R_ADMIN) var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null if(!input) return - if(!SSticker) + if(!SSticker.initialized) + to_chat(usr, span_warning("Please wait for the game to initialize!")) return // If we've already tipped, then send it straight away. @@ -24,40 +17,16 @@ message_admins("[key_name_admin(usr)] sent a tip of the round.") log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Tip") -/datum/admins/proc/announce() - set category = "Admin" - set name = "Announce" - set desc="Announce your desires to the world" - if(!check_rights(0)) - return - - var/message = input("Global message to send:", "Admin Announce", null, null) as message|null - if(message) - if(!check_rights(R_SERVER,0)) - message = adminscrub(message,500) - to_chat(world, "[span_adminnotice("[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:")]\n \t [message]", confidential = TRUE) - log_admin("Announce: [key_name(usr)] : [message]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Announce") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/datum/admins/proc/unprison(mob/M in GLOB.mob_list) - set category = "Admin" - set name = "Unprison" - if (is_centcom_level(M.z)) - SSjob.SendToLateJoin(M) - message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(M)]") - log_admin("[key_name(usr)] has unprisoned [key_name(M)]") +ADMIN_VERB(admin, release_from_prison, "", R_ADMIN, mob/freeing in world) + if(is_centcom_level(freeing.z)) + SSjob.SendToLateJoin(freeing) + message_admins("[key_name_admin(usr)] has unprisoned [key_name_admin(freeing)]") + log_admin("[key_name(usr)] has unprisoned [key_name(freeing)]") else - tgui_alert(usr,"[M.name] is not prisoned.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Unprison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_check_player_exp() //Allows admins to determine who the newer players are. - set category = "Admin" - set name = "Player Playtime" - if(!check_rights(R_ADMIN)) - return + tgui_alert(usr,"[freeing.name] is not prisoned.") +ADMIN_VERB(admin, player_playtime, "Check the playtime for connected players", R_ADMIN) if(!CONFIG_GET(flag/use_exp_tracking)) to_chat(usr, span_warning("Tracking is disabled in the server configuration file."), confidential = TRUE) return @@ -67,13 +36,11 @@ for(var/client/client in sort_list(GLOB.clients, GLOBAL_PROC_REF(cmp_playtime_asc))) msg += "
  • [ADMIN_PP(client.mob)] [key_name_admin(client)]: " + client.get_exp_living() + "
  • " msg += "" - src << browse(msg.Join(), "window=Player_playtime_check") + usr << browse(msg.Join(), "window=Player_playtime_check") -/client/proc/trigger_centcom_recall() - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(admin, trigger_centcom_recall, "", R_ADMIN) var/message = pick(GLOB.admiral_messages) - message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as text|null + message = input("Enter message from the on-call admiral to be put in the recall report.", "Admiral Message", message) as message|null if(!message) return @@ -82,6 +49,9 @@ usr.log_message("triggered a CentCom recall, with the message of: [message]", LOG_GAME) SSshuttle.centcom_recall(SSshuttle.emergency.timer, message) +ADMIN_VERB(admin, player_panel, "", R_ADMIN) + usr.client.holder?.player_panel_new() + /datum/admins/proc/cmd_show_exp_panel(client/client_to_check) if(!check_rights(R_ADMIN)) return @@ -164,26 +134,20 @@ /////////////////////////////////////////////////////////////////////////////////////////////// -/client/proc/cmd_admin_drop_everything(mob/M in GLOB.mob_list) - set category = null - set name = "Drop Everything" - if(!check_rights(R_ADMIN)) - return - - var/confirm = tgui_alert(usr, "Make [M] drop everything?", "Message", list("Yes", "No")) +ADMIN_VERB(admin, drop_everything, "", R_ADMIN, mob/target in world) + var/confirm = tgui_alert(usr, "Make [target] drop everything?", "Message", list("Yes", "No")) if(confirm != "Yes") return - for(var/obj/item/W in M) - if(!M.dropItemToGround(W)) - qdel(W) - M.regenerate_icons() + for(var/obj/item/held in target) + if(!target.dropItemToGround(held)) + qdel(held) + target.regenerate_icons() - log_admin("[key_name(usr)] made [key_name(M)] drop everything!") - var/msg = "[key_name_admin(usr)] made [ADMIN_LOOKUPFLW(M)] drop everything!" + log_admin("[key_name(usr)] made [key_name(target)] drop everything!") + var/msg = "[key_name_admin(usr)] made [ADMIN_LOOKUPFLW(target)] drop everything!" message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + admin_ticket_log(target, msg) /proc/cmd_admin_mute(whom, mute_type, automute = 0) if(!whom) diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index 5fe32960a7f..43b92a7b546 100644 --- a/code/modules/admin/verbs/admin_newscaster.dm +++ b/code/modules/admin/verbs/admin_newscaster.dm @@ -1,18 +1,3 @@ -/datum/admins/proc/access_news_network() //MARKER - set category = "Admin.Events" - set name = "Access Newscaster Network" - set desc = "Allows you to view, add and edit news feeds." - - if (!istype(src, /datum/admins)) - src = usr.client.holder - if (!istype(src, /datum/admins)) - to_chat(usr, "Error: you are not an admin!", confidential = TRUE) - return - - var/datum/newspanel/new_newspanel = new - - new_newspanel.ui_interact(usr) - /datum/newspanel ///What newscaster channel is currently being viewed by the player? var/datum/feed_channel/current_channel diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm index 329a950ce8d..035c9c663a8 100644 --- a/code/modules/admin/verbs/adminevents.dm +++ b/code/modules/admin/verbs/adminevents.dm @@ -1,164 +1,90 @@ // Admin Tab - Event Verbs -/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list) - set category = "Admin.Events" - set name = "Subtle Message" - - if(!ismob(M)) - return - if(!check_rights(R_ADMIN)) - return - - message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(M)]'s prayer.") - var/msg = input("Message:", text("Subtle PM to [M.key]")) as text|null +ADMIN_CONTEXT_ENTRY(context_subtle_message, "Subtle Message", R_ADMIN, mob/hearer in world) + message_admins("[key_name_admin(src)] has started answering [ADMIN_LOOKUPFLW(hearer)]'s prayer.") + var/msg = input("Message:", text("Subtle PM to [hearer.ckey]")) as text|null if(!msg) - message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(M)]'s prayer") + message_admins("[key_name_admin(src)] decided not to answer [ADMIN_LOOKUPFLW(hearer)]'s prayer") return - if(usr) - if (usr.client) - if(usr.client.holder) - M.balloon_alert(M, "you hear a voice") - to_chat(M, "You hear a voice in your head... [msg]", confidential = TRUE) - log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") - msg = span_adminnotice(" SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]") + hearer.balloon_alert(hearer, "you hear a voice") + to_chat(hearer, "You hear a voice in your head... [msg]") + log_admin("SubtlePM: [key_name(usr)] -> [key_name(hearer)] : [msg]") + msg = span_adminnotice(" SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(hearer)] : [msg]") message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + admin_ticket_log(hearer, msg) -/client/proc/cmd_admin_headset_message(mob/M in GLOB.mob_list) - set category = "Admin.Events" - set name = "Headset Message" - - admin_headset_message(M) - -/client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null) - var/mob/living/carbon/human/H = M - - if(!check_rights(R_ADMIN)) - return - - if(!istype(H)) - to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human", confidential = TRUE) - return - if(!istype(H.ears, /obj/item/radio/headset)) +ADMIN_CONTEXT_ENTRY(contexxt_headset_message, "Headset Message", R_ADMIN, mob/living/carbon/human/hearer in world, sender in list(RADIO_CHANNEL_CENTCOM, RADIO_CHANNEL_SYNDICATE)) + if(!istype(hearer.ears, /obj/item/radio/headset)) to_chat(usr, "The person you are trying to contact is not wearing a headset.", confidential = TRUE) return - if (!sender) - sender = input("Who is the message from?", "Sender") as null|anything in list(RADIO_CHANNEL_CENTCOM,RADIO_CHANNEL_SYNDICATE) - if(!sender) - return - - message_admins("[key_name_admin(src)] has started answering [key_name_admin(H)]'s [sender] request.") - var/input = input("Please enter a message to reply to [key_name(H)] via their headset.","Outgoing message from [sender]", "") as text|null + message_admins("[key_name_admin(src)] has started answering [key_name_admin(hearer)]'s [sender] request.") + var/input = input("Please enter a message to reply to [key_name(hearer)] via their headset.","Outgoing message from [sender]", "") as text|null if(!input) - message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(H)]'s [sender] request.") + message_admins("[key_name_admin(src)] decided not to answer [key_name_admin(hearer)]'s [sender] request.") return - log_directed_talk(mob, H, input, LOG_ADMIN, "reply") - message_admins("[key_name_admin(src)] replied to [key_name_admin(H)]'s [sender] message with: \"[input]\"") - H.balloon_alert(H, "you hear a voice") - to_chat(H, span_hear("You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] [input]. Message ends.\""), confidential = TRUE) + log_directed_talk(mob, hearer, input, LOG_ADMIN, "reply") + message_admins("[key_name_admin(src)] replied to [key_name_admin(hearer)]'s [sender] message with: \"[input]\"") + hearer.balloon_alert(hearer, "you hear a voice") + to_chat(hearer, span_hear("You hear something crackle in your ears for a moment before a voice speaks. \"Please stand by for a message from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] [input]. Message ends.\""), confidential = TRUE) SSblackbox.record_feedback("tally", "admin_verb", 1, "Headset Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_world_narrate() - set category = "Admin.Events" - set name = "Global Narrate" - - if(!check_rights(R_ADMIN)) - return - - var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text|null - - if (!msg) - return - to_chat(world, "[msg]", confidential = TRUE) - log_admin("GlobalNarrate: [key_name(usr)] : [msg]") +ADMIN_VERB(events, global_narrate, "Send raw html to all conneted clients", R_ADMIN, raw_html as message) + to_chat(world, "[raw_html]") + log_admin("GlobalNarrate: [key_name(usr)] : [raw_html]") message_admins(span_adminnotice("[key_name_admin(usr)] Sent a global narrate")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Global Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_local_narrate(atom/A) - set category = "Admin.Events" - set name = "Local Narrate" - - if(!check_rights(R_ADMIN)) - return - if(!A) - return +ADMIN_CONTEXT_ENTRY(context_local_narrate, "Local Narrate", R_ADMIN, atom/origin in view()) var/range = input("Range:", "Narrate to mobs within how many tiles:", 7) as num|null if(!range) return + var/msg = input("Message:", text("Enter the text you wish to appear to everyone within view:")) as text|null if (!msg) return - for(var/mob/M in view(range,A)) - to_chat(M, msg, confidential = TRUE) - log_admin("LocalNarrate: [key_name(usr)] at [AREACOORD(A)]: [msg]") - message_admins(span_adminnotice(" LocalNarrate: [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(A)]: [msg]
    ")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + for(var/mob/hearer in view(range, origin)) + to_chat(hearer, msg) -/client/proc/cmd_admin_direct_narrate(mob/M) - set category = "Admin.Events" - set name = "Direct Narrate" - - if(!check_rights(R_ADMIN)) - return - - if(!M) - M = input("Direct narrate to whom?", "Active Players") as null|anything in GLOB.player_list - - if(!M) - return + log_admin("LocalNarrate: [key_name(usr)] at [AREACOORD(origin)]: [msg]") + message_admins(span_adminnotice(" LocalNarrate: [key_name_admin(usr)] at [ADMIN_VERBOSEJMP(origin)]: [msg]
    ")) +ADMIN_CONTEXT_ENTRY(context_direct_narrate, "Direct Narrate", R_ADMIN, mob/hearer in world) var/msg = input("Message:", text("Enter the text you wish to appear to your target:")) as text|null - - if( !msg ) + if(!msg) return - to_chat(M, msg, confidential = TRUE) - log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]") - msg = span_adminnotice(" DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]
    ") + to_chat(hearer, msg) + log_admin("DirectNarrate: [key_name(usr)] to ([key_name(hearer)]): [msg]") + msg = span_adminnotice(" DirectNarrate: [key_name(usr)] to ([key_name(hearer)]): [msg]
    ") message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_add_freeform_ai_law() - set category = "Admin.Events" - set name = "Add Custom AI law" - - if(!check_rights(R_ADMIN)) - return + admin_ticket_log(hearer, msg) +ADMIN_VERB(fun, add_ion_law, "Add an ion law to all silicons", R_FUN) var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null if(!input) return log_admin("Admin [key_name(usr)] has added a new AI law - [input]") message_admins("Admin [key_name_admin(usr)] has added a new AI law - [input]") - var/show_log = tgui_alert(usr, "Show ion message?", "Message", list("Yes", "No")) - var/announce_ion_laws = (show_log == "Yes" ? 100 : 0) var/datum/round_event/ion_storm/add_law_only/ion = new() - ion.announce_chance = announce_ion_laws ion.ionMessage = input + if(show_log == "Yes") + ion.announce_chance = 100 + ion.announce(FALSE) + ion.start() + qdel(ion) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Custom AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/admin_call_shuttle() - set category = "Admin.Events" - set name = "Call Shuttle" - +ADMIN_VERB(events, call_shuttle, "", R_ADMIN) if(EMERGENCY_AT_LEAST_DOCKED) return - if(!check_rights(R_ADMIN)) - return - var/confirm = tgui_alert(usr, "You sure?", "Confirm", list("Yes", "Yes (No Recall)", "No")) switch(confirm) if(null, "No") @@ -168,39 +94,22 @@ SSshuttle.emergency.mode = SHUTTLE_IDLE SSshuttle.emergency.request() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Call Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_admin("[key_name(usr)] admin-called the emergency shuttle.") message_admins(span_adminnotice("[key_name_admin(usr)] admin-called the emergency shuttle[confirm == "Yes (No Recall)" ? " (non-recallable)" : ""].")) - return -/client/proc/admin_cancel_shuttle() - set category = "Admin.Events" - set name = "Cancel Shuttle" - if(!check_rights(0)) - return +ADMIN_VERB(events, recall_shuttle, "", R_ADMIN) if(tgui_alert(usr, "You sure?", "Confirm", list("Yes", "No")) != "Yes") return - if(SSshuttle.admin_emergency_no_recall) - SSshuttle.admin_emergency_no_recall = FALSE - + SSshuttle.admin_emergency_no_recall &&= FALSE if(EMERGENCY_AT_LEAST_DOCKED) return SSshuttle.emergency.cancel() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Cancel Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_admin("[key_name(usr)] admin-recalled the emergency shuttle.") message_admins(span_adminnotice("[key_name_admin(usr)] admin-recalled the emergency shuttle.")) - return - -/client/proc/admin_disable_shuttle() - set category = "Admin.Events" - set name = "Disable Shuttle" - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(events, disable_shuttle, "", R_ADMIN) if(SSshuttle.emergency.mode == SHUTTLE_DISABLED) to_chat(usr, span_warning("Error, shuttle is already disabled.")) return @@ -217,13 +126,7 @@ SSshuttle.emergency.mode = SHUTTLE_DISABLED priority_announce("Warning: Emergency Shuttle uplink failure, shuttle disabled until further notice.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') -/client/proc/admin_enable_shuttle() - set category = "Admin.Events" - set name = "Enable Shuttle" - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(events, enable_shuttle, "", R_ADMIN) if(SSshuttle.emergency.mode != SHUTTLE_DISABLED) to_chat(usr, span_warning("Error, shuttle not disabled.")) return @@ -243,100 +146,71 @@ SSshuttle.emergency.setTimer(SSshuttle.last_call_time) priority_announce("Warning: Emergency Shuttle uplink reestablished, shuttle enabled.", "Emergency Shuttle Uplink Alert", 'sound/misc/announce_dig.ogg') -/client/proc/admin_hostile_environment() - set category = "Admin.Events" - set name = "Hostile Environment" +#define HOSTILE_ENVIRONMENT_ENABLE "Enable" +#define HOSTILE_ENVIRONMENT_DISABLE "Disable" +#define HOSTILE_ENVIRONMENT_CLEAR "Clear All" +#define HOSTILE_ENVIRONMENT_OPTIONS list(HOSTILE_ENVIRONMENT_ENABLE, HOSTILE_ENVIRONMENT_DISABLE, HOSTILE_ENVIRONMENT_CLEAR) - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(events, hostile_environments, "", R_ADMIN) + switch(tgui_alert(usr, "Select an Option", "Hostile Environment Manager", HOSTILE_ENVIRONMENT_OPTIONS)) + if(HOSTILE_ENVIRONMENT_ENABLE) + if(SSshuttle.hostile_environments["Admin"]) + to_chat(usr, span_warning("Admin Hostile Environment already enabled!")) + return + message_admins(span_adminnotice("[key_name_admin(usr)] Enabled an admin hostile environment")) + SSshuttle.registerHostileEnvironment("Admin") - switch(tgui_alert(usr, "Select an Option", "Hostile Environment Manager", list("Enable", "Disable", "Clear All"))) - if("Enable") - if (SSshuttle.hostile_environments["Admin"] == TRUE) - to_chat(usr, span_warning("Error, admin hostile environment already enabled.")) - else - message_admins(span_adminnotice("[key_name_admin(usr)] Enabled an admin hostile environment")) - SSshuttle.registerHostileEnvironment("Admin") - if("Disable") - if (!SSshuttle.hostile_environments["Admin"]) - to_chat(usr, span_warning("Error, no admin hostile environment found.")) - else - message_admins(span_adminnotice("[key_name_admin(usr)] Disabled the admin hostile environment")) - SSshuttle.clearHostileEnvironment("Admin") - if("Clear All") + if(HOSTILE_ENVIRONMENT_DISABLE) + if(!SSshuttle.hostile_environments["Admin"]) + to_chat(usr, span_warning("Admin Hostile Environment not enabled!")) + return + message_admins(span_adminnotice("[key_name_admin(usr)] Disabled the admin hostile environment")) + SSshuttle.clearHostileEnvironment("Admin") + + if(HOSTILE_ENVIRONMENT_CLEAR) + if(tgui_alert(usr, "Are you sure?", "Hostile Environment Manager", list("Yes", "No")) != "Yes") + return message_admins(span_adminnotice("[key_name_admin(usr)] Disabled all current hostile environment sources")) SSshuttle.hostile_environments.Cut() SSshuttle.checkHostileEnvironment() -/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in GLOB.nuke_list) - set category = "Admin.Events" - set name = "Toggle Nuke" - set popup_menu = FALSE - if(!check_rights(R_DEBUG)) - return - - if(!N.timing) - var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num|null +ADMIN_VERB(events, toggle_nuke, "", (R_ADMIN|R_DEBUG), obj/machinery/nuclearbomb/nuke in GLOB.nuke_list) + if(!nuke.timing) + var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[nuke.timer_set]") as num|null if(!newtime) return - N.timer_set = newtime - N.toggle_nuke_safety() - N.toggle_nuke_armed() + nuke.timer_set = newtime + nuke.toggle_nuke_safety() + nuke.toggle_nuke_armed() - log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [AREACOORD(N)].") - message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(N)].") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Nuke", "[N.timing]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/admin_change_sec_level() - set category = "Admin.Events" - set name = "Set Security Level" - set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke" - - if(!check_rights(R_ADMIN)) - return + log_admin("[key_name(usr)] [nuke.timing ? "activated" : "deactivated"] a nuke at [AREACOORD(nuke)].") + message_admins("[ADMIN_LOOKUPFLW(usr)] [nuke.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(nuke)].") +ADMIN_VERB(events, set_security_level, "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke", R_ADMIN) var/level = tgui_input_list(usr, "Select Security Level:", "Set Security Level", SSsecurity_level.available_levels) - if(!level) return SSsecurity_level.set_level(level) - log_admin("[key_name(usr)] changed the security level to [level]") message_admins("[key_name_admin(usr)] changed the security level to [level]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Security Level [capitalize(level)]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/run_weather() - set category = "Admin.Events" - set name = "Run Weather" - set desc = "Triggers a weather on the z-level you choose." - - if(!holder) - return - - var/weather_type = input("Choose a weather", "Weather") as null|anything in sort_list(subtypesof(/datum/weather), GLOBAL_PROC_REF(cmp_typepaths_asc)) +ADMIN_VERB(events, run_weather, "Triggers a weather on the specified z-level", R_FUN) + var/weather_type = input(usr, "Choose a weather", "Weather") as null|anything in sort_list(subtypesof(/datum/weather), GLOBAL_PROC_REF(cmp_typepaths_asc)) if(!weather_type) return - var/turf/T = get_turf(mob) - var/z_level = input("Z-Level to target?", "Z-Level", T?.z) as num|null + var/turf/T = get_turf(usr) + var/z_level = input(usr, "Z-Level to target?", "Z-Level", T?.z) as num|null if(!isnum(z_level)) return SSweather.run_weather(weather_type, z_level) - message_admins("[key_name_admin(usr)] started weather of type [weather_type] on the z-level [z_level].") log_admin("[key_name(usr)] started weather of type [weather_type] on the z-level [z_level].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather") - -/client/proc/add_mob_ability() - set category = "Admin.Events" - set name = "Add Mob Ability" - set desc = "Adds an ability to a marked mob." - - if(!holder) - return +ADMIN_VERB(events, add_mob_ability, "Adds an ability to a marked mob", R_FUN) + var/datum/admins/holder = usr.client.holder if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to add actions to it.")) return @@ -381,16 +255,9 @@ message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [marked_mob].") log_admin("[key_name(usr)] added mob ability [ability_type] to mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/remove_mob_ability() - set category = "Admin.Events" - set name = "Remove Mob Ability" - set desc = "Removes an ability from marked mob." - - if(!holder) - return +ADMIN_VERB(events, remove_mob_ability, "Removes an ability from the marked mob", R_FUN) + var/datum/admins/holder = usr.client.holder if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to remove actions from it.")) return @@ -411,49 +278,32 @@ message_admins("[key_name_admin(usr)] removed ability [ability_name] from mob [marked_mob].") log_admin("[key_name(usr)] removed mob ability [ability_name] from mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/command_report_footnote() - set category = "Admin.Events" - set name = "Command Report Footnote" - set desc = "Adds a footnote to the roundstart command report." - - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(events, command_report_footnote, "Adds a footnote to the roundstart command report", R_ADMIN) var/datum/command_footnote/command_report_footnote = new /datum/command_footnote() SScommunications.block_command_report++ //Add a blocking condition to the counter until the inputs are done. command_report_footnote.message = tgui_input_text(usr, "This message will be attached to the bottom of the roundstart threat report. Be sure to delay the roundstart report if you need extra time.", "P.S.") - if(!command_report_footnote.message) + SScommunications.block_command_report-- return command_report_footnote.signature = tgui_input_text(usr, "Whose signature will appear on this footnote?", "Also sign here, here, aaand here.") - if(!command_report_footnote.signature) command_report_footnote.signature = "Classified" + message_admins("[usr] has added a footnote to the command report: [command_report_footnote.message], signed [command_report_footnote.signature]") SScommunications.command_report_footnotes += command_report_footnote SScommunications.block_command_report-- - message_admins("[usr] has added a footnote to the command report: [command_report_footnote.message], signed [command_report_footnote.signature]") - /datum/command_footnote var/message var/signature -/client/proc/delay_command_report() - set category = "Admin.Events" - set name = "Delay Command Report" - set desc = "Prevents the roundstart command report from being sent until toggled." - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(events, delay_command_report, "Prevents the roundstart command report from being sent until toggled", R_ADMIN) if(SScommunications.block_command_report) //If it's anything other than 0, decrease. If 0, increase. SScommunications.block_command_report-- - message_admins("[usr] has enabled the roundstart command report.") + message_admins("[key_name_admin(usr)] has enabled the roundstart command report.") else SScommunications.block_command_report++ - message_admins("[usr] has delayed the roundstart command report.") + message_admins("[key_name_admin(usr)] has delayed the roundstart command report.") diff --git a/code/modules/admin/verbs/adminfun.dm b/code/modules/admin/verbs/adminfun.dm index cc7bfb1fffe..227f602ae44 100644 --- a/code/modules/admin/verbs/adminfun.dm +++ b/code/modules/admin/verbs/adminfun.dm @@ -1,12 +1,6 @@ // Admin Tab - Fun Verbs -/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world) - set category = "Admin.Fun" - set name = "Explosion" - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(game, explosion, "Explosion", R_ADMIN, atom/target as obj|mob|turf in view()) var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null if(devastation == null) return @@ -28,18 +22,11 @@ if (tgui_alert(usr, "Are you sure you want to do this? It will laaag.", "Confirmation", list("Yes", "No")) == "No") return - explosion(O, devastation, heavy, light, flames, flash, explosion_cause = mob) - log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(O)]") - message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(O)]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Explosion") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world) - set category = "Admin.Fun" - set name = "EM Pulse" - - if(!check_rights(R_ADMIN)) - return + explosion(target, devastation, heavy, light, flames, flash, explosion_cause = usr) + log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(target)]") + message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at [AREACOORD(target)]") +ADMIN_VERB(game, emp, "", R_ADMIN, atom/target as obj|mob|turf in view()) var/heavy = input("Range of heavy pulse.", text("Input")) as num|null if(heavy == null) return @@ -48,18 +35,12 @@ return if (heavy || light) - empulse(O, heavy, light) - log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]") - message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]") + empulse(target, heavy, light) + log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(target)]") + message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(target)]") SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_gib(mob/victim in GLOB.mob_list) - set category = "Admin.Fun" - set name = "Gib" - - if(!check_rights(R_ADMIN)) - return - +ADMIN_CONTEXT_ENTRY(context_mob_gib, "Gib", R_ADMIN, mob/victim in GLOB.mob_list) var/confirm = tgui_alert(usr, "Drop a brain?", "Confirm", list("Yes", "No","Cancel")) if(confirm == "Cancel") return @@ -82,29 +63,23 @@ else living_victim.gib(TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Gib") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_gib_self() - set name = "Gibself" - set category = "Admin.Fun" +ADMIN_VERB(fun, gibself, "", R_ADMIN) + if(!isliving(usr)) + to_chat(usr, span_warning("You must be alive to use this!")) + return var/confirm = tgui_alert(usr, "You sure?", "Confirm", list("Yes", "No")) - if(confirm == "Yes") - log_admin("[key_name(usr)] used gibself.") - message_admins(span_adminnotice("[key_name_admin(usr)] used gibself.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Gib Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + if(confirm != "Yes") + return - var/mob/living/ourself = mob - if (istype(ourself)) - ourself.gib(TRUE, TRUE, TRUE) - -/client/proc/everyone_random() - set category = "Admin.Fun" - set name = "Make Everyone Random" - set desc = "Make everyone have a random appearance. You can only use this before rounds!" + log_admin("[key_name(usr)] used gibself.") + message_admins(span_adminnotice("[key_name_admin(usr)] used gibself.")) + var/mob/living/ourself = usr + ourself.gib(TRUE, TRUE, TRUE) +ADMIN_VERB(fun, make_everyone_random, "Make everyone have a random appearance. You can only use this before rounds!", R_FUN) if(SSticker.HasRoundStarted()) - to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!", confidential = TRUE) + to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") return var/frn = CONFIG_GET(flag/force_random_names) @@ -125,90 +100,56 @@ to_chat(world, span_adminnotice("Admin [usr.key] has forced the players to have completely random identities!"), confidential = TRUE) to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.", confidential = TRUE) - CONFIG_SET(flag/force_random_names, TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Everyone Random") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/mass_zombie_infection() - set category = "Admin.Fun" - set name = "Mass Zombie Infection" - set desc = "Infects all humans with a latent organ that will zombify \ - them on death." - - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(fun, mass_zombie_infection, "Infects all humans with a latent organ that will zombify them upon death", R_FUN) var/confirm = tgui_alert(usr, "Please confirm you want to add latent zombie organs in all humans?", "Confirm Zombies", list("Yes", "No")) if(confirm != "Yes") return - for(var/i in GLOB.human_list) - var/mob/living/carbon/human/H = i - new /obj/item/organ/internal/zombie_infection/nodamage(H) + for(var/mob/living/carbon/human/crewman as anything in GLOB.human_list) + new /obj/item/organ/internal/zombie_infection/nodamage(crewman) message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.") log_admin("[key_name(usr)] added a latent zombie infection to all humans.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Infection") - -/client/proc/mass_zombie_cure() - set category = "Admin.Fun" - set name = "Mass Zombie Cure" - set desc = "Removes the zombie infection from all humans, returning them to normal." - if(!check_rights(R_ADMIN)) - return +// Infecting everyone needs R_FUN, but curing only needs R_ADMIN +ADMIN_VERB(fun, mass_zombie_cure, "Removes the admin zombie infection from all humans, returning them to normal", R_ADMIN) var/confirm = tgui_alert(usr, "Please confirm you want to cure all zombies?", "Confirm Zombie Cure", list("Yes", "No")) if(confirm != "Yes") return - for(var/obj/item/organ/internal/zombie_infection/nodamage/I in GLOB.zombie_infection_list) - qdel(I) + for(var/obj/item/organ/internal/zombie_infection/nodamage/organ in GLOB.zombie_infection_list) + qdel(organ) message_admins("[key_name_admin(usr)] cured all zombies.") log_admin("[key_name(usr)] cured all zombies.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Mass Zombie Cure") - -/client/proc/polymorph_all() - set category = "Admin.Fun" - set name = "Polymorph All" - set desc = "Applies the effects of the bolt of change to every single mob." - - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(fun, polymorph_all_mobs, "This will prove to be a terrible idea", R_FUN) var/confirm = tgui_alert(usr, "Please confirm you want polymorph all mobs?", "Confirm Polymorph", list("Yes", "No")) if(confirm != "Yes") return - var/list/mobs = shuffle(GLOB.alive_mob_list.Copy()) // might change while iterating var/who_did_it = key_name_admin(usr) - - message_admins("[key_name_admin(usr)] started polymorphed all living mobs.") + message_admins("[who_did_it] started polymorphed all living mobs.") log_admin("[key_name(usr)] polymorphed all living mobs.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Polymorph All") - - for(var/mob/living/M in mobs) + for(var/mob/living/wabbajee in shuffle(GLOB.alive_mob_list)) CHECK_TICK - if(!M) + if(!wabbajee) continue - M.audible_message(span_hear("...wabbajack...wabbajack...")) - playsound(M.loc, 'sound/magic/staff_change.ogg', 50, TRUE, -1) + wabbajee.audible_message(span_hear("...wabbajack...wabbajack...")) + playsound(wabbajee.loc, 'sound/magic/staff_change.ogg', 50, TRUE, -1) - M.wabbajack() + wabbajee.wabbajack() message_admins("Mass polymorph started by [who_did_it] is complete.") -/client/proc/smite(mob/living/target as mob) - set category = "Admin.Fun" - set name = "Smite" - if(!check_rights(R_ADMIN) || !check_rights(R_FUN)) - return - +ADMIN_CONTEXT_ENTRY(context_smite, "Smite", (R_ADMIN|R_FUN), mob/living/victim as mob in view()) var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in GLOB.smites - if(QDELETED(target) || !punishment) + if(QDELETED(victim) || !punishment) return var/smite_path = GLOB.smites[punishment] @@ -216,7 +157,7 @@ var/configuration_success = smite.configure(usr) if (configuration_success == FALSE) return - smite.effect(src, target) + smite.effect(usr.client, victim) ///"Turns" people into bread. Really, we just add them to the contents of the bread food item. /proc/breadify(atom/movable/target) diff --git a/code/modules/admin/verbs/admingame.dm b/code/modules/admin/verbs/admingame.dm index b578708c7f1..15c99bf655f 100644 --- a/code/modules/admin/verbs/admingame.dm +++ b/code/modules/admin/verbs/admingame.dm @@ -1,182 +1,154 @@ // Admin Tab - Game Verbs -/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list) - set category = "Admin.Game" - set name = "Show Player Panel" - set desc="Edit player (respawn, ban, heal, etc)" - - if(!check_rights()) - return - - log_admin("[key_name(usr)] checked the individual player panel for [key_name(M)][isobserver(usr)?"":" while in game"].") - - if(!M) - to_chat(usr, span_warning("You seem to be selecting a mob that doesn't exist anymore."), confidential = TRUE) - return - - var/body = "Options for [M.key]" - body += "Options panel for [M]" - if(M.client) - body += " played by [M.client] " - body += "\[[M.client.holder ? M.client.holder.rank_names() : "Player"]\]" +ADMIN_CONTEXT_ENTRY(context_player_panel, "Show Player Panel", R_ADMIN, mob/player in GLOB.mob_list) + log_admin("[key_name(usr)] checked the individual player panel for [key_name(player)][isobserver(usr)?"":" while in game"].") + var/body = "Options for [player.key]" + body += "Options panel for [player]" + if(player.client) + body += " played by [player.client] " + body += "\[[player.client.holder ? player.client.holder.rank_names() : "Player"]\]" if(CONFIG_GET(flag/use_exp_tracking)) - body += "\[" + M.client.get_exp_living(FALSE) + "\]" + body += "\[" + player.client.get_exp_living(FALSE) + "\]" - if(isnewplayer(M)) + if(isnewplayer(player)) body += " Hasn't Entered Game " else - body += " \[Heal\] " + body += " \[Heal\] " - if(M.ckey) - body += "
    \[Find Updated Panel\]" + if(player.ckey) + body += "
    \[Find Updated Panel\]" - if(M.client) - body += "
    \[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]" + if(player.client) + body += "
    \[First Seen: [player.client.player_join_date]\]\[Byond account registered on: [player.client.account_join_date]\]" body += "

    CentCom Galactic Ban DB: " if(CONFIG_GET(string/centcom_ban_db)) - body += "Search" + body += "Search" else body += "Disabled" body += "

    Show related accounts by: " - body += "\[ CID | " - body += "IP \]" + body += "\[ CID | " + body += "IP \]" var/full_version = "Unknown" - if(M.client.byond_version) - full_version = "[M.client.byond_version].[M.client.byond_build ? M.client.byond_build : "xxx"]" + if(player.client.byond_version) + full_version = "[player.client.byond_version].[player.client.byond_build ? player.client.byond_build : "xxx"]" body += "
    \[Byond version: [full_version]\]
    " body += "

    \[ " - body += "VV - " - if(M.mind) - body += "TP - " - body += "SKILLS - " + body += "VV - " + if(player.mind) + body += "TP - " + body += "SKILLS - " else - body += "Init Mind - " - if (iscyborg(M)) - body += "BP - " - body += "PM - " - body += "SM - " - if (ishuman(M) && M.mind) - body += "HM - " - body += "FLW - " + body += "Init Mind - " + if (iscyborg(player)) + body += "BP - " + body += "PM - " + body += "SM - " + if (ishuman(player) && player.mind) + body += "HM - " + body += "FLW - " //Default to client logs if available var/source = LOGSRC_MOB - if(M.ckey) + if(player.ckey) source = LOGSRC_CKEY - body += "LOGS\]
    " + body += "LOGS\]
    " - body += "Mob type = [M.type]

    " + body += "Mob type = [player.type]

    " - body += "Kick | " - if(M.client) - body += "Ban | " + body += "Kick | " + if(player.client) + body += "Ban | " else - body += "Ban | " + body += "Ban | " - body += "Notes | Messages | Watchlist | " - if(M.client) - body += "| Prison | " - body += "\ Send back to Lobby | " - var/muted = M.client.prefs.muted + body += "Notes | Messages | Watchlist | " + if(player.client) + body += "| Prison | " + body += "\ Send back to Lobby | " + var/muted = player.client.prefs.muted body += "
    Mute: " - body += "\[IC | " - body += "OOC | " - body += "PRAY | " - body += "ADMINHELP | " - body += "DEADCHAT\]" - body += "(toggle all)" + body += "\[IC | " + body += "OOC | " + body += "PRAY | " + body += "ADMINHELP | " + body += "DEADCHAT\]" + body += "(toggle all)" body += "

    " - body += "Jump to | " - body += "Get | " - body += "Send To" + body += "Jump to | " + body += "Get | " + body += "Send To" body += "

    " - body += "Traitor panel | " - body += "Narrate to | " - body += "Subtle message | " - body += "Play sound to | " - body += "Language Menu" + body += "Traitor panel | " + body += "Narrate to | " + body += "Subtle message | " + body += "Play sound to | " + body += "Language Menu" - if(M.client) - if(!isnewplayer(M)) + if(player.client) + if(!isnewplayer(player)) body += "

    " body += "Transformation:
    " - if(isobserver(M)) + if(isobserver(player)) body += "Ghost | " else - body += "Make Ghost | " + body += "Make Ghost | " - if(ishuman(M) && !ismonkey(M)) + if(ishuman(player) && !ismonkey(player)) body += "Human | " else - body += "Make Human | " + body += "Make Human | " - if(ismonkey(M)) + if(ismonkey(player)) body += "Monkey | " else - body += "Make Monkey | " + body += "Make Monkey | " - if(iscyborg(M)) + if(iscyborg(player)) body += "Cyborg | " else - body += "Make Cyborg | " + body += "Make Cyborg | " - if(isAI(M)) + if(isAI(player)) body += "AI" else - body += "Make AI" + body += "Make AI" body += "

    " body += "Other actions:" body += "
    " - if(!isnewplayer(M)) - body += "Forcesay | " - body += "Apply Client Quirks | " - body += "Thunderdome 1 | " - body += "Thunderdome 2 | " - body += "Thunderdome Admin | " - body += "Thunderdome Observer | " - body += "Commend Behavior | " + if(!isnewplayer(player)) + body += "Forcesay | " + body += "Apply Client Quirks | " + body += "Thunderdome 1 | " + body += "Thunderdome 2 | " + body += "Thunderdome Admin | " + body += "Thunderdome Observer | " + body += "Commend Behavior | " body += "
    " body += "" - usr << browse(body, "window=adminplayeropts-[REF(M)];size=550x515") + usr << browse(body, "window=adminplayeropts-[REF(player)];size=550x515") SSblackbox.record_feedback("tally", "admin_verb", 1, "Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list) - set category = "Admin.Game" - set name = "Godmode" - if(!check_rights(R_ADMIN)) - return +ADMIN_VERB(game, toggle_godmode, "", R_ADMIN, mob/demigod in view()) + demigod.status_flags ^= GODMODE + to_chat(usr, span_adminnotice("Toggled [(demigod.status_flags & GODMODE) ? "ON" : "OFF"]"), confidential = TRUE) - M.status_flags ^= GODMODE - to_chat(usr, span_adminnotice("Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"), confidential = TRUE) - - log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") - var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]" + log_admin("[key_name(usr)] has toggled [key_name(demigod)]'s nodamage to [(demigod.status_flags & GODMODE) ? "On" : "Off"]") + var/msg = "[key_name_admin(usr)] has toggled [ADMIN_LOOKUPFLW(demigod)]'s nodamage to [(demigod.status_flags & GODMODE) ? "On" : "Off"]" message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Godmode", "[M.status_flags & GODMODE ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + admin_ticket_log(demigod, msg) /* If a guy was gibbed and you want to revive him, this is a good way to do so. Works kind of like entering the game with a new character. Character receives a new mind if they didn't have one. Traitors and the like can also be revived with the previous role mostly intact. -/N */ -/client/proc/respawn_character() - set category = "Admin.Game" - set name = "Respawn Character" - set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into." - if(!check_rights(R_ADMIN)) - return - - var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", "")) - if(!input) - return - +*/ +ADMIN_VERB(game, respawn_character, "Respawn a player that has been gibbed/dusted/killed. They must be a ghost", R_SPAWN, input as text) var/mob/dead/observer/G_found for(var/mob/dead/observer/G in GLOB.player_list) if(G.ckey == input) @@ -290,17 +262,10 @@ Traitors and the like can also be revived with the previous role mostly intact. to_chat(new_character, "You have been fully respawned. Enjoy the game.", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Respawn Character") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return new_character -/client/proc/cmd_admin_list_open_jobs() - set category = "Admin.Game" - set name = "Manage Job Slots" - - if(!check_rights(R_ADMIN)) - return - holder.manage_free_slots() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Job Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(game, manage_job_slots, "", R_ADMIN) + usr.client.holder.manage_free_slots() /datum/admins/proc/manage_free_slots() if(!check_rights()) @@ -342,38 +307,23 @@ Traitors and the like can also be revived with the previous role mostly intact. browser.set_content(dat.Join()) browser.open() -/client/proc/toggle_view_range() - set category = "Admin.Game" - set name = "Change View Range" - set desc = "switches between 1x and custom views" - +ADMIN_VERB(game, change_view_range, "Switch between default and larger views", R_ADMIN) + var/datum/view_data/view_size = usr.client.view_size if(view_size.getView() == view_size.default) view_size.setTo(input("Select view range:", "FUCK YE", 7) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,37) - 7) else - view_size.resetToDefault(getScreenSize(prefs.read_preference(/datum/preference/toggle/widescreen))) + view_size.resetToDefault(getScreenSize(usr.client.prefs.read_preference(/datum/preference/toggle/widescreen))) + log_admin("[key_name(usr)] changed their view range to [usr.client.view].") - log_admin("[key_name(usr)] changed their view range to [view].") - //message_admins("\blue [key_name_admin(usr)] changed their view range to [view].") //why? removed by order of XSI - - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Change View Range", "[view]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/toggle_combo_hud() - set category = "Admin.Game" - set name = "Toggle Combo HUD" - set desc = "Toggles the Admin Combo HUD (antag, sci, med, eng)" - - if(!check_rights(R_ADMIN)) - return - - if (combo_hud_enabled) - disable_combo_hud() +ADMIN_VERB(game, toggle_combo_hud, "Toggles the Admin Combo HUD (all huds)", R_ADMIN) + if(usr.client.combo_hud_enabled) + usr.client.disable_combo_hud() else - enable_combo_hud() + usr.client.enable_combo_hud() - to_chat(usr, "You toggled your admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].", confidential = TRUE) - message_admins("[key_name_admin(usr)] toggled their admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].") - log_admin("[key_name(usr)] toggled their admin combo HUD [combo_hud_enabled ? "ON" : "OFF"].") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Combo HUD", "[combo_hud_enabled ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "You toggled your admin combo HUD [usr.client.combo_hud_enabled ? "ON" : "OFF"].", confidential = TRUE) + message_admins("[key_name_admin(usr)] toggled their admin combo HUD [usr.client.combo_hud_enabled ? "ON" : "OFF"].") + log_admin("[key_name(usr)] toggled their admin combo HUD [usr.client.combo_hud_enabled ? "ON" : "OFF"].") /client/proc/enable_combo_hud() if (combo_hud_enabled) @@ -407,46 +357,29 @@ Traitors and the like can also be revived with the previous role mostly intact. mob.lighting_alpha = mob.default_lighting_alpha() mob.update_sight() -/datum/admins/proc/show_traitor_panel(mob/target_mob in GLOB.mob_list) - set category = "Admin.Game" - set desc = "Edit mobs's memory and role" - set name = "Show Traitor Panel" - var/datum/mind/target_mind = target_mob.mind +ADMIN_VERB(game, traitor_panel, "", R_ADMIN, mob/traitor in view()) + var/datum/mind/target_mind = traitor.mind if(!target_mind) to_chat(usr, "This mob has no mind!", confidential = TRUE) return - if(!istype(target_mob) && !istype(target_mind)) - to_chat(usr, "This can only be used on instances of type /mob and /mind", confidential = TRUE) - return target_mind.traitor_panel() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/show_skill_panel(target) - set category = "Admin.Game" - set desc = "Edit mobs's experience and skill levels" - set name = "Show Skill Panel" - var/datum/mind/target_mind - if(ismob(target)) - var/mob/target_mob = target - target_mind = target_mob.mind - else if (istype(target, /datum/mind)) - target_mind = target - else - to_chat(usr, "This can only be used on instances of type /mob and /mind", confidential = TRUE) +ADMIN_VERB(game, skill_panel, "", R_ADMIN, mob/skilled in view()) + if(!SSticker.HasRoundStarted()) + tgui_alert(usr,"The game hasn't started yet!") + return + + var/datum/mind/target_mind = skilled.mind + if(!target_mind) + to_chat(usr, "This mob has no mind!", confidential = TRUE) return var/datum/skill_panel/SP = new(usr, target_mind) SP.ui_interact(usr) -/datum/admins/proc/show_lag_switch_panel() - set category = "Admin.Game" - set name = "Show Lag Switches" - set desc="Display the controls for drastic lag mitigation measures." - +ADMIN_VERB(game, show_lag_switches, "Display the controls for drastic lag mitigation measures", R_ADMIN) if(!SSlag_switch.initialized) to_chat(usr, span_notice("The Lag Switch subsystem has not yet been initialized.")) return - if(!check_rights()) - return var/list/dat = list("Lag Switches

    Lag (Reduction) Switches

    ") dat += "Automatic Trigger: [SSlag_switch.auto_switch ? "On" : "Off"]
    " diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index d314d5ce58e..7eb3d06d40c 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -1,113 +1,66 @@ -/client/proc/jumptoarea(area/A in get_sorted_areas()) - set name = "Jump to Area" - set desc = "Area to jump to" - set category = "Admin.Game" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return +ADMIN_VERB(game, jump_to_area, "Jump to the specified area", NONE, area/destination in world) + var/turf/point - if(!A) - return - - var/list/turfs = list() - for(var/turf/T in A) - if(T.density) + for(var/turf/turf as anything in destination.get_contained_turfs()) + if(turf.density) continue - turfs.Add(T) + point = turf - if(length(turfs)) - var/turf/T = pick(turfs) - usr.forceMove(T) - log_admin("[key_name(usr)] jumped to [AREACOORD(T)]") - message_admins("[key_name_admin(usr)] jumped to [AREACOORD(T)]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Area") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - else - to_chat(src, "Nowhere to jump to!", confidential = TRUE) + if(!point) + to_chat(usr, span_warning("No turf to jump to!")) return + usr.forceMove(point) + log_admin("[key_name(usr)] jumped to [AREACOORD(point)]") + key_name_admin("[key_name(usr)] jumped to [AREACOORD(point)]") -/client/proc/jumptoturf(turf/T in world) - set name = "Jump to Turf" - set category = "Admin.Game" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) +ADMIN_VERB(game, jump_to_turf, "", NONE, turf/destination in world) + usr.forceMove(destination) + log_admin("[key_name(usr)] jumped to [AREACOORD(destination)]") + key_name_admin("[key_name(usr)] jumped to [AREACOORD(destination)]") + +ADMIN_VERB(game, jump_to_mob, "", NONE, mob/destination) + destination ||= tgui_input_list(usr, "Select a mob to teleport to you", "Admin Jump", GLOB.mob_list - usr) + if(!destination) return - log_admin("[key_name(usr)] jumped to [AREACOORD(T)]") - message_admins("[key_name_admin(usr)] jumped to [AREACOORD(T)]") - usr.forceMove(T) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Turf") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return + usr.forceMove(get_turf(destination)) + log_admin("[key_name(usr)] jumped to [key_name(destination)]") + message_admins("[key_name_admin(usr)] jumped to [ADMIN_LOOKUPFLW(destination)] at [AREACOORD(destination)]") -/client/proc/jumptomob(mob/M in GLOB.mob_list) - set category = "Admin.Game" - set name = "Jump to Mob" - - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) +ADMIN_VERB(game, jump_to_coordinate, "", NONE, x as num, y as num, z as num) + if(x < 1 || y < 1 || z < 1 || x > world.maxx || y > world.maxy || z > world.maxz) + to_chat(usr, span_warning("Invaild coordinates")) return - log_admin("[key_name(usr)] jumped to [key_name(M)]") - message_admins("[key_name_admin(usr)] jumped to [ADMIN_LOOKUPFLW(M)] at [AREACOORD(M)]") - if(src.mob) - var/mob/A = src.mob - var/turf/T = get_turf(M) - if(T && isturf(T)) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - A.forceMove(M.loc) - else - to_chat(A, "This mob is not located in the game world.", confidential = TRUE) + var/turf/destination = locate(x, y, z) + usr.forceMove(destination) + log_admin("[key_name(usr)] jumped to [AREACOORD(destination)]") + message_admins("[key_name_admin(usr)] jumped to [AREACOORD(destination)]") -/client/proc/jumptocoord(tx as num, ty as num, tz as num) - set category = "Admin.Game" - set name = "Jump to Coordinate" +ADMIN_VERB(game, jump_to_player, "", NONE) + var/list/players = list() + for(var/client/player as anything in GLOB.clients) + players[key_name(player)] = WEAKREF(player.mob) - if (!holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) + var/player = tgui_input_list(usr, "Select a player", "Admin Jump", players) + var/datum/weakref/player_ref = players[player] + var/mob/chosen_mob = player_ref.resolve() + if(!chosen_mob) + to_chat(usr, span_warning("That mob no longer exists!")) return - if(src.mob) - var/mob/A = src.mob - var/turf/T = locate(tx,ty,tz) - A.forceMove(T) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Coordiate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - message_admins("[key_name_admin(usr)] jumped to coordinates [tx], [ty], [tz]") + usr.forceMove(get_turf(chosen_mob)) + log_admin("[key_name(usr)] jumped to player [key_name(usr)]") + message_admins("[key_name_admin(usr)] jumped to player [key_name_admin(usr)]") -/client/proc/jumptokey() - set category = "Admin.Game" - set name = "Jump to Key" - - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) +ADMIN_VERB(game, get_mob, "", NONE, mob/teleportee) + teleportee ||= tgui_input_list(usr, "Select a mob to teleport to you", "Admin Jump", GLOB.mob_list - usr) + if(!teleportee) return - var/list/keys = list() - for(var/mob/M in GLOB.player_list) - keys += M.client - var/client/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sort_key(keys) - if(!selection) - to_chat(src, "No keys found.", confidential = TRUE) - return - var/mob/M = selection.mob - log_admin("[key_name(usr)] jumped to [key_name(M)]") - message_admins("[key_name_admin(usr)] jumped to [ADMIN_LOOKUPFLW(M)]") - - usr.forceMove(M.loc) - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Jump To Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/Getmob(mob/M in GLOB.mob_list - GLOB.dummy_mob_list) - set category = "Admin.Game" - set name = "Get Mob" - set desc = "Mob to teleport" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return - - var/atom/loc = get_turf(usr) - M.admin_teleport(loc) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - + var/turf/destination = get_turf(usr) + teleportee.admin_teleport(destination) /// Proc to hook user-enacted teleporting behavior and keep logging of the event. /atom/movable/proc/admin_teleport(atom/new_location) @@ -126,46 +79,26 @@ admin_ticket_log(src, msg) return ..() +ADMIN_VERB(game, get_player, "", NONE) + var/list/players = list() + for(var/client/player as anything in GLOB.clients) + players[key_name(player)] = WEAKREF(player.mob) -/client/proc/Getkey() - set category = "Admin.Game" - set name = "Get Key" - set desc = "Key to teleport" - - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) + var/player = tgui_input_list(usr, "Select a player", "Admin Jump", players) + var/datum/weakref/player_ref = players[player] + var/mob/chosen_mob = player_ref.resolve() + if(!chosen_mob) + to_chat(usr, span_warning("That mob no longer exists!")) return - var/list/keys = list() - for(var/mob/M in GLOB.player_list) - keys += M.client - var/client/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in sort_key(keys) - if(!selection) - return - var/mob/M = selection.mob + chosen_mob.admin_teleport(get_turf(usr)) - if(!M) - return - log_admin("[key_name(usr)] teleported [key_name(M)]") - var/msg = "[key_name_admin(usr)] teleported [ADMIN_LOOKUPFLW(M)]" - message_admins(msg) - admin_ticket_log(M, msg) - if(M) - M.forceMove(get_turf(usr)) - usr.forceMove(M.loc) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Get Key") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/sendmob(mob/jumper in sort_mobs()) - set category = "Admin.Game" - set name = "Send Mob" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return +ADMIN_CONTEXT_ENTRY(context_sendmob, "Send Mob", NONE, mob/jumper in world) var/list/sorted_areas = get_sorted_areas() if(!length(sorted_areas)) - to_chat(src, "No areas found.", confidential = TRUE) + to_chat(usr, "No areas found.", confidential = TRUE) return - var/area/target_area = tgui_input_list(src, "Pick an area", "Send Mob", sorted_areas) + var/area/target_area = tgui_input_list(usr, "Pick an area", "Send Mob", sorted_areas) if(isnull(target_area)) return if(!istype(target_area)) @@ -177,5 +110,4 @@ message_admins(msg) admin_ticket_log(jumper, msg) else - to_chat(src, "Failed to move mob to a valid location.", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Send Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "Failed to move mob to a valid location.", confidential = TRUE) diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index 4d47590617a..3fc2f1a58e6 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -13,57 +13,13 @@ // We also make SURE to fail loud, IE: if something stops the message from reaching the recipient, the sender HAS to know // If you "refactor" this to make it "cleaner" I will send you to hell -/// Allows right clicking mobs to send an admin PM to their client, forwards the selected mob's client to cmd_admin_pm -/client/proc/cmd_admin_pm_context(mob/M in GLOB.mob_list) - set category = null - set name = "Admin PM Mob" - if(!holder) - to_chat(src, - type = MESSAGE_TYPE_ADMINPM, - html = span_danger("Error: Admin-PM-Context: Only administrators may use this command."), - confidential = TRUE) - return - if(!ismob(M)) - to_chat(src, - type = MESSAGE_TYPE_ADMINPM, - html = span_danger("Error: Admin-PM-Context: Target mob is not a mob, somehow."), - confidential = TRUE) - return - cmd_admin_pm(M.client, null) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin PM Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/// Shows a list of clients we could send PMs to, then forwards our choice to cmd_admin_pm -/client/proc/cmd_admin_pm_panel() - set category = "Admin" - set name = "Admin PM" - if(!holder) - to_chat(src, - type = MESSAGE_TYPE_ADMINPM, - html = span_danger("Error: Admin-PM-Panel: Only administrators may use this command."), - confidential = TRUE) +/// Allows the admin to send an AdminPM directly to the client of a mob +ADMIN_CONTEXT_ENTRY(contextcmd_admin_pm, "Admin PM Mob", NONE, mob/target in GLOB.mob_list) + if(!istype(target)) + to_chat(src, type = MESSAGE_TYPE_ADMINPM, html = span_danger("Error: Admin-PM-Context: Target mob is somehow not a mob!")) return - var/list/targets = list() - for(var/client/client in GLOB.clients) - var/nametag = "" - var/mob/lad = client.mob - var/mob_name = lad?.name - var/real_mob_name = lad?.real_name - if(!lad) - nametag = "(No Mob)" - else if(isnewplayer(lad)) - nametag = "(New Player)" - else if(isobserver(lad)) - nametag = "[mob_name](Ghost)" - else - nametag = "[real_mob_name](as [mob_name])" - targets["[nametag] - [client]"] = client - - var/target = input(src,"To whom shall we send a message?", "Admin PM", null) as null|anything in sort_list(targets) - if (isnull(target)) - return - cmd_admin_pm(targets[target], null) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin PM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + cmd_admin_pm(target.client, null) /// Replys to some existing ahelp, reply to whom, which can be a client or ckey /client/proc/cmd_ahelp_reply(whom) @@ -157,7 +113,7 @@ return cmd_admin_pm(whom, message) -//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM. +//takes input from cmd_admin_pm_context or /client/Topic and sends them a PM. //Fetching a message if needed. //whom here is a client, a ckey, or [EXTERNAL_PM_USER] if this is from tgs. message is the default message to send /client/proc/cmd_admin_pm(whom, message) diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm deleted file mode 100644 index 3ff5c6802e6..00000000000 --- a/code/modules/admin/verbs/adminsay.dm +++ /dev/null @@ -1,39 +0,0 @@ -/client/proc/cmd_admin_say(msg as text) - set category = "Admin" - set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite - set hidden = TRUE - if(!check_rights(0)) - return - - msg = emoji_parse(copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN)) - if(!msg) - return - - if(findtext(msg, "@") || findtext(msg, "#")) - var/list/link_results = check_asay_links(msg) - if(length(link_results)) - msg = link_results[ASAY_LINK_NEW_MESSAGE_INDEX] - link_results[ASAY_LINK_NEW_MESSAGE_INDEX] = null - var/list/pinged_admin_clients = link_results[ASAY_LINK_PINGED_ADMINS_INDEX] - for(var/iter_ckey in pinged_admin_clients) - var/client/iter_admin_client = pinged_admin_clients[iter_ckey] - if(!iter_admin_client?.holder) - continue - window_flash(iter_admin_client) - SEND_SOUND(iter_admin_client.mob, sound('sound/misc/asay_ping.ogg')) - - mob.log_talk(msg, LOG_ASAY) - msg = keywords_lookup(msg) - var/asay_color = prefs.read_preference(/datum/preference/color/asay_color) - var/custom_asay_color = (CONFIG_GET(flag/allow_admin_asaycolor) && asay_color) ? "" : "" - msg = "[span_adminsay("[span_prefix("ADMIN:")] [key_name(usr, 1)] [ADMIN_FLW(mob)]: [custom_asay_color][msg]")][custom_asay_color ? "":null]" - to_chat(GLOB.admins, - type = MESSAGE_TYPE_ADMINCHAT, - html = msg, - confidential = TRUE) - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Asay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/get_admin_say() - var/msg = input(src, null, "asay \"text\"") as text|null - cmd_admin_say(msg) diff --git a/code/modules/admin/verbs/ai_triumvirate.dm b/code/modules/admin/verbs/ai_triumvirate.dm index ca7ebfe7cc4..fc808d1f1ef 100644 --- a/code/modules/admin/verbs/ai_triumvirate.dm +++ b/code/modules/admin/verbs/ai_triumvirate.dm @@ -27,10 +27,7 @@ GLOBAL_DATUM(triple_ai_controller, /datum/triple_ai_controller) GLOB.triple_ai_controller = null . = ..() -/client/proc/triple_ai() - set category = "Admin.Events" - set name = "Toggle AI Triumvirate" - +ADMIN_VERB(events, toggle_ai_triumvirate, "", R_FUN) if(SSticker.current_state > GAME_STATE_PREGAME) to_chat(usr, "This option is currently only usable during pregame. This may change at a later date.", confidential = TRUE) return diff --git a/code/modules/admin/verbs/anonymousnames.dm b/code/modules/admin/verbs/anonymousnames.dm index 6f01b88f113..5de7528d4c7 100644 --- a/code/modules/admin/verbs/anonymousnames.dm +++ b/code/modules/admin/verbs/anonymousnames.dm @@ -7,10 +7,7 @@ GLOBAL_DATUM(current_anonymous_theme, /datum/anonymous_theme) this is the setup, it handles announcing crew and other settings for the mode and then creating the datum singleton */ -/client/proc/anon_names() - set category = "Admin.Events" - set name = "Setup Anonymous Names" - +ADMIN_VERB(events, setup_anonymous_names, "", R_FUN) if(GLOB.current_anonymous_theme) var/response = tgui_alert(usr, "Anon mode is currently enabled. Disable?", "cold feet", list("Disable Anon Names", "Keep it Enabled")) if(response != "Disable Anon Names") diff --git a/code/modules/admin/verbs/atmosdebug.dm b/code/modules/admin/verbs/atmosdebug.dm index 8335032e670..bc03023e597 100644 --- a/code/modules/admin/verbs/atmosdebug.dm +++ b/code/modules/admin/verbs/atmosdebug.dm @@ -1,11 +1,4 @@ -/client/proc/atmosscan() - set category = "Mapping" - set name = "Check Plumbing" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return - SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Plumbing") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - +ADMIN_VERB(mapping, check_plumbing, "", R_DEBUG) //all plumbing - yes, some things might get stated twice, doesn't matter. for(var/obj/machinery/atmospherics/components/pipe in GLOB.machines) if(pipe.z && (!pipe.nodes || !pipe.nodes.len || (null in pipe.nodes))) @@ -24,13 +17,7 @@ if(!(node1 in node2.nodes)) to_chat(usr, "One-way connection in [node1.name] located at [ADMIN_VERBOSEJMP(node1)]", confidential = TRUE) -/client/proc/powerdebug() - set category = "Mapping" - set name = "Check Power" - if(!src.holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return - SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Power") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(mapping, check_power, "", R_DEBUG) var/list/results = list() for (var/datum/powernet/PN in SSmachines.powernets) diff --git a/code/modules/admin/verbs/beakerpanel.dm b/code/modules/admin/verbs/beakerpanel.dm index 5ba32ae7b6c..b2a8ce6cfc8 100644 --- a/code/modules/admin/verbs/beakerpanel.dm +++ b/code/modules/admin/verbs/beakerpanel.dm @@ -60,11 +60,7 @@ reagents.add_reagent(reagenttype, amount) return container -/datum/admins/proc/beaker_panel() - set category = "Admin.Events" - set name = "Spawn reagent container" - if(!check_rights()) - return +ADMIN_VERB(events, spawn_reagent_container, "", R_SPAWN) var/datum/asset/asset_datum = get_asset_datum(/datum/asset/simple/namespaced/common) asset_datum.send(usr) //Could somebody tell me why this isn't using the browser datum, given that it copypastes all of browser datum's html diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index 95948525229..23c0d93af25 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -1,22 +1,13 @@ -/datum/admins/proc/open_borgopanel(borgo in GLOB.silicon_mobs) - set category = "Admin.Game" - set name = "Show Borg Panel" - set desc = "Show borg panel" - - if(!check_rights(R_ADMIN)) - return - - if (!iscyborg(borgo)) - borgo = input("Select a borg", "Select a borg", null, null) as null|anything in sort_names(GLOB.silicon_mobs) - if (!iscyborg(borgo)) - to_chat(usr, span_warning("Borg is required for borgpanel"), confidential = TRUE) +ADMIN_CONTEXT_ENTRY(context_borg_panel, "Show Borg Panel", R_ADMIN, mob/living/silicon/borgo in world) + if(!istype(borgo)) + var/list/borgs = sort_names(GLOB.silicon_mobs) + borgo = tgui_input_list(usr, "Select Borg", "Borg Panel", borgs) + if(!borgo) + return var/datum/borgpanel/borgpanel = new(usr, borgo) - borgpanel.ui_interact(usr) - - /datum/borgpanel var/mob/living/silicon/robot/borg var/user diff --git a/code/modules/admin/verbs/cinematic.dm b/code/modules/admin/verbs/cinematic.dm index b001099d283..3b7cebbd0b0 100644 --- a/code/modules/admin/verbs/cinematic.dm +++ b/code/modules/admin/verbs/cinematic.dm @@ -1,10 +1,6 @@ -/client/proc/cinematic() - set name = "Cinematic" - set category = "Admin.Fun" - set desc = "Shows a cinematic." // Intended for testing but I thought it might be nice for events on the rare occasion Feel free to comment it out if it's not wanted. - set hidden = TRUE - - if(!SSticker) +ADMIN_VERB(fun, show_cinematic, "Shows a cinematic", R_FUN) + if(!SSticker.initialized) + to_chat(usr, span_warning("Wait for the game to finish loading!")) return var/datum/cinematic/choice = tgui_input_list(usr, "Chose a cinematic to play to everyone in the server.", "Choose Cinematic", sort_list(subtypesof(/datum/cinematic), GLOBAL_PROC_REF(cmp_typepaths_asc))) diff --git a/code/modules/admin/verbs/commandreport.dm b/code/modules/admin/verbs/commandreport.dm index c6fa3e55408..fa871d5c473 100644 --- a/code/modules/admin/verbs/commandreport.dm +++ b/code/modules/admin/verbs/commandreport.dm @@ -7,30 +7,15 @@ #define WIZARD_PRESET "The Wizard Federation" #define CUSTOM_PRESET "Custom Command Name" -/// Verb to change the global command name. -/client/proc/cmd_change_command_name() - set category = "Admin.Events" - set name = "Change Command Name" - - if(!check_rights(R_ADMIN)) - return - +ADMIN_VERB(events, change_command_name, "", R_ADMIN) var/input = input(usr, "Please input a new name for Central Command.", "What?", "") as text|null if(!input) return change_command_name(input) - message_admins("[key_name_admin(src)] has changed Central Command's name to [input]") - log_admin("[key_name(src)] has changed the Central Command name to: [input]") + message_admins("[key_name_admin(usr)] has changed Central Command's name to [input]") + log_admin("[key_name(usr)] has changed the Central Command name to: [input]") -/// Verb to open the create command report window and send command reports. -/client/proc/cmd_admin_create_centcom_report() - set category = "Admin.Events" - set name = "Create Command Report" - - if(!check_rights(R_ADMIN)) - return - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Command Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(events, create_command_report, "", R_ADMIN) var/datum/command_report_menu/tgui = new(usr) tgui.ui_interact(usr) diff --git a/code/modules/admin/verbs/config_helpers.dm b/code/modules/admin/verbs/config_helpers.dm index 1d2d42faecd..a452d47abaf 100644 --- a/code/modules/admin/verbs/config_helpers.dm +++ b/code/modules/admin/verbs/config_helpers.dm @@ -1,19 +1,12 @@ /// Verbs created to help server operators with generating certain config files. -/client/proc/generate_job_config() - set name = "Generate Job Configuration" - set category = "Server" - set desc = "Generate a job configuration (jobconfig.toml) file for the server. If TOML file already exists, will re-generate it based off the already existing config values. Will migrate from the old jobs.txt format if necessary." - - if(!check_rights(R_SERVER)) - return - +ADMIN_VERB(server, generate_job_configuration, "", R_SERVER) if(tgui_alert(usr, "This verb is not at all useful if you are not a server operator with access to the configuration folder. Do you wish to proceed?", "Generate jobconfig.toml for download", list("Yes", "No")) != "Yes") return - if(SSjob.generate_config(usr)) - to_chat(usr, span_notice("Job configuration file generated. Download prompt should appear now.")) - else + if(!SSjob.generate_config(usr)) to_chat(usr, span_warning("Job configuration file could not be generated. Check the server logs / runtimes / above warning messages for more information.")) + return + + to_chat(usr, span_notice("Job configuration file generated. Download prompt should appear now.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Generate Job Configuration") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 221aca3da99..e69de29bb2d 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -1,39 +0,0 @@ -/client/proc/dsay(msg as text) - set category = "Admin.Game" - set name = "Dsay" - set hidden = TRUE - if(!holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return - if(!mob) - return - if(prefs.muted & MUTE_DEADCHAT) - to_chat(src, span_danger("You cannot send DSAY messages (muted)."), confidential = TRUE) - return - - if (handle_spam_prevention(msg,MUTE_DEADCHAT)) - return - - msg = copytext_char(sanitize(msg), 1, MAX_MESSAGE_LEN) - mob.log_talk(msg, LOG_DSAY) - - if (!msg) - return - var/rank_name = holder.rank_names() - var/admin_name = key - if(holder.fakekey) - rank_name = pick(strings("admin_nicknames.json", "ranks", "config")) - admin_name = pick(strings("admin_nicknames.json", "names", "config")) - var/name_and_rank = "[span_tooltip(rank_name, "STAFF")] ([admin_name])" - - deadchat_broadcast("[span_prefix("DEAD:")] [name_and_rank] says, \"[emoji_parse(msg)]\"") - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Dsay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/get_dead_say() - var/msg = input(src, null, "dsay \"text\"") as text|null - - if (isnull(msg)) - return - - dsay(msg) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 8cece00fb58..4fda7a1d5e4 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1,40 +1,19 @@ -/client/proc/Debug2() - set category = "Debug" - set name = "Debug-Game" - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(debug, toggle_global_debugging, "", R_DEBUG) + GLOB.Debug2 = !GLOB.Debug2 + var/message = "has toggled global debugging [(GLOB.Debug2 ? "on" : "off")]" + log_admin("[key_name(usr)] [message]") + message_admins("[key_name_admin(usr)] [message]") - if(GLOB.Debug2) - GLOB.Debug2 = 0 - message_admins("[key_name(src)] toggled debugging off.") - log_admin("[key_name(src)] toggled debugging off.") - else - GLOB.Debug2 = 1 - message_admins("[key_name(src)] toggled debugging on.") - log_admin("[key_name(src)] toggled debugging on.") - - SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Debug Two") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/Cell() - set category = "Debug" - set name = "Air Status in Location" - if(!mob) - return - var/turf/T = get_turf(mob) - if(!isturf(T)) - return - atmos_scan(user=usr, target=T, silent=TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Air Status In Location") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_robotize(mob/M in GLOB.mob_list) - set category = "Admin.Fun" - set name = "Make Cyborg" +ADMIN_VERB(debug, get_air_status, "", R_DEBUG) + atmos_scan(user=usr, target=get_turf(usr), silent=TRUE) +ADMIN_VERB(debug, make_cyborg, "", R_DEBUG, mob/target in GLOB.mob_list) if(!SSticker.HasRoundStarted()) - tgui_alert(usr,"Wait until the game starts") + tgui_alert(usr, "Wait until the game starts") return - log_admin("[key_name(src)] has robotized [M.key].") - INVOKE_ASYNC(M, TYPE_PROC_REF(/mob, Robotize)) + + log_admin("[key_name(usr)] has robotized [key_name(target)].") + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob, Robotize)) /client/proc/poll_type_to_del(search_string) var/list/types = get_fancy_list_of_atom_types() @@ -50,194 +29,168 @@ return return types[key] -//TODO: merge the vievars version into this or something maybe mayhaps -/client/proc/cmd_debug_del_all(object as text) - set category = "Debug" - set name = "Del-All" - - var/type_to_del = poll_type_to_del(object) - +ADMIN_VERB(debug, delete_all_of_type, "", R_DEBUG, object as text) + var/type_to_del = usr.client.poll_type_to_del(object) if(!type_to_del) return + var/force_del = tgui_alert(usr, "Force Deletion?", "Del-All", list("Yes", "No", "Cancel")) + if(force_del == "Cancel") + return + force_del = (force_del == "Yes") + var/counter = 0 - for(var/atom/O in world) - if(istype(O, type_to_del)) - counter++ - qdel(O) + var/atom/target + while((target = locate(type_to_del) in world)) + counter++ + qdel(target, force = force_del) CHECK_TICK - log_admin("[key_name(src)] has deleted all ([counter]) instances of [type_to_del].") - message_admins("[key_name_admin(src)] has deleted all ([counter]) instances of [type_to_del].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Delete All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_debug_force_del_all(object as text) - set category = "Debug" - set name = "Force-Del-All" - - var/type_to_del = poll_type_to_del(object) + var/message = "has [(force_del ? "forcibly" : "")] deleted all ([counter]) instances of '[type_to_del]'" + log_admin("[key_name(usr)] [message]") + message_admins("[key_name_admin(usr)] [message]") +ADMIN_VERB(debug, hard_delete_all_of_type, "", R_DEBUG, object as text) + var/type_to_del = usr.client.poll_type_to_del(object) if(!type_to_del) return - var/counter = 0 - for(var/atom/O in world) - if(istype(O, type_to_del)) - counter++ - qdel(O, force = TRUE) - CHECK_TICK - log_admin("[key_name(src)] has force-deleted all ([counter]) instances of [type_to_del].") - message_admins("[key_name_admin(src)] has force-deleted all ([counter]) instances of [type_to_del].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Force-Delete All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_debug_hard_del_all(object as text) - set category = "Debug" - set name = "Hard-Del-All" - - var/type_to_del = poll_type_to_del(object) - - if(!type_to_del) - return - - var/choice = alert("ARE YOU SURE that you want to hard delete this type? It will cause MASSIVE lag.", "Hoooo lad what happen?", "Yes", "No") + var/choice = tgui_alert( + usr, + "ARE YOU SURE that you want to hard delete this type? This will cause MASSIVE lag!", + "What the fuck happened?", + list("Yes", "No"), + ) if(choice != "Yes") return - choice = alert("Do you want to pre qdelete the atom? This will speed things up significantly, but may break depending on your level of fuckup.", "How do you even get it that bad", "Yes", "No") + choice = tgui_alert( + usr, + "Do you want to pre qdelete the atom? This will speed things up significantly, but may break depending on your level of fuckup.", + "How do you even get it that bad", + list("Yes", "No"), + ) var/should_pre_qdel = TRUE if(choice == "No") should_pre_qdel = FALSE - choice = alert("Ok one last thing, do you want to yield to the game? or do it all at once. These are hard deletes remember.", "Jesus christ man", "Yield", "Ignore the server") + choice = tgui_alert( + usr, + "Ok one last thing, do you want to yield to the game? or do it all at once. These are hard deletes remember.", + "Jesus christ man", + list("Yield", "Ignore the server"), + ) var/should_check_tick = TRUE if(choice == "Ignore the server") should_check_tick = FALSE var/counter = 0 - if(should_check_tick) - for(var/atom/O in world) - if(istype(O, type_to_del)) - counter++ - if(should_pre_qdel) - qdel(O) - del(O) - CHECK_TICK - else - for(var/atom/O in world) - if(istype(O, type_to_del)) - counter++ - if(should_pre_qdel) - qdel(O) - del(O) - CHECK_TICK - log_admin("[key_name(src)] has hard deleted all ([counter]) instances of [type_to_del].") - message_admins("[key_name_admin(src)] has hard deleted all ([counter]) instances of [type_to_del].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Hard Delete All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + var/atom/target + while((target = locate(type_to_del) in world)) + counter++ + if(should_pre_qdel) + qdel(target) + del(target) -/client/proc/cmd_debug_make_powernets() - set category = "Debug" - set name = "Make Powernets" + if(should_check_tick) + CHECK_TICK + + var/message = "has HARD DELETED all ([counter]) instances of '[type_to_del]'" + log_admin("[key_name(usr)] [message]") + message_admins("[key_name_admin(usr)] [message]") + +ADMIN_VERB(debug, make_powernets, "", R_DEBUG) SSmachines.makepowernets() - log_admin("[key_name(src)] has remade the powernet. makepowernets() called.") - message_admins("[key_name_admin(src)] has remade the powernets. makepowernets() called.") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Powernets") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_grantfullaccess(mob/M in GLOB.mob_list) - set category = "Debug" - set name = "Grant Full Access" + log_admin("[key_name(usr)] has remade the powernet.") + message_admins("[key_name_admin(usr)] has remade the powernets.") +ADMIN_VERB(game, grant_full_access, "", R_ADMIN, mob/living/carbon/human/target in view()) if(!SSticker.HasRoundStarted()) - tgui_alert(usr,"Wait until the game starts") + tgui_alert(usr, "Wait until the game starts") return - if(ishuman(M)) - var/mob/living/carbon/human/H = M - var/obj/item/worn = H.wear_id - var/obj/item/card/id/id = null - if(worn) - id = worn.GetID() - if(id) - if(id == worn) - worn = null - qdel(id) + var/obj/item/worn = target.wear_id + var/obj/item/card/id/id = null - id = new /obj/item/card/id/advanced/debug() + if(worn) + id = worn.GetID() + if(id) + if(id == worn) + worn = null + qdel(id) - id.registered_name = H.real_name - id.update_label() - id.update_icon() + id = new /obj/item/card/id/advanced/debug() - if(worn) - if(istype(worn, /obj/item/modular_computer/pda)) - var/obj/item/modular_computer/pda/PDA = worn - PDA.InsertID(id, H) + id.registered_name = target.real_name + id.update_label() + id.update_icon() - else if(istype(worn, /obj/item/storage/wallet)) - var/obj/item/storage/wallet/W = worn - W.front_id = id - id.forceMove(W) - W.update_icon() - else - H.equip_to_slot(id,ITEM_SLOT_ID) + if(worn) + if(istype(worn, /obj/item/modular_computer/pda)) + var/obj/item/modular_computer/pda/PDA = worn + PDA.InsertID(id, target) + else if(istype(worn, /obj/item/storage/wallet)) + var/obj/item/storage/wallet/wallet = worn + wallet.front_id = id + id.forceMove(target) + target.update_icon() else - tgui_alert(usr,"Invalid mob") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Grant Full Access") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - log_admin("[key_name(src)] has granted [M.key] full access.") - message_admins(span_adminnotice("[key_name_admin(usr)] has granted [M.key] full access.")) + target.equip_to_slot(id, ITEM_SLOT_ID) -/client/proc/cmd_assume_direct_control(mob/M in GLOB.mob_list) - set category = "Admin.Game" - set name = "Assume direct control" - set desc = "Direct intervention" + log_admin("[key_name(usr)] has granted [key_name(target)] full access.") + message_admins("[key_name_admin(usr)] has granted [key_name_admin(target)] full access.") - if(M.ckey) - if(tgui_alert(usr,"This mob is being controlled by [M.key]. Are you sure you wish to assume control of it? [M.key] will be made a ghost.",,list("Yes","No")) != "Yes") +ADMIN_VERB(game, assume_direct_control, "", R_ADMIN, mob/target in view()) + if(target.ckey) + var/force = tgui_alert( + usr, + "This mob is already being controlled by '[target.ckey]'. Are you sure you wish to assume control of it? The existing client will be made a ghost.", + "Assuming Control", + list("Yes", "No"), + ) + if(force != "Yes") return - if(!M || QDELETED(M)) + + if(QDELETED(target)) to_chat(usr, span_warning("The target mob no longer exists.")) return - message_admins(span_adminnotice("[key_name_admin(usr)] assumed direct control of [M].")) - log_admin("[key_name(usr)] assumed direct control of [M].") - var/mob/adminmob = mob - if(M.ckey) - M.ghostize(FALSE) - M.key = key - init_verbs() + + var/target_name = key_name(target) + if(target.ckey) + target.ghostize(FALSE) + + var/adminmob = usr + target.key = usr.key if(isobserver(adminmob)) qdel(adminmob) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Assume Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_give_direct_control(mob/M in GLOB.mob_list) - set category = "Admin.Game" - set name = "Give direct control" + message_admins(span_adminnotice("[key_name_admin(usr)] assumed direct control of [target_name].")) + log_admin("[key_name(usr)] assumed direct control of [target_name].") - if(!M) - return - if(M.ckey) - if(tgui_alert(usr,"This mob is being controlled by [M.key]. Are you sure you wish to give someone else control of it? [M.key] will be made a ghost.",,list("Yes","No")) != "Yes") +ADMIN_VERB(game, give_direct_control, "", R_DEBUG, mob/pawn in view()) + if(pawn.ckey) + if(tgui_alert(usr,"This mob is being controlled by [pawn.key]. Are you sure you wish to give someone else control of it? [pawn.key] will be made a ghost.",,list("Yes","No")) != "Yes") return var/client/newkey = input(src, "Pick the player to put in control.", "New player") as null|anything in sort_list(GLOB.clients) var/mob/oldmob = newkey.mob var/delmob = FALSE if((isobserver(oldmob) || tgui_alert(usr,"Do you want to delete [newkey]'s old mob?","Delete?",list("Yes","No")) != "No")) delmob = TRUE - if(!M || QDELETED(M)) + if(QDELETED(pawn)) to_chat(usr, span_warning("The target mob no longer exists, aborting.")) return - if(M.ckey) - M.ghostize(FALSE) - M.ckey = newkey.key - M.client?.init_verbs() + + if(pawn.ckey) + pawn.ghostize(FALSE) + pawn.ckey = newkey.key + pawn.client?.init_verbs() if(delmob) qdel(oldmob) - message_admins(span_adminnotice("[key_name_admin(usr)] gave away direct control of [M] to [newkey].")) - log_admin("[key_name(usr)] gave away direct control of [M] to [newkey].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Direct Control") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_areatest(on_station, filter_maint) - set category = "Mapping" - set name = "Test Areas" + message_admins(span_adminnotice("[key_name_admin(usr)] gave away direct control of [pawn] to [newkey].")) + log_admin("[key_name(usr)] gave away direct control of [pawn] to [newkey].") +/datum/admins/proc/cmd_admin_areatest(on_station = FALSE, filter_maint = FALSE) var/list/dat = list() var/list/areas_all = list() var/list/areas_with_APC = list() @@ -427,24 +380,16 @@ popup.set_content(dat.Join()) popup.open() +ADMIN_VERB(mapping, test_station_areas, "", R_DEBUG) + usr.client.holder.cmd_admin_areatest(on_station = TRUE) -/client/proc/cmd_admin_areatest_station() - set category = "Mapping" - set name = "Test Areas (STATION ONLY)" - cmd_admin_areatest(TRUE) +ADMIN_VERB(mapping, test_station_areas_without_maint, "", R_DEBUG) + usr.client.holder.cmd_admin_areatest(on_station = TRUE, filter_maint = TRUE) -/client/proc/cmd_admin_areatest_station_no_maintenance() - set category = "Mapping" - set name = "Test Areas (STATION - NO MAINT)" - cmd_admin_areatest(on_station = TRUE, filter_maint = TRUE) - -/client/proc/cmd_admin_areatest_all() - set category = "Mapping" - set name = "Test Areas (ALL)" - cmd_admin_areatest(FALSE) +ADMIN_VERB(mapping, test_all_areas, "", R_DEBUG) + usr.client.holder.cmd_admin_areatest() /client/proc/robust_dress_shop() - var/list/baseoutfits = list("Naked","Custom","As Job...", "As Plasmaman...") var/list/outfits = list() var/list/paths = subtypesof(/datum/outfit) - typesof(/datum/outfit/job) - typesof(/datum/outfit/plasmaman) @@ -495,88 +440,66 @@ return dresscode -/client/proc/cmd_admin_rejuvenate(mob/living/M in GLOB.mob_list) - set category = "Debug" - set name = "Rejuvenate" - - if(!check_rights(R_ADMIN)) - return - - if(!mob) - return - if(!istype(M)) - tgui_alert(usr,"Cannot revive a ghost") - return - M.revive(ADMIN_HEAL_ALL) - - log_admin("[key_name(usr)] healed / revived [key_name(M)]") - var/msg = span_danger("Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(M)]!") +ADMIN_CONTEXT_ENTRY(context_rejuvenate, "Rejuvenate", R_ADMIN, mob/living/fallen in world) + fallen.revive(ADMIN_HEAL_ALL) + log_admin("[key_name(usr)] healed / revived [key_name(fallen)]") + var/msg = span_danger("Admin [key_name_admin(usr)] healed / revived [ADMIN_LOOKUPFLW(fallen)]!") message_admins(msg) - admin_ticket_log(M, msg) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvenate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + admin_ticket_log(fallen, msg) -/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in world) - set category = "Debug" - set name = "Delete" +ADMIN_CONTEXT_ENTRY(context_delete, "Delete", (R_SPAWN|R_DEBUG), atom/target as obj|mob|turf in world) + holder.admin_delete(target) - if(!check_rights(R_SPAWN|R_DEBUG)) - return +ADMIN_CONTEXT_ENTRY(context_check_contents, "Check Contents", R_ADMIN, mob/living/target in world) + var/list/all_contents = target.get_contents() + for(var/content in all_contents) + to_chat(usr, "[content] [ADMIN_VV(content)] [ADMIN_TAG(content)]", confidential = TRUE) - admin_delete(A) - -/client/proc/cmd_admin_check_contents(mob/living/M in GLOB.mob_list) - set category = "Debug" - set name = "Check Contents" - - var/list/L = M.get_contents() - for(var/t in L) - to_chat(usr, "[t] [ADMIN_VV(t)] [ADMIN_TAG(t)]", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Contents") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/modify_goals() - set category = "Debug" - set name = "Modify goals" - - if(!check_rights(R_ADMIN)) - return - - holder.modify_goals() - -/datum/admins/proc/modify_goals() +ADMIN_VERB(debug, modify_goals, "", R_ADMIN) var/dat = "" for(var/datum/station_goal/S in GLOB.station_goals) dat += "[S.name] - Announce | Remove
    " - dat += "
    Add New Goal" + dat += "
    Add New Goal" usr << browse(dat, "window=goals;size=400x400") -/client/proc/cmd_debug_mob_lists() - set category = "Debug" - set name = "Debug Mob Lists" - set desc = "For when you just gotta know" - var/chosen_list = tgui_input_list(usr, "Which list?", "Select List", list("Players","Admins","Mobs","Living Mobs","Dead Mobs","Clients","Joined Clients")) +#define MOB_LIST_PLAYERS "Players" +#define MOB_LIST_ADMINS "Admins" +#define MOB_LIST_MOBS "Mobs" +#define MOB_LIST_MOBS_LIVING "Living Mobs" +#define MOB_LIST_MOBS_DEAD "Dead Mobs" +#define MOB_LIST_CLIENTS "Clients" +#define MOB_LIST_CLIENTS_JOINED "Joined Clients" +// Theres probably a better name for this +#define MOB_LIST_LIST list( \ + MOB_LIST_PLAYERS, \ + MOB_LIST_ADMINS, \ + MOB_LIST_MOBS, \ + MOB_LIST_MOBS_LIVING, \ + MOB_LIST_MOBS_DEAD, \ + MOB_LIST_CLIENTS, \ + MOB_LIST_CLIENTS_JOINED) + +ADMIN_VERB(debug, debug_mob_lists, "For when you just gotta know", R_DEBUG) + var/chosen_list = tgui_input_list(usr, "Which list?", "Select List", MOB_LIST_LIST) if(isnull(chosen_list)) return switch(chosen_list) - if("Players") + if(MOB_LIST_PLAYERS) to_chat(usr, jointext(GLOB.player_list,","), confidential = TRUE) - if("Admins") + if(MOB_LIST_ADMINS) to_chat(usr, jointext(GLOB.admins,","), confidential = TRUE) - if("Mobs") + if(MOB_LIST_MOBS) to_chat(usr, jointext(GLOB.mob_list,","), confidential = TRUE) - if("Living Mobs") + if(MOB_LIST_MOBS_LIVING) to_chat(usr, jointext(GLOB.alive_mob_list,","), confidential = TRUE) - if("Dead Mobs") + if(MOB_LIST_MOBS_DEAD) to_chat(usr, jointext(GLOB.dead_mob_list,","), confidential = TRUE) - if("Clients") + if(MOB_LIST_CLIENTS) to_chat(usr, jointext(GLOB.clients,","), confidential = TRUE) - if("Joined Clients") + if(MOB_LIST_CLIENTS_JOINED) to_chat(usr, jointext(GLOB.joined_player_list,","), confidential = TRUE) -/client/proc/cmd_display_del_log() - set category = "Debug" - set name = "Display del() Log" - set desc = "Display del's log of everything that's passed through it." - +ADMIN_VERB(debug, display_del_log, "Display del's log of everything that's passed through it", R_DEBUG) var/list/dellog = list("List of things that have gone through qdel this round

      ") sortTim(SSgarbage.items, cmp=/proc/cmp_qdel_item_time, associative = TRUE) for(var/path in SSgarbage.items) @@ -606,61 +529,38 @@ usr << browse(dellog.Join(), "window=dellog") -/client/proc/cmd_display_overlay_log() - set category = "Debug" - set name = "Display overlay Log" - set desc = "Display SSoverlays log of everything that's passed through it." - - render_stats(SSoverlays.stats, src) - -/client/proc/cmd_display_init_log() - set category = "Debug" - set name = "Display Initialize() Log" - set desc = "Displays a list of things that didn't handle Initialize() properly" +ADMIN_VERB(debug, display_overlay_log, "Display SSoverlays log of everything that's passed through it", R_DEBUG) + render_stats(SSoverlays.stats, usr) +ADMIN_VERB(debug, display_initailize_log, "Displays a list of things that didn't handle Initialize() properly", R_DEBUG) usr << browse(replacetext(SSatoms.InitLog(), "\n", "
      "), "window=initlog") -/client/proc/open_colorblind_test() - set category = "Debug" - set name = "Colorblind Testing" - set desc = "Change your view to a budget version of colorblindness to test for usability" +ADMIN_VERB(debug, colorblind_testing, "Change your view to a budger version of colorblindness to test for usability", R_DEBUG) + usr.client.holder.color_test.ui_interact(usr) - if(!holder) - return - holder.color_test.ui_interact(mob) +ADMIN_VERB(debug, edit_debug_planes, "Edit and visuaize plane masters and their connections (relays)", R_DEBUG) + usr.client.holder.edit_plane_masters() -/client/proc/debug_plane_masters() - set category = "Debug" - set name = "Edit/Debug Planes" - set desc = "Edit and visualize plane masters and their connections (relays)" - - edit_plane_masters() - -/client/proc/edit_plane_masters(mob/debug_on) - if(!holder) - return +/datum/admins/proc/edit_plane_masters(mob/debug_on) if(debug_on) - holder.plane_debug.set_mirroring(TRUE) - holder.plane_debug.set_target(debug_on) + owner.holder.plane_debug.set_mirroring(TRUE) + owner.holder.plane_debug.set_target(debug_on) else - holder.plane_debug.set_mirroring(FALSE) - holder.plane_debug.ui_interact(mob) + owner.holder.plane_debug.set_mirroring(FALSE) + owner.holder.plane_debug.ui_interact(usr) -/client/proc/debug_huds(i as num) - set category = "Debug" - set name = "Debug HUDs" - set desc = "Debug the data or antag HUDs" +ADMIN_VERB(debug, debug_huds, "Debug one of the HUDs", R_DEBUG) + var/list/choices = list() + for(var/idx in 1 to length(GLOB.huds)) + var/datum/hud = GLOB.huds[idx] + choices["[hud.type]"] = hud - if(!holder) + var/choice = tgui_input_list(usr, "Select Hud Type", "Debug HUDs", choices) + if(!choice) return - debug_variables(GLOB.huds[i]) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/debug/view_variables, choices[choice]) -/client/proc/jump_to_ruin() - set category = "Debug" - set name = "Jump to Ruin" - set desc = "Displays a list of all placed ruins to teleport to." - if(!holder) - return +ADMIN_VERB(debug, jump_to_ruin, "Displays a list of all placed ruins for teleporting", R_DEBUG) var/list/names = list() for(var/obj/effect/landmark/ruin/ruin_landmark as anything in GLOB.ruin_landmarks) var/datum/map_template/ruin/template = ruin_landmark.ruin_template @@ -676,23 +576,21 @@ names[name] = ruin_landmark var/ruinname = input("Select ruin", "Jump to Ruin") as null|anything in sort_list(names) - - var/obj/effect/landmark/ruin/landmark = names[ruinname] if(istype(landmark)) var/datum/map_template/ruin/template = landmark.ruin_template - usr.forceMove(get_turf(landmark)) + if(!isobserver(usr)) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/aghost) + if(!isobserver(usr)) + to_chat(usr, span_warning("Failed to aghost.")) + return + + usr.abstract_move(get_turf(landmark)) to_chat(usr, span_name("[template.name]"), confidential = TRUE) to_chat(usr, "[template.description]", confidential = TRUE) -/client/proc/place_ruin() - set category = "Debug" - set name = "Spawn Ruin" - set desc = "Attempt to randomly place a specific ruin." - if (!holder) - return - +ADMIN_VERB(debug, spawn_ruin, "Attempt to randomly place a specific ruin", R_DEBUG) var/list/exists = list() for(var/landmark in GLOB.ruin_landmarks) var/obj/effect/landmark/ruin/L = landmark @@ -716,6 +614,11 @@ if (exists[template]) var/response = tgui_alert(usr,"There is already a [template] in existence.", "Spawn Ruin", list("Jump", "Place Another", "Cancel")) if (response == "Jump") + if(!isobserver(usr)) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/aghost) + if(!isobserver(usr)) + to_chat(usr, span_warning("Failed to aghost.")) + return usr.forceMove(get_turf(exists[template])) return else if (response == "Cancel") @@ -725,25 +628,17 @@ seedRuins(SSmapping.levels_by_trait(data[2]), max(1, template.cost), data[3], list(ruinname = template)) if (GLOB.ruin_landmarks.len > len) var/obj/effect/landmark/ruin/landmark = GLOB.ruin_landmarks[GLOB.ruin_landmarks.len] - log_admin("[key_name(src)] randomly spawned ruin [ruinname] at [COORD(landmark)].") + log_admin("[key_name(usr)] randomly spawned ruin [ruinname] at [COORD(landmark)].") usr.forceMove(get_turf(landmark)) - to_chat(src, span_name("[template.name]"), confidential = TRUE) - to_chat(src, "[template.description]", confidential = TRUE) + to_chat(usr, span_name("[template.name]"), confidential = TRUE) + to_chat(usr, "[template.description]", confidential = TRUE) else - to_chat(src, span_warning("Failed to place [template.name]."), confidential = TRUE) - -/client/proc/unload_ctf() - set category = "Debug" - set name = "Unload CTF" - set desc = "Despawns the majority of CTF" + to_chat(usr, span_warning("Failed to place [template.name]."), confidential = TRUE) +ADMIN_VERB(debug, unload_ctf, "Despawns CTF", R_DEBUG) toggle_id_ctf(usr, unload=TRUE) -/client/proc/run_empty_query(val as num) - set category = "Debug" - set name = "Run empty query" - set desc = "Amount of queries to run" - +ADMIN_VERB(debug, run_empty_query, "Runs a query that does nothing", R_DEBUG, val as num) var/list/queries = list() for(var/i in 1 to val) var/datum/db_query/query = SSdbcore.NewQuery("NULL") @@ -755,45 +650,128 @@ qdel(query) queries.Cut() - message_admins("[key_name_admin(src)] ran [val] empty queries.") + message_admins("[key_name_admin(usr)] ran [val] empty queries.") -/client/proc/clear_dynamic_transit() - set category = "Debug" - set name = "Clear Dynamic Turf Reservations" - set desc = "Deallocates all reserved space, restoring it to round start conditions." - if(!holder) +//Debug procs +ADMIN_VERB(debug, test_movable_UI, "", R_DEBUG) + var/atom/movable/screen/movable/M = new() + M.name = "Movable UI Object" + M.icon_state = "block" + M.maptext = MAPTEXT("Movable") + M.maptext_width = 64 + + var/screen_l = input(usr,"Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") as text|null + if(!screen_l) return + + M.screen_loc = screen_l + + usr.client.screen += M + +// Debug verbs. +ADMIN_VERB(debug, restart_controller, "Restart one of the two main controllers for the game (be careful!)", R_DEBUG, controller in list("Master", "Failsafe")) + switch(controller) + if("Master") + Recreate_MC() + if("Failsafe") + new /datum/controller/failsafe() + else + stack_trace("Invalid controller type [controller] passed to restart_controller()") + message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") + +ADMIN_VERB(debug, debug_controller, "Debug one of the subsystem controllers", R_DEBUG) + var/list/controllers = list() + var/list/controller_choices = list() + + for (var/datum/controller/controller in world) + if (istype(controller, /datum/controller/subsystem)) + continue + controllers["[controller] (controller.type)"] = controller //we use an associated list to ensure clients can't hold references to controllers + controller_choices += "[controller] (controller.type)" + + var/datum/controller/controller_string = input("Select controller to debug", "Debug Controller") as null|anything in controller_choices + var/datum/controller/controller = controllers[controller_string] + + if (!istype(controller)) + return + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/debug/view_variables, controller) + message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") + +ADMIN_VERB(debug, spawn_snap_ui_object, "", R_DEBUG) + var/atom/movable/screen/movable/snap/S = new() + S.name = "Snap UI Object" + S.icon_state = "block" + S.maptext = MAPTEXT("Snap") + S.maptext_width = 64 + + var/screen_l = input(usr, "Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") as text|null + if(!screen_l) + return + + S.screen_loc = screen_l + + usr.client.screen += S + +/// Debug verb for getting the weight of each distinct type within the random_hallucination_weighted_list +ADMIN_VERB(debug, show_hallucination_weights, "", R_DEBUG) + var/header = "Type Weight Percent" + + var/total_weight = debug_hallucination_weighted_list() + var/list/all_weights = list() + var/datum/hallucination/last_type + var/last_type_weight = 0 + for(var/datum/hallucination/hallucination_type as anything in GLOB.random_hallucination_weighted_list) + var/this_weight = GLOB.random_hallucination_weighted_list[hallucination_type] + // Last_type is the abstract parent of the last hallucination type we iterated over + if(last_type) + // If this hallucination is the same path as the last type (subtype), add it to the total of the last type weight + if(ispath(hallucination_type, last_type)) + last_type_weight += this_weight + continue + + // Otherwise we moved onto the next hallucination subtype so we can stop + else + all_weights["[last_type] [last_type_weight] / [total_weight] [round(100 * (last_type_weight / total_weight), 0.01)]% chance"] = last_type_weight + + // Set last_type to the abstract parent of this hallucination + last_type = initial(hallucination_type.abstract_hallucination_parent) + // If last_type is the base hallucination it has no distinct subtypes so we can total it up immediately + if(last_type == /datum/hallucination) + all_weights["[hallucination_type] [this_weight] / [total_weight] [round(100 * (this_weight / total_weight), 0.01)]% chance"] = this_weight + last_type = null + + // Otherwise we start the weight sum for the next entry here + else + last_type_weight = this_weight + + // Sort by weight descending, where weight is the values (not the keys). We assoc_to_keys later to get JUST the text + all_weights = sortTim(all_weights, GLOBAL_PROC_REF(cmp_numeric_dsc), associative = TRUE) + + var/page_style = "" + var/page_contents = "[page_style][header][jointext(assoc_to_keys(all_weights), "")]
      " + var/datum/browser/popup = new(usr, "hallucinationdebug", "Hallucination Weights", 600, 400) + popup.set_content(page_contents) + popup.open() + +ADMIN_VERB(debug, clear_dynamic_turf_reserverations, "Deallocates all reserved space, restoring it to round start conditions", R_DEBUG) + if(length(SSmapping.loaded_lazy_templates)) + to_chat(usr, span_boldbig("WARNING, THERE ARE LOADED LAZY TEMPLATES, THIS WILL CAUSE THEM TO BE UNLOADED AND POTENTIALLY RUIN THE ROUND")) + var/answer = tgui_alert(usr,"WARNING: THIS WILL WIPE ALL RESERVED SPACE TO A CLEAN SLATE! ANY MOVING SHUTTLES, ELEVATORS, OR IN-PROGRESS PHOTOGRAPHY WILL BE DELETED!", "Really wipe dynamic turfs?", list("YES", "NO")) if(answer != "YES") return + message_admins(span_adminnotice("[key_name_admin(src)] cleared dynamic transit space.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Clear Dynamic Transit") // If... log_admin("[key_name(src)] cleared dynamic transit space.") SSmapping.wipe_reservations() //this goes after it's logged, incase something horrible happens. -/client/proc/toggle_medal_disable() - set category = "Debug" - set name = "Toggle Medal Disable" - set desc = "Toggles the safety lock on trying to contact the medal hub." - - if(!check_rights(R_DEBUG)) - return - +ADMIN_VERB(debug, toggle_medal_disable, "Toggles the safety lock on trying to contact the medal hub", R_DEBUG) SSachievements.achievements_enabled = !SSachievements.achievements_enabled + message_admins(span_adminnotice("[key_name_admin(usr)] [SSachievements.achievements_enabled ? "disabled" : "enabled"] the medal hub lockout.")) + log_admin("[key_name(usr)] [SSachievements.achievements_enabled ? "disabled" : "enabled"] the medal hub lockout.") - message_admins(span_adminnotice("[key_name_admin(src)] [SSachievements.achievements_enabled ? "disabled" : "enabled"] the medal hub lockout.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Medal Disable") // If... - log_admin("[key_name(src)] [SSachievements.achievements_enabled ? "disabled" : "enabled"] the medal hub lockout.") - -/client/proc/view_runtimes() - set category = "Debug" - set name = "View Runtimes" - set desc = "Open the runtime Viewer" - - if(!holder) - return - - GLOB.error_cache.show_to(src) +ADMIN_VERB(debug, view_runtimes, "Opem the Runtime Viewer", R_DEBUG) + GLOB.error_cache.show_to(usr) // The runtime viewer has the potential to crash the server if there's a LOT of runtimes // this has happened before, multiple times, so we'll just leave an alert on it @@ -804,74 +782,38 @@ // Not using TGUI alert, because it's view runtimes, stuff is probably broken alert(usr, "[warning]. Proceed with caution. If you really need to see the runtimes, download the runtime log and view it in a text editor.", "HEED THIS WARNING CAREFULLY MORTAL") -/client/proc/pump_random_event() - set category = "Debug" - set name = "Pump Random Event" - set desc = "Schedules the event subsystem to fire a new random event immediately. Some events may fire without notification." - if(!holder) - return - +ADMIN_VERB(debug, pump_random_event, "Schedules the event subsystem to fire a new random event immediately. Some events may fire without notification", R_FUN) SSevents.scheduled = world.time + message_admins(span_adminnotice("[key_name_admin(usr)] pumped a random event.")) + log_admin("[key_name(usr)] pumped a random event.") - message_admins(span_adminnotice("[key_name_admin(src)] pumped a random event.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Pump Random Event") - log_admin("[key_name(src)] pumped a random event.") - -/client/proc/start_line_profiling() - set category = "Profile" - set name = "Start Line Profiling" - set desc = "Starts tracking line by line profiling for code lines that support it" - +ADMIN_VERB(debug, start_line_profiling, "Starts tracking line by line profiling for code lines that support it", R_DEBUG) LINE_PROFILE_START - message_admins(span_adminnotice("[key_name_admin(src)] started line by line profiling.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Start Line Profiling") log_admin("[key_name(src)] started line by line profiling.") -/client/proc/stop_line_profiling() - set category = "Profile" - set name = "Stops Line Profiling" - set desc = "Stops tracking line by line profiling for code lines that support it" - +ADMIN_VERB(debug, stop_line_profiling, "Stops tracking line by line profiling for code lines that support it", R_DEBUG) LINE_PROFILE_STOP - message_admins(span_adminnotice("[key_name_admin(src)] stopped line by line profiling.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Stop Line Profiling") log_admin("[key_name(src)] stopped line by line profiling.") -/client/proc/show_line_profiling() - set category = "Profile" - set name = "Show Line Profiling" - set desc = "Shows tracked profiling info from code lines that support it" - +ADMIN_VERB(debug, show_line_profiling, "Shows tracked profiling info from code lines that support it", R_DEBUG) var/sortlist = list( "Avg time" = GLOBAL_PROC_REF(cmp_profile_avg_time_dsc), "Total Time" = GLOBAL_PROC_REF(cmp_profile_time_dsc), "Call Count" = GLOBAL_PROC_REF(cmp_profile_count_dsc) ) - var/sort = input(src, "Sort type?", "Sort Type", "Avg time") as null|anything in sortlist + var/sort = input(usr, "Sort type?", "Sort Type", "Avg time") as null|anything in sortlist if (!sort) return sort = sortlist[sort] - profile_show(src, sort) + profile_show(usr, sort) -/client/proc/reload_configuration() - set category = "Debug" - set name = "Reload Configuration" - set desc = "Force config reload to world default" - if(!check_rights(R_DEBUG)) - return - if(tgui_alert(usr, "Are you absolutely sure you want to reload the configuration from the default path on the disk, wiping any in-round modifications?", "Really reset?", list("No", "Yes")) == "Yes") +ADMIN_VERB(debug, reload_configuration, "Force config reload to world default", R_DEBUG) + if(tgui_alert(usr, "Are you absolutely sure you want to reload the configuration from the default path on the disk, wiping any in-round modificatoins?", "Really reset?", list("No", "Yes")) == "Yes") config.admin_reload() -/// A debug verb to check the sources of currently running timers -/client/proc/check_timer_sources() - set category = "Debug" - set name = "Check Timer Sources" - set desc = "Checks the sources of the running timers" - if (!check_rights(R_DEBUG)) - return - +ADMIN_VERB(debug, check_timer_sources, "Checks the sources of the running timers", R_DEBUG) var/bucket_list_output = generate_timer_source_output(SStimer.bucket_list) var/second_queue = generate_timer_source_output(SStimer.second_queue) @@ -925,10 +867,7 @@ return b["count"] - a["count"] #ifdef TESTING -/client/proc/check_missing_sprites() - set category = "Debug" - set name = "Debug Worn Item Sprites" - set desc = "We're cancelling the Spritemageddon. (This will create a LOT of runtimes! Don't use on a live server!)" +ADMIN_VERB(debug, check_missing_sprites, "We're cancelling the Spritemageddon. (This will create a LOT of runtimes! Don't use on a live server!)", R_DEBUG) var/actual_file_name for(var/test_obj in subtypesof(/obj/item)) var/obj/item/sprite = new test_obj @@ -937,55 +876,55 @@ //Is there an explicit worn_icon to pick against the worn_icon_state? Easy street expected behavior. if(sprite.worn_icon) if(!(sprite.icon_state in icon_states(sprite.worn_icon))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Slot Flags are [sprite.slot_flags]."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Slot Flags are [sprite.slot_flags]."), confidential = TRUE) else if(sprite.worn_icon_state) if(sprite.slot_flags & ITEM_SLOT_MASK) actual_file_name = 'icons/mob/clothing/mask.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_NECK) actual_file_name = 'icons/mob/clothing/neck.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_BACK) actual_file_name = 'icons/mob/clothing/back.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_HEAD) actual_file_name = 'icons/mob/clothing/head/default.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_BELT) actual_file_name = 'icons/mob/clothing/belt.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_SUITSTORE) actual_file_name = 'icons/mob/clothing/belt_mirror.dmi' if(!(sprite.worn_icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) else if(sprite.icon_state) if(sprite.slot_flags & ITEM_SLOT_MASK) actual_file_name = 'icons/mob/clothing/mask.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Mask slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_NECK) actual_file_name = 'icons/mob/clothing/neck.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Neck slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_BACK) actual_file_name = 'icons/mob/clothing/back.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Back slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_HEAD) actual_file_name = 'icons/mob/clothing/head/default.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Head slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_BELT) actual_file_name = 'icons/mob/clothing/belt.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Belt slot."), confidential = TRUE) if(sprite.slot_flags & ITEM_SLOT_SUITSTORE) actual_file_name = 'icons/mob/clothing/belt_mirror.dmi' if(!(sprite.icon_state in icon_states(actual_file_name))) - to_chat(src, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) + to_chat(usr, span_warning("ERROR sprites for [sprite.type]. Suit Storage slot."), confidential = TRUE) #endif diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index cef43970e23..04c173a5ce6 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -1,15 +1,7 @@ -/client/proc/air_status(turf/target) - set category = "Debug" - set name = "Display Air Status" - - if(!isturf(target)) - return +ADMIN_VERB(debug, display_air_status, "", R_DEBUG, turf/target in view()) atmos_scan(user=usr, target=target, silent=TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Air Status") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/fix_next_move() - set category = "Debug" - set name = "Unfreeze Everyone" +ADMIN_VERB(debug, unfreeze_everyone, "When movement gets fucked", R_ADMIN) var/largest_move_time = 0 var/largest_click_time = 0 var/mob/largest_move_mob = null @@ -33,13 +25,8 @@ message_admins("[ADMIN_LOOKUPFLW(largest_move_mob)] had the largest move delay with [largest_move_time] frames / [DisplayTimeText(largest_move_time)]!") message_admins("[ADMIN_LOOKUPFLW(largest_click_mob)] had the largest click delay with [largest_click_time] frames / [DisplayTimeText(largest_click_time)]!") message_admins("world.time = [world.time]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Unfreeze Everyone") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - -/client/proc/radio_report() - set category = "Debug" - set name = "Radio report" +ADMIN_VERB(debug, radio_report, "", R_DEBUG) var/output = "Radio Report
      " for (var/fq in SSradio.frequencies) output += "Freq: [fq]
      " @@ -63,28 +50,9 @@ output += "    [device] ([AREACOORD(A)])
      " else output += "    [device]
      " - usr << browse(output,"window=radioreport") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Radio Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/reload_admins() - set name = "Reload Admins" - set category = "Admin" - - if(!src.holder) - return - - var/confirm = tgui_alert(usr, "Are you sure you want to reload all admins?", "Confirm", list("Yes", "No")) - if(confirm != "Yes") - return - - load_admins() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Reload All Admins") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - message_admins("[key_name_admin(usr)] manually reloaded admins") - -/client/proc/toggle_cdn() - set name = "Toggle CDN" - set category = "Server" +ADMIN_VERB(server, toggle_cdn, "", R_SERVER|R_DEBUG) var/static/admin_disabled_cdn_transport = null if (alert(usr, "Are you sure you want to toggle the CDN asset transport?", "Confirm", "Yes", "No") != "Yes") return diff --git a/code/modules/admin/verbs/ert.dm b/code/modules/admin/verbs/ert.dm index f87eec87675..10f4622d575 100644 --- a/code/modules/admin/verbs/ert.dm +++ b/code/modules/admin/verbs/ert.dm @@ -261,13 +261,9 @@ return -/client/proc/summon_ert() - set category = "Admin.Fun" - set name = "Summon ERT" - set desc = "Summons an emergency response team" - +ADMIN_VERB(fun, summon_ert, "Summons an Emergency Response Team", R_FUN) message_admins("[key_name(usr)] is creating a CentCom response team...") - if(holder?.makeEmergencyresponseteam()) + if(usr.client.holder?.makeEmergencyresponseteam()) message_admins("[key_name(usr)] created a CentCom response team.") log_admin("[key_name(usr)] created a CentCom response team.") else diff --git a/code/modules/admin/verbs/fix_air.dm b/code/modules/admin/verbs/fix_air.dm deleted file mode 100644 index 15c1cccbfab..00000000000 --- a/code/modules/admin/verbs/fix_air.dm +++ /dev/null @@ -1,20 +0,0 @@ -// Proc taken from yogstation, credit to nichlas0010 for the original -/client/proc/fix_air(turf/open/T in world) - set name = "Fix Air" - set category = "Admin.Game" - set desc = "Fixes air in specified radius." - - if(!holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return - if(check_rights(R_ADMIN,1)) - var/range=input("Enter range:","Num",2) as num - message_admins("[key_name_admin(usr)] fixed air with range [range] in area [T.loc.name]") - usr.log_message("fixed air with range [range] in area [T.loc.name]", LOG_ADMIN) - for(var/turf/open/F in range(range,T)) - if(F.blocks_air) - //skip walls - continue - var/datum/gas_mixture/GM = SSair.parse_gas_string(F.initial_gas_mix, /datum/gas_mixture/turf) - F.copy_air(GM) - F.update_visuals() diff --git a/code/modules/admin/verbs/fov.dm b/code/modules/admin/verbs/fov.dm index f74ba6f8058..17db4411442 100644 --- a/code/modules/admin/verbs/fov.dm +++ b/code/modules/admin/verbs/fov.dm @@ -1,17 +1,9 @@ -/client/proc/cmd_admin_toggle_fov() - set name = "Enable/Disable Field of View" - set category = "Debug" - - if(!check_rights(R_ADMIN) || !check_rights(R_DEBUG)) - return - +ADMIN_VERB(debug, toggle_field_of_view, "", (R_ADMIN|R_DEBUG)) var/on_off = CONFIG_GET(flag/native_fov) message_admins("[key_name_admin(usr)] has [on_off ? "disabled" : "enabled"] the Native Field of View configuration..") log_admin("[key_name(usr)] has [on_off ? "disabled" : "enabled"] the Native Field of View configuration.") CONFIG_SET(flag/native_fov, !on_off) - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Field of View", "[on_off ? "Enabled" : "Disabled"]")) - for(var/mob/living/mob in GLOB.player_list) mob.update_fov() diff --git a/code/modules/admin/verbs/fps.dm b/code/modules/admin/verbs/fps.dm index ce1389c61f2..e1cbbd8ae2e 100644 --- a/code/modules/admin/verbs/fps.dm +++ b/code/modules/admin/verbs/fps.dm @@ -1,23 +1,16 @@ //replaces the old Ticklag verb, fps is easier to understand -/client/proc/set_server_fps() - set category = "Debug" - set name = "Set Server FPS" - set desc = "Sets game speed in frames-per-second. Can potentially break the game" - - if(!check_rights(R_DEBUG)) - return - +ADMIN_VERB(debug, set_server_fps, "Sets game speed in frames-per-second. Will break the game, but that's why it's fun!", R_DEBUG) var/cfg_fps = CONFIG_GET(number/fps) var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [cfg_fps])","FPS", world.fps) as num|null) if(new_fps <= 0) - to_chat(src, span_danger("Error: set_server_fps(): Invalid world.fps value. No changes made."), confidential = TRUE) + to_chat(usr, span_danger("Error: set_server_fps(): Invalid world.fps value. No changes made."), confidential = TRUE) return if(new_fps > cfg_fps * 1.5) if(tgui_alert(usr, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [cfg_fps]","Warning!",list("Confirm","ABORT-ABORT-ABORT")) != "Confirm") return - var/msg = "[key_name(src)] has modified world.fps to [new_fps]" + var/msg = "[key_name(usr)] has modified world.fps to [new_fps]" log_admin(msg, 0) message_admins(msg, 0) SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Set Server FPS", "[new_fps]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 77b43f9b49f..b8c1a13aa37 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -1,35 +1,25 @@ -//This proc allows download of past server logs saved within the data/logs/ folder. -/client/proc/getserverlogs() - set name = "Get Server Logs" - set desc = "View/retrieve logfiles." - set category = "Admin" +ADMIN_VERB(admin, get_server_logs, "View/Retrieve logfiles", R_ADMIN) + usr.client.holder.browseserverlogs() - browseserverlogs() +ADMIN_VERB(admin, get_current_logs, "View/Retrieve current logfiles", R_ADMIN) + usr.client.holder.browseserverlogs(current = TRUE) -/client/proc/getcurrentlogs() - set name = "Get Current Logs" - set desc = "View/retrieve logfiles for the current round." - set category = "Admin" - - browseserverlogs(current=TRUE) - -/client/proc/browseserverlogs(current=FALSE) - var/path = browse_files(current ? BROWSE_ROOT_CURRENT_LOGS : BROWSE_ROOT_ALL_LOGS) +/datum/admins/proc/browseserverlogs(current = FALSE) + var/path = owner.browse_files(current ? BROWSE_ROOT_CURRENT_LOGS : BROWSE_ROOT_ALL_LOGS) if(!path) return - if(file_spam_check()) + if(owner.file_spam_check()) return - message_admins("[key_name_admin(src)] accessed file: [path]") + message_admins("[key_name_admin(usr)] accessed file: [path]") switch(tgui_alert(usr,"View (in game), Open (in your system's text editor), or Download?", path, list("View", "Open", "Download"))) if ("View") - src << browse("
      [html_encode(file2text(file(path)))]
      ", list2params(list("window" = "viewfile.[path]"))) + usr << browse("
      [html_encode(file2text(file(path)))]
      ", list2params(list("window" = "viewfile.[path]"))) if ("Open") - src << run(file(path)) + usr << run(file(path)) if ("Download") - src << ftp(file(path)) + usr << ftp(file(path)) else return - to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.", confidential = TRUE) - return + to_chat(usr, "Attempting to send [path], this may take a fair few minutes if the file is very large.", confidential = TRUE) diff --git a/code/modules/admin/verbs/ghost_pool_protection.dm b/code/modules/admin/verbs/ghost_pool_protection.dm index 843f6868e70..62c30fd78e7 100644 --- a/code/modules/admin/verbs/ghost_pool_protection.dm +++ b/code/modules/admin/verbs/ghost_pool_protection.dm @@ -1,9 +1,6 @@ //very similar to centcom_podlauncher in terms of how this is coded, so i kept a lot of comments from it -/client/proc/ghost_pool_protection() //Creates a verb for admins to open up the ui - set name = "Ghost Pool Protection" - set desc = "Choose which ways people can get into the round, or just clear it out completely for admin events." - set category = "Admin.Events" +ADMIN_VERB(events, ghost_pool_protection, "Choose which ways people can get into the round, or just clear it out completely for admin events", R_FUN) var/datum/ghost_pool_menu/tgui = new(usr)//create the datum tgui.ui_interact(usr)//datum has a tgui component, here we open the window diff --git a/code/modules/admin/verbs/list_exposer.dm b/code/modules/admin/verbs/list_exposer.dm index 851bd901c1e..e6ea83e47de 100644 --- a/code/modules/admin/verbs/list_exposer.dm +++ b/code/modules/admin/verbs/list_exposer.dm @@ -57,32 +57,3 @@ data += "[entry.name][entry.rank][entry.rank != entry.trim ? " ([entry.trim])" : ""]" data += "" usr << browse(data, "window=manifest;size=440x410") - -/datum/admins/proc/output_ai_laws() - var/law_bound_entities = 0 - for(var/mob/living/silicon/subject as anything in GLOB.silicon_mobs) - law_bound_entities++ - - var/message = "" - - if(isAI(subject)) - message += "AI [key_name(subject, usr)]'s laws:" - else if(iscyborg(subject)) - var/mob/living/silicon/robot/borg = subject - message += "CYBORG [key_name(subject, usr)] [borg.connected_ai?"(Slaved to: [key_name(borg.connected_ai)])":"(Independent)"]: laws:" - else if (ispAI(subject)) - message += "pAI [key_name(subject, usr)]'s laws:" - else - message += "SOMETHING SILICON [key_name(subject, usr)]'s laws:" - - message += "
      " - - if (!subject.laws) - message += "[key_name(subject, usr)]'s laws are null?? Contact a coder." - else - message += jointext(subject.laws.get_law_list(include_zeroth = TRUE), "
      ") - - to_chat(usr, message, confidential = TRUE) - - if(!law_bound_entities) - to_chat(usr, "No law bound entities located", confidential = TRUE) diff --git a/code/modules/admin/verbs/lua/lua_editor.dm b/code/modules/admin/verbs/lua/lua_editor.dm index 75d05c0a557..80bda38703e 100644 --- a/code/modules/admin/verbs/lua/lua_editor.dm +++ b/code/modules/admin/verbs/lua/lua_editor.dm @@ -196,14 +196,26 @@ if(isweakref(thing_to_debug)) var/datum/weakref/ref = thing_to_debug thing_to_debug = ref.resolve() - INVOKE_ASYNC(usr.client, TYPE_PROC_REF(/client, debug_variables), thing_to_debug) + INVOKE_ASYNC( \ + SSadmin_verbs, \ + TYPE_PROC_REF(/datum/controller/subsystem/admin_verbs, dynamic_invoke_admin_verb), \ + usr.client, \ + /mob/admin_module_holder/debug/view_variables, \ + list(thing_to_debug), \ + ) return FALSE if("vvGlobal") var/thing_to_debug = traverse_list(params["indices"], current_state.globals) if(isweakref(thing_to_debug)) var/datum/weakref/ref = thing_to_debug thing_to_debug = ref.resolve() - INVOKE_ASYNC(usr.client, TYPE_PROC_REF(/client, debug_variables), thing_to_debug) + INVOKE_ASYNC( \ + SSadmin_verbs, \ + TYPE_PROC_REF(/datum/controller/subsystem/admin_verbs, dynamic_invoke_admin_verb), \ + usr.client, \ + /mob/admin_module_holder/debug/view_variables, \ + list(thing_to_debug), \ + ) return FALSE if("clearArgs") arguments.Cut() @@ -222,11 +234,7 @@ . = ..() qdel(src) -/client/proc/open_lua_editor() - set name = "Open Lua Editor" - set category = "Debug" - if(!check_rights_for(src, R_DEBUG)) - return +ADMIN_VERB(debug, open_lua_editor, "", R_DEBUG) if(SSlua.initialized != TRUE) to_chat(usr, span_warning("SSlua is not initialized!")) return diff --git a/code/modules/admin/verbs/machine_upgrade.dm b/code/modules/admin/verbs/machine_upgrade.dm index 8d0ffa14f40..a869bf504ad 100644 --- a/code/modules/admin/verbs/machine_upgrade.dm +++ b/code/modules/admin/verbs/machine_upgrade.dm @@ -1,13 +1,16 @@ -/proc/machine_upgrade(obj/machinery/M in world) - set name = "Tweak Component Ratings" - set category = "Debug" - if (!istype(M)) +ADMIN_CONTEXT_ENTRY(contexxt_machine_upgrade, "Tweak Component Ratings", R_DEBUG, obj/machinery/machine in world) + if(!length(machine.component_parts)) + to_chat(usr, span_warning("[machine] has no components!")) return - var/new_rating = input("Enter new rating:","Num") as num|null - if(new_rating && M.component_parts) - for(var/obj/item/stock_parts/P in M.component_parts) - P.rating = new_rating - M.RefreshParts() - - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Machine Upgrade", "[new_rating]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + var/new_rating = input(usr, "Enter new rating:","Num") as num|null + if(!new_rating) + return + for(var/obj/item/stock_parts/part in machine.component_parts) + part.rating = new_rating + for(var/datum/stock_part/datum_part in machine.component_parts) + machine.component_parts -= datum_part + var/obj/item/stock_parts/new_part = new datum_part.physical_object_type + new_part.rating = new_rating + machine.component_parts += new_part + machine.RefreshParts() diff --git a/code/modules/admin/verbs/manipulate_organs.dm b/code/modules/admin/verbs/manipulate_organs.dm index d3d1ddfc67b..17ae4518649 100644 --- a/code/modules/admin/verbs/manipulate_organs.dm +++ b/code/modules/admin/verbs/manipulate_organs.dm @@ -1,6 +1,4 @@ -/client/proc/manipulate_organs(mob/living/carbon/C in world) - set name = "Manipulate Organs" - set category = "Debug" +ADMIN_VERB(debug, manipulate_organs, "", R_DEBUG, mob/living/carbon/target in view()) var/operation = tgui_input_list(usr, "Select organ operation", "Organ Manipulation", list("add organ", "add implant", "drop organ/implant", "remove organ/implant")) if (isnull(operation)) return @@ -19,9 +17,9 @@ return organ = organs[organ] organ = new organ - organ.Insert(C) - log_admin("[key_name(usr)] has added organ [organ.type] to [key_name(C)]") - message_admins("[key_name_admin(usr)] has added organ [organ.type] to [ADMIN_LOOKUPFLW(C)]") + organ.Insert(target) + log_admin("[key_name(usr)] has added organ [organ.type] to [key_name(target)]") + message_admins("[key_name_admin(usr)] has added organ [organ.type] to [ADMIN_LOOKUPFLW(target)]") if("add implant") for(var/path in subtypesof(/obj/item/implant)) @@ -35,15 +33,15 @@ return organ = organs[organ] organ = new organ - organ.implant(C) - log_admin("[key_name(usr)] has added implant [organ.type] to [key_name(C)]") - message_admins("[key_name_admin(usr)] has added implant [organ.type] to [ADMIN_LOOKUPFLW(C)]") + organ.implant(target) + log_admin("[key_name(usr)] has added implant [organ.type] to [key_name(target)]") + message_admins("[key_name_admin(usr)] has added implant [organ.type] to [ADMIN_LOOKUPFLW(target)]") if("drop organ/implant", "remove organ/implant") - for(var/obj/item/organ/user_organs as anything in C.internal_organs) + for(var/obj/item/organ/user_organs as anything in target.internal_organs) organs["[user_organs.name] ([user_organs.type])"] = user_organs - for(var/obj/item/implant/user_implants as anything in C.implants) + for(var/obj/item/implant/user_implants as anything in target.implants) organs["[user_implants.name] ([user_implants.type])"] = user_implants var/obj/item/organ = tgui_input_list(usr, "Select organ/implant", "Organ Manipulation", organs) @@ -55,22 +53,22 @@ var/obj/item/organ/O var/obj/item/implant/I - log_admin("[key_name(usr)] has removed [organ.type] from [key_name(C)]") - message_admins("[key_name_admin(usr)] has removed [organ.type] from [ADMIN_LOOKUPFLW(C)]") + log_admin("[key_name(usr)] has removed [organ.type] from [key_name(target)]") + message_admins("[key_name_admin(usr)] has removed [organ.type] from [ADMIN_LOOKUPFLW(target)]") if(isorgan(organ)) O = organ - O.Remove(C) + O.Remove(target) else I = organ - I.removed(C) + I.removed(target) - organ.forceMove(get_turf(C)) + organ.forceMove(get_turf(target)) if(operation == "remove organ/implant") qdel(organ) else if(I) // Put the implant in case. - var/obj/item/implantcase/case = new(get_turf(C)) + var/obj/item/implantcase/case = new(get_turf(target)) case.imp = I I.forceMove(case) case.update_appearance() diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index a772f699992..fb701fdc132 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -1,15 +1,12 @@ -/client/proc/map_template_load() - set category = "Debug" - set name = "Map template - Place" - +ADMIN_VERB(debug, map_template_load, "", R_DEBUG) var/datum/map_template/template - var/map = input(src, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in sort_list(SSmapping.map_templates) + var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in sort_list(SSmapping.map_templates) if(!map) return template = SSmapping.map_templates[map] - var/turf/T = get_turf(mob) + var/turf/T = get_turf(usr) if(!T) return @@ -27,7 +24,7 @@ var/image/item = image('icons/turf/overlays.dmi', place_on,"greenOverlay") SET_PLANE(item, ABOVE_LIGHTING_PLANE, place_on) preview += item - images += preview + usr.client.images += preview if(tgui_alert(usr,"Confirm location.","Template Confirm",list("Yes","No")) == "Yes") if(template.load(T, centered = center)) var/affected = template.get_affected_turfs(T, centered = center) @@ -37,20 +34,17 @@ template.post_load(P) break - message_admins(span_adminnotice("[key_name_admin(src)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]")) + message_admins(span_adminnotice("[key_name_admin(usr)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]")) else - to_chat(src, "Failed to place map", confidential = TRUE) - images -= preview + to_chat(usr, "Failed to place map", confidential = TRUE) + usr.client.images -= preview -/client/proc/map_template_upload() - set category = "Debug" - set name = "Map Template - Upload" - - var/map = input(src, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file +ADMIN_VERB(debug, map_template_upload, "", R_DEBUG) + var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file if(!map) return if(copytext("[map]", -4) != ".dmm")//4 == length(".dmm") - to_chat(src, span_warning("Filename must end in '.dmm': [map]"), confidential = TRUE) + to_chat(usr, span_warning("Filename must end in '.dmm': [map]"), confidential = TRUE) return var/datum/map_template/M switch(tgui_alert(usr, "What kind of map is this?", "Map type", list("Normal", "Shuttle", "Cancel"))) @@ -61,15 +55,15 @@ else return if(!M.cached_map) - to_chat(src, span_warning("Map template '[map]' failed to parse properly."), confidential = TRUE) + to_chat(usr, span_warning("Map template '[map]' failed to parse properly."), confidential = TRUE) return var/datum/map_report/report = M.cached_map.check_for_errors() var/report_link if(report) - report.show_to(src) + report.show_to(usr) report_link = " - validation report" - to_chat(src, span_warning("Map template '[map]' failed validation."), confidential = TRUE) + to_chat(usr, span_warning("Map template '[map]' failed validation."), confidential = TRUE) if(report.loadable) var/response = tgui_alert(usr, "The map failed validation, would you like to load it anyways?", "Map Errors", list("Cancel", "Upload Anyways")) if(response != "Upload Anyways") @@ -79,5 +73,5 @@ return SSmapping.map_templates[M.name] = M - message_admins(span_adminnotice("[key_name_admin(src)] has uploaded a map template '[map]' ([M.width]x[M.height])[report_link].")) - to_chat(src, span_notice("Map template '[map]' ready to place ([M.width]x[M.height])"), confidential = TRUE) + message_admins(span_adminnotice("[key_name_admin(usr)] has uploaded a map template '[map]' ([M.width]x[M.height])[report_link].")) + to_chat(usr, span_notice("Map template '[map]' ready to place ([M.width]x[M.height])"), confidential = TRUE) diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index d6e5782f17a..8a090d1f227 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -19,48 +19,9 @@ //- Identify how hard it is to break into the area and where the weak points are //- Check if the area has too much empty space. If so, make it smaller and replace the rest with maintenance tunnels. -GLOBAL_LIST_INIT(admin_verbs_debug_mapping, list( - /client/proc/camera_view, //-errorage - /client/proc/sec_camera_report, //-errorage - /client/proc/intercom_view, //-errorage - /client/proc/air_status, //Air things - /client/proc/Cell, //More air things - /client/proc/atmosscan, //check plumbing - /client/proc/powerdebug, //check power - /client/proc/count_objects_on_z_level, - /client/proc/count_objects_all, - /client/proc/cmd_assume_direct_control, //-errorage - /client/proc/cmd_give_direct_control, - /client/proc/set_server_fps, //allows you to set the ticklag. - /client/proc/cmd_admin_grantfullaccess, - /client/proc/cmd_admin_areatest_all, - /client/proc/cmd_admin_areatest_station, - /client/proc/cmd_admin_areatest_station_no_maintenance, - #ifdef TESTING - /client/proc/see_dirty_varedits, - #endif - /client/proc/cmd_admin_rejuvenate, - /datum/admins/proc/show_traitor_panel, - /client/proc/disable_communication, - /client/proc/show_map_reports, - /client/proc/cmd_show_at_list, - /client/proc/cmd_show_at_markers, - /client/proc/manipulate_organs, - /client/proc/start_line_profiling, - /client/proc/stop_line_profiling, - /client/proc/show_line_profiling, - /client/proc/create_mapping_job_icons, - /client/proc/debug_z_levels, - /client/proc/place_ruin, - /client/proc/station_food_debug, - /client/proc/station_stack_debug, - /client/proc/check_for_obstructed_atmospherics, -)) -GLOBAL_PROTECT(admin_verbs_debug_mapping) - -/client/proc/camera_view() - set category = "Mapping" - set name = "Camera Range Display" +ADMIN_VERB(mapping, camera_range_display, "Iterate over all cameras in world and generate a camera map", R_DEBUG) + if(tgui_alert(usr, "This can take a very long time and lock up the game!", "Don't do this on live", list("Okay", "Nevermind")) != "Okay") + return var/on = FALSE for(var/turf/T in world) @@ -75,16 +36,10 @@ GLOBAL_PROTECT(admin_verbs_debug_mapping) seen[T]++ for(var/turf/T in seen) T.maptext = MAPTEXT(seen[T]) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Range") #ifdef TESTING GLOBAL_LIST_EMPTY(dirty_vars) - -/client/proc/see_dirty_varedits() - set category = "Mapping" - set name = "Dirty Varedits" - +ADMIN_VERB(mapping, dirty_varedits, "", R_DEBUG) var/list/dat = list() dat += "

      Abandon all hope ye who enter here



      " for(var/thing in GLOB.dirty_vars) @@ -95,14 +50,7 @@ GLOBAL_LIST_EMPTY(dirty_vars) popup.open() #endif -/client/proc/sec_camera_report() - set category = "Mapping" - set name = "Camera Report" - - if(!Master) - tgui_alert(usr,"Master_controller not found.","Sec Camera Report") - return FALSE - +ADMIN_VERB(mapping, camera_report, "", R_DEBUG) var/list/obj/machinery/camera/CL = list() for(var/obj/machinery/camera/C as anything in GLOB.cameranet.cameras) @@ -133,14 +81,11 @@ GLOBAL_LIST_EMPTY(dirty_vars) output += "" usr << browse(output,"window=airreport;size=1000x500") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Camera Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/intercom_view() - set category = "Mapping" - set name = "Intercom Range Display" +ADMIN_VERB(mapping, intercom_range_display, "", R_DEBUG) var/static/intercom_range_display_status = FALSE - intercom_range_display_status = !intercom_range_display_status //blame cyberboss if this breaks something //blamed + //blame cyberboss if this breaks something //blamed + intercom_range_display_status = !intercom_range_display_status for(var/obj/effect/abstract/marker/intercom/marker in GLOB.all_abstract_markers) qdel(marker) @@ -150,13 +95,8 @@ GLOBAL_LIST_EMPTY(dirty_vars) for(var/obj/item/radio/intercom/intercom in GLOB.all_radios[frequency]) for(var/turf/turf in view(7,intercom.loc)) new /obj/effect/abstract/marker/intercom(turf) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Intercom Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/show_map_reports() - set category = "Mapping" - set name = "Show map report list" - set desc = "Displays a list of map reports" +ADMIN_VERB(mapping, show_map_report_list, "Display a list of map reports", R_DEBUG) var/dat = {"List of all map reports:
      "} for(var/datum/map_report/report as anything in GLOB.map_reports) @@ -164,11 +104,7 @@ GLOBAL_LIST_EMPTY(dirty_vars) usr << browse(dat, "window=map_reports") -/client/proc/cmd_show_at_list() - set category = "Mapping" - set name = "Show roundstart AT list" - set desc = "Displays a list of active turfs coordinates at roundstart" - +ADMIN_VERB(mapping, show_roundstart_at_list, "Displays a list of active turfs at roundstart", R_DEBUG) var/dat = {"Coordinate list of Active Turfs at Roundstart
      Real-time Active Turfs list you can see in Air Subsystem at active_turfs var
      "} @@ -176,16 +112,9 @@ GLOBAL_LIST_EMPTY(dirty_vars) var/turf/T = t dat += "[ADMIN_VERBOSEJMP(T)]\n" dat += "
      " - usr << browse(dat, "window=at_list") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Roundstart Active Turfs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_show_at_markers() - set category = "Mapping" - set name = "Show roundstart AT markers" - set desc = "Places a marker on all active-at-roundstart turfs" - +ADMIN_VERB(mapping, show_roundstart_at_markers, "Places a marker on all active-at-roundstart turfs", R_DEBUG) var/count = 0 for(var/obj/effect/abstract/marker/at/AT in GLOB.all_abstract_markers) qdel(AT) @@ -199,27 +128,7 @@ GLOBAL_LIST_EMPTY(dirty_vars) count++ to_chat(usr, "[count] AT markers placed.", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Roundstart Active Turf Markers") - -/client/proc/enable_mapping_verbs() - set category = "Debug" - set name = "Mapping verbs - Enable" - if(!check_rights(R_DEBUG)) - return - remove_verb(src, /client/proc/enable_mapping_verbs) - add_verb(src, list(/client/proc/disable_mapping_verbs, GLOB.admin_verbs_debug_mapping)) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Enable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/disable_mapping_verbs() - set category = "Debug" - set name = "Mapping verbs - Disable" - remove_verb(src, list(/client/proc/disable_mapping_verbs, GLOB.admin_verbs_debug_mapping)) - add_verb(src, /client/proc/enable_mapping_verbs) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Disable Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/count_objects_on_z_level() - set category = "Mapping" - set name = "Count Objects On Level" +ADMIN_VERB(mapping, count_objects_on_zlevel, "", R_DEBUG) var/level = input("Which z-level?","Level?") as text|null if(!level) return @@ -254,12 +163,8 @@ GLOBAL_LIST_EMPTY(dirty_vars) atom_list += A to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level]", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects Zlevel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/count_objects_all() - set category = "Mapping" - set name = "Count Objects All" +ADMIN_VERB(mapping, count_all_objects, "", R_DEBUG) var/type_text = input("Which type path?","") as text|null if(!type_text) return @@ -274,25 +179,17 @@ GLOBAL_LIST_EMPTY(dirty_vars) count++ to_chat(world, "There are [count] objects of type [type_path] in the game world", confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects All") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - //This proc is intended to detect lag problems relating to communication procs GLOBAL_VAR_INIT(say_disabled, FALSE) -/client/proc/disable_communication() - set category = "Mapping" - set name = "Disable all communication verbs" - +// Why is this a mapping verb? +ADMIN_VERB(mapping, disable_all_communication_verbs, "", R_DEBUG) GLOB.say_disabled = !GLOB.say_disabled - if(GLOB.say_disabled) - message_admins("[key] used 'Disable all communication verbs', killing all communication methods.") - else - message_admins("[key] used 'Disable all communication verbs', restoring all communication methods.") + var/message = "has [(GLOB.say_disabled ? "disabled" : "enabled")] all forms of communication" + message_admins("[key_name_admin(usr)] [message]") + log_admin("[key_name(usr)] [message]") -//This generates the icon states for job starting location landmarks. -/client/proc/create_mapping_job_icons() - set name = "Generate job landmarks icons" - set category = "Mapping" +ADMIN_VERB(mapping, generate_job_landmark_icons, "This generates the icon states for job starting location landmarks", R_DEBUG) var/icon/final = icon() var/mob/living/carbon/human/dummy/D = new(locate(1,1,1)) //spawn on 1,1,1 so we don't have runtimes when items are deleted D.setDir(SOUTH) @@ -316,10 +213,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) final.Insert(icon('icons/hud/screen_gen.dmi', "x[x_number == 1 ? "" : x_number]"), "x[x_number == 1 ? "" : x_number]") fcopy(final, "icons/mob/landmarks.dmi") -/client/proc/debug_z_levels() - set name = "Debug Z-Levels" - set category = "Mapping" - +ADMIN_VERB(mapping, debug_zlevels, "", R_DEBUG) var/list/z_list = SSmapping.z_list var/list/messages = list() messages += "World: [world.maxx] x [world.maxy] x [world.maxz]

      " @@ -373,12 +267,9 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) part += "[grid[x - min_x + 1][y - min_y + 1]]" messages += "[part.Join("")]" messages += "" + to_chat(usr, examine_block(messages.Join("")), confidential = TRUE) - to_chat(src, examine_block(messages.Join("")), confidential = TRUE) - -/client/proc/station_food_debug() - set name = "Count Station Food" - set category = "Mapping" +ADMIN_VERB(mapping, count_station_food, "", R_DEBUG) var/list/foodcount = list() for(var/obj/item/food/fuck_me in world) var/turf/location = get_turf(fuck_me) @@ -395,13 +286,11 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) var/page_style = "" var/page_contents = "[page_style][table_header][jointext(table_contents, "")]
      " - var/datum/browser/popup = new(mob, "fooddebug", "Station Food Count", 600, 400) + var/datum/browser/popup = new(usr, "fooddebug", "Station Food Count", 600, 400) popup.set_content(page_contents) popup.open() -/client/proc/station_stack_debug() - set name = "Count Station Stacks" - set category = "Mapping" +ADMIN_VERB(mapping, count_station_stacks, "", R_DEBUG) var/list/stackcount = list() for(var/obj/item/stack/fuck_me in world) var/turf/location = get_turf(fuck_me) @@ -418,22 +307,13 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) var/page_style = "" var/page_contents = "[page_style][table_header][jointext(table_contents, "")]
      " - var/datum/browser/popup = new(mob, "stackdebug", "Station Stack Count", 600, 400) + var/datum/browser/popup = new(usr, "stackdebug", "Station Stack Count", 600, 400) popup.set_content(page_contents) popup.open() -/// Check all tiles with a vent or scrubber on it and ensure that nothing is covering it up. -/client/proc/check_for_obstructed_atmospherics() - set name = "Check For Obstructed Atmospherics" - set category = "Mapping" - if(!holder) - to_chat(src, "Only administrators may use this command.", confidential = TRUE) - return +ADMIN_VERB(mapping, check_for_obstructed_atmopsherics, "Check all tiles with a vent or scrubber on it and ensure that nothing is covering it up", R_DEBUG) message_admins(span_adminnotice("[key_name_admin(usr)] is checking for obstructed atmospherics through the debug command.")) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Check For Obstructed Atmospherics") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - var/list/results = list() - results += "

      Anything that is considered to aesthetically obstruct an atmospherics machine (vent, scrubber, port) is listed below. Please re-arrange to accomodate for this.


      " // Ignore out stuff we see in normal and standard mapping that we don't care about (false alarms). Typically stuff that goes directionally off turfs or other undertile objects that we don't want to care about. diff --git a/code/modules/admin/verbs/maprotation.dm b/code/modules/admin/verbs/maprotation.dm index c41677db37c..6f9d4338142 100644 --- a/code/modules/admin/verbs/maprotation.dm +++ b/code/modules/admin/verbs/maprotation.dm @@ -1,6 +1,4 @@ -/client/proc/forcerandomrotate() - set category = "Server" - set name = "Trigger Random Map Rotation" +ADMIN_VERB(server, trigger_random_map_rotation, "", R_SERVER) var/rotate = tgui_alert(usr,"Force a random map rotation to trigger?", "Rotate map?", list("Yes", "Cancel")) if (rotate != "Yes") return @@ -8,9 +6,7 @@ log_admin("[key_name(usr)] is forcing a random map rotation.") SSmapping.maprotate() -/client/proc/adminchangemap() - set category = "Server" - set name = "Change Map" +ADMIN_VERB(server, change_map, "", R_SERVER) var/list/maprotatechoices = list() for (var/map in config.maplist) var/datum/map_config/virtual_map = config.maplist[map] @@ -46,7 +42,7 @@ return if(copytext("[map_file]", -4) != ".dmm")//4 == length(".dmm") - to_chat(src, span_warning("Filename must end in '.dmm': [map_file]")) + to_chat(usr, span_warning("Filename must end in '.dmm': [map_file]")) return if(fexists("_maps/custom/[map_file]")) @@ -56,11 +52,11 @@ // This is to make sure the map works so the server does not start without a map. var/datum/parsed_map/M = new (map_file) if(!M) - to_chat(src, span_warning("Map '[map_file]' failed to parse properly.")) + to_chat(usr, span_warning("Map '[map_file]' failed to parse properly.")) return if(!M.bounds) - to_chat(src, span_warning("Map '[map_file]' has non-existant bounds.")) + to_chat(usr, span_warning("Map '[map_file]' has non-existant bounds.")) qdel(M) return @@ -73,14 +69,14 @@ if(isnull(config_file)) return if(copytext("[config_file]", -5) != ".json") - to_chat(src, span_warning("Filename must end in '.json': [config_file]")) + to_chat(usr, span_warning("Filename must end in '.json': [config_file]")) return if(fexists("data/custom_map_json/[config_file]")) fdel("data/custom_map_json/[config_file]") if(!fcopy(config_file, "data/custom_map_json/[config_file]")) return if (virtual_map.LoadConfig("data/custom_map_json/[config_file]", TRUE) != TRUE) - to_chat(src, span_warning("Failed to load config: [config_file]. Check that the fields are filled out correctly. \"map_path\": \"custom\" and \"map_file\": \"your_map_name.dmm\"")) + to_chat(usr, span_warning("Failed to load config: [config_file]. Check that the fields are filled out correctly. \"map_path\": \"custom\" and \"map_file\": \"your_map_name.dmm\"")) return json_value = list( "version" = MAP_CURRENT_VERSION, diff --git a/code/modules/admin/verbs/panicbunker.dm b/code/modules/admin/verbs/panicbunker.dm index 8a5ac67a5a8..e4684c66adc 100644 --- a/code/modules/admin/verbs/panicbunker.dm +++ b/code/modules/admin/verbs/panicbunker.dm @@ -1,6 +1,4 @@ -/client/proc/panicbunker() - set category = "Server" - set name = "Toggle Panic Bunker" +ADMIN_VERB(server, toggle_panic_bunker, "", R_SERVER) if (!CONFIG_GET(flag/sql_enabled)) to_chat(usr, span_adminnotice("The Database is not enabled!"), confidential = TRUE) return @@ -10,8 +8,8 @@ var/time_rec = 0 var/message = "" if(new_pb) - time_rec = input(src, "How many living minutes should they need to play? 0 to disable.", "Shit's fucked isn't it", CONFIG_GET(number/panic_bunker_living)) as num - message = input(src, "What should they see when they log in?", "MMM", CONFIG_GET(string/panic_bunker_message)) as text + time_rec = input(usr, "How many living minutes should they need to play? 0 to disable.", "Shit's fucked isn't it", CONFIG_GET(number/panic_bunker_living)) as num + message = input(usr, "What should they see when they log in?", "MMM", CONFIG_GET(string/panic_bunker_message)) as text message = replacetext(message, "%minutes%", time_rec) CONFIG_SET(number/panic_bunker_living, time_rec) CONFIG_SET(string/panic_bunker_message, message) @@ -26,9 +24,7 @@ message_admins("The Database is not connected! Panic bunker will not work until the connection is reestablished.") SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Panic Bunker", "[new_pb ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/toggle_interviews() - set category = "Server" - set name = "Toggle PB Interviews" +ADMIN_VERB(server, toggle_pb_interviews, "", R_SERVER) if (!CONFIG_GET(flag/panic_bunker)) to_chat(usr, span_adminnotice("NOTE: The panic bunker is not enabled, so this change will not effect anything until it is enabled."), confidential = TRUE) var/new_interview = !CONFIG_GET(flag/panic_bunker_interview) diff --git a/code/modules/admin/verbs/plane_debugger.dm b/code/modules/admin/verbs/plane_debugger.dm index 1cf7d9c37a5..d198beee1fc 100644 --- a/code/modules/admin/verbs/plane_debugger.dm +++ b/code/modules/admin/verbs/plane_debugger.dm @@ -348,7 +348,7 @@ if("toggle_mirroring") set_mirroring(!mirror_target) if("vv_mob") - owner.owner.debug_variables(reference_frame) + SSadmin_verbs.dynamic_invoke_admin_verb(owner.owner, /mob/admin_module_holder/debug/view_variables, reference_frame) if("set_group") current_group = params["target_group"] if("connect_relay") @@ -374,7 +374,7 @@ var/plane_edit = params["edit"] var/atom/movable/screen/plane_master/edit = our_planes["[plane_edit]"] var/mob/user = ui.user - user?.client?.debug_variables(edit) + SSadmin_verbs.dynamic_invoke_admin_verb(user.client, /mob/admin_module_holder/debug/view_variables, edit) return TRUE if("set_alpha") var/plane_edit = params["edit"] diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index b1031a38fa1..55ad4e892f2 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -3,12 +3,7 @@ #define SHELLEO_STDOUT 2 #define SHELLEO_STDERR 3 -/client/proc/play_sound(S as sound) - set category = "Admin.Fun" - set name = "Play Global Sound" - if(!check_rights(R_SOUND)) - return - +ADMIN_VERB(fun, play_global_sound, "", R_SOUND, sound/to_play as sound) var/freq = 1 var/vol = input(usr, "What volume would you like the sound to play at?",, 100) as null|num if(!vol) @@ -16,7 +11,7 @@ vol = clamp(vol, 1, 100) var/sound/admin_sound = new() - admin_sound.file = S + admin_sound.file = to_play admin_sound.priority = 250 admin_sound.channel = CHANNEL_ADMIN admin_sound.frequency = freq @@ -28,60 +23,40 @@ var/res = tgui_alert(usr, "Show the title of this song to the players?",, list("Yes","No", "Cancel")) switch(res) if("Yes") - to_chat(world, span_boldannounce("An admin played: [S]"), confidential = TRUE) + to_chat(world, span_boldannounce("An admin played: [to_play]"), confidential = TRUE) if("Cancel") return - log_admin("[key_name(src)] played sound [S]") - message_admins("[key_name_admin(src)] played sound [S]") + log_admin("[key_name(usr)] played sound [to_play]") + message_admins("[key_name_admin(usr)] played sound [to_play]") - for(var/mob/M in GLOB.player_list) - if(M.client.prefs.read_preference(/datum/preference/toggle/sound_midi)) - admin_sound.volume = vol * M.client.admin_music_volume - SEND_SOUND(M, admin_sound) + for(var/mob/listener as anything in GLOB.player_list) + if(listener.client.prefs.read_preference(/datum/preference/toggle/sound_midi)) + admin_sound.volume = vol * listener.client.admin_music_volume + SEND_SOUND(listener, admin_sound) admin_sound.volume = vol - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Global Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +ADMIN_VERB(fun, play_local_sound, "", R_SOUND, sound/playing as sound) + log_admin("[key_name(usr)] played a local sound [playing]") + message_admins("[key_name_admin(usr)] played a local sound [playing]") + playsound(get_turf(usr), playing, 50, FALSE, FALSE) - -/client/proc/play_local_sound(S as sound) - set category = "Admin.Fun" - set name = "Play Local Sound" - if(!check_rights(R_SOUND)) - return - - log_admin("[key_name(src)] played a local sound [S]") - message_admins("[key_name_admin(src)] played a local sound [S]") - playsound(get_turf(src.mob), S, 50, FALSE, FALSE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Local Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/play_direct_mob_sound(S as sound, mob/M) - set category = "Admin.Fun" - set name = "Play Direct Mob Sound" - if(!check_rights(R_SOUND)) - return - - if(!M) - M = input(usr, "Choose a mob to play the sound to. Only they will hear it.", "Play Mob Sound") as null|anything in sort_names(GLOB.player_list) - if(!M || QDELETED(M)) - return - log_admin("[key_name(src)] played a direct mob sound [S] to [M].") - message_admins("[key_name_admin(src)] played a direct mob sound [S] to [ADMIN_LOOKUPFLW(M)].") - SEND_SOUND(M, S) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Direct Mob Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/play_web_sound() - set category = "Admin.Fun" - set name = "Play Internet Sound" - if(!check_rights(R_SOUND)) +ADMIN_VERB(fun, play_direct_mob_sound, "", R_SOUND, sound/playing as sound, mob/target as mob in view()) + if(!target) + target = input(usr, "Choose a mob to play the sound to. Only they will hear it.", "Play Mob Sound") as null|anything in sort_names(GLOB.player_list) + if(!target || QDELETED(target)) return + log_admin("[key_name(usr)] played a direct mob sound [playing] to [target].") + message_admins("[key_name_admin(usr)] played a direct mob sound [playing] to [ADMIN_LOOKUPFLW(target)].") + SEND_SOUND(target, playing) +ADMIN_VERB(fun, play_internet_sound, "", R_SOUND) var/ytdl = CONFIG_GET(string/invoke_youtubedl) if(!ytdl) - to_chat(src, span_boldwarning("Youtube-dl was not configured, action unavailable"), confidential = TRUE) //Check config.txt for the INVOKE_YOUTUBEDL value + to_chat(usr, span_boldwarning("Youtube-dl was not configured, action unavailable")) //Check config.txt for the INVOKE_YOUTUBEDL value return - var/web_sound_input = input("Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound via youtube-dl") as text|null + var/web_sound_input = input(usr, "Enter content URL (supported sites only, leave blank to stop playing)", "Play Internet Sound via youtube-dl") as text|null if(istext(web_sound_input)) var/web_sound_url = "" var/stop_web_sounds = FALSE @@ -90,8 +65,8 @@ web_sound_input = trim(web_sound_input) if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol)) - to_chat(src, span_boldwarning("Non-http(s) URIs are not allowed."), confidential = TRUE) - to_chat(src, span_warning("For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website."), confidential = TRUE) + to_chat(usr, span_boldwarning("Non-http(s) URIs are not allowed.")) + to_chat(usr, span_warning("For youtube-dl shortcuts like ytsearch: please use the appropriate full url from the website.")) return var/shell_scrubbed_input = shell_url_scrub(web_sound_input) var/list/output = world.shelleo("[ytdl] --geo-bypass --format \"bestaudio\[ext=mp3]/best\[ext=mp4]\[height <= 360]/bestaudio\[ext=m4a]/bestaudio\[ext=aac]\" --dump-single-json --no-playlist -- \"[shell_scrubbed_input]\"") @@ -103,8 +78,8 @@ try data = json_decode(stdout) catch(var/exception/e) - to_chat(src, span_boldwarning("Youtube-dl JSON parsing FAILED:"), confidential = TRUE) - to_chat(src, span_warning("[e]: [stdout]"), confidential = TRUE) + to_chat(usr, span_boldwarning("Youtube-dl JSON parsing FAILED:")) + to_chat(usr, span_warning("[e]: [stdout]")) return if (data["url"]) @@ -146,59 +121,37 @@ return SSblackbox.record_feedback("nested tally", "played_url", 1, list("[ckey]", "[web_sound_input]")) - log_admin("[key_name(src)] played web sound: [web_sound_input]") - message_admins("[key_name(src)] played web sound: [web_sound_input]") + log_admin("[key_name(usr)] played web sound: [web_sound_input]") + message_admins("[key_name(usr)] played web sound: [web_sound_input]") else - to_chat(src, span_boldwarning("Youtube-dl URL retrieval FAILED:"), confidential = TRUE) - to_chat(src, span_warning("[stderr]"), confidential = TRUE) + to_chat(usr, span_boldwarning("Youtube-dl URL retrieval FAILED:"), confidential = TRUE) + to_chat(usr, span_warning("[stderr]"), confidential = TRUE) else //pressed ok with blank - log_admin("[key_name(src)] stopped web sound") - message_admins("[key_name(src)] stopped web sound") + log_admin("[key_name(usr)] stopped web sound") + message_admins("[key_name(usr)] stopped web sound") web_sound_url = null stop_web_sounds = TRUE if(web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol)) - to_chat(src, span_boldwarning("BLOCKED: Content URL not using http(s) protocol"), confidential = TRUE) - to_chat(src, span_warning("The media provider returned a content URL that isn't using the HTTP or HTTPS protocol"), confidential = TRUE) + to_chat(usr, span_boldwarning("BLOCKED: Content URL not using http(s) protocol"), confidential = TRUE) + to_chat(usr, span_warning("The media provider returned a content URL that isn't using the HTTP or HTTPS protocol"), confidential = TRUE) return + if(web_sound_url || stop_web_sounds) - for(var/m in GLOB.player_list) - var/mob/M = m - var/client/C = M.client - if(C.prefs.read_preference(/datum/preference/toggle/sound_midi)) + for(var/mob/listener as anything in GLOB.player_list) + var/client/listner_client = listener.client + if(listner_client.prefs.read_preference(/datum/preference/toggle/sound_midi)) if(!stop_web_sounds) - C.tgui_panel?.play_music(web_sound_url, music_extra_data) + listner_client.tgui_panel?.play_music(web_sound_url, music_extra_data) else - C.tgui_panel?.stop_music() + listner_client.tgui_panel?.stop_music() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Internet Sound") +ADMIN_VERB(fun, set_round_end_sound, "", R_SOUND, sound/to_play as sound) + SSticker.SetRoundEndSound(to_play) -/client/proc/set_round_end_sound(S as sound) - set category = "Admin.Fun" - set name = "Set Round End Sound" - if(!check_rights(R_SOUND)) - return - - SSticker.SetRoundEndSound(S) - - log_admin("[key_name(src)] set the round end sound to [S]") - message_admins("[key_name_admin(src)] set the round end sound to [S]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Round End Sound") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/stop_sounds() - set category = "Debug" - set name = "Stop All Playing Sounds" - if(!src.holder) - return - - log_admin("[key_name(src)] stopped all currently playing sounds.") - message_admins("[key_name_admin(src)] stopped all currently playing sounds.") - for(var/mob/M in GLOB.player_list) - SEND_SOUND(M, sound(null)) - var/client/C = M.client - C?.tgui_panel?.stop_music() - SSblackbox.record_feedback("tally", "admin_verb", 1, "Stop All Playing Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + log_admin("[key_name(usr)] set the round end sound to [to_play]") + message_admins("[key_name_admin(usr)] set the round end sound to [to_play]") //world/proc/shelleo #undef SHELLEO_ERRORLEVEL diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index c2112c224d1..01b6988ae7b 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -1,35 +1,28 @@ -/proc/possess(obj/O in world) - set name = "Possess Obj" - set category = "Object" - - if((O.obj_flags & DANGEROUS_POSSESSION) && CONFIG_GET(flag/forbid_singulo_possession)) - to_chat(usr, "[O] is too powerful for you to possess.", confidential = TRUE) +ADMIN_VERB(object, possess_object, "", R_POSSESS, obj/target in world) + if((target.obj_flags & DANGEROUS_POSSESSION) && CONFIG_GET(flag/forbid_singulo_possession)) + to_chat(usr, "[target] is too powerful for you to possess.", confidential = TRUE) return - var/turf/T = get_turf(O) + var/turf/target_turf = get_turf(target) - if(T) - log_admin("[key_name(usr)] has possessed [O] ([O.type]) at [AREACOORD(T)]") - message_admins("[key_name(usr)] has possessed [O] ([O.type]) at [AREACOORD(T)]") + if(target_turf) + log_admin("[key_name(usr)] has possessed [target] ([target.type]) at [AREACOORD(target_turf)]") + message_admins("[key_name(usr)] has possessed [target] ([target.type]) at [AREACOORD(target_turf)]") else - log_admin("[key_name(usr)] has possessed [O] ([O.type]) at an unknown location") - message_admins("[key_name(usr)] has possessed [O] ([O.type]) at an unknown location") + log_admin("[key_name(usr)] has possessed [target] ([target.type]) at an unknown location") + message_admins("[key_name(usr)] has possessed [target] ([target.type]) at an unknown location") if(!usr.control_object) //If you're not already possessing something... usr.name_archive = usr.real_name - usr.forceMove(O) - usr.real_name = O.name - usr.name = O.name - usr.reset_perspective(O) - usr.control_object = O - O.AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Possess Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/proc/release() - set name = "Release Obj" - set category = "Object" + usr.forceMove(target) + usr.real_name = target.name + usr.name = target.name + usr.reset_perspective(target) + usr.control_object = target + target.AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) +ADMIN_VERB(object, release_object, "", R_POSSESS) if(!usr.control_object) //lest we are banished to the nullspace realm. return @@ -38,19 +31,10 @@ usr.name_archive = "" usr.name = usr.real_name if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - H.name = H.get_visible_name() + var/mob/living/carbon/human/user = usr + user.name = user.get_visible_name() usr.control_object.RemoveElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds) usr.forceMove(get_turf(usr.control_object)) usr.reset_perspective() usr.control_object = null - SSblackbox.record_feedback("tally", "admin_verb", 1, "Release Object") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/proc/givetestverbs(mob/M in GLOB.mob_list) - set desc = "Give this guy possess/release verbs" - set category = "Debug" - set name = "Give Possessing Verbs" - add_verb(M, GLOBAL_PROC_REF(possess)) - add_verb(M, GLOBAL_PROC_REF(release)) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Possessing Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/reestablish_db_connection.dm b/code/modules/admin/verbs/reestablish_db_connection.dm index 1cc899f72a8..e69de29bb2d 100644 --- a/code/modules/admin/verbs/reestablish_db_connection.dm +++ b/code/modules/admin/verbs/reestablish_db_connection.dm @@ -1,30 +0,0 @@ -/client/proc/reestablish_db_connection() - set category = "Server" - set name = "Reestablish DB Connection" - if (!CONFIG_GET(flag/sql_enabled)) - to_chat(usr, span_adminnotice("The Database is not enabled!"), confidential = TRUE) - return - - if (SSdbcore.IsConnected()) - if (!check_rights(R_DEBUG,0)) - tgui_alert(usr,"The database is already connected! (Only those with +debug can force a reconnection)", "The database is already connected!") - return - - var/reconnect = tgui_alert(usr,"The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", list("Force Reconnect", "Cancel")) - if (reconnect != "Force Reconnect") - return - - SSdbcore.Disconnect() - log_admin("[key_name(usr)] has forced the database to disconnect") - message_admins("[key_name_admin(usr)] has forced the database to disconnect!") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Force Reestablished Database Connection") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - log_admin("[key_name(usr)] is attempting to re-establish the DB Connection") - message_admins("[key_name_admin(usr)] is attempting to re-establish the DB Connection") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Reestablished Database Connection") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - SSdbcore.failed_connections = 0 - if(!SSdbcore.Connect()) - message_admins("Database connection failed: " + SSdbcore.ErrorMsg()) - else - message_admins("Database connection re-established") diff --git a/code/modules/admin/verbs/requests.dm b/code/modules/admin/verbs/requests.dm index 2f7d1d0fbd6..e69de29bb2d 100644 --- a/code/modules/admin/verbs/requests.dm +++ b/code/modules/admin/verbs/requests.dm @@ -1,7 +0,0 @@ -/// Verb for opening the requests manager panel -/client/proc/requests() - set name = "Requests Manager" - set desc = "Open the request manager panel to view all requests during this round" - set category = "Admin.Game" - SSblackbox.record_feedback("tally", "admin_verb", 1, "Request Manager") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - GLOB.requests.ui_interact(usr) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index d867d06f035..6c01efbbfc5 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -1,10 +1,6 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) -/client/proc/secrets() //Creates a verb for admins to open up the ui - set name = "Secrets" - set desc = "Abuse harder than you ever have before with this handy dandy semi-misc stuff menu" - set category = "Admin.Game" - SSblackbox.record_feedback("tally", "admin_verb", 1, "Secrets Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/client/proc/secrets() var/datum/secrets_menu/tgui = new(usr)//create the datum tgui.ui_interact(usr)//datum has a tgui component, here we open the window @@ -102,25 +98,25 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) D.cure(0) if("list_bombers") - holder.list_bombers() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/list_bombers) if("list_signalers") - holder.list_signalers() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/list_signalers) if("list_lawchanges") - holder.list_law_changes() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/list_law_changes) if("showailaws") - holder.check_ai_laws() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/check_ai_laws) if("manifest") - holder.show_manifest() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/show_manifest) if("dna") - holder.list_dna() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/list_dna) if("fingerprints") - holder.list_fingerprints() + SSadmin_verbs.dynamic_invoke_admin_verb(holder, /mob/admin_module_holder/game/list_fingerprints) if("ctfbutton") toggle_id_ctf(holder, "centcom") @@ -247,16 +243,13 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) log_admin("[key_name(holder)] made all SMESs powered", 1) message_admins(span_adminnotice("[key_name_admin(holder)] made all SMESs powered")) power_restore_quick() + if("anon_name") - if(!is_funmin) - return - holder.anon_names() - SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Anonymous Names")) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/events/setup_anonymous_names) + if("tripleAI") - if(!is_funmin) - return - holder.triple_ai() - SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Triple AI")) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/events/toggle_ai_triumvirate) + if("onlyone") if(!is_funmin) return diff --git a/code/modules/admin/verbs/selectequipment.dm b/code/modules/admin/verbs/selectequipment.dm index 01cd7f13c20..1dd90468b8f 100644 --- a/code/modules/admin/verbs/selectequipment.dm +++ b/code/modules/admin/verbs/selectequipment.dm @@ -1,8 +1,4 @@ -/client/proc/cmd_select_equipment(mob/target in GLOB.mob_list) - set category = "Admin.Events" - set name = "Select equipment" - - +ADMIN_CONTEXT_ENTRY(context_select_equipment, "Select Equipment", R_ADMIN, mob/target in world) var/datum/select_equipment/ui = new(usr, target) ui.ui_interact(usr) @@ -181,7 +177,7 @@ user.admin_apply_outfit(target_mob, new_outfit) if("customoutfit") - user.outfit_manager() + SSadmin_verbs.dynamic_invoke_admin_verb(user, /mob/admin_module_holder/debug/outfit_manager) if("togglefavorite") var/datum/outfit/outfit_path = resolve_outfit(params["path"]) diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index 541c54f81a0..2b2ca57bf9c 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -1,18 +1,12 @@ // Server Tab - Server Verbs -/client/proc/toggle_random_events() - set category = "Server" - set name = "Toggle random events on/off" - set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" + +ADMIN_VERB(server, toggle_random_events, "Toggles random events such as meteors, black holes, blob (but not space dust) on/off", R_SERVER) var/new_are = !CONFIG_GET(flag/allow_random_events) CONFIG_SET(flag/allow_random_events, new_are) message_admins("[key_name_admin(usr)] has [new_are ? "enabled" : "disabled"] random events.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Random Events", "[new_are ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/toggle_hub() - set category = "Server" - set name = "Toggle Hub" +ADMIN_VERB(server, toggle_hub, "", R_SERVER) world.update_hub_visibility(!GLOB.hub_visibility) log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(GLOB.hub_visibility?"on":"off")] the hub.") @@ -20,15 +14,7 @@ if (GLOB.hub_visibility && !world.reachable) message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggled Hub Visibility", "[GLOB.hub_visibility ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/datum/admins/proc/restart() - set category = "Server" - set name = "Reboot World" - set desc = "Restarts the world immediately" - if (!usr.client.holder) - return - +ADMIN_VERB(server, reboot_world, "Restarts the world immediately", R_SERVER) var/localhost_addresses = list("127.0.0.1", "::1") var/list/options = list("Regular Restart", "Regular Restart (with delay)", "Hard Restart (No Delay/Feeback Reason)", "Hardest Restart (No actions, just reboot)") if(world.TgsAvailable()) @@ -40,7 +26,6 @@ var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options if(result) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Reboot World") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! var/init_by = "Initiated by [usr.client.holder.fakekey ? "Admin" : usr.key]." switch(result) if("Regular Restart") @@ -66,43 +51,24 @@ to_chat(world, "Server restart - [init_by]") world.TgsEndProcess() -/datum/admins/proc/end_round() - set category = "Server" - set name = "End Round" - set desc = "Attempts to produce a round end report and then restart the server organically." - - if (!usr.client.holder) - return +ADMIN_VERB(server, end_round, "Attempts to produce a round end report and then restart the server organically.", R_SERVER) var/confirm = tgui_alert(usr, "End the round and restart the game world?", "End Round", list("Yes", "Cancel")) if(confirm == "Cancel") return if(confirm == "Yes") SSticker.force_ending = TRUE - SSblackbox.record_feedback("tally", "admin_verb", 1, "End Round") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleooc() - set category = "Server" - set desc = "Toggle dis bitch" - set name = "Toggle OOC" +ADMIN_VERB(server, toggle_ooc, "Toggle dis bitch", R_SERVER) toggle_ooc() log_admin("[key_name(usr)] toggled OOC.") message_admins("[key_name_admin(usr)] toggled OOC.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle OOC", "[GLOB.ooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleoocdead() - set category = "Server" - set desc = "Toggle dis bitch" - set name = "Toggle Dead OOC" +ADMIN_VERB(server, toggle_dead_ooc, "Toggle dis bitch", R_SERVER) toggle_dooc() - log_admin("[key_name(usr)] toggled OOC.") message_admins("[key_name_admin(usr)] toggled Dead OOC.") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead OOC", "[GLOB.dooc_allowed ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/startnow() - set category = "Server" - set desc = "Start the round RIGHT NOW" - set name = "Start Now" +ADMIN_VERB(server, start_now, "Start the round RIGHT NOW", R_SERVER) if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP) if(!SSticker.start_immediately) var/localhost_addresses = list("127.0.0.1", "::1") @@ -128,14 +94,7 @@ to_chat(usr, "Error: Start Now: Game has already started.") return FALSE -/datum/admins/proc/delay_round_end() - set category = "Server" - set desc = "Prevent the server from restarting" - set name = "Delay Round End" - - if(!check_rights(R_SERVER)) - return - +ADMIN_VERB(server, delay_round_end, "Prevent the server from restarting", R_SERVER) if(SSticker.delay_end) tgui_alert(usr, "The round end is already delayed. The reason for the current delay is: \"[SSticker.admin_delay_notice]\"", "Alert", list("Ok")) return @@ -154,23 +113,15 @@ log_admin("[key_name(usr)] delayed the round end for reason: [SSticker.admin_delay_notice]") message_admins("[key_name_admin(usr)] delayed the round end for reason: [SSticker.admin_delay_notice]") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Delay Round End", "Reason: [delay_reason]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleenter() - set category = "Server" - set desc = "People can't enter" - set name = "Toggle Entering" +ADMIN_VERB(server, toggle_entering, "People can't enter", R_SERVER) if(!SSlag_switch.initialized) return SSlag_switch.set_measure(DISABLE_NON_OBSJOBS, !SSlag_switch.measures[DISABLE_NON_OBSJOBS]) log_admin("[key_name(usr)] toggled new player game entering. Lag Switch at index ([DISABLE_NON_OBSJOBS])") message_admins("[key_name_admin(usr)] toggled new player game entering [SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "OFF" : "ON"].") - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Entering", "[!SSlag_switch.measures[DISABLE_NON_OBSJOBS] ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleAI() - set category = "Server" - set desc = "People can't be AI" - set name = "Toggle AI" +ADMIN_VERB(server, toggle_ai, "People can't be AI", R_SERVER) var/alai = CONFIG_GET(flag/allow_ai) CONFIG_SET(flag/allow_ai, !alai) if (alai) @@ -179,12 +130,8 @@ to_chat(world, "The AI job is chooseable now.", confidential = TRUE) log_admin("[key_name(usr)] toggled AI allowed.") world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle AI", "[!alai ? "Disabled" : "Enabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleaban() - set category = "Server" - set desc = "Respawn basically" - set name = "Toggle Respawn" +ADMIN_VERB(server, toggle_respawn, "Respawn basically", R_SERVER) var/new_nores = !CONFIG_GET(flag/norespawn) CONFIG_SET(flag/norespawn, new_nores) if (!new_nores) @@ -194,14 +141,9 @@ message_admins(span_adminnotice("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")) log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[!new_nores ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/delay() - set category = "Server" - set desc = "Delay the game start" - set name = "Delay Pre-Game" - - var/newtime = input("Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(SSticker.GetTimeLeft()/10)) as num|null +ADMIN_VERB(server, delay_pre_game, "Delay the game start", R_SERVER) + var/newtime = input(usr, "Set a new time in seconds. Set -1 for indefinite delay.","Set Delay",round(SSticker.GetTimeLeft()/10)) as num|null if(SSticker.current_state > GAME_STATE_PREGAME) return tgui_alert(usr, "Too late... The game has already started!") if(newtime) @@ -215,15 +157,8 @@ to_chat(world, "The game will start in [DisplayTimeText(newtime)].", confidential = TRUE) SEND_SOUND(world, sound('sound/ai/default/attention.ogg')) log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/datum/admins/proc/set_admin_notice() - set category = "Server" - set name = "Set Admin Notice" - set desc ="Set an announcement that appears to everyone who joins the server. Only lasts this round" - if(!check_rights(0)) - return +ADMIN_VERB(server, set_admin_notice, "Set an announcement that appears to everone who joins the server; only lasts this round", R_SERVER) var/new_admin_notice = input(src,"Set a public notice for this round. Everyone who joins the server will see it.\n(Leaving it blank will delete the current notice):","Set Notice",GLOB.admin_notice) as message|null if(new_admin_notice == null) return @@ -236,14 +171,9 @@ message_admins("[key_name(usr)] set the admin notice.") log_admin("[key_name(usr)] set the admin notice:\n[new_admin_notice]") to_chat(world, span_adminnotice("Admin Notice:\n \t [new_admin_notice]"), confidential = TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Admin Notice") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! GLOB.admin_notice = new_admin_notice - return -/datum/admins/proc/toggleguests() - set category = "Server" - set desc = "Guests can't enter" - set name = "Toggle guests" +ADMIN_VERB(server, toggle_guests, "Guests can't enter", R_SERVER) var/new_guest_ban = !CONFIG_GET(flag/guest_ban) CONFIG_SET(flag/guest_ban, new_guest_ban) if (new_guest_ban) diff --git a/code/modules/admin/verbs/spawnobjasmob.dm b/code/modules/admin/verbs/spawnobjasmob.dm index 78e3a6457a7..f9d1c01d914 100644 --- a/code/modules/admin/verbs/spawnobjasmob.dm +++ b/code/modules/admin/verbs/spawnobjasmob.dm @@ -1,13 +1,5 @@ -/datum/admins/proc/spawn_objasmob(object as text) - set category = "Debug" - set desc = "(obj path) Spawn object-mob" - set name = "Spawn object-mob" - - if(!check_rights(R_SPAWN)) - return - +ADMIN_VERB(debug, spawn_object_as_mob, "Spawn an object-mob", R_SPAWN, object as text) var/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/obj))) - if (!chosen) return @@ -16,18 +8,60 @@ var/obj/chosen_obj = text2path(chosen) var/list/settings = list( - "mainsettings" = list( - "name" = list("desc" = "Name", "type" = "string", "value" = "Bob"), - "maxhealth" = list("desc" = "Max. health", "type" = "number", "value" = 100), - "access" = list("desc" = "Access ID", "type" = "datum", "path" = "/obj/item/card/id", "value" = "Default"), - "objtype" = list("desc" = "Base obj type", "type" = "datum", "path" = "/obj", "value" = "[chosen]"), - "googlyeyes" = list("desc" = "Googly eyes", "type" = "boolean", "value" = "No"), - "disableai" = list("desc" = "Disable AI", "type" = "boolean", "value" = "Yes"), - "idledamage" = list("desc" = "Damaged while idle", "type" = "boolean", "value" = "No"), - "dropitem" = list("desc" = "Drop obj on death", "type" = "boolean", "value" = "Yes"), - "mobtype" = list("desc" = "Base mob type", "type" = "datum", "path" = "/mob/living/simple_animal/hostile/mimic/copy", "value" = "/mob/living/simple_animal/hostile/mimic/copy"), - "ckey" = list("desc" = "ckey", "type" = "ckey", "value" = "none"), - )) + "mainsettings" = list( + "name" = list( + "desc" = "Name", + "type" = "string", + "value" = "Bob", + ), + "maxhealth" = list( + "desc" = "Max. health", + "type" = "number", + "value" = 100, + ), + "access" = list( + "desc" = "Access ID", + "type" = "datum", + "path" = "/obj/item/card/id", + "value" = "Default", + ), + "objtype" = list( + "desc" = "Base obj type", + "type" = "datum", + "path" = "/obj", "value" = "[chosen]", + ), + "googlyeyes" = list( + "desc" = "Googly eyes", + "type" = "boolean", + "value" = "No", + ), + "disableai" = list( + "desc" = "Disable AI", + "type" = "boolean", + "value" = "Yes", + ), + "idledamage" = list( + "desc" = "Damaged while idle", + "type" = "boolean", + "value" = "No", + ), + "dropitem" = list( + "desc" = "Drop obj on death", + "type" = "boolean", + "value" = "Yes", + ), + "mobtype" = list( + "desc" = "Base mob type", + "type" = "datum", + "path" = "/mob/living/simple_animal/hostile/mimic/copy", "value" = "/mob/living/simple_animal/hostile/mimic/copy", + ), + "ckey" = list( + "desc" = "ckey", + "type" = "ckey", + "value" = "none", + ), + ), + ) var/list/prefreturn = presentpreflikepicker(usr,"Customize mob", "Customize mob", Button1="Ok", width = 450, StealFocus = 1,Timeout = 0, settings=settings) if (prefreturn["button"] == 1) @@ -63,7 +97,4 @@ if (mainsettings["ckey"]["value"] != "none") basemob.ckey = mainsettings["ckey"]["value"] - - log_admin("[key_name(usr)] spawned a sentient object-mob [basemob] from [chosen_obj] at [AREACOORD(usr)]") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn object-mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/view_variables/admin_delete.dm b/code/modules/admin/view_variables/admin_delete.dm index c28b366f926..66778816cdc 100644 --- a/code/modules/admin/view_variables/admin_delete.dm +++ b/code/modules/admin/view_variables/admin_delete.dm @@ -1,4 +1,4 @@ -/client/proc/admin_delete(datum/D) +/datum/admins/proc/admin_delete(datum/D) var/atom/A = D var/coords = "" var/jmp_coords = "" @@ -20,7 +20,7 @@ var/turf/T = D T.ScrapeAway() else - vv_update_display(D, "deleted", VV_MSG_DELETED) + owner?.vv_update_display(D, "deleted", VV_MSG_DELETED) qdel(D) if(!QDELETED(D)) - vv_update_display(D, "deleted", "") + owner?.vv_update_display(D, "deleted", "") diff --git a/code/modules/admin/view_variables/mark_datum.dm b/code/modules/admin/view_variables/mark_datum.dm deleted file mode 100644 index b7296f2553a..00000000000 --- a/code/modules/admin/view_variables/mark_datum.dm +++ /dev/null @@ -1,19 +0,0 @@ -/client/proc/mark_datum(datum/D) - if(!holder) - return - if(holder.marked_datum) - holder.UnregisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING) - vv_update_display(holder.marked_datum, "marked", "") - holder.marked_datum = D - holder.RegisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/admins, handle_marked_del)) - vv_update_display(D, "marked", VV_MSG_MARKED) - -/client/proc/mark_datum_mapview(datum/D as mob|obj|turf|area in view(view)) - set category = "Debug" - set name = "Mark Object" - mark_datum(D) - -/datum/admins/proc/handle_marked_del(datum/source) - SIGNAL_HANDLER - UnregisterSignal(marked_datum, COMSIG_PARENT_QDELETING) - marked_datum = null diff --git a/code/modules/admin/view_variables/tag_datum.dm b/code/modules/admin/view_variables/tag_datum.dm deleted file mode 100644 index 3b611e3cdf9..00000000000 --- a/code/modules/admin/view_variables/tag_datum.dm +++ /dev/null @@ -1,18 +0,0 @@ -/client/proc/tag_datum(datum/target_datum) - if(!holder || QDELETED(target_datum)) - return - holder.add_tagged_datum(target_datum) - -/client/proc/toggle_tag_datum(datum/target_datum) - if(!holder || !target_datum) - return - - if(LAZYFIND(holder.tagged_datums, target_datum)) - holder.remove_tagged_datum(target_datum) - else - holder.add_tagged_datum(target_datum) - -/client/proc/tag_datum_mapview(datum/target_datum as mob|obj|turf|area in view(view)) - set category = "Debug" - set name = "Tag Datum" - tag_datum(target_datum) diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index d6934144a8c..f77e036c6a1 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -11,7 +11,7 @@ else if(islist(target)) vv_do_list(target, href_list) if(href_list["Vars"]) - debug_variables(locate(href_list["Vars"])) + SSadmin_verbs.dynamic_invoke_admin_verb(src, /mob/admin_module_holder/debug/view_variables, locate(href_list["Vars"])) //Stuff below aren't in dropdowns/etc. @@ -118,5 +118,4 @@ if(href_list["datumrefresh"]) var/datum/DAT = locate(href_list["datumrefresh"]) if(isdatum(DAT) || istype(DAT, /client) || islist(DAT)) - debug_variables(DAT) - + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, DAT) diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 09759c72c6f..7980521e2ff 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -40,12 +40,12 @@ message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a VV window") log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [target]") to_chat(C, "[holder.fakekey ? "an Administrator" : "[usr.client.key]"] has granted you access to view a View Variables window", confidential = TRUE) - C.debug_variables(target) + SSadmin_verbs.dynamic_invoke_admin_verb(C, /mob/admin_module_holder/debug/view_variables, target) if(check_rights(R_DEBUG)) if(href_list[VV_HK_DELETE]) - usr.client.admin_delete(target) + usr.client.holder.admin_delete(target) if (isturf(target)) // show the turf that took its place - usr.client.debug_variables(target) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, target) return if(href_list[VV_HK_MARK]) @@ -137,5 +137,4 @@ menu.Unlock() menu.ui_interact(usr) if(href_list[VV_HK_CALLPROC]) - usr.client.callproc_datum(target) - + usr.client.admin_context_wrapper_context_callproc(target) diff --git a/code/modules/admin_verbs/README.md b/code/modules/admin_verbs/README.md new file mode 100644 index 00000000000..802ac1f6afa --- /dev/null +++ b/code/modules/admin_verbs/README.md @@ -0,0 +1 @@ +## TODO diff --git a/code/modules/admin_verbs/admin_module_holder.dm b/code/modules/admin_verbs/admin_module_holder.dm new file mode 100644 index 00000000000..9ab3b01e708 --- /dev/null +++ b/code/modules/admin_verbs/admin_module_holder.dm @@ -0,0 +1,13 @@ +GENERAL_PROTECT_DATUM(/mob/admin_module_holder) + +/// Exists to hold admin verbs. Should never be directly created or accessed +/mob/admin_module_holder + +/mob/admin_module_holder/proc/dynamic_map_generate() + return + +/mob/admin_module_holder/Read(F) + del(src) + +/mob/admin_module_holder/Write(F) + return null diff --git a/code/modules/admin_verbs/admin_verbs.dm b/code/modules/admin_verbs/admin_verbs.dm new file mode 100644 index 00000000000..c73dbbe19fb --- /dev/null +++ b/code/modules/admin_verbs/admin_verbs.dm @@ -0,0 +1,30 @@ +// +// Admin Verbs modify the game state in some manner, whether that is by modifying the local area, or the station as a whole +// +#define ADMIN_VERB_ADMIN(module, _name, _desc, params...) ADMIN_VERB(module, _name, _desc, R_ADMIN, ##params) + +ADMIN_CONTEXT_ENTRY(contextcmd_fix_air, "Fix Air", R_ADMIN, turf/target in world) + var/range = tgui_input_number(usr, "Specify the radius", "Fix Air", 2, min_value = 0) + message_admins("[key_name_admin(usr)] fixed air with range [range] in area [target.loc.name]") + usr.log_message("fixed air with range [range] in area [target.loc.name]", LOG_ADMIN) + for(var/turf/open/open_turf in range(range, target)) + if(open_turf.blocks_air) + continue + + var/datum/gas_mixture/initial_air = SSair.parse_gas_string(open_turf.initial_gas_mix, /datum/gas_mixture/turf) + open_turf.copy_air(initial_air) + open_turf.update_visuals() + +ADMIN_VERB_ADMIN(events, access_news_network, "Allows you to view, add and edit news feeds") + var/datum/newspanel/new_newspanel = new + new_newspanel.ui_interact(usr) + +ADMIN_VERB_ADMIN(admin, announce, "Announce your desires to the world", message as message|null) + if(!message) + return + message = check_rights_for(usr.client, R_SERVER) ? message : adminscrub(message, 500) + to_chat(world, "[span_adminnotice("[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:")]\n \t [message]") + log_admin("Announce: [key_name(usr)] : [message]") + +ADMIN_VERB(admin, known_alts_panel, "View all known alt accounts", NONE) + GLOB.known_alts.show_panel(usr.client) diff --git a/code/modules/admin_verbs/default_verbs.dm b/code/modules/admin_verbs/default_verbs.dm new file mode 100644 index 00000000000..e0ef6275784 --- /dev/null +++ b/code/modules/admin_verbs/default_verbs.dm @@ -0,0 +1,246 @@ +// +// Default Verbs have no permissions and are available to any and all admins +// +#define ADMIN_VERB_DEFAULT(module, _name, _desc, params...) ADMIN_VERB(module, _name, _desc, NONE, ##params) + +ADMIN_VERB_DEFAULT(server, reestablish_db_connection, "Attempts to establish a connection to the DB") + if(!CONFIG_GET(flag/sql_enabled)) + to_chat(usr, span_adminnotice("The Database is not enabled!")) + return + + if(SSdbcore.IsConnected()) + if(!check_rights(R_DEBUG,0)) + tgui_alert(usr, "The database is already connected! (Only those with +debug can force a reconnection)", "The database is already connected!") + return + + var/reconnect = tgui_alert(usr, "The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", list("Force Reconnect", "Cancel")) + if(reconnect != "Force Reconnect") + return + + SSdbcore.Disconnect() + log_admin("[key_name(usr)] has forced the database to disconnect") + message_admins("[key_name_admin(usr)] has forced the database to disconnect!") + + log_admin("[key_name(usr)] is attempting to re-establish the DB Connection") + message_admins("[key_name_admin(usr)] is attempting to re-establish the DB Connection") + + SSdbcore.failed_connections = 0 + if(!SSdbcore.Connect()) + message_admins("Database connection failed: " + SSdbcore.ErrorMsg()) + else + message_admins("Database connection re-established") + +ADMIN_VERB_DEFAULT(debug, debug_stat_panel, "Enable advanced stat panel debugging") + usr.client.stat_panel.send_message("create_debug") + +ADMIN_VERB_DEFAULT(game, dead_say, "Speak a message to observers", message as text) + if(usr.client.prefs.muted & MUTE_DEADCHAT) + to_chat(src, span_danger("You cannot send DSAY messages (muted).")) + return + + if(!message) + message = tgui_input_text(usr, "Message", "Dead Say") + if(!message) + return + + if(usr.client.handle_spam_prevention(message, MUTE_DEADCHAT)) + return + + message = copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN) + if(!message) + return + usr.log_talk(message, LOG_DSAY) + + var/rank_name = usr.client.holder.rank_names() + var/admin_name = usr.ckey + if(usr.client.holder.fakekey) + rank_name = pick(strings("admin_nicknames.json", "ranks", "config")) + admin_name = pick(strings("admin_nicknames.json", "names", "config")) + var/name_and_rank = "[span_tooltip(rank_name, "STAFF")] ([admin_name])" + deadchat_broadcast("[span_prefix("DEAD:")] [name_and_rank] says, \"[emoji_parse(message)]\"") + +ADMIN_VERB_DEFAULT(admin, deadmin, "Become a normal player") + usr.client.holder.deactivate() + log_admin("[key_name(usr)] deadmined") + +ADMIN_VERB_DEFAULT(debug, reload_admins, "Reloads all admins from the data store") + var/confirm = tgui_alert(usr, "Are you sure you want to reload all admins?", "Confirm", list("Yes", "No")) + if(confirm != "Yes") + return + + message_admins("[key_name_admin(usr)] manually reloaded admins.") + load_admins() + +ADMIN_VERB_DEFAULT(debug, stop_all_sounds, "Stop all sounds on all connected clients") + log_admin("[key_name(usr)] stopped all currently playing sounds.") + message_admins("[key_name_admin(usr)] stopped all currently playing sounds.") + for(var/mob/player as anything in GLOB.player_list) + SEND_SOUND(player, sound(null)) + // player list is only supposed to contain mobs with an attached client, + // but clients can just poof in and out of existence + player.client?.tgui_panel.stop_music() + +ADMIN_VERB_DEFAULT(game, secrets_panel, "Abuse harder than you ever knew was possible") + usr.client?.secrets() + +ADMIN_VERB_DEFAULT(game, requests_manager, "Open the request manager panel to view all requests during this round") + GLOB.requests.ui_interact(usr) + +ADMIN_VERB_DEFAULT(admin, admin_say, "Speak to your fellow jannies", message as text) + message ||= tgui_input_text(usr, "Message", "Admin Say") + message = emoji_parse(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + if(!message) + return + + if(findtext(message, "@") || findtext(message, "#")) + var/list/link_results = check_asay_links(message) + if(length(link_results)) + message = link_results[ASAY_LINK_NEW_MESSAGE_INDEX] + link_results[ASAY_LINK_NEW_MESSAGE_INDEX] = null + var/list/pinged_admin_clients = link_results[ASAY_LINK_PINGED_ADMINS_INDEX] + for(var/iter_ckey in pinged_admin_clients) + var/client/iter_admin_client = pinged_admin_clients[iter_ckey] + if(!iter_admin_client?.holder) + continue + window_flash(iter_admin_client) + SEND_SOUND(iter_admin_client.mob, sound('sound/misc/asay_ping.ogg')) + usr.log_talk(message, LOG_ASAY) + message = keywords_lookup(message) + var/asay_color = usr.client?.prefs.read_preference(/datum/preference/color/asay_color) + var/custom_asay_color = (CONFIG_GET(flag/allow_admin_asaycolor) && asay_color) ? "" : "" + message = "[span_adminsay("[span_prefix("ADMIN:")] [key_name(usr, 1)] [ADMIN_FLW(usr)]: [custom_asay_color][message]")][custom_asay_color ? "":null]" + to_chat(GLOB.admins, + type = MESSAGE_TYPE_ADMINCHAT, + html = message, + confidential = TRUE) + +ADMIN_VERB_DEFAULT(admin, admin_pm, "Send a message directly to a client") + var/list/targets = list() + for(var/client/client in GLOB.clients) + var/nametag = "" + var/mob/lad = client.mob + var/mob_name = lad?.name + var/real_mob_name = lad?.real_name + if(!lad) + nametag = "(No Mob)" + else if(isnewplayer(lad)) + nametag = "(New Player)" + else if(isobserver(lad)) + nametag = "[mob_name](Ghost)" + else + nametag = "[real_mob_name](as [mob_name])" + targets["[nametag] - [client]"] = client + + var/whom = input(usr, "To whom shall we send a message?", "Admin PM", null) as null|anything in sort_list(targets) + if(!whom) + return + whom = disambiguate_client(targets[whom]) + + var/message = usr.client.request_adminpm_message(whom, null) + if(!usr.client.sends_adminpm_message(whom, message)) + return + usr.client.notify_adminpm_message(whom, message) + +ADMIN_CONTEXT_ENTRY(contextcmd_tag_atom, "Tag Atom", NONE, atom/target in view(view)) + tag_datum(target) + +ADMIN_VERB(debug, tag_datum, "Tag an atom in view", NONE, atom/target) + usr.client.tag_datum(target) + +/client/proc/tag_datum(datum/target_datum) + if(!holder || QDELETED(target_datum)) + return + holder.add_tagged_datum(target_datum) + +/client/proc/toggle_tag_datum(datum/target_datum) + if(!holder || !target_datum) + return + + if(LAZYFIND(holder.tagged_datums, target_datum)) + holder.remove_tagged_datum(target_datum) + else + holder.add_tagged_datum(target_datum) + +ADMIN_CONTEXT_ENTRY(contextcmd_mark_atom, "Mark Atom", NONE, atom/target in view(view)) + mark_datum(target) + +ADMIN_VERB(debug, mark_object, "Mark an atom in view", NONE, atom/target) + usr.client.mark_datum(target) + +/client/proc/mark_datum(datum/D) + if(!holder) + return + if(holder.marked_datum) + holder.UnregisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING) + vv_update_display(holder.marked_datum, "marked", "") + holder.marked_datum = D + holder.RegisterSignal(holder.marked_datum, COMSIG_PARENT_QDELETING, TYPE_PROC_REF(/datum/admins, handle_marked_del)) + vv_update_display(D, "marked", VV_MSG_MARKED) + +/datum/admins/proc/handle_marked_del(datum/source) + SIGNAL_HANDLER + UnregisterSignal(marked_datum, COMSIG_PARENT_QDELETING) + marked_datum = null + +/atom/proc/investigate_log(message, subject) + if(!message || !subject) + return + var/F = file("[GLOB.log_directory]/[subject].html") + var/source = "[src]" + + if(isliving(src)) + var/mob/living/source_mob = src + source += " ([source_mob.ckey ? source_mob.ckey : "*no key*"])" + + WRITE_FILE(F, "[time_stamp(format = "YYYY-MM-DD hh:mm:ss")] [REF(src)] ([x],[y],[z]) || [source] [message]
      ") + +ADMIN_VERB(game, investigate, "Look at various detailed investigate sources", NONE) + var/list/investigates = list( + INVESTIGATE_ACCESSCHANGES, + INVESTIGATE_ATMOS, + INVESTIGATE_BOTANY, + INVESTIGATE_CARGO, + INVESTIGATE_CRAFTING, + INVESTIGATE_DEATHS, + INVESTIGATE_ENGINE, + INVESTIGATE_EXPERIMENTOR, + INVESTIGATE_GRAVITY, + INVESTIGATE_HALLUCINATIONS, + INVESTIGATE_HYPERTORUS, + INVESTIGATE_PORTAL, + INVESTIGATE_PRESENTS, + INVESTIGATE_RADIATION, + INVESTIGATE_RECORDS, + INVESTIGATE_RESEARCH, + INVESTIGATE_WIRES, + ) + + var/list/logs_present = list("notes, memos, watchlist") + var/list/logs_missing = list("---") + + for(var/subject in investigates) + var/temp_file = file("[GLOB.log_directory]/[subject].html") + if(fexists(temp_file)) + logs_present += subject + else + logs_missing += "[subject] (empty)" + + var/list/combined = sort_list(logs_present) + sort_list(logs_missing) + + var/selected = tgui_input_list(usr, "Investigate what?", "Investigation", combined) + if(isnull(selected)) + return + if(!(selected in combined) || selected == "---") + return + + selected = replacetext(selected, " (empty)", "") + + if(selected == "notes, memos, watchlist" && check_rights(R_ADMIN)) + browse_messages() + return + + var/F = file("[GLOB.log_directory]/[selected].html") + if(!fexists(F)) + to_chat(usr, span_danger("No [selected] logfile was found."), confidential = TRUE) + return + usr << browse(F,"window=investigate[selected];size=800x300") diff --git a/code/modules/fishing/admin.dm b/code/modules/admin_verbs/fishing_calculator.dm similarity index 91% rename from code/modules/fishing/admin.dm rename to code/modules/admin_verbs/fishing_calculator.dm index ad97ab890b4..e4011df8a61 100644 --- a/code/modules/fishing/admin.dm +++ b/code/modules/admin_verbs/fishing_calculator.dm @@ -1,10 +1,4 @@ -// Helper tool to see fishing probabilities with different setups -/datum/admins/proc/fishing_calculator() - set name = "Fishing Calculator" - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(debug, fishing_calculator, "Helper tool to see fishing probabilities with different setups", R_DEBUG) var/datum/fishing_calculator/ui = new(usr) ui.ui_interact(usr) diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin_verbs/vv_admin_verb.dm similarity index 82% rename from code/modules/admin/view_variables/view_variables.dm rename to code/modules/admin_verbs/vv_admin_verb.dm index 2db59be5b38..af3c04d9a43 100644 --- a/code/modules/admin/view_variables/view_variables.dm +++ b/code/modules/admin_verbs/vv_admin_verb.dm @@ -1,61 +1,61 @@ -/client/proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world +ADMIN_CONTEXT_ENTRY(contextcmd_vv, "View Variables", NONE, datum/target in world) + SSadmin_verbs.dynamic_invoke_admin_verb(src, /mob/admin_module_holder/debug/view_variables, target) + +ADMIN_VERB(debug, view_variables, "View a list of all vars on most datums aswell as provide additional functions via a dropdown", NONE, selected as anything) var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round. - if(!usr.client || !usr.client.holder) //This is usr because admins can call the proc on other clients, even if they're not admins, to show them VVs. - to_chat(usr, span_danger("You need to be an administrator to access this."), confidential = TRUE) - return - - if(!D) + var/datum/target = selected + if(!target) return var/datum/asset/asset_cache_datum = get_asset_datum(/datum/asset/simple/vv) asset_cache_datum.send(usr) - var/islist = islist(D) - if(!islist && !istype(D)) + var/islist = islist(target) + if(!islist && !istype(target)) return var/title = "" - var/refid = REF(D) + var/refid = REF(target) var/icon/sprite var/hash - var/type = islist? /list : D.type + var/type = islist? /list : target.type var/no_icon = FALSE - if(istype(D, /atom)) - sprite = getFlatIcon(D) + if(istype(target, /atom)) + sprite = getFlatIcon(target) if(sprite) hash = md5(sprite) - src << browse_rsc(sprite, "vv[hash].png") + usr.client << browse_rsc(sprite, "vv[hash].png") else no_icon = TRUE - title = "[D] ([REF(D)]) = [type]" + title = "[target] ([REF(target)]) = [type]" var/formatted_type = replacetext("[type]", "/", "/") var/sprite_text if(sprite) sprite_text = no_icon? "\[NO ICON\]" : "" - var/list/header = islist(D)? list("/list") : D.vv_get_header() + var/list/header = islist(target)? list("/list") : target.vv_get_header() var/ref_line = "@[copytext(refid, 2, -1)]" // get rid of the brackets, add a @ prefix for copy pasting in asay + var/datum/admins/holder = usr.client.holder var/marked_line - if(holder && holder.marked_datum && holder.marked_datum == D) + if(holder && holder.marked_datum && holder.marked_datum == target) marked_line = VV_MSG_MARKED + var/tagged_line - if(holder && LAZYFIND(holder.tagged_datums, D)) - var/tag_index = LAZYFIND(holder.tagged_datums, D) + if(holder && LAZYFIND(holder.tagged_datums, target)) + var/tag_index = LAZYFIND(holder.tagged_datums, target) tagged_line = VV_MSG_TAGGED(tag_index) + var/varedited_line - if(!islist && (D.datum_flags & DF_VAR_EDITED)) + if(!islist && (target.datum_flags & DF_VAR_EDITED)) varedited_line = VV_MSG_EDITED var/deleted_line - if(!islist && D.gc_destroyed) + if(!islist && target.gc_destroyed) deleted_line = VV_MSG_DELETED var/list/dropdownoptions @@ -75,17 +75,17 @@ var/link = dropdownoptions[name] dropdownoptions[i] = "" else - dropdownoptions = D.vv_get_dropdown() + dropdownoptions = target.vv_get_dropdown() var/list/names = list() if(!islist) - for(var/V in D.vars) + for(var/V in target.vars) names += V sleep(1 TICKS) var/list/variable_html = list() if(islist) - var/list/L = D + var/list/L = target for(var/i in 1 to L.len) var/key = L[i] var/value @@ -95,8 +95,8 @@ else names = sort_list(names) for(var/V in names) - if(D.can_vv_get(V)) - variable_html += D.vv_get_var(V) + if(target.can_vv_get(V)) + variable_html += target.vv_get_var(V) var/html = {" @@ -272,7 +272,7 @@ datumrefresh=[refid];[HrefToken()]'>Refresh "} - src << browse(html, "window=variables[refid];size=475x650") + usr.client << browse(html, "window=variables[refid];size=475x650") -/client/proc/vv_update_display(datum/D, span, content) - src << output("[span]:[content]", "variables[REF(D)].browser:replace_span") +/client/proc/vv_update_display(datum/target, span, content) + src << output("[span]:[content]", "variables[REF(target)].browser:replace_span") diff --git a/code/modules/antagonists/traitor/balance_helper.dm b/code/modules/antagonists/traitor/balance_helper.dm index e78625ff1c1..58d834318cf 100644 --- a/code/modules/antagonists/traitor/balance_helper.dm +++ b/code/modules/antagonists/traitor/balance_helper.dm @@ -1,10 +1,4 @@ -/client/proc/cmd_admin_debug_traitor_objectives() - set name = "Debug Traitor Objectives" - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return - +ADMIN_VERB(debug, debug_traitor_objectives, "", R_DEBUG) SStraitor.traitor_debug_panel?.ui_interact(usr) /datum/traitor_objective_debug diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index c86215547c3..3dbb0b17a6a 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -220,6 +220,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( GLOB.clients += src GLOB.directory[ckey] = src + var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]" // Instantiate stat panel stat_panel = new(src, "statbrowser") @@ -232,30 +233,21 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( set_right_click_menu_mode(TRUE) + /// Used for assigning admin verb datums, and so it needs to be up here + var/reconnecting = FALSE + if(GLOB.player_details[ckey]) + reconnecting = TRUE + player_details = GLOB.player_details[ckey] + player_details.byond_version = full_version + else + player_details = new(ckey) + player_details.byond_version = full_version + GLOB.player_details[ckey] = player_details + GLOB.ahelp_tickets.ClientLogin(src) GLOB.interviews.client_login(src) GLOB.requests.client_login(src) - var/connecting_admin = FALSE //because de-admined admins connecting should be treated like admins. - //Admin Authorisation - var/datum/admins/admin_datum = GLOB.admin_datums[ckey] - if (!isnull(admin_datum)) - admin_datum.associate(src) - connecting_admin = TRUE - else if(GLOB.deadmins[ckey]) - add_verb(src, /client/proc/readmin) - connecting_admin = TRUE - if(CONFIG_GET(flag/autoadmin)) - if(!GLOB.admin_datums[ckey]) - var/list/autoadmin_ranks = ranks_from_rank_name(CONFIG_GET(string/autoadmin_rank)) - if (autoadmin_ranks.len == 0) - to_chat(world, "Autoadmin rank not found") - else - new /datum/admins(autoadmin_ranks, ckey) - if(CONFIG_GET(flag/enable_localhost_rank) && !connecting_admin) - var/localhost_addresses = list("127.0.0.1", "::1") - if(isnull(address) || (address in localhost_addresses)) - var/datum/admin_rank/localhost_rank = new("!localhost!", R_EVERYTHING, R_DBRANKS, R_EVERYTHING) //+EVERYTHING -DBRANKS *EVERYTHING - new /datum/admins(list(localhost_rank), ckey, 1, 1) + //preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum) prefs = GLOB.preferences_datums[ckey] if(prefs) @@ -273,7 +265,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(fexists("data/server_last_roundend_report.html")) add_verb(src, /client/proc/show_servers_last_roundend_report) - var/full_version = "[byond_version].[byond_build ? byond_build : "xxx"]" log_access("Login: [key_name(src)] from [address ? address : "localhost"]-[computer_id] || BYOND v[full_version]") var/alert_mob_dupe_login = FALSE @@ -315,18 +306,31 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( else message_admins(span_danger("[message_type]: Connecting player [key_name_admin(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round]. ")) log_admin_private("[message_type]: Connecting player [key_name(src)] has the same [matches] as [joined_player_ckey](no longer logged in)[in_round].") - var/reconnecting = FALSE - if(GLOB.player_details[ckey]) - reconnecting = TRUE - player_details = GLOB.player_details[ckey] - player_details.byond_version = full_version - else - player_details = new(ckey) - player_details.byond_version = full_version - GLOB.player_details[ckey] = player_details - . = ..() //calls mob.Login() + + var/connecting_admin = FALSE //because de-admined admins connecting should be treated like admins. + //Admin Authorisation + var/datum/admins/admin_datum = GLOB.admin_datums[ckey] + if (!isnull(admin_datum)) + admin_datum.associate(src) + connecting_admin = TRUE + else if(GLOB.deadmins[ckey]) + add_verb(src, /client/proc/readmin) + connecting_admin = TRUE + if(CONFIG_GET(flag/autoadmin)) + if(!GLOB.admin_datums[ckey]) + var/list/autoadmin_ranks = ranks_from_rank_name(CONFIG_GET(string/autoadmin_rank)) + if (autoadmin_ranks.len == 0) + to_chat(world, "Autoadmin rank not found") + else + new /datum/admins(autoadmin_ranks, ckey) + if(CONFIG_GET(flag/enable_localhost_rank) && !connecting_admin) + var/localhost_addresses = list("127.0.0.1", "::1") + if(isnull(address) || (address in localhost_addresses)) + var/datum/admin_rank/localhost_rank = new("!localhost!", R_EVERYTHING, R_DBRANKS, R_EVERYTHING) //+EVERYTHING -DBRANKS *EVERYTHING + new /datum/admins(list(localhost_rank), ckey, 1, 1) + if (length(GLOB.stickybanadminexemptions)) GLOB.stickybanadminexemptions -= ckey if (!length(GLOB.stickybanadminexemptions)) @@ -1240,13 +1244,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( /// Attempts to make the client orbit the given object, for administrative purposes. /// If they are not an observer, will try to aghost them. /client/proc/admin_follow(atom/movable/target) - var/can_ghost = TRUE - if (!isobserver(mob)) - can_ghost = admin_ghost() - - if(!can_ghost) - return FALSE + SSadmin_verbs.dynamic_invoke_admin_verb(src, /mob/admin_module_holder/game/aghost) + if(!isobserver(mob)) + return // lacked permissions required to aghost var/mob/dead/observer/observer = mob observer.ManualFollow(target) diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm index 7358cc9cee3..bbd4ebddc1b 100644 --- a/code/modules/client/player_details.dm +++ b/code/modules/client/player_details.dm @@ -5,7 +5,9 @@ GLOBAL_LIST_EMPTY(player_details) /datum/player_details var/list/player_actions = list() var/list/logging = list() + /// List of login callbacks, will be passed the mob as the first argument var/list/post_login_callbacks = list() + /// List of logout callbacks, will be passed the mob as the first argument var/list/post_logout_callbacks = list() var/list/played_names = list() //List of names this key played under this round var/byond_version = "Unknown" @@ -14,6 +16,14 @@ GLOBAL_LIST_EMPTY(player_details) /datum/player_details/New(key) achievements = new(key) +/datum/player_details/proc/do_login(mob/mob) + for(var/datum/callback/callback as anything in post_login_callbacks) + callback.Invoke(mob) + +/datum/player_details/proc/do_logout(mob/mob) + for(var/datum/callback/callback as anything in post_logout_callbacks) + callback.Invoke(mob) + /proc/log_played_names(ckey, ...) if(!ckey) return diff --git a/code/modules/client/preferences/middleware/legacy_toggles.dm b/code/modules/client/preferences/middleware/legacy_toggles.dm index 926f2687903..beecf5dfdda 100644 --- a/code/modules/client/preferences/middleware/legacy_toggles.dm +++ b/code/modules/client/preferences/middleware/legacy_toggles.dm @@ -21,7 +21,6 @@ "member_public" = MEMBER_PUBLIC, "sound_adminhelp" = SOUND_ADMINHELP, "sound_prayers" = SOUND_PRAYERS, - "split_admin_tabs" = SPLIT_ADMIN_TABS, ) var/list/legacy_chat_toggles = list( @@ -54,7 +53,6 @@ "deadmin_position_silicon", "sound_adminhelp", "sound_prayers", - "split_admin_tabs", ) var/static/list/admin_only_chat_toggles = list( diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index dfbe0479d77..dc9796f7ceb 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -127,38 +127,18 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") else GLOB.dooc_allowed = !GLOB.dooc_allowed - -/client/proc/set_ooc() - set name = "Set Player OOC Color" - set desc = "Modifies player OOC Color" - set category = "Server" - if(IsAdminAdvancedProcCall()) - return +ADMIN_VERB(server, set_player_ooc_color, "Set the default OOC color", (R_FUN|R_ADMIN)) var/newColor = input(src, "Please select the new player OOC color.", "OOC color") as color|null if(isnull(newColor)) return - if(!check_rights(R_FUN)) - message_admins("[usr.key] has attempted to use the Set Player OOC Color verb!") - log_admin("[key_name(usr)] tried to set player ooc color without authorization.") - return var/new_color = sanitize_color(newColor) message_admins("[key_name_admin(usr)] has set the players' ooc color to [new_color].") log_admin("[key_name_admin(usr)] has set the player ooc color to [new_color].") GLOB.OOC_COLOR = new_color - -/client/proc/reset_ooc() - set name = "Reset Player OOC Color" - set desc = "Returns player OOC Color to default" - set category = "Server" - if(IsAdminAdvancedProcCall()) - return +ADMIN_VERB(server, reset_player_ooc_color, "Returns all player colors to default", (R_FUN|R_ADMIN)) if(tgui_alert(usr, "Are you sure you want to reset the OOC color of all players?", "Reset Player OOC Color", list("Yes", "No")) != "Yes") return - if(!check_rights(R_FUN)) - message_admins("[usr.key] has attempted to use the Reset Player OOC Color verb!") - log_admin("[key_name(usr)] tried to reset player ooc color without authorization.") - return message_admins("[key_name_admin(usr)] has reset the players' ooc color.") log_admin("[key_name_admin(usr)] has reset player ooc color.") GLOB.OOC_COLOR = null diff --git a/code/modules/error_handler/error_viewer.dm b/code/modules/error_handler/error_viewer.dm index fbaa0ca3fae..0f33159aa0e 100644 --- a/code/modules/error_handler/error_viewer.dm +++ b/code/modules/error_handler/error_viewer.dm @@ -79,6 +79,7 @@ GLOBAL_DATUM(error_cache, /datum/error_viewer/error_cache) var/list/errors_silenced = list() /datum/error_viewer/error_cache/show_to(user, datum/error_viewer/back_to, linear) + user = CLIENT_FROM_VAR(user) var/html = build_header() html += "[GLOB.total_runtimes] runtimes, [GLOB.total_runtimes_skipped] skipped

      " if (!linear) diff --git a/code/modules/explorer_drone/manager.dm b/code/modules/explorer_drone/manager.dm index 74a972216a4..80e710bcde5 100644 --- a/code/modules/explorer_drone/manager.dm +++ b/code/modules/explorer_drone/manager.dm @@ -141,11 +141,6 @@ . = ..() QDEL_NULL(temp_adventure) -/client/proc/adventure_manager() - set category = "Debug" - set name = "Adventure Manager" - - if(!check_rights(R_DEBUG)) - return +ADMIN_VERB(debug, adventure_manager, "", R_DEBUG) var/datum/adventure_browser/browser = new() browser.ui_interact(usr) diff --git a/code/modules/mob/dead/observer/observer_say.dm b/code/modules/mob/dead/observer/observer_say.dm index 522e250204f..6943c89d0dd 100644 --- a/code/modules/mob/dead/observer/observer_say.dm +++ b/code/modules/mob/dead/observer/observer_say.dm @@ -33,9 +33,9 @@ message = trim_left(copytext_char(message, length(message_mods[RADIO_KEY]) + 2)) switch(message_mods[RADIO_EXTENSION]) if(MODE_ADMIN) - client.cmd_admin_say(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/admin/admin_say, message) if(MODE_DEADMIN) - client.dsay(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/game/dead_say, message) if(MODE_PUPPET) if(!mind.current.say(message)) to_chat(src, span_warning("Your linked body was unable to speak!")) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 621203a2d4a..7eaaa330847 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1103,9 +1103,7 @@ return usr.client.holder.Topic("vv_override", list("makeai"=href_list[VV_HK_TARGET])) if(href_list[VV_HK_MODIFY_ORGANS]) - if(!check_rights(NONE)) - return - usr.client.manipulate_organs(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/debug/manipulate_organs, src) if(href_list[VV_HK_MARTIAL_ART]) if(!check_rights(NONE)) return diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index cd128de28f2..e563b43cc2b 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -111,11 +111,11 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( return if(message_mods[RADIO_EXTENSION] == MODE_ADMIN) - client?.cmd_admin_say(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/admin/admin_say, message) return if(message_mods[RADIO_EXTENSION] == MODE_DEADMIN) - client?.dsay(message) + SSadmin_verbs.dynamic_invoke_admin_verb(client, /mob/admin_module_holder/game/dead_say, message) return // dead is the only state you can never emote diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index cda4e179fcc..6aad91eca02 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -103,9 +103,7 @@ for(var/datum/action/A in client.player_details.player_actions) A.Grant(src) - for(var/foo in client.player_details.post_login_callbacks) - var/datum/callback/CB = foo - CB.Invoke() + client.player_details.do_login(src) log_played_names(client.ckey,name,real_name) auto_deadmin_on_login() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 713990af438..48ef3c660e6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1257,54 +1257,47 @@ if(!check_rights(NONE)) return regenerate_icons() + if(href_list[VV_HK_PLAYER_PANEL]) - if(!check_rights(NONE)) - return - usr.client.holder.show_player_panel(src) + usr.client.admin_context_wrapper_context_player_panel(src) + if(href_list[VV_HK_GODMODE]) - if(!check_rights(R_ADMIN)) - return - usr.client.cmd_admin_godmode(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/toggle_godmode, src) + if(href_list[VV_HK_GIVE_SPELL]) - if(!check_rights(NONE)) - return - usr.client.give_spell(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/fun/give_mob_spell, src) + if(href_list[VV_HK_REMOVE_SPELL]) - if(!check_rights(NONE)) - return - usr.client.remove_spell(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/fun/remove_spell, src) + if(href_list[VV_HK_GIVE_DISEASE]) - if(!check_rights(NONE)) - return - usr.client.give_disease(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/fun/give_disease, src) + if(href_list[VV_HK_GIB]) - if(!check_rights(R_FUN)) - return - usr.client.cmd_admin_gib(src) + usr.client.admin_context_wrapper_context_mob_gib(src) + if(href_list[VV_HK_BUILDMODE]) if(!check_rights(R_BUILD)) return togglebuildmode(src) + if(href_list[VV_HK_DROP_ALL]) - if(!check_rights(NONE)) - return - usr.client.cmd_admin_drop_everything(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/admin/drop_everything, src) + if(href_list[VV_HK_DIRECT_CONTROL]) - if(!check_rights(NONE)) - return - usr.client.cmd_assume_direct_control(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/assume_direct_control, src) + if(href_list[VV_HK_GIVE_DIRECT_CONTROL]) - if(!check_rights(NONE)) - return - usr.client.cmd_give_direct_control(src) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/give_direct_control, src) + if(href_list[VV_HK_OFFER_GHOSTS]) if(!check_rights(NONE)) return offer_control(src) + if(href_list[VV_HK_VIEW_PLANES]) - if(!check_rights(R_DEBUG)) - return - usr.client.edit_plane_masters(src) + usr.client.holder.edit_plane_masters(src) + /** * extra var handling for the logging var */ @@ -1406,10 +1399,7 @@ if(!canon_client) return - for(var/foo in canon_client.player_details.post_logout_callbacks) - var/datum/callback/CB = foo - CB.Invoke() - + canon_client.player_details.do_logout(src) if(canon_client?.movingmob) LAZYREMOVE(canon_client.movingmob.client_mobs_in_contents, src) canon_client.movingmob = null diff --git a/code/modules/procedural_mapping/mapGenerator.dm b/code/modules/procedural_mapping/mapGenerator.dm index faecf0a92b7..462cc1a9ac2 100644 --- a/code/modules/procedural_mapping/mapGenerator.dm +++ b/code/modules/procedural_mapping/mapGenerator.dm @@ -141,40 +141,37 @@ // HERE BE DEBUG DRAGONS // /////////////////////////// -/client/proc/debugNatureMapGenerator() - set name = "Test Nature Map Generator" - set category = "Debug" - +ADMIN_VERB(debug, test_nature_map_generator, "", R_DEBUG) var/datum/map_generator/nature/N = new() var/startInput = input(usr,"Start turf of Map, (X;Y;Z)", "Map Gen Settings", "1;1;1") as text|null if (isnull(startInput)) return - var/endInput = input(usr,"End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[mob ? mob.z : 1]") as text|null + var/endInput = input(usr,"End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[usr.z]") as text|null if (isnull(endInput)) return //maxx maxy and current z so that if you fuck up, you only fuck up one entire z level instead of the entire universe if(!startInput || !endInput) - to_chat(src, "Missing Input") + to_chat(usr, "Missing Input") return var/list/startCoords = splittext(startInput, ";") var/list/endCoords = splittext(endInput, ";") if(!startCoords || !endCoords) - to_chat(src, "Invalid Coords") - to_chat(src, "Start Input: [startInput]") - to_chat(src, "End Input: [endInput]") + to_chat(usr, "Invalid Coords") + to_chat(usr, "Start Input: [startInput]") + to_chat(usr, "End Input: [endInput]") return var/turf/Start = locate(text2num(startCoords[1]),text2num(startCoords[2]),text2num(startCoords[3])) var/turf/End = locate(text2num(endCoords[1]),text2num(endCoords[2]),text2num(endCoords[3])) if(!Start || !End) - to_chat(src, "Invalid Turfs") - to_chat(src, "Start Coords: [startCoords[1]] - [startCoords[2]] - [startCoords[3]]") - to_chat(src, "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]") + to_chat(usr, "Invalid Turfs") + to_chat(usr, "Start Coords: [startCoords[1]] - [startCoords[2]] - [startCoords[3]]") + to_chat(usr, "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]") return var/list/clusters = list("None"=CLUSTER_CHECK_NONE,"All"=CLUSTER_CHECK_ALL,"Sames"=CLUSTER_CHECK_SAMES,"Differents"=CLUSTER_CHECK_DIFFERENTS, \ @@ -187,7 +184,7 @@ var/theCluster = 0 if(moduleClusters != "None") if(!clusters[moduleClusters]) - to_chat(src, "Invalid Cluster Flags") + to_chat(usr, "Invalid Cluster Flags") return theCluster = clusters[moduleClusters] else @@ -198,9 +195,9 @@ M.clusterCheckFlags = theCluster - to_chat(src, "Defining Region") + to_chat(usr, "Defining Region") N.defineRegion(Start, End) - to_chat(src, "Region Defined") - to_chat(src, "Generating Region") + to_chat(usr, "Region Defined") + to_chat(usr, "Generating Region") N.generate() - to_chat(src, "Generated Region") + to_chat(usr, "Generated Region") diff --git a/code/modules/reagents/chemistry/chem_wiki_render.dm b/code/modules/reagents/chemistry/chem_wiki_render.dm index a2ac0af8ffb..5f0eeefee20 100644 --- a/code/modules/reagents/chemistry/chem_wiki_render.dm +++ b/code/modules/reagents/chemistry/chem_wiki_render.dm @@ -1,8 +1,5 @@ //Generates a wikitable txt file for use with the wiki - does not support productless reactions at the moment -/client/proc/generate_wikichem_list() - set category = "Debug" - set name = "Parse Wikichems" - +ADMIN_VERB(debug, generate_wikichem_list, "Generate a wikichem list for the wiki", R_DEBUG) //If we're a reaction product var/prefix_reaction = {"{| class=\"wikitable sortable\" style=\"width:100%; text-align:left; border: 3px solid #FFDD66; cellspacing=0; cellpadding=2; background-color:white;\" ! scope=\"col\" style='width:150px; background-color:#FFDD66;'|Name diff --git a/code/modules/requests/request_manager.dm b/code/modules/requests/request_manager.dm index fef7e9fb0dd..a24202f9c3f 100644 --- a/code/modules/requests/request_manager.dm +++ b/code/modules/requests/request_manager.dm @@ -150,21 +150,22 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new) switch(action) if ("pp") - var/mob/M = request.owner?.mob - usr.client.holder.show_player_panel(M) + usr.client.admin_context_wrapper_context_player_panel(request.owner?.mob) return TRUE + if ("vv") - var/mob/M = request.owner?.mob - usr.client.debug_variables(M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, request.owner?.mob) return TRUE + if ("sm") - var/mob/M = request.owner?.mob - usr.client.cmd_admin_subtle_message(M) + usr.client.admin_context_wrapper_context_subtle_message(request.owner?.mob) return TRUE + if ("flw") var/mob/M = request.owner?.mob usr.client.admin_follow(M) return TRUE + if ("tp") if(!SSticker.HasRoundStarted()) tgui_alert(usr,"The game hasn't started yet!") @@ -179,8 +180,9 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new) D.traitor_panel() return TRUE else - usr.client.holder.show_traitor_panel(M) + SSadmin_verbs.dynamic_invoke_admin_verb(usr, /mob/admin_module_holder/game/traitor_panel, M) return TRUE + if ("logs") var/mob/M = request.owner?.mob if(!ismob(M)) @@ -188,6 +190,7 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new) return TRUE show_individual_logging_panel(M, null, null) return TRUE + if ("smite") if(!check_rights(R_FUN)) to_chat(usr, "Insufficient permissions to smite, you require +FUN", confidential = TRUE) @@ -196,15 +199,17 @@ GLOBAL_DATUM_INIT(requests, /datum/request_manager, new) if (!H || !istype(H)) to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human", confidential = TRUE) return TRUE - usr.client.smite(H) + usr.client.admin_context_wrapper_context_smite(H) return TRUE + if ("rply") if (request.req_type == REQUEST_PRAYER) to_chat(usr, "Cannot reply to a prayer", confidential = TRUE) return TRUE var/mob/M = request.owner?.mob - usr.client.admin_headset_message(M, request.req_type == REQUEST_SYNDICATE ? RADIO_CHANNEL_SYNDICATE : RADIO_CHANNEL_CENTCOM) + usr.client.admin_context_wrapper_contexxt_headset_message(M, request.req_type == REQUEST_SYNDICATE ? RADIO_CHANNEL_SYNDICATE : RADIO_CHANNEL_CENTCOM) return TRUE + if ("setcode") if (request.req_type != REQUEST_NUKE) to_chat(usr, "You cannot set the nuke code for a non-nuke-code-request request!", confidential = TRUE) diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm index 07a91f6f727..b3b83bc2bfa 100644 --- a/code/modules/unit_tests/create_and_destroy.dm +++ b/code/modules/unit_tests/create_and_destroy.dm @@ -30,6 +30,8 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE) /obj/merge_conflict_marker, //briefcase launchpads erroring /obj/machinery/launchpad/briefcase, + //Shouldn't be created + /mob/admin_module_holder, //Both are abstract types meant to scream bloody murder if spawned in raw /obj/item/organ/external, /obj/item/organ/external/wings, diff --git a/code/modules/unit_tests/mob_faction.dm b/code/modules/unit_tests/mob_faction.dm index 359ec40f66f..e17fab331f0 100644 --- a/code/modules/unit_tests/mob_faction.dm +++ b/code/modules/unit_tests/mob_faction.dm @@ -6,7 +6,8 @@ var/list/ignored = list( /mob/living/carbon, /mob/dview, - /mob/oranges_ear + /mob/oranges_ear, + /mob/admin_module_holder, ) ignored += typesof(/mob/camera/imaginary_friend) ignored += typesof(/mob/living/simple_animal/pet/gondola/gondolapod) diff --git a/code/modules/wiremod/core/admin_panel.dm b/code/modules/wiremod/core/admin_panel.dm index 74e72ad5efe..6a679f71bef 100644 --- a/code/modules/wiremod/core/admin_panel.dm +++ b/code/modules/wiremod/core/admin_panel.dm @@ -63,12 +63,12 @@ if ("save_circuit") circuit.attempt_save_to(usr.client) if ("vv_circuit") - usr.client?.debug_variables(circuit) + SSadmin_verbs.dynamic_invoke_admin_verb(usr.client, /mob/admin_module_holder/debug/view_variables, circuit) if ("open_circuit") circuit.ui_interact(usr) if ("open_player_panel") var/datum/mind/inserter = circuit.inserter_mind?.resolve() - usr.client?.holder?.show_player_panel(inserter?.current) + usr.client?.admin_context_wrapper_context_player_panel(inserter?.current) return TRUE diff --git a/code/modules/wiremod/core/duplicator.dm b/code/modules/wiremod/core/duplicator.dm index a784f4030bc..28c9aed9e53 100644 --- a/code/modules/wiremod/core/duplicator.dm +++ b/code/modules/wiremod/core/duplicator.dm @@ -217,13 +217,7 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( rel_x = component_data["rel_x"] rel_y = component_data["rel_y"] -/client/proc/load_circuit() - set name = "Load Circuit" - set category = "Admin.Fun" - - if(!check_rights(R_VAREDIT)) - return - +ADMIN_VERB(fun, load_circuit, "", R_VAREDIT) var/list/errors = list() var/option = alert(usr, "Load by file or direct input?", "Load by file or string", "File", "Direct Input") @@ -237,10 +231,10 @@ GLOBAL_LIST_INIT(circuit_dupe_whitelisted_types, list( if(!txt) return - var/obj/item/integrated_circuit/loaded/circuit = new(mob.drop_location()) + var/obj/item/integrated_circuit/loaded/circuit = new(usr.drop_location()) circuit.load_circuit_data(txt, errors) if(length(errors)) - to_chat(src, span_warning("The following errors were found whilst compiling the circuit data:")) + to_chat(usr, span_warning("The following errors were found whilst compiling the circuit data:")) for(var/error in errors) - to_chat(src, span_warning(error)) + to_chat(usr, span_warning(error)) diff --git a/html/statbrowser.js b/html/statbrowser.js index 0d89487af5b..87fe69fc282 100644 --- a/html/statbrowser.js +++ b/html/statbrowser.js @@ -18,6 +18,7 @@ if (!String.prototype.trim) { var status_tab_parts = ["Loading..."]; var current_tab = null; var mc_tab_parts = [["Loading...", ""]]; +var admin_verb_cats = []; var href_token = null; var spells = []; var spell_tabs = []; @@ -35,7 +36,6 @@ var menu = document.getElementById('menu'); var under_menu = document.getElementById('under_menu'); var statcontentdiv = document.getElementById('statcontent'); var storedimages = []; -var split_admin_tabs = false; // Any BYOND commands that could result in the client's focus changing go through this // to ensure that when we relinquish our focus, we don't do it after the result of @@ -47,10 +47,7 @@ function run_after_focus(callback) { function createStatusTab(name) { if (name.indexOf(".") != -1) { var splitName = name.split("."); - if (split_admin_tabs && splitName[0] === "Admin") - name = splitName[1]; - else - name = splitName[0]; + name = splitName[0]; } if (document.getElementById(name) || name.trim() == "") { return; @@ -68,6 +65,17 @@ function createStatusTab(name) { B.className = "button"; //ORDERING ALPHABETICALLY B.style.order = name.charCodeAt(0); + switch (name) { + case "Status": + B.style.order = 1; + break; + case "MC": + B.style.order = 2; + break; + case "Admin Verbs": + B.style.order = 3; + break; + } if (name == "Status" || name == "MC") { B.style.order = name == "Status" ? 1 : 2; } @@ -152,10 +160,7 @@ function verbs_cat_check(cat) { var tabCat = cat; if (cat.indexOf(".") != -1) { var splitName = cat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") - tabCat = splitName[1]; - else - tabCat = splitName[0]; + tabCat = splitName[0]; } var verbs_in_cat = 0; var verbcat = ""; @@ -168,10 +173,7 @@ function verbs_cat_check(cat) { verbcat = part[0]; if (verbcat.indexOf(".") != -1) { var splitName = verbcat.split("."); - if (split_admin_tabs && splitName[0] === "Admin") - verbcat = splitName[1]; - else - verbcat = splitName[0]; + verbcat = splitName[0]; } if (verbcat != tabCat || verbcat.trim() == "") { continue; @@ -252,6 +254,8 @@ function tab_change(tab) { draw_status(); } else if (tab == "MC") { draw_mc(); + } else if (tab == "Admin Verbs") { + draw_admin_verbs(); } else if (spell_tabs_thingy) { draw_spells(tab); } else if (verb_tabs_thingy) { @@ -297,13 +301,9 @@ function draw_debug() { var table1 = document.createElement("table"); for (var i = 0; i < verb_tabs.length; i++) { var part = verb_tabs[i]; - // Hide subgroups except admin subgroups if they are split + // Hide subgroups if (verb_tabs[i].lastIndexOf(".") != -1) { - var splitName = verb_tabs[i].split("."); - if (split_admin_tabs && splitName[0] === "Admin") - part = splitName[1]; - else - continue; + continue; } var tr = document.createElement("tr"); var td1 = document.createElement("td"); @@ -393,6 +393,47 @@ function draw_mc() { document.getElementById("statcontent").appendChild(table); } +function draw_admin_verbs() { + try { + statcontentdiv.textContent = ""; + var categories = Object.keys(admin_verb_cats); + for(var i = 0; i < categories.length; i++) { + var category = categories[i]; + var categoryHeader = document.createElement("h3"); + categoryHeader.textContent = category; + + var verbList = admin_verb_cats[category]; + var categoryTable = document.createElement("div"); + categoryTable.className = "grid-container"; + var verbIdx = 0; + + for(var l = 0; l < verbList.length; l++) { + var verbInfo = verbList[l]; + + var verbName = verbInfo[0]; + var verbDesc = verbInfo[1]; + var verbRef = verbInfo[2]; + + var verbEntry = document.createElement("a"); + verbEntry.onclick = make_verb_onclick(verbRef) + verbEntry.className = "grid-item"; + verbEntry.title = verbDesc; + + var verbTitle = document.createElement("span"); + verbTitle.textContent = verbName; + verbTitle.className = "grid-item-text"; + + verbEntry.appendChild(verbTitle); + categoryTable.appendChild(verbEntry); + } + statcontentdiv.appendChild(categoryHeader); + statcontentdiv.appendChild(categoryTable); + } + } catch(except) { + statcontentdiv.textContent = "NTOS Exception: " + except + "\nReport this to your nearest Technical Resolution Specialist" + } +} + function remove_tickets() { if (tickets) { tickets = []; @@ -510,6 +551,13 @@ function remove_mc() { } }; +function remove_admin_verbs() { + removePermanentTab("Admin Verbs"); + if(current_tab == "Admin Verbs") { + tab_change("Status"); + } +} + function draw_sdql2() { statcontentdiv.textContent = ""; var table = document.createElement("table"); @@ -655,20 +703,10 @@ function draw_verbs(cat) { var additions = {}; // additional sub-categories to be rendered table.className = "grid-container"; sortVerbs(); - if (split_admin_tabs && cat.lastIndexOf(".") != -1) { - var splitName = cat.split("."); - if (splitName[0] === "Admin") - cat = splitName[1]; - } verbs.reverse(); // sort verbs backwards before we draw for (var i = 0; i < verbs.length; ++i) { var part = verbs[i]; var name = part[0]; - if (split_admin_tabs && name.lastIndexOf(".") != -1) { - var splitName = name.split("."); - if (splitName[0] === "Admin") - name = splitName[1]; - } var command = part[1]; if (command && name.lastIndexOf(cat, 0) != -1 && (name.length == cat.length || name.charAt(cat.length) == ".")) { @@ -763,10 +801,7 @@ function add_verb_list(payload) { var category = part[0]; if (category.indexOf(".") != -1) { var splitName = category.split("."); - if (split_admin_tabs && splitName[0] === "Admin") - category = splitName[1]; - else - category = splitName[0]; + category = splitName[0]; } if (findVerbindex(part[1], verbs)) continue; @@ -892,6 +927,23 @@ Byond.subscribeTo('update_mc', function (payload) { } }); +Byond.subscribeTo('update_admin_verbs', function(payload) { + admin_verb_cats = payload; + + if(!verb_tabs.includes("Admin Verbs")) { + addPermanentTab("Admin Verbs") + } + + createStatusTab("Admin Verbs"); + if(current_tab == "Admin Verbs") { + draw_admin_verbs(); + } +}) + +Byond.subscribeTo('remove_admin_verbs', function() { + remove_admin_verbs(); +}) + Byond.subscribeTo('remove_spells', function () { for (var s = 0; s < spell_tabs.length; s++) { removeStatusTab(spell_tabs[s]); @@ -933,6 +985,7 @@ Byond.subscribeTo('create_listedturf', function (TN) { Byond.subscribeTo('remove_admin_tabs', function () { href_token = null; remove_mc(); + remove_admin_verbs(); remove_tickets(); remove_sdql2(); remove_interviews(); @@ -952,20 +1005,6 @@ Byond.subscribeTo('update_interviews', function (I) { } }); -Byond.subscribeTo('update_split_admin_tabs', function (status) { - status = (status == true); - - if (split_admin_tabs !== status) { - if (split_admin_tabs === true) { - removeStatusTab("Events"); - removeStatusTab("Fun"); - removeStatusTab("Game"); - } - update_verbs(); - } - split_admin_tabs = status; -}); - Byond.subscribeTo('add_admin_tabs', function (ht) { href_token = ht; addPermanentTab("MC"); diff --git a/tgstation.dme b/tgstation.dme index 78b6069f9b2..5544b19a67b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -318,6 +318,7 @@ #include "code\__HELPERS\_planes.dm" #include "code\__HELPERS\_string_lists.dm" #include "code\__HELPERS\admin.dm" +#include "code\__HELPERS\admin_verb.dm" #include "code\__HELPERS\ai.dm" #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" @@ -514,6 +515,7 @@ #include "code\controllers\configuration\entries\resources.dm" #include "code\controllers\subsystem\achievements.dm" #include "code\controllers\subsystem\addiction.dm" +#include "code\controllers\subsystem\admin_verbs.dm" #include "code\controllers\subsystem\ai_controllers.dm" #include "code\controllers\subsystem\air.dm" #include "code\controllers\subsystem\ambience.dm" @@ -2203,7 +2205,6 @@ #include "code\modules\admin\admin_pda_message.dm" #include "code\modules\admin\admin_ranks.dm" #include "code\modules\admin\admin_verbs.dm" -#include "code\modules\admin\adminmenu.dm" #include "code\modules\admin\antag_panel.dm" #include "code\modules\admin\chat_commands.dm" #include "code\modules\admin\check_antagonists.dm" @@ -2269,7 +2270,6 @@ #include "code\modules\admin\verbs\adminhelp.dm" #include "code\modules\admin\verbs\adminjump.dm" #include "code\modules\admin\verbs\adminpm.dm" -#include "code\modules\admin\verbs\adminsay.dm" #include "code\modules\admin\verbs\ai_triumvirate.dm" #include "code\modules\admin\verbs\anonymousnames.dm" #include "code\modules\admin\verbs\atmosdebug.dm" @@ -2283,7 +2283,6 @@ #include "code\modules\admin\verbs\debug.dm" #include "code\modules\admin\verbs\diagnostics.dm" #include "code\modules\admin\verbs\ert.dm" -#include "code\modules\admin\verbs\fix_air.dm" #include "code\modules\admin\verbs\fov.dm" #include "code\modules\admin\verbs\fps.dm" #include "code\modules\admin\verbs\getlogs.dm" @@ -2322,16 +2321,18 @@ #include "code\modules\admin\view_variables\debug_variables.dm" #include "code\modules\admin\view_variables\filterrific.dm" #include "code\modules\admin\view_variables\get_variables.dm" -#include "code\modules\admin\view_variables\mark_datum.dm" #include "code\modules\admin\view_variables\mass_edit_variables.dm" #include "code\modules\admin\view_variables\modify_variables.dm" #include "code\modules\admin\view_variables\particle_editor.dm" #include "code\modules\admin\view_variables\reference_tracking.dm" -#include "code\modules\admin\view_variables\tag_datum.dm" #include "code\modules\admin\view_variables\topic.dm" #include "code\modules\admin\view_variables\topic_basic.dm" #include "code\modules\admin\view_variables\topic_list.dm" -#include "code\modules\admin\view_variables\view_variables.dm" +#include "code\modules\admin_verbs\admin_module_holder.dm" +#include "code\modules\admin_verbs\admin_verbs.dm" +#include "code\modules\admin_verbs\default_verbs.dm" +#include "code\modules\admin_verbs\fishing_calculator.dm" +#include "code\modules\admin_verbs\vv_admin_verb.dm" #include "code\modules\antagonists\_common\antag_datum.dm" #include "code\modules\antagonists\_common\antag_helpers.dm" #include "code\modules\antagonists\_common\antag_hud.dm" @@ -3255,7 +3256,6 @@ #include "code\modules\explorer_drone\exploration_events\fluff.dm" #include "code\modules\explorer_drone\exploration_events\resource.dm" #include "code\modules\explorer_drone\exploration_events\trader.dm" -#include "code\modules\fishing\admin.dm" #include "code\modules\fishing\bait.dm" #include "code\modules\fishing\fish_catalog.dm" #include "code\modules\fishing\fishing_equipment.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/legacy_toggles.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/legacy_toggles.tsx index e94eb6c522a..d23540868a1 100644 --- a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/legacy_toggles.tsx +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/legacy_toggles.tsx @@ -95,10 +95,3 @@ export const sound_prayers: FeatureToggle = { category: 'ADMIN', component: CheckboxInput, }; - -export const split_admin_tabs: FeatureToggle = { - name: 'Split admin tabs', - category: 'ADMIN', - description: "When enabled, will split the 'Admin' panel into several tabs.", - component: CheckboxInput, -};