From 2a842644d5860286edfec85b772f32e67eeb7598 Mon Sep 17 00:00:00 2001 From: warriorstar-orion Date: Fri, 12 Dec 2025 14:18:22 -0500 Subject: [PATCH] port ADMIN_VERB and friends (#30646) * port ADMIN_VERB and friends * some renaming * dumb * one more rename * never search and replace this codebase * fix TM issues, more renaming * add a static analysis to shore up user verbs * fix double message on roundstart * remove macro we're not using yet * convert remaining playsounds verbs * convert more verbs i missed somehow * why is this a completely different signature than everything else * fix ui_interact arg * fix logging view and others * buncha issues caught in TM * fix mentor tickets ui * fix bug report viewing * moron --- .github/workflows/ci.yml | 1 + code/__DEFINES/admin_defines.dm | 1 + code/__DEFINES/flags.dm | 1 + code/__DEFINES/subsystems.dm | 35 +- code/__DEFINES/user_verb_defines.dm | 76 ++ code/__HELPERS/lists.dm | 24 +- code/__HELPERS/unique_ids.dm | 11 +- code/_onclick/hud/movable_screen_objects.dm | 20 +- code/_onclick/observer_onclick.dm | 4 +- code/controllers/subsystem/SSblackbox.dm | 2 +- code/controllers/subsystem/SSdbcore.dm | 20 +- code/controllers/subsystem/SSdebugview.dm | 10 +- code/controllers/subsystem/SSgarbage.dm | 25 +- code/controllers/subsystem/SStimer.dm | 22 +- code/controllers/subsystem/SSverb_manager.dm | 12 +- .../subsystem/non_firing/SSatoms.dm | 13 +- .../subsystem/non_firing/SSuser_verbs.dm | 154 +++ .../subsystem/tickets/SStickets.dm | 6 +- code/controllers/verbs.dm | 35 +- code/datums/datumvars.dm | 26 +- code/datums/keybindings/admin_keybinds.dm | 6 +- code/datums/station_traits/admin_panel.dm | 8 +- code/datums/user_verb.dm | 27 + code/datums/vv_core_topics.dm | 8 +- code/game/atom_vv.dm | 10 +- code/game/jobs/job_exp.dm | 11 +- code/game/machinery/computer/ai_core.dm | 14 +- .../game/machinery/computer/communications.dm | 20 +- code/game/objects/explosion.dm | 17 +- code/game/verbs/who.dm | 2 +- code/modules/admin/admin_investigate.dm | 11 +- code/modules/admin/admin_memo.dm | 12 +- code/modules/admin/admin_verbs.dm | 994 ++++-------------- code/modules/admin/centcom_ban_db.dm | 14 +- code/modules/admin/holder2.dm | 4 +- code/modules/admin/machine_upgrade.dm | 15 +- code/modules/admin/menus/antagonist_menu.dm | 4 +- code/modules/admin/misc_admin_procs.dm | 310 ++---- code/modules/admin/outfits.dm | 9 +- .../admin/permissionverbs/permissionedit.dm | 11 +- .../admin/tickets/adminticketsverbs.dm | 28 +- .../admin/tickets/mentorticketsverbs.dm | 23 +- code/modules/admin/topic.dm | 92 +- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 14 +- code/modules/admin/verbs/SDQL2/sdql2_verbs.dm | 14 +- .../admin/verbs/admin_zlevel_manager_verb.dm | 15 +- code/modules/admin/verbs/adminjump.dm | 100 +- code/modules/admin/verbs/adminpm.dm | 44 +- code/modules/admin/verbs/adminsay.dm | 136 +-- code/modules/admin/verbs/antag-ooc.dm | 17 +- code/modules/admin/verbs/asays.dm | 44 +- code/modules/admin/verbs/atmosdebug.dm | 34 +- code/modules/admin/verbs/bloom_edit.dm | 13 +- code/modules/admin/verbs/cinematic.dm | 14 +- code/modules/admin/verbs/custom_event.dm | 19 +- code/modules/admin/verbs/deadsay.dm | 34 +- code/modules/admin/verbs/debug.dm | 427 +++----- code/modules/admin/verbs/debug_dmapi.dm | 41 +- code/modules/admin/verbs/diagnostics.dm | 33 +- code/modules/admin/verbs/freeze.dm | 9 +- code/modules/admin/verbs/getlogs.dm | 33 +- code/modules/admin/verbs/logging_view.dm | 19 +- code/modules/admin/verbs/manage_queue.dm | 62 +- .../admin/verbs/map_template_loadverb.dm | 61 +- code/modules/admin/verbs/mapping_verbs.dm | 71 +- code/modules/admin/verbs/one_click_antag.dm | 14 +- code/modules/admin/verbs/ping_all_admins.dm | 24 +- code/modules/admin/verbs/playsound.dm | 148 +-- code/modules/admin/verbs/possess.dm | 61 +- code/modules/admin/verbs/randomverbs.dm | 618 ++++------- code/modules/admin/verbs/screenshot.dm | 38 +- code/modules/admin/verbs/serialization.dm | 72 +- code/modules/admin/verbs/space_transitions.dm | 45 +- code/modules/admin/verbs/ticklag.dm | 22 +- code/modules/admin/verbs/toggledebugverbs.dm | 37 +- code/modules/admin/verbs/view_instances.dm | 15 +- code/modules/economy/economy_admin.dm | 11 +- code/modules/error_handler/error_handler.dm | 11 +- code/modules/events/event_procs.dm | 23 +- code/modules/holiday/holiday.dm | 17 +- code/modules/library/library_admin.dm | 12 +- code/modules/mob/mob_vv.dm | 31 +- code/modules/paperwork/fax.dm | 10 +- .../procedural_mapping/mapGenerator.dm | 38 +- code/modules/response_team/ert.dm | 17 +- .../station_goals/secondary/secondary_goal.dm | 6 +- code/modules/station_goals/station_goal.dm | 2 +- code/modules/tgui/modules/ert_manager.dm | 2 +- .../tgui_input/say_modal/tgui_say_speech.dm | 10 +- code/modules/vote/vote_verb.dm | 28 +- paradise.dme | 3 + tools/ci/check_user_verb_params.py | 147 +++ 92 files changed, 1751 insertions(+), 3113 deletions(-) create mode 100644 code/__DEFINES/user_verb_defines.dm create mode 100644 code/controllers/subsystem/non_firing/SSuser_verbs.dm create mode 100644 code/datums/user_verb.dm create mode 100644 tools/ci/check_user_verb_params.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2623fc2e4e2..d9dfa975d77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,7 @@ jobs: python -m tools.ci.check_map_sizes python -m tools.ci.check_legacy_attack_chain python -m tools.ci.check_simplemob_additions + python -m tools.ci.check_user_verb_params python -m tools.maplint.source --github - name: Run DreamChecker diff --git a/code/__DEFINES/admin_defines.dm b/code/__DEFINES/admin_defines.dm index e9e80b91110..307f1b1e7a7 100644 --- a/code/__DEFINES/admin_defines.dm +++ b/code/__DEFINES/admin_defines.dm @@ -21,6 +21,7 @@ #define BANTYPE_ADMIN_TEMP 8 //Admin Permissions +#define R_NONE NONE #define R_BUILDMODE (1<<0) #define R_ADMIN (1<<1) #define R_BAN (1<<2) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index f26be195ad8..a627f5a7eee 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -188,6 +188,7 @@ #define ZAP_SUPERMATTER_FLAGS (ZAP_GENERATES_POWER) GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) +GLOBAL_LIST_INIT(more_bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288)) //Mob mobility var flags /// can move diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index d92a12d42d4..909112b1e56 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -54,23 +54,24 @@ #define INIT_ORDER_DBCORE 26 #define INIT_ORDER_REDIS 25 // Make sure we dont miss any events #define INIT_ORDER_BLACKBOX 24 -#define INIT_ORDER_CLEANUP 23 -#define INIT_ORDER_INPUT 22 -#define INIT_ORDER_SOUNDS 21 -#define INIT_ORDER_INSTRUMENTS 20 -#define INIT_ORDER_RESEARCH 19 // SoonTM -#define INIT_ORDER_VIS 18 -#define INIT_ORDER_STATION 17 //This is high priority because it manipulates a lot of the subsystems that will initialize after it. -#define INIT_ORDER_EVENTS 16 -#define INIT_ORDER_JOBS 15 -#define INIT_ORDER_AI_MOVEMENT 14 -#define INIT_ORDER_AI_CONTROLLERS 13 -#define INIT_ORDER_TICKER 12 -#define INIT_ORDER_MAPPING 11 -#define INIT_ORDER_SPATIAL_GRID 10 -#define INIT_ORDER_AI_IDLE_CONTROLLERS 9 -#define INIT_ORDER_EARLY_ASSETS 8 -#define INIT_ORDER_ATOMS 7 +#define INIT_ORDER_USER_VERBS 23 +#define INIT_ORDER_CLEANUP 22 +#define INIT_ORDER_INPUT 21 +#define INIT_ORDER_SOUNDS 20 +#define INIT_ORDER_INSTRUMENTS 19 +#define INIT_ORDER_RESEARCH 18 // SoonTM +#define INIT_ORDER_VIS 17 +#define INIT_ORDER_STATION 16 //This is high priority because it manipulates a lot of the subsystems that will initialize after it. +#define INIT_ORDER_EVENTS 15 +#define INIT_ORDER_JOBS 14 +#define INIT_ORDER_AI_MOVEMENT 13 +#define INIT_ORDER_AI_CONTROLLERS 12 +#define INIT_ORDER_TICKER 11 +#define INIT_ORDER_MAPPING 10 +#define INIT_ORDER_SPATIAL_GRID 9 +#define INIT_ORDER_AI_IDLE_CONTROLLERS 8 +#define INIT_ORDER_EARLY_ASSETS 7 +#define INIT_ORDER_ATOMS 6 #define INIT_ORDER_MACHINES 5 #define INIT_ORDER_HOLIDAY 4 #define INIT_ORDER_IDLENPCS 3 diff --git a/code/__DEFINES/user_verb_defines.dm b/code/__DEFINES/user_verb_defines.dm new file mode 100644 index 00000000000..7d305887261 --- /dev/null +++ b/code/__DEFINES/user_verb_defines.dm @@ -0,0 +1,76 @@ +/// Use this to mark your verb as not having a description. Should ONLY be used if you are also hiding the verb! +#define VERB_NO_DESCRIPTION "" + +#define VERB_VISIBILITY_FLAG_LOCALHOST "Localhost" +#define VERB_VISIBILITY_FLAG_MOREDEBUG "Moredebug" + +/client/CanProcCall(procname) + if(findtext(procname, "__avd_") == 1) + message_admins("[key_name_admin(usr)] attempted to directly call admin verb '[procname]'.") + log_admin("[key_name(usr)] attempted to directly call admin verb '[procname]'.") + return FALSE + return ..() + +/** + * This is the only macro you should use to define admin verbs. + * It will define the verb and the verb holder for you. + * Using it is very simple: + * USER_VERB(verb_path, R_PERM, "Name", "Description", "Admin.Category", args...) + * This sets up all of the above and also acts as syntatic sugar as a verb delcaration for the verb itself. + * Note that the verb args have an injected `client/user` argument that is the user that called the verb. + * Do not use usr in your verb; technically you can but I'll kill you. + */ +#define _USER_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_category, show_in_context_menu, verb_args...) \ +/datum/user_verb/##verb_path_name \ +{ \ + name = ##verb_name; \ + description = ##verb_desc; \ + category = ##verb_category; \ + permissions = ##verb_permissions; \ + verb_path = /client/proc/__avd_##verb_path_name; \ +}; \ +/client/proc/__avd_##verb_path_name(##verb_args) \ +{ \ + set name = ##verb_name; \ + set desc = ##verb_desc; \ + set hidden = FALSE; /* this is explicitly needed as the proc begins with an underscore */ \ + set popup_menu = ##show_in_context_menu; \ + set category = ##verb_category; \ + var/list/_verb_args = list(usr, /datum/user_verb/##verb_path_name); \ + _verb_args += args; \ + SSuser_verbs.invoke_verb(arglist(_verb_args)); \ +}; \ +/datum/user_verb/##verb_path_name/__avd_do_verb(client/client, ##verb_args) + +#define USER_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_category, verb_args...) \ +_USER_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_category, FALSE, ##verb_args) + +#define USER_CONTEXT_MENU(verb_path_name, verb_permissions, verb_name, verb_args...) \ +_USER_VERB(verb_path_name, verb_permissions, verb_name, VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, TRUE, ##verb_args) + +#define USER_VERB_AND_CONTEXT_MENU(verb_path_name, verb_permissions, verb_name, verb_desc, verb_category, verb_args...) \ +_USER_VERB(verb_path_name, verb_permissions, verb_name, verb_desc, verb_category, TRUE, ##verb_args) + +/// Used to define a special check to determine if the admin verb should exist at all. Useful for verbs such as play sound which require configuration. +#define USER_VERB_CUSTOM_EXIST_CHECK(verb_path_name) \ +/datum/user_verb/##verb_path_name/__avd_check_should_exist() + +/// Used to define the visibility flag of the verb. If the admin does not have this flag enabled they will not see the verb. +#define USER_VERB_VISIBILITY(verb_path_name, verb_visibility) /datum/user_verb/##verb_path_name/visibility_flag = ##verb_visibility + +// These are put here to prevent the "procedure override precedes definition" error. +/datum/user_verb/proc/__avd_get_verb_path() + CRASH("__avd_get_verb_path not defined. use the macro") +/datum/user_verb/proc/__avd_do_verb(...) + CRASH("__avd_do_verb not defined. use the macro") +/datum/user_verb/proc/__avd_check_should_exist() + return TRUE + +/// Used for verbs you do not want to show up in the master verb panel. +#define VERB_CATEGORY_HIDDEN null +#define VERB_CATEGORY_EVENT "Event" +#define VERB_CATEGORY_ADMIN "Admin" +#define VERB_CATEGORY_DEBUG "Debug" +#define VERB_CATEGORY_SERVER "Server" +#define VERB_CATEGORY_MAPPING "Mapping" +#define VERB_CATEGORY_OOC "OOC" diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index b1349b63199..a5e3bd39474 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -538,23 +538,25 @@ return (result + L.Copy(Li, 0)) return (result + R.Copy(Ri, 0)) +#define MAX_BITFIELD_BITS 24 + //Converts a bitfield to a list of numbers (or words if a wordlist is provided) -/proc/bitfield2list(bitfield = 0, list/wordlist) +/proc/bitfield2list(bitfield = 0, list/L) var/list/r = list() - if(istype(wordlist,/list)) - var/max = min(length(wordlist),16) - var/bit = 1 - for(var/i=1, i<=max, i++) - if(bitfield & bit) - r += wordlist[i] - bit = bit << 1 + if(islist(L)) + var/max = min(length(L), MAX_BITFIELD_BITS) + for(var/i in 0 to max-1) + if(bitfield & (1 << i)) + r += L[i+1] else - for(var/bit=1, bit<=65535, bit = bit << 1) - if(bitfield & bit) - r += bit + for(var/i in 0 to MAX_BITFIELD_BITS-1) + if(bitfield & (1 << i)) + r += (1 << i) return r +#undef MAX_BITFIELD_BITS + // Returns the key based on the index /proc/get_key_by_index(list/L, index) var/i = 1 diff --git a/code/__HELPERS/unique_ids.dm b/code/__HELPERS/unique_ids.dm index 0f54d48354e..84e1d75cca2 100644 --- a/code/__HELPERS/unique_ids.dm +++ b/code/__HELPERS/unique_ids.dm @@ -84,18 +84,11 @@ GLOBAL_LIST_EMPTY(uid_log) * * In-round ability to view what has created a UID, and how many times a UID for that path has been declared */ -/client/proc/uid_log() - set name = "View UID Log" - set category = "Debug" - set desc = "Shows the log of created UIDs this round" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB(uid_log, R_DEBUG, "View UID Log", "Shows the log of created UIDs this round", VERB_CATEGORY_DEBUG) var/list/sorted = sortTim(GLOB.uid_log, GLOBAL_PROC_REF(cmp_numeric_dsc), TRUE) var/list/text = list("

UID Log

", "

Current UID: [GLOB.next_unique_datum_id]

", "" - usr << browse(text.Join(), "window=uidlog") + client << browse(text.Join(), "window=uidlog") diff --git a/code/_onclick/hud/movable_screen_objects.dm b/code/_onclick/hud/movable_screen_objects.dm index 65fd2f13c20..b2687804773 100644 --- a/code/_onclick/hud/movable_screen_objects.dm +++ b/code/_onclick/hud/movable_screen_objects.dm @@ -50,38 +50,30 @@ 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" - +USER_VERB(test_movable_ui, R_DEBUG, "Spawn Movable UI Object", "Spawn Movable UI Object", VERB_CATEGORY_DEBUG) var/atom/movable/screen/movable/M = new() M.name = "Movable UI Object" M.icon_state = "block" M.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 + var/screen_l = input(client, "Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Movable UI Object") as text if(!screen_l) return M.screen_loc = screen_l + client.screen += M - screen += M - -/client/proc/test_snap_UI() - set category = "Debug" - set name = "Spawn Snap UI Object" - +USER_VERB(test_snap_ui, R_DEBUG, "Spawn Snap UI Object", "Spawn Snap UI Object", VERB_CATEGORY_DEBUG) var/atom/movable/screen/movable/snap/S = new() S.name = "Snap UI Object" S.icon_state = "block" S.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 + var/screen_l = input(client, "Where on the screen? (Formatted as 'X,Y' e.g: '1,1' for bottom left)","Spawn Snap UI Object") as text if(!screen_l) return S.screen_loc = screen_l - - screen += S + client.screen += S diff --git a/code/_onclick/observer_onclick.dm b/code/_onclick/observer_onclick.dm index 5463044467b..0988ed0aba7 100644 --- a/code/_onclick/observer_onclick.dm +++ b/code/_onclick/observer_onclick.dm @@ -41,12 +41,12 @@ if(modifiers["ctrl"]) M = get_mob_in_atom_with_warning(A) if(M) - client.holder.show_player_panel(M) + SSuser_verbs.invoke_verb(client, /datum/user_verb/show_player_panel, M) return if(modifiers["shift"] && modifiers["middle"]) M = get_mob_in_atom_with_warning(A) if(M) - client.freeze(M) + SSuser_verbs.invoke_verb(client, /datum/user_verb/admin_freeze, M) return if(modifiers["middle"]) MiddleClickOn(A) diff --git a/code/controllers/subsystem/SSblackbox.dm b/code/controllers/subsystem/SSblackbox.dm index 59309bc512e..f215970817d 100644 --- a/code/controllers/subsystem/SSblackbox.dm +++ b/code/controllers/subsystem/SSblackbox.dm @@ -202,7 +202,7 @@ SUBSYSTEM_DEF(blackbox) * * Arguments: * * key_type - Type of key. Either "text", "amount", "tally", "nested tally", "associative" - * * key - Key of the data to be used (EG: "admin_verb") + * * key - Key of the data to be used (EG: "user_verb") * * stat - Either a number accumulated via "amount", "tally", or "nested tally"; or a number/string collected by "ledger" or "nested ledger". * * data - The actual data to logged * * overwrite - Do we want to overwrite the existing key diff --git a/code/controllers/subsystem/SSdbcore.dm b/code/controllers/subsystem/SSdbcore.dm index e4ceaeb0ea9..565fe3a7283 100644 --- a/code/controllers/subsystem/SSdbcore.dm +++ b/code/controllers/subsystem/SSdbcore.dm @@ -481,28 +481,26 @@ SUBSYSTEM_DEF(dbcore) item = null // Verb that lets admins force reconnect the DB -/client/proc/reestablish_db_connection() - set category = "Debug" - set name = "Reestablish DB Connection" +USER_VERB(reestablish_db_connection, R_ADMIN, "Reestablish DB Connection", "Force a reconnection to the database.", VERB_CATEGORY_DEBUG) if(!GLOB.configuration.database.enabled) - to_chat(usr, "The Database is not enabled in the server configuration!") + to_chat(client, "The Database is not enabled in the server configuration!") return if(SSdbcore.IsConnected()) - if(!check_rights(R_DEBUG, FALSE)) - to_chat(usr, "The database is already connected! (Only those with +DEBUG can force a reconnection)") + if(!check_rights_client(R_DEBUG, FALSE, client)) + to_chat(client, "The database is already connected! (Only those with +DEBUG can force a reconnection)") return - var/reconnect = alert("The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", "Force Reconnect", "Cancel") + var/reconnect = alert(client, "The database is already connected! If you *KNOW* that this is incorrect, you can force a reconnection", "The database is already connected!", "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(client)] has forced the database to disconnect") + message_admins("[key_name_admin(client)] 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") + log_admin("[key_name(client)] is attempting to re-establish the DB Connection") + message_admins("[key_name_admin(client)] is attempting to re-establish the DB Connection") SSblackbox.record_feedback("tally", "admin_verb", 1, "Force Reconnect DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! SSdbcore.failed_connections = 0 // Reset this diff --git a/code/controllers/subsystem/SSdebugview.dm b/code/controllers/subsystem/SSdebugview.dm index 437d544f01c..0d3684b31af 100644 --- a/code/controllers/subsystem/SSdebugview.dm +++ b/code/controllers/subsystem/SSdebugview.dm @@ -70,14 +70,8 @@ SUBSYSTEM_DEF(debugview) maptext_width = viewsizes[1] * world.icon_size // Make a verb for dumping full SS stats -/client/proc/ss_breakdown() - set name = "SS Info Breakdown" - set category = "Debug" - - if(!check_rights(R_DEBUG|R_VIEWRUNTIMES)) - return - - var/datum/browser/popup = new(usr, "ss_breakdown", "Subsystem Breakdown", 1100, 850) +USER_VERB(ss_breakdown, R_DEBUG|R_VIEWRUNTIMES, "SS Info Breakdown", "Dump stats of all subsystems", VERB_CATEGORY_DEBUG) + var/datum/browser/popup = new(client, "ss_breakdown", "Subsystem Breakdown", 1100, 850) var/list/html = list() html += "CPU: [round(world.cpu, 1)] | MCPU: [round(world.map_cpu, 1)] | FPS/TPS: [world.fps] | Clients: [length(GLOB.clients)] | BYOND: [world.byond_version].[world.byond_build]" diff --git a/code/controllers/subsystem/SSgarbage.dm b/code/controllers/subsystem/SSgarbage.dm index 9818f483fd2..90b11aab6a9 100644 --- a/code/controllers/subsystem/SSgarbage.dm +++ b/code/controllers/subsystem/SSgarbage.dm @@ -383,12 +383,7 @@ SUBSYSTEM_DEF(garbage) #ifdef REFERENCE_TRACKING -/datum/proc/find_refs() - set category = "Debug" - set name = "Find References" - - if(!check_rights(R_DEBUG)) - return +USER_VERB(find_refs, R_DEBUG, "Find References", "Find references.", VERB_CATEGORY_DEBUG) find_references(FALSE) /datum/proc/find_references(skip_alert) @@ -446,23 +441,13 @@ SUBSYSTEM_DEF(garbage) SSgarbage.can_fire = 1 SSgarbage.next_fire = world.time + world.tick_lag -/datum/proc/qdel_then_find_references() - set category = "Debug" - set name = "qdel() then Find References" - if(!check_rights(R_DEBUG)) - return - - qdel(src, TRUE) //force a qdel +USER_VERB(qdel_then_find_references, R_DEBUG, "qdel() then Find References", "qdel() then Find References", VERB_CATEGORY_DEBUG) + qdel(user, TRUE) //force a qdel if(!running_find_references) find_references(TRUE) -/datum/proc/qdel_then_if_fail_find_references() - set category = "Debug" - set name = "qdel() then Find References if GC failure" - if(!check_rights(R_DEBUG)) - return - - qdel_and_find_ref_if_fail(src, TRUE) +USER_VERB(qdel_then_if_fail_find_references, R_DEBUG, "qdel() then Find References if GC failure", "qdel() then Find References if GC failure", VERB_CATEGORY_DEBUG) + qdel_and_find_ref_if_fail(user, TRUE) /datum/proc/DoSearchVar(potential_container, container_name, recursive_limit = 64, search_time = world.time) if((usr?.client && !usr.client.running_find_references) || SSgarbage.ref_search_stop) diff --git a/code/controllers/subsystem/SStimer.dm b/code/controllers/subsystem/SStimer.dm index 44191cb87fb..e33a94a47df 100644 --- a/code/controllers/subsystem/SStimer.dm +++ b/code/controllers/subsystem/SStimer.dm @@ -590,30 +590,16 @@ GLOBAL_LIST_EMPTY(timers_by_proc) * * In-round ability to view what has created a timer, and how many times a timer for that path has been created */ -/client/proc/timer_log() - set name = "View Timer Log" - set category = "Debug" - set desc = "Shows the log of what types created timers this round" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - +USER_VERB(timer_log, R_DEBUG|R_VIEWRUNTIMES, "View Timer Log", "Shows the log of what types created timers this round", VERB_CATEGORY_DEBUG) var/list/sorted = sortTim(GLOB.timers_by_proc, GLOBAL_PROC_REF(cmp_numeric_dsc), TRUE) var/list/text = list("

Timer Log

", "" - usr << browse(text.Join(), "window=timerlog") - -/client/proc/debug_timers() - set name = "Debug Timers" - set category = "Debug" - set desc = "Shows currently active timers, grouped by callback" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return + client << browse(text.Join(), "window=timerlog") +USER_VERB(debug_timers, R_DEBUG|R_VIEWRUNTIMES, "Debug Timers", "Shows currently active timers, grouped by callback", VERB_CATEGORY_DEBUG) var/list/timers = list() for(var/id in SStimer.timer_id_dict) var/datum/timedevent/T = SStimer.timer_id_dict[id] @@ -646,7 +632,7 @@ GLOBAL_LIST_EMPTY(timers_by_proc) text += "
  • [key] - [sorted2[key]]
  • " text += "" - usr << browse(text.Join(), "window=timerdebug") + client << browse(text.Join(), "window=timerdebug") /** diff --git a/code/controllers/subsystem/SSverb_manager.dm b/code/controllers/subsystem/SSverb_manager.dm index 9382a121a3e..80549cc779d 100644 --- a/code/controllers/subsystem/SSverb_manager.dm +++ b/code/controllers/subsystem/SSverb_manager.dm @@ -162,13 +162,7 @@ SUBSYSTEM_DEF(verb_manager) /datum/controller/subsystem/verb_manager/Recover() verb_queue = SSverb_manager.verb_queue -/client/proc/force_verb_bypass() - set category = "Debug" - set name = "Enable Forced Verb Execution" - - if(!check_rights(R_DEBUG)) - return - - if(alert(src,"This will make all verbs bypass the queueing system, creating more lag. Are you absolutely sure?","Verb Manager","Yes","No") == "Yes") +USER_VERB(force_verb_bypass, R_DEBUG, "Enable Forced Verb Execution", "Enable Forced Verb Execution", VERB_CATEGORY_DEBUG) + if(alert(client, "This will make all verbs bypass the queueing system, creating more lag. Are you absolutely sure?","Verb Manager","Yes","No") == "Yes") SSverb_manager.FOR_ADMINS_IF_VERBS_FUCKED_immediately_execute_all_verbs = TRUE - message_admins("Admin [key_name_admin(usr)] has forced verbs to bypass the verb queue subsystem.") + message_admins("Admin [key_name_admin(client)] has forced verbs to bypass the verb queue subsystem.") diff --git a/code/controllers/subsystem/non_firing/SSatoms.dm b/code/controllers/subsystem/non_firing/SSatoms.dm index 24ec639670e..09d204ceb2e 100644 --- a/code/controllers/subsystem/non_firing/SSatoms.dm +++ b/code/controllers/subsystem/non_firing/SSatoms.dm @@ -114,16 +114,7 @@ SUBSYSTEM_DEF(atoms) old_initialized = SSatoms.old_initialized BadInitializeCalls = SSatoms.BadInitializeCalls - - -/client/proc/debug_atom_init() - set name = "Atom Init Log" - set category = "Debug" - set desc = "Shows what failed to init this round" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - +USER_VERB(debug_atom_init, R_DEBUG|R_VIEWRUNTIMES, "Atom Init Log", "Shows what failed to init this round", VERB_CATEGORY_DEBUG) var/list/html_data = list() html_data += "

    Bad Initialize() Calls

    " @@ -134,5 +125,5 @@ SUBSYSTEM_DEF(atoms) html_data += "
    TypeQdeleted before initDid not initSlept during initNo init hint
    " - usr << browse(html_data.Join(), "window=initdebug") + client << browse(html_data.Join(), "window=initdebug") diff --git a/code/controllers/subsystem/non_firing/SSuser_verbs.dm b/code/controllers/subsystem/non_firing/SSuser_verbs.dm new file mode 100644 index 00000000000..3c0468d92e3 --- /dev/null +++ b/code/controllers/subsystem/non_firing/SSuser_verbs.dm @@ -0,0 +1,154 @@ +GENERAL_PROTECT_DATUM(/datum/controller/subsystem/user_verbs) + +SUBSYSTEM_DEF(user_verbs) + name = "User Verbs" + flags = SS_NO_FIRE + init_order = INIT_ORDER_USER_VERBS + /// A list of all user verbs indexed by their type. + var/list/user_verbs_by_type = list() + /// A list of all user verbs indexed by their visibility flag. + var/list/user_verbs_by_visibility_flag = list() + /// A map of all associated admins and their visibility flags. + var/list/admin_visibility_flags = list() + /// A list of all admins that are pending initialization of this SS. + var/list/admins_pending_subsytem_init = list() + +/datum/controller/subsystem/user_verbs/Initialize() + setup_verb_list() + process_pending_admins() + +/datum/controller/subsystem/user_verbs/Recover() + user_verbs_by_type = SSuser_verbs.user_verbs_by_type + +/datum/controller/subsystem/user_verbs/stat_entry(msg) + msg = "V:[length(user_verbs_by_type)]" + return ..() + +/datum/controller/subsystem/user_verbs/proc/process_pending_admins() + var/list/pending_admins = admins_pending_subsytem_init + admins_pending_subsytem_init = null + for(var/admin_ckey in pending_admins) + associate(GLOB.directory[admin_ckey]) + +/datum/controller/subsystem/user_verbs/proc/setup_verb_list() + if(length(user_verbs_by_type)) + CRASH("Attempting to set up user verbs twice!") + for(var/datum/user_verb/verb_type as anything in subtypesof(/datum/user_verb)) + var/datum/user_verb/verb_singleton = new verb_type + if(!verb_singleton.__avd_check_should_exist()) + qdel(verb_singleton, force = TRUE) + continue + + user_verbs_by_type[verb_type] = verb_singleton + if(verb_singleton.visibility_flag) + if(!(verb_singleton.visibility_flag in user_verbs_by_visibility_flag)) + user_verbs_by_visibility_flag[verb_singleton.visibility_flag] = list() + user_verbs_by_visibility_flag[verb_singleton.visibility_flag] |= list(verb_singleton) + +/datum/controller/subsystem/user_verbs/proc/get_valid_verbs_for(client/admin) + if(isnull(admin.holder)) + CRASH("Tried to get valid verbs for client without permissions") + + var/list/has_permission = list() + for(var/permission_flag in GLOB.more_bitflags) + if(check_rights_client(permission_flag, FALSE, admin)) + has_permission["[permission_flag]"] = TRUE + + var/list/valid_verbs = list() + for(var/datum/user_verb/verb_type as anything in user_verbs_by_type) + var/datum/user_verb/verb_singleton = user_verbs_by_type[verb_type] + if(!verify_visibility(admin, verb_singleton)) + continue + + var/verb_permissions = verb_singleton.permissions + if(verb_permissions == R_NONE) + valid_verbs |= list(verb_singleton) + else for(var/permission_flag in bitfield2list(verb_permissions)) + if(!has_permission["[permission_flag]"]) + continue + valid_verbs |= list(verb_singleton) + + return valid_verbs + +/datum/controller/subsystem/user_verbs/proc/verify_visibility(client/admin, datum/user_verb/verb_singleton) + var/needed_flag = verb_singleton.visibility_flag + return !needed_flag || (needed_flag in admin_visibility_flags[admin.ckey]) + +/datum/controller/subsystem/user_verbs/proc/update_visibility_flag(client/admin, flag, state) + if(state) + admin_visibility_flags[admin.ckey] |= list(flag) + associate(admin) + return + + admin_visibility_flags[admin.ckey] -= list(flag) + // they lost the flag, iterate over verbs with that flag and yoink em + for(var/datum/user_verb/verb_singleton as anything in user_verbs_by_visibility_flag[flag]) + verb_singleton.unassign_from_client(admin) + admin.init_verbs() + +/datum/controller/subsystem/user_verbs/proc/invoke_verb(client/admin, datum/user_verb/verb_type, ...) + if(IsAdminAdvancedProcCall()) + message_admins("PERMISSION ELEVATION: [key_name_admin(admin)] attempted to dynamically invoke user verb '[verb_type]'.") + return + + if(ismob(admin)) + var/mob/mob = admin + admin = mob.client + + if(!ispath(verb_type, /datum/user_verb) || verb_type == /datum/user_verb) + CRASH("Attempted to dynamically invoke user verb with invalid typepath '[verb_type]'.") + if(isnull(admin.holder)) + CRASH("Attempted to dynamically invoke user verb '[verb_type]' with a non-admin.") + + var/list/verb_args = args.Copy() + verb_args.Cut(2, 3) + var/datum/user_verb/verb_singleton = user_verbs_by_type[verb_type] // this cannot be typed because we need to use `:` + if(isnull(verb_singleton)) + CRASH("Attempted to dynamically invoke user verb '[verb_type]' that doesn't exist.") + + if(!check_rights_client(verb_singleton.permissions, FALSE, admin)) + to_chat(admin, "You lack the permissions to do this.") + return + + var/old_usr = usr + usr = admin.mob + // THE MACRO ENSURES THIS EXISTS. IF IT EVER DOESNT EXIST SOMEONE DIDNT USE THE DAMN MACRO! + verb_singleton.__avd_do_verb(arglist(verb_args)) + usr = old_usr + SSblackbox.record_feedback("tally", "dynamic_user_verb_invocation", 1, "[verb_type]") + +/** + * Assosciates and/or resyncs an admin with their accessible user verbs. + */ +/datum/controller/subsystem/user_verbs/proc/associate(client/user) + if(IsAdminAdvancedProcCall()) + return + + if(!isnull(admins_pending_subsytem_init)) // if the list exists we are still initializing + if(!(user.ckey in admins_pending_subsytem_init)) + to_chat(user, "User Verbs are still initializing. Please wait and you will be automatically assigned your verbs when it is complete.") + admins_pending_subsytem_init |= list(user.ckey) + return + + // refresh their verbs + admin_visibility_flags[user.ckey] ||= list() + if(user.holder.is_localhost_autoadmin) + admin_visibility_flags[user.ckey] |= list(VERB_VISIBILITY_FLAG_LOCALHOST) + for(var/datum/user_verb/verb_singleton as anything in get_valid_verbs_for(user)) + verb_singleton.assign_to_client(user) + user.init_verbs() + +/** + * Unassociates an admin from their user verbs. + * Goes over all user verbs because we don't know which ones are assigned to the admin's mob without a bunch of extra bookkeeping. + * This might be a performance issue in the future if we have a lot of user verbs. + */ +/datum/controller/subsystem/user_verbs/proc/deassociate(client/user) + if(IsAdminAdvancedProcCall()) + return + + UnregisterSignal(user, COMSIG_MOB_CLIENT_LOGIN) + for(var/verb_type in user_verbs_by_type) + var/datum/user_verb/user_verb = user_verbs_by_type[verb_type] + user_verb.unassign_from_client(user) + admin_visibility_flags -= list(user.ckey) diff --git a/code/controllers/subsystem/tickets/SStickets.dm b/code/controllers/subsystem/tickets/SStickets.dm index 6d8a76d13bd..5ac7654e76a 100644 --- a/code/controllers/subsystem/tickets/SStickets.dm +++ b/code/controllers/subsystem/tickets/SStickets.dm @@ -305,7 +305,7 @@ SUBSYSTEM_DEF(tickets) if(!closeTicket(N)) to_chat(C, "Unable to close ticket") if("Man Up") - C.man_up(returnClient(N)) + SSuser_verbs.invoke_verb(C, /datum/user_verb/man_up, returnClient(N)) T.lastStaffResponse = "Autoresponse: [message_key]" resolveTicket(N) message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with: [message_key]") @@ -747,9 +747,9 @@ UI STUFF if(href_list["resolveall"]) if(ticket_system_name == "Mentor Tickets") - usr.client.resolveAllMentorTickets() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/resolve_all_mentor_tickets) else - usr.client.resolveAllAdminTickets() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/resolve_all_admin_tickets) if(href_list["close"]) onCloseDetailUI(usr) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 244b32125b0..49f40a48129 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -1,14 +1,10 @@ //TODO: rewrite and standardise all controller datums to the datum/controller type //TODO: allow all controllers to be deleted for clean restarts (see WIP master controller stuff) - MC done - lighting done - -/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(!check_rights(R_DEBUG)) - return +USER_VERB(restart_controller, R_DEBUG, "Restart Controller", \ + "Restart one of the various periodic loop controllers for the game (be careful!)", \ + VERB_CATEGORY_DEBUG, \ + controller in list("Master", "Failsafe")) switch(controller) if("Master") Recreate_MC() @@ -17,27 +13,24 @@ new /datum/controller/failsafe() SSblackbox.record_feedback("tally", "admin_verb", 1, "Restart Failsafe") - message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.") + message_admins("Admin [key_name_admin(client)] has restarted the [controller] controller.") -/client/proc/debug_controller(controller in list("Configuration", "pAI", "Cameras", "Space Manager")) - set category = "Debug" - set name = "Debug Misc Controller" - set desc = "Debug the various non-subsystem controllers for the game (be careful!)" - - if(!check_rights(R_DEBUG)) - return +USER_VERB(debug_misc_controller, R_DEBUG, "Debug Misc Controller", \ + "Debug the various non-subsystem controllers for the game (be careful!)", \ + VERB_CATEGORY_DEBUG, + controller in list("Configuration", "pAI", "Cameras", "Space Manager")) switch(controller) if("Configuration") - debug_variables(GLOB.configuration) + SSuser_verbs.invoke_verb(client, /datum/user_verb/debug_variables, GLOB.configuration) SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Config") if("pAI") - debug_variables(GLOB.paiController) + SSuser_verbs.invoke_verb(client, /datum/user_verb/debug_variables, GLOB.paiController) SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug pAI") if("Cameras") - debug_variables(GLOB.cameranet) + SSuser_verbs.invoke_verb(client, /datum/user_verb/debug_variables, GLOB.cameranet) SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Cameras") if("Space Manager") - debug_variables(GLOB.space_manager) + SSuser_verbs.invoke_verb(client, /datum/user_verb/debug_variables, GLOB.space_manager) SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Space") - message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") + message_admins("Admin [key_name_admin(client)] is debugging the [controller] controller.") diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 28f737f68ea..1a4dea3226a 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -137,15 +137,12 @@ var/datum/ui_module/colour_matrix_tester/CMT = new(target=src) CMT.ui_interact(usr) +USER_CONTEXT_MENU(debug_variables, R_ADMIN|R_VIEWRUNTIMES, "\[Admin\] View Variables", datum/thing in world) + client.debug_variables(thing) + /client/proc/debug_variables(datum/D in world) - set name = "\[Admin\] View Variables" - var/static/cookieoffset = rand(1, 9999) //to force cookies to reset after the round. - if(!check_rights(R_ADMIN|R_VIEWRUNTIMES)) - to_chat(usr, "You need to be an administrator to access this.") - return - if(!D) return @@ -724,14 +721,7 @@ debug_variables(locate(href_list["listrefresh"])) return TRUE -/client/proc/debug_global_variables(var_search as text) - set category = "Debug" - set name = "Debug Global Variables" - - if(!check_rights(R_ADMIN|R_VIEWRUNTIMES)) - to_chat(usr, "You need to be an administrator to access this.") - return - +USER_VERB(debug_global_variables, R_ADMIN|R_VIEWRUNTIMES, "Debug Global Variables", "Debug Global Variables", VERB_CATEGORY_DEBUG, var_search as text) var_search = trim(var_search) if(!var_search) return @@ -741,13 +731,13 @@ if("vars") return FALSE if(!(var_search in GLOB.vars)) - to_chat(src, "GLOB.[var_search] does not exist.") + to_chat(client, "GLOB.[var_search] does not exist.") return log_and_message_admins("is debugging the Global Variables controller with the search term \"[var_search]\"") var/result = GLOB.vars[var_search] if(islist(result) || isclient(result) || istype(result, /datum)) - to_chat(src, "Now showing GLOB.[var_search].") - return debug_variables(result) - to_chat(src, "GLOB.[var_search] returned [result].") + to_chat(client, "Now showing GLOB.[var_search].") + return client.debug_variables(result) + to_chat(client, "GLOB.[var_search] returned [result].") #undef VV_HTML_ENCODE diff --git a/code/datums/keybindings/admin_keybinds.dm b/code/datums/keybindings/admin_keybinds.dm index 3bf1e6b1736..9c88b8619b6 100644 --- a/code/datums/keybindings/admin_keybinds.dm +++ b/code/datums/keybindings/admin_keybinds.dm @@ -26,7 +26,7 @@ /datum/keybinding/admin/aghost/down(client/C) . = ..() - C.admin_ghost() + SSuser_verbs.invoke_verb(C, /datum/user_verb/admin_ghost) /datum/keybinding/admin/player_panel name = "Player Panel" @@ -43,7 +43,7 @@ /datum/keybinding/admin/apm/down(client/C) . = ..() - C.cmd_admin_pm_panel() + SSuser_verbs.invoke_verb(C, /datum/user_verb/admin_pm_panel) /datum/keybinding/admin/invisimin name = "Invisimin" @@ -51,4 +51,4 @@ /datum/keybinding/admin/invisimin/down(client/C) . = ..() - C.invisimin() + SSuser_verbs.invoke_verb(C, /datum/user_verb/invisimin) diff --git a/code/datums/station_traits/admin_panel.dm b/code/datums/station_traits/admin_panel.dm index 6c11de92f12..ddf13659ba2 100644 --- a/code/datums/station_traits/admin_panel.dm +++ b/code/datums/station_traits/admin_panel.dm @@ -1,10 +1,6 @@ -/// Opens the station traits admin panel -/datum/admins/proc/station_traits_panel() - set name = "Modify Station Traits" - set category = "Event" - +USER_VERB(modify_station_traits, R_ADMIN, "Modify Station Traits", "Open the station traits panel.", VERB_CATEGORY_EVENT) var/static/datum/ui_module/station_traits_panel/station_traits_panel = new - station_traits_panel.ui_interact(usr) + station_traits_panel.ui_interact(client.mob) /datum/ui_module/station_traits_panel var/static/list/future_traits diff --git a/code/datums/user_verb.dm b/code/datums/user_verb.dm new file mode 100644 index 00000000000..0911e5c75d5 --- /dev/null +++ b/code/datums/user_verb.dm @@ -0,0 +1,27 @@ +GENERAL_PROTECT_DATUM(/datum/user_verb) + +/** + * This is the user verb datum. It is used to store the verb's information and handle the verb's functionality. + * All of this is setup for you, and you should not be defining this manually. + * That means you reader. + */ +/datum/user_verb + var/name //! The name of the verb. + var/description //! The description of the verb. + var/category //! The category of the verb. + var/permissions //! The permissions required to use the verb. + var/visibility_flag //! The flag that determines if the verb is visible. + VAR_PROTECTED/verb_path //! The path to the verb proc. + +/datum/user_verb/Destroy(force) + if(!force) + return QDEL_HINT_LETMELIVE + return ..() + +/// Assigns the verb to the user. +/datum/user_verb/proc/assign_to_client(client/user) + add_verb(user, verb_path) + +/// Unassigns the verb from the user. +/datum/user_verb/proc/unassign_from_client(client/user) + remove_verb(user, verb_path) diff --git a/code/datums/vv_core_topics.dm b/code/datums/vv_core_topics.dm index 82cba327e88..94a3f26dc05 100644 --- a/code/datums/vv_core_topics.dm +++ b/code/datums/vv_core_topics.dm @@ -3,12 +3,9 @@ /// from [/datum/proc/vv_do_topic] for that reason. /client/proc/vv_core_topics(datum/target, href_list) if(href_list[VV_HK_JUMP_TO]) - if(!check_rights(R_ADMIN)) - return - var/turf/T = get_turf(target) if(T) - jumptoturf(T) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/jump_to_turf, T) href_list["datumrefresh"] = target.UID() if(href_list["varnameedit"] && href_list["datumedit"]) if(!check_rights(R_ADMIN | R_VAREDIT)) return @@ -59,7 +56,8 @@ return if(target) - callproc_datum(target) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/call_proc_datum, target) + if(href_list[VV_HK_ADDCOMPONENT]) if(!check_rights(NONE)) return diff --git a/code/game/atom_vv.dm b/code/game/atom_vv.dm index 394f7998996..85b02f4ab61 100644 --- a/code/game/atom_vv.dm +++ b/code/game/atom_vv.dm @@ -47,16 +47,10 @@ log_admin("[key_name(usr)] has rotated \the [src]") href_list["datumrefresh"] = UID() if(href_list[VV_HK_EXPLODE]) - if(!check_rights(R_DEBUG|R_EVENT)) - return - - usr.client.cmd_admin_explosion(src) + SSuser_verbs.invoke_verb(usr.client, /datum/user_verb/admin_explosion, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_EMP]) - if(!check_rights(R_DEBUG|R_EVENT)) - return - - usr.client.cmd_admin_emp(src) + SSuser_verbs.invoke_verb(usr.client, /datum/user_verb/admin_emp, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_ADDREAGENT]) /* Made on /TG/, credit to them. */ if(!check_rights(R_DEBUG|R_ADMIN)) diff --git a/code/game/jobs/job_exp.dm b/code/game/jobs/job_exp.dm index 79a7af64eac..ba3507e9da3 100644 --- a/code/game/jobs/job_exp.dm +++ b/code/game/jobs/job_exp.dm @@ -33,12 +33,8 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list( )) // Admin Verbs - -/client/proc/cmd_mentor_check_player_exp() //Allows admins to determine who the newer players are. - set category = "Admin" - set name = "Check Player Playtime" - if(!check_rights(R_ADMIN|R_MOD|R_MENTOR)) - return +/// Allows admins to determine who the newer players are. +USER_VERB(check_player_exp, R_ADMIN|R_MOD|R_MENTOR, "Check Player Playtime", "Return a playtime report.", VERB_CATEGORY_ADMIN) var/list/msg = list() msg += "Playtime Report" var/datum/job/theirjob @@ -69,8 +65,7 @@ GLOBAL_LIST_INIT(role_playtime_requirements, list( msg += "" msg += "" - src << browse(msg.Join(""), "window=Player_playtime_check") - + client << browse(msg.Join(""), "window=Player_playtime_check") /datum/admins/proc/cmd_mentor_show_exp_panel(client/C) if(!C) diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index c4d39c0177c..efa0f7a83f8 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -267,18 +267,15 @@ GLOB.empty_playable_ai_cores -= src return ..() -/client/proc/empty_ai_core_toggle_latejoin() - set name = "Toggle AI Core Latejoin" - set category = "Admin" - +USER_VERB(empty_ai_core_toggle_latejoin, R_ADMIN, "Toggle AI Core Latejoin", "Toggle AI Core Latejoin", VERB_CATEGORY_ADMIN) var/list/cores = list() for(var/obj/structure/ai_core/deactivated/D in world) cores["[D] ([D.loc.loc])"] = D if(!length(cores)) - to_chat(src, "No deactivated AI cores were found.") + to_chat(client, "No deactivated AI cores were found.") - var/id = input("Which core?", "Toggle AI Core Latejoin", null) as null|anything in cores + var/id = input(client, "Which core?", "Toggle AI Core Latejoin", null) as null|anything in cores if(!id) return var/obj/structure/ai_core/deactivated/D = cores[id] @@ -286,11 +283,10 @@ if(D in GLOB.empty_playable_ai_cores) GLOB.empty_playable_ai_cores -= D - to_chat(src, "\The [id] is now not available for latejoining AIs.") + to_chat(client, "\The [id] is now not available for latejoining AIs.") else GLOB.empty_playable_ai_cores += D - to_chat(src, "\The [id] is now available for latejoining AIs.") - + to_chat(client, "\The [id] is now available for latejoining AIs.") /* This is a good place for AI-related object verbs so I'm sticking it here. diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 35daffb4ade..c8196d468b6 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -308,14 +308,10 @@ setMenuState(ui.user, COMM_SCREEN_ANNOUNCER) if("make_other_announcement") - if(!ADMIN_CHECK(ui.user)) - return - ui.user.client.cmd_admin_create_centcom_report() + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/create_centcom_report) if("dispatch_ert") - if(!ADMIN_CHECK(ui.user)) - return - ui.user.client.response_team() // check_rights is handled on the other side, if someone does get ahold of this + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/dispatch_ert) if("send_nuke_codes") if(!ADMIN_CHECK(ui.user)) @@ -335,19 +331,13 @@ SEND_SOUND(ui.user, sound(cc_announcement_sounds[params["sound"]])) if("toggle_ert_allowed") - if(!ADMIN_CHECK(ui.user)) - return - ui.user.client.toggle_ert_calling() + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/toggle_ert_calling) if("view_econ") - if(!ADMIN_CHECK(ui.user)) - return - ui.user.client.economy_manager() + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/economy_panel) if("view_fax") - if(!ADMIN_CHECK(ui.user)) - return - ui.user.client.fax_panel() + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/fax_panel) if("make_cc_announcement") if(!ADMIN_CHECK(ui.user)) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 0ca168b027e..6302247524e 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -212,12 +212,9 @@ for(var/turf/tile in spiral_range_turfs(range, epicenter)) tile.ex_act(EXPLODE_HEAVY) -/client/proc/check_bomb_impacts() - set name = "Check Bomb Impact" - set category = "Debug" - - var/newmode = alert("Use reactionary explosions?","Check Bomb Impact", "Yes", "No") - var/turf/epicenter = get_turf(mob) +USER_VERB(check_bomb_impact, R_DEBUG, "Check Bomb Impact", "Test bomb impact ranges.", VERB_CATEGORY_DEBUG) + var/newmode = alert(client, "Use reactionary explosions?","Check Bomb Impact", "Yes", "No") + var/turf/epicenter = get_turf(client.mob) if(!epicenter) return @@ -225,7 +222,7 @@ var/heavy = 0 var/light = 0 var/list/choices = list("Small Bomb","Medium Bomb","Big Bomb","Custom Bomb") - var/choice = input("Bomb Size?") in choices + var/choice = input(client, "Bomb Size?") in choices switch(choice) if(null) return 0 @@ -242,9 +239,9 @@ heavy = 5 light = 7 if("Custom Bomb") - dev = input("Devastation range (Tiles):") as num - heavy = input("Heavy impact range (Tiles):") as num - light = input("Light impact range (Tiles):") as num + dev = input(client, "Devastation range (Tiles):") as num + heavy = input(client, "Heavy impact range (Tiles):") as num + light = input(client, "Light impact range (Tiles):") as num var/max_range = max(dev, heavy, light) var/x0 = epicenter.x diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm index d83132ad21a..5bcf4e43ea4 100644 --- a/code/game/verbs/who.dm +++ b/code/game/verbs/who.dm @@ -101,7 +101,7 @@ to_chat(src, msg.Join("
    ")) /client/verb/adminwho() - set category = "Admin" + set category = VERB_CATEGORY_ADMIN set name = "Adminwho" var/list/adminmsg = list() diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 9a9bc64b37b..03dc0ab0d07 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -12,20 +12,13 @@ GLOBAL_PROTECT(investigate_log_wrapper) GLOB.investigate_log_wrapper[subject] += "[time_stamp()] [UID()] [ADMIN_COORDJMP(src)] || [src] [message]" -//ADMINVERBS -/client/proc/investigate_show(subject in GLOB.investigate_log_wrapper) - set name = "Investigate Round Objects" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(investigate_show, R_ADMIN, "Investigate Round Objects", "View Investigation panel.", VERB_CATEGORY_ADMIN, subject in GLOB.investigate_log_wrapper) // Should never happen if(!(subject in GLOB.investigate_log_wrapper)) return var/list/entries = GLOB.investigate_log_wrapper[subject] - var/datum/browser/B = new(usr, "investigatelog", "Investigate ([subject])", 800, 400) + var/datum/browser/B = new(client, "investigatelog", "Investigate ([subject])", 800, 400) B.set_content(entries.Join("
    ")) B.open() diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm index 1f88ee3f7bf..a6fac4b394f 100644 --- a/code/modules/admin/admin_memo.dm +++ b/code/modules/admin/admin_memo.dm @@ -1,15 +1,11 @@ -/client/proc/admin_memo() - set name = "Memo" - set category = "Server" - if(!check_rights(R_SERVER)) - return +USER_VERB(server_memo, R_SERVER, "Memo", "View and modify server memos.", VERB_CATEGORY_SERVER) if(!SSdbcore.IsConnected()) - to_chat(src, "Failed to establish database connection.") + to_chat(client, "Failed to establish database connection.") return - var/memotask = input(usr,"Choose task.","Memo") in list("Show","Write","Edit","Remove") + var/memotask = input(client, "Choose task.", "Memo") in list("Show", "Write", "Edit", "Remove") if(!memotask) return - admin_memo_output(memotask) + client.admin_memo_output(memotask) /client/proc/admin_memo_output(task, checkrights = 1, silent = 0) if(checkrights && !check_rights(R_SERVER)) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 2c58b5a5431..8b9d45ccc79 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -1,382 +1,22 @@ -//admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless -GLOBAL_LIST_INIT(admin_verbs_default, list( - /client/proc/deadmin_self, /*destroys our own admin datum so we can play as a regular player*/ - /client/proc/hide_verbs, /*hides all our adminverbs*/ - /client/proc/cmd_mentor_check_new_players, - /client/proc/cmd_mentor_check_player_exp /* shows players by playtime */ - )) -GLOBAL_LIST_INIT(admin_verbs_admin, list( - /client/proc/check_antagonists, /*shows all antags*/ - /client/proc/check_antagonists2, /*shows all antags*/ - /datum/admins/proc/show_player_panel, - /client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/ - /client/proc/invisimin, /*allows our mob to go invisible/visible*/ - /datum/admins/proc/announce, /*priority announce something to all clients.*/ - /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ - /client/proc/admin_observe, /*allows us to freely observe mobs */ - /client/proc/admin_observe_target, /*and gives it to us on right click*/ - /client/proc/toggle_view_range, /*changes how far we can see*/ - /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ - /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ - /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ - /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ - /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ - /client/proc/cmd_admin_open_logging_view, - /client/proc/getserverlogs, /*allows us to fetch server logs (diary) for other days*/ - /client/proc/get_server_logs_by_round_id, - /client/proc/Getmob, /*teleports a mob to our location*/ - /client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/ - /client/proc/jump_to, /*Opens a menu for jumping to an Area, Mob, Key or Coordinate*/ - /client/proc/jumptoturf, /*allows us to jump to a specific turf*/ - /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 centcomm*/ - /client/proc/admin_deny_shuttle, /*toggles availability of shuttle calling*/ - /client/proc/check_ai_laws, /*shows AI and borg laws*/ - /client/proc/manage_silicon_laws, /* Allows viewing and editing silicon laws. */ - /client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/ - /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ - /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ - /datum/admins/proc/toggleooc, /*toggles ooc on/off for everyone*/ - /datum/admins/proc/togglelooc, /*toggles looc on/off for everyone*/ - /datum/admins/proc/toggleoocdead, /*toggles ooc on/off for everyone who is dead*/ - /datum/admins/proc/toggledsay, /*toggles dsay on/off for everyone*/ - /datum/admins/proc/toggleemoji, /*toggles using emoji in ooc for everyone*/ - /client/proc/game_panel, /*game panel, allows to change game-mode etc*/ - /client/proc/cmd_admin_say, /*admin-only ooc chat*/ - /client/proc/cmd_staff_say, - /datum/admins/proc/PlayerNotes, - /client/proc/cmd_mentor_say, - /client/proc/cmd_dev_say, - /datum/admins/proc/show_player_notes, - /client/proc/free_slot, /*frees slot for chosen job*/ - /client/proc/update_mob_sprite, - /client/proc/man_up, - /client/proc/global_man_up, - /client/proc/library_manager, - /client/proc/view_asays, - /client/proc/view_msays, - /client/proc/view_devsays, - /client/proc/view_staffsays, - /client/proc/empty_ai_core_toggle_latejoin, - /client/proc/aooc, - /client/proc/freeze, - /client/proc/secrets, - /client/proc/debug_variables, - /client/proc/reset_all_tcs, /*resets all telecomms scripts*/ - /client/proc/toggle_mentor_chat, - /client/proc/toggle_advanced_interaction, /*toggle admin ability to interact with not only machines, but also atoms such as buttons and doors*/ - /client/proc/list_ssds_afks, - /client/proc/ccbdb_lookup_ckey, - /client/proc/view_instances, - /client/proc/start_vote, - /client/proc/ping_all_admins, - /client/proc/show_watchlist, - /client/proc/debugstatpanel, - /client/proc/create_rnd_restore_disk, - /client/proc/open_admin_zlevel_manager, -)) -GLOBAL_LIST_INIT(admin_verbs_ban, list( - /client/proc/ban_panel, - /datum/admins/proc/vpn_whitelist - )) -GLOBAL_LIST_INIT(admin_verbs_sounds, list( - /client/proc/play_local_sound, - /client/proc/play_sound, - /client/proc/play_server_sound, - /client/proc/play_intercomm_sound, - /client/proc/stop_global_admin_sounds, - /client/proc/stop_sounds_global, - /client/proc/play_sound_tgchat - )) -GLOBAL_LIST_INIT(admin_verbs_event, list( - /client/proc/object_talk, - /client/proc/cmd_admin_dress, - /client/proc/cmd_admin_gib_self, - /client/proc/drop_bomb, - /client/proc/disease_outbreak, - /client/proc/one_click_antag, - /client/proc/cmd_admin_add_freeform_ai_law, - /client/proc/cmd_admin_add_random_ai_law, - /client/proc/economy_manager, - /client/proc/everyone_random, - /client/proc/make_sound, - /client/proc/toggle_random_events, - /client/proc/toggle_random_events, - /client/proc/toggle_ert_calling, - /client/proc/set_holiday, - /client/proc/show_tip, - /client/proc/cmd_admin_change_custom_event, - /client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/ - /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_world_narrate, /*sends text to all players with no padding*/ - /client/proc/response_team, // Response Teams admin verb - /client/proc/cmd_admin_create_centcom_report, - /client/proc/fax_panel, - /client/proc/event_manager_panel, - /client/proc/modify_goals, - /client/proc/outfit_manager, - /client/proc/cmd_admin_headset_message, - /client/proc/change_human_appearance_admin, /* Allows an admin to change the basic appearance of human-based mobs */ - /client/proc/change_human_appearance_self, /* Allows the human-based mob itself to change its basic appearance */ - /datum/admins/proc/station_traits_panel, - /datum/admins/proc/toggle_ai, - )) +/client/proc/add_user_verbs() + SSuser_verbs.associate(src) -GLOBAL_LIST_INIT(admin_verbs_spawn, list( - /datum/admins/proc/spawn_atom, /*allows us to spawn instances*/ - /client/proc/respawn_character, - /client/proc/admin_deserialize, - /client/proc/create_crate, - /client/proc/json_spawn_menu - )) -GLOBAL_LIST_INIT(admin_verbs_server, list( - /client/proc/reload_admins, - /datum/admins/proc/startnow, - /datum/admins/proc/restart, - /datum/admins/proc/end_round, - /datum/admins/proc/delay, - /datum/admins/proc/toggleaban, - /datum/admins/proc/toggleenter, /*toggles whether people can join the current game*/ - /datum/admins/proc/toggleguests, /*toggles whether guests can join the current game*/ - /client/proc/toggle_log_hrefs, - /client/proc/toggle_antagHUD_use, - /client/proc/toggle_antagHUD_restrictions, - /client/proc/set_next_map, - /client/proc/manage_queue, - /client/proc/add_queue_server_bypass - )) -GLOBAL_LIST_INIT(admin_verbs_debug, list( - /client/proc/cmd_admin_list_open_jobs, - /client/proc/cmd_debug_make_powernets, - /client/proc/debug_controller, - /client/proc/cmd_debug_mob_lists, - /client/proc/cmd_debug_del_sing, - /client/proc/restart_controller, - /client/proc/enable_debug_verbs, - /client/proc/cmd_display_del_log, - /client/proc/cmd_display_del_log_simple, - /client/proc/check_bomb_impacts, - /client/proc/test_movable_UI, - /client/proc/test_snap_UI, - /proc/machine_upgrade, - /client/proc/map_template_load, - /client/proc/map_template_upload, - /client/proc/map_template_load_lazy, - /client/proc/view_runtimes, - /client/proc/admin_serialize, - /client/proc/uid_log, - /client/proc/reestablish_db_connection, - /client/proc/ss_breakdown, - #ifdef REFERENCE_TRACKING - /datum/proc/find_refs, - /datum/proc/qdel_then_find_references, - /datum/proc/qdel_then_if_fail_find_references, - #endif - /client/proc/dmapi_debug, - /client/proc/dmapi_log, - /client/proc/timer_log, - /client/proc/debug_timers, - /client/proc/force_verb_bypass, - /client/proc/show_gc_queues, - /client/proc/debug_global_variables, - /client/proc/raw_gas_scan, - /client/proc/teleport_interesting_turf, - /client/proc/visualize_interesting_turfs, - /client/proc/profile_code, - /client/proc/debug_atom_init, - /client/proc/debug_bloom, - /client/proc/cmd_mass_screenshot, - /client/proc/allow_browser_inspect, - /client/proc/view_bug_reports, - )) -GLOBAL_LIST_INIT(admin_verbs_possess, list( - /proc/possess, - /proc/release - )) -GLOBAL_LIST_INIT(admin_verbs_permissions, list( - /client/proc/edit_admin_permissions, - /client/proc/big_brother - )) -GLOBAL_LIST_INIT(admin_verbs_rejuv, list( - /client/proc/respawn_character, - /client/proc/cmd_admin_rejuvenate - )) -GLOBAL_LIST_INIT(admin_verbs_mod, list( - /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ - /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ - /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ - /datum/admins/proc/PlayerNotes, - /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ - /client/proc/cmd_mentor_say, - /datum/admins/proc/show_player_notes, - /client/proc/player_panel_new, - /client/proc/dsay, - /datum/admins/proc/show_player_panel, - /client/proc/ban_panel, - /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ - /client/proc/admin_observe, - /client/proc/admin_observe_target, -)) -GLOBAL_LIST_INIT(admin_verbs_mentor, list( - /client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/ - /client/proc/cmd_admin_pm_panel, /*admin-pm list*/ - /client/proc/cmd_admin_pm_by_key_panel, /*admin-pm list by key*/ - /client/proc/openMentorTicketUI, - /client/proc/admin_observe, /* Allow mentors to observe as well, though they face some limitations */ - /client/proc/admin_observe_target, - /client/proc/cmd_mentor_say, /* mentor say*/ - /client/proc/view_msays, - /client/proc/cmd_staff_say, - // cmd_mentor_say is added/removed by the toggle_mentor_chat verb -)) -GLOBAL_LIST_INIT(admin_verbs_dev, list( - /client/proc/cmd_dev_say, - /client/proc/view_devsays, - /client/proc/cmd_staff_say, - /client/proc/view_staffsays -)) -GLOBAL_LIST_INIT(admin_verbs_proccall, list( - /client/proc/callproc, - /client/proc/callproc_datum, - /client/proc/SDQL2_query, - /client/proc/load_sdql2_query, -)) -GLOBAL_LIST_INIT(admin_verbs_ticket, list( - /client/proc/openAdminTicketUI, - /client/proc/openMentorTicketUI, - /client/proc/resolveAllAdminTickets, - /client/proc/resolveAllMentorTickets -)) -// In this list are verbs that should ONLY be executed by maintainers, aka people who know how badly this will break the server -// If you are adding something here, you MUST justify it -GLOBAL_LIST_INIT(admin_verbs_maintainer, list( - /client/proc/ticklag, // This adjusts the server tick rate and is VERY easy to hard lockup the server with - /client/proc/debugNatureMapGenerator, // This lags like hell, and is very easy to nuke half the server with - /client/proc/vv_by_ref, // This allows you to lookup **ANYTHING** in the server memory by spamming refs. Locked for security. - /client/proc/cinematic, // This will break everyone's screens in the round. Dont use this for adminbus. - /client/proc/throw_runtime, // Do I even need to explain why this is locked? -)) -GLOBAL_LIST_INIT(view_runtimes_verbs, list( - /client/proc/view_runtimes, - /client/proc/cmd_display_del_log, - /client/proc/cmd_display_del_log_simple, - /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ - /client/proc/ss_breakdown, - /client/proc/show_gc_queues, - /client/proc/debug_global_variables, - /client/proc/debug_timers, - /client/proc/timer_log, - /client/proc/raw_gas_scan, - /client/proc/teleport_interesting_turf, - /client/proc/visualize_interesting_turfs, - /client/proc/profile_code, - /client/proc/view_bug_reports, -)) -GLOBAL_LIST_INIT(view_logs_verbs, list( - /client/proc/getserverlogs, - /client/proc/get_server_logs_by_round_id, -)) +/client/proc/remove_user_verbs() + SSuser_verbs.deassociate(src) -/client/proc/add_admin_verbs() - if(holder) - // If they have ANYTHING OTHER THAN ONLY VIEW RUNTIMES AND/OR DEV, then give them the default admin verbs - if(holder.rights & ~(R_VIEWRUNTIMES|R_DEV_TEAM)) - add_verb(src, GLOB.admin_verbs_default) - if(holder.rights & R_BUILDMODE) - add_verb(src, /client/proc/togglebuildmodeself) - if(holder.rights & R_ADMIN) - add_verb(src, GLOB.admin_verbs_admin) - add_verb(src, GLOB.admin_verbs_ticket) - spawn(1) - control_freak = 0 - if(holder.rights & R_BAN) - add_verb(src, GLOB.admin_verbs_ban) - if(holder.rights & R_EVENT) - add_verb(src, GLOB.admin_verbs_event) - if(holder.rights & R_SERVER) - add_verb(src, GLOB.admin_verbs_server) - if(holder.rights & R_DEBUG) - add_verb(src, GLOB.admin_verbs_debug) - spawn(1) - control_freak = 0 // Setting control_freak to 0 allows you to use the Profiler and other client-side tools - if(holder.rights & R_POSSESS) - add_verb(src, GLOB.admin_verbs_possess) - if(holder.rights & R_PERMISSIONS) - add_verb(src, GLOB.admin_verbs_permissions) - if(holder.rights & R_STEALTH) - add_verb(src, /client/proc/stealth) - if(holder.rights & R_REJUVINATE) - add_verb(src, GLOB.admin_verbs_rejuv) - if(holder.rights & R_SOUNDS) - add_verb(src, GLOB.admin_verbs_sounds) - if(holder.rights & R_SPAWN) - add_verb(src, GLOB.admin_verbs_spawn) - if(holder.rights & R_MOD) - add_verb(src, GLOB.admin_verbs_mod) - if(holder.rights & R_MENTOR) - add_verb(src, GLOB.admin_verbs_mentor) - if(holder.rights & R_PROCCALL) - add_verb(src, GLOB.admin_verbs_proccall) - if(holder.rights & R_MAINTAINER) - add_verb(src, GLOB.admin_verbs_maintainer) - if(holder.rights & R_VIEWRUNTIMES) - add_verb(src, GLOB.view_runtimes_verbs) - spawn(1) // This setting exposes the profiler for people with R_VIEWRUNTIMES. They must still have it set in cfg/admin.txt - control_freak = 0 - if(holder.rights & R_DEV_TEAM) - add_verb(src, GLOB.admin_verbs_dev) - if(holder.rights & R_VIEWLOGS) - add_verb(src, GLOB.view_logs_verbs) - if(is_connecting_from_localhost()) - add_verb(src, /client/proc/export_current_character) +USER_VERB(hide_verbs, R_NONE, "Adminverbs - Hide All", "Hide most of your admin verbs.", VERB_CATEGORY_ADMIN) + client.remove_user_verbs() + add_verb(client, /client/proc/show_verbs) -/client/proc/hide_verbs() - set name = "Adminverbs - Hide All" - set category = "Admin" - - if(!holder) - return - - remove_verb(src, list( - /client/proc/togglebuildmodeself, - /client/proc/stealth, - /client/proc/readmin, - /client/proc/cmd_dev_say, - /client/proc/export_current_character, - GLOB.admin_verbs_default, - GLOB.admin_verbs_admin, - GLOB.admin_verbs_ban, - GLOB.admin_verbs_event, - GLOB.admin_verbs_server, - GLOB.admin_verbs_debug, - GLOB.admin_verbs_possess, - GLOB.admin_verbs_permissions, - GLOB.admin_verbs_rejuv, - GLOB.admin_verbs_sounds, - GLOB.admin_verbs_spawn, - GLOB.admin_verbs_mod, - GLOB.admin_verbs_mentor, - GLOB.admin_verbs_proccall, - GLOB.admin_verbs_show_debug_verbs, - GLOB.admin_verbs_ticket, - GLOB.admin_verbs_maintainer, - GLOB.admin_verbs_dev - )) - add_verb(src, /client/proc/show_verbs) - - to_chat(src, "Almost all of your adminverbs have been hidden.") + to_chat(client, "Almost all of your adminverbs have been hidden.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Hide Admin Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return /client/proc/show_verbs() set name = "Adminverbs - Show" - set category = "Admin" - - if(!holder) - return + set category = VERB_CATEGORY_ADMIN remove_verb(src, /client/proc/show_verbs) - add_admin_verbs() + add_user_verbs() to_chat(src, "All of your adminverbs are now visible.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Admin Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! @@ -423,46 +63,35 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( // TODO: SStgui.on_transfer() to move windows from old and new SSblackbox.record_feedback("tally", "admin_verb", 1, "Aghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/admin_ghost() - set category = "Admin" - set name = "Aghost" - - if(!check_rights(R_ADMIN|R_MOD)) - return - - do_aghost() +USER_VERB(admin_ghost, R_ADMIN|R_MOD, "Aghost", "Aghost self.", VERB_CATEGORY_ADMIN) + client.do_aghost() /// Allow an admin to observe someone. /// mentors are allowed to use this verb while living, but with some stipulations: /// if they attempt to do anything that would stop their orbit, they will immediately be returned to their body. -/client/proc/admin_observe() - set name = "Aobserve" - set category = "Admin" - if(!check_rights(R_ADMIN|R_MOD|R_MENTOR)) - return - - if(isnewplayer(mob)) - to_chat(src, "You cannot aobserve while in the lobby. Please join or observe first.") +USER_VERB(admin_observe, R_ADMIN|R_MOD|R_MENTOR, "Aobserve", "Admin-observe a player mob.", VERB_CATEGORY_ADMIN) + if(isnewplayer(client.mob)) + to_chat(client, "You cannot aobserve while in the lobby. Please join or observe first.") return var/mob/target - target = tgui_input_list(mob, "Select a mob to observe", "Aobserve", GLOB.player_list) + target = tgui_input_list(client, "Select a mob to observe", "Aobserve", GLOB.player_list) if(isnull(target)) return - if(target == src) - to_chat(src, "You can't observe yourself!") + if(target == client) + to_chat(client, "You can't observe yourself!") return if(isobserver(target)) - to_chat(src, "[target] is a ghost, and cannot be observed.") + to_chat(client, "[target] is a ghost, and cannot be observed.") return if(isnewplayer(target)) - to_chat(src, "[target] is in the lobby, and cannot be observed.") + to_chat(client, "[target] is in the lobby, and cannot be observed.") return - admin_observe_target(target) + SSuser_verbs.invoke_verb(client, /datum/user_verb/admin_observe_target, target) /client/proc/cleanup_admin_observe(mob/dead/observer/ghost) if(!istype(ghost) || !ghost.mob_observed) @@ -475,63 +104,54 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( // handler will handle removing the trait mob.stop_orbit() log_admin("[key_name(src)] has de-activated Aobserve") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Aobserve") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Aobserve") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return TRUE -/// targeted form of admin_observe: this should only appear in the right-click menu. -/client/proc/admin_observe_target(mob/target as mob in GLOB.mob_list) - set name = "\[Admin\] Aobserve" - set category = null - - if(!check_rights(R_ADMIN|R_MOD|R_MENTOR, mob)) - return - - var/full_admin = check_rights(R_ADMIN|R_MOD, FALSE, mob) - - if(isnewplayer(mob)) - to_chat(src, "You cannot aobserve while in the lobby. Please join or observe first.") +USER_CONTEXT_MENU(admin_observe_target, R_ADMIN|R_MOD|R_MENTOR, "\[Admin\] Aobserve", mob/target as mob) + if(isnewplayer(client.mob)) + to_chat(client, "You cannot aobserve while in the lobby. Please join or observe first.") return if(isnewplayer(target)) - to_chat(src, "[target] is currently in the lobby.") + to_chat(client, "[target] is currently in the lobby.") return if(isobserver(target)) - to_chat(src, "You can't observe a ghost.") + to_chat(client, "You can't observe a ghost.") return - var/mob/dead/observer/observer = mob + var/mob/dead/observer/observer = client.mob if(istype(observer) && target == locateUID(observer.mob_observed)) - cleanup_admin_observe(mob) + client.cleanup_admin_observe(client.mob) return - cleanup_admin_observe(mob) + client.cleanup_admin_observe(client.mob) - if(isnull(target) || target == src) + if(isnull(target) || target == client.mob) // let the default one find the target if there isn't one - admin_observe() + SSuser_verbs.invoke_verb(client, /datum/user_verb/admin_observe) return // observers don't need to ghost, so we don't need to worry about adding any traits - if(isobserver(mob)) - var/mob/dead/observer/ghost = mob - SSblackbox.record_feedback("tally", "admin_verb", 1, "Aobserve") + if(isobserver(client.mob)) + var/mob/dead/observer/ghost = client.mob + SSblackbox.record_feedback("tally", "admin_verb", 1, "Aobserve") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! ghost.do_observe(target) return - log_admin("[key_name(src)] has Aobserved out of their body to follow [target]") - do_aghost() - var/mob/dead/observer/ghost = mob + log_admin("[key_name(client)] has Aobserved out of their body to follow [target]") + client.do_aghost() + var/mob/dead/observer/ghost = client.mob + var/full_admin = check_rights_client(R_ADMIN|R_MOD, FALSE, client) if(!full_admin) // if they're a me and they're alive, add the MENTOR_OBSERVINGtrait to ensure that they can only go back to their body. // we need to handle this here because when you aghost, your mob gets set to the ghost. Oops! - ADD_TRAIT(mob.mind, TRAIT_MENTOR_OBSERVING, MENTOR_OBSERVING) - RegisterSignal(ghost, COMSIG_ATOM_ORBITER_STOP, PROC_REF(on_mentor_observe_end), override = TRUE) - to_chat(src, "You have temporarily observed [target], either move or observe again to un-observe.") - log_admin("[key_name(src)] has mobserved out of their body to follow [target].") + ADD_TRAIT(client.mob.mind, TRAIT_MENTOR_OBSERVING, MENTOR_OBSERVING) + RegisterSignal(ghost, COMSIG_ATOM_ORBITER_STOP, TYPE_PROC_REF(/client, on_mentor_observe_end), override = TRUE) + to_chat(client, "You have temporarily observed [target], either move or observe again to un-observe.") + log_admin("[key_name(client)] has mobserved out of their body to follow [target].") else - log_admin("[key_name(src)] is aobserving [target].") - + log_admin("[key_name(client)] is aobserving [target].") ghost.do_observe(target) @@ -554,96 +174,50 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( log_and_message_admins("[key_name_mentor(src)] was unable to re-enter their body after mentor observing.") to_chat(src, "Unable to return you to your body after mentor ghosting. If your body still exists, please contact a coder, and you should probably ahelp.") -/client/proc/invisimin() - set name = "Invisimin" - set category = "Admin" - set desc = "Toggles ghost-like invisibility (Don't abuse this)" - - if(!check_rights(R_ADMIN)) - return - if(!isliving(mob)) +USER_VERB(invisimin, R_ADMIN, "Invisimin", "Toggles ghost-like invisibility (Don't abuse this)", VERB_CATEGORY_ADMIN) + if(!isliving(client.mob)) return - if(mob.invisibility == INVISIBILITY_OBSERVER) - mob.invisibility = initial(mob.invisibility) - mob.add_to_all_human_data_huds() - to_chat(mob, "Invisimin off. Invisibility reset.") - log_admin("[key_name(mob)] has turned Invisimin OFF") + var/mob/living/client_mob = client.mob + if(client_mob.invisibility == INVISIBILITY_OBSERVER) + client_mob.invisibility = initial(client_mob.invisibility) + client_mob.add_to_all_human_data_huds() + to_chat(client, "Invisimin off. Invisibility reset.") + log_admin("[key_name(client)] has turned Invisimin OFF") else - mob.invisibility = INVISIBILITY_OBSERVER - mob.remove_from_all_data_huds() - to_chat(mob, "Invisimin on. You are now as invisible as a ghost.") - log_admin("[key_name(mob)] has turned Invisimin ON") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Invisimin") + client_mob.invisibility = INVISIBILITY_OBSERVER + client_mob.remove_from_all_data_huds() + to_chat(client, "Invisimin on. You are now as invisible as a ghost.") + log_admin("[key_name(client)] has turned Invisimin ON") -/client/proc/player_panel_new() - set name = "Player Panel" - set category = "Admin" + SSblackbox.record_feedback("tally", "admin_verb", 1, "Invisimin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - if(!check_rights(R_ADMIN|R_MOD)) - return - - holder.player_panel_new() +USER_VERB(player_panel, R_ADMIN|R_MOD, "Player Panel", "Opens the player panel.", VERB_CATEGORY_ADMIN) + client.holder.player_panel_new() 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! - return -/client/proc/check_antagonists() - set name = "Check Antagonists" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - holder.check_antagonists() - log_admin("[key_name(usr)] checked antagonists") +USER_VERB(check_antagonists, R_ADMIN, "Check Antagonists", "Open the Antagonists panel.", VERB_CATEGORY_ADMIN) + client.holder.check_antagonists() + log_admin("[key_name(client)] checked antagonists") SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Antags") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return - -/client/proc/check_antagonists2() - set name = "TGUI - Antagonists" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return +USER_VERB(check_antagonists_tgui, R_ADMIN, "TGUI - Antagonists", "Open the TGUI Antagonists panel.", VERB_CATEGORY_ADMIN) var/datum/ui_module/admin = get_admin_ui_module(/datum/ui_module/admin/antagonist_menu) - admin.ui_interact(usr) - log_admin("[key_name(usr)] checked antagonists") + admin.ui_interact(client.mob) + log_admin("[key_name(client)] checked antagonists") SSblackbox.record_feedback("tally", "admin_verb", 1, "Check Antags2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return -/client/proc/ban_panel() - set name = "Ban Panel" - set category = "Admin" - - if(!check_rights(R_BAN)) - return - - holder.DB_ban_panel() +USER_VERB(ban_panel, R_BAN, "Ban Panel", "Opens the ban panel.", VERB_CATEGORY_ADMIN) + client.holder.DB_ban_panel() SSblackbox.record_feedback("tally", "admin_verb", 1, "Ban Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return -/client/proc/game_panel() - set name = "Game Panel" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - holder.Game() +USER_VERB(game_panel, R_ADMIN, "Game Panel", "Opens the game panel.", VERB_CATEGORY_ADMIN) + client.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! - return -/client/proc/secrets() - set name = "Secrets" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - holder.Secrets() +USER_VERB(secrets_panel, R_ADMIN, "Secrets", "Opens the secrets panel.", VERB_CATEGORY_ADMIN) + client.holder.Secrets() SSblackbox.record_feedback("tally", "admin_verb", 1, "Secrets") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return /client/proc/getStealthKey() return GLOB.stealthminID[ckey] @@ -659,105 +233,81 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( i = 0 GLOB.stealthminID["[ckey]"] = "@[num2text(num)]" -/client/proc/stealth() - set category = "Admin" - set name = "Stealth Mode" - - if(!check_rights(R_ADMIN)) - return - - if(holder) +USER_VERB(stealth_mode, R_ADMIN, "Stealth Mode", "Enables stealth mode.", VERB_CATEGORY_ADMIN) + var/datum/admins/holder = client.holder + if(istype(holder)) holder.big_brother = 0 if(holder.fakekey) holder.fakekey = null else - var/new_key = ckeyEx(clean_input("Enter your desired display name.", "Fake Key", key)) + var/new_key = ckeyEx(clean_input("Enter your desired display name.", "Fake Key", client.key, user = client)) if(!new_key) return if(length(new_key) >= 26) new_key = copytext(new_key, 1, 26) holder.fakekey = new_key - createStealthKey() - log_admin("[key_name(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]") - message_admins("[key_name_admin(usr)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", 1) + client.createStealthKey() + log_admin("[key_name(client)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]") + message_admins("[key_name_admin(client)] has turned stealth mode [holder.fakekey ? "ON" : "OFF"]", 1) 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! -/client/proc/big_brother() - set category = "Admin" - set name = "Big Brother Mode" - - if(!check_rights(R_PERMISSIONS)) - return - +USER_VERB(big_brother, R_PERMISSIONS, "Big Brother Mode", "Enables Big Brother mode.", VERB_CATEGORY_ADMIN) + var/datum/admins/holder = client.holder if(holder) if(holder.fakekey) holder.fakekey = null holder.big_brother = 0 else - var/new_key = ckeyEx(clean_input("Enter your desired display name. Unlike normal stealth mode, this will not appear in Who at all, except for other heads.", "Fake Key", key)) + var/new_key = ckeyEx(clean_input("Enter your desired display name. Unlike normal stealth mode, this will not appear in Who at all, except for other heads.", "Fake Key", client.key, user = client)) if(!new_key) return if(length(new_key) >= 26) new_key = copytext(new_key, 1, 26) holder.fakekey = new_key holder.big_brother = 1 - if(isobserver(mob)) - mob.invisibility = 90 - mob.see_invisible = 90 - createStealthKey() - log_admin("[key_name(usr)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]", TRUE) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Big Brother Mode") + if(isobserver(client.mob)) + client.mob.invisibility = 90 + client.mob.see_invisible = 90 + client.createStealthKey() + log_admin("[key_name(client)] has turned BB mode [holder.fakekey ? "ON" : "OFF"]", TRUE) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Big Brother Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/drop_bomb() // Some admin dickery that can probably be done better -- TLE - set category = "Event" - set name = "Drop Bomb" - set desc = "Cause an explosion of varying strength at your location." - - if(!check_rights(R_EVENT)) - return - - var/turf/epicenter = mob.loc +USER_VERB(drop_bomb, R_EVENT, "Drop Bomb", "Cause an explosion of varying strength at your location.", VERB_CATEGORY_EVENT) + var/turf/epicenter = client.mob.loc var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb") - var/choice = tgui_input_list(src, "What size explosion would you like to produce?", "Drop Bomb", choices) + var/choice = tgui_input_list(client, "What size explosion would you like to produce?", "Drop Bomb", choices) switch(choice) if(null) return 0 if("Small Bomb") - explosion(epicenter, 1, 2, 3, 3, cause = "[ckey]: Drop Bomb command") + explosion(epicenter, 1, 2, 3, 3, cause = "[client.ckey]: Drop Bomb command") if("Medium Bomb") - explosion(epicenter, 2, 3, 4, 4, cause = "[ckey]: Drop Bomb command") + explosion(epicenter, 2, 3, 4, 4, cause = "[client.ckey]: Drop Bomb command") if("Big Bomb") - explosion(epicenter, 3, 5, 7, 5, cause = "[ckey]: Drop Bomb command") + explosion(epicenter, 3, 5, 7, 5, cause = "[client.ckey]: Drop Bomb command") if("Custom Bomb") - var/devastation_range = tgui_input_number(src, "Devastation range (in tiles):", "Custom Bomb", max_value = 255) + var/devastation_range = tgui_input_number(client, "Devastation range (in tiles):", "Custom Bomb", max_value = 255) if(isnull(devastation_range)) return - var/heavy_impact_range = tgui_input_number(src, "Heavy impact range (in tiles):", "Custom Bomb", max_value = 255) + var/heavy_impact_range = tgui_input_number(client, "Heavy impact range (in tiles):", "Custom Bomb", max_value = 255) if(isnull(heavy_impact_range)) return - var/light_impact_range = tgui_input_number(src, "Light impact range (in tiles):", "Custom Bomb", max_value = 255) + var/light_impact_range = tgui_input_number(client, "Light impact range (in tiles):", "Custom Bomb", max_value = 255) if(isnull(light_impact_range)) return - var/flash_range = tgui_input_number(src, "Flash range (in tiles):", "Custom Bomb", max_value = 255) + var/flash_range = tgui_input_number(client, "Flash range (in tiles):", "Custom Bomb", max_value = 255) if(isnull(flash_range)) return - explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, 1, 1, cause = "[ckey]: Drop Bomb command") - log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc]") - message_admins("[key_name_admin(usr)] created an admin explosion at [epicenter.loc]") + explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, 1, 1, cause = "[client.ckey]: Drop Bomb command") + log_admin("[key_name(client)] created an admin explosion at [epicenter.loc]") + message_admins("[key_name_admin(client)] 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/give_spell(mob/T as mob in GLOB.mob_list) // -- Urist - set category = "Event" - set name = "Give Spell" - set desc = "Gives a spell to a mob." - - if(!check_rights(R_EVENT)) - return - +USER_VERB(give_spell, R_EVENT, "Give Spell", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T) var/list/spell_list = list() var/type_length = length("/datum/spell") + 2 for(var/A in GLOB.spells) spell_list[copytext("[A]", type_length)] = A - var/datum/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list + var/datum/spell/S = input(client, "Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list if(!S) return S = spell_list[S] @@ -767,19 +317,16 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( T.AddSpell(new S) 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(T)] the spell [S].") - message_admins("[key_name_admin(usr)] gave [key_name(T)] the spell [S].", 1) + log_admin("[key_name(client)] gave [key_name(T)] the spell [S].") + message_admins("[key_name_admin(client)] gave [key_name(T)] the spell [S].", 1) -/client/proc/give_disease(mob/T in GLOB.mob_list) - set category = "Event" - set name = "Give Disease" - set desc = "Gives a Disease to a mob." +USER_VERB(give_disease, R_EVENT, "Give Disease", VERB_NO_DESCRIPTION, VERB_CATEGORY_HIDDEN, mob/T) var/datum/disease/given_disease = null - if(tgui_input_list(usr, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes") - given_disease = AdminCreateVirus(usr) + if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes") + given_disease = AdminCreateVirus(client) else - given_disease = tgui_input_list(usr, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases) + given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases) if(!given_disease) return @@ -788,18 +335,15 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( given_disease = new given_disease T.ForceContractDisease(given_disease) 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 [given_disease].") - message_admins("[key_name_admin(usr)] gave [key_name(T)] the disease [given_disease].") + log_admin("[key_name(client)] gave [key_name(T)] the disease [given_disease].") + message_admins("[key_name_admin(client)] gave [key_name(T)] the disease [given_disease].") -/client/proc/disease_outbreak() - set category = "Event" - set name = "Disease Outbreak" - set desc = "Creates a disease and infects a random player with it" +USER_VERB(disease_outbreak, R_EVENT, "Disease Outbreak", "Creates a disease and infects a random player with it.", VERB_CATEGORY_EVENT) var/datum/disease/given_disease = null - if(tgui_input_list(usr, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes") - given_disease = AdminCreateVirus(usr) + if(tgui_input_list(client, "Create own disease", "Would you like to create your own disease?", list("Yes","No")) == "Yes") + given_disease = AdminCreateVirus(client) else - given_disease = tgui_input_list(usr, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases) + given_disease = tgui_input_list(client, "ACHOO", "Choose the disease to give to that guy", GLOB.diseases) if(!given_disease) return @@ -818,118 +362,71 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( var/list/name_symptoms = list() for(var/datum/symptom/S in given_advanced_disease.symptoms) name_symptoms += S.name - message_admins("[key_name_admin(usr)] has triggered a custom virus outbreak of [given_advanced_disease.name]! It has these symptoms: [english_list(name_symptoms)] and these base stats [english_map(given_advanced_disease.base_properties)]") + message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_advanced_disease.name]! It has these symptoms: [english_list(name_symptoms)] and these base stats [english_map(given_advanced_disease.base_properties)]") else - message_admins("[key_name_admin(usr)] has triggered a custom virus outbreak of [given_disease.name]!") - -/client/proc/make_sound(obj/O in view()) // -- TLE - set name = "\[Admin\] Make Sound" - set desc = "Display a message to everyone who can hear the target" - - if(!check_rights(R_EVENT)) - return + message_admins("[key_name_admin(client)] has triggered a custom virus outbreak of [given_disease.name]!") +USER_CONTEXT_MENU(make_sound, R_EVENT, "\[Admin\] Make Sound", obj/O in view()) if(O) - var/message = clean_input("What do you want the message to be?", "Make Sound") + var/message = clean_input("What do you want the message to be?", "Make Sound", user = client) if(!message) return for(var/mob/V in hearers(O)) V.show_message(admin_pencode_to_html(message), 2) - log_admin("[key_name(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") - message_admins("[key_name_admin(usr)] made [O] at [O.x], [O.y], [O.z] make a sound") + log_admin("[key_name(client)] made [O] at [O.x], [O.y], [O.z] make a sound") + message_admins("[key_name_admin(client)] made [O] at [O.x], [O.y], [O.z] make a sound") SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Sound") //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 = "Event" - - if(!check_rights(R_EVENT)) - return - - if(src.mob) - togglebuildmode(src.mob) +USER_VERB(toggle_build_mode_self, R_EVENT, "Toggle Build Mode Self", "Toggle Build Mode on yourself.", VERB_CATEGORY_EVENT) + if(client.mob) + togglebuildmode(client.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! -/client/proc/object_talk(msg as text) // -- TLE - set name = "oSay" - set desc = "Display a message to everyone who can hear the target" - - if(!check_rights(R_EVENT)) - return - +USER_VERB(object_talk, R_EVENT, "oSay", "Display a message to everyone who can hear the target", VERB_CATEGORY_EVENT, msg as text) + var/mob/living/mob = client.mob if(mob.control_object) if(!msg) return for(var/mob/V in hearers(mob.control_object)) V.show_message("[mob.control_object.name] says: \"" + msg + "\"", 2) - log_admin("[key_name(usr)] used oSay on [mob.control_object]: [msg]") - message_admins("[key_name_admin(usr)] used oSay on [mob.control_object]: [msg]") + log_admin("[key_name(client)] used oSay on [mob.control_object]: [msg]") + message_admins("[key_name_admin(client)] used oSay on [mob.control_object]: [msg]") SSblackbox.record_feedback("tally", "admin_verb", 1, "oSay") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/deadmin_self() - set name = "De-admin self" - set category = "Admin" - - if(!check_rights(R_ADMIN|R_MENTOR)) - return - - log_admin("[key_name(usr)] deadmined themself.") - message_admins("[key_name_admin(usr)] deadmined themself.") - deadmin() - to_chat(src, "You are now a normal player.") +USER_VERB(deadmin_self, R_ADMIN|R_MENTOR, "De-admin self", "De-admin yourself.", VERB_CATEGORY_ADMIN) + log_admin("[key_name(client)] deadmined themself.") + message_admins("[key_name_admin(client)] deadmined themself.") + client.deadmin() + to_chat(client, "You are now a normal player.") SSblackbox.record_feedback("tally", "admin_verb", 1, "De-admin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/toggle_log_hrefs() - set name = "Toggle href logging" - set category = "Server" - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(toggle_log_hrefs, R_SERVER, "Toggle href logging", "Toggle href logging", VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return // Why would we ever turn this off? if(GLOB.configuration.logging.href_logging) GLOB.configuration.logging.href_logging = FALSE - to_chat(src, "Stopped logging hrefs") + to_chat(client, "Stopped logging hrefs") else GLOB.configuration.logging.href_logging = TRUE - to_chat(src, "Started logging hrefs") + to_chat(client, "Started logging hrefs") -/client/proc/check_ai_laws() - set name = "Check AI Laws" - set category = "Admin" +USER_VERB(check_ai_laws, R_ADMIN, "Check AI Laws", "Output AI laws.", VERB_CATEGORY_ADMIN) + client.holder.output_ai_laws() - if(!check_rights(R_ADMIN)) - return - - holder.output_ai_laws() - -/client/proc/manage_silicon_laws() - set name = "Manage Silicon Laws" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - var/mob/living/silicon/S = input("Select silicon.", "Manage Silicon Laws") as null|anything in GLOB.silicon_mob_list +USER_VERB(open_law_manager, R_ADMIN, "Manage Silicon Laws", "Open the law manager.", VERB_CATEGORY_ADMIN) + var/mob/living/silicon/S = input(client, "Select silicon.", "Manage Silicon Laws") as null|anything in GLOB.silicon_mob_list if(!S) return var/datum/ui_module/law_manager/L = new(S) - L.ui_interact(usr) + L.ui_interact(client.mob) log_and_message_admins("has opened [S]'s law manager.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Silicon Laws") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/change_human_appearance_admin(mob/living/carbon/human/H in GLOB.mob_list) - set name = "\[Admin\] C.M.A. - Admin" - set desc = "Allows you to change the mob appearance" - - if(!check_rights(R_EVENT)) - return - +USER_CONTEXT_MENU(change_human_appearance, R_EVENT, "\[Admin\] C.M.A. - Admin", mob/living/carbon/human/H in GLOB.mob_list) if(!istype(H)) if(isbrain(H)) var/mob/living/brain/B = H @@ -943,18 +440,12 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( else return - if(holder) + if(client.holder) log_and_message_admins("is altering the appearance of [H].") - H.change_appearance(APPEARANCE_ALL, usr, usr, check_species_whitelist = 0) + H.change_appearance(APPEARANCE_ALL, client.mob, client.mob, check_species_whitelist = 0) SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Admin") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/change_human_appearance_self(mob/living/carbon/human/H in GLOB.mob_list) - set name = "\[Admin\] C.M.A. - Self" - set desc = "Allows the mob to change its appearance" - - if(!check_rights(R_EVENT)) - return - +USER_CONTEXT_MENU(change_human_appearance_self, R_EVENT, "\[Admin\] C.M.A. - Self",mob/living/carbon/human/H in GLOB.mob_list) if(!istype(H)) if(isbrain(H)) var/mob/living/brain/B = H @@ -969,10 +460,10 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( return if(!H.client) - to_chat(usr, "Only mobs with clients can alter their own appearance.") + to_chat(client, "Only mobs with clients can alter their own appearance.") return - switch(alert("Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) + switch(alert(client, "Do you wish for [H] to be allowed to select non-whitelisted races?","Alter Mob Appearance","Yes","No","Cancel")) if("Yes") log_and_message_admins("has allowed [H] to change [H.p_their()] appearance, without whitelisting of races.") H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 0) @@ -981,190 +472,126 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( H.change_appearance(APPEARANCE_ALL, H.loc, check_species_whitelist = 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "CMA - Self") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/free_slot() - set name = "Free Job Slot" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(free_job_slot, R_ADMIN, "Free Job Slot", "Frees a station job role.", VERB_CATEGORY_ADMIN) var/list/jobs = list() for(var/datum/job/J in SSjobs.occupations) if(J.current_positions >= J.total_positions && J.total_positions != -1) jobs += J.title if(!length(jobs)) - to_chat(usr, "There are no fully staffed jobs.") + to_chat(client, "There are no fully staffed jobs.") return - var/job = input("Please select job slot to free", "Free Job Slot") as null|anything in jobs + var/job = input(client, "Please select job slot to free", "Free Job Slot") as null|anything in jobs if(job) SSjobs.FreeRole(job, force = TRUE) - log_admin("[key_name(usr)] has freed a job slot for [job].") - message_admins("[key_name_admin(usr)] has freed a job slot for [job].") - -/client/proc/man_up(mob/T as mob in GLOB.player_list) - set name = "\[Admin\] Man Up" - set desc = "Tells mob to man up and deal with it." - - if(!check_rights(R_ADMIN)) - return + log_admin("[key_name(client)] has freed a job slot for [job].") + message_admins("[key_name_admin(client)] has freed a job slot for [job].") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Free Job Slot") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +USER_CONTEXT_MENU(man_up, R_ADMIN, "\[Admin\] Man Up", mob/T as mob in GLOB.player_list) to_chat(T, chat_box_notice_thick("Man up.
    Deal with it.

    Move on.
    ")) SEND_SOUND(T, sound('sound/voice/manup1.ogg')) - log_admin("[key_name(usr)] told [key_name(T)] to man up and deal with it.") - message_admins("[key_name_admin(usr)] told [key_name(T)] to man up and deal with it.") + log_admin("[key_name(client)] told [key_name(T)] to man up and deal with it.") + message_admins("[key_name_admin(client)] told [key_name(T)] to man up and deal with it.") -/client/proc/global_man_up() - set category = "Admin" - set name = "Man Up Global" - set desc = "Tells everyone to man up and deal with it." - - if(!check_rights(R_ADMIN)) - return - - if(tgui_alert(usr, "Are you sure you want to send the global message?", "Confirm Man Up Global", list("Yes", "No")) == "Yes") +USER_VERB(global_man_up, R_ADMIN, "Man Up Global", "Tells everyone to man up and deal with it.", VERB_CATEGORY_ADMIN) + if(tgui_alert(client, "Are you sure you want to send the global message?", "Confirm Man Up Global", list("Yes", "No")) == "Yes") var/manned_up_sound = sound('sound/voice/manup1.ogg') for(var/sissy in GLOB.player_list) to_chat(sissy, chat_box_notice_thick("Man up.
    Deal with it.

    Move on.
    ")) SEND_SOUND(sissy, manned_up_sound) - log_admin("[key_name(usr)] told everyone to man up and deal with it.") - message_admins("[key_name_admin(usr)] told everyone to man up and deal with it.") + log_admin("[key_name(client)] told everyone to man up and deal with it.") + message_admins("[key_name_admin(client)] told everyone to man up and deal with it.") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Man Up Global") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/toggle_advanced_interaction() - set name = "Toggle Advanced Admin Interaction" - set category = "Admin" - set desc = "Allows you to interact with atoms such as buttons and doors, on top of regular machinery interaction." +USER_VERB(toggle_advanced_interaction, R_ADMIN, "Toggle Advanced Admin Interaction", \ + "Allows you to interact with atoms such as buttons and doors, on top of regular machinery interaction.", VERB_CATEGORY_ADMIN) + client.advanced_admin_interaction = !client.advanced_admin_interaction - if(!check_rights(R_ADMIN)) - return + log_admin("[key_name(client)] has [client.advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.") + message_admins("[key_name_admin(client)] has [client.advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.") - advanced_admin_interaction = !advanced_admin_interaction - - log_admin("[key_name(usr)] has [advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.") - message_admins("[key_name_admin(usr)] has [advanced_admin_interaction ? "activated" : "deactivated"] their advanced admin interaction.") - -/client/proc/show_watchlist() - set name = "Show Watchlist" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - watchlist_show() - -/client/proc/cmd_admin_alert_message(mob/about_to_be_banned) - set name = "Send Alert Message" - set category = "Admin" +USER_VERB(show_watchlist, R_ADMIN, "Show Watchlist", "Show the watchlist.", VERB_CATEGORY_ADMIN) + client.watchlist_show() +USER_VERB(send_alert_message, R_ADMIN, "Send Alert Message", "Sends a large notice to a player.", VERB_CATEGORY_ADMIN, mob/about_to_be_banned) if(!ismob(about_to_be_banned)) return - if(!check_rights(R_ADMIN)) - return - var/default_text = "An admin is trying to talk to you!\nCheck your chat window and click their name to respond or you may be banned!" - var/new_text = tgui_input_text(src, "Input your message, or use the default.", "Admin Message - Text Selector", default_text, 500, TRUE) + var/new_text = tgui_input_text(client, "Input your message, or use the default.", "Admin Message - Text Selector", default_text, 500, TRUE) if(!new_text) return if(default_text == new_text) show_blurb(about_to_be_banned, 15, new_text, null, "center", "center", COLOR_RED, null, null, 1) - log_admin("[key_name(src)] sent a default admin alert to [key_name(about_to_be_banned)].") - message_admins("[key_name(src)] sent a default admin alert to [key_name(about_to_be_banned)].") + log_admin("[key_name(client)] sent a default admin alert to [key_name(about_to_be_banned)].") + message_admins("[key_name(client)] sent a default admin alert to [key_name(about_to_be_banned)].") return new_text = strip_html(new_text, 500) - var/message_color = tgui_input_color(src, "Input your message color:", "Admin Message - Color Selector", COLOR_RED) + var/message_color = tgui_input_color(client, "Input your message color:", "Admin Message - Color Selector", COLOR_RED) if(isnull(message_color)) return show_blurb(about_to_be_banned, 15, new_text, null, "center", "center", message_color, null, null, 1) - log_admin("[key_name(src)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".") - message_admins("[key_name(src)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".") + log_admin("[key_name(client)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".") + message_admins("[key_name(client)] sent an admin alert to [key_name(about_to_be_banned)] with custom message \"[new_text]\".") -/client/proc/debugstatpanel() - set name = "Debug Stat Panel" - set category = "Debug" +USER_VERB(debug_statpanel, R_DEBUG, "Debug Stat Panel", "Toggles local debug of the stat panel", VERB_CATEGORY_DEBUG) + client.stat_panel.send_message("create_debug") - src.stat_panel.send_message("create_debug") +USER_VERB(profile_code, R_DEBUG|R_VIEWRUNTIMES, "Profile Code", "View code profiler", VERB_CATEGORY_DEBUG) + winset(client, null, "command=.profile") -/client/proc/profile_code() - set name = "Profile Code" - set category = "Debug" - - winset(usr, null, "command=.profile") - -/client/proc/export_current_character() - set name = "Export Character DMI/JSON" - set category = "Admin" - - if(ishuman(mob)) - var/mob/living/carbon/human/H = mob +USER_VERB(export_character, R_ADMIN, "Export Character DMI/JSON", "Saves character DMI and JSON to data directory.", VERB_CATEGORY_ADMIN) + if(ishuman(client.mob)) + var/mob/living/carbon/human/H = client.mob H.export_dmi_json() -/client/proc/raw_gas_scan() - set name = "Raw Gas Scan" - set category = "Debug" - set desc = "Scans your current tile, including LINDA data not normally displayed." +USER_VERB(raw_gas_scan, R_DEBUG|R_VIEWRUNTIMES, "Raw Gas Scan", "Scans your current tile, including LINDA data not normally displayed.", VERB_CATEGORY_DEBUG) + atmos_scan(client.mob, get_turf(client.mob), silent = TRUE, milla_turf_details = TRUE) - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - - atmos_scan(mob, get_turf(mob), silent = TRUE, milla_turf_details = TRUE) - -/client/proc/teleport_interesting_turf() - set name = "Interesting Turf" - set category = "Debug" - set desc = "Teleports you to a random Interesting Turf from MILLA" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - - if(!isobserver(mob)) - to_chat(mob, "You must be an observer to do this!") +USER_VERB(find_interesting_turf, R_DEBUG|R_VIEWRUNTIMES, "Interesting Turf", \ + "Teleports you to a random Interesting Turf from MILLA", VERB_CATEGORY_DEBUG) + if(!isobserver(client.mob)) + to_chat(client.mob, "You must be an observer to do this!") return var/list/interesting_tile = get_random_interesting_tile() if(!length(interesting_tile)) - to_chat(mob, "There are no interesting turfs. How interesting!") + to_chat(client, "There are no interesting turfs. How interesting!") return var/turf/T = interesting_tile[MILLA_INDEX_TURF] - var/mob/dead/observer/O = mob + var/mob/dead/observer/O = client.mob admin_forcemove(O, T) O.manual_follow(T) -/client/proc/visualize_interesting_turfs() - set name = "Visualize Interesting Turfs" - set category = "Debug" - set desc = "Shows all the Interesting Turfs from MILLA" - - if(!check_rights(R_DEBUG | R_VIEWRUNTIMES)) - return - +USER_VERB(visualize_interesting_turfs, R_DEBUG|R_VIEWRUNTIMES, "Visualize Interesting Turfs", "Shows all the Interesting Turfs from MILLA", VERB_CATEGORY_DEBUG) if(SSair.interesting_tile_count > 500) // This can potentially iterate through a list thats 20k things long. Give ample warning to the user - if(tgui_alert(usr, "WARNING: There are [SSair.interesting_tile_count] Interesting Turfs. This process will be lag intensive and should only be used if the atmos controller \ + if(tgui_alert(client, "WARNING: There are [SSair.interesting_tile_count] Interesting Turfs. This process will be lag intensive and should only be used if the atmos controller \ is screaming bloody murder. Are you sure you with to continue", "WARNING", list("I am sure", "Nope")) != "I am sure") return else - if(tgui_alert(usr, "Visualizing turfs may cause server to lag. Are you sure?", "Warning", list("Yes", "No")) != "Yes") + if(tgui_alert(client, "Visualizing turfs may cause server to lag. Are you sure?", "Warning", list("Yes", "No")) != "Yes") return var/display_turfs_overlay = FALSE - if(tgui_alert(usr, "Would you like to have all interesting turfs have a client side overlay applied as well?", "Optional", list("Yes", "No")) == "Yes") + if(tgui_alert(client, "Would you like to have all interesting turfs have a client side overlay applied as well?", "Optional", list("Yes", "No")) == "Yes") display_turfs_overlay = TRUE - message_admins("[key_name_admin(usr)] is visualizing interesting atmos turfs. Server may lag.") + message_admins("[key_name_admin(client)] is visualizing interesting atmos turfs. Server may lag.") var/list/zlevel_turf_indexes = list() var/list/coords = get_interesting_atmos_tiles() if(!length(coords)) - to_chat(mob, "There are no interesting turfs. How interesting!") + to_chat(client, "There are no interesting turfs. How interesting!") return while(length(coords)) @@ -1178,16 +605,16 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( zlevel_turf_indexes["[T.z]"] = list() zlevel_turf_indexes["[T.z]"] |= T if(display_turfs_overlay) - usr.client.images += image('icons/effects/alphacolors.dmi', T, "red") + client.images += image('icons/effects/alphacolors.dmi', T, "red") CHECK_TICK // Sort the keys zlevel_turf_indexes = sortAssoc(zlevel_turf_indexes) for(var/key in zlevel_turf_indexes) - to_chat(usr, "Z[key]: [length(zlevel_turf_indexes["[key]"])] Interesting Turfs") + to_chat(client, "Z[key]: [length(zlevel_turf_indexes["[key]"])] Interesting Turfs") - var/z_to_view = tgui_input_number(usr, "A list of z-levels their ITs has appeared in chat. Please enter a Z to visualize. Enter 0 or close the window to cancel", "Selection", 0) + var/z_to_view = tgui_input_number(client, "A list of z-levels their ITs has appeared in chat. Please enter a Z to visualize. Enter 0 or close the window to cancel", "Selection", 0) if(!z_to_view) return @@ -1196,7 +623,7 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( var/list/ui_dat = list() var/list/turf_markers = list() - var/datum/browser/vis = new(usr, "atvis", "Interesting Turfs (Z[z_to_view])", 300, 315) + var/datum/browser/vis = new(client, "atvis", "Interesting Turfs (Z[z_to_view])", 300, 315) ui_dat += "
    " ui_dat += "" // Now generate the other list @@ -1210,14 +637,7 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( vis.set_content(ui_dat.Join("")) vis.open(FALSE) - -/client/proc/create_rnd_restore_disk() - set name = "Create RnD Backup Restore Disk" - set category = "Event" // Im putting this in event because the name is long and will offset everything - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(create_rnd_restore_disk, R_ADMIN, "Create RnD Backup Restore Disk", "Create RnD Backup Restore Disk", VERB_CATEGORY_EVENT) var/list/targets = list() for(var/rnc_uid in SSresearch.backups) @@ -1225,7 +645,7 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( targets["[B.last_name] - [B.last_timestamp]"] = rnc_uid - var/choice = input(src, "Select a backup to restore", "RnD Backup Restore") as null|anything in targets + var/choice = input(client, "Select a backup to restore", "RnD Backup Restore") as null|anything in targets if(!choice || !(choice in targets)) return @@ -1234,17 +654,15 @@ GLOBAL_LIST_INIT(view_logs_verbs, list( return var/datum/rnd_backup/B = SSresearch.backups[actual_target] - if(tgui_alert(usr, "Are you sure you want to restore this RnD backup? The disk will spawn below your character.", "Are you sure?", list("Yes", "No")) != "Yes") + if(tgui_alert(client, "Are you sure you want to restore this RnD backup? The disk will spawn below your character.", "Are you sure?", list("Yes", "No")) != "Yes") return - B.to_backup_disk(get_turf(usr)) + B.to_backup_disk(get_turf(client.mob)) /proc/ghost_follow_uid(mob/user, uid) var/client/client = user.client if(!isobserver(user)) - if(!check_rights(R_ADMIN|R_MOD)) // Need to be mod or admin to aghost - return - user.client.admin_ghost() + SSuser_verbs.invoke_verb(user, /datum/user_verb/admin_ghost) var/datum/target = locateUID(uid) if(QDELETED(target)) to_chat(user, "This datum has been deleted!") diff --git a/code/modules/admin/centcom_ban_db.dm b/code/modules/admin/centcom_ban_db.dm index e1115aa9532..79ad8254b34 100644 --- a/code/modules/admin/centcom_ban_db.dm +++ b/code/modules/admin/centcom_ban_db.dm @@ -105,13 +105,7 @@ popup.set_content(popup_data.Join()) popup.open(FALSE) -// Just a simple verb so admins can do manual lookups -/client/proc/ccbdb_lookup_ckey() - set name = "Global Ban DB Lookup" - set category = "Admin" - - if(!check_rights(R_ADMIN)) - return - - var/input_ckey = input(usr, "Please enter a ckey to lookup", "Global Ban DB Lookup") - holder.create_ccbdb_lookup(input_ckey) +/// Just a simple verb so admins can do manual lookups +USER_VERB(ccbdb_lookup_ckey, R_ADMIN, "Global Ban DB Lookup", "Lookup global bans by ckey.", VERB_CATEGORY_ADMIN) + var/input_ckey = input(client, "Please enter a ckey to lookup", "Global Ban DB Lookup") + client.holder.create_ccbdb_lookup(input_ckey) diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index ecde29c1430..c9a7987f24f 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -89,7 +89,7 @@ GLOBAL_PROTECT(href_token) return owner.holder = src - owner.add_admin_verbs() + owner.add_user_verbs() if(isobserver(owner.mob)) var/mob/dead/observer/ghost = owner.mob ghost.update_admin_actions() @@ -133,7 +133,7 @@ GLOBAL_PROTECT(href_token) if(owner) GLOB.admins -= owner - owner.hide_verbs() + owner.remove_user_verbs() owner.holder = null owner.init_verbs() if(isobserver(owner.mob)) diff --git a/code/modules/admin/machine_upgrade.dm b/code/modules/admin/machine_upgrade.dm index 258b6b9a938..586ba9e2c94 100644 --- a/code/modules/admin/machine_upgrade.dm +++ b/code/modules/admin/machine_upgrade.dm @@ -1,20 +1,15 @@ -/proc/machine_upgrade(obj/machinery/M in world) - set name = "\[Admin\] Tweak Component Ratings" - - if(!check_rights(R_DEBUG)) - return - +USER_CONTEXT_MENU(machine_upgrade, R_DEBUG, "\[Admin\] Tweak Component Ratings", obj/machinery/M as obj in world) if(!istype(M)) - to_chat(usr, "This can only be used on subtypes of /obj/machinery.") + to_chat(client, "This can only be used on subtypes of /obj/machinery.") return - var/new_rating = input("Enter new rating:","Num") as num + var/new_rating = input(client, "Enter new rating:","Num") as num if(!isnull(new_rating) && M.component_parts) for(var/obj/item/stock_parts/P in M.component_parts) P.rating = new_rating M.RefreshParts() - message_admins("[key_name_admin(usr)] has set the component rating of [M] to [new_rating]") - log_admin("[key_name(usr)] has set the component rating of [M] to [new_rating]") + message_admins("[key_name_admin(client)] has set the component rating of [M] to [new_rating]") + log_admin("[key_name(client)] has set the component rating of [M] to [new_rating]") SSblackbox.record_feedback("tally", "admin_verb", 1, "Machine Upgrade") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/menus/antagonist_menu.dm b/code/modules/admin/menus/antagonist_menu.dm index 2b052b0cdef..c19950458ad 100644 --- a/code/modules/admin/menus/antagonist_menu.dm +++ b/code/modules/admin/menus/antagonist_menu.dm @@ -167,7 +167,7 @@ RESTRICT_TYPE(/datum/ui_module/admin/antagonist_menu) if(QDELETED(mind.current)) to_chat(ui.user, "Mind doesn't have a corresponding mob.") return - ui.user.client.holder.show_player_panel(mind.current) + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/show_player_panel, mind.current) if("pm") ui.user.client.cmd_admin_pm(params["ckey"], null) if("follow") @@ -179,7 +179,7 @@ RESTRICT_TYPE(/datum/ui_module/admin/antagonist_menu) if(!ismob(mind.current)) to_chat(ui.user, "This can only be used on instances of type /mob") return - C.admin_observe_target(mind.current) + SSuser_verbs.invoke_verb(C, /datum/user_verb/admin_observe_target, mind.current) if("tp") var/datum/mind/mind = locateUID(params["mind_uid"]) if(QDELETED(mind)) diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm index 00077057902..f3d674bef20 100644 --- a/code/modules/admin/misc_admin_procs.dm +++ b/code/modules/admin/misc_admin_procs.dm @@ -70,16 +70,11 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) ///////////////////////////////////////////////////////////////////////////////////////////////Panels -/datum/admins/proc/show_player_panel(mob/M in GLOB.mob_list) - set name = "\[Admin\] Show Player Panel" - set desc="Edit player (respawn, ban, heal, etc)" - +USER_CONTEXT_MENU(show_player_panel, R_ADMIN|R_MOD, "\[Admin\] Show Player Panel", mob/M) if(!M) - to_chat(usr, "You seem to be selecting a mob that doesn't exist anymore.") + to_chat(client, "You seem to be selecting a mob that doesn't exist anymore.") return - if(!check_rights(R_ADMIN|R_MOD)) - return var/our_key = M.key if(M.client && M.client.holder) if(M.client.holder.fakekey && M.client.holder.big_brother) @@ -289,34 +284,19 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) "} - usr << browse(body, "window=adminplayeropts;size=550x615") + client << browse(body, "window=adminplayeropts;size=550x615") SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Player Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! #define PLAYER_NOTES_ENTRIES_PER_PAGE 50 -/datum/admins/proc/PlayerNotes() - set category = "Admin" - set name = "Player Notes" - - if(!check_rights(R_ADMIN|R_MOD)) - return +USER_VERB(player_notes, R_ADMIN|R_MOD, "Player Notes", "Open Player Notes panel.", VERB_CATEGORY_ADMIN) show_note() -/datum/admins/proc/show_player_notes(key as text) - set category = "Admin" - set name = "Show Player Notes" - - if(!check_rights(R_ADMIN|R_MOD)) - return - +USER_VERB(player_notes_target, R_ADMIN|R_MOD, "Show Player Notes", "Show Player Notes panel for a given ckey.", VERB_CATEGORY_ADMIN, key as text) show_note(key) -/datum/admins/proc/vpn_whitelist() - set category = "Admin" - set name = "VPN Ckey Whitelist" - if(!check_rights(R_BAN)) - return - var/key = stripped_input(usr, "Enter ckey to add/remove, or leave blank to cancel:", "VPN Whitelist add/remove", max_length=32) +USER_VERB(vpn_whitelist, R_BAN, "VPN Ckey Whitelist", "Modify ckey's presence on VPN whitelist", VERB_CATEGORY_ADMIN) + var/key = stripped_input(client, "Enter ckey to add/remove, or leave blank to cancel:", "VPN Whitelist add/remove", max_length=32) if(key) GLOB.ipintel_manager.vpn_whitelist_panel(key) @@ -348,118 +328,87 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) /////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge //i.e. buttons/verbs - -/datum/admins/proc/restart() - set category = "Server" - set name = "Restart" - set desc = "Restarts the world." - - if(!check_rights(R_SERVER)) - return - +USER_VERB(restart_server, R_SERVER, "Restart", "Restarts the world.", VERB_CATEGORY_SERVER) // Give an extra popup if they are rebooting a live server var/is_live_server = TRUE - if(usr.client.is_connecting_from_localhost()) + if(client.is_connecting_from_localhost()) is_live_server = FALSE var/list/options = list("Regular Restart", "Hard Restart") if(world.TgsAvailable()) // TGS lets you kill the process entirely options += "Terminate Process (Kill and restart DD)" - var/result = input(usr, "Select reboot method", "World Reboot", options[1]) as null|anything in options + var/result = input(client, "Select reboot method", "World Reboot", options[1]) as null|anything in options if(result && is_live_server) - if(alert(usr, "WARNING: THIS IS A LIVE SERVER, NOT A LOCAL TEST SERVER. DO YOU STILL WANT TO RESTART","This server is live","Restart","Cancel") != "Restart") + if(alert(client, "WARNING: THIS IS A LIVE SERVER, NOT A LOCAL TEST SERVER. DO YOU STILL WANT TO RESTART","This server is live","Restart","Cancel") != "Restart") return FALSE 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]." + var/init_by = "Initiated by [client.holder.fakekey ? "Admin" : client.key]." switch(result) if("Regular Restart") - var/delay = input("What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null + var/delay = input(client, "What delay should the restart have (in seconds)?", "Restart Delay", 5) as num|null if(!delay) return FALSE // These are pasted each time so that they dont false send if reboot is cancelled - message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]") - log_admin("[key_name(usr)] has initiated a server restart of type [result]") + message_admins("[key_name_admin(client)] has initiated a server restart of type [result]") + log_admin("[key_name(client)] has initiated a server restart of type [result]") SSticker.delay_end = FALSE // We arent delayed anymore - SSticker.reboot_helper(init_by, "admin reboot - by [usr.key] [usr.client.holder.fakekey ? "(stealth)" : ""]", delay * 10) + SSticker.reboot_helper(init_by, "admin reboot - by [client.key] [client.holder.fakekey ? "(stealth)" : ""]", delay * 10) if("Hard Restart") - message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]") - log_admin("[key_name(usr)] has initiated a server restart of type [result]") + message_admins("[key_name_admin(client)] has initiated a server restart of type [result]") + log_admin("[key_name(client)] has initiated a server restart of type [result]") world.Reboot(fast_track = TRUE) if("Terminate Process (Kill and restart DD)") - message_admins("[key_name_admin(usr)] has initiated a server restart of type [result]") - log_admin("[key_name(usr)] has initiated a server restart of type [result]") + message_admins("[key_name_admin(client)] has initiated a server restart of type [result]") + log_admin("[key_name(client)] has initiated a server restart of type [result]") world.TgsEndProcess() // Just nuke the entire process if we are royally fucked -/datum/admins/proc/end_round() - set category = "Server" - set name = "End Round" - set desc = "Instantly ends the round and brings up the scoreboard, in the same way that wizards dying do." - if(!check_rights(R_SERVER)) - return - var/input = sanitize(copytext_char(input(usr, "What text should players see announcing the round end? Input nothing to cancel.", "Specify Announcement Text", "Shift Has Ended!"), 1, MAX_MESSAGE_LEN)) +USER_VERB(end_round, R_SERVER, "End Round", \ + "Instantly ends the round and brings up the scoreboard, in the same way that wizards dying do.", \ + VERB_CATEGORY_SERVER) + var/input = sanitize(copytext_char(input(client, "What text should players see announcing the round end? Input nothing to cancel.", "Specify Announcement Text", "Shift Has Ended!"), 1, MAX_MESSAGE_LEN)) if(!input) return if(SSticker.force_ending) return - message_admins("[key_name_admin(usr)] has admin ended the round with message: '[input]'") - log_admin("[key_name(usr)] has admin ended the round with message: '[input]'") + message_admins("[key_name_admin(client)] has admin ended the round with message: '[input]'") + log_admin("[key_name(client)] has admin ended the round with message: '[input]'") SSticker.force_ending = TRUE SSticker.record_biohazard_results() to_chat(world, "[input]") 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! SSticker.mode_result = "admin ended" -/datum/admins/proc/announce() - set category = "Admin" - set name = "Announce" - set desc = "Announce your desires to the world" - - if(!check_rights(R_ADMIN)) - return - - var/message = input("Global message to send:", "Admin Announce", null, null) as message|null +USER_VERB(announce, R_ADMIN, "Announce", "Announce your desires to the world", VERB_CATEGORY_ADMIN) + var/message = input(client, "Global message to send:", "Admin Announce", null) as message|null if(message) - if(!check_rights(R_SERVER,0)) + if(!check_rights_client(R_SERVER, 0, client)) message = adminscrub(message,500) message = replacetext(message, "\n", "
    ") // required since we're putting it in a

    tag - to_chat(world, chat_box_notice("[usr.client.holder.fakekey ? "Administrator" : usr.key] Announces:

    [message]

    ")) - log_admin("Announce: [key_name(usr)] : [message]") + to_chat(world, chat_box_notice("[client.holder.fakekey ? "Administrator" : client.key] Announces:

    [message]

    ")) + log_admin("Announce: [key_name(client)] : [message]") for(var/client/clients_to_alert in GLOB.clients) window_flash(clients_to_alert) if(clients_to_alert.prefs?.sound & SOUND_ADMINHELP) SEND_SOUND(clients_to_alert, sound('sound/misc/server_alert.ogg')) + 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/toggleooc() - set category = "Server" - set desc="Globally Toggles OOC" - set name="Toggle OOC" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(toggle_ooc, R_ADMIN, "Toggle OOC", "Globally Toggles OOC", VERB_CATEGORY_SERVER) toggle_ooc() log_and_message_admins("toggled OOC.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/togglelooc() - set category = "Server" - set desc="Globally Toggles LOOC" - set name="Toggle LOOC" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(toggle_looc, R_ADMIN, "Toggle LOOC", "Globally Toggles LOOC", VERB_CATEGORY_SERVER) GLOB.looc_enabled = !(GLOB.looc_enabled) if(GLOB.looc_enabled) to_chat(world, "The LOOC channel has been globally enabled!") @@ -468,92 +417,57 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) log_and_message_admins("toggled LOOC.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle LOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggledsay() - set category = "Server" - set desc="Globally Toggles DSAY" - set name="Toggle DSAY" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(toggle_dsay, R_ADMIN, "Toggle DSAY", "Globally Toggles DSAY", VERB_CATEGORY_SERVER) GLOB.dsay_enabled = !(GLOB.dsay_enabled) if(GLOB.dsay_enabled) to_chat(world, "Deadchat has been globally enabled!", MESSAGE_TYPE_DEADCHAT) else to_chat(world, "Deadchat has been globally disabled!", MESSAGE_TYPE_DEADCHAT) - log_admin("[key_name(usr)] toggled deadchat.") - message_admins("[key_name_admin(usr)] toggled deadchat.", 1) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deadchat") //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 Dead OOC." - set name="Toggle Dead OOC" - - if(!check_rights(R_ADMIN)) - return + log_admin("[key_name(client)] toggled deadchat.") + message_admins("[key_name_admin(client)] toggled deadchat.", 1) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deadchat") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +USER_VERB(toggle_ooc_dead, R_ADMIN, "Toggle Dead OOC", "Toggle Dead OOC.", VERB_CATEGORY_SERVER) GLOB.dooc_enabled = !(GLOB.dooc_enabled) - log_admin("[key_name(usr)] toggled Dead OOC.") - message_admins("[key_name_admin(usr)] toggled Dead OOC.", 1) + log_admin("[key_name(client)] toggled Dead OOC.") + message_admins("[key_name_admin(client)] toggled Dead OOC.", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Dead OOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleemoji() - set category = "Server" - set desc = "Toggle OOC Emoji" - set name = "Toggle OOC Emoji" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(toggle_emoji, R_ADMIN, "Toggle OOC Emoji", "Toggle OOC Emoji", VERB_CATEGORY_SERVER) GLOB.configuration.general.enable_ooc_emoji = !(GLOB.configuration.general.enable_ooc_emoji) - log_admin("[key_name(usr)] toggled OOC Emoji.") - message_admins("[key_name_admin(usr)] toggled OOC Emoji.", 1) + log_admin("[key_name(client)] toggled OOC Emoji.") + message_admins("[key_name_admin(client)] toggled OOC Emoji.", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle OOC Emoji") -/datum/admins/proc/startnow() - set category = "Server" - set desc="Start the round RIGHT NOW" - set name="Start Now" - - if(!check_rights(R_SERVER)) - return - +USER_VERB(start_server_now, R_SERVER, "Start Now", "Start the round RIGHT NOW", VERB_CATEGORY_SERVER) if(SSticker.current_state < GAME_STATE_STARTUP) - alert("Unable to start the game as it is not set up.") + alert(client, "Unable to start the game as it is not set up.") return if(!SSticker.ticker_going) - alert("Remove the round-start delay first.") + alert(client, "Remove the round-start delay first.") return if(GLOB.configuration.general.start_now_confirmation) - if(alert(usr, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes") + if(alert(client, "This is a live server. Are you sure you want to start now?", "Start game", "Yes", "No") != "Yes") return if(SSticker.current_state == GAME_STATE_PREGAME || SSticker.current_state == GAME_STATE_STARTUP) SSticker.force_start = TRUE - log_admin("[usr.key] has started the game.") + log_admin("[client.key] has started the game.") var/msg = "" if(SSticker.current_state == GAME_STATE_STARTUP) msg = " (The server is still setting up, but the round will be started as soon as possible.)" - message_admins("[usr.key] has started the game.[msg]") + message_admins("[client.key] has started the game.[msg]") SSblackbox.record_feedback("tally", "admin_verb", 1, "Start Game") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return 1 else - to_chat(usr, "Error: Start Now: Game has already started.") + to_chat(client, "Error: Start Now: Game has already started.") return -/datum/admins/proc/toggleenter() - set category = "Server" - set desc="People can't enter" - set name="Toggle Entering" - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(toggle_enter, R_SERVER, "Toggle Entering", "People can't enter", VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return GLOB.enter_allowed = !GLOB.enter_allowed @@ -561,40 +475,25 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) to_chat(world, "New players may no longer enter the game.") else to_chat(world, "New players may now enter the game.") - log_admin("[key_name(usr)] toggled new player game entering.") - message_admins("[key_name_admin(usr)] toggled new player game entering.", 1) + log_admin("[key_name(client)] toggled new player game entering.") + message_admins("[key_name_admin(client)] toggled new player game entering.", 1) world.update_status() SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Entering") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggle_ai() - set category = "Event" - set desc="People can't be AI" - set name="Toggle AI" - - if(!check_rights(R_EVENT)) - return - - +USER_VERB(toggle_ai_role, R_EVENT, "Toggle AI", "People can't be AI", VERB_CATEGORY_EVENT) GLOB.configuration.jobs.allow_ai = !(GLOB.configuration.jobs.allow_ai) if(!GLOB.configuration.jobs.allow_ai) to_chat(world, "The AI job is no longer chooseable.") else to_chat(world, "The AI job is chooseable now.") - message_admins("[key_name_admin(usr)] toggled AI allowed.") - log_admin("[key_name(usr)] toggled AI allowed.") + message_admins("[key_name_admin(client)] toggled AI allowed.") + log_admin("[key_name(client)] toggled AI allowed.") world.update_status() SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle AI") //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="Toggle the ability for players to respawn." - set name="Toggle Respawn" - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(toggle_respawn, R_SERVER, "Toggle Respawn", "Toggle the ability for players to respawn.", VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return GLOB.configuration.general.respawn_enabled = !(GLOB.configuration.general.respawn_enabled) @@ -602,25 +501,18 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) to_chat(world, "You may now respawn.") else to_chat(world, "You may no longer respawn") - message_admins("[key_name_admin(usr)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].", 1) - log_admin("[key_name(usr)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].") + message_admins("[key_name_admin(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].", 1) + log_admin("[key_name(client)] toggled respawn to [GLOB.configuration.general.respawn_enabled ? "On" : "Off"].") world.update_status() SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Respawn") //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/end" - set name="Delay" - - if(!check_rights(R_SERVER)) - return - +USER_VERB(delay_game, R_SERVER, "Delay", "Delay the game start/end", VERB_CATEGORY_SERVER) if(SSticker.current_state < GAME_STATE_STARTUP) - alert("Slow down a moment, let the ticker start first!") + alert(client, "Slow down a moment, let the ticker start first!") return - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return if(SSblackbox) @@ -628,8 +520,8 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) if(SSticker.current_state > GAME_STATE_PREGAME) SSticker.delay_end = !SSticker.delay_end - log_admin("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].") - message_admins("[key_name(usr)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1) + log_admin("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].") + message_admins("[key_name(client)] [SSticker.delay_end ? "delayed the round end" : "has made the round end normally"].", 1) if(SSticker.delay_end) SSticker.real_reboot_time = 0 // Immediately show the "Admin delayed round end" message return //alert("Round end delayed", null, null, null, null, null) @@ -637,12 +529,12 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) SSticker.ticker_going = FALSE SSticker.delay_end = TRUE to_chat(world, "The game start has been delayed.") - log_admin("[key_name(usr)] delayed the game.") + log_admin("[key_name(client)] delayed the game.") else SSticker.ticker_going = TRUE SSticker.round_start_time = world.time + SSticker.pregame_timeleft to_chat(world, "The game will start soon.") - log_admin("[key_name(usr)] removed the delay.") + log_admin("[key_name(client)] removed the delay.") ////////////////////////////////////////////////////////////////////////////////////////////////ADMIN HELPER PROCS @@ -725,14 +617,9 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) return "" -/datum/admins/proc/spawn_atom(object as text) - set category = "Debug" - set desc = "(atom path) Spawn an atom. Append a period to the text in order to exclude subtypes of paths matching the input." - set name = "Spawn" - - if(!check_rights(R_SPAWN)) - return - +USER_VERB(spawn_atom, R_SPAWN, "Spawn", \ + "Spawn an atom. Append a period to the text in order to exclude subtypes of paths matching the input.", \ + VERB_CATEGORY_DEBUG, object as text) if(!object) return @@ -761,48 +648,35 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) if(length(matches)==1) chosen = matches[1] else - chosen = tgui_input_list(usr, "Select an Atom Type", "Spawn Atom", matches) + chosen = tgui_input_list(client, "Select an Atom Type", "Spawn Atom", matches) if(!chosen) return if(ispath(chosen,/turf)) - var/turf/T = get_turf(usr.loc) + var/turf/T = get_turf(client.mob.loc) T.ChangeTurf(chosen) else - var/atom/A = new chosen(usr.loc) + var/atom/A = new chosen(client.mob.loc) A.admin_spawned = TRUE - log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])") + log_admin("[key_name(client)] spawned [chosen] at ([client.mob.x],[client.mob.y],[client.mob.z])") 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/show_traitor_panel(mob/M in GLOB.mob_list) - set category = "Admin" - set desc = "Edit mobs's memory and role" - set name = "Show Traitor Panel" - - if(!check_rights(R_ADMIN|R_MOD)) - return - +USER_VERB_VISIBILITY(show_traitor_panel, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(show_traitor_panel, R_ADMIN|R_MOD, "Show Traitor Panel", "Edit mob's memory and role", VERB_CATEGORY_ADMIN, mob/M in GLOB.mob_list) if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") + to_chat(client, "This can only be used on instances of type /mob") return if(!M.mind) - to_chat(usr, "This mob has no mind!") + to_chat(client, "This mob has no mind!") return M.mind.edit_memory() SSblackbox.record_feedback("tally", "admin_verb", 1, "Show Traitor Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/datum/admins/proc/toggleguests() - set category = "Server" - set desc="Guests can't enter" - set name="Toggle Guests" - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(toggle_guests, R_SERVER, "Toggle Guests", "Guests can't enter", VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return GLOB.configuration.general.guest_ban = !(GLOB.configuration.general.guest_ban) @@ -810,8 +684,8 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) to_chat(world, "Guests may no longer enter the game.") else to_chat(world, "Guests may now enter the game.") - log_admin("[key_name(usr)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.") - message_admins("[key_name_admin(usr)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.", 1) + log_admin("[key_name(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.") + message_admins("[key_name_admin(client)] toggled guests game entering [GLOB.configuration?.general.guest_ban ? "dis" : ""]allowed.", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Guests") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/admins/proc/output_ai_laws() @@ -848,13 +722,7 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE) log_admin("[key_name(usr)] checked the AI laws") message_admins("[key_name_admin(usr)] checked the AI laws") -/client/proc/update_mob_sprite(mob/living/carbon/human/H as mob) - set name = "\[Admin\] Update Mob Sprite" - set desc = "Should fix any mob sprite update errors." - - if(!check_rights(R_ADMIN)) - return - +USER_CONTEXT_MENU(update_mob_sprite, R_ADMIN, "\[Admin\] Update Mob Sprite", mob/living/carbon/human/H as mob) if(istype(H)) H.regenerate_icons() diff --git a/code/modules/admin/outfits.dm b/code/modules/admin/outfits.dm index 1b6720781a8..d3a6be2a630 100644 --- a/code/modules/admin/outfits.dm +++ b/code/modules/admin/outfits.dm @@ -1,12 +1,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits -/client/proc/outfit_manager() - set category = "Event" - set name = "Outfit Manager" - - if(!check_rights(R_EVENT)) - return - holder.outfit_manager(usr) +USER_VERB(outfit_manager, R_EVENT, "Outfit Manager", "Opens the outfit manager.", VERB_CATEGORY_EVENT) + client.holder.outfit_manager(client.mob) /datum/admins/proc/outfit_manager(mob/admin) var/list/dat = list("" - usr << browse(text.Join(), "window=gcqueuestatus") + client << browse(text.Join(), "window=gcqueuestatus") /client/proc/cmd_admin_toggle_block(mob/M, block) if(!check_rights(R_SPAWN)) @@ -878,40 +749,20 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) else alert("Invalid mob") -/client/proc/view_runtimes() - set category = "Debug" - set name = "View Runtimes" - set desc = "Open the Runtime Viewer" +USER_VERB(view_runtimes, R_DEBUG|R_VIEWRUNTIMES, "View Runtimes", "Open the Runtime Viewer", VERB_CATEGORY_DEBUG) + GLOB.error_cache.showTo(client) - if(!check_rights(R_DEBUG|R_VIEWRUNTIMES)) +USER_VERB(allow_browser_inspect, R_DEBUG, "Allow Browser Inspect", "Allow browser debugging via inspect", VERB_CATEGORY_DEBUG) + if(client.byond_version < 516) + to_chat(client, "You can only use this on 516!") return - GLOB.error_cache.showTo(usr) + to_chat(client, "You can now right click to use inspect on browsers.") + winset(client, "", "browser-options=byondstorage,find,devtools") -/client/proc/allow_browser_inspect() - set category = "Debug" - set name = "Allow Browser Inspect" - set desc = "Allow browser debugging via inspect" - - if(!check_rights(R_DEBUG) || !isclient(src)) - return - - if(byond_version < 516) - to_chat(src, "You can only use this on 516!") - return - - to_chat(src, "You can now right click to use inspect on browsers.") - winset(src, "", "browser-options=byondstorage,find,devtools") - -/client/proc/cmd_clean_radiation() - set name = "Remove All Radiation" - set desc = "Remove all radiation in the world." - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return - - if(alert(src, "Are you sure you want to remove all radiation in the world? This may lag the server. Alternatively, use the radiation cleaning buildmode.", "Lag warning", "Yes, I'm sure", "No, I want to live") != "Yes, I'm sure") +USER_VERB_VISIBILITY(debug_clean_radiation, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_clean_radiation, R_DEBUG, "Remove All Radiation", "Remove all radiation in the world.", VERB_CATEGORY_DEBUG) + if(alert(client, "Are you sure you want to remove all radiation in the world? This may lag the server. Alternatively, use the radiation cleaning buildmode.", "Lag warning", "Yes, I'm sure", "No, I want to live") != "Yes, I'm sure") return log_and_message_admins("is decontaminating the world of all radiation. (This may be laggy!)") @@ -924,21 +775,15 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) log_and_message_admins_no_usr("The world has been decontaminated of [counter] radiation components.") -/client/proc/view_bug_reports() - set name = "View Bug Reports" - set desc = "Select a bug report to view" - set category = "Debug" - if(!check_rights(R_DEBUG|R_VIEWRUNTIMES|R_ADMIN)) - return +USER_VERB(view_bug_reports, R_DEBUG|R_VIEWRUNTIMES|R_ADMIN, "View Bug Reports", "Select a bug report to view", VERB_CATEGORY_DEBUG) if(!length(GLOB.bug_reports)) - to_chat(usr, "There are no bug reports to view") + to_chat(client, "There are no bug reports to view") return var/list/bug_report_selection = list() for(var/datum/tgui_bug_report_form/report in GLOB.bug_reports) bug_report_selection["[report.initial_key] - [report.bug_report_data["title"]]"] = report - var/datum/tgui_bug_report_form/form = bug_report_selection[tgui_input_list(usr, "Select a report to view:", "Bug Reports", bug_report_selection)] - if(!form?.assign_approver(usr)) + var/datum/tgui_bug_report_form/form = bug_report_selection[tgui_input_list(client, "Select a report to view:", "Bug Reports", bug_report_selection)] + if(!form?.assign_approver(client.mob)) return - form.ui_interact(usr) - return + form.ui_interact(client.mob) diff --git a/code/modules/admin/verbs/debug_dmapi.dm b/code/modules/admin/verbs/debug_dmapi.dm index 495323578a6..f2bbb68dd57 100644 --- a/code/modules/admin/verbs/debug_dmapi.dm +++ b/code/modules/admin/verbs/debug_dmapi.dm @@ -1,35 +1,22 @@ // Admin verb to debug the DMAPI - -/client/proc/dmapi_debug() - set name = "Debug DMAPI" - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB(debug_dmapi, R_DEBUG, "Debug DMAPI", "Dump DMAPI information.", VERB_CATEGORY_DEBUG) if(!world.TgsAvailable()) - to_chat(src, "DMAPI not connected") + to_chat(client, "DMAPI not connected") return - to_chat(src, "TGS Info") - to_chat(src, "Revision: [world.TgsRevision()]") - to_chat(src, "Version: [world.TgsVersion()]") - to_chat(src, "API Version: [world.TgsApiVersion()]") - to_chat(src, "Instance Name: [world.TgsInstanceName()]") - to_chat(src, "Testmerges:") + to_chat(client, "TGS Info") + to_chat(client, "Revision: [world.TgsRevision()]") + to_chat(client, "Version: [world.TgsVersion()]") + to_chat(client, "API Version: [world.TgsApiVersion()]") + to_chat(client, "Instance Name: [world.TgsInstanceName()]") + to_chat(client, "Testmerges:") for(var/datum/tgs_revision_information/test_merge/TM as anything in world.TgsTestMerges()) - to_chat(src, "#[TM.number] | [TM.author] - [TM.title]") + to_chat(client, "#[TM.number] | [TM.author] - [TM.title]") - to_chat(src, "Channel info:") + to_chat(client, "Channel info:") for(var/datum/tgs_chat_channel/CC as anything in world.TgsChatChannelInfo()) - to_chat(src, "I:[CC.id] | FN:[CC.friendly_name] | AC:[CC.is_admin_channel] | PC:[CC.is_private_channel] | CT:[CC.custom_tag]") - to_chat(src, "Security level: [world.TgsSecurityLevel()]") + to_chat(client, "I:[CC.id] | FN:[CC.friendly_name] | AC:[CC.is_admin_channel] | PC:[CC.is_private_channel] | CT:[CC.custom_tag]") + to_chat(client, "Security level: [world.TgsSecurityLevel()]") -/client/proc/dmapi_log() - set name = "DMAPI Log" - set category = "Debug" - - if(!check_rights(R_DEBUG)) - return - - usr << browse(GLOB.tgs_log.Join("
    "), "window=dmapi_log") +USER_VERB(dmapi_log, R_DEBUG, "DMAPI Log", "Open the DMAPI log.", VERB_CATEGORY_DEBUG) + client << browse(GLOB.tgs_log.Join("
    "), "window=dmapi_log") diff --git a/code/modules/admin/verbs/diagnostics.dm b/code/modules/admin/verbs/diagnostics.dm index 3c4ce89abeb..3768f070e98 100644 --- a/code/modules/admin/verbs/diagnostics.dm +++ b/code/modules/admin/verbs/diagnostics.dm @@ -99,40 +99,25 @@ SSblackbox.record_feedback("tally", "admin_verb", 1, "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 = "Server" - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(reload_admins, R_SERVER, "Reload Admins", "Perform a forced refresh of admin data.", VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return - message_admins("[key_name_admin(usr)] has manually reloaded admins") - log_admin("[key_name(usr)] has manually reloaded admins") + message_admins("[key_name_admin(client)] has manually reloaded admins") + log_admin("[key_name(client)] has manually reloaded admins") load_admins(run_async=TRUE) SSblackbox.record_feedback("tally", "admin_verb", 1, "Reload Admins") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/vv_by_ref() - set name = "VV by Ref" - set desc = "Give this a ref string, and you will see its corresponding VV panel if it exists" - set category = "Debug" - - // It's gated by "Debug Verbs", so might as well gate it to the debug permission - // AA: This seems harmless but is **incredibly** powerful and dangerous. Maints only. - if(!check_rights(R_MAINTAINER)) - return - - var/refstring = clean_input("Which reference?","Ref") +USER_VERB(vv_by_ref, R_MAINTAINER, "VV by Ref", "Give this a ref string, and you will see its corresponding VV panel if it exists", VERB_CATEGORY_DEBUG) + var/refstring = clean_input("Which reference?","Ref", user = client) if(!refstring) return var/datum/D = locate(refstring) if(!D) - to_chat(usr, "That ref string does not correspond to any datum.") + to_chat(client, "That ref string does not correspond to any datum.") return - debug_variables(D) + SSuser_verbs.invoke_verb(client, /datum/user_verb/debug_variables, D) diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 2b90556e018..8fff9411e20 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -8,13 +8,8 @@ GLOBAL_LIST_EMPTY(frozen_atom_list) // A list of admin-frozen atoms. -/client/proc/freeze(atom/movable/M) - set name = "\[Admin\] Freeze" - - if(!check_rights(R_ADMIN)) - return - - M.admin_Freeze(src) +USER_CONTEXT_MENU(admin_freeze, R_ADMIN, "\[Admin\] Freeze", atom/movable/M) + M.admin_Freeze(client) /// Created here as a base proc. Override as needed for any type of object or mob you want able to be frozen. /atom/movable/proc/admin_Freeze(client/admin) diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 8e0fcaaad45..e94c822eafd 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -1,24 +1,11 @@ -/// 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" +/// Allows download of past server logs saved within the data/logs/ folder. +USER_VERB(get_server_logs, R_ADMIN|R_VIEWLOGS, "Get Server Logs", "View/retrieve logfiles.", VERB_CATEGORY_ADMIN) + access_file_by_browsing_path(client.mob, "data/logs/") - if(!check_rights(R_ADMIN|R_VIEWLOGS)) - return - - access_file_by_browsing_path(usr, "data/logs/") - -/// This proc allows download of past server logs saved within the data/logs/ folder by specifying a specific round ID. -/client/proc/get_server_logs_by_round_id() - set name = "Get Round Logs" - set desc = "View/retrieve logfiles for a given round." - set category = "Admin" - - if(!check_rights(R_ADMIN|R_VIEWLOGS)) - return - - var/round_id = input(usr, "Enter a round ID.", "Enter Round ID", "[GLOB.round_id]") as null|text +/// Allows download of past server logs saved within the data/logs/ folder by specifying a specific round ID. +USER_VERB(get_server_logs_by_round_id, R_ADMIN|R_VIEWLOGS, "Get Round Logs", \ + "View/retrieve logfiles for a given round.", VERB_CATEGORY_ADMIN) + var/round_id = input(client, "Enter a round ID.", "Enter Round ID", "[GLOB.round_id]") as null|text if(isnull(round_id)) return @@ -30,12 +17,12 @@ ) if(!query.warn_execute()) qdel(query) - to_chat(usr, "Could not check database for round [round_id].") + to_chat(client, "Could not check database for round [round_id].") return if(!query.NextRow()) qdel(query) - to_chat(usr, "Could not find round [round_id] in database.") + to_chat(client, "Could not find round [round_id] in database.") return // convert unix timestamp in seconds to byond timestamp in deciseconds @@ -45,7 +32,7 @@ if(!fexists(round_path)) log_debug("Logs for round `[round_id]` not found in path `[round_path]`.") - access_file_by_browsing_path(usr, round_path) + access_file_by_browsing_path(client.mob, round_path) /proc/access_file_by_browsing_path(mob/user, path) if(!user.client) diff --git a/code/modules/admin/verbs/logging_view.dm b/code/modules/admin/verbs/logging_view.dm index 89bfc79ad43..db1492217a7 100644 --- a/code/modules/admin/verbs/logging_view.dm +++ b/code/modules/admin/verbs/logging_view.dm @@ -1,21 +1,14 @@ GLOBAL_LIST_EMPTY(open_logging_views) -/client/proc/cmd_admin_open_logging_view() - set category = "Admin" - set name = "Logging View" - set desc = "Opens the detailed logging viewer" - open_logging_view() - -/client/proc/open_logging_view(list/mob/mobs_to_add = null, clear_view = FALSE) - var/datum/log_viewer/cur_view = GLOB.open_logging_views[usr.client.ckey] +USER_VERB(logging_view, R_ADMIN, "Logging View", "Opens the detailed logging viewer", VERB_CATEGORY_ADMIN, mob/M as null, clear_view as null) + var/datum/log_viewer/cur_view = GLOB.open_logging_views[client.ckey] if(!cur_view) cur_view = new /datum/log_viewer() - GLOB.open_logging_views[usr.client.ckey] = cur_view + GLOB.open_logging_views[client.ckey] = cur_view else if(clear_view) cur_view.clear_all() - if(length(mobs_to_add)) - cur_view.add_mobs(mobs_to_add) - - cur_view.show_ui(usr) + if(istype(M)) + cur_view.add_mobs(list(M)) + cur_view.show_ui(client.mob) diff --git a/code/modules/admin/verbs/manage_queue.dm b/code/modules/admin/verbs/manage_queue.dm index 8adacf54e88..2ca94378cde 100644 --- a/code/modules/admin/verbs/manage_queue.dm +++ b/code/modules/admin/verbs/manage_queue.dm @@ -1,51 +1,37 @@ -/client/proc/manage_queue() - set name = "Manage Queue Server" - set desc = "Manage the queue server and its settings" - set category = "Server" - - if(!check_rights(R_SERVER)) - return - +USER_VERB(manage_queue, R_SERVER, "Manage Queue Server", "Manage the queue server and its settings", VERB_CATEGORY_SERVER) var/list/choices = list("Show Status", "Toggle Queue Server", "Set Threshold", "Toggle Setting Persistence") - var/choice = input(usr, "Please, select an option", "Queue Server Manipulation") as null|anything in choices + var/choice = input(client, "Please, select an option", "Queue Server Manipulation") as null|anything in choices switch(choice) if("Show Status") - to_chat(usr, "Queue Server Status") - to_chat(usr, "Enabled: [SSqueue.queue_enabled ? "Yes" : "No"]") - to_chat(usr, "Queue Threshold: [SSqueue.queue_threshold]") - to_chat(usr, "Setting Persistence: [SSqueue.persist_queue ? "Yes" : "No"]") + to_chat(client, "Queue Server Status") + to_chat(client, "Enabled: [SSqueue.queue_enabled ? "Yes" : "No"]") + to_chat(client, "Queue Threshold: [SSqueue.queue_threshold]") + to_chat(client, "Setting Persistence: [SSqueue.persist_queue ? "Yes" : "No"]") if("Toggle Queue Server") SSqueue.queue_enabled = !SSqueue.queue_enabled - to_chat(usr, "Queue server is now [SSqueue.queue_enabled ? "Enabled" : "Disabled"]") - message_admins("[key_name_admin(usr)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.") - log_admin("[key_name(usr)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has now **[SSqueue.queue_enabled ? "enabled" : "disabled"]** the queue server.") + to_chat(client, "Queue server is now [SSqueue.queue_enabled ? "Enabled" : "Disabled"]") + message_admins("[key_name_admin(client)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.") + log_admin("[key_name(client)] has [SSqueue.queue_enabled ? "enabled" : "disabled"] the server queue.") + GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[client.ckey]` has now **[SSqueue.queue_enabled ? "enabled" : "disabled"]** the queue server.") if("Set Threshold") - var/new_threshold = input(usr, "Enter new threshold", "Queue Server Manipulation", SSqueue.queue_threshold) as num|null + var/new_threshold = input(client, "Enter new threshold", "Queue Server Manipulation", SSqueue.queue_threshold) as num|null if(!new_threshold) return SSqueue.queue_threshold = new_threshold - to_chat(usr, "Queue threshold is now [SSqueue.queue_threshold]") - message_admins("[key_name_admin(usr)] has set the queue threshold to [SSqueue.queue_threshold].") - log_admin("[key_name(usr)] has set the queue threshold to [SSqueue.queue_threshold].") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has set the queue threshold to **[SSqueue.queue_threshold]**.") + to_chat(client, "Queue threshold is now [SSqueue.queue_threshold]") + message_admins("[key_name_admin(client)] has set the queue threshold to [SSqueue.queue_threshold].") + log_admin("[key_name(client)] has set the queue threshold to [SSqueue.queue_threshold].") + GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[client.ckey]` has set the queue threshold to **[SSqueue.queue_threshold]**.") if("Toggle Setting Persistence") SSqueue.persist_queue = !SSqueue.persist_queue - to_chat(usr, "Queue server setting persistence is now [SSqueue.persist_queue ? "Enabled" : "Disabled"]") - message_admins("[key_name_admin(usr)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.") - log_admin("[key_name(usr)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.") - GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[usr.ckey]` has now **[SSqueue.persist_queue ? "enabled" : "disabled"]** server queue settings persistence.") + to_chat(client, "Queue server setting persistence is now [SSqueue.persist_queue ? "Enabled" : "Disabled"]") + message_admins("[key_name_admin(client)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.") + log_admin("[key_name(client)] has [SSqueue.persist_queue ? "enabled" : "disabled"] the server queue settings persistence.") + GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "**\[Queue Server]** `[client.ckey]` has now **[SSqueue.persist_queue ? "enabled" : "disabled"]** server queue settings persistence.") -/client/proc/add_queue_server_bypass() - set name = "Add Queue Server Bypass" - set desc = "Allow a ckey to bypass the server queue" - set category = "Server" - - if(!check_rights(R_SERVER)) - return - - var/bypass_ckey = tgui_input_text(usr, "Please, enter a ckey. Enter nothing to cancel", "Queue Server Bypass") +USER_VERB(add_queue_server_bypass, R_SERVER, "Add Queue Server Bypass", "Allow a ckey to bypass the server queue", VERB_CATEGORY_SERVER) + var/bypass_ckey = tgui_input_text(client, "Please, enter a ckey. Enter nothing to cancel", "Queue Server Bypass") if(!bypass_ckey) return @@ -53,9 +39,9 @@ var/clean_ckey = ckey(bypass_ckey) if(!clean_ckey) - to_chat(usr, "Invalid ckey supplied") + to_chat(client, "Invalid ckey supplied") return SSqueue.queue_bypass_list.Add(clean_ckey) - message_admins("[key_name_admin(usr)] has added the ckey [clean_ckey] to the queue bypass list.") - log_admin("[key_name(usr)] has added the ckey [clean_ckey] to the queue bypass list.") + message_admins("[key_name_admin(client)] has added the ckey [clean_ckey] to the queue bypass list.") + log_admin("[key_name(client)] has added the ckey [clean_ckey] to the queue bypass list.") diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index c05060131fc..4300b0f02f8 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -1,78 +1,59 @@ -/client/proc/map_template_load() - set category = "Debug" - set name = "Map template - Place" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB(map_template_place, R_DEBUG, "Map template - Place", "Map template - Place", VERB_CATEGORY_DEBUG) var/datum/map_template/template - var/map = input(usr, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in GLOB.map_templates + var/map = input(client, "Choose a Map Template to place at your CURRENT LOCATION","Place Map Template") as null|anything in GLOB.map_templates if(!map) return template = GLOB.map_templates[map] - var/turf/T = get_turf(mob) + var/turf/T = get_turf(client.mob) if(!T) return if(!template.fits_in_map_bounds(T, centered = TRUE)) - to_chat(usr, "Map is too large to fit in bounds. Map's dimensions: ([template.width], [template.height])") + to_chat(client, "Map is too large to fit in bounds. Map's dimensions: ([template.width], [template.height])") return var/list/preview = list() for(var/S in template.get_affected_turfs(T,centered = TRUE)) preview += image('icons/turf/overlays.dmi',S,"greenOverlay") - usr.client.images += preview - if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes") + client.images += preview + if(alert(client, "Confirm location.","Template Confirm","Yes","No") == "Yes") var/timer = start_watch() - message_admins("[key_name_admin(usr)] has started to place the map template ([template.name]) at (JMP)") + message_admins("[key_name_admin(client)] has started to place the map template ([template.name]) at (JMP)") if(template.load(T, centered = TRUE)) - message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at (JMP). Took [stop_watch(timer)]s.") + message_admins("[key_name_admin(client)] has placed a map template ([template.name]) at (JMP). Took [stop_watch(timer)]s.") else - to_chat(usr, "Failed to place map") - usr.client.images -= preview + to_chat(client, "Failed to place map") + client.images -= preview -/client/proc/map_template_upload() - set category = "Debug" - set name = "Map Template - Upload" - - if(!check_rights(R_DEBUG)) - return - - var/map = input(usr, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file +USER_VERB(map_template_upload, R_DEBUG, "Map Template - Upload", "Map Template - Upload", VERB_CATEGORY_DEBUG) + var/map = input(client, "Choose a Map Template to upload to template storage","Upload Map Template") as null|file if(!map) return if(copytext("[map]",-4) != ".dmm") - to_chat(usr, "Bad map file: [map]") + to_chat(client, "Bad map file: [map]") return var/timer = start_watch() - message_admins("[key_name_admin(usr)] has begun uploading a map template ([map])") + message_admins("[key_name_admin(client)] has begun uploading a map template ([map])") var/datum/map_template/M = new(map=map, rename="[map]") if(M.preload_size(map)) - to_chat(usr, "Map template '[map]' ready to place ([M.width]x[M.height])") + to_chat(client, "Map template '[map]' ready to place ([M.width]x[M.height])") GLOB.map_templates[M.name] = M - message_admins("[key_name_admin(usr)] has uploaded a map template ([map]). Took [stop_watch(timer)]s.") + message_admins("[key_name_admin(client)] has uploaded a map template ([map]). Took [stop_watch(timer)]s.") else - to_chat(usr, "Map template '[map]' failed to load properly") + to_chat(client, "Map template '[map]' failed to load properly") -/client/proc/map_template_load_lazy() - set category = "Debug" - set name = "Map template - Lazy Load" - - if(!check_rights(R_DEBUG)) - return - - var/map = input(usr, "Choose a Map Template to place on the lazy load map level.","Place Map Template") as null|anything in GLOB.map_templates +USER_VERB(map_template_load_lazy, R_DEBUG, "Map template - Lazy Load", "Map template - Lazy Load", VERB_CATEGORY_DEBUG) + var/map = input(client, "Choose a Map Template to place on the lazy load map level.","Place Map Template") as null|anything in GLOB.map_templates if(!map) return var/datum/map_template/template = GLOB.map_templates[map] - message_admins("[key_name_admin(usr)] is lazyloading the map template ([template.name]).") + message_admins("[key_name_admin(client)] is lazyloading the map template ([template.name]).") var/datum/turf_reservation/reserve = SSmapping.lazy_load_template(template) if(!istype(reserve)) message_admins("Lazyloading [template.name] failed! You should report this as a bug.") return - message_admins("[key_name_admin(usr)] has lazyloaded the map template ([template.name]) at [ADMIN_JMP(reserve.bottom_left_turf)]") - + message_admins("[key_name_admin(client)] has lazyloaded the map template ([template.name]) at [ADMIN_JMP(reserve.bottom_left_turf)]") diff --git a/code/modules/admin/verbs/mapping_verbs.dm b/code/modules/admin/verbs/mapping_verbs.dm index 49e16972ee6..14b4484e658 100644 --- a/code/modules/admin/verbs/mapping_verbs.dm +++ b/code/modules/admin/verbs/mapping_verbs.dm @@ -35,13 +35,8 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) /obj/effect/debugging/marker/Move() return 0 -/client/proc/camera_view() - set category = "Mapping" - set name = "Camera Range Display" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB_VISIBILITY(debug_camera_view, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_camera_view, R_DEBUG, "Camera Range Display", "Camera Range Display", VERB_CATEGORY_MAPPING) if(GLOB.camera_range_display_status) GLOB.camera_range_display_status = 0 else @@ -59,13 +54,8 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) SSblackbox.record_feedback("tally", "admin_verb", 1, "Camera Range Display") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/sec_camera_report() - set category = "Mapping" - set name = "Camera Report" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB_VISIBILITY(debug_camera_report, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_camera_report, R_DEBUG, "Camera Report", "Camera Report", VERB_CATEGORY_MAPPING) var/list/obj/machinery/camera/CL = list() for(var/obj/machinery/camera/C in GLOB.cameranet.cameras) @@ -95,16 +85,11 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) output += "
  • Camera not connected to wall at \[[C1.x], [C1.y], [C1.z]\] ([C1.loc.loc]) Network: [C1.network]
  • " output += "" - usr << browse(output,"window=airreport;size=1000x500") + client << browse(output,"window=airreport;size=1000x500") SSblackbox.record_feedback("tally", "admin_verb", 1, "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" - - if(!check_rights(R_DEBUG)) - return - +USER_VERB_VISIBILITY(debug_view_intercoms, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_view_intercoms, R_DEBUG, "Intercom Range Display", "Intercom Range Display", VERB_CATEGORY_MAPPING) if(GLOB.intercom_range_display_status) GLOB.intercom_range_display_status = 0 else @@ -121,20 +106,15 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) qdel(F) SSblackbox.record_feedback("tally", "admin_verb", 1, "Intercom Range Display") //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" - - if(!check_rights(R_DEBUG)) - return - - var/level = clean_input("Which z-level?","Level?") +USER_VERB_VISIBILITY(debug_object_count_zlevel, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_object_count_zlevel, R_DEBUG, "Count Objects On Level", "Count Objects On Level", VERB_CATEGORY_MAPPING) + var/level = clean_input("Which z-level?","Level?", user = client) if(!level) return var/num_level = text2num(level) if(!num_level) return if(!isnum(num_level)) return - var/type_text = clean_input("Which type path?","Path?") + var/type_text = clean_input("Which type path?","Path?", user = client) if(!type_text) return var/type_path = text2path(type_text) if(!type_path) return @@ -159,14 +139,9 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) to_chat(world, "There are [count] objects of type [type_path] on z-level [num_level].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects (On Level)") //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" - - if(!check_rights(R_DEBUG)) - return - - var/type_text = clean_input("Which type path?","") +USER_VERB_VISIBILITY(debug_object_count_world, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(debug_object_count_world, R_DEBUG, "Count Objects All", "Count Objects All", VERB_CATEGORY_MAPPING) + var/type_text = clean_input("Which type path?","", user = client) if(!type_text) return var/type_path = text2path(type_text) if(!type_path) return @@ -180,28 +155,22 @@ GLOBAL_VAR_INIT(intercom_range_display_status, 0) to_chat(world, "There are [count] objects of type [type_path] in the game world.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Count Objects (Global)") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/set_next_map() - set category = "Server" - set name = "Set Next Map" - - if(!check_rights(R_SERVER)) - return - +USER_VERB(set_next_map, R_SERVER, "Set Next Map", "Set Next Map", VERB_CATEGORY_SERVER) var/list/map_datums = list() for(var/x in subtypesof(/datum/map)) var/datum/map/M = x if(initial(M.voteable)) map_datums["[initial(M.fluff_name)] ([initial(M.technical_name)])"] = M // Put our map in - var/target_map_name = input(usr, "Select target map", "Next map", null) as null|anything in map_datums + var/target_map_name = input(client, "Select target map", "Next map", null) as null|anything in map_datums if(!target_map_name) return var/datum/map/TM = map_datums[target_map_name] SSmapping.next_map = new TM - var/announce_to_players = alert(usr, "Do you wish to tell the playerbase about your choice?", "Announce", "Yes", "No") - message_admins("[key_name_admin(usr)] has set the next map to [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") - log_admin("[key_name(usr)] has set the next map to [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") + var/announce_to_players = alert(client, "Do you wish to tell the playerbase about your choice?", "Announce", "Yes", "No") + message_admins("[key_name_admin(client)] has set the next map to [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") + log_admin("[key_name(client)] has set the next map to [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") if(announce_to_players == "Yes") - to_chat(world, "[key] has chosen the following map for next round: [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") + to_chat(world, "[client.key] has chosen the following map for next round: [SSmapping.next_map.fluff_name] ([SSmapping.next_map.technical_name])") diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index 89597123153..038f7baac6b 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -1,14 +1,6 @@ -/client/proc/one_click_antag() - set name = "Create Antagonist" - set desc = "Auto-create an antagonist of your choice" - set category = "Event" - - if(!check_rights(R_SERVER|R_EVENT)) return - - if(holder) - holder.one_click_antag() - return - +USER_VERB(one_click_antag, R_SERVER|R_EVENT, "Create Antagonist", "Auto-create an antagonist of your choice", VERB_CATEGORY_EVENT) + if(client.holder) + client.holder.one_click_antag() /datum/admins/proc/one_click_antag() diff --git a/code/modules/admin/verbs/ping_all_admins.dm b/code/modules/admin/verbs/ping_all_admins.dm index 7279a2d9842..9453a63109e 100644 --- a/code/modules/admin/verbs/ping_all_admins.dm +++ b/code/modules/admin/verbs/ping_all_admins.dm @@ -1,11 +1,5 @@ -/client/proc/ping_all_admins() - set name = "Ping all admins" - set category = "Admin" - - if(!check_rights(R_ADMIN, FALSE)) - return - - var/msg = input(src, "What message do you want the ping to show?", "Ping all admins") as text|null +USER_VERB(ping_all_admins, R_ADMIN, "Ping all admins", "Ping all admins", VERB_CATEGORY_ADMIN) + var/msg = input(client, "What message do you want the ping to show?", "Ping all admins") as text|null msg = sanitize(copytext_char(msg, 1, MAX_MESSAGE_LEN)) if(!msg) @@ -17,23 +11,23 @@ if(R_ADMIN & C.holder.rights) admins_to_ping += C - var/de_admin_also = alert(usr, "Do you want to ping admins that have used de-admin?","Ping all admins", "Yes", "No") + var/de_admin_also = alert(client, "Do you want to ping admins that have used de-admin?","Ping all admins", "Yes", "No") if(de_admin_also == "Yes") for(var/key in GLOB.de_admins) - var/client/C = GLOB.directory[ckey] + var/client/C = GLOB.directory[client.ckey] if(!C) continue admins_to_ping += C if(length(admins_to_ping) < 2) // All by yourself? - to_chat(usr, "No other admins online to ping[de_admin_also == "Yes" ? ", including those that have used de-admin" : ""]!") + to_chat(client, "No other admins online to ping[de_admin_also == "Yes" ? ", including those that have used de-admin" : ""]!") return - var/datum/say/asay = new(usr.ckey, usr.client.holder.rank, msg, world.timeofday) + var/datum/say/asay = new(client.ckey, client.holder.rank, msg, world.timeofday) GLOB.asays += asay - log_ping_all_admins("[length(admins_to_ping)] clients pinged: [msg]", src) + log_ping_all_admins("[length(admins_to_ping)] clients pinged: [msg]", client) for(var/client/C in admins_to_ping) SEND_SOUND(C, sound('sound/misc/ping.ogg')) - to_chat(C, "ALL ADMIN PING: [key_name(usr, TRUE)] ([admin_jump_link(mob)]): [msg]") - to_chat(usr, "[length(admins_to_ping)] clients pinged.") + to_chat(C, "ALL ADMIN PING: [key_name(client, TRUE)] ([admin_jump_link(client.mob)]): [msg]") + to_chat(client, "[length(admins_to_ping)] clients pinged.") diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index bc62a9dbd9d..7f92917739a 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -1,26 +1,17 @@ GLOBAL_LIST_EMPTY(sounds_cache) -/client/proc/stop_global_admin_sounds() - set category = "Event" - set name = "Stop Global Admin Sounds" - if(!check_rights(R_SOUNDS)) - return - +USER_VERB(stop_global_admin_sounds, R_SOUNDS, "Stop Global Admin Sounds", "Stop all playing admin sounds", VERB_CATEGORY_EVENT) var/sound/awful_sound = sound(null, repeat = 0, wait = 0, channel = CHANNEL_ADMIN) - log_admin("[key_name(src)] stopped admin sounds.") - message_admins("[key_name_admin(src)] stopped admin sounds.", 1) + log_admin("[key_name(client)] stopped admin sounds.") + message_admins("[key_name_admin(client)] stopped admin sounds.", 1) for(var/mob/M in GLOB.player_list) M << awful_sound var/client/C = M.client C?.tgui_panel?.stop_music() -/client/proc/play_sound(S as sound) - set category = "Event" - set name = "Legacy Play Global Sound" - if(!check_rights(R_SOUNDS)) return - - if(alert("WARNING: Legacy Play Global Sound does not support CDN asset sending. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really use Legacy Play Global Sound?", "Yes", "No") == "No") +USER_VERB(play_sound, R_SOUNDS, "Legacy Play Global Sound", "Send a sound to players", VERB_CATEGORY_EVENT, S as sound) + if(alert(client, "WARNING: Legacy Play Global Sound does not support CDN asset sending. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really use Legacy Play Global Sound?", "Yes", "No") == "No") return var/sound/uploaded_sound = sound(S, repeat = 0, wait = 1, channel = CHANNEL_ADMIN) @@ -28,85 +19,73 @@ GLOBAL_LIST_EMPTY(sounds_cache) GLOB.sounds_cache += S - if(alert("Are you sure?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request" ,"Play", "Cancel") == "Cancel") + if(alert(client, "Are you sure?\nSong: [S]\nNow you can also play this sound using \"Play Server Sound\".", "Confirmation request" ,"Play", "Cancel") == "Cancel") return - if(holder.fakekey) - if(alert("Playing this sound will expose your real ckey despite being in stealth mode. You sure?", "Double check" ,"Play", "Cancel") == "Cancel") + if(client.holder.fakekey) + if(alert(client, "Playing this sound will expose your real ckey despite being in stealth mode. You sure?", "Double check" ,"Play", "Cancel") == "Cancel") return - - log_admin("[key_name(src)] played sound [S]") - message_admins("[key_name_admin(src)] played sound [S]", 1) + log_admin("[key_name(client)] played sound [S]") + message_admins("[key_name_admin(client)] played sound [S]", 1) for(var/mob/M in GLOB.player_list) if(M.client.prefs.sound & SOUND_MIDI) - if(ckey in M.client.prefs.admin_sound_ckey_ignore) + if(client.ckey in M.client.prefs.admin_sound_ckey_ignore) continue // This player has this admin muted if(isnewplayer(M) && (M.client.prefs.sound & SOUND_LOBBY)) M.stop_sound_channel(CHANNEL_LOBBYMUSIC) uploaded_sound.volume = 100 * M.client.prefs.get_channel_volume(CHANNEL_ADMIN) var/this_uid = M.client.UID() - to_chat(M, "[ckey] played [S] (SILENCE) (ALWAYS SILENCE THIS ADMIN)") + to_chat(M, "[client.ckey] played [S] (SILENCE) (ALWAYS SILENCE THIS ADMIN)") SEND_SOUND(M, uploaded_sound) 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! - -/client/proc/play_local_sound(S as sound) - set category = "Event" - set name = "Play Local Sound" - if(!check_rights(R_SOUNDS)) return - - log_admin("[key_name(src)] played a local sound [S]") - message_admins("[key_name_admin(src)] played a local sound [S]", 1) - playsound(get_turf(src.mob), S, 50, FALSE, 0) +USER_VERB(play_local_sound, R_SOUNDS, "Play Local Sound", "Send a sound to players", VERB_CATEGORY_EVENT, S as sound) + log_admin("[key_name(client)] played a local sound [S]") + message_admins("[key_name_admin(client)] played a local sound [S]", 1) + playsound(get_turf(client.mob), S, 50, FALSE, 0) 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_server_sound() - set category = "Event" - set name = "Play Server Sound" - if(!check_rights(R_SOUNDS)) return - +USER_VERB(play_server_sound, R_SOUNDS, "Play Server Sound", "Send a sound to players", VERB_CATEGORY_EVENT) var/list/sounds = file2list("sound/serversound_list.txt") sounds += GLOB.sounds_cache - var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds + var/melody = input(client, "Select a sound from the server to play", "Server sound list") as null|anything in sounds if(!melody) return - play_sound(melody) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Server Sound") //If you are copy-pasting this, ensure the 2nd paramter is unique to the new proc! + SSuser_verbs.invoke_verb(client, /datum/user_verb/play_local_sound, melody) -/client/proc/play_intercomm_sound() - set category = "Event" - set name = "Play Sound via Intercomms" - set desc = "Plays a sound at every intercomm on the station z level. Works best with small sounds." - if(!check_rights(R_SOUNDS)) return +USER_VERB(play_intercomm_sound, \ + R_SOUNDS, "Play Sound via Intercomms", \ + "Plays a sound at every intercomm on the station z level. Works best with small sounds.", \ + VERB_CATEGORY_EVENT) - var/A = alert("This will play a sound at every intercomm, are you sure you want to continue? This works best with short sounds, beware.","Warning","Yep","Nope") + var/A = alert(client, "This will play a sound at every intercomm, are you sure you want to continue? This works best with short sounds, beware.","Warning","Yep","Nope") if(A != "Yep") return var/list/sounds = file2list("sound/serversound_list.txt") sounds += GLOB.sounds_cache - var/melody = input("Select a sound from the server to play", "Server sound list") as null|anything in sounds + var/melody = input(client, "Select a sound from the server to play", "Server sound list") as null|anything in sounds if(!melody) return var/cvol = 35 - var/inputvol = input("How loud would you like this to be? (1-70)", "Volume", "35") as num | null + var/inputvol = input(client, "How loud would you like this to be? (1-70)", "Volume", "35") as num | null if(!inputvol) return if(inputvol && inputvol >= 1 && inputvol <= 70) cvol = inputvol //Allows for override to utilize intercomms on all z-levels - var/B = alert("Do you want to play through intercomms on ALL Z-levels, or just the station?", "Override", "All", "Station") + var/B = alert(client, "Do you want to play through intercomms on ALL Z-levels, or just the station?", "Override", "All", "Station") var/ignore_z = 0 if(B == "All") ignore_z = 1 //Allows for override to utilize incomplete and unpowered intercomms - var/C = alert("Do you want to play through unpowered / incomplete intercomms, so the crew can't silence it?", "Override", "Yep", "Nope") + var/C = alert(client, "Do you want to play through unpowered / incomplete intercomms, so the crew can't silence it?", "Override", "Yep", "Nope") var/ignore_power = 0 if(C == "Yep") ignore_power = 1 @@ -119,27 +98,16 @@ GLOBAL_LIST_EMPTY(sounds_cache) continue playsound(I, melody, cvol) -/client/proc/stop_sounds_global() - set category = "Debug" - set name = "Stop Sounds Global" - set desc = "Stop all playing sounds globally." - if(!check_rights(R_SOUNDS)) - return - - log_admin("[key_name(src)] stopped all currently playing sounds.") - message_admins("[key_name_admin(src)] stopped all currently playing sounds.") +USER_VERB(stop_sounds_global, R_SOUNDS, "Stop Sounds Global", "Stop all playing sounds globally.", VERB_CATEGORY_DEBUG) + log_admin("[key_name(client)] stopped all currently playing sounds.") + message_admins("[key_name_admin(client)] 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() -/client/proc/play_sound_tgchat() - set category = "Event" - set name = "Play Global Sound" - if(!check_rights(R_SOUNDS)) - return - - var/sound_mode = tgui_alert(src, "Play a sound from which source?", "Select Source", list("Web", "Upload MP3")) +USER_VERB(play_sound_tgchat, R_SOUNDS, "Play Global Sound", "Play a sound to be heard by all players.", VERB_CATEGORY_EVENT) + var/sound_mode = tgui_alert(client, "Play a sound from which source?", "Select Source", list("Web", "Upload MP3")) if(!sound_mode) return @@ -152,18 +120,18 @@ GLOBAL_LIST_EMPTY(sounds_cache) if(sound_mode == "Web") if(!GLOB.configuration.system.ytdlp_url) - to_chat(src, "yt-dlp was not configured, action unavailable") //Check config + to_chat(client, "yt-dlp was not configured, action unavailable") //Check config return - web_sound_input = tgui_input_text(src, "Enter content URL", "Play Internet Sound", null) + web_sound_input = tgui_input_text(client, "Enter content URL", "Play Internet Sound", null) if(!length(web_sound_input)) return web_sound_input = trim(web_sound_input) if(findtext(web_sound_input, ":") && !findtext(web_sound_input, GLOB.is_http_protocol)) - to_chat(src, "Non-http(s) URIs are not allowed.") - to_chat(src, "For yt-dlp shortcuts like ytsearch: please use the appropriate full url from the website.") + to_chat(client, "Non-http(s) URIs are not allowed.") + to_chat(client, "For yt-dlp shortcuts like ytsearch: please use the appropriate full url from the website.") return // Prepare the body @@ -181,35 +149,35 @@ GLOBAL_LIST_EMPTY(sounds_cache) try data = json_decode(media_poll_response.body) catch(var/exception/e) - to_chat(src, "yt-dlp JSON parsing FAILED:") - to_chat(src, "[e]: [media_poll_response.body]") + to_chat(client, "yt-dlp JSON parsing FAILED:") + to_chat(client, "[e]: [media_poll_response.body]") return else - to_chat(src, "yt-dlp URL retrieval FAILED:") - to_chat(src, "[media_poll_response.body]") + to_chat(client, "yt-dlp URL retrieval FAILED:") + to_chat(client, "[media_poll_response.body]") return else if(sound_mode == "Upload MP3") if(GLOB.configuration.asset_cache.asset_transport == "simple") - if(tgui_alert(src, "WARNING: Your server is using simple asset transport. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really play direct sound?", list("Yes", "No")) != "Yes") + if(tgui_alert(client, "WARNING: Your server is using simple asset transport. Sounds will have to be sent directly to players, which may freeze the game for long durations. Are you SURE?", "Really play direct sound?", list("Yes", "No")) != "Yes") return must_send_assets = TRUE - var/soundfile = input(src, "Choose an MP3 file to play", "Upload Sound") as null|file + var/soundfile = input(client, "Choose an MP3 file to play", "Upload Sound") as null|file if(!soundfile) return var/static/regex/only_extension = regex(@{"^.*\.([a-z0-9]{1,5})$"}, "gi") var/extension = only_extension.Replace("[soundfile]", "$1") if(!length(extension) || extension != "mp3") - to_chat(src, "Invalid filename extension.") + to_chat(client, "Invalid filename extension.") return var/static/playsound_notch = 1 asset_name = "admin_sound_[playsound_notch++].[extension]" SSassets.transport.register_asset(asset_name, soundfile) - log_admin("[key_name_admin(src)] uploaded admin sound '[soundfile]' to asset transport.") - message_admins("[key_name_admin(src)] uploaded admin sound '[soundfile]' to asset transport.") + log_admin("[key_name_admin(client)] uploaded admin sound '[soundfile]' to asset transport.") + message_admins("[key_name_admin(client)] uploaded admin sound '[soundfile]' to asset transport.") var/static/regex/remove_extension = regex(@{"\.[a-z0-9]+$"}, "gi") data["title"] = remove_extension.Replace("[soundfile]", "") @@ -227,26 +195,26 @@ GLOBAL_LIST_EMPTY(sounds_cache) music_extra_data["link"] = data["webpage_url"] music_extra_data["title"] = data["title"] - var/res = tgui_alert(src, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No")) + var/res = tgui_alert(client, "Show the title of and link to this song to the players?\n[title]", "Show Info?", list("Yes", "No")) if(!res) return if(res == "Yes") - log_admin("[key_name(src)] played sound: [web_sound_input]") - message_admins("[key_name(src)] played sound: [web_sound_input]") - to_chat(world, "[src.ckey] played: [webpage_url]") + log_admin("[key_name(client)] played sound: [web_sound_input]") + message_admins("[key_name(client)] played sound: [web_sound_input]") + to_chat(world, "[client.ckey] played: [webpage_url]") else if(res == "No") music_extra_data["link"] = "Song Link Hidden" music_extra_data["title"] = "Song Title Hidden" music_extra_data["artist"] = "Song Artist Hidden" - log_admin("[key_name(src)] played sound: [web_sound_input]") - message_admins("[key_name(src)] played sound: [web_sound_input]") - to_chat(world, "[src.ckey] played a sound") + log_admin("[key_name(client)] played sound: [web_sound_input]") + message_admins("[key_name(client)] played sound: [web_sound_input]") + to_chat(world, "[client.ckey] played a sound") SSblackbox.record_feedback("tally", "admin_verb", 1, "Play Global Sound TGchat") if(!must_send_assets && web_sound_url && !findtext(web_sound_url, GLOB.is_http_protocol)) - to_chat(src, "BLOCKED: Content URL not using http(s) protocol", confidential = TRUE) - to_chat(src, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol", confidential = TRUE) + to_chat(client, "BLOCKED: Content URL not using http(s) protocol", confidential = TRUE) + to_chat(client, "The media provider returned a content URL that isn't using the HTTP or HTTPS protocol", confidential = TRUE) return if(web_sound_url) @@ -254,14 +222,14 @@ GLOBAL_LIST_EMPTY(sounds_cache) var/client/C = M.client var/player_uid = M.client.UID() if(C.prefs.sound & SOUND_MIDI) - if(ckey in M.client.prefs.admin_sound_ckey_ignore) - to_chat(C, "But [src.ckey] is muted locally in preferences!") + if(client.ckey in M.client.prefs.admin_sound_ckey_ignore) + to_chat(C, "But [client.ckey] is muted locally in preferences!") continue else if(must_send_assets) SSassets.transport.send_assets(C, asset_name) C.tgui_panel?.play_music(web_sound_url, music_extra_data) - to_chat(C, "(SILENCE) (ALWAYS SILENCE THIS ADMIN)") + to_chat(C, "(SILENCE) (ALWAYS SILENCE THIS ADMIN)") else to_chat(C, "But Admin MIDIs are disabled in preferences!") return diff --git a/code/modules/admin/verbs/possess.dm b/code/modules/admin/verbs/possess.dm index 6031dca821a..14ffb2be8f9 100644 --- a/code/modules/admin/verbs/possess.dm +++ b/code/modules/admin/verbs/possess.dm @@ -1,53 +1,44 @@ -/proc/possess(obj/O as obj in world) - set name = "\[Admin\] Possess Obj" - - if(!check_rights(R_POSSESS)) - return - +USER_CONTEXT_MENU(possess_object, R_POSSESS, "\[Admin\] Possess Obj", obj/O as obj in world) if(istype(O,/obj/singularity)) if(GLOB.configuration.general.forbid_singulo_possession) // I love how this needs to exist - to_chat(usr, "It is forbidden to possess singularities.") + to_chat(client, "It is forbidden to possess singularities.") return var/turf/T = get_turf(O) - var/confirm = alert("Are you sure you want to possess [O]?", "Confirm possession", "Yes", "No") + var/confirm = alert(client, "Are you sure you want to possess [O]?", "Confirm possession", "Yes", "No") if(confirm != "Yes") return if(T) - log_admin("[key_name(usr)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])") - message_admins("[key_name_admin(usr)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])", 1) + log_admin("[key_name(client)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])") + message_admins("[key_name_admin(client)] has possessed [O] ([O.type]) at ([T.x], [T.y], [T.z])", 1) else - log_admin("[key_name(usr)] has possessed [O] ([O.type]) at an unknown location") - message_admins("[key_name_admin(usr)] has possessed [O] ([O.type]) at an unknown location", 1) + log_admin("[key_name(client)] has possessed [O] ([O.type]) at an unknown location") + message_admins("[key_name_admin(client)] has possessed [O] ([O.type]) at an unknown location", 1) - if(!usr.control_object) //If you're not already possessing something... - usr.name_archive = usr.real_name + var/mob/client_mob = client.mob - usr.loc = O - usr.real_name = O.name - usr.name = O.name - usr.client.eye = O - usr.control_object = O + if(!client_mob.control_object) //If you're not already possessing something... + client_mob.name_archive = client_mob.real_name + + client_mob.loc = O + client_mob.real_name = O.name + client_mob.name = O.name + client_mob.client.eye = O + client_mob.control_object = O 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(obj/O as obj in world) - set name = "\[Admin\] Release Obj" - //usr.loc = get_turf(usr) - - if(!check_rights(R_POSSESS)) - return - - if(usr.control_object && usr.name_archive) //if you have a name archived and if you are actually relassing an object - usr.real_name = usr.name_archive - usr.name = usr.real_name - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr +USER_CONTEXT_MENU(release_object, R_POSSESS, "\[Admin\] Release Obj", obj/O as obj in world) + var/mob/client_mob = client.mob + if(client_mob.control_object && client_mob.name_archive) //if you have a name archived and if you are actually relassing an object + client_mob.real_name = client_mob.name_archive + client_mob.name = client_mob.real_name + if(ishuman(client_mob)) + var/mob/living/carbon/human/H = client_mob H.name = H.get_visible_name() -// usr.regenerate_icons() //So the name is updated properly - usr.loc = O.loc // Appear where the object you were controlling is -- TLE - usr.client.eye = usr - usr.control_object = null + client_mob.loc = O.loc // Appear where the object you were controlling is -- TLE + client_mob.client.eye = client_mob + client_mob.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! diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 7abe5ce3a77..d5da334caf6 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -15,16 +15,10 @@ message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1) 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! -/client/proc/cmd_admin_prison(mob/M as mob in GLOB.mob_list) - set category = "Admin" - set name = "Prison" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(imprison, R_ADMIN, "Prison", "Send a mob to prison.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list) if(ismob(M)) if(is_ai(M)) - alert("The AI can't be sent to prison you jerk!", null, null, null, null, null) + alert(client, "The AI can't be sent to prison you jerk!", null, null, null, null) return //strip their stuff before they teleport into a cell :downs: for(var/obj/item/W in M) @@ -41,45 +35,32 @@ prisoner.equip_to_slot_or_del(new /obj/item/clothing/shoes/orange(prisoner), ITEM_SLOT_SHOES) spawn(50) to_chat(M, "You have been sent to the prison station!") - log_admin("[key_name(usr)] sent [key_name(M)] to the prison station.") - message_admins("[key_name_admin(usr)] sent [key_name_admin(M)] to the prison station.", 1) + log_admin("[key_name(client)] sent [key_name(M)] to the prison station.") + message_admins("[key_name_admin(client)] sent [key_name_admin(M)] to the prison station.", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Prison") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_subtle_message(mob/M as mob in GLOB.mob_list) - set name = "\[Admin\] Subtle Message" - +USER_CONTEXT_MENU(subtle_message, R_EVENT, "\[Admin\] Subtle Message", mob/M as mob in GLOB.mob_list) if(!ismob(M)) return - if(!check_rights(R_EVENT)) - return - - var/msg = clean_input("Message:", "Subtle PM to [M.key]") + var/msg = clean_input("Message:", "Subtle PM to [M.key]", user = client) if(!msg) return msg = admin_pencode_to_html(msg) - if(usr) - if(usr.client) - if(usr.client.holder) - to_chat(M, "You hear a voice in your head... [msg]") + if(client.holder) + to_chat(M, "You hear a voice in your head... [msg]") - log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]") - message_admins("Subtle Message: [key_name_admin(usr)] -> [key_name_admin(M)] : [msg]", 1) - M.create_log(MISC_LOG, "Subtle Message: [msg]", "From: [key_name_admin(usr)]") + log_admin("SubtlePM: [key_name(client)] -> [key_name(M)] : [msg]") + message_admins("Subtle Message: [key_name_admin(client)] -> [key_name_admin(M)] : [msg]", 1) + M.create_log(MISC_LOG, "Subtle Message: [msg]", "From: [key_name_admin(client)]") 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! -/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are. - set category = "Admin" - set name = "Check New Players" - - if(!check_rights(R_MENTOR|R_MOD|R_ADMIN)) - return - - var/age = input(src, "Show accounts younger then ____ days", "Age check") as num|null - var/playtime_hours = input(src, "Show accounts with less than ____ hours", "Playtime check") as num|null +USER_VERB(check_new_players, R_MENTOR|R_MOD|R_ADMIN, "Check New Players", "Perform a player account age check.", VERB_CATEGORY_ADMIN) + var/age = input(client, "Show accounts younger then ____ days", "Age check") as num|null + var/playtime_hours = input(client, "Show accounts with less than ____ hours", "Playtime check") as num|null if(isnull(age)) age = -1 if(isnull(playtime_hours)) @@ -112,62 +93,45 @@ msg += "[key_name_mentor(C.mob)]: [client_hours] living + ghost hours
    " if(missing_ages) - to_chat(src, "Some accounts did not have proper ages set in their clients. This function requires database to be present") + to_chat(client, "Some accounts did not have proper ages set in their clients. This function requires database to be present") if(msg != "") - src << browse(msg, "window=Player_age_check") + client << browse(msg, "window=Player_age_check") else - to_chat(src, "No matches for that age range found.") + to_chat(client, "No matches for that age range found.") - -/client/proc/cmd_admin_world_narrate() // Allows administrators to fluff events a little easier -- TLE - set category = "Event" - set name = "Global Narrate" - - if(!check_rights(R_SERVER|R_EVENT)) - return - - var/msg = clean_input("Message:", "Enter the text you wish to appear to everyone:") +USER_VERB(global_narrate, R_SERVER|R_EVENT, "Global Narrate", "Narrate text to the whole game world.", VERB_CATEGORY_EVENT) + var/msg = clean_input("Message:", "Enter the text you wish to appear to everyone:", user = client) if(!msg) return msg = admin_pencode_to_html(msg) to_chat(world, "[msg]") - log_admin("GlobalNarrate: [key_name(usr)] : [msg]") - message_admins("GlobalNarrate: [key_name_admin(usr)]: [msg]
    ", 1) - 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_direct_narrate(mob/M) // Targetted narrate -- TLE - set name = "\[Admin\] Direct Narrate" - - if(!check_rights(R_SERVER|R_EVENT)) - return + log_admin("GlobalNarrate: [key_name(client)] : [msg]") + message_admins("GlobalNarrate: [key_name_admin(client)]: [msg]
    ", 1) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Global Narrate") +USER_CONTEXT_MENU(direct_narrate, R_SERVER|R_EVENT, "\[Admin\] Direct Narrate", mob/M) if(!M) - M = input("Direct narrate to who?", "Active Players") as null|anything in get_mob_with_client_list() + M = input(client, "Direct narrate to who?", "Active Players") as null|anything in get_mob_with_client_list() if(!M) return - var/msg = clean_input("Message:", "Enter the text you wish to appear to your target:") + var/msg = clean_input("Message:", "Enter the text you wish to appear to your target:", user = client) if(!msg) return msg = admin_pencode_to_html(msg) to_chat(M, msg) - log_admin("DirectNarrate: [key_name(usr)] to ([key_name(M)]): [msg]") - message_admins("Direct Narrate: [key_name_admin(usr)] to ([key_name_admin(M)]): [msg]
    ", 1) - M.create_log(MISC_LOG, "Direct Narrate: [msg]", "From: [key_name_admin(usr)]") + log_admin("DirectNarrate: [key_name(client)] to ([key_name(M)]): [msg]") + message_admins("Direct Narrate: [key_name_admin(client)] to ([key_name_admin(M)]): [msg]
    ", 1) + M.create_log(MISC_LOG, "Direct Narrate: [msg]", "From: [key_name_admin(client)]") 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_headset_message(mob/M in GLOB.mob_list) - set name = "\[Admin\] Headset Message" - - admin_headset_message(M) +USER_CONTEXT_MENU(headset_message, R_SERVER|R_EVENT, "\[Admin\] Headset Message", mob/M in GLOB.mob_list) + client.admin_headset_message(M) /client/proc/admin_headset_message(mob/M in GLOB.mob_list, sender = null) var/mob/living/carbon/human/H = M @@ -199,22 +163,14 @@ to_chat(H, "Incoming priority transmission from [sender == "Syndicate" ? "your benefactor" : "Central Command"]. Message as follows[sender == "Syndicate" ? ", agent." : ":"] [input]") SEND_SOUND(H, 'sound/effects/headset_message.ogg') - -/client/proc/cmd_admin_godmode(mob/M as mob in GLOB.mob_list) - set category = "Admin" - set name = "Godmode" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(godmode, R_ADMIN, "Godmode", "Toggles godmode on a mob.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list) M.status_flags ^= GODMODE - to_chat(usr, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]") + to_chat(client, "Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]") - log_admin("[key_name(usr)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") - message_admins("[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]", 1) + log_admin("[key_name(client)] has toggled [key_name(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]") + message_admins("[key_name_admin(client)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Godmode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0) if(automute) if(!GLOB.configuration.general.enable_auto_mute) @@ -272,101 +228,77 @@ to_chat(M, "You have been [muteunmute] from [mute_string].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Mute") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_add_random_ai_law() - set category = "Event" - set name = "Add Random AI Law" - - if(!check_rights(R_EVENT)) - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") +USER_VERB(add_random_ai_law, R_EVENT, "Add Random AI Law", "Add a random law to the AI.", VERB_CATEGORY_EVENT) + var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return - log_admin("[key_name(src)] has added a random AI law.") - message_admins("[key_name_admin(src)] has added a random AI law.") + log_admin("[key_name(client)] has added a random AI law.") + message_admins("[key_name_admin(client)] has added a random AI law.") - var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") + var/show_log = alert(client, "Show ion message?", "Message", "Yes", "No") var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) new /datum/event/ion_storm(botEmagChance = 0, announceEvent = announce_ion_laws) - SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Random AI Law") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/toggle_antagHUD_use() - set category = "Server" - set name = "Toggle antagHUD usage" - set desc = "Toggles antagHUD usage for observers" - - if(!check_rights(R_SERVER)) - return + SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Random AI Law") +USER_VERB(toggle_antaghud_use, R_SERVER, "Toggle antagHUD usage", "Toggles antagHUD usage for observers", VERB_CATEGORY_SERVER) var/action="" if(GLOB.configuration.general.allow_antag_hud) GLOB.antag_hud_users.Cut() - for(var/mob/dead/observer/g in get_ghosts()) + for(var/mob/dead/observer/g in client.get_ghosts()) if(g.antagHUD) g.antagHUD = FALSE // Disable it on those that have it enabled to_chat(g, "The Administrators have disabled AntagHUD.") GLOB.configuration.general.allow_antag_hud = FALSE - to_chat(src, "AntagHUD usage has been disabled") + to_chat(client, "AntagHUD usage has been disabled") action = "disabled" else - for(var/mob/dead/observer/g in get_ghosts()) + for(var/mob/dead/observer/g in client.get_ghosts()) if(!g.client.holder) // Add the verb back for all non-admin ghosts to_chat(g, "The Administrators have enabled AntagHUD.")// Notify all observers they can now use AntagHUD GLOB.configuration.general.allow_antag_hud = TRUE action = "enabled" - to_chat(src, "AntagHUD usage has been enabled") + to_chat(client, "AntagHUD usage has been enabled") - log_admin("[key_name(usr)] has [action] antagHUD usage for observers") - message_admins("Admin [key_name_admin(usr)] has [action] antagHUD usage for observers", 1) + log_admin("[key_name(client)] has [action] antagHUD usage for observers") + message_admins("Admin [key_name_admin(client)] has [action] antagHUD usage for observers", 1) -/client/proc/toggle_antagHUD_restrictions() - set category = "Server" - set name = "Toggle antagHUD Restrictions" - set desc = "Restricts players that have used antagHUD from being able to join this round." - - if(!check_rights(R_SERVER)) - return - - if(!usr.client.is_connecting_from_localhost()) - if(tgui_alert(usr, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") +USER_VERB(toggle_antaghug_restrictions, R_SERVER, "Toggle antagHUD Restrictions", \ + "Restricts players that have used antagHUD from being able to join this round.", \ + VERB_CATEGORY_SERVER) + if(!client.is_connecting_from_localhost()) + if(tgui_alert(client, "Are you sure about this?", "Confirm", list("Yes", "No")) != "Yes") return var/action="" if(GLOB.configuration.general.restrict_antag_hud_rejoin) - for(var/mob/dead/observer/g in get_ghosts()) + for(var/mob/dead/observer/g in client.get_ghosts()) to_chat(g, "The administrator has lifted restrictions on joining the round if you use AntagHUD") action = "lifted restrictions" GLOB.configuration.general.restrict_antag_hud_rejoin = FALSE - to_chat(src, "AntagHUD restrictions have been lifted") + to_chat(client, "AntagHUD restrictions have been lifted") else - for(var/mob/dead/observer/g in get_ghosts()) + for(var/mob/dead/observer/g in client.get_ghosts()) to_chat(g, "The administrator has placed restrictions on joining the round if you use AntagHUD") to_chat(g, "Your AntagHUD has been disabled, you may choose to re-enabled it but will be under restrictions.") g.antagHUD = FALSE GLOB.antag_hud_users -= g.ckey action = "placed restrictions" GLOB.configuration.general.restrict_antag_hud_rejoin = TRUE - to_chat(src, "AntagHUD restrictions have been enabled") + to_chat(client, "AntagHUD restrictions have been enabled") - log_admin("[key_name(usr)] has [action] on joining the round if they use AntagHUD") - message_admins("Admin [key_name_admin(usr)] has [action] on joining the round if they use AntagHUD", 1) + log_admin("[key_name(client)] has [action] on joining the round if they use AntagHUD") + message_admins("Admin [key_name_admin(client)] has [action] on joining the round if they use AntagHUD", 1) -/* -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 = "Event" - 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_SPAWN)) - return - - var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", "")) +/// 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. +USER_VERB(respawn_character, R_SPAWN, "Respawn Character", \ + "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.", \ + VERB_CATEGORY_EVENT) + var/input = ckey(input(client, "Please specify which key will be respawned.", "Key", "")) if(!input) return @@ -377,13 +309,13 @@ Traitors and the like can also be revived with the previous role mostly intact. break if(!G_found)//If a ghost was not found. - to_chat(usr, "There is no active key like that in the game or the person is not currently a ghost.") + to_chat(client, "There is no active key like that in the game or the person is not currently a ghost.") return if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something //Check if they were an alien if(G_found.mind.assigned_role=="Alien") - if(alert("This character appears to have been an alien. Would you like to respawn them as such?", null,"Yes","No")=="Yes") + if(alert(client, "This character appears to have been an alien. Would you like to respawn them as such?", null,"Yes","No")=="Yes") var/turf/T if(length(GLOB.xeno_spawn)) T = pick(GLOB.xeno_spawn) else T = pick(GLOB.latejoin) @@ -402,7 +334,7 @@ Traitors and the like can also be revived with the previous role mostly intact. G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use new_xeno.key = G_found.key to_chat(new_xeno, "You have been fully respawned. Enjoy the game.") - message_admins("[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.", 1) + message_admins("[key_name_admin(client)] has respawned [new_xeno.key] as a filthy xeno.", 1) return //all done. The ghost is auto-deleted var/mob/living/carbon/human/new_character = new(pick(GLOB.latejoin))//The mob being spawned. @@ -513,7 +445,7 @@ Traitors and the like can also be revived with the previous role mostly intact. if(alert(new_character,"Would you like an active AI to announce this character?", null,"No","Yes")=="Yes") call(TYPE_PROC_REF(/mob/new_player, AnnounceArrival))(new_character, new_character.mind.assigned_role) - message_admins("[key_name_admin(usr)] has respawned [key_name_admin(G_found)] as [new_character.real_name].", 1) + message_admins("[key_name_admin(client)] has respawned [key_name_admin(G_found)] as [new_character.real_name].", 1) to_chat(new_character, "You have been fully respawned. Enjoy the game.") @@ -521,7 +453,7 @@ Traitors and the like can also be revived with the previous role mostly intact. return new_character //I use this proc for respawn character too. /N -/proc/create_xeno(ckey) +/proc/create_xeno(ckey, mob/user) if(!ckey) var/list/candidates = list() for(var/mob/M in GLOB.player_list) @@ -539,10 +471,10 @@ Traitors and the like can also be revived with the previous role mostly intact. if(length(candidates)) ckey = input("Pick the player you want to respawn as a xeno.", "Suitable Candidates") as null|anything in candidates else - to_chat(usr, "Error: create_xeno(): no suitable candidates.") + to_chat(user, "Error: create_xeno(): no suitable candidates.") if(!istext(ckey)) return 0 - var/alien_caste = input(usr, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva") + var/alien_caste = input(user, "Please choose which caste to spawn.","Pick a caste",null) as null|anything in list("Queen","Hunter","Sentinel","Drone","Larva") var/obj/effect/landmark/spawn_here = length(GLOB.xeno_spawn) ? pick(GLOB.xeno_spawn) : pick(GLOB.latejoin) var/mob/living/carbon/alien/new_xeno switch(alien_caste) @@ -554,10 +486,9 @@ Traitors and the like can also be revived with the previous role mostly intact. else return 0 new_xeno.ckey = ckey - message_admins("[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1) + message_admins("[key_name_admin(user)] has spawned [ckey] as a filthy xeno [alien_caste].", 1) return 1 - /client/proc/get_ghosts(notify = 0, what = 2) // what = 1, return ghosts ass list. // what = 2, return mob list @@ -582,52 +513,32 @@ Traitors and the like can also be revived with the previous role mostly intact. else return mobs -/client/proc/cmd_admin_add_freeform_ai_law() - set category = "Event" - set name = "Add Custom AI law" - - if(!check_rights(R_EVENT)) - return - - var/input = clean_input("Please enter anything you want the AI to do. Anything. Serious.", "What?", "") +USER_VERB(add_freeform_ai_law, R_EVENT, "Add Custom AI law", "Add custom AI law.", VERB_CATEGORY_EVENT) + var/input = clean_input("Please enter anything you want the AI to do. Anything. Serious.", "What?", "", user = client) 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]") + log_admin("Admin [key_name(client)] has added a new AI law - [input]") + message_admins("Admin [key_name_admin(client)] has added a new AI law - [input]") - var/show_log = alert(src, "Show ion message?", "Message", "Yes", "No") + var/show_log = alert(client, "Show ion message?", "Message", "Yes", "No") var/announce_ion_laws = (show_log == "Yes" ? 1 : -1) new /datum/event/ion_storm(botEmagChance = 0, announceEvent = announce_ion_laws, ionMessage = input) - 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/cmd_admin_rejuvenate(mob/living/M as mob in GLOB.mob_list) - set name = "\[Admin\] Rejuvenate" - - if(!check_rights(R_REJUVINATE)) - return - - if(!mob) - return +USER_CONTEXT_MENU(admin_rejuvenate, R_REJUVINATE, "\[Admin\] Rejuvenate", mob/living/M as mob in GLOB.mob_list) if(!istype(M)) - alert("Cannot revive a ghost") + alert(client, "Cannot revive a ghost") return M.revive() - log_admin("[key_name(usr)] healed / revived [key_name(M)]") - message_admins("Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!", 1) + log_admin("[key_name(client)] healed / revived [key_name(M)]") + message_admins("Admin [key_name_admin(client)] healed / revived [key_name_admin(M)]!", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Rejuvenate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_create_centcom_report() - set category = "Event" - set name = "Create Communications Report" - - if(!check_rights(R_SERVER|R_EVENT)) - return - -//the stuff on the list is |"report type" = "report title"|, if that makes any sense +USER_VERB(create_centcom_report, R_SERVER|R_EVENT, "Create Communications Report", "Send an IC announcement to the game world.", VERB_CATEGORY_EVENT) + //the stuff on the list is |"report type" = "report title"|, if that makes any sense var/list/MsgType = list("Central Command Report" = "Nanotrasen Update", "Syndicate Communique" = "Syndicate Message", "Space Wizard Federation Message" = "Sorcerous Message", @@ -638,22 +549,22 @@ Traitors and the like can also be revived with the previous role mostly intact. "Enemy Communications Intercepted" = 'sound/AI/intercept.ogg', "New Command Report Created" = 'sound/AI/commandreport.ogg') - var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType + var/type = input(client, "Pick a type of report to send", "Report Type", "") as anything in MsgType if(type == "Custom") - type = clean_input("What would you like the report type to be?", "Report Type", "Encrypted Transmission") + type = clean_input("What would you like the report type to be?", "Report Type", "Encrypted Transmission", user = client) - var/subtitle = input(usr, "Pick a title for the report.", "Title", MsgType[type]) as text|null + var/subtitle = input(client, "Pick a title for the report.", "Title", MsgType[type]) as text|null if(!subtitle) return - var/message = input(usr, "Please enter anything you want. Anything. Serious.", "What's the message?") as message|null + var/message = input(client, "Please enter anything you want. Anything. Serious.", "What's the message?") as message|null if(!message) return - switch(alert("Should this be announced to the general population?", null,"Yes","No", "Cancel")) + switch(alert(client, "Should this be announced to the general population?", null,"Yes","No", "Cancel")) if("Yes") - var/beepsound = input(usr, "What sound should the announcement make?", "Announcement Sound", "") as anything in MsgSound - var/should_translate = alert(usr, "Should it be auto-translated for all human mobs?", "Translation", "Yes", "No") + var/beepsound = input(client, "What sound should the announcement make?", "Announcement Sound", "") as anything in MsgSound + var/should_translate = alert(client, "Should it be auto-translated for all human mobs?", "Translation", "Yes", "No") if(should_translate != "Yes") should_translate = null // We can just do it like this since force_translation just needs any value to not be false/null GLOB.major_announcement.Announce( @@ -671,18 +582,12 @@ Traitors and the like can also be revived with the previous role mostly intact. else return - log_admin("[key_name(src)] has created a communications report: [message]") - message_admins("[key_name_admin(src)] has created a communications report", 1) + log_admin("[key_name(client)] has created a communications report: [message]") + message_admins("[key_name_admin(client)] has created a communications report", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Comms Report") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/cmd_admin_delete(atom/A as obj|mob|turf in view()) - set name = "\[Admin\] Delete" - - if(!check_rights(R_ADMIN)) - return - - admin_delete(A) +USER_CONTEXT_MENU(admin_delete, R_ADMIN, "\[Admin\] Delete", atom/A as obj|mob|turf in view()) + client.admin_delete(A) /client/proc/admin_delete(datum/D) if(istype(D) && !D.can_vv_delete()) @@ -700,95 +605,71 @@ Traitors and the like can also be revived with the previous role mostly intact. else qdel(D) -/client/proc/cmd_admin_list_open_jobs() - set category = "Admin" - set name = "List free slots" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(list_open_jobs, R_ADMIN, "List free slots", "List available station jobs.", VERB_CATEGORY_ADMIN) if(SSjobs) var/currentpositiontally var/totalpositiontally - to_chat(src, "Job Name: Filled job slot / Total job slots (Free job slots)") + to_chat(client, "Job Name: Filled job slot / Total job slots (Free job slots)") for(var/datum/job/job in SSjobs.occupations) - to_chat(src, "[job.title]: [job.current_positions] / \ + to_chat(client, "[job.title]: [job.current_positions] / \ [job.total_positions == -1 ? "UNLIMITED" : job.total_positions] \ ([job.total_positions == -1 ? "UNLIMITED" : job.total_positions - job.current_positions])") if(job.total_positions != -1) // Only count position that isn't unlimited currentpositiontally += job.current_positions totalpositiontally += job.total_positions - to_chat(src, "Currently filled job slots (Excluding unlimited): [currentpositiontally] / [totalpositiontally] ([totalpositiontally - currentpositiontally])") + to_chat(client, "Currently filled job slots (Excluding unlimited): [currentpositiontally] / [totalpositiontally] ([totalpositiontally - currentpositiontally])") SSblackbox.record_feedback("tally", "admin_verb", 1, "List Free Slots") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in view()) - set category = "Event" - set name = "Explosion" - - if(!check_rights(R_DEBUG|R_EVENT)) - return - - var/devastation = input("Range of total devastation. -1 to none", "Input") as num|null +USER_VERB(admin_explosion, R_DEBUG|R_EVENT, "Explosion", "Create a custom explosion.", VERB_CATEGORY_EVENT, atom/O as obj|mob|turf in view()) + var/devastation = input(client, "Range of total devastation. -1 to none", "Input") as num|null if(devastation == null) return - var/heavy = input("Range of heavy impact. -1 to none", "Input") as num|null + var/heavy = input(client, "Range of heavy impact. -1 to none", "Input") as num|null if(heavy == null) return - var/light = input("Range of light impact. -1 to none", "Input") as num|null + var/light = input(client, "Range of light impact. -1 to none", "Input") as num|null if(light == null) return - var/flash = input("Range of flash. -1 to none", "Input") as num|null + var/flash = input(client, "Range of flash. -1 to none", "Input") as num|null if(flash == null) return - var/flames = input("Range of flames. -1 to none", "Input") as num|null + var/flames = input(client, "Range of flames. -1 to none", "Input") as num|null if(flames == null) return if((devastation != -1) || (heavy != -1) || (light != -1) || (flash != -1) || (flames != -1)) if((devastation > 20) || (heavy > 20) || (light > 20) || (flames > 20)) - if(alert(src, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No") + if(alert(client, "Are you sure you want to do this? It will laaag.", "Confirmation", "Yes", "No") == "No") return - explosion(O, devastation, heavy, light, flash, null, null,flames, cause = "[ckey]: Explosion command") - log_admin("[key_name(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") + explosion(O, devastation, heavy, light, flash, null, null,flames, cause = "[client.ckey]: Explosion command") + log_admin("[key_name(client)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") + message_admins("[key_name_admin(client)] created an explosion ([devastation],[heavy],[light],[flames]) at ([O.x],[O.y],[O.z])") SSblackbox.record_feedback("tally", "admin_verb", 1, "EXPL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return else return -/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in view()) - set category = "Event" - set name = "EM Pulse" - - if(!check_rights(R_DEBUG|R_EVENT)) - return - - var/heavy = input("Range of heavy pulse.", "Input") as num|null +USER_VERB(admin_emp, R_DEBUG|R_EVENT, "EM Pulse", "Cause an electromagnetic pulse.", VERB_CATEGORY_EVENT, atom/O as obj|mob|turf in view()) + var/heavy = input(client, "Range of heavy pulse.", "Input") as num|null if(heavy == null) return - var/light = input("Range of light pulse.", "Input") as num|null + var/light = input(client, "Range of light pulse.", "Input") as num|null if(light == null) return if(heavy || light) empulse(O, heavy, light) - log_admin("[key_name(usr)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])") - message_admins("[key_name_admin(usr)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])", 1) + log_admin("[key_name(client)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])") + message_admins("[key_name_admin(client)] created an EM pulse ([heavy], [light]) at ([O.x],[O.y],[O.z])", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "EMP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return else return -/client/proc/cmd_admin_gib(mob/M as mob in GLOB.mob_list) - set category = "Admin" - set name = "Gib" - - if(!check_rights(R_ADMIN|R_EVENT)) - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") +USER_VERB(gib_mob, R_ADMIN|R_EVENT, "Gib", "Gibs a chosen mob.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list) + var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return //Due to the delay here its easy for something to have happened to the mob if(!M) return - log_admin("[key_name(usr)] has gibbed [key_name(M)]") - message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]", 1) + log_admin("[key_name(client)] has gibbed [key_name(M)]") + message_admins("[key_name_admin(client)] has gibbed [key_name_admin(M)]", 1) if(isobserver(M)) gibs(M.loc) @@ -797,68 +678,43 @@ Traitors and the like can also be revived with the previous role mostly intact. M.gib() 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 = "Event" - - if(!check_rights(R_ADMIN|R_EVENT)) - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") +USER_VERB(gib_self, R_ADMIN|R_EVENT, "Gibself", "Gibself.", VERB_CATEGORY_EVENT) + var/mob/mob = client.mob + var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No") if(confirm == "Yes") if(isobserver(mob)) // so they don't spam gibs everywhere return else mob.gib() - log_admin("[key_name(usr)] used gibself.") - message_admins("[key_name_admin(usr)] used gibself.", 1) + log_admin("[key_name(client)] used gibself.") + message_admins("[key_name_admin(client)] used gibself.", 1) SSblackbox.record_feedback("tally", "admin_verb", 1, "Gibself") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/cmd_admin_check_contents(mob/living/M as mob in GLOB.mob_list) - set name = "\[Admin\] Check Contents" - - if(!check_rights(R_ADMIN)) - return - +USER_CONTEXT_MENU(admin_check_contents, R_ADMIN, "\[Admin\] Check Contents", mob/living/M as mob) var/list/L = M.get_contents() for(var/t in L) - to_chat(usr, "[t]") + to_chat(client, "[t]") + 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/toggle_view_range() - set category = "Admin" - set name = "Change View Range" - set desc = "switches between 1x and custom views" - - if(!check_rights(R_ADMIN)) - return - - if(view == world.view) - view = input("Select view range:", "View Range", world.view) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128) +USER_VERB(toggle_view_range, R_ADMIN, "Change View Range", "Change tile view range.", VERB_CATEGORY_ADMIN) + if(client.view == world.view) + client.view = input(client, "Select view range:", "View Range", world.view) in list(1,2,3,4,5,6,7,8,9,10,11,12,13,14,128) else - view = world.view - - log_admin("[key_name(usr)] changed their view range to [view].") - //message_admins("[key_name_admin(usr)] changed their view range to [view].", 1) //why? removed by order of XSI + client.view = world.view + log_admin("[key_name(client)] changed their view range to [client.view].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Change View Range") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/admin_call_shuttle() - - set category = "Admin" - set name = "Call Shuttle" - +USER_VERB(call_shuttle, R_ADMIN, "Call Shuttle", "Calls the shuttle.", VERB_CATEGORY_ADMIN) if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED) return - if(!check_rights(R_ADMIN)) - return - - var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No") + var/confirm = alert(client, "You sure?", "Confirm", "Yes", "No") if(confirm != "Yes") return - if(alert("Set Shuttle Recallable (Select Yes unless you know what this does)", "Recallable?", "Yes", "No") == "Yes") + if(alert(client, "Set Shuttle Recallable (Select Yes unless you know what this does)", "Recallable?", "Yes", "No") == "Yes") SSshuttle.emergency.canRecall = TRUE else SSshuttle.emergency.canRecall = FALSE @@ -868,27 +724,21 @@ Traitors and the like can also be revived with the previous role mostly intact. else SSshuttle.emergency.request() + log_admin("[key_name(client)] admin-called the emergency shuttle.") + message_admins("[key_name_admin(client)] admin-called the emergency shuttle.") 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("[key_name_admin(usr)] admin-called the emergency shuttle.") - return -/client/proc/admin_cancel_shuttle() - set category = "Admin" - set name = "Cancel Shuttle" - - if(!check_rights(R_ADMIN)) - return - if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return +USER_VERB(cancel_shuttle, R_ADMIN, "Cancel Shuttle", "Cancels the shuttle.", VERB_CATEGORY_ADMIN) + if(alert(client, "You sure?", "Confirm", "Yes", "No") != "Yes") return if(SSshuttle.emergency.mode >= SHUTTLE_DOCKED) return if(!SSshuttle.emergency.canRecall) - if(alert("Shuttle is currently set to be nonrecallable. Recalling may break things. Respect Recall Status?", "Override Recall Status?", "Yes", "No") == "Yes") + if(alert(client, "Shuttle is currently set to be nonrecallable. Recalling may break things. Respect Recall Status?", "Override Recall Status?", "Yes", "No") == "Yes") return else - var/keepStatus = alert("Maintain recall status on future shuttle calls?", "Maintain Status?", "Yes", "No") == "Yes" //Keeps or drops recallability + var/keepStatus = alert(client, "Maintain recall status on future shuttle calls?", "Maintain Status?", "Yes", "No") == "Yes" //Keeps or drops recallability SSshuttle.emergency.canRecall = TRUE // must be true for cancel proc to work SSshuttle.emergency.cancel(byCC = TRUE) if(keepStatus) @@ -896,138 +746,100 @@ Traitors and the like can also be revived with the previous role mostly intact. else SSshuttle.emergency.cancel(byCC = TRUE) + log_admin("[key_name(client)] admin-recalled the emergency shuttle.") + message_admins("[key_name_admin(client)] admin-recalled the emergency shuttle.") 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("[key_name_admin(usr)] admin-recalled the emergency shuttle.") - return - -/client/proc/admin_deny_shuttle() - set category = "Admin" - set name = "Toggle Deny Shuttle" +USER_VERB(deny_shuttle, R_ADMIN, "Toggle Deny Shuttle", "Toggles crew shuttle calling-ability.", VERB_CATEGORY_ADMIN) if(SSticker.current_state < GAME_STATE_PLAYING) - alert("The game hasn't started yet!") + alert(client, "The game hasn't started yet!") return - if(!check_rights(R_ADMIN)) - return - - var/alert = alert(usr, "Do you want to ALLOW or DENY shuttle calls?", "Toggle Deny Shuttle", "Allow", "Deny", "Cancel") + var/alert = alert(client, "Do you want to ALLOW or DENY shuttle calls?", "Toggle Deny Shuttle", "Allow", "Deny", "Cancel") if(alert == "Cancel") return - SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deny Shuttle") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Deny Shuttle") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! if(alert == "Allow") if(!length(SSshuttle.hostile_environments)) - to_chat(usr, "No hostile environments found, cleared for takeoff!") + to_chat(client, "No hostile environments found, cleared for takeoff!") return - if(alert(usr, "[english_list(SSshuttle.hostile_environments)] is currently blocking the shuttle call, do you want to clear them?", "Toggle Deny Shuttle", "Yes", "No") == "Yes") + if(alert(client, "[english_list(SSshuttle.hostile_environments)] is currently blocking the shuttle call, do you want to clear them?", "Toggle Deny Shuttle", "Yes", "No") == "Yes") SSshuttle.hostile_environments.Cut() - var/log = "[key_name(src)] has cleared all hostile environments, allowing the shuttle to be called." + var/log = "[key_name(client)] has cleared all hostile environments, allowing the shuttle to be called." log_admin(log) message_admins(log) return - SSshuttle.registerHostileEnvironment(src) // wow, a client blocking the shuttle - + SSshuttle.registerHostileEnvironment(client) // wow, a client blocking the shuttle log_and_message_admins("has denied the shuttle to be called.") -/client/proc/cmd_admin_attack_log(mob/M as mob in GLOB.mob_list) - set category = "Admin" - set name = "Attack Log" - - if(!check_rights(R_ADMIN)) - return - - to_chat(usr, "Attack Log for [mob]") +USER_VERB(open_attack_log, R_ADMIN, "Attack Log", "Prints the attack log.", VERB_CATEGORY_ADMIN, mob/M as mob in GLOB.mob_list) + to_chat(client, "Attack Log for [M]") for(var/t in M.attack_log_old) - to_chat(usr, t) + to_chat(client, t) SSblackbox.record_feedback("tally", "admin_verb", 1, "Attack Log") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/proc/everyone_random() - set category = "Event" - set name = "Make Everyone Random" - set desc = "Make everyone have a random appearance. You can only use this before rounds!" - - if(!check_rights(R_SERVER|R_EVENT)) - return - +USER_VERB(everyone_random, R_SERVER|R_EVENT, "Make Everyone Random", \ + "Make everyone have a random appearance. You can only use this before rounds!", \ + VERB_CATEGORY_EVENT) if(SSticker && SSticker.mode) - to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") + to_chat(client, "Nope you can't do this, the game's already started. This only works before rounds!") return if(SSticker.random_players) SSticker.random_players = 0 - message_admins("Admin [key_name_admin(usr)] has disabled \"Everyone is Special\" mode.", 1) - to_chat(usr, "Disabled.") + message_admins("Admin [key_name_admin(client)] has disabled \"Everyone is Special\" mode.", 1) + to_chat(client, "Disabled.") return - var/notifyplayers = alert(src, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel") + var/notifyplayers = alert(client, "Do you want to notify the players?", "Options", "Yes", "No", "Cancel") if(notifyplayers == "Cancel") return - log_admin("Admin [key_name(src)] has forced the players to have random appearances.") - message_admins("Admin [key_name_admin(usr)] has forced the players to have random appearances.", 1) + log_admin("Admin [key_name(client)] has forced the players to have random appearances.") + message_admins("Admin [key_name_admin(client)] has forced the players to have random appearances.", 1) if(notifyplayers == "Yes") - to_chat(world, "Admin [usr.key] has forced the players to have completely random identities!") + to_chat(world, "Admin [client.key] has forced the players to have completely random identities!") - to_chat(usr, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") + to_chat(client, "Remember: you can always disable the randomness by using the verb again, assuming the round hasn't started yet.") SSticker.random_players = 1 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/toggle_random_events() - set category = "Event" - set name = "Toggle random events on/off" +USER_VERB(toggle_random_events, R_SERVER|R_EVENT, "Toggle random events on/off", \ + "Toggles random events such as meteors, black holes, blob (but not space dust) on/off", \ + VERB_CATEGORY_EVENT) - set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off" - if(!check_rights(R_SERVER|R_EVENT)) - return - - if(tgui_alert(usr, "[GLOB.configuration.event.enable_random_events ? "Disable" : "Enable"] random events?", "Confirm", list("Yes", "No")) != "Yes") + if(tgui_alert(client, "[GLOB.configuration.event.enable_random_events ? "Disable" : "Enable"] random events?", "Confirm", list("Yes", "No")) != "Yes") return if(!GLOB.configuration.event.enable_random_events) GLOB.configuration.event.enable_random_events = TRUE - to_chat(usr, "Random events enabled") - message_admins("Admin [key_name_admin(usr)] has enabled random events.") + to_chat(client, "Random events enabled") + message_admins("Admin [key_name_admin(client)] has enabled random events.") else GLOB.configuration.event.enable_random_events = FALSE - to_chat(usr, "Random events disabled") - message_admins("Admin [key_name_admin(usr)] has disabled random events.") + to_chat(client, "Random events disabled") + message_admins("Admin [key_name_admin(client)] has disabled random events.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Toggle Random Events") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/reset_all_tcs() - set category = "Admin" - set name = "Reset NTTC Configuration" - set desc = "Resets NTTC to the default configuration." - - if(!check_rights(R_ADMIN)) - return - - var/confirm = alert(src, "You sure you want to reset NTTC?", "Confirm", "Yes", "No") +USER_VERB(reset_telecoms, R_ADMIN, "Reset NTTC Configuration", "Resets NTTC to the default configuration.", VERB_CATEGORY_ADMIN) + var/confirm = alert(client, "You sure you want to reset NTTC?", "Confirm", "Yes", "No") if(confirm != "Yes") return for(var/obj/machinery/tcomms/core/C in GLOB.tcomms_machines) C.nttc.reset() - log_admin("[key_name(usr)] reset NTTC scripts.") - message_admins("[key_name_admin(usr)] reset NTTC scripts.") + log_admin("[key_name(client)] reset NTTC scripts.") + message_admins("[key_name_admin(client)] reset NTTC scripts.") SSblackbox.record_feedback("tally", "admin_verb", 1, "Reset NTTC Configuration") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/list_ssds_afks() - set category = "Admin" - set name = "List SSDs and AFKs" - set desc = "Lists SSD and AFK players" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(list_ssds_afks, R_ADMIN, "List SSDs and AFKs", "List SSDs and AFK players", VERB_CATEGORY_ADMIN) /* ======== SSD Section ========= */ var/msg = "SSD & AFK Report" msg += "SSD Players:
    " @@ -1111,37 +923,24 @@ Traitors and the like can also be revived with the previous role mostly intact. msg += "" msg += "" msg += "
    Cryo
    " - src << browse(msg, "window=Player_ssd_afk_check;size=600x300") - -/client/proc/toggle_ert_calling() - set category = "Event" - set name = "Toggle ERT" - - set desc = "Toggle the station's ability to call a response team." - if(!check_rights(R_EVENT)) - return + client << browse(msg, "window=Player_ssd_afk_check;size=600x300") +USER_VERB(toggle_ert_calling, R_EVENT, "Toggle ERT", "Toggle the station's ability to call a response team.", VERB_CATEGORY_EVENT) if(SSticker.mode.ert_disabled) SSticker.mode.ert_disabled = FALSE - to_chat(usr, "ERT has been Enabled.") - log_admin("Admin [key_name(src)] has enabled ERT calling.") - message_admins("Admin [key_name_admin(usr)] has enabled ERT calling.", 1) + to_chat(client, "ERT has been Enabled.") + log_admin("Admin [key_name(client)] has enabled ERT calling.") + message_admins("Admin [key_name_admin(client)] has enabled ERT calling.", 1) else SSticker.mode.ert_disabled = TRUE - to_chat(usr, "ERT has been Disabled.") - log_admin("Admin [key_name(src)] has disabled ERT calling.") - message_admins("Admin [key_name_admin(usr)] has disabled ERT calling.", 1) + to_chat(client, "ERT has been Disabled.") + log_admin("Admin [key_name(client)] has disabled ERT calling.") + message_admins("Admin [key_name_admin(client)] has disabled ERT calling.", 1) -/client/proc/show_tip() - set category = "Event" - set name = "Show Custom Tip" - set desc = "Sends a tip (that you specify) to all players. After all \ - you're the experienced player here." - - if(!check_rights(R_EVENT)) - return - - var/input = input(usr, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null +USER_VERB(show_tip, R_EVENT, "Show Custom Tip", \ + "Sends a tip (that you specify) to all players. After all, you're the experienced player here.", \ + VERB_CATEGORY_EVENT) + var/input = input(client, "Please specify your tip that you want to send to the players.", "Tip", "") as message|null if(!input) return @@ -1153,21 +952,15 @@ Traitors and the like can also be revived with the previous role mostly intact. // If we've already tipped, then send it straight away. if(SSticker.tipped) SSticker.send_tip_of_the_round() - message_admins("[key_name_admin(usr)] sent a custom Tip of the round.") - log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") + message_admins("[key_name_admin(client)] sent a custom Tip of the round.") + log_admin("[key_name(client)] sent \"[input]\" as the Tip of the Round.") return - message_admins("[key_name_admin(usr)] set the Tip of the round to \"[html_encode(SSticker.selected_tip)]\".") - log_admin("[key_name(usr)] sent \"[input]\" as the Tip of the Round.") + message_admins("[key_name_admin(client)] set the Tip of the round to \"[html_encode(SSticker.selected_tip)]\".") + log_admin("[key_name(client)] sent \"[input]\" as the Tip of the Round.") -/client/proc/modify_goals() - set category = "Event" - set name = "Modify Station Goals" - - if(!check_rights(R_EVENT)) - return - - holder.modify_goals() +USER_VERB(modify_goals, R_EVENT, "Modify Station Goals", "Modify station goals.", VERB_CATEGORY_EVENT) + client.holder.modify_goals() /datum/admins/proc/modify_goals() if(SSticker.current_state < GAME_STATE_PLAYING) @@ -1231,16 +1024,11 @@ Traitors and the like can also be revived with the previous role mostly intact. return REMOVE_TRAIT(D, chosen_trait, source) -/client/proc/create_crate(object as text) - set name = "Create Crate" - set desc = "Spawn a crate from a supplypack datum. Append a period to the text in order to exclude subtypes of paths matching the input." - set category = "Event" - - if(!check_rights(R_SPAWN)) - return - +USER_VERB(create_crate, R_SPAWN, "Create Crate", \ + "Spawn a crate from a supplypack datum. Append a period to the text in order to exclude subtypes of paths matching the input.", \ + VERB_CATEGORY_EVENT, + object as text) var/list/types = SSeconomy.supply_packs - var/list/matches = list() var/include_subtypes = TRUE @@ -1261,12 +1049,12 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!length(matches)) return - var/chosen = input("Select a supply crate type", "Create Crate", matches[1]) as null|anything in matches + var/chosen = input(client, "Select a supply crate type", "Create Crate", matches[1]) as null|anything in matches if(!chosen) return var/datum/supply_packs/the_pack = new chosen() - var/spawn_location = get_turf(usr) + var/spawn_location = get_turf(client.mob) if(!spawn_location) return var/obj/structure/closet/crate/crate = the_pack.create_package(spawn_location) @@ -1275,5 +1063,5 @@ Traitors and the like can also be revived with the previous role mostly intact. A.admin_spawned = TRUE qdel(the_pack) - log_admin("[key_name(usr)] created a '[chosen]' crate at ([usr.x],[usr.y],[usr.z])") + log_admin("[key_name(client)] created a '[chosen]' crate at ([COORD(client.mob)])") SSblackbox.record_feedback("tally", "admin_verb", 1, "Create Crate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/screenshot.dm b/code/modules/admin/verbs/screenshot.dm index 6d7190398d4..2a32ada573f 100644 --- a/code/modules/admin/verbs/screenshot.dm +++ b/code/modules/admin/verbs/screenshot.dm @@ -1,13 +1,13 @@ -/client/proc/cmd_mass_screenshot() - set category = "Debug" - set name = "Mass Screenshot" +USER_VERB(mass_screenshot, R_DEBUG, "Mass Screenshot", "Take a sliced screenshot of a z-level.", VERB_CATEGORY_DEBUG) set waitfor = FALSE - if(!check_rights(R_DEBUG) || !mob) + if(!client.mob) return + var/mob/mob = client.mob + var/confirmation = tgui_alert( - usr, + client, "Are you sure you want to mass screenshot this z-level? \ Ensure you have emptied your BYOND screenshots folder.", "Mass Screenshot", @@ -15,9 +15,9 @@ ) if(confirmation != "Yes") return - + var/sleep_duration = tgui_input_number( - usr, + client, "Enter a delay in deciseconds between screenshots to allow the client to render changes.", "Screenshot delay", default = 2, max_value = 10, min_value = 1, round_value = TRUE @@ -26,25 +26,25 @@ return if(!isobserver(mob)) - admin_ghost() + SSuser_verbs.invoke_verb(client, /datum/user_verb/admin_ghost) - message_admins("[key_name(usr)] started a mass screenshot operation") + message_admins("[key_name(client)] started a mass screenshot operation") // Prepare for screenshot - var/old_client_view = view - var/old_status_bar_visible = winget(src, "menu.statusbar", "is-checked") == "false" ? "true" : "false" + var/old_client_view = client.view + var/old_status_bar_visible = winget(client, "menu.statusbar", "is-checked") == "false" ? "true" : "false" var/old_hud_version = mob.hud_used ? mob.hud_used.hud_version : HUD_STYLE_NOHUD var/old_mob_alpha = mob.alpha var/old_mob_movement = mob.animate_movement - view = 15 - winset(src, "paramapwindow.status_bar", "is-visible=false") + client.view = 15 + winset(client, "paramapwindow.status_bar", "is-visible=false") mob.hud_used?.show_hud(HUD_STYLE_NOHUD) mob.hud_used?.remove_parallax() mob.alpha = 0 mob.animate_movement = NO_STEPS - var/half_chunk_size = view + 1 + var/half_chunk_size = client.view + 1 var/chunk_size = half_chunk_size * 2 - 1 var/cur_x = half_chunk_size var/cur_y = half_chunk_size @@ -60,7 +60,7 @@ while(cur_x < width) mob.forceMove(locate(cur_x, cur_y, cur_z)) sleep(sleep_duration) - winset(src, null, "command='.screenshot auto'") + winset(client, null, "command='.screenshot auto'") if(cur_x == width_inside) break cur_x += chunk_size @@ -72,10 +72,10 @@ cur_y = min(cur_y, height_inside) catch(var/exception/e) exception = e - + // Bring UI back - view = old_client_view - winset(src, "paramapwindow.status_bar", "is-visible=" + old_status_bar_visible) + client.view = old_client_view + winset(client, "paramapwindow.status_bar", "is-visible=" + old_status_bar_visible) mob.alpha = old_mob_alpha mob.hud_used?.show_hud(old_hud_version) mob.hud_used?.update_parallax_pref() @@ -84,4 +84,4 @@ if(exception) throw exception - to_chat(usr, "Provide these values when asked for the MapTileImageTool: [width] [height] [half_chunk_size] [world.icon_size]") + to_chat(client, "Provide these values when asked for the MapTileImageTool: [width] [height] [half_chunk_size] [world.icon_size]") diff --git a/code/modules/admin/verbs/serialization.dm b/code/modules/admin/verbs/serialization.dm index aa4236a5cd0..b2daeb89fa8 100644 --- a/code/modules/admin/verbs/serialization.dm +++ b/code/modules/admin/verbs/serialization.dm @@ -1,30 +1,25 @@ -/client/proc/admin_serialize() - set name = "Serialize Marked Datum" - set desc = "Turns your marked object into a JSON string you can later use to re-create the object" - set category = "Debug" - - if(!check_rights(R_ADMIN|R_DEBUG)) +USER_VERB(serialize_datum, R_ADMIN|R_DEBUG, "Serialize Marked Datum", \ + "Turns your marked object into a JSON string you can later use to re-create the object", \ + VERB_CATEGORY_DEBUG) + if(!istype(client.holder.marked_datum, /atom/movable)) + to_chat(client, "The marked datum is not an atom/movable!") return - if(!istype(holder.marked_datum, /atom/movable)) - to_chat(src, "The marked datum is not an atom/movable!") - return - - var/atom/movable/AM = holder.marked_datum + var/atom/movable/AM = client.holder.marked_datum var/json_data = json_encode(AM.serialize()) - var/choice = alert(usr, "Would you like to store this on your PC or server side?", "Storage Location", "PC", "Server", "Cancel") + var/choice = alert(client, "Would you like to store this on your PC or server side?", "Storage Location", "PC", "Server", "Cancel") if(!choice || choice == "Cancel") return if(choice == "PC") - to_chat(src, chat_box_examine(json_data)) + to_chat(client, chat_box_examine(json_data)) if(choice == "Server") // Right, get their slot names var/list/slots = list("--NEW--") - var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = usr.ckey)) + var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = client.ckey)) if(!dbq.warn_execute()) qdel(dbq) return @@ -34,14 +29,14 @@ qdel(dbq) - var/slot_choice = input(usr, "Select a slot to update, or create a new one.", "Slot Selection") as null|anything in slots + var/slot_choice = input(client, "Select a slot to update, or create a new one.", "Slot Selection") as null|anything in slots if(!slot_choice) return if(slot_choice == "--NEW--") // New slot, save to DB - var/chosen_slot_name = input(usr, "Name your slot", "Slot name") as null|text + var/chosen_slot_name = input(client, "Name your slot", "Slot name") as null|text if(!chosen_slot_name || length(chosen_slot_name) == 0) return @@ -50,7 +45,7 @@ // And save var/datum/db_query/dbq2 = SSdbcore.NewQuery("INSERT INTO json_datum_saves (ckey, slotname, slotjson) VALUES(:ckey, :slotname, :slotjson)", list( - "ckey" = usr.ckey, + "ckey" = client.ckey, "slotname" = clean_name, "slotjson" = json_data )) @@ -59,18 +54,18 @@ return qdel(dbq2) - to_chat(usr, "Successfully saved [clean_name]. You can spawn it from Debug > Spawn Saved JSON Datum.") + to_chat(client, "Successfully saved [clean_name]. You can spawn it from Debug > Spawn Saved JSON Datum.") else // Existing slot, warn first - var/confirmation = alert(usr, "Are you sure you want to update '[slot_choice]'? This cannot be undone!", "You sure?", "Yes", "No") + var/confirmation = alert(client, "Are you sure you want to update '[slot_choice]'? This cannot be undone!", "You sure?", "Yes", "No") if(confirmation != "Yes") return // Now update var/datum/db_query/dbq2 = SSdbcore.NewQuery("UPDATE json_datum_saves SET slotjson=:slotjson WHERE slotname=:slotname AND ckey=:ckey", list( "slotjson" = json_data, - "ckey" = usr.ckey, + "ckey" = client.ckey, "slotname" = slot_choice )) if(!dbq2.warn_execute()) @@ -78,36 +73,19 @@ return qdel(dbq2) - to_chat(usr, "Successfully updated [slot_choice]. You can spawn it from Debug > Spawn Saved JSON Datum.") + to_chat(client, "Successfully updated [slot_choice]. You can spawn it from Debug > Spawn Saved JSON Datum.") - -/client/proc/admin_deserialize() - set name = "Deserialize JSON datum" - set desc = "Creates an object from a JSON string" - set category = "Debug" - - if(!check_rights(R_SPAWN)) // this involves spawning things - return - - var/json_text = input("Enter the JSON code:","Text") as message|null +USER_VERB(deserialize_json, R_SPAWN, "Deserialize JSON datum", "Creates an object from a JSON string", VERB_CATEGORY_DEBUG) + var/json_text = input(client, "Enter the JSON code:","Text") as message|null if(json_text) - json_to_object(json_text, get_turf(usr)) - message_admins("[key_name_admin(usr)] spawned an atom from a custom JSON object.") - log_admin("[key_name(usr)] spawned an atom from a custom JSON object, JSON Text: [json_text]") - - -/client/proc/json_spawn_menu() - set name = "Spawn Saved JSON Datum" - set desc = "Spawns a JSON datums saved server side" - set category = "Debug" - - // This needs a holder to function - if(!check_rights(R_SPAWN) || !holder) - return + json_to_object(json_text, get_turf(client.mob)) + message_admins("[key_name_admin(client)] spawned an atom from a custom JSON object.") + log_admin("[key_name(client)] spawned an atom from a custom JSON object, JSON Text: [json_text]") +USER_VERB(spawn_json, R_SPAWN, "Spawn Saved JSON Datum", "Spawns a JSON datums saved server side", VERB_CATEGORY_DEBUG) // Right, get their slot names var/list/slots = list() - var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname, id FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = usr.ckey)) + var/datum/db_query/dbq = SSdbcore.NewQuery("SELECT slotname, id FROM json_datum_saves WHERE ckey=:ckey", list("ckey" = client.ckey)) if(!dbq.warn_execute()) qdel(dbq) return @@ -117,10 +95,10 @@ qdel(dbq) - var/datum/browser/popup = new(usr, "jsonspawnmenu", "JSON Spawn Menu", 400, 300) + var/datum/browser/popup = new(client, "jsonspawnmenu", "JSON Spawn Menu", 400, 300) // Cache this to reduce proc jumps - var/holder_uid = holder.UID() + var/holder_uid = client.holder.UID() var/list/rows = list() rows += "" diff --git a/code/modules/admin/verbs/space_transitions.dm b/code/modules/admin/verbs/space_transitions.dm index bf2dd51bab7..2448b009c14 100644 --- a/code/modules/admin/verbs/space_transitions.dm +++ b/code/modules/admin/verbs/space_transitions.dm @@ -1,51 +1,32 @@ -/client/proc/admin_redo_space_transitions() - set name = "Remake Space Transitions" - set desc = "Re-assigns all space transitions" - set category = "Debug" - - if(!check_rights(R_ADMIN|R_DEBUG)) - return - - var/choice = alert("Do you want to rebuild space transitions?", null,"Yes", "No") +USER_VERB_VISIBILITY(redo_space_transitions, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(redo_space_transitions, R_ADMIN|R_DEBUG, "Remake Space Transitions", "Re-assigns all space transitions", VERB_CATEGORY_DEBUG) + var/choice = alert(client, "Do you want to rebuild space transitions?", null,"Yes", "No") if(choice == "No") return - - message_admins("[key_name_admin(usr)] re-assigned all space transitions") + message_admins("[key_name_admin(client)] re-assigned all space transitions") GLOB.space_manager.do_transition_setup() - log_admin("[key_name(usr)] re-assigned all space transitions") + log_admin("[key_name(client)] re-assigned all space transitions") SSblackbox.record_feedback("tally", "admin_verb", 1, "Remake Space Transitions") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - - -/client/proc/make_turf_space_map() - set name = "Make Space Map" - set desc = "Create a map of the space levels as turfs at your feet" - set category = "Debug" - - if(!check_rights(R_ADMIN|R_DEBUG)) - return - - var/choice = alert("Are you sure you want to make a space map out of turfs?", null,"Yes","No") +USER_VERB_VISIBILITY(make_turf_space_map, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(make_turf_space_map, R_ADMIN|R_DEBUG, "Make Space Map", "Create a map of the space levels as turfs at your feet", VERB_CATEGORY_DEBUG) + var/choice = alert(client, "Are you sure you want to make a space map out of turfs?", null,"Yes","No") if(choice == "No") return var/static/list/sectortypes = list(TRANSITION_TAG_SPACE, TRANSITION_TAG_LAVALAND) - var/sectortype = tgui_input_list(usr, "Please select sector type", "", sectortypes) + var/sectortype = tgui_input_list(client, "Please select sector type", "", sectortypes) if(!(sectortype in sectortypes)) return - message_admins("[key_name_admin(usr)] made a space map") + message_admins("[key_name_admin(client)] made a space map") - GLOB.space_manager.map_as_turfs(get_turf(usr), sectortype) - log_admin("[key_name(usr)] made a space map") + GLOB.space_manager.map_as_turfs(get_turf(client.mob), sectortype) + log_admin("[key_name(client)] made a space map") - -/proc/save_lavaland_maps() - for(var/zlvl in levels_by_trait(ORE_LEVEL)) - GLOB.maploader.save_map(locate(1, 1, zlvl), locate(world.maxx, world.maxy, zlvl), "lavaland_[zlvl]") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Make Space Map") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/ticklag.dm b/code/modules/admin/verbs/ticklag.dm index 3edabe4be31..34eea0f6c39 100644 --- a/code/modules/admin/verbs/ticklag.dm +++ b/code/modules/admin/verbs/ticklag.dm @@ -1,21 +1,13 @@ -//Merged Doohl's and the existing ticklag as they both had good elements about them ~Carn - -/client/proc/ticklag() - set category = "Debug" - set name = "Set Ticklag" - set desc = "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9" - - if(!check_rights(R_MAINTAINER)) return - - var/newtick = input("Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null +USER_VERB(set_ticklag, R_MAINTAINER, "Set Ticklag", \ + "Sets a new tick lag. Recommend you don't mess with this too much! Stable, time-tested ticklag value is 0.9", \ + VERB_CATEGORY_DEBUG) + var/newtick = input(client, "Sets a new tick lag. Please don't mess with this too much! The stable, time-tested ticklag value is 0.9","Lag of Tick", world.tick_lag) as num|null //I've used ticks of 2 before to help with serious singulo lags if(newtick && newtick <= 2 && newtick > 0) - log_admin("[key_name(src)] has modified world.tick_lag to [newtick]", 0) - message_admins("[key_name_admin(src)] has modified world.tick_lag to [newtick]", 0) + log_admin("[key_name(client)] has modified world.tick_lag to [newtick]", 0) + message_admins("[key_name_admin(client)] has modified world.tick_lag to [newtick]", 0) world.tick_lag = newtick SSblackbox.record_feedback("tally", "admin_verb", 1, "Set Ticklag") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! else - to_chat(src, "Error: ticklag(): Invalid world.ticklag value. No changes made.") - - + to_chat(client, "Error: ticklag(): Invalid world.ticklag value. No changes made.") diff --git a/code/modules/admin/verbs/toggledebugverbs.dm b/code/modules/admin/verbs/toggledebugverbs.dm index 120a69b924b..f558347f4f8 100644 --- a/code/modules/admin/verbs/toggledebugverbs.dm +++ b/code/modules/admin/verbs/toggledebugverbs.dm @@ -1,32 +1,9 @@ -GLOBAL_LIST_INIT(admin_verbs_show_debug_verbs, list( - /client/proc/camera_view, - /client/proc/sec_camera_report, - /client/proc/intercom_view, - /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, - /client/proc/startSinglo, - /client/proc/cmd_admin_grantfullaccess, - /client/proc/cmd_admin_areatest, - /client/proc/cmd_admin_rejuvenate, - /datum/admins/proc/show_traitor_panel, - /client/proc/forceEvent, - /client/proc/admin_redo_space_transitions, - /client/proc/make_turf_space_map, - /client/proc/cmd_clean_radiation, -)) - // Would be nice to make this a permanent admin pref so we don't need to click it each time -/client/proc/enable_debug_verbs() - set category = "Debug" - set name = "Debug verbs" - - if(!check_rights(R_DEBUG)) - return - - add_verb(src, GLOB.admin_verbs_show_debug_verbs) - +USER_VERB(enable_debug_verbs, R_DEBUG, "Debug verbs", "Enable all debug verbs.", VERB_CATEGORY_DEBUG) + SSuser_verbs.update_visibility_flag(client, VERB_VISIBILITY_FLAG_MOREDEBUG, TRUE) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +USER_VERB_VISIBILITY(disable_debug_verbs, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(disable_debug_verbs, R_DEBUG, "Debug verbs", "Disable all debug verbs.", VERB_CATEGORY_DEBUG) + SSuser_verbs.update_visibility_flag(client, VERB_VISIBILITY_FLAG_MOREDEBUG, FALSE) SSblackbox.record_feedback("tally", "admin_verb", 1, "Debug Verbs") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/view_instances.dm b/code/modules/admin/verbs/view_instances.dm index 65d6105da3a..06c0e2a31c5 100644 --- a/code/modules/admin/verbs/view_instances.dm +++ b/code/modules/admin/verbs/view_instances.dm @@ -1,12 +1,5 @@ -/client/proc/view_instances() - set name = "View Server Instances" - set desc = "View the running server instances" - set category = "Server" - - if(!check_rights(R_ADMIN)) - return - - to_chat(usr, "Server instances info") +USER_VERB(view_server_instances, R_ADMIN, "View Server Instances", "View the running server instances", VERB_CATEGORY_SERVER) + to_chat(client, "Server instances info") var/datum/db_query/dbq1 = SSdbcore.NewQuery({" SELECT server_id, key_name, key_value FROM instance_data_cache WHERE server_id IN (SELECT server_id FROM instance_data_cache WHERE @@ -29,5 +22,5 @@ var/server_data = servers_outer[server] var/players = text2num(server_data["playercount"]) - to_chat(usr, "[server] - [players] player[players == 1 ? "" : "s"] online.") - to_chat(usr, "Offline instances are not reported") + to_chat(client, "[server] - [players] player[players == 1 ? "" : "s"] online.") + to_chat(client, "Offline instances are not reported") diff --git a/code/modules/economy/economy_admin.dm b/code/modules/economy/economy_admin.dm index 22ba9d4f493..b59caf54e58 100644 --- a/code/modules/economy/economy_admin.dm +++ b/code/modules/economy/economy_admin.dm @@ -1,13 +1,6 @@ -/client/proc/economy_manager() - set name = "Economy Panel" - set category = "Event" - set desc = "Perform Various Event Modification to the Economy" - - if(!check_rights(R_EVENT)) - return - +USER_VERB(economy_panel, R_EVENT, "Economy Panel", "Open the economy panel.", VERB_CATEGORY_EVENT) var/datum/ui_module/economy_manager/E = new() - E.ui_interact(usr) + E.ui_interact(client.mob) /datum/ui_module/economy_manager name = "Economy Manager" diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index f77ccd5a487..cf3dd339e2f 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -143,15 +143,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) GLOB.error_cache.logError(e, desclines, e_src = e_src) #endif -/client/proc/throw_runtime() - set name = "Throw Runtime" - set desc = "Throws a runtime, what did you expect?" - set category = "Debug" - - if(!check_rights(R_MAINTAINER)) - return - - throw_runtime_inner(1337, 0) +USER_VERB(throw_runtime, R_MAINTAINER, "Throw Runtime", "Throws a runtime, what did you expect?", VERB_CATEGORY_DEBUG) + client.throw_runtime_inner(1337, 0) /client/proc/throw_runtime_inner(x, y) to_chat(usr, "[x]/[y]=[x/y]") diff --git a/code/modules/events/event_procs.dm b/code/modules/events/event_procs.dm index 217db61eaec..1fb14af107d 100644 --- a/code/modules/events/event_procs.dm +++ b/code/modules/events/event_procs.dm @@ -1,22 +1,13 @@ +USER_VERB_VISIBILITY(trigger_event, VERB_VISIBILITY_FLAG_MOREDEBUG) +USER_VERB(trigger_event, R_EVENT, "Trigger Event", "Trigger Event", VERB_CATEGORY_EVENT, event_type in SSevents.allEvents) + if(ispath(event_type)) + new event_type(new /datum/event_meta(EVENT_LEVEL_MAJOR)) + message_admins("[key_name_admin(client)] has triggered an event. ([event_type])", 1) -/client/proc/forceEvent(type in SSevents.allEvents) - set name = "Trigger Event" - set category = "Event" - - if(!check_rights(R_EVENT)) - return - - if(ispath(type)) - new type(new /datum/event_meta(EVENT_LEVEL_MAJOR)) - message_admins("[key_name_admin(usr)] has triggered an event. ([type])", 1) - -/client/proc/event_manager_panel() - set name = "Event Manager Panel" - set category = "Event" +USER_VERB(event_manager_panel, R_EVENT, "Event Manager Panel", "Event Manager Panel", VERB_CATEGORY_EVENT) if(SSevents) - SSevents.Interact(usr) + SSevents.Interact(client) SSblackbox.record_feedback("tally", "admin_verb", 1, "Event Manager") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return /proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in! var/list/safe_areas = typecacheof(list( diff --git a/code/modules/holiday/holiday.dm b/code/modules/holiday/holiday.dm index 0b10e9e0472..9f80635766a 100644 --- a/code/modules/holiday/holiday.dm +++ b/code/modules/holiday/holiday.dm @@ -320,20 +320,17 @@ // to_chat(world, "Easter calculates to be on [begin_day] of [begin_month] ([days_early] early) to [end_day] of [end_month] ([days_extra] extra) for 20[yy]") return ..() - -/client/proc/set_holiday(T as text|null) - set name = "Set Holiday" - set category = "Event" - set desc = "Force-set the Holiday variable to make the game think it's a certain day." - if(!check_rights(R_SERVER)) return - +USER_VERB(set_holiday, R_SERVER, "Set Holiday", \ + "Force-set the Holiday variable to make the game think it's a certain day.", \ + VERB_CATEGORY_EVENT, \ + T as text|null) var/list/choice = list() for(var/H in subtypesof(/datum/holiday)) choice += "[H]" choice += "--CANCEL--" - var/selected = input("What holiday would you like to force?","Holiday Forcing","--CANCEL--") in choice + var/selected = input(client, "What holiday would you like to force?","Holiday Forcing","--CANCEL--") in choice if(selected == "--CANCEL--") return @@ -352,5 +349,5 @@ //update our hub status world.update_status() - message_admins("ADMIN: Event: [key_name_admin(src)] force-set Holiday to \"[H]\"") - log_admin("[key_name(src)] force-set Holiday to \"[H]\"") + message_admins("ADMIN: Event: [key_name_admin(client)] force-set Holiday to \"[H]\"") + log_admin("[key_name(client)] force-set Holiday to \"[H]\"") diff --git a/code/modules/library/library_admin.dm b/code/modules/library/library_admin.dm index 3d82c277217..85107eda32d 100644 --- a/code/modules/library/library_admin.dm +++ b/code/modules/library/library_admin.dm @@ -2,16 +2,10 @@ #define LIBRARY_MENU_CKEY 2 #define LIBRARY_MENU_REPORTS 3 -/client/proc/library_manager() - set name = "Manage Library" - set category = "Admin" - set desc = "Manage Flagged Books and Perform Maintenance on the Library System" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(library_manager, R_ADMIN, "Manage Library", "Manage Flagged Books and Perform Maintenance on the Library System", VERB_CATEGORY_ADMIN) var/datum/ui_module/library_manager/L = new() - L.ui_interact(usr) + L.ui_interact(client.mob) + SSblackbox.record_feedback("tally", "admin_verb", 1, "Manage Library") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /datum/ui_module/library_manager name = "Library Manager" diff --git a/code/modules/mob/mob_vv.dm b/code/modules/mob/mob_vv.dm index a21848be8cc..db7140efc9a 100644 --- a/code/modules/mob/mob_vv.dm +++ b/code/modules/mob/mob_vv.dm @@ -42,34 +42,19 @@ rename_character(real_name, new_name) href_list["datumrefresh"] = UID() if(href_list[VV_HK_MOB_PLAYER_PANEL]) - if(!check_rights(R_ADMIN|R_MOD)) - return - - usr.client.holder.show_player_panel(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/show_player_panel, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_GIVE_SPELL]) - if(!check_rights(R_SERVER|R_EVENT)) - return - - usr.client.give_spell(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/give_spell, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_GIVE_DISEASE]) - if(!check_rights(R_SERVER|R_EVENT)) - return - - usr.client.give_disease(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/give_disease, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_GODMODE]) - if(!check_rights(R_EVENT)) - return - - usr.client.cmd_admin_godmode(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/godmode, src) href_list["datumrefresh"] = UID() if(href_list[VV_HK_GIB]) - if(!check_rights(R_ADMIN|R_EVENT)) - return - - usr.client.cmd_admin_gib(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/gib_mob, src) if(href_list[VV_HK_BUILD_MODE]) if(!check_rights(R_BUILDMODE)) return @@ -83,11 +68,7 @@ if(usr.client) usr.client.cmd_admin_drop_everything(src) if(href_list[VV_HK_DIRECT_CONTROL]) - if(!check_rights(R_DEBUG|R_ADMIN)) - return - - if(usr.client) - usr.client.cmd_assume_direct_control(src) + SSuser_verbs.invoke_verb(usr, /datum/user_verb/assume_direct_control, src) if(href_list[VV_HK_OFFER_CONTROL]) if(!check_rights(R_ADMIN)) return diff --git a/code/modules/paperwork/fax.dm b/code/modules/paperwork/fax.dm index 97ec2496581..f2d2c6c93f0 100644 --- a/code/modules/paperwork/fax.dm +++ b/code/modules/paperwork/fax.dm @@ -20,14 +20,10 @@ GLOBAL_LIST_EMPTY(adminfaxes) /datum/fax/admin/New() return -// Fax panel - lets admins check all faxes sent during the round -/client/proc/fax_panel() - set name = "Fax Panel" - set category = "Event" - if(holder) - holder.fax_panel(usr) +USER_VERB(fax_panel, R_ADMIN, "Fax Panel", "Lets admins check all faxes sent during the round.", VERB_CATEGORY_EVENT) + if(client.holder) + client.holder.fax_panel(client.mob) SSblackbox.record_feedback("tally", "admin_verb", 1, "Fax Panel") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - return /datum/admins/proc/fax_panel(mob/living/user) var/html = "Refresh" diff --git a/code/modules/procedural_mapping/mapGenerator.dm b/code/modules/procedural_mapping/mapGenerator.dm index e2e2b0c865b..a4f3655f3dd 100644 --- a/code/modules/procedural_mapping/mapGenerator.dm +++ b/code/modules/procedural_mapping/mapGenerator.dm @@ -122,48 +122,42 @@ // HERE BE DEBUG DRAGONS // /////////////////////////// -/client/proc/debugNatureMapGenerator() - set name = "Test Nature Map Generator" - set category = "Debug" - - if(!check_rights(R_MAINTAINER)) - return - +USER_VERB(test_nature_map_generator, R_MAINTAINER, "Test Nature Map Generator", "Test nature map generator", VERB_CATEGORY_DEBUG) var/datum/map_generator/nature/N = new() - var/startInput = clean_input("Start turf of Map, (X;Y;Z)", "Map Gen Settings", "1;1;1") - var/endInput = clean_input("End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[mob ? mob.z : 1]") + var/startInput = clean_input("Start turf of Map, (X;Y;Z)", "Map Gen Settings", "1;1;1", user = client) + var/endInput = clean_input("End turf of Map (X;Y;Z)", "Map Gen Settings", "[world.maxx];[world.maxy];[client.mob ? client.mob.z : 1]", user = client) //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(client, "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(client, "Invalid Coords") + to_chat(client, "Start Input: [startInput]") + to_chat(client, "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(client, "Invalid Turfs") + to_chat(client, "Start Coords: [startCoords[1]] - [startCoords[2]] - [startCoords[3]]") + to_chat(client, "End Coords: [endCoords[1]] - [endCoords[2]] - [endCoords[3]]") return var/list/clusters = list("None"=MAP_GENERATOR_CLUSTER_CHECK_NONE,"All"=MAP_GENERATOR_CLUSTER_CHECK_ALL,"Sames"=MAP_GENERATOR_CLUSTER_CHECK_SAMES,"Differents"=MAP_GENERATOR_CLUSTER_CHECK_DIFFERENTS, \ "Same turfs"=MAP_GENERATOR_CLUSTER_CHECK_SAME_TURFS, "Same atoms"=MAP_GENERATOR_CLUSTER_CHECK_SAME_ATOMS, "Different turfs"=MAP_GENERATOR_CLUSTER_CHECK_DIFFERENT_TURFS, \ "Different atoms"=MAP_GENERATOR_CLUSTER_CHECK_DIFFERENT_ATOMS, "All turfs"=MAP_GENERATOR_CLUSTER_CHECK_ALL_TURFS,"All atoms"=MAP_GENERATOR_CLUSTER_CHECK_ALL_ATOMS) - var/moduleClusters = input("Cluster Flags (Cancel to leave unchanged from defaults)","Map Gen Settings") as null|anything in clusters + var/moduleClusters = input(client, "Cluster Flags (Cancel to leave unchanged from defaults)","Map Gen Settings") as null|anything in clusters //null for default var/theCluster = 0 if(moduleClusters != "None") if(!clusters[moduleClusters]) - to_chat(src, "Invalid Cluster Flags") + to_chat(client, "Invalid Cluster Flags") return theCluster = clusters[moduleClusters] else @@ -174,9 +168,9 @@ M.clusterCheckFlags = theCluster - to_chat(src, "Defining Region") + to_chat(client, "Defining Region") N.defineRegion(Start, End) - to_chat(src, "Region Defined") - to_chat(src, "Generating Region") + to_chat(client, "Region Defined") + to_chat(client, "Generating Region") N.generate() - to_chat(src, "Generated Region") + to_chat(client, "Generated Region") diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index f3c1a4f016f..50021ca559c 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -11,24 +11,19 @@ GLOBAL_VAR_INIT(send_emergency_team, FALSE) GLOBAL_VAR_INIT(ert_request_answered, FALSE) GLOBAL_LIST_EMPTY(ert_request_messages) -/client/proc/response_team() - set name = "Dispatch CentComm Response Team" - set category = "Event" - set desc = "Send an CentComm response team to the station." - - if(!check_rights(R_EVENT)) - return - +USER_VERB(dispatch_ert, R_EVENT, "Dispatch CentComm Response Team", \ + "Send an CentComm response team to the station.", \ + VERB_CATEGORY_EVENT) if(SSticker.current_state < GAME_STATE_PLAYING) - to_chat(usr, "The game hasn't started yet!") + to_chat(client, "The game hasn't started yet!") return if(SSticker.current_state == GAME_STATE_PREGAME) - to_chat(usr, "The round hasn't started yet!") + to_chat(client, "The round hasn't started yet!") return var/datum/ui_module/ert_manager/E = new() - E.ui_interact(usr) + E.ui_interact(client.mob) /mob/proc/JoinResponseTeam() diff --git a/code/modules/station_goals/secondary/secondary_goal.dm b/code/modules/station_goals/secondary/secondary_goal.dm index f5d0e6ed2e2..25b299fb550 100644 --- a/code/modules/station_goals/secondary/secondary_goal.dm +++ b/code/modules/station_goals/secondary/secondary_goal.dm @@ -118,16 +118,16 @@ log_admin("[key_name_admin(usr)] removed secondary goal [src] ([admin_desc])") tracker.unregister(SSshuttle.supply) qdel(src) - usr.client.modify_goals() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/modify_goals) else if(href_list["mark_complete"]) completed = 1 tracker.unregister(SSshuttle.supply) - usr.client.modify_goals() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/modify_goals) message_admins("[key_name_admin(usr)] marked secondary goal [src] ([admin_desc]) as complete") log_admin("[key_name_admin(usr)] marked secondary goal [src] ([admin_desc]) as complete") else if(href_list["reset_progress"]) completed = 0 tracker.reset() - usr.client.modify_goals() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/modify_goals) message_admins("[key_name_admin(usr)] reset progress of secondary goal [src] ([admin_desc])") log_admin("[key_name_admin(usr)] reset progress of secondary goal [src] ([admin_desc])") diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm index c77d9c79ce0..8b0d4606677 100644 --- a/code/modules/station_goals/station_goal.dm +++ b/code/modules/station_goals/station_goal.dm @@ -52,4 +52,4 @@ message_admins("[key_name_admin(usr)] removed station goal [src]") log_admin("[key_name_admin(usr)] removed station goal [src]") qdel(src) - usr.client.modify_goals() + SSuser_verbs.invoke_verb(usr, /datum/user_verb/modify_goals) diff --git a/code/modules/tgui/modules/ert_manager.dm b/code/modules/tgui/modules/ert_manager.dm index d204d60b34b..357e68493e9 100644 --- a/code/modules/tgui/modules/ert_manager.dm +++ b/code/modules/tgui/modules/ert_manager.dm @@ -111,7 +111,7 @@ trigger_armed_response_team(D, commander_slots, security_slots, medical_slots, engineering_slots, janitor_slots, paranormal_slots, cyborg_slots, cyborg_security) if("view_player_panel") - ui.user.client.holder.show_player_panel(locate(params["uid"])) + SSuser_verbs.invoke_verb(ui.user, /datum/user_verb/show_player_panel, locate(params["uid"])) if("deny_ert") GLOB.ert_request_answered = TRUE diff --git a/code/modules/tgui_input/say_modal/tgui_say_speech.dm b/code/modules/tgui_input/say_modal/tgui_say_speech.dm index 87a0fbdd67a..d434a909132 100644 --- a/code/modules/tgui_input/say_modal/tgui_say_speech.dm +++ b/code/modules/tgui_input/say_modal/tgui_say_speech.dm @@ -28,19 +28,19 @@ client.looc(entry) return TRUE if(ADMIN_CHANNEL) - client.cmd_admin_say(entry) + SSuser_verbs.invoke_verb(client, /datum/user_verb/admin_say, entry) return TRUE if(MENTOR_CHANNEL) - client.cmd_mentor_say(entry) + SSuser_verbs.invoke_verb(client, /datum/user_verb/mentor_say, entry) return TRUE if(DSAY_CHANNEL) - client.dsay(entry) + SSuser_verbs.invoke_verb(client, /datum/user_verb/dsay, entry) return TRUE if(DEV_CHANNEL) - client.cmd_dev_say(entry) + SSuser_verbs.invoke_verb(client, /datum/user_verb/dev_say, entry) return TRUE if(STAFF_CHANNEL) - client.cmd_staff_say(entry) + SSuser_verbs.invoke_verb(client, /datum/user_verb/staff_say, entry) return TRUE return FALSE diff --git a/code/modules/vote/vote_verb.dm b/code/modules/vote/vote_verb.dm index 9dbcad13634..28481195a73 100644 --- a/code/modules/vote/vote_verb.dm +++ b/code/modules/vote/vote_verb.dm @@ -7,16 +7,9 @@ else to_chat(usr, "There is no active vote") -/client/proc/start_vote() - set category = "Admin" - set name = "Start Vote" - set desc = "Start a vote on the server" - - if(!check_rights(R_ADMIN)) - return - +USER_VERB(start_vote, R_ADMIN, "Start Vote", "Start a vote on the server", VERB_CATEGORY_ADMIN) if(SSvote.active_vote) - to_chat(usr, "A vote is already in progress") + to_chat(client, "A vote is already in progress") return // Ask admins which type of vote they want to start @@ -28,7 +21,7 @@ for(var/vtype in vote_types) votemap["[vtype]"] = vtype - var/choice = tgui_input_list(usr, "Select a vote type", "Vote", vote_types) + var/choice = tgui_input_list(client, "Select a vote type", "Vote", vote_types) if(choice == null) return @@ -36,26 +29,25 @@ if(choice != "\[CUSTOM]") // Not custom, figure it out var/datum/vote/votetype = votemap["[choice]"] - SSvote.start_vote(new votetype(usr.ckey)) + SSvote.start_vote(new votetype(client.ckey)) return // Its custom, lets ask - var/question = tgui_input_text(usr, "What is the vote for?", "Create Vote", encode = FALSE) + var/question = tgui_input_text(client, "What is the vote for?", "Create Vote", encode = FALSE) if(isnull(question)) return var/list/choices = list() for(var/i in 1 to 10) - var/option = tgui_input_text(usr, "Please enter an option or hit cancel to finish", "Create Vote", encode = FALSE) - if(isnull(option) || !usr.client) + var/option = tgui_input_text(client, "Please enter an option or hit cancel to finish", "Create Vote", encode = FALSE) + if(isnull(option) || !client) break choices |= option - var/c2 = tgui_alert(usr, "Show counts while vote is happening?", "Counts", list("Yes", "No")) - var/c3 = input(usr, "Select a result calculation type", "Vote", VOTE_RESULT_TYPE_MAJORITY) as anything in list(VOTE_RESULT_TYPE_MAJORITY) + var/c2 = tgui_alert(client, "Show counts while vote is happening?", "Counts", list("Yes", "No")) + var/c3 = input(client, "Select a result calculation type", "Vote", VOTE_RESULT_TYPE_MAJORITY) as anything in list(VOTE_RESULT_TYPE_MAJORITY) - var/datum/vote/V = new /datum/vote(usr.ckey, question, choices, TRUE) + var/datum/vote/V = new /datum/vote(client.ckey, question, choices, TRUE) V.show_counts = (c2 == "Yes") V.vote_result_type = c3 SSvote.start_vote(V) - diff --git a/paradise.dme b/paradise.dme index 6dcf446dfc1..8cf3d3dd280 100644 --- a/paradise.dme +++ b/paradise.dme @@ -151,6 +151,7 @@ #include "code\__DEFINES\turfs.dm" #include "code\__DEFINES\typeids.dm" #include "code\__DEFINES\uplinks_defines.dm" +#include "code\__DEFINES\user_verb_defines.dm" #include "code\__DEFINES\vampire_defines.dm" #include "code\__DEFINES\vehicle_defines.dm" #include "code\__DEFINES\vending_defines.dm" @@ -396,6 +397,7 @@ #include "code\controllers\subsystem\non_firing\SSsounds.dm" #include "code\controllers\subsystem\non_firing\SSspatial_grid.dm" #include "code\controllers\subsystem\non_firing\SStitlescreen.dm" +#include "code\controllers\subsystem\non_firing\SSuser_verbs.dm" #include "code\controllers\subsystem\processing\SSai_behaviors.dm" #include "code\controllers\subsystem\processing\SSai_idle_behaviors.dm" #include "code\controllers\subsystem\processing\SSdcs.dm" @@ -460,6 +462,7 @@ #include "code\datums\spawners_menu.dm" #include "code\datums\station_state.dm" #include "code\datums\tgs_event_handler.dm" +#include "code\datums\user_verb.dm" #include "code\datums\verb_callbacks.dm" #include "code\datums\vv_core_topics.dm" #include "code\datums\actions\action.dm" diff --git a/tools/ci/check_user_verb_params.py b/tools/ci/check_user_verb_params.py new file mode 100644 index 00000000000..05447ad8fdc --- /dev/null +++ b/tools/ci/check_user_verb_params.py @@ -0,0 +1,147 @@ +import os +import sys +import time +from dataclasses import dataclass +from typing import Any + +from avulto import DME, Path as p, ProcDecl +from avulto.ast import NodeKind, SourceLoc + + +RED = "\033[0;31m" +GREEN = "\033[0;32m" +BLUE = "\033[0;34m" +NC = "\033[0m" # No Color + + +def make_error(source_loc: SourceLoc, msg) -> str: + if os.getenv("GITHUB_ACTIONS") == "true": + return f"::error file={source_loc.file_path},line={source_loc.line},title=User Verbs::{source_loc.file_path}:{source_loc.line}: {RED}{msg}{NC}" + else: + return f"{source_loc.file_path}:{source_loc.line}: {RED}{msg}{NC}" + + +PROCS_NEED_CLIENT = ( + "alert", + "tgui_input_list", + "tgui_input_number", + "to_chat", +) + +BAD_VARS = ( + "usr", + "src", +) + + +class Walker: + def __init__(self): + self.bad_names = [] + self.bad_inputs = [] + self.bad_calls = [] + self.bad_clean_inputs = [] + + def visit_Identifier(self, node, source_info): + if node.name in BAD_VARS: + self.bad_names.append((node, source_info)) + + def visit_Input(self, node, source_info): + if node.args[0].kind == NodeKind.CONSTANT: + self.bad_inputs.append((node, source_info)) + elif str(node.args[0]) in BAD_VARS: + self.bad_names.append((node.args[0], source_info)) + + def visit_Call(self, node, source_info): + if ( + str(node.name) in PROCS_NEED_CLIENT + and node.args[0].kind == NodeKind.CONSTANT + ): + self.bad_calls.append((node, source_info)) + + if str(node.name) == "clean_input": + last_arg = node.args[-1] + if last_arg.kind == NodeKind.ASSIGN_OP: + if str(last_arg.lhs) != "user" or str(last_arg.rhs) != "client": + self.bad_clean_inputs.append((node, source_info)) + else: + self.bad_clean_inputs.append((node, source_info)) + + for arg in node.args: + if arg.kind == NodeKind.IDENTIFIER: + self.visit_Identifier(arg, source_info) + elif arg.kind == NodeKind.CALL: + self.visit_Call(arg, source_info) + elif arg.kind == NodeKind.INTERP_STRING: + # "[key_name(usr)] blah blah" + # + # hate we have to nest this so deeply but once we have a + # visit_Node for any Node, its tree is not going to get + # visited node by node unless we so do explicitly. + for expr, _ in arg.token_pairs: + if expr.kind == NodeKind.CALL: + self.visit_Call(expr, source_info) + elif expr.kind == NodeKind.IDENTIFIER: + self.visit_Identifier(expr, source_info) + + +if __name__ == "__main__": + print("check_user_verb_params started") + + exit_code = 0 + start = time.time() + + dme = DME.from_file("paradise.dme", parse_procs=True) + errors = [] + + for pth in dme.subtypesof("/datum/user_verb"): + walker = Walker() + td = dme.types[pth] + proc = td.proc_decls("__avd_do_verb")[0] + proc.walk(walker) + + if walker.bad_names: + exit_code = 1 + for name, source_loc in walker.bad_names: + errors.append( + make_error( + source_loc, + f"user verb {td.path} uses `{name}` instead of implicit client/client arg", + ) + ) + + if walker.bad_inputs: + exit_code = 1 + for node, source_loc in walker.bad_inputs: + errors.append( + make_error( + source_loc, + f"input() call in {td.path} missing explicit recipient", + ) + ) + + if walker.bad_calls: + exit_code = 1 + for node, source_loc in walker.bad_calls: + errors.append( + make_error( + source_loc, + f"call {node.name}() in {td.path} missing explicit recipient", + ) + ) + + if walker.bad_clean_inputs: + exit_code = 1 + for node, source_loc in walker.bad_clean_inputs: + errors.append( + make_error( + source_loc, + f"call {node.name}() in {td.path} must have `user = client` as its last arg", + ) + ) + + for error in sorted(errors): + print(error) + + end = time.time() + print(f"check_user_verb_params tests completed in {end - start:.2f}s\n") + sys.exit(exit_code)
    SlotActions