mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
[MIRROR] Server logs (#10486)
Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
37ad599827
commit
11a5a81208
@@ -77,5 +77,10 @@
|
|||||||
#define AHELP_CLOSED 2
|
#define AHELP_CLOSED 2
|
||||||
#define AHELP_RESOLVED 3
|
#define AHELP_RESOLVED 3
|
||||||
|
|
||||||
|
// LOG BROWSE TYPES
|
||||||
|
#define BROWSE_ROOT_ALL_LOGS 1
|
||||||
|
#define BROWSE_ROOT_RUNTIME_LOGS 2
|
||||||
|
#define BROWSE_ROOT_CURRENT_LOGS 3
|
||||||
|
|
||||||
/// A value for /datum/admins/cached_feedback_link to indicate empty, rather than unobtained
|
/// A value for /datum/admins/cached_feedback_link to indicate empty, rather than unobtained
|
||||||
#define NO_FEEDBACK_LINK "no_feedback_link"
|
#define NO_FEEDBACK_LINK "no_feedback_link"
|
||||||
|
|||||||
@@ -12,6 +12,9 @@
|
|||||||
/// Simply removes the < and > characters, and limits the length of the message.
|
/// Simply removes the < and > characters, and limits the length of the message.
|
||||||
#define STRIP_HTML_SIMPLE(text, limit) (GLOB.angular_brackets.Replace(copytext(text, 1, limit), ""))
|
#define STRIP_HTML_SIMPLE(text, limit) (GLOB.angular_brackets.Replace(copytext(text, 1, limit), ""))
|
||||||
|
|
||||||
|
/// Removes characters incompatible with file names.
|
||||||
|
#define SANITIZE_FILENAME(text) (GLOB.filename_forbidden_chars.Replace(text, ""))
|
||||||
|
|
||||||
#define MAX_MESSAGE_CHUNKS 130
|
#define MAX_MESSAGE_CHUNKS 130
|
||||||
|
|
||||||
#define MAX_TGUI_INPUT (MAX_MESSAGE_CHUNKS * 1024)
|
#define MAX_TGUI_INPUT (MAX_MESSAGE_CHUNKS * 1024)
|
||||||
|
|||||||
@@ -7,3 +7,8 @@ GLOBAL_DATUM_INIT(is_valid_url, /regex, regex("((?:https://)\[-a-zA-Z0-9@:%._+~#
|
|||||||
GLOBAL_DATUM_INIT(angular_brackets, /regex, regex(@"[<>]", "g"))
|
GLOBAL_DATUM_INIT(angular_brackets, /regex, regex(@"[<>]", "g"))
|
||||||
|
|
||||||
GLOBAL_DATUM_INIT(is_color, /regex, regex("^#\[0-9a-fA-F]{6}$"))
|
GLOBAL_DATUM_INIT(is_color, /regex, regex("^#\[0-9a-fA-F]{6}$"))
|
||||||
|
|
||||||
|
//All characters forbidden by filenames: ", \, \n, \t, /, ?, %, *, :, |, <, >, ..
|
||||||
|
GLOBAL_DATUM_INIT(filename_forbidden_chars, /regex, regex(@{""|[\\\n\t/?%*:|<>]|\.\."}, "g"))
|
||||||
|
GLOBAL_PROTECT(filename_forbidden_chars)
|
||||||
|
// had to use the OR operator for quotes instead of putting them in the character class because it breaks the syntax highlighting otherwise.
|
||||||
|
|||||||
@@ -12,52 +12,112 @@
|
|||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
//Sends resource files to client cache
|
/**
|
||||||
/client/proc/getFiles()
|
* For FTP requests. (i.e. downloading runtime logs.)
|
||||||
for(var/file in args)
|
*
|
||||||
src << browse_rsc(file)
|
* However it'd be ok to use for accessing attack logs and such too, which are even laggier.
|
||||||
|
*/
|
||||||
|
GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||||
|
|
||||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list(".txt",".log",".htm"))
|
/client/proc/browse_files(root_type=BROWSE_ROOT_ALL_LOGS, max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "gz", "json"))
|
||||||
|
// wow why was this ever a parameter
|
||||||
|
var/root = "data/logs/"
|
||||||
|
switch(root_type)
|
||||||
|
if(BROWSE_ROOT_ALL_LOGS)
|
||||||
|
root = "data/logs/"
|
||||||
|
if(BROWSE_ROOT_CURRENT_LOGS)
|
||||||
|
root = log_path
|
||||||
var/path = root
|
var/path = root
|
||||||
|
|
||||||
for(var/i=0, i<max_iterations, i++)
|
for(var/i in 1 to max_iterations)
|
||||||
var/list/choices = sortList(flist(path))
|
var/list/choices = flist(path)
|
||||||
if(path != root)
|
if(path != root)
|
||||||
choices.Insert(1,"/")
|
choices.Insert(1,"/")
|
||||||
|
choices = sortList(choices) + "Download Folder"
|
||||||
|
|
||||||
var/choice = tgui_input_list(src, "Choose a file to access:", "Download", choices)
|
var/choice = tgui_input_list(src,"Choose a file to access:","Download",choices)
|
||||||
switch(choice)
|
switch(choice)
|
||||||
if(null)
|
if(null)
|
||||||
return
|
return
|
||||||
if("/")
|
if("/")
|
||||||
path = root
|
path = root
|
||||||
continue
|
continue
|
||||||
|
if("Download Folder")
|
||||||
|
var/list/comp_flist = flist(path)
|
||||||
|
var/confirmation = tgui_alert(src, "Are you SURE you want to download all the files in this folder? (This will open [length(comp_flist)] prompt[length(comp_flist) == 1 ? "" : "s"])", "Confirmation", list("Yes", "No"))
|
||||||
|
if(confirmation != "Yes")
|
||||||
|
continue
|
||||||
|
for(var/file in comp_flist)
|
||||||
|
src << ftp(path + file)
|
||||||
|
return
|
||||||
path += choice
|
path += choice
|
||||||
|
|
||||||
if(copytext(path,-1,0) != "/") //didn't choose a directory, no need to iterate again
|
if(copytext_char(path, -1) != "/") //didn't choose a directory, no need to iterate again
|
||||||
break
|
break
|
||||||
|
var/extensions
|
||||||
var/extension = copytext(path,-4,0)
|
for(var/i in valid_extensions)
|
||||||
if( !fexists(path) || !(extension in valid_extensions) )
|
if(extensions)
|
||||||
|
extensions += "|"
|
||||||
|
extensions += "[i]"
|
||||||
|
var/regex/valid_ext = new("\\.([extensions])$", "i")
|
||||||
|
if( !fexists(path) || !(valid_ext.Find(path)) )
|
||||||
to_chat(src, span_red("Error: browse_files(): File not found/Invalid file([path])."))
|
to_chat(src, span_red("Error: browse_files(): File not found/Invalid file([path])."))
|
||||||
return
|
return
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
#define FTPDELAY 200 //200 tick delay to discourage spam
|
#define FTPDELAY 200 //200 tick delay to discourage spam
|
||||||
/* This proc is a failsafe to prevent spamming of file requests.
|
#define ADMIN_FTPDELAY_MODIFIER 0.5 //Admins get to spam files faster since we ~trust~ them!
|
||||||
|
/* This proc is a failsafe to prevent spamming of file requests.
|
||||||
It is just a timer that only permits a download every [FTPDELAY] ticks.
|
It is just a timer that only permits a download every [FTPDELAY] ticks.
|
||||||
This can be changed by modifying FTPDELAY's value above.
|
This can be changed by modifying FTPDELAY's value above.
|
||||||
|
|
||||||
PLEASE USE RESPONSIBLY, Some log files canr each sizes of 4MB! */
|
PLEASE USE RESPONSIBLY, Some log files can reach sizes of 4MB! */
|
||||||
/client/proc/file_spam_check()
|
/client/proc/file_spam_check()
|
||||||
var/time_to_wait = fileaccess_timer - world.time
|
var/time_to_wait = GLOB.fileaccess_timer - world.time
|
||||||
if(time_to_wait > 0)
|
if(time_to_wait > 0)
|
||||||
to_chat(src, span_red("Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds."))
|
to_chat(src, span_red("Error: file_spam_check(): Spam. Please wait [DisplayTimeText(time_to_wait)]."))
|
||||||
return 1
|
return TRUE
|
||||||
fileaccess_timer = world.time + FTPDELAY
|
var/delay = FTPDELAY
|
||||||
return 0
|
if(holder)
|
||||||
|
delay *= ADMIN_FTPDELAY_MODIFIER
|
||||||
|
GLOB.fileaccess_timer = world.time + delay
|
||||||
|
return FALSE
|
||||||
#undef FTPDELAY
|
#undef FTPDELAY
|
||||||
|
#undef ADMIN_FTPDELAY_MODIFIER
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a directory and returns every file within every sub directory.
|
||||||
|
* If extensions_filter is provided then only files that end in that extension are given back.
|
||||||
|
* If extensions_filter is a list, any file that matches at least one entry is given back.
|
||||||
|
*/
|
||||||
|
/proc/pathwalk(path, extensions_filter)
|
||||||
|
var/list/jobs = list(path)
|
||||||
|
var/list/filenames = list()
|
||||||
|
|
||||||
|
while(jobs.len)
|
||||||
|
var/current_dir = pop(jobs)
|
||||||
|
var/list/new_filenames = flist(current_dir)
|
||||||
|
for(var/new_filename in new_filenames)
|
||||||
|
// if filename ends in / it is a directory, append to currdir
|
||||||
|
if(findtext(new_filename, "/", -1))
|
||||||
|
jobs += "[current_dir][new_filename]"
|
||||||
|
continue
|
||||||
|
// filename extension filtering
|
||||||
|
if(extensions_filter)
|
||||||
|
if(islist(extensions_filter))
|
||||||
|
for(var/allowed_extension in extensions_filter)
|
||||||
|
if(endswith(new_filename, allowed_extension))
|
||||||
|
filenames += "[current_dir][new_filename]"
|
||||||
|
break
|
||||||
|
else if(endswith(new_filename, extensions_filter))
|
||||||
|
filenames += "[current_dir][new_filename]"
|
||||||
|
else
|
||||||
|
filenames += "[current_dir][new_filename]"
|
||||||
|
return filenames
|
||||||
|
|
||||||
|
/proc/pathflatten(path)
|
||||||
|
return replacetext(path, "/", "_")
|
||||||
|
|
||||||
/// Returns the md5 of a file at a given path.
|
/// Returns the md5 of a file at a given path.
|
||||||
/proc/md5filepath(path)
|
/proc/md5filepath(path)
|
||||||
@@ -65,6 +125,7 @@
|
|||||||
|
|
||||||
/// Save file as an external file then md5 it.
|
/// Save file as an external file then md5 it.
|
||||||
/// Used because md5ing files stored in the rsc sometimes gives incorrect md5 results.
|
/// Used because md5ing files stored in the rsc sometimes gives incorrect md5 results.
|
||||||
|
/// https://www.byond.com/forum/post/2611357
|
||||||
/proc/md5asfile(file)
|
/proc/md5asfile(file)
|
||||||
var/static/notch = 0
|
var/static/notch = 0
|
||||||
// its importaint this code can handle md5filepath sleeping instead of hard blocking, if it's converted to use rust_g.
|
// its importaint this code can handle md5filepath sleeping instead of hard blocking, if it's converted to use rust_g.
|
||||||
@@ -73,3 +134,23 @@
|
|||||||
fcopy(file, filename)
|
fcopy(file, filename)
|
||||||
. = md5filepath(filename)
|
. = md5filepath(filename)
|
||||||
fdel(filename)
|
fdel(filename)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes the name of each node in the path.
|
||||||
|
*
|
||||||
|
* Im case you are wondering when to use this proc and when to use SANITIZE_FILENAME,
|
||||||
|
*
|
||||||
|
* You use SANITIZE_FILENAME to sanitize the name of a file [e.g. example.txt]
|
||||||
|
*
|
||||||
|
* You use sanitize_filepath sanitize the path of a file [e.g. root/node/example.txt]
|
||||||
|
*
|
||||||
|
* If you use SANITIZE_FILENAME to sanitize a file path things will break.
|
||||||
|
*/
|
||||||
|
/proc/sanitize_filepath(path)
|
||||||
|
. = ""
|
||||||
|
var/delimiter = "/" //Very much intentionally hardcoded
|
||||||
|
var/list/all_nodes = splittext(path, delimiter)
|
||||||
|
for(var/node in all_nodes)
|
||||||
|
if(.)
|
||||||
|
. += delimiter // Add the delimiter before each successive node.
|
||||||
|
. += SANITIZE_FILENAME(node)
|
||||||
|
|||||||
@@ -661,8 +661,7 @@ GLOBAL_LIST_EMPTY(cached_examine_icons)
|
|||||||
|
|
||||||
if (!isicon(icon2collapse))
|
if (!isicon(icon2collapse))
|
||||||
if (isfile(thing)) //special snowflake
|
if (isfile(thing)) //special snowflake
|
||||||
//var/name = SANITIZE_FILENAME("[generate_asset_name(thing)].png")
|
var/name = SANITIZE_FILENAME("[generate_asset_name(thing)].png")
|
||||||
var/name = "[generate_asset_name(thing)].png"
|
|
||||||
if (!SSassets.cache[name])
|
if (!SSassets.cache[name])
|
||||||
SSassets.transport.register_asset(name, thing)
|
SSassets.transport.register_asset(name, thing)
|
||||||
for (var/thing2 in targets)
|
for (var/thing2 in targets)
|
||||||
|
|||||||
@@ -632,6 +632,18 @@ GLOBAL_LIST_EMPTY(text_tag_cache)
|
|||||||
var/static/regex/regex = new(@"[^a-zA-Z0-9]","g")
|
var/static/regex/regex = new(@"[^a-zA-Z0-9]","g")
|
||||||
return replacetext(name, regex, "")
|
return replacetext(name, regex, "")
|
||||||
|
|
||||||
|
/// Returns TRUE if the input_text ends with the ending
|
||||||
|
/proc/endswith(input_text, ending)
|
||||||
|
var/input_length = LAZYLEN(ending)
|
||||||
|
return !!findtext(input_text, ending, -input_length)
|
||||||
|
|
||||||
|
/// Returns TRUE if the input_text starts with any of the beginnings
|
||||||
|
/proc/starts_with_any(input_text, list/beginnings)
|
||||||
|
for(var/beginning in beginnings)
|
||||||
|
if(!!findtext(input_text, beginning, 1, LAZYLEN(beginning)+1))
|
||||||
|
return TRUE
|
||||||
|
return FALSE
|
||||||
|
|
||||||
//finds the first occurrence of one of the characters from needles argument inside haystack
|
//finds the first occurrence of one of the characters from needles argument inside haystack
|
||||||
//it may appear this can be optimised, but it really can't. findtext() is so much faster than anything you can do in byondcode.
|
//it may appear this can be optimised, but it really can't. findtext() is so much faster than anything you can do in byondcode.
|
||||||
//stupid byond :(
|
//stupid byond :(
|
||||||
|
|||||||
@@ -45,8 +45,6 @@ var/list/admin_verbs_admin = list(
|
|||||||
/client/proc/mark_datum_mapview, //VOREStation Add,
|
/client/proc/mark_datum_mapview, //VOREStation Add,
|
||||||
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
/client/proc/cmd_check_new_players, //allows us to see every new player, //VOREStation Add,
|
||||||
/client/proc/toggle_view_range, //changes how far we can see,
|
/client/proc/toggle_view_range, //changes how far we can see,
|
||||||
/datum/admins/proc/view_txt_log, //shows the server log (diary) for today,
|
|
||||||
/datum/admins/proc/view_atk_log, //shows the server combat-log, doesn't do anything presently,
|
|
||||||
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
/client/proc/cmd_admin_pm_context, //right-click adminPM interface,
|
||||||
/client/proc/cmd_admin_pm_panel, //admin-pm list,
|
/client/proc/cmd_admin_pm_panel, //admin-pm list,
|
||||||
/client/proc/cmd_admin_subtle_message, //send an message to somebody as a 'voice in their head',
|
/client/proc/cmd_admin_subtle_message, //send an message to somebody as a 'voice in their head',
|
||||||
@@ -55,7 +53,6 @@ var/list/admin_verbs_admin = list(
|
|||||||
/client/proc/cmd_admin_check_player_logs, //checks a player's attack logs,
|
/client/proc/cmd_admin_check_player_logs, //checks a player's attack logs,
|
||||||
/client/proc/cmd_admin_check_dialogue_logs, //checks a player's dialogue logs,
|
/client/proc/cmd_admin_check_dialogue_logs, //checks a player's dialogue logs,
|
||||||
/datum/admins/proc/access_news_network, //allows access of newscasters,
|
/datum/admins/proc/access_news_network, //allows access of newscasters,
|
||||||
/client/proc/giveruntimelog, //allows us to give access to runtime logs to somebody,
|
|
||||||
/client/proc/getserverlog, //allows us to fetch server logs (diary) for other days,
|
/client/proc/getserverlog, //allows us to fetch server logs (diary) for other days,
|
||||||
/client/proc/jumptocoord, //we ghost and jump to a coordinate,
|
/client/proc/jumptocoord, //we ghost and jump to a coordinate,
|
||||||
/client/proc/Getmob, //teleports a mob to our location,
|
/client/proc/Getmob, //teleports a mob to our location,
|
||||||
@@ -236,8 +233,6 @@ var/list/admin_verbs_server = list(
|
|||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_debug = list(
|
var/list/admin_verbs_debug = list(
|
||||||
/client/proc/reload_configuration, // CHOMPEdit
|
|
||||||
/client/proc/getruntimelog, //allows us to access runtime logs to somebody,
|
|
||||||
/client/proc/cmd_admin_list_open_jobs,
|
/client/proc/cmd_admin_list_open_jobs,
|
||||||
/client/proc/Debug2,
|
/client/proc/Debug2,
|
||||||
/client/proc/kill_air,
|
/client/proc/kill_air,
|
||||||
@@ -298,7 +293,8 @@ var/list/admin_verbs_debug = list(
|
|||||||
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
||||||
/datum/admins/proc/quick_authentic_nif, //CHOMPStation add
|
/datum/admins/proc/quick_authentic_nif, //CHOMPStation add
|
||||||
/client/proc/reload_jobwhitelist, //ChompADD
|
/client/proc/reload_jobwhitelist, //ChompADD
|
||||||
/client/proc/reload_alienwhitelist //ChompADD
|
/client/proc/reload_alienwhitelist, //ChompADD
|
||||||
|
/client/proc/reload_configuration //CHOMPAdd
|
||||||
)
|
)
|
||||||
|
|
||||||
var/list/admin_verbs_paranoid_debug = list(
|
var/list/admin_verbs_paranoid_debug = list(
|
||||||
@@ -328,8 +324,6 @@ var/list/admin_verbs_hideable = list(
|
|||||||
/datum/admins/proc/announce,
|
/datum/admins/proc/announce,
|
||||||
/client/proc/admin_ghost,
|
/client/proc/admin_ghost,
|
||||||
/client/proc/toggle_view_range,
|
/client/proc/toggle_view_range,
|
||||||
/datum/admins/proc/view_txt_log,
|
|
||||||
/datum/admins/proc/view_atk_log,
|
|
||||||
/client/proc/cmd_admin_subtle_message,
|
/client/proc/cmd_admin_subtle_message,
|
||||||
/client/proc/cmd_admin_check_contents,
|
/client/proc/cmd_admin_check_contents,
|
||||||
/client/proc/cmd_admin_check_player_logs,
|
/client/proc/cmd_admin_check_player_logs,
|
||||||
@@ -429,8 +423,6 @@ var/list/admin_verbs_mod = list(
|
|||||||
/datum/admins/proc/sendFax,
|
/datum/admins/proc/sendFax,
|
||||||
/client/proc/getserverlog, //allows us to fetch server logs (diary) for other days,
|
/client/proc/getserverlog, //allows us to fetch server logs (diary) for other days,
|
||||||
/datum/admins/proc/view_persistent_data,
|
/datum/admins/proc/view_persistent_data,
|
||||||
/datum/admins/proc/view_txt_log, //shows the server log (diary) for today,
|
|
||||||
/datum/admins/proc/view_atk_log, //shows the server combat-log, doesn't do anything presently,
|
|
||||||
/client/proc/start_vote,
|
/client/proc/start_vote,
|
||||||
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
/datum/admins/proc/quick_nif, //CHOMPStation Add,
|
||||||
/client/proc/reload_jobwhitelist, //ChompADD
|
/client/proc/reload_jobwhitelist, //ChompADD
|
||||||
|
|||||||
@@ -1,70 +1,20 @@
|
|||||||
/*
|
|
||||||
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 Game Masters to grant a client access to the .getruntimelog verb
|
|
||||||
//Permissions expire at the end of each round.
|
|
||||||
//Runtimes can be used to meta or spot game-crashing exploits so it's advised to only grant coders that
|
|
||||||
//you trust access. Also, it may be wise to ensure that they are not going to play in the current round.
|
|
||||||
/client/proc/giveruntimelog()
|
|
||||||
set name = ".giveruntimelog"
|
|
||||||
set desc = "Give somebody access to any session logfiles saved to the /log/runtime/ folder."
|
|
||||||
set category = null
|
|
||||||
|
|
||||||
if(!src.holder)
|
|
||||||
to_chat(src, span_red("Only Admins may use this command."))
|
|
||||||
return
|
|
||||||
|
|
||||||
var/client/target = tgui_input_list(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions", GLOB.clients)
|
|
||||||
if(!istype(target,/client))
|
|
||||||
to_chat(src, span_red("Error: giveruntimelog(): Client not found."))
|
|
||||||
return
|
|
||||||
|
|
||||||
add_verb(target, /client/proc/getruntimelog)
|
|
||||||
to_chat(target, span_red("You have been granted access to runtime logs. Please use them responsibly or risk being banned."))
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
//This proc allows download of runtime logs saved within the data/logs/ folder by dreamdeamon.
|
|
||||||
//It works similarly to show-server-log.
|
|
||||||
/client/proc/getruntimelog()
|
|
||||||
set name = ".getruntimelog"
|
|
||||||
set desc = "Retrieve any session logfiles saved by dreamdeamon."
|
|
||||||
set category = null
|
|
||||||
|
|
||||||
var/path = browse_files("data/logs/runtime/")
|
|
||||||
if(!path)
|
|
||||||
return
|
|
||||||
|
|
||||||
if(file_spam_check())
|
|
||||||
return
|
|
||||||
|
|
||||||
message_admins("[key_name_admin(src)] accessed file: [path]")
|
|
||||||
src << run( file(path) )
|
|
||||||
to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.")
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
//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.
|
||||||
//It works similarly to show-server-log.
|
//It works similarly to show-server-log.
|
||||||
/client/proc/getserverlog()
|
/client/proc/getserverlog()
|
||||||
set name = ".getserverlog"
|
set name = "Get Server Logs"
|
||||||
set desc = "Fetch logfiles from data/logs"
|
set desc = "Fetch logfiles from data/logs"
|
||||||
set category = null
|
set category = "Admin.Logs"
|
||||||
|
browseserverlogs()
|
||||||
|
|
||||||
var/path = browse_files("data/logs/")
|
|
||||||
|
/client/proc/browseserverlogs(current=FALSE, runtimes=FALSE)
|
||||||
|
var/log_choice = BROWSE_ROOT_ALL_LOGS
|
||||||
|
if(current)
|
||||||
|
log_choice = BROWSE_ROOT_CURRENT_LOGS
|
||||||
|
else if (runtimes)
|
||||||
|
log_choice = BROWSE_ROOT_RUNTIME_LOGS
|
||||||
|
var/path = browse_files(log_choice)
|
||||||
|
feedback_add_details("admin_verb","VTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||||
if(!path)
|
if(!path)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -72,44 +22,13 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
message_admins("[key_name_admin(src)] accessed file: [path]")
|
message_admins("[key_name_admin(src)] accessed file: [path]")
|
||||||
src << run( file(path) )
|
switch(tgui_alert(src,"View (in game), Open (in your system's text editor), or Download?", path, list("View", "Open", "Download")))
|
||||||
to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.")
|
if ("View")
|
||||||
return
|
src << browse("<html><pre style='word-wrap: break-word;'>[html_encode(file2text(file(path)))]</pre></html>", list2params(list("window" = "viewfile.[path]")))
|
||||||
|
if ("Open")
|
||||||
|
src << run(file(path))
|
||||||
//Other log stuff put here for the sake of organisation
|
if ("Download")
|
||||||
|
src << ftp(file(path))
|
||||||
//Shows today's server log
|
else
|
||||||
/datum/admins/proc/view_txt_log()
|
return
|
||||||
set category = "Admin.Logs"
|
to_chat(src, "Attempting to send [path], this may take a fair few minutes if the file is very large.", confidential = TRUE)
|
||||||
set name = "Show Server Log"
|
|
||||||
set desc = "Shows today's server log."
|
|
||||||
|
|
||||||
var/path = "[log_path].log"
|
|
||||||
if( fexists(path) )
|
|
||||||
src << run( file(path) )
|
|
||||||
else
|
|
||||||
to_chat(src, span_red("Error: view_txt_log(): File not found/Invalid path([path])."))
|
|
||||||
return
|
|
||||||
feedback_add_details("admin_verb","VTL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
||||||
return
|
|
||||||
|
|
||||||
//Shows today's attack log
|
|
||||||
/datum/admins/proc/view_atk_log()
|
|
||||||
set category = "Admin.Logs"
|
|
||||||
set name = "Show Server Attack Log"
|
|
||||||
set desc = "Shows today's server attack log."
|
|
||||||
|
|
||||||
to_chat(usr, "This verb doesn't actually do anything.")
|
|
||||||
|
|
||||||
/*
|
|
||||||
var/path = "data/logs/[time2text(world.realtime,"YYYY/MM-Month/DD-Day")] Attack.log"
|
|
||||||
if( fexists(path) )
|
|
||||||
src << run( file(path) )
|
|
||||||
else
|
|
||||||
to_chat(src, span_red("<Error: view_atk_log(): File not found/Invalid path([path])."))
|
|
||||||
return
|
|
||||||
usr << run( file(path) )
|
|
||||||
feedback_add_details("admin_verb","SSAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
|
||||||
return
|
|
||||||
*/
|
|
||||||
|
|||||||
Reference in New Issue
Block a user