mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
Ports the player ticket panel from skyrat (#66954)
* Ports the player ticket panel from skyrat Adds a player side panel to view active admin tickets, this will make it easier for players to find previous admin messages, remember what they said previously etc. This is especially good for the cases that TGchat drops messages
This commit is contained in:
@@ -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("<font color='blue'>[key_name_admin(usr)] PM'd [LinkedReplyName()]</font>")
|
||||
AddInteraction("<font color='blue'>[key_name_admin(usr)] PM'd [LinkedReplyName()]</font>", player_message = "<font color='blue'>[key_name_admin(usr, include_name = FALSE)] PM'd [LinkedReplyName()]</font>")
|
||||
message_admins("<font color='blue'>Ticket [TicketHref("#[id]")] created</font>")
|
||||
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)]</span><b>: [LinkedReplyName(ref_src)] [FullMonty(ref_src)]:</b> <span class='linkify'>[keywords_lookup(msg)]"))
|
||||
|
||||
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
|
||||
AddInteraction("<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>", player_message = "<font color='red'>[LinkedReplyName(ref_src)]: [msg]</font>")
|
||||
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("<font color='purple'>Reopened by [key_name_admin(usr)]</font>")
|
||||
AddInteraction("<font color='purple'>Reopened by [key_name_admin(usr)]</font>", 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("<font color='red'>Closed by [key_name].</font>")
|
||||
AddInteraction("<font color='red'>Closed by [key_name].</font>", player_message = "<font color='red'>Ticket closed!</font>")
|
||||
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("<font color='green'>Resolved by [key_name].</font>")
|
||||
AddInteraction("<font color='green'>Resolved by [key_name].</font>", player_message = "<font color='green'>Ticket resolved!</font>")
|
||||
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("<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Player Ticket</title></head>")
|
||||
dat += "<b>State: "
|
||||
switch(state)
|
||||
if(AHELP_ACTIVE)
|
||||
dat += "<font color='red'>OPEN</font></b>"
|
||||
if(AHELP_RESOLVED)
|
||||
dat += "<font color='green'>RESOLVED</font></b>"
|
||||
if(AHELP_CLOSED)
|
||||
dat += "CLOSED</b>"
|
||||
else
|
||||
dat += "UNKNOWN</b>"
|
||||
dat += "\n[FOURSPACES]<A href='?_src_=holder;[HrefToken(forceGlobal = TRUE)];player_ticket_panel=1'>Refresh</A>"
|
||||
dat += "<br><br>Opened at: [gameTimestamp("hh:mm:ss", opened_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
|
||||
if(closed_at)
|
||||
dat += "<br>Closed at: [gameTimestamp("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
|
||||
dat += "<br><br>"
|
||||
dat += "<br><b>Log:</b><br><br>"
|
||||
for (var/interaction in player_interactions)
|
||||
dat += "[interaction]<br>"
|
||||
|
||||
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? <a href='?src=[REF(src)];tguiless_adminhelp=1'>Click here</a>"))
|
||||
|
||||
/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
|
||||
|
||||
@@ -214,9 +214,9 @@
|
||||
type = MESSAGE_TYPE_ADMINPM,
|
||||
html = span_notice("PM to-<b>Admins</b>: <span class='linkify'>[rawmsg]</span>"),
|
||||
confidential = TRUE)
|
||||
var/datum/admin_help/AH = admin_ticket_log(src, "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, TRUE)]</b> to <i>External</i>: [keywordparsedmsg]</font>")
|
||||
var/datum/admin_help/new_admin_help = admin_ticket_log(src, "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, TRUE)]</b> to <i>External</i>: [keywordparsedmsg]</font>", player_message = "<font color='red'>Reply PM from-<b>[key_name(src, TRUE, FALSE)]</b> to <i>External</i>: [msg]</font>")
|
||||
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-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span>"),
|
||||
confidential = TRUE)
|
||||
//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, log_in_blackbox = FALSE)
|
||||
var/interaction_message = "<font color='purple'>PM from-<b>[key_name(src, recipient, TRUE)]</b> to-<b>[key_name(recipient, src, TRUE)]</b>: [keywordparsedmsg]</font>"
|
||||
var/player_interaction_message = "<font color='purple'>PM from-<b>[key_name(src, recipient, FALSE)]</b> to-<b>[key_name(recipient, src, FALSE)]</b>: [msg]</font>"
|
||||
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-<b>[key_name(src, recipient, 1)]</b>: <span class='linkify'>[keywordparsedmsg]</span>"
|
||||
admin_ticket_log(src, "<font color='red'>[replymsg]</font>", log_in_blackbox = FALSE)
|
||||
var/replymsg = "Reply PM from-<b>[key_name(src, recipient, TRUE)]</b>: <span class='linkify'>[keywordparsedmsg]</span>"
|
||||
var/player_replymsg = "Reply PM from-<b>[key_name(src, recipient, FALSE)]</b>: <span class='linkify'>[msg]</span>"
|
||||
admin_ticket_log(src, "<font color='red'>[replymsg]</font>", 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-<b>[key_name(recipient, src, 1)]</b>: <span class='linkify'>[msg]</span>"),
|
||||
confidential = TRUE)
|
||||
|
||||
admin_ticket_log(recipient, "<font color='purple'>PM From [key_name_admin(src)]: [keywordparsedmsg]</font>", log_in_blackbox = FALSE)
|
||||
admin_ticket_log(recipient, "<font color='purple'>PM From [key_name_admin(src)]: [keywordparsedmsg]</font>", log_in_blackbox = FALSE, player_message = "<font color='purple'>PM From [key_name_admin(src, include_name = FALSE)]: [msg]</font>")
|
||||
|
||||
if(!already_logged) //Reply to an existing ticket
|
||||
SSblackbox.LogAhelp(recipient.current_ticket.id, "Reply", msg, recipient.ckey, src.ckey)
|
||||
|
||||
Reference in New Issue
Block a user