mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-27 23:27:34 +01:00
Player Ticket History - A Synopsis At A Glance (#75830)
## About The Pull Request Adds a new front-end for viewing player ticket history stored in the connected database. Also adds a button to directly query for previous tickets from the ticket panel. ## Pictures     ## Why It's Good For The Game Gives admins the ability to look at a players behaviour in-game without the need for external tooling, (statbus) ## Changelog 🆑 admin: Player Ticket History - view a player's ticket history without the need to use external tooling. /🆑
This commit is contained in:
@@ -92,6 +92,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
/client/proc/toggle_view_range, /*changes how far we can see*/
|
||||
/client/proc/cmd_admin_law_panel,
|
||||
/client/proc/log_viewer_new,
|
||||
/client/proc/player_ticket_history,
|
||||
)
|
||||
GLOBAL_LIST_INIT(admin_verbs_ban, list(/client/proc/unban_panel, /client/proc/ban_panel, /client/proc/stickybanpanel, /client/proc/library_control))
|
||||
GLOBAL_PROTECT(admin_verbs_ban)
|
||||
|
||||
@@ -1122,6 +1122,15 @@
|
||||
return
|
||||
M.mind_initialize()
|
||||
|
||||
else if(href_list["player_ticket_history"])
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
var/target_ckey = href_list["player_ticket_history"]
|
||||
GLOB.player_ticket_history.cache_history_for_ckey(target_ckey)
|
||||
GLOB.player_ticket_history.user_selections[usr.ckey] = target_ckey
|
||||
GLOB.player_ticket_history.ui_interact(usr)
|
||||
return
|
||||
|
||||
else if(href_list["create_object"])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
@@ -573,6 +573,10 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
|
||||
for(var/I in ticket_interactions)
|
||||
dat += "[I]<br>"
|
||||
|
||||
// Helper for opening directly to player ticket history
|
||||
dat += "<br><br><b>Player Ticket History:</b>"
|
||||
dat += "[FOURSPACES]<A href='?_src_=holder;[HrefToken()];player_ticket_history=[initiator_ckey]'>Open</A>"
|
||||
|
||||
// Append any tickets also opened by this user if relevant
|
||||
var/list/related_tickets = GLOB.ahelp_tickets.TicketsByCKey(initiator_ckey)
|
||||
if (related_tickets.len > 1)
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/// Holds information about a ticket
|
||||
/datum/ticket_history
|
||||
var/player_ckey
|
||||
/// Number of the ticket *for that round*
|
||||
var/ticket_number
|
||||
var/round_id
|
||||
var/list/ticket_log
|
||||
|
||||
/datum/ticket_log_entry
|
||||
var/timestamp
|
||||
var/origin_ckey
|
||||
var/target_ckey
|
||||
var/action
|
||||
var/message
|
||||
|
||||
GENERAL_PROTECT_DATUM(/datum/ticket_history)
|
||||
GENERAL_PROTECT_DATUM(/datum/ticket_log_entry)
|
||||
|
||||
GLOBAL_DATUM_INIT(player_ticket_history, /datum/ticket_history_holder, new)
|
||||
GLOBAL_PROTECT(player_ticket_history)
|
||||
|
||||
/client/proc/player_ticket_history()
|
||||
set name = "Player Ticket History"
|
||||
set desc = "Allows you to view the ticket history of a player."
|
||||
set category = "Admin"
|
||||
if(!check_rights(R_ADMIN))
|
||||
return
|
||||
GLOB.player_ticket_history.ui_interact(mob)
|
||||
|
||||
/datum/ticket_history_holder
|
||||
/// Assosciative list of ticket histories. ckey -> list/datum/ticket_history
|
||||
var/list/ticket_histories = list()
|
||||
/// Assosciative list of user_ckey -> target_ckey
|
||||
var/list/user_selections = list()
|
||||
|
||||
/datum/ticket_history_holder/proc/cache_history_for_ckey(ckey, entries = 5)
|
||||
ckey = lowertext(ckey)
|
||||
|
||||
if(!isnum(entries) || entries <= 0)
|
||||
return
|
||||
|
||||
var/list/datum/ticket_history/history_cache = list()
|
||||
ticket_histories[ckey] = history_cache
|
||||
|
||||
var/datum/db_query/ticket_lookup = SSdbcore.NewQuery("\
|
||||
WITH DISTINCT_TICKETS AS ( \
|
||||
SELECT id, round_id, ticket, sender, recipient FROM [format_table_name("ticket")] \
|
||||
WHERE id IN ( \
|
||||
SELECT MAX(id) FROM ticket GROUP BY round_id, ticket \
|
||||
) \
|
||||
AND round_id != :current_round \
|
||||
) \
|
||||
SELECT round_id, ticket FROM DISTINCT_TICKETS \
|
||||
WHERE sender = :ckey OR recipient = :ckey \
|
||||
ORDER BY id DESC \
|
||||
LIMIT :max_entries",
|
||||
list(
|
||||
"ckey" = ckey,
|
||||
"current_round" = GLOB.round_id,
|
||||
"max_entries" = entries,
|
||||
)
|
||||
)
|
||||
if(!ticket_lookup.Execute())
|
||||
qdel(ticket_lookup)
|
||||
to_chat(usr, "Failed to query ticket history for [ckey]!")
|
||||
return
|
||||
|
||||
var/list/lookup_targets = list()
|
||||
// round-ticket
|
||||
while(ticket_lookup.NextRow())
|
||||
lookup_targets += "[ticket_lookup.item[1]]-[ticket_lookup.item[2]]"
|
||||
qdel(ticket_lookup)
|
||||
|
||||
for(var/lookup_string in lookup_targets)
|
||||
ASYNC
|
||||
var/datum/ticket_history/ticket_history = new
|
||||
history_cache += ticket_history
|
||||
|
||||
var/round = splittext(lookup_string, "-")[1]
|
||||
var/ticket = splittext(lookup_string, "-")[2]
|
||||
|
||||
ticket_history.round_id = text2num(round)
|
||||
ticket_history.ticket_number = text2num(ticket)
|
||||
|
||||
var/datum/db_query/ticket_lookup_instance = SSdbcore.NewQuery("\
|
||||
SELECT action, message, timestamp, recipient, sender \
|
||||
FROM [format_table_name("ticket")] \
|
||||
WHERE round_id = :round AND ticket = :ticket \
|
||||
ORDER BY id DESC \
|
||||
", list(
|
||||
"round" = round,
|
||||
"ticket" = ticket
|
||||
))
|
||||
if(!ticket_lookup_instance.warn_execute())
|
||||
qdel(ticket_lookup_instance)
|
||||
lookup_targets -= lookup_string
|
||||
continue
|
||||
|
||||
var/list/ticket_log = list()
|
||||
while(ticket_lookup_instance.NextRow())
|
||||
var/datum/ticket_log_entry/log_entry = new
|
||||
ticket_log += log_entry
|
||||
log_entry.action = ticket_lookup_instance.item[1]
|
||||
log_entry.message = ticket_lookup_instance.item[2]
|
||||
log_entry.timestamp = ticket_lookup_instance.item[3]
|
||||
log_entry.target_ckey = ticket_lookup_instance.item[4]
|
||||
log_entry.origin_ckey = ticket_lookup_instance.item[5]
|
||||
qdel(ticket_lookup_instance)
|
||||
ticket_history.ticket_log = ticket_log
|
||||
lookup_targets -= lookup_string
|
||||
|
||||
// wait for all the queries to finish
|
||||
UNTIL(lookup_targets.len == 0)
|
||||
|
||||
if(!length(history_cache))
|
||||
to_chat(usr, span_adminnotice("No ticket history found for [ckey]!"))
|
||||
ticket_histories -= ckey
|
||||
return
|
||||
|
||||
to_chat(usr, span_adminnotice("Finished caching ticket history for [ckey]!"))
|
||||
|
||||
/datum/ticket_history_holder/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/ticket_history_holder/ui_static_data(mob/user)
|
||||
if(!check_rights_for(CLIENT_FROM_VAR(user), R_ADMIN))
|
||||
return list()
|
||||
|
||||
if(!SSdbcore.IsConnected())
|
||||
return list(
|
||||
"db_connected" = 0,
|
||||
)
|
||||
|
||||
var/list/data = list(
|
||||
"db_connected" = TRUE,
|
||||
)
|
||||
var/list/cached_ckeys = list()
|
||||
for(var/ckey in ticket_histories)
|
||||
cached_ckeys += ckey
|
||||
data["cached_ckeys"] = cached_ckeys
|
||||
|
||||
if(user.ckey in user_selections)
|
||||
var/list/ticket_cache = list()
|
||||
for(var/datum/ticket_history/ticket_history as anything in ticket_histories[user_selections[user.ckey]])
|
||||
var/list/ticket_data = list(
|
||||
"ticket_number" = ticket_history.ticket_number,
|
||||
"round_id" = ticket_history.round_id,
|
||||
)
|
||||
var/list/ticket_log = list()
|
||||
for(var/datum/ticket_log_entry/entry as anything in ticket_history.ticket_log)
|
||||
ticket_log += list(list(
|
||||
"timestamp" = entry.timestamp,
|
||||
"origin_ckey" = entry.origin_ckey,
|
||||
"target_ckey" = entry.target_ckey,
|
||||
"action" = entry.action,
|
||||
"message" = entry.message,
|
||||
))
|
||||
|
||||
ticket_data["ticket_log"] = ticket_log
|
||||
ticket_cache += list(ticket_data)
|
||||
data["ticket_cache"] = ticket_cache
|
||||
data["target_ckey"] = user_selections[user.ckey]
|
||||
|
||||
return data
|
||||
|
||||
/datum/ticket_history_holder/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("select-user")
|
||||
var/target = params["target"]
|
||||
if(!(target in ticket_histories))
|
||||
return TRUE
|
||||
user_selections[ui.user.ckey] = target
|
||||
SStgui.update_static_data(ui.user, ui)
|
||||
return TRUE
|
||||
|
||||
if("cache-user")
|
||||
var/target = params["target"]
|
||||
var/amount = ("amount" in params) ? params["amount"] : 5
|
||||
cache_history_for_ckey(target, amount)
|
||||
SStgui.update_static_data(ui.user, ui)
|
||||
return TRUE
|
||||
|
||||
else
|
||||
stack_trace("[type]/ui_act: unknown action type [action]")
|
||||
|
||||
/datum/ticket_history_holder/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!isnull(ui))
|
||||
ui.send_full_update()
|
||||
return
|
||||
|
||||
ui = new(user, src, "PlayerTicketHistory")
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
Reference in New Issue
Block a user