add admin verb for log access by round ID (#29174)

* add admin verb for log access by round ID

* Update code/modules/admin/verbs/getlogs.dm

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Signed-off-by: warriorstar-orion <orion@snowfrost.garden>

* add check_rights

---------

Signed-off-by: warriorstar-orion <orion@snowfrost.garden>
Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
This commit is contained in:
warriorstar-orion
2025-05-04 01:34:44 -04:00
committed by GitHub
parent 7bfa944664
commit b5fa9dda9f
4 changed files with 64 additions and 29 deletions
+1
View File
@@ -23,6 +23,7 @@ GLOBAL_LIST_INIT(admin_verbs_admin, list(
/client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/
/client/proc/cmd_admin_open_logging_view,
/client/proc/getserverlogs, /*allows us to fetch server logs (diary) for other days*/
/client/proc/get_server_logs_by_round_id,
/client/proc/Getmob, /*teleports a mob to our location*/
/client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/
/client/proc/jump_to, /*Opens a menu for jumping to an Area, Mob, Key or Coordinate*/
+55 -27
View File
@@ -1,41 +1,69 @@
/*
HOW DO I LOG RUNTIMES?
Firstly, start dreamdeamon if it isn't already running. Then select "world>Log Session" (or press the F3 key)
navigate the popup window to the data/logs/runtime/ folder from where your tgstation .dmb is located.
(you may have to make this folder yourself)
OPTIONAL: you can select the little checkbox down the bottom to make dreamdeamon save the log everytime you
start a world. Just remember to repeat these steps with a new name when you update to a new revision!
Save it with the name of the revision your server uses (e.g. r3459.txt).
Game Masters will now be able to grant access any runtime logs you have archived this way!
This will allow us to gather information on bugs across multiple servers and make maintaining the TG
codebase for the entire /TG/station commuity a TONNE easier :3 Thanks for your help!
*/
//This proc allows download of past server logs saved within the data/logs/ folder.
/// This proc allows download of past server logs saved within the data/logs/ folder.
/client/proc/getserverlogs()
set name = "Get Server Logs"
set desc = "View/retrieve logfiles."
set category = "Admin"
var/path = browse_files("data/logs/")
if(!path)
if(!check_rights(R_ADMIN))
return
if(file_spam_check())
access_file_by_browsing_path(usr, "data/logs/")
/// This proc allows download of past server logs saved within the data/logs/ folder by specifying a specific round ID.
/client/proc/get_server_logs_by_round_id()
set name = "Get Round Logs"
set desc = "View/retrieve logfiles for a given round."
set category = "Admin"
if(!check_rights(R_ADMIN))
return
message_admins("[key_name_admin(src)] accessed file: [path]")
switch(alert("View (in game), Open (in your system's text editor), or Download?", path, "View", "Open", "Download"))
var/round_id = input(usr, "Enter a round ID.", "Enter Round ID", "[GLOB.round_id]") as null|text
if(isnull(round_id))
return
var/round_path = "[GLOB.log_directory]/"
if(round_id != "[GLOB.round_id]")
var/datum/db_query/query = SSdbcore.NewQuery(
"SELECT UNIX_TIMESTAMP(initialize_datetime) AS dt FROM round WHERE id = :id",
list(id = round_id)
)
if(!query.warn_execute())
qdel(query)
to_chat(usr, "Could not check database for round [round_id].")
return
if(!query.NextRow())
qdel(query)
to_chat(usr, "Could not find round [round_id] in database.")
return
// convert unix timestamp in seconds to byond timestamp in deciseconds
var/round_datetime = (query.item[1] - BYOND_EPOCH_UNIX) * 10
round_path = "data/logs/[time2text(round_datetime, "YYYY/MM-Month/DD-Day")]/round-[round_id]/"
qdel(query)
access_file_by_browsing_path(usr, round_path)
/proc/access_file_by_browsing_path(mob/user, path)
if(!user.client)
return
var/filename = user.client.browse_files(path)
if(!filename)
return
if(user.client.file_spam_check())
return
message_admins("[key_name_admin(user)] accessed file: [filename]")
switch(alert("View (in game), Open (in your system's text editor), or Download?", filename, "View", "Open", "Download"))
if("View")
src << browse("<pre style='word-wrap: break-word;'>[html_encode(wrap_file2text(wrap_file(path)))]</pre>", list2params(list("window" = "viewfile.[path]")))
user << browse("<pre style='word-wrap: break-word;'>[html_encode(wrap_file2text(wrap_file(filename)))]</pre>", list2params(list("window" = "viewfile.[filename]")))
if("Open")
src << run(wrap_file(path))
user << run(wrap_file(filename))
if("Download")
src << ftp(wrap_file(path))
user << ftp(wrap_file(filename))
else
return
to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.")
return
to_chat(user, "Attempting to send [filename], this may take a fair few minutes if the file is very large.")