mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-16 17:44:25 +01:00
Ports ticket system overhaul from downstream (#17063)
* Ports ticket system overhaul from downstream * Various fixes * fixes * Update tickets.dm * Update tickets.dm * Update ticket.dm * Refactor --------- Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
@@ -81,6 +81,8 @@ GLOBAL_PROTECT(protected_ranks)
|
||||
flag = R_MOD
|
||||
if("EVENT")
|
||||
flag = R_EVENT
|
||||
if("MENTOR")
|
||||
flag = R_MENTOR
|
||||
if("@")
|
||||
if(previous_rank)
|
||||
switch(group_count)
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
// Reports are a way to notify admins of wrongdoings that happened
|
||||
// while no admin was present. They work a bit similar to news, but
|
||||
// they can only be read by admins and moderators.
|
||||
|
||||
// a single admin report
|
||||
/datum//admin_report/var
|
||||
ID // the ID of the report
|
||||
body // the content of the report
|
||||
author // key of the author
|
||||
date // date on which this was created
|
||||
done // whether this was handled
|
||||
|
||||
offender_key // store the key of the offender
|
||||
offender_cid // store the cid of the offender
|
||||
|
||||
/datum//report_topic_handler
|
||||
Topic(href,href_list)
|
||||
..()
|
||||
var/client/C = locate(href_list["client"])
|
||||
if(href_list["action"] == "show_reports")
|
||||
C.display_admin_reports()
|
||||
else if(href_list["action"] == "remove")
|
||||
C.mark_report_done(text2num(href_list["ID"]))
|
||||
else if(href_list["action"] == "edit")
|
||||
C.edit_report(text2num(href_list["ID"]))
|
||||
|
||||
var/datum/report_topic_handler/report_topic_handler
|
||||
|
||||
world/New()
|
||||
..()
|
||||
report_topic_handler = new
|
||||
|
||||
// add a new news datums
|
||||
/proc/make_report(body, author, okey, cid)
|
||||
var/savefile/Reports = new("data/reports.sav")
|
||||
var/list/reports
|
||||
var/lastID
|
||||
|
||||
Reports["reports"] >> reports
|
||||
Reports["lastID"] >> lastID
|
||||
|
||||
if(!reports) reports = list()
|
||||
if(!lastID) lastID = 0
|
||||
|
||||
var/datum/admin_report/created = new()
|
||||
created.ID = ++lastID
|
||||
created.body = body
|
||||
created.author = author
|
||||
created.date = world.realtime
|
||||
created.done = 0
|
||||
created.offender_key = okey
|
||||
created.offender_cid = cid
|
||||
|
||||
reports.Insert(1, created)
|
||||
|
||||
Reports["reports"] << reports
|
||||
Reports["lastID"] << lastID
|
||||
|
||||
// load the reports from disk
|
||||
/proc/load_reports()
|
||||
var/savefile/Reports = new("data/reports.sav")
|
||||
var/list/reports
|
||||
|
||||
Reports["reports"] >> reports
|
||||
|
||||
if(!reports) reports = list()
|
||||
|
||||
return reports
|
||||
|
||||
// check if there are any unhandled reports
|
||||
/client/proc/unhandled_reports()
|
||||
if(!src.holder) return 0
|
||||
var/list/reports = load_reports()
|
||||
|
||||
for(var/datum/admin_report/N in reports)
|
||||
if(N.done)
|
||||
continue
|
||||
else return 1
|
||||
|
||||
return 0
|
||||
|
||||
// checks if the player has an unhandled report against him
|
||||
/client/proc/is_reported()
|
||||
var/list/reports = load_reports()
|
||||
|
||||
for(var/datum/admin_report/N in reports) if(!N.done)
|
||||
if(N.offender_key == src.key)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
// display only the reports that haven't been handled
|
||||
/client/proc/display_admin_reports()
|
||||
set category = "Admin.Moderation"
|
||||
set name = "Display Admin Reports"
|
||||
if(!src.holder) return
|
||||
|
||||
var/list/reports = load_reports()
|
||||
|
||||
var/output = ""
|
||||
if(unhandled_reports())
|
||||
// load the list of unhandled reports
|
||||
for(var/datum/admin_report/N in reports)
|
||||
if(N.done)
|
||||
continue
|
||||
output += span_bold("Reported player:") + " [N.offender_key](CID: [N.offender_cid])<br>"
|
||||
output += span_bold("Offense:") + "[N.body]<br>"
|
||||
output += "<small>Occurred at [time2text(N.date,"MM/DD hh:mm:ss")]</small><br>"
|
||||
output += "<small>authored by <i>[N.author]</i></small><br>"
|
||||
output += " <a href='byond://?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=remove;ID=[N.ID]'>Flag as Handled</a>"
|
||||
if(src.key == N.author)
|
||||
output += " <a href='byond://?src=\ref[report_topic_handler];client=\ref[src];[HrefToken()];action=edit;ID=[N.ID]'>Edit</a>"
|
||||
output += "<br>"
|
||||
output += "<br>"
|
||||
else
|
||||
output += "Whoops, no reports!"
|
||||
|
||||
var/datum/browser/popup = new(src, "news", "News", 600, 400)
|
||||
popup.set_content(output)
|
||||
popup.open()
|
||||
|
||||
/client/proc/Report(mob/M as mob in world)
|
||||
set category = "Admin.Moderation"
|
||||
if(!src.holder)
|
||||
return
|
||||
|
||||
var/CID = "Unknown"
|
||||
if(M.client)
|
||||
CID = M.client.computer_id
|
||||
|
||||
var/body = tgui_input_text(src.mob, "Describe in detail what you're reporting [M] for", "Report")
|
||||
if(!body) return
|
||||
|
||||
|
||||
make_report(body, key, M.key, CID)
|
||||
|
||||
spawn(1)
|
||||
display_admin_reports()
|
||||
|
||||
/client/proc/mark_report_done(ID as num)
|
||||
if(!src.holder || src.holder.level < 0)
|
||||
return
|
||||
|
||||
var/savefile/Reports = new("data/reports.sav")
|
||||
var/list/reports
|
||||
|
||||
Reports["reports"] >> reports
|
||||
|
||||
var/datum/admin_report/found
|
||||
for(var/datum/admin_report/N in reports)
|
||||
if(N.ID == ID)
|
||||
found = N
|
||||
if(!found)
|
||||
to_chat(src, span_boldwarning("* An error occurred, sorry."))
|
||||
|
||||
found.done = 1
|
||||
|
||||
Reports["reports"] << reports
|
||||
|
||||
|
||||
/client/proc/edit_report(ID as num)
|
||||
if(!src.holder || src.holder.level < 0)
|
||||
to_chat(src, span_boldwarning("You tried to modify the news, but you're not an admin!"))
|
||||
return
|
||||
|
||||
var/savefile/Reports = new("data/reports.sav")
|
||||
var/list/reports
|
||||
|
||||
Reports["reports"] >> reports
|
||||
|
||||
var/datum/admin_report/found
|
||||
for(var/datum/admin_report/N in reports)
|
||||
if(N.ID == ID)
|
||||
found = N
|
||||
if(!found)
|
||||
to_chat(src, span_boldwarning("* An error occurred, sorry."))
|
||||
|
||||
var/body = tgui_input_text(src.mob, "Enter a body for the news", "Body", multiline = TRUE, prevent_enter = TRUE)
|
||||
if(!body) return
|
||||
|
||||
found.body = body
|
||||
|
||||
Reports["reports"] << reports
|
||||
@@ -1,25 +1,4 @@
|
||||
//admin verb groups - They can overlap if you so wish. Only one of each verb will exist in the verbs list regardless
|
||||
var/list/admin_verbs_default = list(
|
||||
// /datum/admins/proc/show_player_panel, //shows an interface for individual players, with various links (links require additional flags, //VOREStation Remove,
|
||||
// /client/proc/player_panel_new, //shows an interface for all players, with links to various panels, //VOREStation Remove,
|
||||
// /client/proc/player_panel, //VOREStation Remove,
|
||||
/client/proc/cmd_admin_say, //VOREStation Add,
|
||||
/client/proc/cmd_mod_say, //VOREStation Add,
|
||||
/client/proc/cmd_event_say, //VOREStation Add,
|
||||
/client/proc/cmd_mentor_ticket_panel,
|
||||
/client/proc/cmd_mentor_say,
|
||||
// /client/proc/hide_verbs, //hides all our adminverbs, //VOREStation Remove,
|
||||
// /client/proc/hide_most_verbs, //hides all our hideable adminverbs, //VOREStation Remove,
|
||||
// /client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Remove,
|
||||
// /client/proc/mark_datum_mapview, //VOREStation Remove,
|
||||
// /client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Remove,
|
||||
// /client/proc/check_antagonists, //shows all antags,
|
||||
// /client/proc/cmd_mod_say,
|
||||
// /client/proc/deadchat //toggles deadchat on/off,
|
||||
// /client/proc/toggle_ahelp_sound,
|
||||
/client/proc/debugstatpanel,
|
||||
)
|
||||
|
||||
var/list/admin_verbs_admin = list(
|
||||
/client/proc/toggle_vantag_hud,
|
||||
/datum/admins/proc/set_tcrystals,
|
||||
@@ -83,9 +62,6 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/toggleoocdead, //toggles ooc on/off for everyone who is dead,
|
||||
/datum/admins/proc/togglehubvisibility, //toggles visibility on the BYOND Hub.,
|
||||
/datum/admins/proc/toggledsay, //toggles dsay on/off for everyone,
|
||||
/client/proc/cmd_admin_say, //admin-only ooc chat,
|
||||
/client/proc/cmd_mod_say,
|
||||
/client/proc/cmd_event_say,
|
||||
/datum/admins/proc/PlayerNotes,
|
||||
/datum/admins/proc/show_player_info,
|
||||
/client/proc/free_slot, //frees slot for chosen job,
|
||||
@@ -117,8 +93,6 @@ var/list/admin_verbs_admin = list(
|
||||
/datum/admins/proc/sendFax,
|
||||
/client/proc/despawn_player,
|
||||
/datum/admins/proc/view_feedback,
|
||||
/client/proc/make_mentor,
|
||||
/client/proc/unmake_mentor,
|
||||
/client/proc/delbook,
|
||||
/client/proc/toggle_spawning_with_recolour,
|
||||
/client/proc/start_vote,
|
||||
@@ -199,7 +173,6 @@ var/list/admin_verbs_server = list(
|
||||
/datum/admins/proc/delay,
|
||||
/datum/admins/proc/toggleaban,
|
||||
/datum/admins/proc/togglepersistence,
|
||||
/client/proc/cmd_mod_say,
|
||||
/client/proc/toggle_log_hrefs,
|
||||
/datum/admins/proc/immreboot,
|
||||
/client/proc/everyone_random,
|
||||
@@ -290,9 +263,6 @@ var/list/admin_verbs_possess = list(
|
||||
/proc/possess,
|
||||
/proc/release
|
||||
)
|
||||
var/list/admin_verbs_permissions = list(
|
||||
/client/proc/edit_admin_permissions
|
||||
)
|
||||
var/list/admin_verbs_rejuv = list(
|
||||
/client/proc/respawn_character
|
||||
)
|
||||
@@ -387,8 +357,6 @@ var/list/admin_verbs_mod = list(
|
||||
/client/proc/debug_variables, //allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify, //VOREStation Add,
|
||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||
/client/proc/cmd_mod_say,
|
||||
/client/proc/cmd_event_say,
|
||||
/datum/admins/proc/show_player_info,
|
||||
/datum/admins/proc/show_traitor_panel,
|
||||
/client/proc/player_panel_new,
|
||||
@@ -409,7 +377,6 @@ var/list/admin_verbs_mod = list(
|
||||
|
||||
var/list/admin_verbs_event_manager = list(
|
||||
/client/proc/toggle_vantag_hud,
|
||||
/client/proc/cmd_event_say,
|
||||
/client/proc/cmd_admin_pm_context,
|
||||
/client/proc/cmd_admin_pm_panel,
|
||||
/client/proc/admin_ghost,
|
||||
@@ -515,8 +482,6 @@ var/list/admin_verbs_event_manager = list(
|
||||
/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/secrets,
|
||||
/client/proc/cmd_mod_say,
|
||||
/client/proc/cmd_event_say,
|
||||
/datum/admins/proc/show_player_info,
|
||||
/client/proc/free_slot, //frees slot for chosen job,
|
||||
/client/proc/cmd_admin_change_custom_event,
|
||||
@@ -543,7 +508,6 @@ var/list/admin_verbs_event_manager = list(
|
||||
/datum/admins/proc/startnow,
|
||||
/datum/admins/proc/restart,
|
||||
/datum/admins/proc/delay,
|
||||
/client/proc/cmd_mod_say,
|
||||
/datum/admins/proc/immreboot,
|
||||
/client/proc/everyone_random,
|
||||
/client/proc/cmd_admin_delete, //delete an instance/object/mob/etc,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/client/proc/add_admin_verbs()
|
||||
// OLD ADMIN VERB SYSTEM
|
||||
if(holder)
|
||||
var/rights = holder.rank_flags()
|
||||
add_verb(src, admin_verbs_default)
|
||||
var/rights = holder.rank_flags()
|
||||
if(rights & R_HOLDER)
|
||||
if(rights & R_BUILDMODE) add_verb(src, /client/proc/togglebuildmodeself)
|
||||
if(rights & R_ADMIN) add_verb(src, admin_verbs_admin)
|
||||
if(rights & R_FUN) add_verb(src, admin_verbs_fun)
|
||||
@@ -12,7 +11,6 @@
|
||||
if(CONFIG_GET(flag/debugparanoid) && !(rights & R_ADMIN))
|
||||
remove_verb(src, admin_verbs_paranoid_debug) //Right now it's just callproc but we can easily add others later on.
|
||||
if(rights & R_POSSESS) add_verb(src, admin_verbs_possess)
|
||||
if(rights & R_PERMISSIONS) add_verb(src, admin_verbs_permissions)
|
||||
if(rights & R_STEALTH) add_verb(src, /client/proc/stealth)
|
||||
if(rights & R_REJUVINATE) add_verb(src, admin_verbs_rejuv)
|
||||
if(rights & R_SOUNDS) add_verb(src, admin_verbs_sounds)
|
||||
@@ -26,14 +24,12 @@
|
||||
/client/proc/remove_admin_verbs()
|
||||
// OLD ADMIN VERB SYSTEM
|
||||
remove_verb(src, list(
|
||||
admin_verbs_default,
|
||||
/client/proc/togglebuildmodeself,
|
||||
admin_verbs_admin,
|
||||
admin_verbs_fun,
|
||||
admin_verbs_server,
|
||||
admin_verbs_debug,
|
||||
admin_verbs_possess,
|
||||
admin_verbs_permissions,
|
||||
/client/proc/stealth,
|
||||
admin_verbs_rejuv,
|
||||
admin_verbs_sounds,
|
||||
@@ -130,7 +126,7 @@
|
||||
set category = "Admin.Game"
|
||||
set desc = "Toggles ghost-like invisibility (Don't abuse this)"
|
||||
|
||||
if(holder && mob)
|
||||
if(check_rights(R_HOLDER) && mob)
|
||||
if(mob.invisibility > INVISIBILITY_OBSERVER)
|
||||
to_chat(mob, span_warning("You can't use this, your current invisibility level ([mob.invisibility]) is above the observer level ([INVISIBILITY_OBSERVER])."))
|
||||
return
|
||||
@@ -149,7 +145,7 @@
|
||||
/client/proc/player_panel()
|
||||
set name = "Player Panel"
|
||||
set category = "Admin.Game"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
holder.player_panel_old()
|
||||
feedback_add_details("admin_verb","PP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -157,7 +153,7 @@
|
||||
/client/proc/player_panel_new()
|
||||
set name = "Player Panel New"
|
||||
set category = "Admin.Game"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
holder.player_panel_new()
|
||||
feedback_add_details("admin_verb","PPN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -165,7 +161,7 @@
|
||||
/client/proc/check_antagonists()
|
||||
set name = "Check Antagonists"
|
||||
set category = "Admin.Investigate"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
holder.check_antagonists()
|
||||
log_admin("[key_name(usr)] checked antagonists.") //for tsar~
|
||||
feedback_add_details("admin_verb","CHA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -192,7 +188,7 @@ ADMIN_VERB(game_panel, R_ADMIN|R_SERVER|R_FUN, "Game Panel", "Look at the state
|
||||
/client/proc/secrets()
|
||||
set name = "Secrets"
|
||||
set category = "Admin.Secrets"
|
||||
if (holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
holder.Secrets()
|
||||
feedback_add_details("admin_verb","S") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -219,7 +215,7 @@ ADMIN_VERB(game_panel, R_ADMIN|R_SERVER|R_FUN, "Game Panel", "Look at the state
|
||||
/client/proc/stealth()
|
||||
set category = "Admin.Game"
|
||||
set name = "Stealth Mode"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
if(holder.fakekey)
|
||||
holder.fakekey = null
|
||||
if(isnewplayer(src.mob))
|
||||
@@ -396,7 +392,7 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
/client/proc/check_ai_laws()
|
||||
set name = "Check AI Laws"
|
||||
set category = "Admin.Silicon"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
src.holder.output_ai_laws()
|
||||
|
||||
/client/proc/rename_silicon()
|
||||
@@ -458,7 +454,7 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
/client/proc/mod_panel()
|
||||
set name = "Moderator Panel"
|
||||
set category = "Admin.Moderation"
|
||||
/* if(holder)
|
||||
/* if(check_rights(R_HOLDER))
|
||||
holder.mod_panel()*/
|
||||
// feedback_add_details("admin_verb","MP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
@@ -466,14 +462,14 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
/client/proc/playernotes()
|
||||
set name = "Show Player Info"
|
||||
set category = "Admin.Moderation"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
holder.PlayerNotes()
|
||||
return
|
||||
|
||||
/client/proc/free_slot()
|
||||
set name = "Free Job Slot"
|
||||
set category = "Admin.Game"
|
||||
if(holder)
|
||||
if(check_rights(R_HOLDER))
|
||||
var/list/jobs = list()
|
||||
for (var/datum/job/J in job_master.occupations)
|
||||
if (J.current_positions >= J.total_positions && J.total_positions != -1)
|
||||
@@ -542,11 +538,8 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
|
||||
message_admins(span_blue("[key_name_admin(usr)] gave [key_name(T)] the spell [S]."), 1)
|
||||
|
||||
/client/proc/debugstatpanel()
|
||||
set name = "Debug Stat Panel"
|
||||
set category = "Debug.Misc"
|
||||
|
||||
src.stat_panel.send_message("create_debug")
|
||||
ADMIN_VERB(debugstatpanel, R_DEBUG, "Debug Stat Panel", "Allows to debug the statpanel", "Debug.Misc")
|
||||
user.stat_panel.send_message("create_debug")
|
||||
|
||||
/client/proc/spawn_reagent()
|
||||
set name = "Spawn Reagent"
|
||||
@@ -618,7 +611,7 @@ ADMIN_VERB(deadmin, R_NONE, "DeAdmin", "Shed your admin powers.", ADMIN_CATEGORY
|
||||
var/atom/movable/orbiter
|
||||
var/input
|
||||
|
||||
if(holder.marked_datum)
|
||||
if(check_rights(R_HOLDER) && holder.marked_datum)
|
||||
input = tgui_alert(usr, "You have \n[holder.marked_datum] marked, should this be the center of the orbit, or the orbiter?", "Orbit", list("Center", "Orbiter", "Neither"))
|
||||
switch(input)
|
||||
if("Center")
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
/client/proc/edit_admin_permissions()
|
||||
set category = "Admin.Secrets"
|
||||
set name = "Permissions Panel"
|
||||
set desc = "Edit admin permissions"
|
||||
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
return
|
||||
|
||||
usr.client.holder.edit_admin_permissions()
|
||||
ADMIN_VERB(edit_admin_permissions, R_PERMISSIONS, "Permissions Panel", "Edit admin permissions.", "Admin.Secrets")
|
||||
user.holder.edit_admin_permissions()
|
||||
|
||||
/datum/admins/proc/edit_admin_permissions(action, target, operation, page)
|
||||
if(!check_rights(R_PERMISSIONS))
|
||||
|
||||
+16
-16
@@ -29,21 +29,21 @@
|
||||
check_antagonists()
|
||||
return
|
||||
|
||||
if(href_list["ahelp"])
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT))
|
||||
if(href_list["ticket"])
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT|R_MENTOR))
|
||||
return
|
||||
|
||||
var/ahelp_ref = href_list["ahelp"]
|
||||
var/datum/admin_help/AH = locate(ahelp_ref)
|
||||
if(AH)
|
||||
AH.Action(href_list["ahelp_action"])
|
||||
var/ticket_ref = href_list["ticket"]
|
||||
var/datum/ticket/T = locate(ticket_ref)
|
||||
if(T)
|
||||
T.Action(href_list["ticket_action"])
|
||||
else
|
||||
to_chat(usr, "Ticket [ahelp_ref] has been deleted!")
|
||||
to_chat(usr, "Ticket [ticket_ref] has been deleted!")
|
||||
|
||||
else if(href_list["ahelp_tickets"])
|
||||
GLOB.ahelp_tickets.BrowseTickets(text2num(href_list["ahelp_tickets"]))
|
||||
else if(href_list["tickets"])
|
||||
GLOB.tickets.BrowseTickets(text2num(href_list["tickets"]))
|
||||
|
||||
mentor_commands(href, href_list, src)
|
||||
// mentor_commands(href, href_list, src) - Skip because client is already admin & contents handled above
|
||||
|
||||
if(href_list["dbsearchckey"] || href_list["dbsearchadmin"])
|
||||
|
||||
@@ -865,9 +865,9 @@
|
||||
to_chat(M, span_filter_system(span_warning("No ban appeals URL has been set.")))
|
||||
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
|
||||
message_admins(span_blue("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes."))
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
var/datum/ticket/T = M.client ? M.client.current_ticket : null
|
||||
if(T)
|
||||
T.Resolve()
|
||||
qdel(M.client)
|
||||
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
|
||||
if("No")
|
||||
@@ -893,9 +893,9 @@
|
||||
message_admins(span_blue("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban."))
|
||||
feedback_inc("ban_perma",1)
|
||||
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
var/datum/ticket/T = M.client ? M.client.current_ticket : null
|
||||
if(T)
|
||||
T.Resolve()
|
||||
qdel(M.client)
|
||||
//qdel(M)
|
||||
if("Cancel")
|
||||
|
||||
@@ -1,796 +0,0 @@
|
||||
/client/var/datum/admin_help/current_ticket //the current ticket the (usually) not-admin client is dealing with
|
||||
|
||||
//
|
||||
//TICKET MANAGER
|
||||
//
|
||||
|
||||
GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
|
||||
/datum/admin_help_tickets
|
||||
var/list/active_tickets = list()
|
||||
var/list/closed_tickets = list()
|
||||
var/list/resolved_tickets = list()
|
||||
|
||||
var/obj/effect/statclick/ticket_list/astatclick = new(null, null, AHELP_ACTIVE)
|
||||
var/obj/effect/statclick/ticket_list/cstatclick = new(null, null, AHELP_CLOSED)
|
||||
var/obj/effect/statclick/ticket_list/rstatclick = new(null, null, AHELP_RESOLVED)
|
||||
|
||||
/datum/admin_help_tickets/Destroy()
|
||||
QDEL_LIST(active_tickets)
|
||||
QDEL_LIST(closed_tickets)
|
||||
QDEL_LIST(resolved_tickets)
|
||||
QDEL_NULL(astatclick)
|
||||
QDEL_NULL(cstatclick)
|
||||
QDEL_NULL(rstatclick)
|
||||
return ..()
|
||||
|
||||
//private
|
||||
/datum/admin_help_tickets/proc/ListInsert(datum/admin_help/new_ticket)
|
||||
var/list/ticket_list
|
||||
switch(new_ticket.state)
|
||||
if(AHELP_ACTIVE)
|
||||
ticket_list = active_tickets
|
||||
if(AHELP_CLOSED)
|
||||
ticket_list = closed_tickets
|
||||
if(AHELP_RESOLVED)
|
||||
ticket_list = resolved_tickets
|
||||
else
|
||||
CRASH("Invalid ticket state: [new_ticket.state]")
|
||||
var/num_closed = ticket_list.len
|
||||
if(num_closed)
|
||||
for(var/I in 1 to num_closed)
|
||||
var/datum/admin_help/AH = ticket_list[I]
|
||||
if(AH.id > new_ticket.id)
|
||||
ticket_list.Insert(I, new_ticket)
|
||||
return
|
||||
ticket_list += new_ticket
|
||||
|
||||
//opens the ticket listings for one of the 3 states
|
||||
/datum/admin_help_tickets/proc/BrowseTickets(state)
|
||||
if(!check_rights(R_ADMIN|R_SERVER)) //Prevents non-staff from opening the list of ahelp tickets
|
||||
return
|
||||
var/list/l2b
|
||||
var/title
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
l2b = active_tickets
|
||||
title = "Active Tickets"
|
||||
if(AHELP_CLOSED)
|
||||
l2b = closed_tickets
|
||||
title = "Closed Tickets"
|
||||
if(AHELP_RESOLVED)
|
||||
l2b = resolved_tickets
|
||||
title = "Resolved Tickets"
|
||||
if(!l2b)
|
||||
return
|
||||
var/list/dat = list("<html><head><title>[title]</title></head>")
|
||||
dat += "<A href='byond://?_src_=holder;[HrefToken()];ahelp_tickets=[state]'>Refresh</A><br><br>"
|
||||
for(var/datum/admin_help/AH as anything in l2b)
|
||||
dat += span_adminnotice(span_adminhelp("Ticket #[AH.id]") + ": <A href='byond://?_src_=holder;ahelp=\ref[AH];[HrefToken()];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A>") + "<br>"
|
||||
dat += "</html>"
|
||||
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/admin_help_tickets/proc/stat_entry()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SHOULD_NOT_SLEEP(TRUE)
|
||||
var/list/L = list()
|
||||
var/num_disconnected = 0
|
||||
L[++L.len] = list("== Admin Tickets ==", "", null, null)
|
||||
L[++L.len] = list("Active Tickets:", "[astatclick.update("[active_tickets.len]")]", null, REF(astatclick))
|
||||
astatclick.update("[active_tickets.len]")
|
||||
for(var/datum/admin_help/AH as anything in active_tickets)
|
||||
if(AH.initiator)
|
||||
L[++L.len] = list("#[AH.id]. [AH.initiator_key_name]:", "[AH.statclick.update()]", REF(AH))
|
||||
else
|
||||
++num_disconnected
|
||||
if(num_disconnected)
|
||||
L[++L.len] = list("Disconnected:", "[astatclick.update("[num_disconnected]")]", null, REF(astatclick))
|
||||
L[++L.len] = list("Closed Tickets:", "[cstatclick.update("[closed_tickets.len]")]", null, REF(cstatclick))
|
||||
L[++L.len] = list("Resolved Tickets:", "[rstatclick.update("[resolved_tickets.len]")]", null, REF(rstatclick))
|
||||
return L
|
||||
|
||||
//Reassociate still open ticket if one exists
|
||||
/datum/admin_help_tickets/proc/ClientLogin(client/C)
|
||||
C.current_ticket = CKey2ActiveTicket(C.ckey)
|
||||
if(C.current_ticket)
|
||||
C.current_ticket.AddInteraction("Client reconnected.")
|
||||
C.current_ticket.initiator = C
|
||||
|
||||
//Dissasociate ticket
|
||||
/datum/admin_help_tickets/proc/ClientLogout(client/C)
|
||||
if(C.current_ticket)
|
||||
C.current_ticket.AddInteraction("Client disconnected.")
|
||||
C.current_ticket.initiator = null
|
||||
C.current_ticket = null
|
||||
|
||||
//Get a ticket given a ckey
|
||||
/datum/admin_help_tickets/proc/CKey2ActiveTicket(ckey)
|
||||
for(var/datum/admin_help/AH as anything in active_tickets)
|
||||
if(AH.initiator_ckey == ckey)
|
||||
return AH
|
||||
|
||||
//
|
||||
//TICKET LIST STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ticket_list
|
||||
var/current_state
|
||||
|
||||
/obj/effect/statclick/ticket_list/Initialize(mapload, text, target)
|
||||
. = ..()
|
||||
current_state = target
|
||||
|
||||
/obj/effect/statclick/ticket_list/Click()
|
||||
GLOB.ahelp_tickets.BrowseTickets(current_state)
|
||||
|
||||
//called by admin topic
|
||||
/obj/effect/statclick/ticket_list/proc/Action()
|
||||
Click()
|
||||
//
|
||||
//TICKET DATUM
|
||||
//
|
||||
|
||||
/datum/admin_help
|
||||
var/id
|
||||
var/name
|
||||
var/state = AHELP_ACTIVE
|
||||
|
||||
var/opened_at
|
||||
var/closed_at
|
||||
|
||||
var/client/initiator //semi-misnomer, it's the person who ahelped/was bwoinked
|
||||
var/initiator_ckey
|
||||
var/initiator_key_name
|
||||
|
||||
var/list/_interactions //use AddInteraction() or, preferably, admin_ticket_log()
|
||||
|
||||
var/obj/effect/statclick/ahelp/statclick
|
||||
|
||||
var/static/ticket_counter = 0
|
||||
|
||||
//call this on its own to create a ticket, don't manually assign current_ticket
|
||||
//msg is the title of the ticket: usually the ahelp text
|
||||
//is_bwoink is TRUE if this ticket was started by an admin PM
|
||||
/datum/admin_help/New(msg, client/C, is_bwoink)
|
||||
//clean the input msg
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg || !C || !C.mob)
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
id = ++ticket_counter
|
||||
opened_at = world.time
|
||||
|
||||
name = msg
|
||||
|
||||
initiator = C
|
||||
initiator_ckey = initiator.ckey
|
||||
initiator_key_name = key_name(initiator, FALSE, TRUE)
|
||||
if(initiator.current_ticket) //This is a bug
|
||||
log_debug("Multiple ahelp current_tickets")
|
||||
initiator.current_ticket.AddInteraction("Ticket erroneously left open by code")
|
||||
initiator.current_ticket.Close()
|
||||
initiator.current_ticket = src
|
||||
|
||||
var/parsed_message = keywords_lookup(msg)
|
||||
|
||||
statclick = new(null, src)
|
||||
_interactions = list()
|
||||
|
||||
if(is_bwoink)
|
||||
AddInteraction(span_blue("[key_name_admin(usr)] PM'd [LinkedReplyName()]"))
|
||||
message_admins(span_blue("Ticket [TicketHref("#[id]")] created"))
|
||||
else
|
||||
MessageNoRecipient(parsed_message)
|
||||
send2adminchat() //VOREStation Add
|
||||
//show it to the person adminhelping too
|
||||
to_chat(C, span_admin_pm_notice("PM to-" + span_bold("Admins") + ": [name]"))
|
||||
|
||||
//send it to irc if nobody is on and tell us how many were on
|
||||
var/admin_number_present = send2irc_adminless_only(initiator_ckey, name)
|
||||
log_admin("Ticket #[id]: [key_name(initiator)]: [name] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
if(admin_number_present <= 0)
|
||||
to_chat(C, span_admin_pm_notice("No active admins are online, your adminhelp was sent to the admin discord.")) //VOREStation Edit
|
||||
|
||||
// Also send it to discord since that's the hip cool thing now.
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) ticket opened.",
|
||||
"body" = "[key_name(initiator)] has opened a ticket. \n[msg]",
|
||||
"color" = COLOR_WEBHOOK_POOR
|
||||
)
|
||||
)
|
||||
|
||||
GLOB.ahelp_tickets.active_tickets += src
|
||||
|
||||
/datum/admin_help/Destroy()
|
||||
RemoveActive()
|
||||
GLOB.ahelp_tickets.closed_tickets -= src
|
||||
GLOB.ahelp_tickets.resolved_tickets -= src
|
||||
return ..()
|
||||
|
||||
/datum/admin_help/proc/AddInteraction(formatted_message)
|
||||
_interactions += "[gameTimestamp()]: [formatted_message]"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/FullMonty(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
if(initiator && initiator.mob)
|
||||
. = ADMIN_FULLMONTY_NONAME(initiator.mob)
|
||||
else
|
||||
. = "Initiator disconnected."
|
||||
if(state == AHELP_ACTIVE)
|
||||
. += ClosureLinks(ref_src)
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/ClosureLinks(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = " (<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken(TRUE)];ahelp_action=reject'>REJT</A>)"
|
||||
. += " (<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken(TRUE)];ahelp_action=icissue'>IC</A>)"
|
||||
. += " (<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken(TRUE)];ahelp_action=close'>CLOSE</A>)"
|
||||
. += " (<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken(TRUE)];ahelp_action=resolve'>RSLVE</A>)"
|
||||
. += " (<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken(TRUE)];ahelp_action=handleissue'>HANDLE</A>)"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/LinkedReplyName(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken()];ahelp_action=reply'>[initiator_key_name]</A>"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/TicketHref(msg, ref_src, action = "ticket")
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A href='byond://?_src_=holder;ahelp=[ref_src];[HrefToken()];ahelp_action=[action]'>[msg]</A>"
|
||||
|
||||
//message from the initiator without a target, all admins will see this
|
||||
//won't bug irc
|
||||
/datum/admin_help/proc/MessageNoRecipient(msg)
|
||||
var/ref_src = "\ref[src]"
|
||||
var/chat_msg = span_admin_pm_notice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]") + span_bold(": [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:") + msg)
|
||||
|
||||
AddInteraction(span_red("[LinkedReplyName(ref_src)]: [msg]"))
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(!check_rights_for(X, R_ADMIN))
|
||||
continue
|
||||
if(X.prefs?.read_preference(/datum/preference/toggle/holder/play_adminhelp_ping))
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
window_flash(X)
|
||||
to_chat(X, chat_msg)
|
||||
|
||||
//Reopen a closed ticket
|
||||
/datum/admin_help/proc/Reopen()
|
||||
if(state == AHELP_ACTIVE)
|
||||
to_chat(usr, span_warning("This ticket is already open."))
|
||||
return
|
||||
|
||||
if(GLOB.ahelp_tickets.CKey2ActiveTicket(initiator_ckey))
|
||||
to_chat(usr, span_warning("This user already has an active ticket, cannot reopen this one."))
|
||||
return
|
||||
|
||||
statclick = new(null, src)
|
||||
GLOB.ahelp_tickets.active_tickets += src
|
||||
GLOB.ahelp_tickets.closed_tickets -= src
|
||||
GLOB.ahelp_tickets.resolved_tickets -= src
|
||||
switch(state)
|
||||
if(AHELP_CLOSED)
|
||||
feedback_dec("ahelp_close")
|
||||
if(AHELP_RESOLVED)
|
||||
feedback_dec("ahelp_resolve")
|
||||
state = AHELP_ACTIVE
|
||||
closed_at = null
|
||||
if(initiator)
|
||||
initiator.current_ticket = src
|
||||
|
||||
AddInteraction(span_purple("Reopened by [key_name_admin(usr)]"))
|
||||
if(initiator)
|
||||
to_chat(initiator, span_filter_adminlog("[span_purple("Ticket [TicketHref("#[id]")] was reopened by [key_name(usr,FALSE,FALSE)].")]"))
|
||||
var/msg = span_adminhelp("Ticket [TicketHref("#[id]")] reopened by [key_name_admin(usr)].")
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
feedback_inc("ahelp_reopen")
|
||||
TicketPanel() //can only be done from here, so refresh it
|
||||
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) reopened.",
|
||||
"body" = "Reopened by [key_name(usr)]."
|
||||
)
|
||||
)
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/RemoveActive()
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
closed_at = world.time
|
||||
QDEL_NULL(statclick)
|
||||
GLOB.ahelp_tickets.active_tickets -= src
|
||||
if(initiator && initiator.current_ticket == src)
|
||||
initiator.current_ticket = null
|
||||
|
||||
//Mark open ticket as closed/meme
|
||||
/datum/admin_help/proc/Close(silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_CLOSED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
AddInteraction(span_filter_adminlog(span_red("Closed by [key_name_admin(usr)].")))
|
||||
if(initiator)
|
||||
to_chat(initiator, span_filter_adminlog("[span_red("Ticket [TicketHref("#[id]")] was closed by [key_name(usr,FALSE,FALSE)].")]"))
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_close")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] closed by [key_name_admin(usr)]."
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) closed.",
|
||||
"body" = "Closed by [key_name(usr)].",
|
||||
"color" = COLOR_WEBHOOK_BAD
|
||||
)
|
||||
)
|
||||
|
||||
//Mark open ticket as resolved/legitimate, returns ahelp verb
|
||||
/datum/admin_help/proc/Resolve(silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_RESOLVED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
|
||||
AddInteraction(span_filter_adminlog(span_green("Resolved by [key_name_admin(usr)].")))
|
||||
if(initiator)
|
||||
to_chat(initiator, span_filter_adminlog("[span_green("Ticket [TicketHref("#[id]")] was marked resolved by [key_name(usr,FALSE,FALSE)].")]"))
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_resolve")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] resolved by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) resolved.",
|
||||
"body" = "Marked as Resolved by [key_name(usr)].",
|
||||
"color" = COLOR_WEBHOOK_GOOD
|
||||
)
|
||||
)
|
||||
|
||||
//Close and return ahelp verb, use if ticket is incoherent
|
||||
/datum/admin_help/proc/Reject(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
if(initiator)
|
||||
if(initiator.prefs?.read_preference(/datum/preference/toggle/holder/play_adminhelp_ping))
|
||||
initiator << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
to_chat(initiator, span_filter_pm("[span_red(span_huge(span_bold("- AdminHelp Rejected! -")))]<br>\
|
||||
[span_red(span_bold("Your admin help was rejected."))]<br>\
|
||||
Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting."))
|
||||
|
||||
feedback_inc("ahelp_reject")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] rejected by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("Rejected by [key_name_admin(usr)].")
|
||||
Close(silent = TRUE)
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) rejected.",
|
||||
"body" = "Rejected by [key_name(usr)].",
|
||||
"color" = COLOR_WEBHOOK_BAD
|
||||
)
|
||||
)
|
||||
|
||||
//Resolve ticket with IC Issue message
|
||||
/datum/admin_help/proc/ICIssue(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
var/msg = "[span_red(span_huge(span_bold("- AdminHelp marked as IC issue! -")))]<br>"
|
||||
msg += "[span_red(span_bold("This is something that can be solved ICly, and does not currently require staff intervention."))]<br>"
|
||||
msg += "[span_red("Your AdminHelp may also be unanswerable due to ongoing events.")]"
|
||||
|
||||
if(initiator)
|
||||
to_chat(initiator,span_filter_pm(msg))
|
||||
|
||||
feedback_inc("ahelp_icissue")
|
||||
msg = "Ticket [TicketHref("#[id]")] marked as IC by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("Marked as IC issue by [key_name_admin(usr)]")
|
||||
Resolve(silent = TRUE)
|
||||
SSwebhooks.send(
|
||||
WEBHOOK_AHELP_SENT,
|
||||
list(
|
||||
"name" = "Ticket ([id]) (Game ID: [game_id]) marked as IC issue.",
|
||||
"body" = "Marked as IC Issue by [key_name(usr)].",
|
||||
"color" = COLOR_WEBHOOK_BAD
|
||||
)
|
||||
)
|
||||
|
||||
//Resolve ticket with IC Issue message
|
||||
/datum/admin_help/proc/HandleIssue()
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
var/msg = span_red("Your AdminHelp is being handled by [key_name(usr,FALSE,FALSE)] please be patient.")
|
||||
|
||||
if(initiator)
|
||||
to_chat(initiator, msg)
|
||||
|
||||
feedback_inc("ahelp_handling")
|
||||
msg = "Ticket [TicketHref("#[id]")] being handled by [key_name(usr,FALSE,FALSE)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
AddInteraction("[key_name_admin(usr)] is now handling this ticket.")
|
||||
var/query_string = "type=admintake"
|
||||
query_string += "&key=[url_encode(CONFIG_GET(string/chat_webhook_key))]"
|
||||
query_string += "&admin=[url_encode(key_name(usr))]"
|
||||
query_string += "&user=[url_encode(key_name(initiator))]"
|
||||
world.Export("[CONFIG_GET(string/chat_webhook_url)]?[query_string]")
|
||||
|
||||
|
||||
|
||||
|
||||
//Show the ticket panel
|
||||
/datum/admin_help/proc/TicketPanel()
|
||||
tgui_interact(usr.client.mob)
|
||||
|
||||
/datum/admin_help/proc/TicketPanelLegacy()
|
||||
var/list/dat = list("<html><head><title>Ticket #[id]</title></head>")
|
||||
var/ref_src = "\ref[src]"
|
||||
dat += "<h4>Admin Help Ticket #[id]: [LinkedReplyName(ref_src)]</h4>"
|
||||
dat += span_bold("State: ")
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
dat += span_red(span_bold("OPEN"))
|
||||
if(AHELP_RESOLVED)
|
||||
dat += span_green(span_bold("RESOLVED"))
|
||||
if(AHELP_CLOSED)
|
||||
dat += span_bold("CLOSED")
|
||||
else
|
||||
dat += span_bold("UNKNOWN")
|
||||
dat += "[GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
|
||||
if(state != AHELP_ACTIVE)
|
||||
dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
|
||||
dat += "<br><br>Opened at: [gameTimestamp(wtime = opened_at)] (Approx [(world.time - opened_at) / 600] minutes ago)"
|
||||
if(closed_at)
|
||||
dat += "<br>Closed at: [gameTimestamp(wtime = closed_at)] (Approx [(world.time - closed_at) / 600] minutes ago)"
|
||||
dat += "<br><br>"
|
||||
if(initiator)
|
||||
dat += span_bold("Actions:") + " [FullMonty(ref_src)]<br>"
|
||||
else
|
||||
dat += span_bold("DISCONNECTED") + "[GLOB.TAB][ClosureLinks(ref_src)]<br>"
|
||||
dat += "<br>" + span_bold("Log:") + "<br><br>"
|
||||
for(var/I in _interactions)
|
||||
dat += "[I]<br>"
|
||||
dat += "</html>"
|
||||
usr << browse(dat.Join(), "window=ahelp[id];size=620x480")
|
||||
|
||||
/datum/admin_help/proc/Retitle()
|
||||
var/new_title = tgui_input_text(usr, "Enter a title for the ticket", "Rename Ticket", name)
|
||||
if(new_title)
|
||||
name = new_title
|
||||
//not saying the original name cause it could be a long ass message
|
||||
var/msg = "Ticket [TicketHref("#[id]")] titled [name] by [key_name_admin(usr)]"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
TicketPanel() //we have to be here to do this
|
||||
|
||||
/datum/admin_help/tgui_fallback(payload)
|
||||
if(..())
|
||||
return
|
||||
|
||||
TicketPanelLegacy()
|
||||
|
||||
/datum/admin_help/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "AdminTicketPanel", "Ticket #[id] - [LinkedReplyName("\ref[src]")]")
|
||||
ui.open()
|
||||
|
||||
/datum/admin_help/tgui_state(mob/user)
|
||||
return GLOB.tgui_admin_state
|
||||
|
||||
/datum/admin_help/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["id"] = id
|
||||
|
||||
var/ref_src = "\ref[src]"
|
||||
data["title"] = name
|
||||
data["name"] = LinkedReplyName(ref_src)
|
||||
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
data["state"] = "open"
|
||||
if(AHELP_RESOLVED)
|
||||
data["state"] = "resolved"
|
||||
if(AHELP_CLOSED)
|
||||
data["state"] = "closed"
|
||||
else
|
||||
data["state"] = "unknown"
|
||||
|
||||
data["opened_at"] = (world.time - opened_at)
|
||||
data["closed_at"] = (world.time - closed_at)
|
||||
data["opened_at_date"] = gameTimestamp(wtime = opened_at)
|
||||
data["closed_at_date"] = gameTimestamp(wtime = closed_at)
|
||||
|
||||
data["actions"] = FullMonty(ref_src)
|
||||
|
||||
data["log"] = _interactions
|
||||
|
||||
return data
|
||||
|
||||
/datum/admin_help/tgui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("retitle")
|
||||
Retitle()
|
||||
. = TRUE
|
||||
if("reopen")
|
||||
Reopen()
|
||||
. = TRUE
|
||||
if("legacy")
|
||||
TicketPanelLegacy()
|
||||
. = TRUE
|
||||
|
||||
//Forwarded action from admin/Topic
|
||||
/datum/admin_help/proc/Action(action)
|
||||
testing("Ahelp action: [action]")
|
||||
switch(action)
|
||||
if("ticket")
|
||||
TicketPanel()
|
||||
if("retitle")
|
||||
Retitle()
|
||||
if("reject")
|
||||
Reject()
|
||||
if("reply")
|
||||
usr.client.cmd_ahelp_reply(initiator)
|
||||
if("icissue")
|
||||
ICIssue()
|
||||
if("close")
|
||||
Close()
|
||||
if("resolve")
|
||||
Resolve()
|
||||
if("handleissue")
|
||||
HandleIssue()
|
||||
if("reopen")
|
||||
Reopen()
|
||||
|
||||
//
|
||||
// TICKET STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ahelp
|
||||
var/datum/admin_help/ahelp_datum
|
||||
|
||||
/obj/effect/statclick/ahelp/Initialize(mapload, text, target)
|
||||
. = ..()
|
||||
ahelp_datum = target
|
||||
|
||||
/obj/effect/statclick/ahelp/update()
|
||||
return ..(ahelp_datum.name)
|
||||
|
||||
/obj/effect/statclick/ahelp/Click()
|
||||
ahelp_datum.TicketPanel()
|
||||
|
||||
/obj/effect/statclick/ahelp/Destroy()
|
||||
ahelp_datum = null
|
||||
return ..()
|
||||
|
||||
//
|
||||
// CLIENT PROCS
|
||||
//
|
||||
|
||||
/client/verb/adminhelp(msg as text)
|
||||
set category = "Admin"
|
||||
set name = "Adminhelp"
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, span_danger("Error: Admin-PM: You cannot send adminhelps (Muted)."))
|
||||
return
|
||||
if(handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
//remove out adminhelp verb temporarily to prevent spamming of admins.
|
||||
remove_verb(src, /client/verb/adminhelp)
|
||||
spawn(1200)
|
||||
add_verb(src, /client/verb/adminhelp) // 2 minute cool-down for adminhelps
|
||||
|
||||
feedback_add_details("admin_verb","Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
if(current_ticket)
|
||||
var/input = tgui_alert(usr, "You already have a ticket open. Is this for the same issue?","Duplicate?",list("Yes","No"))
|
||||
if(!input)
|
||||
return
|
||||
if(input == "Yes")
|
||||
if(current_ticket)
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
to_chat(usr, span_admin_pm_notice("PM to-" + span_bold("Admins") + ": [msg]"))
|
||||
return
|
||||
else
|
||||
to_chat(usr, span_warning("Ticket not found, creating new one..."))
|
||||
else
|
||||
current_ticket.AddInteraction("[key_name_admin(usr)] opened a new ticket.")
|
||||
current_ticket.Close()
|
||||
|
||||
new /datum/admin_help(msg, src, FALSE)
|
||||
|
||||
//admin proc
|
||||
/client/proc/cmd_admin_ticket_panel()
|
||||
set name = "Show Ticket List"
|
||||
set category = "Admin.Misc"
|
||||
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_DEBUG|R_EVENT, TRUE))
|
||||
return
|
||||
|
||||
var/browse_to
|
||||
|
||||
switch(tgui_input_list(usr, "Display which ticket list?", "List Choice", list("Active Tickets", "Closed Tickets", "Resolved Tickets")))
|
||||
if("Active Tickets")
|
||||
browse_to = AHELP_ACTIVE
|
||||
if("Closed Tickets")
|
||||
browse_to = AHELP_CLOSED
|
||||
if("Resolved Tickets")
|
||||
browse_to = AHELP_RESOLVED
|
||||
else
|
||||
return
|
||||
|
||||
GLOB.ahelp_tickets.BrowseTickets(browse_to)
|
||||
|
||||
//
|
||||
// LOGGING
|
||||
//
|
||||
|
||||
//Use this proc when an admin takes action that may be related to an open ticket on what
|
||||
//what can be a client, ckey, or mob
|
||||
/proc/admin_ticket_log(what, message)
|
||||
var/client/C
|
||||
var/mob/Mob = what
|
||||
if(istype(Mob))
|
||||
C = Mob.client
|
||||
else
|
||||
C = what
|
||||
if(istype(C) && C.current_ticket)
|
||||
C.current_ticket.AddInteraction(message)
|
||||
return C.current_ticket
|
||||
if(istext(what)) //ckey
|
||||
var/datum/admin_help/AH = GLOB.ahelp_tickets.CKey2ActiveTicket(what)
|
||||
if(AH)
|
||||
AH.AddInteraction(message)
|
||||
return AH
|
||||
|
||||
//
|
||||
// HELPER PROCS
|
||||
//
|
||||
|
||||
/proc/get_admin_counts(requiredflags = R_BAN)
|
||||
. = list("total" = list(), "noflags" = list(), "afk" = list(), "stealth" = list(), "present" = list())
|
||||
for(var/client/X in GLOB.admins)
|
||||
.["total"] += X
|
||||
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
|
||||
.["noflags"] += X
|
||||
else if(X.is_afk())
|
||||
.["afk"] += X
|
||||
else if(X.holder.fakekey)
|
||||
.["stealth"] += X
|
||||
else
|
||||
.["present"] += X
|
||||
|
||||
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/activemins = adm["present"]
|
||||
. = activemins.len
|
||||
if(. <= 0)
|
||||
var/final = ""
|
||||
var/list/afkmins = adm["afk"]
|
||||
var/list/stealthmins = adm["stealth"]
|
||||
var/list/powerlessmins = adm["noflags"]
|
||||
var/list/allmins = adm["total"]
|
||||
if(!afkmins.len && !stealthmins.len && !powerlessmins.len)
|
||||
final = "[msg] - No admins online"
|
||||
else
|
||||
final = "[msg] - All admins stealthed\[[english_list(stealthmins)]\], AFK\[[english_list(afkmins)]\], or lacks +BAN\[[english_list(powerlessmins)]\]! Total: [allmins.len] "
|
||||
send2irc(source,final)
|
||||
|
||||
/proc/ircadminwho()
|
||||
var/list/message = list("Admins: ")
|
||||
var/list/admin_keys = list()
|
||||
for(var/client/C as anything in GLOB.admins)
|
||||
admin_keys += "[C][C.holder.fakekey ? "(Stealth)" : ""][C.is_afk() ? "(AFK)" : ""]"
|
||||
|
||||
for(var/admin in admin_keys)
|
||||
if(LAZYLEN(admin_keys) > 1)
|
||||
message += ", [admin]"
|
||||
else
|
||||
message += "[admin]"
|
||||
|
||||
return jointext(message, "")
|
||||
|
||||
/proc/keywords_lookup(msg,irc)
|
||||
|
||||
//This is a list of words which are ignored by the parser when comparing message contents for names. MUST BE IN LOWER CASE!
|
||||
var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","alien","as", "i")
|
||||
|
||||
//explode the input msg into a list
|
||||
var/list/msglist = splittext(msg, " ")
|
||||
|
||||
//generate keywords lookup
|
||||
var/list/surnames = list()
|
||||
var/list/forenames = list()
|
||||
var/list/ckeys = list()
|
||||
var/founds = ""
|
||||
for(var/mob/M in mob_list)
|
||||
var/list/indexing = list(M.real_name, M.name)
|
||||
if(M.mind)
|
||||
indexing += M.mind.name
|
||||
|
||||
for(var/string in indexing)
|
||||
var/list/L = splittext(string, " ")
|
||||
var/surname_found = 0
|
||||
//surnames
|
||||
for(var/i=L.len, i>=1, i--)
|
||||
var/word = ckey(L[i])
|
||||
if(word)
|
||||
surnames[word] = M
|
||||
surname_found = i
|
||||
break
|
||||
//forenames
|
||||
for(var/i=1, i<surname_found, i++)
|
||||
var/word = ckey(L[i])
|
||||
if(word)
|
||||
forenames[word] = M
|
||||
//ckeys
|
||||
ckeys[M.ckey] = M
|
||||
|
||||
var/ai_found = 0
|
||||
msg = ""
|
||||
var/list/mobs_found = list()
|
||||
for(var/original_word in msglist)
|
||||
var/word = ckey(original_word)
|
||||
if(word)
|
||||
if(!(word in adminhelp_ignored_words))
|
||||
if(word == "ai")
|
||||
ai_found = 1
|
||||
else
|
||||
var/mob/found = ckeys[word]
|
||||
if(!found)
|
||||
found = surnames[word]
|
||||
if(!found)
|
||||
found = forenames[word]
|
||||
if(found)
|
||||
if(!(found in mobs_found))
|
||||
mobs_found += found
|
||||
if(!ai_found && isAI(found))
|
||||
ai_found = 1
|
||||
var/is_antag = 0
|
||||
if(found.mind && found.mind.special_role)
|
||||
is_antag = 1
|
||||
founds += "Name: [found.name]([found.real_name]) Ckey: [found.ckey] [is_antag ? "(Antag)" : null] "
|
||||
var/textentry = "(<A href='byond://?_src_=holder;[HrefToken()];adminmoreinfo=\ref[found]'>?</A>|<A href='byond://?_src_=holder;[HrefToken()];adminplayerobservefollow=\ref[found]'>F</A> "
|
||||
msg += "[original_word]" + span_small((is_antag ? span_red(textentry) : span_black(textentry)))
|
||||
continue
|
||||
msg += "[original_word] "
|
||||
if(irc)
|
||||
if(founds == "")
|
||||
return "Search Failed"
|
||||
else
|
||||
return founds
|
||||
|
||||
return msg
|
||||
@@ -1,39 +0,0 @@
|
||||
/datum/admin_help/proc/send2adminchat()
|
||||
if(!CONFIG_GET(string/chat_webhook_url))
|
||||
return
|
||||
|
||||
var/list/adm = get_admin_counts()
|
||||
var/list/afkmins = adm["afk"]
|
||||
var/list/allmins = adm["total"]
|
||||
|
||||
spawn(0) //Unreliable world.Exports()
|
||||
var/query_string = "type=adminhelp"
|
||||
query_string += "&key=[url_encode(CONFIG_GET(string/chat_webhook_key))]"
|
||||
query_string += "&from=[url_encode(key_name(initiator))]"
|
||||
query_string += "&msg=[url_encode(html_decode(name))]"
|
||||
query_string += "&admin_number=[allmins.len]"
|
||||
query_string += "&admin_number_afk=[afkmins.len]"
|
||||
world.Export("[CONFIG_GET(string/chat_webhook_url)]?[query_string]")
|
||||
|
||||
/client/verb/adminspice()
|
||||
set category = "Admin"
|
||||
set name = "Request Spice"
|
||||
set desc = "Request admins to spice round up for you"
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(usr, span_danger("Error: You cannot request spice (muted from adminhelps)."))
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Are you sure you want to request the admins spice things up for you? You accept the consequences if you do.","Spicy!",list("Yes","No")) == "Yes")
|
||||
message_admins("[ADMIN_FULLMONTY(usr)] has requested the round be spiced up a little.")
|
||||
to_chat(usr, span_notice("You have requested some more spice in your round."))
|
||||
else
|
||||
to_chat(usr, span_notice("Spice request cancelled."))
|
||||
return
|
||||
|
||||
//if they requested spice, then remove spice verb temporarily to prevent spamming
|
||||
remove_verb(usr, /client/verb/adminspice)
|
||||
spawn(10 MINUTES)
|
||||
if(usr) // In case we left in the 10 minute cooldown
|
||||
add_verb(usr, /client/verb/adminspice) // 10 minute cool-down for spice request
|
||||
@@ -53,19 +53,19 @@
|
||||
to_chat(src, span_admin_pm_warning("Error: Admin-PM: Client not found."))
|
||||
return
|
||||
|
||||
var/datum/admin_help/AH = C.current_ticket
|
||||
var/datum/ticket/T = C.current_ticket
|
||||
|
||||
if(AH)
|
||||
if(T)
|
||||
message_admins(span_pm("[key_name_admin(src)] has started replying to [key_name(C, 0, 0)]'s admin help."))
|
||||
var/msg = tgui_input_text(src,"Message:", "Private message to [key_name(C, 0, 0)]", multiline = TRUE)
|
||||
if (!msg)
|
||||
message_admins(span_pm("[key_name_admin(src)] has cancelled their reply to [key_name(C, 0, 0)]'s admin help."))
|
||||
return
|
||||
cmd_admin_pm(whom, msg, AH)
|
||||
cmd_admin_pm(whom, msg, T)
|
||||
|
||||
//takes input from cmd_admin_pm_context, cmd_admin_pm_panel or /client/Topic and sends them a PM.
|
||||
//Fetching a message if needed. src is the sender and C is the target client
|
||||
/client/proc/cmd_admin_pm(whom, msg, datum/admin_help/AH)
|
||||
/client/proc/cmd_admin_pm(whom, msg, datum/ticket/T)
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, span_admin_pm_warning("Error: Admin-PM: You are unable to use admin PM-s (muted)."))
|
||||
return
|
||||
@@ -171,7 +171,7 @@
|
||||
else
|
||||
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
|
||||
if(!recipient.current_ticket)
|
||||
new /datum/admin_help(msg, recipient, TRUE)
|
||||
new /datum/ticket(msg, recipient, TRUE, 1)
|
||||
|
||||
to_chat(recipient, span_admin_pm_warning(span_huge(span_bold("-- Administrator private message --"))))
|
||||
to_chat(recipient, span_admin_pm_warning("Admin PM from-<b>[key_name(src, recipient, 0)]</b>: [msg]"))
|
||||
@@ -218,7 +218,7 @@
|
||||
/proc/IrcPm(target,msg,sender)
|
||||
var/client/C = GLOB.directory[target]
|
||||
|
||||
var/datum/admin_help/ticket = C ? C.current_ticket : GLOB.ahelp_tickets.CKey2ActiveTicket(target)
|
||||
var/datum/ticket/ticket = C ? C.current_ticket : GLOB.tickets.CKey2ActiveTicket(target)
|
||||
var/compliant_msg = trim(lowertext(msg))
|
||||
var/irc_tagged = "[sender](IRC)"
|
||||
var/list/splits = splittext(compliant_msg, " ")
|
||||
|
||||
@@ -1,63 +1,53 @@
|
||||
/client/proc/cmd_admin_say(msg as text)
|
||||
set category = "Admin.Chat"
|
||||
set name = "Asay" //Gave this shit a shorter name so you only have to time out "asay" rather than "admin say" to use it --NeoFite
|
||||
set hidden = 1
|
||||
if(!check_rights(R_ADMIN)) //VOREStation Edit
|
||||
return
|
||||
|
||||
msg = sanitize(msg)
|
||||
ADMIN_VERB(cmd_admin_say, R_ADMIN, "ASay", "Send a message to other admins", "Admin.Chat", message as text)
|
||||
var/msg = sanitize(message)
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
log_adminsay(msg,src)
|
||||
log_adminsay(msg, user)
|
||||
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(check_rights_for(C, R_ADMIN))
|
||||
to_chat(C, span_admin_channel(create_text_tag("admin", "ADMIN:", C) + " " + span_name("[key_name(usr, 1)]") + "([admin_jump_link(mob, src)]): " + span_name("[msg]") ))
|
||||
to_chat(C, span_admin_channel(create_text_tag("admin", "ADMIN:", C) + " " + span_name("[key_name(user, 1)]") + "([admin_jump_link(user.mob, C.holder)]): " + span_name("[msg]") ))
|
||||
|
||||
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_mod_say(msg as text)
|
||||
set category = "Admin.Chat"
|
||||
set name = "Msay"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_SERVER)) //VOREStation Edit
|
||||
return
|
||||
|
||||
msg = sanitize(msg)
|
||||
log_modsay(msg,src)
|
||||
ADMIN_VERB(cmd_mod_say, (R_ADMIN|R_MOD|R_SERVER), "Msay", "Send a message to other mod", "Admin.Chat", message as text)
|
||||
var/msg = sanitize(message)
|
||||
log_modsay(msg, user)
|
||||
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
var/sender_name = key_name(usr, 1)
|
||||
var/sender_name = key_name(user, 1)
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
sender_name = span_admin("[sender_name]")
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(check_rights(R_ADMIN|R_MOD|R_SERVER)) //VOREStation Edit
|
||||
to_chat(C, span_mod_channel(create_text_tag("mod", "MOD:", C) + " " + span_name("[sender_name]") + "([admin_jump_link(mob, C.holder)]): " + span_name("[msg]") ))
|
||||
to_chat(C, span_mod_channel(create_text_tag("mod", "MOD:", C) + " " + span_name("[sender_name]") + "([admin_jump_link(user.mob, C.holder)]): " + span_name("[msg]") ))
|
||||
|
||||
feedback_add_details("admin_verb","MS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_event_say(msg as text)
|
||||
set category = "Admin.Chat"
|
||||
set name = "Esay"
|
||||
set hidden = 1
|
||||
|
||||
if(!check_rights(R_ADMIN|R_MOD|R_EVENT|R_SERVER)) //VOREStation Edit
|
||||
return
|
||||
|
||||
msg = sanitize(msg)
|
||||
log_eventsay(msg,src)
|
||||
ADMIN_VERB(cmd_event_say, (R_ADMIN|R_MOD|R_EVENT|R_SERVER), "Esay", "Send a message to other event manager", "Admin.Chat", message as text)
|
||||
var/msg = sanitize(message)
|
||||
log_eventsay(msg, user)
|
||||
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
var/sender_name = key_name(usr, 1)
|
||||
var/sender_name = key_name(user, 1)
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
sender_name = span_admin("[sender_name]")
|
||||
for(var/client/C in GLOB.admins)
|
||||
to_chat(C, span_event_channel(create_text_tag("event", "EVENT:", C) + " " + span_name("[sender_name]") + "([admin_jump_link(mob, C.holder)]): " + span_name("[msg]") ))
|
||||
to_chat(C, span_event_channel(create_text_tag("event", "EVENT:", C) + " " + span_name("[sender_name]") + "([admin_jump_link(user.mob, C.holder)]): " + span_name("[msg]") ))
|
||||
|
||||
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
ADMIN_VERB(cmd_mentor_say, (R_ADMIN|R_MOD|R_EVENT|R_SERVER|R_MENTOR), "Mentorsay", "Send a message to other mentors", "Admin.Chat", message as text)
|
||||
var/msg = sanitize(message)
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
log_admin("Mentorsay: [key_name(user)]: [msg]")
|
||||
|
||||
for(var/client/C in GLOB.admins)
|
||||
to_chat(C, create_text_tag("mentor", "MENTOR:", C) + " " + span_mentor_channel(span_name("[user]") + ": " + span_message("[msg]")))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//DO NOT ADD MORE TO THIS FILE.
|
||||
//Use vv_do_topic()!
|
||||
/client/proc/view_var_Topic(href, href_list, hsrc)
|
||||
if((usr.client != src) || !src.holder)
|
||||
if((usr.client != src) || check_rights(R_HOLDER))
|
||||
return
|
||||
var/datum/target = locate(href_list["target"])
|
||||
if(istype(target))
|
||||
@@ -18,10 +18,10 @@
|
||||
|
||||
var/mob/M = locate(href_list["rename"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
var/new_name = sanitize(tgui_input_text(usr,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
var/new_name = sanitize(tgui_input_text(src,"What would you like to name this mob?","Input a name",M.real_name,MAX_NAME_LEN), MAX_NAME_LEN)
|
||||
if( !new_name || !M ) return
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
var/D = locate(href_list["datumedit"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
to_chat(usr, "This can only be used on instances of types /client or /datum")
|
||||
to_chat(src, "This can only be used on instances of types /client or /datum")
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnameedit"], 1)
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
var/D = locate(href_list["datumchange"])
|
||||
if(!istype(D,/datum) && !istype(D,/client))
|
||||
to_chat(usr, "This can only be used on instances of types /client or /datum")
|
||||
to_chat(src, "This can only be used on instances of types /client or /datum")
|
||||
return
|
||||
|
||||
modify_variables(D, href_list["varnamechange"], 0)
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
var/atom/A = locate(href_list["datummass"])
|
||||
if(!istype(A))
|
||||
to_chat(usr, "This can only be used on instances of type /atom")
|
||||
to_chat(src, "This can only be used on instances of type /atom")
|
||||
return
|
||||
|
||||
cmd_mass_modify_object_variables(A, href_list["varnamemass"])
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["mob_player_panel"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.holder.show_player_panel(M)
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["give_spell"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.give_spell(M)
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
var/mob/living/M = locate(href_list["give_modifier"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob/living")
|
||||
to_chat(src, "This can only be used on instances of type /mob/living")
|
||||
return
|
||||
|
||||
src.admin_give_modifier(M)
|
||||
@@ -98,22 +98,22 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["give_wound_internal"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, span_notice("This can only be used on instances of type /mob/living/carbon/human"))
|
||||
to_chat(src, span_notice("This can only be used on instances of type /mob/living/carbon/human"))
|
||||
return
|
||||
|
||||
var/severity = tgui_input_number(usr, "How much damage should the bleeding internal wound cause? \
|
||||
var/severity = tgui_input_number(src, "How much damage should the bleeding internal wound cause? \
|
||||
Bleed timer directly correlates with this. 0 cancels. Input is rounded to nearest integer.",
|
||||
"Wound Severity", 0)
|
||||
if(!severity) return
|
||||
|
||||
var/obj/item/organ/external/chosen_organ = tgui_input_list(usr, "Choose an external organ to inflict IB on!", "Organ Choice", H.organs)
|
||||
var/obj/item/organ/external/chosen_organ = tgui_input_list(src, "Choose an external organ to inflict IB on!", "Organ Choice", H.organs)
|
||||
if(!chosen_organ || !istype(chosen_organ))
|
||||
to_chat(usr, span_notice("The chosen organ is of inappropriate type or no longer exists."))
|
||||
return
|
||||
|
||||
var/datum/wound/internal_bleeding/I = new /datum/wound/internal_bleeding(severity)
|
||||
if(!I || !istype(I))
|
||||
to_chat(usr, span_notice("Could not initialize internal wound"))
|
||||
to_chat(src, span_notice("Could not initialize internal wound"))
|
||||
log_debug("[usr] attempted to create an internal bleeding wound on [H]'s [chosen_organ] of [severity] damage \
|
||||
and wound initialization failed")
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["godmode"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.cmd_admin_godmode(M)
|
||||
@@ -145,7 +145,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["gib"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
src.cmd_admin_gib(M)
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["build_mode"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
togglebuildmode(M)
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["drop_everything"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
@@ -177,7 +177,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["direct_control"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be used on instances of type /mob")
|
||||
to_chat(src, "This can only be used on instances of type /mob")
|
||||
return
|
||||
|
||||
if(usr.client)
|
||||
@@ -188,22 +188,22 @@
|
||||
|
||||
var/mob/M = locate(href_list["give_ai"])
|
||||
if(!isliving(M))
|
||||
to_chat(usr, span_notice("This can only be used on instances of type /mob/living"))
|
||||
to_chat(src, span_notice("This can only be used on instances of type /mob/living"))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(L.client || L.teleop)
|
||||
to_chat(usr, span_warning("This cannot be used on player mobs!"))
|
||||
to_chat(src, span_warning("This cannot be used on player mobs!"))
|
||||
return
|
||||
|
||||
if(L.ai_holder) //Cleaning up the original ai
|
||||
var/ai_holder_old = L.ai_holder
|
||||
L.ai_holder = null
|
||||
qdel(ai_holder_old) //Only way I could make #TESTING - Unable to be GC'd to stop. del() logs show it works.
|
||||
L.ai_holder_type = tgui_input_list(usr, "Choose AI holder", "AI Type", typesof(/datum/ai_holder/))
|
||||
L.ai_holder_type = tgui_input_list(src, "Choose AI holder", "AI Type", typesof(/datum/ai_holder/))
|
||||
L.initialize_ai_holder()
|
||||
L.faction = sanitize(tgui_input_text(usr, "Please input AI faction", "AI faction", "neutral"))
|
||||
L.a_intent = tgui_input_list(usr, "Please choose AI intent", "AI intent", list(I_HURT, I_HELP))
|
||||
if(tgui_alert(usr, "Make mob wake up? This is needed for carbon mobs.", "Wake mob?", list("Yes", "No")) == "Yes")
|
||||
L.faction = sanitize(tgui_input_text(src, "Please input AI faction", "AI faction", "neutral"))
|
||||
L.a_intent = tgui_input_list(src, "Please choose AI intent", "AI intent", list(I_HURT, I_HELP))
|
||||
if(tgui_alert(src, "Make mob wake up? This is needed for carbon mobs.", "Wake mob?", list("Yes", "No")) == "Yes")
|
||||
L.AdjustSleeping(-100)
|
||||
|
||||
else if(href_list["make_skeleton"])
|
||||
@@ -211,7 +211,7 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["make_skeleton"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be used on instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be used on instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
H.ChangeToSkeleton()
|
||||
@@ -223,17 +223,17 @@
|
||||
|
||||
var/obj/O = locate(href_list["delall"])
|
||||
if(!isobj(O))
|
||||
to_chat(usr, "This can only be used on instances of type /obj")
|
||||
to_chat(src, "This can only be used on instances of type /obj")
|
||||
return
|
||||
|
||||
var/action_type = tgui_alert(usr, "Strict type ([O.type]) or type and all subtypes?","Type Selection",list("Strict type","Type and subtypes","Cancel"))
|
||||
var/action_type = tgui_alert(src, "Strict type ([O.type]) or type and all subtypes?","Type Selection",list("Strict type","Type and subtypes","Cancel"))
|
||||
if(action_type == "Cancel" || !action_type)
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Are you really sure you want to delete all objects of type [O.type]?","Delete All?",list("Yes","No")) != "Yes")
|
||||
if(tgui_alert(src, "Are you really sure you want to delete all objects of type [O.type]?","Delete All?",list("Yes","No")) != "Yes")
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Second confirmation required. Delete?","REALLY?",list("Yes","No")) != "Yes")
|
||||
if(tgui_alert(src, "Second confirmation required. Delete?","REALLY?",list("Yes","No")) != "Yes")
|
||||
return
|
||||
|
||||
var/O_type = O.type
|
||||
@@ -246,7 +246,7 @@
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
to_chat(usr, "No objects of this type exist")
|
||||
to_chat(src, "No objects of this type exist")
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
|
||||
message_admins(span_notice("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) "))
|
||||
@@ -258,7 +258,7 @@
|
||||
qdel(Obj)
|
||||
CHECK_TICK
|
||||
if(!i)
|
||||
to_chat(usr, "No objects of this type exist")
|
||||
to_chat(src, "No objects of this type exist")
|
||||
return
|
||||
log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
|
||||
message_admins(span_notice("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) "))
|
||||
@@ -267,7 +267,7 @@
|
||||
|
||||
var/obj/item/pda/P = locate(href_list["fakepdapropconvo"])
|
||||
if(!istype(P))
|
||||
to_chat(usr, span_warning("This can only be done to instances of type /pda"))
|
||||
to_chat(src, span_warning("This can only be done to instances of type /pda"))
|
||||
return
|
||||
|
||||
P.createPropFakeConversation_admin(usr)
|
||||
@@ -277,7 +277,7 @@
|
||||
|
||||
var/atom/A = locate(href_list["rotatedatum"])
|
||||
if(!istype(A))
|
||||
to_chat(usr, "This can only be done to instances of type /atom")
|
||||
to_chat(src, "This can only be done to instances of type /atom")
|
||||
return
|
||||
|
||||
switch(href_list["rotatedir"])
|
||||
@@ -290,12 +290,12 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))
|
||||
|
||||
@@ -304,12 +304,12 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makerobot"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makerobot"=href_list["makerobot"]))
|
||||
|
||||
@@ -318,12 +318,12 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makealien"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makealien"=href_list["makealien"]))
|
||||
|
||||
@@ -332,12 +332,12 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makeai"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
if(tgui_alert(usr, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(tgui_alert(src, "Confirm mob type change?","Confirm",list("Transform","Cancel")) != "Transform") return
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
holder.Topic(href, list("makeai"=href_list["makeai"]))
|
||||
|
||||
@@ -346,67 +346,67 @@
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["setspecies"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon/human")
|
||||
return
|
||||
|
||||
var/new_species = tgui_input_list(usr, "Please choose a new species.","Species", GLOB.all_species)
|
||||
var/new_species = tgui_input_list(src, "Please choose a new species.","Species", GLOB.all_species)
|
||||
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.set_species(new_species))
|
||||
to_chat(usr, "Set species of [H] to [H.species].")
|
||||
to_chat(src, "Set species of [H] to [H.species].")
|
||||
else
|
||||
to_chat(usr, "Failed! Something went wrong.")
|
||||
to_chat(src, "Failed! Something went wrong.")
|
||||
|
||||
else if(href_list["addlanguage"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/H = locate(href_list["addlanguage"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob")
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
|
||||
var/new_language = tgui_input_list(usr, "Please choose a language to add.","Language", GLOB.all_languages)
|
||||
var/new_language = tgui_input_list(src, "Please choose a language to add.","Language", GLOB.all_languages)
|
||||
|
||||
if(!new_language)
|
||||
return
|
||||
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.add_language(new_language))
|
||||
to_chat(usr, "Added [new_language] to [H].")
|
||||
to_chat(src, "Added [new_language] to [H].")
|
||||
else
|
||||
to_chat(usr, "Mob already knows that language.")
|
||||
to_chat(src, "Mob already knows that language.")
|
||||
|
||||
else if(href_list["remlanguage"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/H = locate(href_list["remlanguage"])
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob")
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
|
||||
if(!H.languages.len)
|
||||
to_chat(usr, "This mob knows no languages.")
|
||||
to_chat(src, "This mob knows no languages.")
|
||||
return
|
||||
|
||||
var/datum/language/rem_language = tgui_input_list(usr, "Please choose a language to remove.","Language", H.languages)
|
||||
var/datum/language/rem_language = tgui_input_list(src, "Please choose a language to remove.","Language", H.languages)
|
||||
|
||||
if(!rem_language)
|
||||
return
|
||||
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(H.remove_language(rem_language.name))
|
||||
to_chat(usr, "Removed [rem_language] from [H].")
|
||||
to_chat(src, "Removed [rem_language] from [H].")
|
||||
else
|
||||
to_chat(usr, "Mob doesn't know that language.")
|
||||
to_chat(src, "Mob doesn't know that language.")
|
||||
|
||||
else if(href_list["addverb"])
|
||||
if(!check_rights(R_DEBUG)) return
|
||||
@@ -414,7 +414,7 @@
|
||||
var/mob/H = locate(href_list["addverb"])
|
||||
|
||||
if(!ismob(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob")
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
var/list/possibleverbs = list()
|
||||
possibleverbs += "Cancel" // One for the top...
|
||||
@@ -434,9 +434,9 @@
|
||||
possibleverbs -= H.verbs
|
||||
possibleverbs += "Cancel" // ...And one for the bottom
|
||||
|
||||
var/verb = tgui_input_list(usr, "Select a verb!", "Verbs", possibleverbs)
|
||||
var/verb = tgui_input_list(src, "Select a verb!", "Verbs", possibleverbs)
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(!verb || verb == "Cancel")
|
||||
return
|
||||
@@ -449,11 +449,11 @@
|
||||
var/mob/H = locate(href_list["remverb"])
|
||||
|
||||
if(!istype(H))
|
||||
to_chat(usr, "This can only be done to instances of type /mob")
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
var/verb = tgui_input_list(usr, "Please choose a verb to remove.","Verbs", H.verbs)
|
||||
var/verb = tgui_input_list(src, "Please choose a verb to remove.","Verbs", H.verbs)
|
||||
if(!H)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(!verb)
|
||||
return
|
||||
@@ -465,18 +465,18 @@
|
||||
|
||||
var/mob/living/carbon/M = locate(href_list["addorgan"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon")
|
||||
return
|
||||
|
||||
var/new_organ = tgui_input_list(usr, "Please choose an organ to add.","Organ", subtypesof(/obj/item/organ))
|
||||
var/new_organ = tgui_input_list(src, "Please choose an organ to add.","Organ", subtypesof(/obj/item/organ))
|
||||
if(!new_organ) return
|
||||
|
||||
if(!M)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(locate(new_organ) in M.internal_organs)
|
||||
to_chat(usr, "Mob already has that organ.")
|
||||
to_chat(src, "Mob already has that organ.")
|
||||
return
|
||||
|
||||
new new_organ(M)
|
||||
@@ -487,20 +487,20 @@
|
||||
|
||||
var/mob/living/carbon/M = locate(href_list["remorgan"])
|
||||
if(!istype(M))
|
||||
to_chat(usr, "This can only be done to instances of type /mob/living/carbon")
|
||||
to_chat(src, "This can only be done to instances of type /mob/living/carbon")
|
||||
return
|
||||
|
||||
var/obj/item/organ/rem_organ = tgui_input_list(usr, "Please choose an organ to remove.","Organ", M.internal_organs)
|
||||
var/obj/item/organ/rem_organ = tgui_input_list(src, "Please choose an organ to remove.","Organ", M.internal_organs)
|
||||
|
||||
if(!M)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
if(!(locate(rem_organ) in M.internal_organs))
|
||||
to_chat(usr, "Mob does not have that organ.")
|
||||
to_chat(src, "Mob does not have that organ.")
|
||||
return
|
||||
|
||||
to_chat(usr, "Removed [rem_organ] from [M].")
|
||||
to_chat(src, "Removed [rem_organ] from [M].")
|
||||
rem_organ.removed()
|
||||
qdel(rem_organ)
|
||||
|
||||
@@ -510,12 +510,12 @@
|
||||
var/mob/H = locate(href_list["fix_nano"])
|
||||
|
||||
if(!istype(H) || !H.client)
|
||||
to_chat(usr, "This can only be done on mobs with clients")
|
||||
to_chat(src, "This can only be done on mobs with clients")
|
||||
return
|
||||
|
||||
H.client.send_resources()
|
||||
|
||||
to_chat(usr, "Resource files sent")
|
||||
to_chat(src, "Resource files sent")
|
||||
to_chat(H, "Your NanoUI Resource files have been refreshed")
|
||||
|
||||
log_admin("[key_name(usr)] resent the NanoUI resource files to [key_name(H)] ")
|
||||
@@ -525,7 +525,7 @@
|
||||
|
||||
var/mob/M = locate(href_list["regenerateicons"])
|
||||
if(!ismob(M))
|
||||
to_chat(usr, "This can only be done to instances of type /mob")
|
||||
to_chat(src, "This can only be done to instances of type /mob")
|
||||
return
|
||||
M.regenerate_icons()
|
||||
|
||||
@@ -537,10 +537,10 @@
|
||||
|
||||
var/Text = href_list["adjustDamage"]
|
||||
|
||||
var/amount = tgui_input_number(usr, "Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0, min_value=-INFINITY, round_value=FALSE)
|
||||
var/amount = tgui_input_number(src, "Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0, min_value=-INFINITY, round_value=FALSE)
|
||||
|
||||
if(!L)
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
to_chat(src, "Mob doesn't exist anymore")
|
||||
return
|
||||
|
||||
switch(Text)
|
||||
@@ -551,7 +551,7 @@
|
||||
if("brain") L.adjustBrainLoss(amount)
|
||||
if("clone") L.adjustCloneLoss(amount)
|
||||
else
|
||||
to_chat(usr, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
to_chat(src, "You caused an error. DEBUG: Text:[Text] Mob:[L]")
|
||||
return
|
||||
|
||||
if(amount != 0)
|
||||
@@ -570,11 +570,11 @@
|
||||
var/client/C = value["value"]
|
||||
if (!C)
|
||||
return
|
||||
var/prompt = tgui_alert(usr, "Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", list("Yes", "No"))
|
||||
var/prompt = tgui_alert(src, "Do you want to grant [C] access to view this VV window? (they will not be able to edit or change anysrc nor open nested vv windows unless they themselves are an admin)", "Confirm", list("Yes", "No"))
|
||||
if (prompt != "Yes")
|
||||
return
|
||||
if(!thing)
|
||||
to_chat(usr, span_warning("The object you tried to expose to [C] no longer exists (GC'd)"))
|
||||
to_chat(src, span_warning("The object you tried to expose to [C] no longer exists (GC'd)"))
|
||||
return
|
||||
message_admins("[key_name_admin(usr)] Showed [key_name_admin(C)] a <a href='byond://?_src_=vars;[HrefToken(TRUE)];datumrefresh=\ref[thing]'>VV window</a>")
|
||||
log_admin("Admin [key_name(usr)] Showed [key_name(C)] a VV window of a [src]")
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#define ICON_STATE_CHECKED 1 /// this dmi is checked. We don't check this one anymore.
|
||||
#define ICON_STATE_NULL 2 /// this dmi has null-named icon_state, allowing it to show a sprite on vv editor.
|
||||
|
||||
ADMIN_VERB_AND_CONTEXT_MENU(debug_variables, (R_DEBUG|R_SERVER|R_ADMIN|R_SPAWN|R_FUN|R_EVENT), "View Variables", "View the variables of a datum.", "Debug.Investigate", datum/thing in world)
|
||||
user.debug_variables(thing)
|
||||
// This is kept as a separate proc because admins are able to show VV to non-admins
|
||||
|
||||
/client/proc/debug_variables(datum/D in world)
|
||||
set category = "Debug.Investigate"
|
||||
set name = "View Variables"
|
||||
|
||||
Reference in New Issue
Block a user