mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
AHelp improvements (#26092)
* Ahelp refactor * Same ticket nagging * Remie review * Dead code * Require tickets for PMs + other fixes * Remove full monty redundancy * Stylesheet * Listings refresh * Add ban logs to tickets * Tickets can stay associated after reconnect * Don't show active disconnected tickets in the main list * Ticket titles * More beautiful + fixes * Needful * IC issues close the ticket, feedback, and other stuff * Move shit around * IC issue -> resolve. Inline with the meaning of resolve. Documentation * Classic style + fixes * Width * Formatting * Whoops * Formatting * That top note * That cream * Pure vanilla * move to status panel * Fix the listing * Sleep checks * Stay frosty * Allows close/resolve of disconnected players * Ban logging will work if the player logs out. * Sorted closed and resolved lists * Fixes * IRC commands * More feedback * Small fix * Unfix * Just witnessed a memetide of tickets * Make the timer unique for good measure * Fix * Make it use QDEL_LIST * Fix * colorful * Fix * No more name prompt * Retitling * Fix * Fix * < CANT CODE * Phrasing * The better * Better linking and stuff * Language * Bluh * This may have broke things, let's back up * Ticket reopening * Admin panel verb for viewing a ticket list * Slightly better refreshing * Improve reject and IC issue wording * Log client disconnects and reconnects * Hopefully fixes the same issue issue * This should be here * Almost a terrible idea * More feedback * Better timing * Better timing and logging * Adding notes * Improves teleport logging * saddest commit in history * Fix feedback counters for reopened tickets * Fixed
This commit is contained in:
@@ -51,7 +51,7 @@
|
||||
#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]"
|
||||
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
|
||||
#define ADMIN_SET_SD_CODE "(<a href='?_src_=holder;set_selfdestruct_code=1'>SETCODE</a>)"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)]"
|
||||
#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]"
|
||||
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]"
|
||||
#define ADMIN_JMP(src) "(<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)"
|
||||
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
|
||||
@@ -61,4 +61,8 @@
|
||||
#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt"
|
||||
#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage"
|
||||
#define ADMIN_PUNISHMENT_GIB "Gib"
|
||||
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
|
||||
#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device"
|
||||
|
||||
#define AHELP_ACTIVE 1
|
||||
#define AHELP_CLOSED 2
|
||||
#define AHELP_RESOLVED 3
|
||||
@@ -1043,6 +1043,7 @@
|
||||
|
||||
if(result)
|
||||
var/newtype = GLOB.species_list[result]
|
||||
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [H] to [result]")
|
||||
H.set_species(newtype)
|
||||
|
||||
else if(href_list["editbodypart"])
|
||||
@@ -1088,7 +1089,7 @@
|
||||
to_chat(usr, "[C] doesn't have such bodypart.")
|
||||
else
|
||||
to_chat(usr, "Only humans can be augmented.")
|
||||
|
||||
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [C]")
|
||||
|
||||
|
||||
else if(href_list["purrbation"])
|
||||
@@ -1111,12 +1112,16 @@
|
||||
if(success)
|
||||
to_chat(usr, "Put [H] on purrbation.")
|
||||
log_admin("[key_name(usr)] has put [key_name(H)] on purrbation.")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has put [key_name(H)] on purrbation.</span>")
|
||||
var/msg = "<span class='notice'>[key_name_admin(usr)] has put [key_name(H)] on purrbation.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(H, msg)
|
||||
|
||||
else
|
||||
to_chat(usr, "Removed [H] from purrbation.")
|
||||
log_admin("[key_name(usr)] has removed [key_name(H)] from purrbation.")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has removed [key_name(H)] from purrbation.</span>")
|
||||
var/msg = "<span class='notice'>[key_name_admin(usr)] has removed [key_name(H)] from purrbation.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(H, msg)
|
||||
|
||||
else if(href_list["adjustDamage"] && href_list["mobToDamage"])
|
||||
if(!check_rights(0))
|
||||
@@ -1155,6 +1160,8 @@
|
||||
|
||||
if(amount != 0)
|
||||
log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
|
||||
message_admins("<span class='notice'>[key_name(usr)] dealt [amount] amount of [Text] damage to [L] </span>")
|
||||
var/msg = "<span class='notice'>[key_name(usr)] dealt [amount] amount of [Text] damage to [L] </span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(L, msg)
|
||||
href_list["datumrefresh"] = href_list["mobToDamage"]
|
||||
|
||||
|
||||
@@ -130,12 +130,16 @@
|
||||
if(!query_add_ban.warn_execute())
|
||||
return
|
||||
to_chat(usr, "<span class='adminnotice'>Ban saved to database.</span>")
|
||||
message_admins("[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database.",1)
|
||||
var/msg = "[key_name_admin(usr)] has added a [bantype_str] for [ckey] [(job)?"([job])":""] [(duration > 0)?"([duration] minutes)":""] with the reason: \"[reason]\" to the ban database."
|
||||
message_admins(msg,1)
|
||||
var/datum/admin_help/AH = admin_ticket_log(ckey, msg)
|
||||
|
||||
if(announceinirc)
|
||||
send2irc("BAN ALERT","[a_ckey] applied a [bantype_str] on [ckey]")
|
||||
|
||||
if(kickbannedckey)
|
||||
if(AH)
|
||||
AH.Resolve() //with prejudice
|
||||
if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
|
||||
qdel(banned_mob.client)
|
||||
return 1
|
||||
|
||||
@@ -21,6 +21,7 @@ GLOBAL_LIST_INIT(admin_verbs_default, AVerbsDefault())
|
||||
/client/proc/reestablish_db_connection,/*reattempt a connection to the database*/
|
||||
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
|
||||
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
|
||||
/client/proc/cmd_admin_ticket_panel,
|
||||
/client/proc/stop_sounds
|
||||
)
|
||||
GLOBAL_PROTECT(admin_verbs_admin)
|
||||
|
||||
@@ -49,7 +49,10 @@
|
||||
return
|
||||
if(logged)
|
||||
log_admin_private("[key_name(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""]: [text]")
|
||||
message_admins("[key_name_admin(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""]:<br>[text]")
|
||||
var/header = "[key_name_admin(usr)] has created a [type][(type == "note" || type == "message" || type == "watchlist entry") ? " for [target_ckey]" : ""]"
|
||||
message_admins("[header]:<br>[text]")
|
||||
admin_ticket_log(target_ckey, "<font color='blue'>[header]</font>")
|
||||
admin_ticket_log(target_ckey, text)
|
||||
if(browse)
|
||||
browse_messages("[type]")
|
||||
else
|
||||
|
||||
@@ -5,45 +5,19 @@
|
||||
message_admins("[usr.key] has attempted to override the admin panel!")
|
||||
log_admin("[key_name(usr)] tried to use the admin panel without authorization.")
|
||||
return
|
||||
if(href_list["rejectadminhelp"])
|
||||
if(world.time && (spamcooldown > world.time))
|
||||
to_chat(usr, "Please wait [max(round((spamcooldown - world.time)*0.1, 0.1), 0)] seconds.")
|
||||
return
|
||||
if(href_list["ahelp"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/client/C = locate(href_list["rejectadminhelp"]) in GLOB.clients
|
||||
if(!C)
|
||||
return
|
||||
if (deltimer(C.adminhelptimerid))
|
||||
C.giveadminhelpverb()
|
||||
|
||||
var/ahelp_ref = href_list["ahelp"]
|
||||
var/datum/admin_help/AH = locate(ahelp_ref)
|
||||
if(AH)
|
||||
AH.Action(href_list["ahelp_action"])
|
||||
else
|
||||
to_chat(usr, "Ticket [ahelp_ref] has been deleted!")
|
||||
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
to_chat(C, "<font color='red' size='4'><b>- AdminHelp Rejected! -</b></font>")
|
||||
to_chat(C, "<font color='red'><b>Your admin help was rejected.</b> The adminhelp verb has been returned to you so that you may try again.</font>")
|
||||
to_chat(C, "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.")
|
||||
|
||||
message_admins("[key_name_admin(usr)] Rejected [C.key]'s admin help. [C.key]'s Adminhelp verb has been returned to them.")
|
||||
log_admin_private("[key_name(usr)] Rejected [C.key]'s admin help.")
|
||||
spamcooldown = world.time + 150 // 15 seconds
|
||||
|
||||
else if(href_list["icissue"])
|
||||
if(world.time && spamcooldown > world.time)
|
||||
to_chat(usr, "Please wait [max(round((spamcooldown - world.time)*0.1, 0.1), 0)] seconds.")
|
||||
return
|
||||
var/client/C = locate(href_list["icissue"]) in GLOB.clients
|
||||
if(!C)
|
||||
return
|
||||
|
||||
var/msg = "<font color='red' size='4'><b>- AdminHelp marked as IC issue! -</b></font><br>"
|
||||
msg += "<font color='red'><b>Losing is part of the game!</b></font><br>"
|
||||
msg += "<font color='red'>Your character will frequently die, sometimes without even a possibility of avoiding it. Events will often be out of your control. No matter how good or prepared you are, sometimes you just lose.</font>"
|
||||
|
||||
to_chat(C, msg)
|
||||
|
||||
message_admins("[key_name_admin(usr)] marked [C.key]'s admin help as an IC issue.")
|
||||
log_admin_private("[key_name(usr)] marked [C.key]'s admin help as an IC issue.")
|
||||
spamcooldown = world.time + 150 // 15 seconds
|
||||
else if(href_list["ahelp_tickets"])
|
||||
GLOB.ahelp_tickets.BrowseTickets(text2num(href_list["ahelp_tickets"]))
|
||||
|
||||
else if(href_list["stickyban"])
|
||||
stickyban(href_list["stickyban"],href_list)
|
||||
@@ -1149,8 +1123,11 @@
|
||||
else
|
||||
to_chat(M, "<span class='danger'>No ban appeals URL has been set.</span>")
|
||||
log_admin_private("[key_name(usr)] has banned [M.ckey].\nReason: [key_name(M)]\nThis will be removed in [mins] minutes.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis will be removed in [mins] minutes.</span>")
|
||||
|
||||
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis will be removed in [mins] minutes.</span>"
|
||||
message_admins(msg)
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
qdel(M.client)
|
||||
if("No")
|
||||
var/reason = input(usr,"Please State Reason.","Reason") as message|null
|
||||
@@ -1174,7 +1151,11 @@
|
||||
return
|
||||
ban_unban_log_save("[key_name(usr)] has permabanned [key_name(M)]. - Reason: [reason] - This is a permanent ban.")
|
||||
log_admin_private("[key_name(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis is a permanent ban.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis is a permanent ban.</span>")
|
||||
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has banned [key_name_admin(M)].\nReason: [reason]\nThis is a permanent ban.</span>"
|
||||
message_admins(msg)
|
||||
var/datum/admin_help/AH = M.client ? M.client.current_ticket : null
|
||||
if(AH)
|
||||
AH.Resolve()
|
||||
feedback_inc("ban_perma",1)
|
||||
qdel(M.client)
|
||||
if("Cancel")
|
||||
|
||||
@@ -1,3 +1,602 @@
|
||||
/client/var/adminhelptimerid = 0 //a timer id for returning the ahelp verb
|
||||
/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)
|
||||
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='?_src_=holder;ahelp_tickets=[state]'>Refresh</A><br><br>"
|
||||
for(var/I in l2b)
|
||||
var/datum/admin_help/AH = I
|
||||
dat += "<span class='adminnotice'><span class='adminhelp'>Ticket #[AH.id]</span>: <A HREF='?_src_=holder;ahelp=\ref[AH];ahelp_action=ticket'>[AH.initiator_key_name]: [AH.name]</A></span><br>"
|
||||
|
||||
usr << browse(dat.Join(), "window=ahelp_list[state];size=600x480")
|
||||
|
||||
//Tickets statpanel
|
||||
/datum/admin_help_tickets/proc/stat_entry()
|
||||
var/num_disconnected = 0
|
||||
stat("Active Tickets:", astatclick.update("[active_tickets.len]"))
|
||||
for(var/I in active_tickets)
|
||||
var/datum/admin_help/AH = I
|
||||
if(AH.initiator)
|
||||
stat("#[AH.id]. [AH.initiator_key_name]:", AH.statclick.update())
|
||||
else
|
||||
++num_disconnected
|
||||
if(num_disconnected)
|
||||
stat("Disconnected:", astatclick.update("[num_disconnected]"))
|
||||
stat("Closed Tickets:", cstatclick.update("[closed_tickets.len]"))
|
||||
stat("Resolved Tickets:", rstatclick.update("[resolved_tickets.len]"))
|
||||
|
||||
//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.")
|
||||
|
||||
//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/I in active_tickets)
|
||||
var/datum/admin_help/AH = I
|
||||
if(AH.initiator_ckey == ckey)
|
||||
return AH
|
||||
|
||||
//
|
||||
//TICKET LIST STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ticket_list
|
||||
var/current_state
|
||||
|
||||
/obj/effect/statclick/ticket_list/New(loc, name, state)
|
||||
current_state = state
|
||||
..()
|
||||
|
||||
/obj/effect/statclick/ticket_list/Click()
|
||||
GLOB.ahelp_tickets.BrowseTickets(current_state)
|
||||
|
||||
//
|
||||
//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
|
||||
stack_trace("Multiple ahelp current_tickets")
|
||||
initiator.current_ticket.AddInteraction("Ticket erroneously left open by code")
|
||||
initiator.current_ticket.Close()
|
||||
initiator.current_ticket = src
|
||||
|
||||
TimeoutVerb()
|
||||
|
||||
var/parsed_message = keywords_lookup(msg)
|
||||
|
||||
statclick = new(null, src)
|
||||
_interactions = list()
|
||||
|
||||
if(is_bwoink)
|
||||
AddInteraction("<font color='blue'>[key_name_admin(usr)] PM'd [LinkedReplyName()]</font>")
|
||||
message_admins("<font color='blue'>Ticket [TicketHref("#[id]")] created</font>")
|
||||
else
|
||||
MessageNoRecipient(parsed_message)
|
||||
|
||||
//show it to the person adminhelping too
|
||||
to_chat(C, "<span class='adminnotice'>PM to-<b>Admins</b>: [name]</span>")
|
||||
|
||||
//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_private("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 class='notice'>No active admins are online, your adminhelp was sent to the admin irc.</span>")
|
||||
|
||||
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]"
|
||||
|
||||
//Removes the ahelp verb and returns it after 2 minutes
|
||||
/datum/admin_help/proc/TimeoutVerb()
|
||||
initiator.verbs -= /client/verb/adminhelp
|
||||
initiator.adminhelptimerid = addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/FullMonty(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = ADMIN_FULLMONTY_NONAME(initiator.mob)
|
||||
if(state == AHELP_ACTIVE)
|
||||
. += ClosureLinks(ref_src)
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/ClosureLinks(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
. = " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=reject'>REJT</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=icissue'>IC</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=close'>CLOSE</A>)"
|
||||
. += " (<A HREF='?_src_=holder;ahelp=[ref_src];ahelp_action=resolve'>RSLVE</A>)"
|
||||
|
||||
//private
|
||||
/datum/admin_help/proc/LinkedReplyName(ref_src)
|
||||
if(!ref_src)
|
||||
ref_src = "\ref[src]"
|
||||
return "<A HREF='?_src_=holder;ahelp=[ref_src];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='?_src_=holder;ahelp=[ref_src];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 class='adminnotice'><span class='adminhelp'>Ticket [TicketHref("#[id]", ref_src)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> [msg]</span>"
|
||||
|
||||
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
window_flash(X, ignorepref = TRUE)
|
||||
to_chat(X, chat_msg)
|
||||
|
||||
//Reopen a closed ticket
|
||||
/datum/admin_help/proc/Reopen()
|
||||
if(state == AHELP_ACTIVE)
|
||||
to_chat(usr, "<span class='warning'>This ticket is already open.</span>")
|
||||
return
|
||||
|
||||
if(GLOB.ahelp_tickets.CKey2ActiveTicket(initiator_ckey))
|
||||
to_chat(usr, "<span class='warning'>This user already has an active ticket, cannot reopen this one.</span>")
|
||||
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("<font color='purple'>Reopened by [key_name_admin(usr)]</font>")
|
||||
var/msg = "<span class='adminhelp'>Ticket [TicketHref("#[id]")] reopened by [key_name_admin(usr)].</span>"
|
||||
message_admins(msg)
|
||||
log_admin_private(msg)
|
||||
feedback_inc("ahelp_reopen")
|
||||
TicketPanel() //can only be done from here, so refresh it
|
||||
|
||||
//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(key_name = key_name_admin(usr), silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_CLOSED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
AddInteraction("<font color='red'>Closed by [key_name].</font>")
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_close")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] closed by [key_name]."
|
||||
message_admins(msg)
|
||||
log_admin_private(msg)
|
||||
|
||||
//Mark open ticket as resolved/legitimate, returns ahelp verb
|
||||
/datum/admin_help/proc/Resolve(key_name = key_name_admin(usr), silent = FALSE)
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
RemoveActive()
|
||||
state = AHELP_RESOLVED
|
||||
GLOB.ahelp_tickets.ListInsert(src)
|
||||
|
||||
if(initiator)
|
||||
initiator.giveadminhelpverb()
|
||||
|
||||
AddInteraction("<font color='green'>Resolved by [key_name].</font>")
|
||||
if(!silent)
|
||||
feedback_inc("ahelp_resolve")
|
||||
var/msg = "Ticket [TicketHref("#[id]")] resolved by [key_name]"
|
||||
message_admins(msg)
|
||||
log_admin_private(msg)
|
||||
|
||||
//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)
|
||||
initiator.giveadminhelpverb()
|
||||
|
||||
initiator << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
to_chat(initiator, "<font color='red' size='4'><b>- AdminHelp Rejected! -</b></font>")
|
||||
to_chat(initiator, "<font color='red'><b>Your admin help was rejected.</b> The adminhelp verb has been returned to you so that you may try again.</font>")
|
||||
to_chat(initiator, "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]"
|
||||
message_admins(msg)
|
||||
log_admin_private(msg)
|
||||
AddInteraction("Rejected by [key_name].")
|
||||
Close(silent = TRUE)
|
||||
|
||||
//Resolve ticket with IC Issue message
|
||||
/datum/admin_help/proc/ICIssue(key_name = key_name_admin(usr))
|
||||
if(state != AHELP_ACTIVE)
|
||||
return
|
||||
|
||||
var/msg = "<font color='red' size='4'><b>- AdminHelp marked as IC issue! -</b></font><br>"
|
||||
msg += "<font color='red'><b>Losing is part of the game!</b></font><br>"
|
||||
msg += "<font color='red'>Your character will frequently die, sometimes without even a possibility of avoiding it. Events will often be out of your control. No matter how good or prepared you are, sometimes you just lose.</font>"
|
||||
|
||||
if(initiator)
|
||||
to_chat(initiator, msg)
|
||||
|
||||
feedback_inc("ahelp_icissue")
|
||||
msg = "Ticket [TicketHref("#[id]")] marked as IC by [key_name]"
|
||||
message_admins(msg)
|
||||
log_admin_private(msg)
|
||||
AddInteraction("Marked as IC issue by [key_name]")
|
||||
Resolve(silent = TRUE)
|
||||
|
||||
//Show the ticket panel
|
||||
/datum/admin_help/proc/TicketPanel()
|
||||
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 += "<b>State: "
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
dat += "<font color='red'>OPEN</font>"
|
||||
if(AHELP_RESOLVED)
|
||||
dat += "<font color='green'>RESOLVED</font>"
|
||||
if(AHELP_CLOSED)
|
||||
dat += "CLOSED"
|
||||
else
|
||||
dat += "UNKNOWN"
|
||||
dat += "</b>[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 += "<b>Actions:</b> [FullMonty(ref_src)]<br>"
|
||||
else
|
||||
dat += "<b>DISCONNECTED</b>[GLOB.TAB][ClosureLinks(ref_src)]<br>"
|
||||
dat += "<br><b>Log:</b><br><br>"
|
||||
for(var/I in _interactions)
|
||||
dat += "[I]<br>"
|
||||
|
||||
usr << browse(dat.Join(), "window=ahelp[id];size=620x480")
|
||||
|
||||
/datum/admin_help/proc/Retitle()
|
||||
var/new_title = input(usr, "Enter a title for the ticket", "Rename Ticket", name) as text|null
|
||||
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_private(msg)
|
||||
TicketPanel() //we have to be here to do this
|
||||
|
||||
//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("reopen")
|
||||
Reopen()
|
||||
|
||||
//
|
||||
// TICKET STATCLICK
|
||||
//
|
||||
|
||||
/obj/effect/statclick/ahelp
|
||||
var/datum/admin_help/ahelp_datum
|
||||
|
||||
/obj/effect/statclick/ahelp/New(loc, datum/admin_help/AH)
|
||||
ahelp_datum = AH
|
||||
..(loc)
|
||||
|
||||
/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/proc/giveadminhelpverb()
|
||||
src.verbs |= /client/verb/adminhelp
|
||||
deltimer(adminhelptimerid)
|
||||
adminhelptimerid = 0
|
||||
|
||||
/client/verb/adminhelp(msg as text)
|
||||
set category = "Admin"
|
||||
set name = "Adminhelp"
|
||||
|
||||
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: You cannot send adminhelps (Muted).</span>")
|
||||
return
|
||||
if(handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
|
||||
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)
|
||||
if(alert(usr, "You already have a ticket open. Is this for the same issue?",,"Yes","No") != "No")
|
||||
if(current_ticket)
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
current_ticket.TimeoutVerb()
|
||||
return
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>Ticket not found, creating new one...</span>")
|
||||
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"
|
||||
|
||||
if(!check_rights(R_ADMIN, TRUE))
|
||||
return
|
||||
|
||||
var/browse_to
|
||||
|
||||
switch(input("Display which ticket list?") as null|anything in 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(requiredflags)
|
||||
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)
|
||||
send2otherserver(source,final)
|
||||
|
||||
|
||||
/proc/send2irc(msg,msg2)
|
||||
if(config.useircbot)
|
||||
shell("python nudge.py [msg] [msg2]")
|
||||
return
|
||||
|
||||
/proc/send2otherserver(source,msg,type = "Ahelp")
|
||||
if(config.cross_allowed)
|
||||
var/list/message = list()
|
||||
message["message_sender"] = source
|
||||
message["message"] = msg
|
||||
message["source"] = "([config.cross_name])"
|
||||
message["key"] = global.comms_key
|
||||
message["crossmessage"] = type
|
||||
|
||||
world.Export("[config.cross_address]?[list2params(message)]")
|
||||
|
||||
|
||||
/proc/ircadminwho()
|
||||
var/list/message = list("Admins: ")
|
||||
var/list/admin_keys = list()
|
||||
for(var/adm in GLOB.admins)
|
||||
var/client/C = adm
|
||||
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!
|
||||
@@ -68,127 +667,3 @@
|
||||
return founds
|
||||
|
||||
return msg
|
||||
|
||||
|
||||
/client/var/adminhelptimerid = 0
|
||||
|
||||
/client/proc/giveadminhelpverb()
|
||||
src.verbs |= /client/verb/adminhelp
|
||||
adminhelptimerid = 0
|
||||
|
||||
/client/verb/adminhelp(msg as text)
|
||||
set category = "Admin"
|
||||
set name = "Adminhelp"
|
||||
|
||||
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
|
||||
//handle muting and automuting
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<span class='danger'>Error: Admin-PM: You cannot send adminhelps (Muted).</span>")
|
||||
return
|
||||
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
return
|
||||
|
||||
//clean the input msg
|
||||
if(!msg)
|
||||
return
|
||||
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
|
||||
if(!msg) return
|
||||
var/original_msg = msg
|
||||
|
||||
//remove our adminhelp verb temporarily to prevent spamming of admins.
|
||||
src.verbs -= /client/verb/adminhelp
|
||||
adminhelptimerid = addtimer(CALLBACK(src, .proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
|
||||
|
||||
msg = keywords_lookup(msg)
|
||||
|
||||
if(!mob)
|
||||
return //this doesn't happen
|
||||
|
||||
var/ref_client = "\ref[src]"
|
||||
msg = "<span class='adminnotice'><b><font color=red>HELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> [ADMIN_FULLMONTY_NONAME(mob)] [ADMIN_SMITE(mob)] (<A HREF='?_src_=holder;rejectadminhelp=[ref_client]'>REJT</A>) (<A HREF='?_src_=holder;icissue=[ref_client]'>IC</A>):</b> [msg]</span>"
|
||||
|
||||
//send this msg to all admins
|
||||
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(X.prefs.toggles & SOUND_ADMINHELP)
|
||||
X << 'sound/effects/adminhelp.ogg'
|
||||
window_flash(X, ignorepref = TRUE)
|
||||
to_chat(X, msg)
|
||||
|
||||
|
||||
//show it to the person adminhelping too
|
||||
to_chat(src, "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>")
|
||||
|
||||
//send it to irc if nobody is on and tell us how many were on
|
||||
var/admin_number_present = send2irc_adminless_only(ckey,original_msg)
|
||||
log_admin_private("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
|
||||
if(admin_number_present <= 0)
|
||||
to_chat(src, "<span class='notice'>No active admins are online, your adminhelp was sent to the admin irc.</span>")
|
||||
feedback_add_details("admin_verb","Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
/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(requiredflags)
|
||||
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)
|
||||
send2otherserver(source,final)
|
||||
|
||||
|
||||
/proc/send2irc(msg,msg2)
|
||||
if(config.useircbot)
|
||||
shell("python nudge.py [msg] [msg2]")
|
||||
return
|
||||
|
||||
/proc/send2otherserver(source,msg,type = "Ahelp")
|
||||
if(config.cross_allowed)
|
||||
var/list/message = list()
|
||||
message["message_sender"] = source
|
||||
message["message"] = msg
|
||||
message["source"] = "([config.cross_name])"
|
||||
message["key"] = global.comms_key
|
||||
message["crossmessage"] = type
|
||||
|
||||
world.Export("[config.cross_address]?[list2params(message)]")
|
||||
|
||||
|
||||
/proc/ircadminwho()
|
||||
var/list/message = list("Admins: ")
|
||||
var/list/admin_keys = list()
|
||||
for(var/adm in GLOB.admins)
|
||||
var/client/C = adm
|
||||
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, "")
|
||||
|
||||
@@ -104,9 +104,12 @@
|
||||
to_chat(src, "Only administrators may use this command.")
|
||||
return
|
||||
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)]")
|
||||
M.forceMove(get_turf(usr))
|
||||
var/atom/loc = get_turf(usr)
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)] to [COORD(loc)]")
|
||||
var/msg = "[key_name_admin(usr)] teleported [key_name_admin(M)] to [ADMIN_COORDJMP(loc)]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
M.forceMove(loc)
|
||||
feedback_add_details("admin_verb","Get Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/Getkey()
|
||||
@@ -129,7 +132,9 @@
|
||||
if(!M)
|
||||
return
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name(M)]")
|
||||
var/msg = "[key_name_admin(usr)] teleported [key_name_admin(M)]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
if(M)
|
||||
M.forceMove(get_turf(usr))
|
||||
usr.loc = M.loc
|
||||
@@ -146,7 +151,9 @@
|
||||
if(M.forceMove(safepick(get_area_turfs(A))))
|
||||
|
||||
log_admin("[key_name(usr)] teleported [key_name(M)] to [A]")
|
||||
message_admins("[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]")
|
||||
var/msg = "[key_name_admin(usr)] teleported [key_name_admin(M)] to [A]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
else
|
||||
to_chat(src, "Failed to move mob to a valid location.")
|
||||
feedback_add_details("admin_verb","Send Mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -50,21 +50,30 @@
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
return
|
||||
message_admins("[key_name_admin(src)] has started replying to [key_name(C, 0, 0)]'s admin help.")
|
||||
|
||||
var/datum/admin_help/AH = C.current_ticket
|
||||
|
||||
if(AH)
|
||||
message_admins("[key_name_admin(src)] has started replying to [key_name(C, 0, 0)]'s admin help.")
|
||||
var/msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
|
||||
if (!msg)
|
||||
message_admins("[key_name_admin(src)] has cancelled their reply to [key_name(C, 0, 0)]'s admin help.")
|
||||
return
|
||||
cmd_admin_pm(whom, msg)
|
||||
cmd_admin_pm(whom, msg, AH)
|
||||
|
||||
//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)
|
||||
/client/proc/cmd_admin_pm(whom, msg, datum/admin_help/AH)
|
||||
if(prefs.muted & MUTE_ADMINHELP)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>")
|
||||
return
|
||||
|
||||
var/client/C
|
||||
if(!holder && !current_ticket) //no ticket? https://www.youtube.com/watch?v=iHSPf6x1Fdo
|
||||
to_chat(src, "<font color='red'>You can no longer reply to this ticket, please open another one by using the Adminhelp verb if need be.</font>")
|
||||
to_chat(src, "<font color='blue'>Message: [msg]</font>")
|
||||
return
|
||||
|
||||
var/client/recipient
|
||||
var/irc = 0
|
||||
if(istext(whom))
|
||||
if(cmptext(copytext(whom,1,2),"@"))
|
||||
@@ -72,9 +81,11 @@
|
||||
if(whom == "IRCKEY")
|
||||
irc = 1
|
||||
else
|
||||
C = GLOB.directory[whom]
|
||||
recipient = GLOB.directory[whom]
|
||||
else if(istype(whom,/client))
|
||||
C = whom
|
||||
recipient = whom
|
||||
|
||||
|
||||
if(irc)
|
||||
if(!ircreplyamount) //to prevent people from spamming irc
|
||||
return
|
||||
@@ -89,16 +100,16 @@
|
||||
|
||||
|
||||
else
|
||||
if(!C)
|
||||
if(!recipient)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
else
|
||||
adminhelp(msg) //admin we are replying to left. adminhelp instead
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
//get message text, limit it's length.and clean/escape html
|
||||
if(!msg)
|
||||
msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
|
||||
msg = input(src,"Message:", "Private message to [key_name(recipient, 0, 0)]") as text|null
|
||||
|
||||
if(!msg)
|
||||
return
|
||||
@@ -107,11 +118,11 @@
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: You are unable to use admin PM-s (muted).</font>")
|
||||
return
|
||||
|
||||
if(!C)
|
||||
if(!recipient)
|
||||
if(holder)
|
||||
to_chat(src, "<font color='red'>Error: Admin-PM: Client not found.</font>")
|
||||
else
|
||||
adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
|
||||
current_ticket.MessageNoRecipient(msg)
|
||||
return
|
||||
|
||||
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
|
||||
@@ -132,41 +143,55 @@
|
||||
|
||||
if(irc)
|
||||
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [rawmsg]</font>")
|
||||
admin_ticket_log(src, "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, TRUE)] to <i>IRC</i>: [keywordparsedmsg]</font>")
|
||||
ircreplyamount--
|
||||
send2irc("Reply: [ckey]",rawmsg)
|
||||
else
|
||||
if(C.holder)
|
||||
if(recipient.holder)
|
||||
if(holder) //both are admins
|
||||
to_chat(C, "<font color='red'>Admin PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
|
||||
//omg this is dumb, just fill in both their tickets
|
||||
var/interaction_message = "<font color='purple'>PM from-<b>[key_name(src, recipient, 1)]</b> to-<b>[key_name(recipient, src, 1)]</b>: [keywordparsedmsg]</font>"
|
||||
admin_ticket_log(src, interaction_message)
|
||||
if(recipient != src) //reeee
|
||||
admin_ticket_log(recipient, interaction_message)
|
||||
|
||||
else //recipient is an admin but sender is not
|
||||
to_chat(C, "<font color='red'>Reply PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>")
|
||||
var/replymsg = "<font color='red'>Reply PM from-<b>[key_name(src, recipient, 1)]</b>: [keywordparsedmsg]</font>"
|
||||
admin_ticket_log(src, replymsg)
|
||||
to_chat(recipient, replymsg)
|
||||
to_chat(src, "<font color='blue'>PM to-<b>Admins</b>: [msg]</font>")
|
||||
|
||||
//play the recieving admin the adminhelp sound (if they have them enabled)
|
||||
if(C.prefs.toggles & SOUND_ADMINHELP)
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
if(recipient.prefs.toggles & SOUND_ADMINHELP)
|
||||
recipient << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
else
|
||||
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
|
||||
to_chat(C, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
|
||||
to_chat(C, "<font color='red'>Admin PM from-<b>[key_name(src, C, 0)]</b>: [msg]</font>")
|
||||
to_chat(C, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>")
|
||||
if(!recipient.current_ticket)
|
||||
new /datum/admin_help(msg, recipient, TRUE)
|
||||
|
||||
to_chat(recipient, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
|
||||
to_chat(recipient, "<font color='red'>Admin PM from-<b>[key_name(src, recipient, 0)]</b>: [msg]</font>")
|
||||
to_chat(recipient, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
|
||||
to_chat(src, "<font color='blue'>Admin PM to-<b>[key_name(recipient, src, 1)]</b>: [msg]</font>")
|
||||
|
||||
admin_ticket_log(recipient, "<font color='blue'>PM From [key_name_admin(src)]: [keywordparsedmsg]</font>")
|
||||
|
||||
//always play non-admin recipients the adminhelp sound
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
recipient << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
//AdminPM popup for ApocStation and anybody else who wants to use it. Set it with POPUP_ADMIN_PM in config.txt ~Carn
|
||||
if(config.popup_admin_pm)
|
||||
spawn() //so we don't hold the caller proc up
|
||||
var/sender = src
|
||||
var/sendername = key
|
||||
var/reply = input(C, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
|
||||
if(C && reply)
|
||||
var/reply = input(recipient, msg,"Admin PM from-[sendername]", "") as text|null //show message and await a reply
|
||||
if(recipient && reply)
|
||||
if(sender)
|
||||
C.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
|
||||
recipient.cmd_admin_pm(sender,reply) //sender is still about, let's reply to them
|
||||
else
|
||||
adminhelp(reply) //sender has left, adminhelp instead
|
||||
return
|
||||
@@ -180,22 +205,47 @@
|
||||
for(var/client/X in GLOB.admins)
|
||||
to_chat(X, "<B><font color='blue'>PM: [key_name(src, X, 0)]->IRC:</B> \blue [keywordparsedmsg]</font>" )
|
||||
else
|
||||
window_flash(C, ignorepref = TRUE)
|
||||
log_admin_private("PM: [key_name(src)]->[key_name(C)]: [rawmsg]")
|
||||
window_flash(recipient, ignorepref = TRUE)
|
||||
log_admin_private("PM: [key_name(src)]->[key_name(recipient)]: [rawmsg]")
|
||||
//we don't use message_admins here because the sender/receiver might get it too
|
||||
for(var/client/X in GLOB.admins)
|
||||
if(X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
|
||||
to_chat(X, "<B><font color='blue'>PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" )
|
||||
if(X.key!=key && X.key!=recipient.key) //check client/X is an admin and isn't the sender or recipient
|
||||
to_chat(X, "<B><font color='blue'>PM: [key_name(src, X, 0)]->[key_name(recipient, X, 0)]:</B> \blue [keywordparsedmsg]</font>" )
|
||||
|
||||
|
||||
|
||||
|
||||
/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/compliant_msg = trim(lowertext(msg))
|
||||
var/unhandled = FALSE
|
||||
var/irc_tagged = "[sender](IRC)"
|
||||
switch(compliant_msg)
|
||||
if("ticket close")
|
||||
if(ticket)
|
||||
ticket.Close(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully closed"
|
||||
if("ticket resolve")
|
||||
if(ticket)
|
||||
ticket.Resolve(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully resolved"
|
||||
if("ticket ic")
|
||||
if(ticket)
|
||||
ticket.ICIssue(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully marked as IC issue"
|
||||
if("ticket reject")
|
||||
if(ticket)
|
||||
ticket.Reject(irc_tagged)
|
||||
return "Ticket #[ticket.id] successfully rejected"
|
||||
else
|
||||
unhandled = TRUE
|
||||
if(!unhandled)
|
||||
return "Ticket could not be found"
|
||||
|
||||
var/static/stealthkey
|
||||
var/adminname = config.showircname ? "[sender](IRC)" : "Administrator"
|
||||
var/adminname = config.showircname ? irc_tagged : "Administrator"
|
||||
|
||||
if(!C)
|
||||
return "No client"
|
||||
@@ -214,6 +264,9 @@
|
||||
to_chat(C, "<font color='red' size='4'><b>-- Administrator private message --</b></font>")
|
||||
to_chat(C, "<font color='red'>Admin PM from-<b><a href='?priv_msg=[stealthkey]'>[adminname]</A></b>: [msg]</font>")
|
||||
to_chat(C, "<font color='red'><i>Click on the administrator's name to reply.</i></font>")
|
||||
|
||||
admin_ticket_log(C, "<font color='blue'>PM From [irc_tagged]: [msg]</font>")
|
||||
|
||||
window_flash(C, ignorepref = TRUE)
|
||||
//always play non-admin recipients the adminhelp sound
|
||||
C << 'sound/effects/adminhelp.ogg'
|
||||
|
||||
@@ -68,8 +68,10 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
|
||||
if(!target)
|
||||
to_chat(usr, "<font color='red'>Error: callproc(): owner of proc no longer exists.</font>")
|
||||
return
|
||||
log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
message_admins("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
var/msg = "[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
log_admin(msg)
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target, msg)
|
||||
returnval = WrapAdminProcCall(target, procname, lst) // Pass the lst as an argument list to the proc
|
||||
else
|
||||
//this currently has no hascall protection. wasn't able to get it working.
|
||||
@@ -125,7 +127,9 @@ GLOBAL_PROTECT(AdminProcCall)
|
||||
to_chat(usr, "<span class='warning'>Error: callproc_datum(): owner of proc no longer exists.</span>")
|
||||
return
|
||||
log_admin("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
message_admins("[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].")
|
||||
var/msg = "[key_name(src)] called [A]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(A, msg)
|
||||
feedback_add_details("admin_verb","Atom ProcCall") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
var/returnval = WrapAdminProcCall(A, procname, lst) // Pass the lst as an argument list to the proc
|
||||
|
||||
@@ -614,4 +614,6 @@ GLOBAL_PROTECT(VVpixelmovement)
|
||||
return
|
||||
log_world("### VarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]")
|
||||
log_admin("[key_name(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
message_admins("[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]")
|
||||
var/msg = "[key_name_admin(src)] modified [original_name]'s [variable] to [O.vars[variable]]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(O, msg)
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
prayer_type = "CULTIST PRAYER"
|
||||
deity = "Nar-Sie"
|
||||
|
||||
msg = "<span class='adminnotice'>\icon[cross]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)] [ADMIN_SMITE(src)]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'>\icon[cross]<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> [msg]</span>"
|
||||
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(C.prefs.chat_toggles & CHAT_PRAYER)
|
||||
@@ -48,21 +48,21 @@
|
||||
|
||||
/proc/Centcomm_announce(text , mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SMITE(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
|
||||
/proc/Syndicate_announce(text , mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SMITE(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SYNDICATE_REPLY(Sender)]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
|
||||
/proc/Nuke_request(text , mob/Sender)
|
||||
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_SMITE(Sender)] [ADMIN_CENTCOM_REPLY(Sender)] [ADMIN_SET_SD_CODE]:</b> [msg]</span>"
|
||||
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[ADMIN_FULLMONTY(Sender)] [ADMIN_CENTCOM_REPLY(Sender)] [ADMIN_SET_SD_CODE]:</b> [msg]</span>"
|
||||
to_chat(GLOB.admins, msg)
|
||||
for(var/obj/machinery/computer/communications/C in GLOB.machines)
|
||||
C.overrideCooldown()
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
M.regenerate_icons()
|
||||
|
||||
log_admin("[key_name(usr)] made [key_name(M)] drop everything!")
|
||||
message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!")
|
||||
var/msg = "[key_name_admin(usr)] made [key_name_admin(M)] drop everything!"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","Drop Everything") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
/client/proc/cmd_admin_subtle_message(mob/M in GLOB.mob_list)
|
||||
set category = "Special Verbs"
|
||||
set name = "Subtle Message"
|
||||
@@ -41,7 +42,9 @@
|
||||
to_chat(M, "<i>You hear a voice in your head... <b>[msg]</i></b>")
|
||||
|
||||
log_admin("SubtlePM: [key_name(usr)] -> [key_name(M)] : [msg]")
|
||||
message_admins("<span class='adminnotice'><b> SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] :</b> [msg]</span>")
|
||||
msg = "<span class='adminnotice'><b> SubtleMessage: [key_name_admin(usr)] -> [key_name_admin(M)] :</b> [msg]</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","Subtle Message") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_world_narrate()
|
||||
@@ -82,7 +85,9 @@
|
||||
|
||||
to_chat(M, msg)
|
||||
log_admin("DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]): [msg]")
|
||||
message_admins("<span class='adminnotice'><b> DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]):</b> [msg]<BR></span>")
|
||||
msg = "<span class='adminnotice'><b> DirectNarrate: [key_name(usr)] to ([M.name]/[M.key]):</b> [msg]<BR></span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","Direct Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_local_narrate(atom/A)
|
||||
@@ -117,7 +122,9 @@
|
||||
to_chat(usr, "<span class='adminnotice'>Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]</span>")
|
||||
|
||||
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"]")
|
||||
var/msg = "[key_name_admin(usr)] has toggled [key_name_admin(M)]'s nodamage to [(M.status_flags & GODMODE) ? "On" : "Off"]"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_toggle","Godmode|[M.status_flags & GODMODE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -238,7 +245,9 @@
|
||||
return 0
|
||||
|
||||
new_xeno.ckey = ckey
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].</span>")
|
||||
var/msg = "<span class='notice'>[key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(new_xeno, msg)
|
||||
return 1
|
||||
|
||||
/*
|
||||
@@ -297,7 +306,9 @@ 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("<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.</span>")
|
||||
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(new_xeno, msg)
|
||||
return //all done. The ghost is auto-deleted
|
||||
|
||||
//check if they were a monkey
|
||||
@@ -307,7 +318,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
|
||||
new_monkey.key = G_found.key
|
||||
to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.</span>")
|
||||
var/msg = "<span class='adminnotice'>[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(new_monkey, msg)
|
||||
return //all done. The ghost is auto-deleted
|
||||
|
||||
|
||||
@@ -404,7 +417,9 @@ 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?",,"No","Yes")=="Yes")
|
||||
AnnounceArrival(new_character, new_character.mind.assigned_role)
|
||||
|
||||
message_admins("<span class='adminnotice'>[admin] has respawned [player_key] as [new_character.real_name].</span>")
|
||||
var/msg = "<span class='adminnotice'>[admin] has respawned [player_key] as [new_character.real_name].</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(new_character, msg)
|
||||
|
||||
to_chat(new_character, "You have been fully respawned. Enjoy the game.")
|
||||
|
||||
@@ -447,7 +462,9 @@ Traitors and the like can also be revived with the previous role mostly intact.
|
||||
M.revive(full_heal = 1, admin_revive = 1)
|
||||
|
||||
log_admin("[key_name(usr)] healed / revived [key_name(M)]")
|
||||
message_admins("<span class='danger'>Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!</span>")
|
||||
var/msg = "<span class='danger'>Admin [key_name_admin(usr)] healed / revived [key_name_admin(M)]!</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(M, msg)
|
||||
feedback_add_details("admin_verb","Rejuvinate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_create_centcom_report()
|
||||
@@ -1169,5 +1186,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
|
||||
if(ADMIN_PUNISHMENT_BSA)
|
||||
bluespace_artillery(target)
|
||||
|
||||
message_admins("[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment].")
|
||||
var/msg = "[key_name_admin(usr)] punished [key_name_admin(target)] with [punishment]."
|
||||
message_admins(msg)
|
||||
admin_ticket_log(target, msg)
|
||||
log_admin("[key_name(usr)] punished [key_name(target)] with [punishment].")
|
||||
|
||||
@@ -75,9 +75,6 @@
|
||||
|
||||
// Admin PM
|
||||
if(href_list["priv_msg"])
|
||||
if (href_list["ahelp_reply"])
|
||||
cmd_ahelp_reply(href_list["priv_msg"])
|
||||
return
|
||||
cmd_admin_pm(href_list["priv_msg"],null)
|
||||
return
|
||||
|
||||
@@ -159,6 +156,8 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
GLOB.clients += src
|
||||
GLOB.directory[ckey] = src
|
||||
|
||||
GLOB.ahelp_tickets.ClientLogin(src)
|
||||
|
||||
//Admin Authorisation
|
||||
var/localhost_addresses = list("127.0.0.1", "::1")
|
||||
if(address && (address in localhost_addresses))
|
||||
@@ -340,6 +339,8 @@ GLOBAL_LIST(external_rsc_urls)
|
||||
adminGreet(1)
|
||||
holder.owner = null
|
||||
GLOB.admins -= src
|
||||
|
||||
GLOB.ahelp_tickets.ClientLogout(src)
|
||||
GLOB.directory -= ckey
|
||||
GLOB.clients -= src
|
||||
if(movingmob != null)
|
||||
|
||||
@@ -566,7 +566,6 @@
|
||||
if(ETA)
|
||||
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
|
||||
|
||||
|
||||
if(client && client.holder)
|
||||
if(statpanel("MC"))
|
||||
stat("Location:", "([x], [y], [z])")
|
||||
@@ -588,6 +587,8 @@
|
||||
for(var/datum/controller/subsystem/SS in Master.subsystems)
|
||||
SS.stat_entry()
|
||||
GLOB.cameranet.stat_entry()
|
||||
if(statpanel("Tickets"))
|
||||
GLOB.ahelp_tickets.stat_entry()
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
|
||||
@@ -210,6 +210,7 @@
|
||||
/world/proc/OnReboot(reason, feedback_c, feedback_r, round_end_sound_sent)
|
||||
feedback_set_details("[feedback_c]","[feedback_r]")
|
||||
log_game("<span class='boldannounce'>Rebooting World. [reason]</span>")
|
||||
feedback_set("ahelp_unresolved", GLOB.ahelp_tickets.active_tickets.len)
|
||||
if(GLOB.blackbox)
|
||||
GLOB.blackbox.save_all_data_to_sql()
|
||||
Master.Shutdown() //run SS shutdowns
|
||||
|
||||
@@ -66,6 +66,7 @@ h1.alert, h2.alert {color: #000000;}
|
||||
.notice {color: #000099;}
|
||||
.boldnotice {color: #000099; font-weight: bold;}
|
||||
.adminnotice {color: #0000ff;}
|
||||
.adminhelp {color: #ff0000; font-weight: bold;}
|
||||
.unconscious {color: #0000ff; font-weight: bold;}
|
||||
.suicide {color: #ff5050; font-style: italic;}
|
||||
.green {color: #03ff39;}
|
||||
|
||||
Reference in New Issue
Block a user