diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 09f99aa8f38..ac7cdcc4646 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -195,6 +195,8 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
var/list/opening_responders
/// Whether this ahelp has sent a webhook or not, and what type
var/webhook_sent = WEBHOOK_NONE
+ /// List of player interactions
+ var/list/player_interactions
/**
* Call this on its own to create a ticket, don't manually assign current_ticket
@@ -228,9 +230,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
statclick = new(null, src)
ticket_interactions = list()
+ player_interactions = list()
if(is_bwoink)
- AddInteraction("[key_name_admin(usr)] PM'd [LinkedReplyName()]")
+ AddInteraction("[key_name_admin(usr)] PM'd [LinkedReplyName()]", player_message = "[key_name_admin(usr, include_name = FALSE)] PM'd [LinkedReplyName()]")
message_admins("Ticket [TicketHref("#[id]")] created")
else
MessageNoRecipient(msg_raw, urgent)
@@ -342,11 +345,13 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
GLOB.ahelp_tickets.resolved_tickets -= src
return ..()
-/datum/admin_help/proc/AddInteraction(formatted_message)
+/datum/admin_help/proc/AddInteraction(formatted_message, player_message)
if(heard_by_no_admins && usr && usr.ckey != initiator_ckey)
heard_by_no_admins = FALSE
send2adminchat(initiator_ckey, "Ticket #[id]: Answered by [key_name(usr)]")
ticket_interactions += "[time_stamp()]: [formatted_message]"
+ if (!isnull(player_message))
+ player_interactions += "[time_stamp()]: [player_message]"
//Removes the ahelp verb and returns it after 2 minutes
/datum/admin_help/proc/TimeoutVerb()
@@ -392,7 +397,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
//Message to be sent to all admins
var/admin_msg = span_adminnotice(span_adminhelp("Ticket [TicketHref("#[id]", ref_src)]: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]: [keywords_lookup(msg)]"))
- AddInteraction("[LinkedReplyName(ref_src)]: [msg]")
+ AddInteraction("[LinkedReplyName(ref_src)]: [msg]", player_message = "[LinkedReplyName(ref_src)]: [msg]")
log_admin_private("Ticket #[id]: [key_name(initiator)]: [msg]")
//send this msg to all admins
@@ -436,7 +441,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(initiator)
initiator.current_ticket = src
- AddInteraction("Reopened by [key_name_admin(usr)]")
+ AddInteraction("Reopened by [key_name_admin(usr)]", player_message = "Ticket reopened!")
var/msg = span_adminhelp("Ticket [TicketHref("#[id]")] reopened by [key_name_admin(usr)].")
message_admins(msg)
log_admin_private(msg)
@@ -463,7 +468,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
RemoveActive()
state = AHELP_CLOSED
GLOB.ahelp_tickets.ListInsert(src)
- AddInteraction("Closed by [key_name].")
+ AddInteraction("Closed by [key_name].", player_message = "Ticket closed!")
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "closed")
var/msg = "Ticket [TicketHref("#[id]")] closed by [key_name]."
@@ -481,7 +486,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 50)
- AddInteraction("Resolved by [key_name].")
+ AddInteraction("Resolved by [key_name].", player_message = "Ticket resolved!")
to_chat(initiator, span_adminhelp("Your ticket has been resolved by an admin. The Adminhelp verb will be returned to you shortly."), confidential = TRUE)
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "resolved")
@@ -508,7 +513,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
var/msg = "Ticket [TicketHref("#[id]")] rejected by [key_name]"
message_admins(msg)
log_admin_private(msg)
- AddInteraction("Rejected by [key_name].")
+ AddInteraction("Rejected by [key_name].", player_message = "Ticket rejected!")
SSblackbox.LogAhelp(id, "Rejected", "Rejected by [usr.key]", null, usr.ckey)
Close(silent = TRUE)
@@ -527,7 +532,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
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]")
+ AddInteraction("Marked as IC issue by [key_name]", player_message = "Marked as IC issue!")
SSblackbox.LogAhelp(id, "IC Issue", "Marked as IC issue by [usr.key]", null, usr.ckey)
Resolve(silent = TRUE)
@@ -622,6 +627,32 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if("reopen")
Reopen()
+/datum/admin_help/proc/player_ticket_panel()
+ var/list/dat = list("Player Ticket")
+ dat += "State: "
+ switch(state)
+ if(AHELP_ACTIVE)
+ dat += "OPEN"
+ if(AHELP_RESOLVED)
+ dat += "RESOLVED"
+ if(AHELP_CLOSED)
+ dat += "CLOSED"
+ else
+ dat += "UNKNOWN"
+ dat += "\n[FOURSPACES]Refresh"
+ dat += "
Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
+ if(closed_at)
+ dat += "
Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
+ dat += "
"
+ dat += "
Log:
"
+ for (var/interaction in player_interactions)
+ dat += "[interaction]
"
+
+ var/datum/browser/player_panel = new(usr, "ahelp[id]", 0, 620, 480)
+ player_panel.set_content(dat.Join())
+ player_panel.open()
+
+
//
// TICKET STATCLICK
//
@@ -752,34 +783,68 @@ GLOBAL_DATUM_INIT(admin_help_ui_handler, /datum/admin_help_ui_handler, new)
GLOB.admin_help_ui_handler.ui_interact(mob)
to_chat(src, span_boldnotice("Adminhelp failing to open or work? Click here"))
+/client/verb/view_latest_ticket()
+ set category = "Admin"
+ set name = "View Latest Ticket"
+
+ if(!current_ticket)
+ // Check if the client had previous tickets, and show the latest one
+ var/list/prev_tickets = list()
+ var/datum/admin_help/last_ticket
+ // Check all resolved tickets for this player
+ for(var/datum/admin_help/resolved_ticket in GLOB.ahelp_tickets.resolved_tickets)
+ if(resolved_ticket.initiator_ckey == ckey) // Initiator is a misnomer, it's always the non-admin player even if an admin bwoinks first
+ prev_tickets += resolved_ticket
+ // Check all closed tickets for this player
+ for(var/datum/admin_help/closed_ticket in GLOB.ahelp_tickets.closed_tickets)
+ if(closed_ticket.initiator_ckey == ckey)
+ prev_tickets += closed_ticket
+ // Take the most recent entry of prev_tickets and open the panel on it
+ if(LAZYLEN(prev_tickets))
+ last_ticket = pop(prev_tickets)
+ last_ticket.player_ticket_panel()
+ return
+
+ // client had no tickets this round
+ to_chat(src, span_warning("You have not had an ahelp ticket this round."))
+ return
+
+ current_ticket.player_ticket_panel()
//
// 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
-//log_in_blackbox: Whether or not this message with the blackbox system.
-//If disabled, this message should be logged with a different proc call
-/proc/admin_ticket_log(what, message, log_in_blackbox = TRUE)
- var/client/C
+/// 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
+/// player_message: If the message should be shown in the player ticket panel, fill this out
+/// log_in_blackbox: Whether or not this message with the blackbox system.
+/// If disabled, this message should be logged with a different proc call
+/proc/admin_ticket_log(what, message, player_message, log_in_blackbox = TRUE)
+ var/client/mob_client
var/mob/Mob = what
if(istype(Mob))
- C = Mob.client
+ mob_client = Mob.client
else
- C = what
- if(istype(C) && C.current_ticket)
- C.current_ticket.AddInteraction(message)
+ mob_client = what
+ if(istype(mob_client) && mob_client.current_ticket)
+ if (isnull(player_message))
+ mob_client.current_ticket.AddInteraction(message)
+ else
+ mob_client.current_ticket.AddInteraction(message, player_message)
if(log_in_blackbox)
- SSblackbox.LogAhelp(C.current_ticket.id, "Interaction", message, C.ckey, usr.ckey)
- return C.current_ticket
+ SSblackbox.LogAhelp(mob_client.current_ticket.id, "Interaction", message, mob_client.ckey, usr.ckey)
+ return mob_client.current_ticket
if(istext(what)) //ckey
- var/datum/admin_help/AH = GLOB.ahelp_tickets.CKey2ActiveTicket(what)
- if(AH)
- AH.AddInteraction(message)
+ var/datum/admin_help/active_admin_help = GLOB.ahelp_tickets.CKey2ActiveTicket(what)
+ if(active_admin_help)
+ if (isnull(player_message))
+ active_admin_help.AddInteraction(message)
+ else
+ active_admin_help.AddInteraction(message, player_message)
if(log_in_blackbox)
- SSblackbox.LogAhelp(AH.id, "Interaction", message, what, usr.ckey)
- return AH
+ SSblackbox.LogAhelp(active_admin_help.id, "Interaction", message, what, usr.ckey)
+ return active_admin_help
//
// HELPER PROCS
diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm
index 0fb00e2ec69..44688da482b 100644
--- a/code/modules/admin/verbs/adminpm.dm
+++ b/code/modules/admin/verbs/adminpm.dm
@@ -214,9 +214,9 @@
type = MESSAGE_TYPE_ADMINPM,
html = span_notice("PM to-Admins: [rawmsg]"),
confidential = TRUE)
- var/datum/admin_help/AH = admin_ticket_log(src, "Reply PM from-[key_name(src, TRUE, TRUE)] to External: [keywordparsedmsg]")
+ var/datum/admin_help/new_admin_help = admin_ticket_log(src, "Reply PM from-[key_name(src, TRUE, TRUE)] to External: [keywordparsedmsg]", player_message = "Reply PM from-[key_name(src, TRUE, FALSE)] to External: [msg]")
externalreplyamount--
- send2adminchat("[AH ? "#[AH.id] " : ""]Reply: [ckey]", rawmsg)
+ send2adminchat("[new_admin_help ? "#[new_admin_help.id] " : ""]Reply: [ckey]", rawmsg)
else
var/badmin = FALSE //Lets figure out if an admin is getting bwoinked.
if(holder && recipient.holder && !current_ticket) //Both are admins, and this is not a reply to our own ticket.
@@ -234,14 +234,16 @@
html = span_notice("Admin PM to-[key_name(recipient, src, 1)]: [keywordparsedmsg]"),
confidential = TRUE)
//omg this is dumb, just fill in both their tickets
- var/interaction_message = "PM from-[key_name(src, recipient, 1)] to-[key_name(recipient, src, 1)]: [keywordparsedmsg]"
- admin_ticket_log(src, interaction_message, log_in_blackbox = FALSE)
+ var/interaction_message = "PM from-[key_name(src, recipient, TRUE)] to-[key_name(recipient, src, TRUE)]: [keywordparsedmsg]"
+ var/player_interaction_message = "PM from-[key_name(src, recipient, FALSE)] to-[key_name(recipient, src, FALSE)]: [msg]"
+ admin_ticket_log(src, interaction_message, log_in_blackbox = FALSE, player_message = player_interaction_message)
if(recipient != src) //reeee
- admin_ticket_log(recipient, interaction_message, log_in_blackbox = FALSE)
+ admin_ticket_log(recipient, interaction_message, log_in_blackbox = FALSE, player_message = player_interaction_message)
SSblackbox.LogAhelp(current_ticket.id, "Reply", msg, recipient.ckey, src.ckey)
else //recipient is an admin but sender is not
- var/replymsg = "Reply PM from-[key_name(src, recipient, 1)]: [keywordparsedmsg]"
- admin_ticket_log(src, "[replymsg]", log_in_blackbox = FALSE)
+ var/replymsg = "Reply PM from-[key_name(src, recipient, TRUE)]: [keywordparsedmsg]"
+ var/player_replymsg = "Reply PM from-[key_name(src, recipient, FALSE)]: [msg]"
+ admin_ticket_log(src, "[replymsg]", log_in_blackbox = FALSE, player_message = player_replymsg)
to_chat(recipient,
type = MESSAGE_TYPE_ADMINPM,
html = span_danger("[replymsg]"),
@@ -280,7 +282,7 @@
html = span_notice("Admin PM to-[key_name(recipient, src, 1)]: [msg]"),
confidential = TRUE)
- admin_ticket_log(recipient, "PM From [key_name_admin(src)]: [keywordparsedmsg]", log_in_blackbox = FALSE)
+ admin_ticket_log(recipient, "PM From [key_name_admin(src)]: [keywordparsedmsg]", log_in_blackbox = FALSE, player_message = "PM From [key_name_admin(src, include_name = FALSE)]: [msg]")
if(!already_logged) //Reply to an existing ticket
SSblackbox.LogAhelp(recipient.current_ticket.id, "Reply", msg, recipient.ckey, src.ckey)
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 982648b6f13..fad493d9ee4 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -100,6 +100,9 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
if(href_list["priv_msg"])
cmd_admin_pm(href_list["priv_msg"],null)
return
+ if (href_list["player_ticket_panel"])
+ view_latest_ticket()
+ return
// TGUIless adminhelp
if(href_list["tguiless_adminhelp"])
no_tgui_adminhelp(input(src, "Enter your ahelp", "Ahelp") as null|message)