Ahelp and Mhelp QOL (#24597)

* Bound ahelp/mhelp replies more tightly to their ticket.

* Hardened PMs further against missing data.

* Support expanding Discord notifications for ahelp/mhelp.

Functionality changes:
* Informs the user when their ticket is reopened.
* Informs other mentors/admins when tickets are converted.
* Discord messages now get a "Ticket 3, " or similar prefix.
  Not useful by itself, but will be with the following PR.

Code changes:
* When you create a ticket, you get the ticket object back.
* checkForTicket now allows you to fetch a ticket by number, and falls
  back to searching for open tickets if the ticket isn't found.
* Corrected and simplified the logic for adding PMs to tickets.
* Responses are now added through the ticket system, not the tickets
  directly.
This commit is contained in:
Charlie Nolan
2024-03-26 06:44:26 -07:00
committed by GitHub
parent b30890dd2a
commit e2f6212656
10 changed files with 95 additions and 62 deletions
+1 -1
View File
@@ -44,7 +44,7 @@ GLOBAL_VAR_INIT(nologevent, 0)
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob))
if(important || (C.prefs && !(C.prefs.toggles & PREFTOGGLE_CHAT_NO_TICKETLOGS)))
to_chat(C, msg, MESSAGE_TYPE_MENTORCHAT, confidential = TRUE)
to_chat(C, msg, MESSAGE_TYPE_MENTORPM, confidential = TRUE)
if(important)
if(C.prefs?.sound & SOUND_MENTORHELP)
SEND_SOUND(C, sound('sound/effects/adminhelp.ogg'))
+12 -5
View File
@@ -25,13 +25,20 @@
if(!msg) // No message after sanitisation
return
var/span_type
var/message_type
var/datum/ticket/T
if(selected_type == "Mentorhelp")
SSmentor_tickets.newHelpRequest(src, msg) // Mhelp
T = SSmentor_tickets.newHelpRequest(src, msg) // Mhelp
span_type = "mentorhelp"
message_type = MESSAGE_TYPE_MENTORPM
else
SStickets.newHelpRequest(src, msg) // Ahelp
T = SStickets.newHelpRequest(src, msg) // Ahelp
span_type = "adminhelp"
message_type = MESSAGE_TYPE_ADMINPM
//show it to the person adminhelping too
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [msg]</span>", MESSAGE_TYPE_ADMINPM, confidential = TRUE)
to_chat(src, "<span class='[span_type]'>[selected_type]</b>: [msg]</span>", message_type, confidential = TRUE)
SSblackbox.record_feedback("tally", "admin_verb", 1, "Adminhelp") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
switch(selected_type)
@@ -41,11 +48,11 @@
var/active_admins = admincount[1]
log_admin("[selected_type]: [key_name(src)]: [msg] - heard by [active_admins] non-AFK admins.")
GLOB.discord_manager.send2discord_simple_noadmins("**\[Adminhelp]** [key_name(src)]: [msg]", check_send_always = TRUE)
GLOB.discord_manager.send2discord_simple_noadmins("**\[Adminhelp]** Ticket [T.ticketNum], [key_name(src)]: [msg]", check_send_always = TRUE)
if("Mentorhelp")
var/list/mentorcount = staff_countup(R_MENTOR)
var/active_mentors = mentorcount[1]
log_admin("[selected_type]: [key_name(src)]: [msg] - heard by [active_mentors] non-AFK mentors.")
GLOB.discord_manager.send2discord_simple_mentor("[key_name(src)]: [msg]")
GLOB.discord_manager.send2discord_simple_mentor("Ticket [T.ticketNum], [key_name(src)]: [msg]")
+41 -39
View File
@@ -60,7 +60,7 @@
//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, type = "PM")
/client/proc/cmd_admin_pm(whom, msg, type = "PM", ticket_id = -1)
if(check_mute(ckey, MUTE_ADMINHELP))
to_chat(src, "<span class='danger'>Error: Private-Message: You are unable to use PM-s (muted).</span>")
return
@@ -112,21 +112,30 @@
else
msg = admin_pencode_to_html(msg)
var/recieve_span = "playerreply"
var/send_span
var/recieve_span
var/send_pm_type = " "
var/recieve_pm_type = "Player"
var/message_type
var/datum/controller/subsystem/tickets/tickets_system
// We treat PMs as mentorhelps if we were explicitly so, or if neither
// party is an admin.
if(type == "Mentorhelp" || !(check_rights(R_ADMIN|R_MOD, 0, C.mob) || check_rights(R_ADMIN|R_MOD, 0, src.mob)))
send_span = "mentorhelp"
recieve_span = "mentorhelp"
message_type = MESSAGE_TYPE_MENTORPM
tickets_system = SSmentor_tickets
else
send_span = "adminhelp"
recieve_span = "adminhelp"
message_type = MESSAGE_TYPE_ADMINPM
tickets_system = SStickets
if(holder)
//mod PMs are maroon
//PMs sent from admins and mods display their rank
if(holder)
if(check_rights(R_MOD|R_MENTOR,0) && !check_rights(R_ADMIN,0))
recieve_span = "mentorhelp"
else
recieve_span = "adminhelp"
send_pm_type = holder.rank + " "
recieve_pm_type = holder.rank
send_pm_type = holder.rank + " "
recieve_pm_type = holder.rank
else if(!C.holder)
to_chat(src, "<span class='danger'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</span>")
@@ -159,12 +168,12 @@
var/emoji_msg = "<span class='emoji_enabled'>[msg]</span>"
recieve_message = chat_box_red("<span class='[recieve_span]'>[type] from-<b>[recieve_pm_type] [C.holder ? key_name(src, TRUE, type) : key_name_hidden(src, TRUE, type)]</b>:<br><br>[emoji_msg]</span>")
recieve_message = chat_box_red("<span class='[recieve_span]'>[type] from-<b>[recieve_pm_type] [C.holder ? key_name(src, TRUE, type, ticket_id = ticket_id) : key_name_hidden(src, TRUE, type, ticket_id = ticket_id)]</b>:<br><br>[emoji_msg]</span>")
to_chat(C, recieve_message)
var/ping_link = check_rights(R_ADMIN, 0, mob) ? "(<a href='?src=[pm_tracker.UID()];ping=[C.key]'>PING</a>)" : ""
var/window_link = "(<a href='?src=[pm_tracker.UID()];newtitle=[C.key]'>WINDOW</a>)"
var/alert_link = check_rights(R_ADMIN, FALSE, mob) ? " (<a href='?src=[pm_tracker.UID()];adminalert=[C.mob.UID()]'>ALERT</a>)" : ""
to_chat(src, "<span class='pmsend'>[send_pm_type][type] to-<b>[holder ? key_name(C, TRUE, type) : key_name_hidden(C, TRUE, type)]</b>: [emoji_msg]</span> [ping_link] [window_link][alert_link]", MESSAGE_TYPE_ADMINPM)
to_chat(src, "<span class='[send_span]'>[send_pm_type][type] to-<b>[holder ? key_name(C, TRUE, type, ticket_id = ticket_id) : key_name_hidden(C, TRUE, type, ticket_id = ticket_id)]</b>: [emoji_msg]</span> [ping_link] [window_link][alert_link]", message_type)
/*if(holder && !C.holder)
C.last_pm_recieved = world.time
@@ -182,38 +191,31 @@
if(X == C || X == src)
continue
if(X.key != key && X.key != C.key)
switch(type)
if("Mentorhelp")
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob))
to_chat(X, "<span class='mentorhelp'>[type]: [key_name(src, TRUE, type)]-&gt;[key_name(C, TRUE, type)]: [emoji_msg]</span>", type = MESSAGE_TYPE_MENTORCHAT)
if("Adminhelp")
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
to_chat(X, "<span class='adminhelp'>[type]: [key_name(src, TRUE, type)]-&gt;[key_name(C, TRUE, type)]: [emoji_msg]</span>", type = MESSAGE_TYPE_ADMINCHAT)
else
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
to_chat(X, "<span class='boldnotice'>[type]: [key_name(src, TRUE, type)]-&gt;[key_name(C, TRUE, type)]: [emoji_msg]</span>", type = MESSAGE_TYPE_ADMINCHAT)
if(message_type == MESSAGE_TYPE_MENTORPM)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, X.mob))
to_chat(X, "<span class='mentorhelp'>[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]-&gt;[key_name(C, TRUE, type, ticket_id = ticket_id)]: [emoji_msg]</span>", type = message_type)
else
if(check_rights(R_ADMIN|R_MOD, 0, X.mob))
to_chat(X, "<span class='adminhelp'>[type]: [key_name(src, TRUE, type, ticket_id = ticket_id)]-&gt;[key_name(C, TRUE, type, ticket_id = ticket_id)]: [emoji_msg]</span>", type = message_type)
//Check if the mob being PM'd has any open admin tickets.
var/tickets = list()
if(type == "Mentorhelp")
tickets = SSmentor_tickets.checkForTicket(C)
else
tickets = SStickets.checkForTicket(C)
if(tickets)
for(var/datum/ticket/i in tickets)
i.addResponse(src, msg) // Add this response to their open tickets.
//Check if the mob being PM'd has any open tickets.
var/list/tickets = tickets_system.checkForTicket(C, ticket_id)
if(length(tickets))
tickets_system.addResponse(tickets, src, msg)
return
if(type == "Mentorhelp")
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
// If we didn't find a specific ticket by the target mob, we check for
// tickets by the source mob.
if(message_type == MESSAGE_TYPE_MENTORPM)
if(check_rights(R_ADMIN|R_MOD|R_MENTOR, 0, C.mob))
tickets = SSmentor_tickets.checkForTicket(src)
else // Ahelp
if(check_rights(R_ADMIN|R_MOD, 0, C.mob)) //Is the person being pm'd an admin? If so we check if the pm'er has open tickets
else
if(check_rights(R_ADMIN|R_MOD, 0, C.mob))
tickets = SStickets.checkForTicket(src)
if(tickets)
for(var/datum/ticket/i in tickets)
i.addResponse(src, msg)
return
if(length(tickets))
tickets_system.addResponse(tickets, src, msg)
/client/proc/cmd_admin_discord_pm()
if(check_mute(ckey, MUTE_ADMINHELP))