Refactors the ticket SSes. Fixes the ticket conversion

This commit is contained in:
joep van der velden
2020-08-22 13:12:41 +02:00
parent 8cee2bb22e
commit f2d21f9299
5 changed files with 134 additions and 147 deletions
@@ -10,19 +10,25 @@ GLOBAL_REAL(SSmentor_tickets, /datum/controller/subsystem/tickets/mentor_tickets
ticket_system_name = "Mentor Tickets"
ticket_name = "Mentor Ticket"
span_class = "mentorhelp"
anchor_link_extra = ";is_mhelp=1"
ticket_help_type = "Mentorhelp"
ticket_help_span = "mentorhelp"
other_ticket_name = "Admin"
other_ticket_permission = R_ADMIN
close_rights = R_MENTOR | R_ADMIN
rights_needed = R_MENTOR | R_ADMIN | R_MOD
/datum/controller/subsystem/tickets/mentor_tickets/Initialize()
. = ..()
close_messages = list("<font color='red' size='3'><b>- [ticket_name] Closed -</b></font>",
"<span class='boldmessage'>Please try to be as descriptive as possible in mentor helps. Mentors do not know the full situation you're in and need more information to give you a helpful response.</span>",
"<span class='[span_class]'>Your [ticket_name] has now been closed.</span>")
return ..()
/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg)
message_mentorTicket(msg)
/datum/controller/subsystem/tickets/mentor_tickets/message_staff(msg, prefix_type = NONE, important = FALSE)
message_mentorTicket(msg, important)
/datum/controller/subsystem/tickets/mentor_tickets/create_other_system_ticket(datum/ticket/T)
SStickets.newTicket(T.clientName, T.content, T.title)
SStickets.newTicket(T.clientName, T.content, T.raw_title)
/datum/controller/subsystem/tickets/mentor_tickets/autoRespond(N)
return
+75 -15
View File
@@ -10,6 +10,9 @@
#define TICKET_RESOLVED 3
#define TICKET_STALE 4
#define TICKET_STAFF_MESSAGE_ADMIN_CHANNEL 1
#define TICKET_STAFF_MESSAGE_PREFIX 2
SUBSYSTEM_DEF(tickets)
name = "Admin Tickets"
init_order = INIT_ORDER_TICKETS
@@ -24,6 +27,11 @@ SUBSYSTEM_DEF(tickets)
var/close_rights = R_ADMIN
var/rights_needed = R_ADMIN | R_MOD
/// Text that will be added to the anchor link
var/anchor_link_extra = ""
var/ticket_help_type = "Adminhelp"
var/ticket_help_span = "adminhelp"
/// The name of the other ticket type to convert to
var/other_ticket_name = "Mentor"
/// Which permission to look for when seeing if there is staff available for the other ticket type
@@ -76,22 +84,55 @@ SUBSYSTEM_DEF(tickets)
var/datum/ticket/T = i
resolveTicket(T.ticketNum)
/**
* Will either make a new ticket using the given text or will add the text to an existing ticket.
* Staff will get a message
* Arguments:
* C - The client who requests help
* text - The text the client send
*/
/datum/controller/subsystem/tickets/proc/newHelpRequest(client/C, text)
var/ticketNum // Holder for the ticket number
var/datum/ticket/T
// Get the open ticket assigned to the client and add a response. If no open tickets then make a new one
if((T = checkForOpenTicket(C)))
ticketNum = T.ticketNum
T.addResponse(C, text)
T.setCooldownPeriod()
to_chat(C.mob, "<span class='[span_class]'>Your [ticket_name] #[ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.</span>")
var/url_message = makeUrlMessage(C, text, ticketNum)
message_staff(url_message, NONE, TRUE)
else
newTicket(C, text, text)
/**
* Will add the URLs usable by staff to the message and return it
* Arguments:
* C - The client who send the message
* msg - The raw message
* ticketNum - Which ticket number the ticket has
*/
/datum/controller/subsystem/tickets/proc/makeUrlMessage(client/C, msg, ticketNum)
var/finalised_msg = "<span class='[ticket_help_span]'>[ticket_help_type]: </span><span class='boldnotice'>[key_name(C, TRUE, ticket_help_type)] "
finalised_msg += "([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_TP(C.mob,"TP")]) ([ADMIN_SM(C.mob,"SM")]) "
finalised_msg += "([admin_jump_link(C.mob)]) (<A HREF='?_src_=holder;openticket=[ticketNum][anchor_link_extra]'>TICKET</A>) "
finalised_msg += "[isAI(C.mob) ? "(<A HREF='?_src_=holder;adminchecklaws=[C.mob.UID()]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[ticketNum][anchor_link_extra]'>TAKE</A>) "
finalised_msg += "(<A HREF='?_src_=holder;resolve=[ticketNum][anchor_link_extra]'>RESOLVE</A>) <A HREF='?_src_=holder;autorespond=[ticketNum][anchor_link_extra]'>(AUTO)</A> "
finalised_msg += "<a href='?_src_=holder;convert_ticket=[ticketNum][anchor_link_extra]'>(CONVERT)</a> :</span> <span class='[ticket_help_span]'>[msg]</span>"
return finalised_msg
//Open a new ticket and populate details then add to the list of open tickets
/datum/controller/subsystem/tickets/proc/newTicket(client/C, passedContent, title)
if(!C || !passedContent)
return
//Check if the user has an open ticket already within the cooldown period, if so we don't create a new one and re-set the cooldown period
var/datum/ticket/existingTicket = checkForOpenTicket(C)
if(existingTicket)
existingTicket.setCooldownPeriod()
to_chat(C.mob, "<span class='[span_class]'>Your [ticket_name] #[existingTicket.ticketNum] remains open! Visit \"My tickets\" under the Admin Tab to view it.</span>")
return
if(!title)
title = passedContent
var/datum/ticket/T = new(title, passedContent, getTicketCounterAndInc())
var/new_ticket_num = getTicketCounterAndInc()
var/url_title = makeUrlMessage(C, title, new_ticket_num)
var/datum/ticket/T = new(url_title, title, passedContent, new_ticket_num)
allTickets += T
T.clientName = C
T.locationSent = C.mob.loc.name
@@ -102,6 +143,8 @@ SUBSYSTEM_DEF(tickets)
var/ticket_open_sound = sound('sound/effects/adminticketopen.ogg')
SEND_SOUND(C, ticket_open_sound)
message_staff(url_title, NONE, TRUE)
//Set ticket state with key N to open
/datum/controller/subsystem/tickets/proc/openTicket(N)
var/datum/ticket/T = allTickets[N]
@@ -146,7 +189,7 @@ SUBSYSTEM_DEF(tickets)
create_other_system_ticket(T)
/datum/controller/subsystem/tickets/proc/create_other_system_ticket(datum/ticket/T)
SSmentor_tickets.newTicket(T.clientName, T.content, T.title)
SSmentor_tickets.newTicket(T.clientName, T.content, T.raw_title)
/datum/controller/subsystem/tickets/proc/autoRespond(N)
if(!check_rights(rights_needed))
@@ -247,6 +290,7 @@ SUBSYSTEM_DEF(tickets)
var/clientName // Client which opened the ticket
var/timeOpened // Time the ticket was opened
var/title //The initial message with links
var/raw_title // The title without URLs added
var/list/content // content of the staff help
var/lastStaffResponse // Last staff member who responded
var/lastResponseTime // When the staff last responded
@@ -257,8 +301,9 @@ SUBSYSTEM_DEF(tickets)
var/ticketCooldown // Cooldown before allowing the user to open another ticket.
var/client/staffAssigned // Staff member who has assigned themselves to this ticket
/datum/ticket/New(tit, cont, num)
/datum/ticket/New(tit, raw_tit, cont, num)
title = tit
raw_title = raw_tit
content = list()
content += cont
timeOpened = worldtime2text()
@@ -437,9 +482,21 @@ UI STUFF
to_chat(target, text)
return TRUE
//Sends a message to the designated staff
/datum/controller/subsystem/tickets/proc/message_staff(var/msg, var/alt = FALSE)
message_adminTicket(msg, alt)
/**
* Sends a message to the designated staff
* Arguments:
* msg - The message being send
* alt - If an alternative prefix should be used or not. Defaults to TICKET_STAFF_MESSAGE_PREFIX
* important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
send a sound and flash the window. Defaults to FALSE
*/
/datum/controller/subsystem/tickets/proc/message_staff(msg, prefix_type = TICKET_STAFF_MESSAGE_PREFIX, important = FALSE)
switch(prefix_type)
if(TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
msg = "<span class=admin_channel>ADMIN TICKET: [msg]</span>"
if(TICKET_STAFF_MESSAGE_PREFIX)
msg = "<span class=adminticket><span class='prefix'>ADMIN TICKET:</span> [msg]</span>"
message_adminTicket(msg, important)
/datum/controller/subsystem/tickets/Topic(href, href_list)
@@ -521,7 +578,7 @@ UI STUFF
if(span_class == "mentorhelp")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) has taken [ticket_name] number [index]</span>")
else
message_staff("<span class='admin_channel'>[usr.client] / ([usr]) has taken [ticket_name] number [index]</span>", TRUE)
message_staff("<span class='admin_channel'>[usr.client] / ([usr]) has taken [ticket_name] number [index]</span>", TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
to_chat_safe(returnClient(index), "<span class='[span_class]'>Your [ticket_name] is being handled by [usr.client].</span>")
/datum/controller/subsystem/tickets/proc/unassignTicket(index)
@@ -532,4 +589,7 @@ UI STUFF
if(span_class == "mentorhelp")
message_staff("<span class='[span_class]'>[usr.client] / ([usr]) has unassigned [ticket_name] number [index]</span>")
else
message_staff("<span class='admin_channel'>[usr.client] / ([usr]) has unassigned [ticket_name] number [index]</span>", TRUE)
message_staff("<span class='admin_channel'>[usr.client] / ([usr]) has unassigned [ticket_name] number [index]</span>", TICKET_STAFF_MESSAGE_ADMIN_CHANNEL)
#undef TICKET_STAFF_MESSAGE_ADMIN_CHANNEL
#undef TICKET_STAFF_MESSAGE_PREFIX
+26 -9
View File
@@ -20,22 +20,39 @@ GLOBAL_VAR_INIT(nologevent, 0)
if(C.prefs.atklog <= loglevel)
to_chat(C, msg)
/proc/message_adminTicket(var/msg, var/alt = FALSE)
if(alt)
msg = "<span class=admin_channel>ADMIN TICKET: [msg]</span>"
else
msg = "<span class=adminticket><span class='prefix'>ADMIN TICKET:</span> [msg]</span>"
/**
* Sends a message to the staff able to see admin tickets
* Arguments:
* msg - The message being send
* important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
send a sound and flash the window. Defaults to FALSE
*/
/proc/message_adminTicket(msg, important = FALSE)
for(var/client/C in GLOB.admins)
if(R_ADMIN & C.holder.rights)
if(C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS))
if(important || (C.prefs && !(C.prefs.toggles & CHAT_NO_TICKETLOGS)))
to_chat(C, msg)
if(important)
if(C.prefs?.sound & SOUND_ADMINHELP)
SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
window_flash(C)
/proc/message_mentorTicket(var/msg)
/**
* Sends a message to the staff able to see mentor tickets
* Arguments:
* msg - The message being send
* important - If the message is important. If TRUE it will ignore the CHAT_NO_TICKETLOGS preferences,
send a sound and flash the window. Defaults to FALSE
*/
/proc/message_mentorTicket(msg, important = FALSE)
for(var/client/C in GLOB.admins)
if(check_rights(R_ADMIN | R_MENTOR | R_MOD, 0, C.mob))
if(C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS))
if(important || (C.prefs && !(C.prefs.toggles & CHAT_NO_MENTORTICKETLOGS)))
to_chat(C, msg)
if(important)
if(C.prefs?.sound & SOUND_MENTORHELP)
SEND_SOUND(C, 'sound/effects/adminhelp.ogg')
window_flash(C)
/proc/admin_ban_mobsearch(var/mob/M, var/ckey_to_find, var/mob/admin_to_notify)
if(!M || !M.ckey)
+13 -11
View File
@@ -26,17 +26,16 @@
message_admins("[key_name_admin(usr)] rejected [key_name_admin(C.mob)]'s admin help")
log_admin("[key_name(usr)] rejected [key_name(C.mob)]'s admin help")
if(href_list["openadminticket"])
if(!check_rights(R_ADMIN))
return
var/ticketID = text2num(href_list["openadminticket"])
SStickets.showDetailUI(usr, ticketID)
if(href_list["openmentorticket"])
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
return
var/ticketID = text2num(href_list["openmentorticket"])
SSmentor_tickets.showDetailUI(usr, ticketID)
if(href_list["openticket"])
var/ticketID = text2num(href_list["openticket"])
if(!href_list["is_mhelp"])
if(!check_rights(R_ADMIN))
return
SStickets.showDetailUI(usr, ticketID)
else
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
return
SSmentor_tickets.showDetailUI(usr, ticketID)
if(href_list["stickyban"])
stickyban(href_list["stickyban"],href_list)
@@ -1666,6 +1665,9 @@
SStickets.resolveTicket(index)
else if(href_list["autorespond"])
if(href_list["is_mhelp"])
to_chat(usr, "<span class='warning'>Auto responses are not yet available for mentor helps.</span>")
return
var/index = text2num(href_list["autorespond"])
if(!check_rights(R_ADMIN|R_MOD))
return
+10 -108
View File
@@ -29,64 +29,12 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
msg = sanitize_simple(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg) return
var/original_msg = msg
if(selected_type == "Mentorhelp")
SSmentor_tickets.newHelpRequest(src, msg)
else
SStickets.newHelpRequest(src, msg)
//explode the input msg into a list
var/list/msglist = splittext(msg, " ")
//generate keywords lookup
var/list/surnames = list()
var/list/forenames = list()
var/list/ckeys = list()
for(var/mob/M in GLOB.mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind) indexing += M.mind.name
for(var/string in indexing)
var/list/L = splittext(string, " ")
var/surname_found = 0
//surnames
for(var/i=L.len, i>=1, i--)
var/word = ckey(L[i])
if(word)
surnames[word] = M
surname_found = i
break
//forenames
for(var/i=1, i<surname_found, i++)
var/word = ckey(L[i])
if(word)
forenames[word] = M
//ckeys
ckeys[M.ckey] = M
var/ai_found = 0
msg = ""
var/list/mobs_found = list()
for(var/original_word in msglist)
var/word = ckey(original_word)
if(word)
if(!(word in GLOB.adminhelp_ignored_words))
if(word == "ai")
ai_found = 1
else
var/mob/found = ckeys[word]
if(!found)
found = surnames[word]
if(!found)
found = forenames[word]
if(found)
if(!(found in mobs_found))
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
msg += "<b><font color='black'>[original_word] </font></b> "
continue
msg += "[original_word] "
if(!mob) return //this doesn't happen
//send this msg to all admins
//See how many staff are on
var/admin_number_afk = 0
var/list/mentorholders = list()
var/list/modholders = list()
@@ -103,65 +51,19 @@ GLOBAL_LIST_INIT(adminhelp_ignored_words, list("unknown","the","a","an","of","mo
if(check_rights(R_MENTOR, 0, X.mob))
mentorholders += X
continue
var/ticketNum // Holder for the ticket number
var/prunedmsg ="[src]: [msg]" // Message without links
var/datum/ticket/T
var/isMhelp = selected_type == "Mentorhelp"
var/span
if(isMhelp)
span = "<span class='mentorhelp'>"
if(SSmentor_tickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SSmentor_tickets.checkForOpenTicket(src)
else
ticketNum = SSmentor_tickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
else //Ahelp
span = "<span class='adminhelp'>"
if(SStickets.checkForOpenTicket(src)) // If user already has an open ticket
T = SStickets.checkForOpenTicket(src) // Make T equal to the ticket they have open
else
ticketNum = SStickets.getTicketCounter() // ticketNum is the ticket ready to be assigned.
if(T)
ticketNum = T.ticketNum // ticketNum is the number of their ticket.
T.addResponse(src, msg)
var/finalised_msg = "[span][selected_type]: </span><span class='boldnotice'>[key_name(src, TRUE, selected_type)] "
finalised_msg += "([ADMIN_QUE(mob,"?")]) ([ADMIN_PP(mob,"PP")]) ([ADMIN_VV(mob,"VV")]) ([ADMIN_TP(mob,"TP")]) ([ADMIN_SM(mob,"SM")]) "
finalised_msg += "([admin_jump_link(mob)]) (<A HREF='?_src_=holder;[isMhelp ? "openmentorticket" : "openadminticket"]=[ticketNum]'>TICKET</A>) "
finalised_msg += "[ai_found ? "(<A HREF='?_src_=holder;adminchecklaws=[mob.UID()]'>CL</A>)" : ""] (<A HREF='?_src_=holder;take_question=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>TAKE</A>) "
finalised_msg += "(<A HREF='?_src_=holder;resolve=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>RESOLVE</A>) [isMhelp ? "" : "<A HREF='?_src_=holder;autorespond=[ticketNum]'>(AUTO)</A>"] "
finalised_msg += "<a href='?_src_=holder;convert_ticket=[ticketNum][isMhelp ? ";is_mhelp=1" : ""]'>(CONVERT)</a> :</span> [span][msg]</span>"
if(isMhelp)
//Open a new adminticket and inform the user.
SSmentor_tickets.newTicket(src, prunedmsg, finalised_msg)
for(var/client/X in mentorholders + modholders + adminholders)
if(X.prefs.sound & SOUND_MENTORHELP)
SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
to_chat(X, finalised_msg)
else //Ahelp
//Open a new adminticket and inform the user.
SStickets.newTicket(src, prunedmsg, finalised_msg)
for(var/client/X in modholders + adminholders)
if(X.prefs.sound & SOUND_ADMINHELP)
SEND_SOUND(X, 'sound/effects/adminhelp.ogg')
window_flash(X)
to_chat(X, finalised_msg)
//show it to the person adminhelping too
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [original_msg]</span>")
to_chat(src, "<span class='boldnotice'>[selected_type]</b>: [msg]</span>")
var/admin_number_present = adminholders.len - admin_number_afk
log_admin("[selected_type]: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins.")
log_admin("[selected_type]: [key_name(src)]: [msg] - heard by [admin_number_present] non-AFK admins.")
if(admin_number_present <= 0)
if(!admin_number_afk)
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!No admins online!!")
send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!No admins online!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg] - !!All admins AFK ([admin_number_afk])!!")
send2adminirc("[selected_type] from [key_name(src)]: [msg] - !!All admins AFK ([admin_number_afk])!!")
else
send2adminirc("[selected_type] from [key_name(src)]: [original_msg]")
send2adminirc("[selected_type] from [key_name(src)]: [msg]")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return