Skip to content

Commit

Permalink
Add logging for manually changing your targeted zone (tgstation#72814)
Browse files Browse the repository at this point in the history
## About The Pull Request

See title.
Surgery hud is exempt from this.
## Why It's Good For The Game

Requested by @Mothblocks 
## Changelog

Signed-off-by: GitHub <noreply@github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
Co-authored-by: dragomagol <66640614+dragomagol@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 24, 2023
1 parent ac4bec4 commit 18b041b
Show file tree
Hide file tree
Showing 17 changed files with 229 additions and 76 deletions.
19 changes: 19 additions & 0 deletions code/__DEFINES/logging.dm
Expand Up @@ -54,6 +54,25 @@
#define LOGSRC_CKEY "Ckey"
#define LOGSRC_MOB "Mob"

// Log header keys
#define LOG_HEADER_CATEGORY "category"
#define LOG_HEADER_INIT_TIMESTAMP "timestamp"
#define LOG_HEADER_ROUND_ID "round_id"

// Log data keys
#define LOG_ENTRY_MESSAGE "message"
#define LOG_ENTRY_TIMESTAMP "timestamp"
#define LOG_ENTRY_DATA "data"

// Log json keys
#define LOG_JSON_CATEGORY "category"
#define LOG_JSON_ENTRIES "entries"
#define LOG_JSON_LOGGING_START "log_start"

// Log categories
#define LOG_CATEGORY_NOT_FOUND "invalid_category"
#define LOG_CATEGORY_TARGET_ZONE_SWITCH "target_zone_switch"

//wrapper macros for easier grepping
#define DIRECT_OUTPUT(A, B) A << B
#define DIRECT_INPUT(A, B) A >> B
Expand Down
1 change: 1 addition & 0 deletions code/__HELPERS/logging/_logging.dm
Expand Up @@ -128,6 +128,7 @@ GLOBAL_LIST_INIT(testing_global_profiler, list("_PROFILE_NAME" = "Global"))
/* Close open log handles. This should be called as late as possible, and no logging should hapen after. */
/proc/shutdown_logging()
rustg_log_close_all()
GLOB.logger.shutdown_logging()

/* Helper procs for building detailed log lines */
/proc/key_name(whom, include_link = null, include_name = TRUE)
Expand Down
1 change: 1 addition & 0 deletions code/__HELPERS/logging/game.dm
Expand Up @@ -32,3 +32,4 @@
/proc/log_vote(text)
if (CONFIG_GET(flag/log_vote))
WRITE_LOG(GLOB.world_game_log, "VOTE: [text]")

4 changes: 4 additions & 0 deletions code/__HELPERS/type2type.dm
Expand Up @@ -372,3 +372,7 @@ GLOBAL_LIST_INIT(modulo_angle_to_dir, list(NORTH,NORTHEAST,EAST,SOUTHEAST,SOUTH,
/// for use inside of browse() calls to html assets that might be loaded on a cdn.
/proc/url2htmlloader(url)
return {"<html><head><meta http-equiv="refresh" content="0;URL='[url]'"/></head><body onLoad="parent.location='[url]'"></body></html>"}

/// Formats a larger number to correct textual representation without losing data
/proc/big_number_to_text(number)
return num2text(number, INFINITY)
1 change: 0 additions & 1 deletion code/_globalvars/logging.dm
Expand Up @@ -146,4 +146,3 @@ GLOBAL_PROTECT(world_uplink_log)

GLOBAL_VAR(world_virus_log)
GLOBAL_PROTECT(world_virus_log)

4 changes: 3 additions & 1 deletion code/_onclick/hud/screen_objects.dm
Expand Up @@ -512,11 +512,13 @@
return BODY_ZONE_PRECISE_EYES
return BODY_ZONE_HEAD

/atom/movable/screen/zone_sel/proc/set_selected_zone(choice, mob/user)
/atom/movable/screen/zone_sel/proc/set_selected_zone(choice, mob/user, should_log = TRUE)
if(user != hud?.mymob)
return

if(choice != hud.mymob.zone_selected)
if(should_log)
hud.mymob.log_manual_zone_selected_update("screen_hud", new_target = choice)
hud.mymob.zone_selected = choice
update_appearance()
SEND_SIGNAL(user, COMSIG_MOB_SELECTED_ZONE_SET, choice)
Expand Down
3 changes: 3 additions & 0 deletions code/controllers/configuration/entries/general.dm
Expand Up @@ -103,6 +103,9 @@
/// log voting
/datum/config_entry/flag/log_vote

/// log manual zone switching
/datum/config_entry/flag/log_zone_switch

/// log client whisper
/datum/config_entry/flag/log_whisper

Expand Down
2 changes: 1 addition & 1 deletion code/datums/components/surgery_initiator.dm
Expand Up @@ -208,7 +208,7 @@
return TRUE

var/atom/movable/screen/zone_sel/zone_selector = user.hud_used?.zone_select
zone_selector?.set_selected_zone(zone, user)
zone_selector?.set_selected_zone(zone, user, should_log = FALSE)

return TRUE
if ("start_surgery")
Expand Down
3 changes: 3 additions & 0 deletions code/datums/json_savefile.dm
Expand Up @@ -57,6 +57,9 @@ GENERAL_PROTECT_DATUM(/datum/json_savefile)
if(path)
rustg_file_write(json_encode(tree), path)

/datum/json_savefile/serialize_list(list/options)
return tree.Copy()

/// Traverses the entire dir tree of the given savefile and dynamically assembles the tree from it
/datum/json_savefile/proc/import_byond_savefile(savefile/savefile)
tree.Cut()
Expand Down
111 changes: 39 additions & 72 deletions code/datums/keybinding/mob.dm
Expand Up @@ -106,132 +106,99 @@
M.toggle_move_intent()
return TRUE

/datum/keybinding/mob/target_head_cycle
/datum/keybinding/mob/target/down(client/user)
. = ..()
if(.)
return .

var/original = user.mob.zone_selected
switch(keybind_signal)
if(COMSIG_KB_MOB_TARGETCYCLEHEAD_DOWN)
user.body_toggle_head()
if(COMSIG_KB_MOB_TARGETEYES_DOWN)
user.body_eyes()
if(COMSIG_KB_MOB_TARGETMOUTH_DOWN)
user.body_mouth()
if(COMSIG_KB_MOB_TARGETRIGHTARM_DOWN)
user.body_r_arm()
if(COMSIG_KB_MOB_TARGETBODYCHEST_DOWN)
user.body_chest()
if(COMSIG_KB_MOB_TARGETLEFTARM_DOWN)
user.body_l_arm()
if(COMSIG_KB_MOB_TARGETRIGHTLEG_DOWN)
user.body_r_leg()
if(COMSIG_KB_MOB_TARGETBODYGROIN_DOWN)
user.body_groin()
if(COMSIG_KB_MOB_TARGETLEFTLEG_DOWN)
user.body_l_leg()
else
stack_trace("Target keybind pressed but not implemented! '[keybind_signal]'")
return FALSE
user.mob.log_manual_zone_selected_update("keybind", old_target = original)

/datum/keybinding/mob/target/head_cycle
hotkey_keys = list("Numpad8")
name = "target_head_cycle"
full_name = "Target: Cycle Head"
description = "Pressing this key targets the head, and continued presses will cycle to the eyes and mouth. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETCYCLEHEAD_DOWN

/datum/keybinding/mob/target_head_cycle/down(client/user)
. = ..()
if(.)
return
user.body_toggle_head()
return TRUE

/datum/keybinding/mob/target_eyes
/datum/keybinding/mob/target/eyes
hotkey_keys = list("Numpad7")
name = "target_eyes"
full_name = "Target: Eyes"
description = "Pressing this key targets the eyes. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETEYES_DOWN

/datum/keybinding/mob/target_eyes/down(client/user)
. = ..()
if(.)
return
user.body_eyes()
return TRUE

/datum/keybinding/mob/target_mouth
/datum/keybinding/mob/target/mouth
hotkey_keys = list("Numpad9")
name = "target_mouths"
full_name = "Target: Mouth"
description = "Pressing this key targets the mouth. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETMOUTH_DOWN

/datum/keybinding/mob/target_mouth/down(client/user)
. = ..()
if(.)
return
user.body_mouth()
return TRUE

/datum/keybinding/mob/target_r_arm
/datum/keybinding/mob/target/r_arm
hotkey_keys = list("Numpad4")
name = "target_r_arm"
full_name = "Target: right arm"
description = "Pressing this key targets the right arm. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETRIGHTARM_DOWN

/datum/keybinding/mob/target_r_arm/down(client/user)
. = ..()
if(.)
return
user.body_r_arm()
return TRUE

/datum/keybinding/mob/target_body_chest
/datum/keybinding/mob/target/body_chest
hotkey_keys = list("Numpad5")
name = "target_body_chest"
full_name = "Target: Body"
description = "Pressing this key targets the body. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETBODYCHEST_DOWN

/datum/keybinding/mob/target_body_chest/down(client/user)
. = ..()
if(.)
return
user.body_chest()
return TRUE

/datum/keybinding/mob/target_left_arm
/datum/keybinding/mob/target/left_arm
hotkey_keys = list("Numpad6")
name = "target_left_arm"
full_name = "Target: left arm"
description = "Pressing this key targets the body. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETLEFTARM_DOWN

/datum/keybinding/mob/target_left_arm/down(client/user)
. = ..()
if(.)
return
user.body_l_arm()
return TRUE

/datum/keybinding/mob/target_right_leg
/datum/keybinding/mob/target/right_leg
hotkey_keys = list("Numpad1")
name = "target_right_leg"
full_name = "Target: Right leg"
description = "Pressing this key targets the right leg. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETRIGHTLEG_DOWN

/datum/keybinding/mob/target_right_leg/down(client/user)
. = ..()
if(.)
return
user.body_r_leg()
return TRUE

/datum/keybinding/mob/target_body_groin
/datum/keybinding/mob/target/body_groin
hotkey_keys = list("Numpad2")
name = "target_body_groin"
full_name = "Target: Groin"
description = "Pressing this key targets the groin. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETBODYGROIN_DOWN

/datum/keybinding/mob/target_body_groin/down(client/user)
. = ..()
if(.)
return
user.body_groin()
return TRUE

/datum/keybinding/mob/target_left_leg
/datum/keybinding/mob/target/left_leg
hotkey_keys = list("Numpad3")
name = "target_left_leg"
full_name = "Target: left leg"
description = "Pressing this key targets the left leg. This will impact where you hit people, and can be used for surgery."
keybind_signal = COMSIG_KB_MOB_TARGETLEFTLEG_DOWN

/datum/keybinding/mob/target_left_leg/down(client/user)
. = ..()
if(.)
return
user.body_l_leg()
return TRUE

/datum/keybinding/mob/prevent_movement
hotkey_keys = list("Alt")
name = "block_movement"
Expand Down
2 changes: 1 addition & 1 deletion code/game/world.dm
Expand Up @@ -133,6 +133,7 @@ GLOBAL_VAR(restart_counter)
GLOB.picture_logging_prefix = "O_[override_dir]_"
GLOB.picture_log_directory = "data/picture_logs/[override_dir]"

GLOB.logger.init_logging()
GLOB.demo_log = "[GLOB.log_directory]/demo.log"
GLOB.dynamic_log = "[GLOB.log_directory]/dynamic.log"
GLOB.filter_log = "[GLOB.log_directory]/filters.log"
Expand Down Expand Up @@ -165,7 +166,6 @@ GLOBAL_VAR(restart_counter)
GLOB.world_uplink_log = "[GLOB.log_directory]/uplink.log"
GLOB.world_virus_log = "[GLOB.log_directory]/virus.log"


#ifdef UNIT_TESTS
GLOB.test_log = "[GLOB.log_directory]/tests.log"
start_log(GLOB.test_log)
Expand Down
@@ -0,0 +1,3 @@
/datum/log_category/target_zone_switch
category = LOG_CATEGORY_TARGET_ZONE_SWITCH
config_flag = /datum/config_entry/flag/log_zone_switch
32 changes: 32 additions & 0 deletions code/modules/logging/log_category.dm
@@ -0,0 +1,32 @@
/// The main datum that contains all log entries for a category
/datum/log_category
/// The category this datum contains
var/category
/// If set this config flag is checked to enable this log category
var/config_flag
/// List of all entries, in chronological order of when they were added
var/list/entries = list()

/// Backup log category to catch attempts to log to a category that doesn't exist
/datum/log_category/backup_category_not_found
category = LOG_CATEGORY_NOT_FOUND

/// Add an entry to this category. It is very important that any data you provide doesn't hold references to anything!
/datum/log_category/proc/add_entry(message, list/data)
var/list/entry = list(
LOG_ENTRY_MESSAGE = message,
LOG_ENTRY_TIMESTAMP = big_number_to_text(rustg_unix_timestamp()),
)
if(data)
entry[LOG_ENTRY_DATA] = data

entries += list(entry)
write_entry(entry)

/// Allows for category specific file splitting. Needs to accept a null entry for the default file.
/datum/log_category/proc/get_output_file(list/entry)
return "[GLOB.log_directory]/[category].json"

/// Writes an entry to the output file for the category
/datum/log_category/proc/write_entry(list/entry)
rustg_file_append("[json_encode(entry)]\n", get_output_file(entry))
70 changes: 70 additions & 0 deletions code/modules/logging/log_holder.dm
@@ -0,0 +1,70 @@
GLOBAL_DATUM_INIT(logger, /datum/log_holder, new)
GLOBAL_PROTECT(logger)

/**
* Main datum to manage logging actions
*/
/datum/log_holder
/// Round ID, if set, that logging is initialized for
var/round_id
/// When the log_holder first initialized
var/logging_start_timestamp

/// Associative: category -> datum
var/list/datum/log_category/log_categories
/// typecache list for categories that exist but are disabled
var/list/disabled_categories

var/initialized = FALSE
var/shutdown = FALSE

/// Assembles basic information for logging, creating the log category datums and checking for config flags as required
/datum/log_holder/proc/init_logging()
if(initialized)
CRASH("Attempted to call init_logging twice!")
initialized = TRUE

round_id = GLOB.round_id
logging_start_timestamp = rustg_unix_timestamp()
log_categories = list()
disabled_categories = list()
for(var/datum/log_category/category_type as anything in subtypesof(/datum/log_category))
var/category = initial(category_type.category)
if(!category)
continue

if(category in log_categories)
stack_trace("Found two identical log category type definitions! [category_type]")
continue

var/config_flag = initial(category_type.config_flag)
if(config_flag && !config.Get(config_flag))
disabled_categories[category] = TRUE
continue
category_type = log_categories[category] = new category_type
var/list/log_start_entry = list(
LOG_HEADER_CATEGORY = category,
LOG_HEADER_INIT_TIMESTAMP = big_number_to_text(logging_start_timestamp),
LOG_HEADER_ROUND_ID = big_number_to_text(GLOB.round_id),
)
rustg_file_write("[json_encode(log_start_entry)]\n", category_type.get_output_file(null))

/// Tells the log_holder to not allow any more logging to be done, and dumps all categories to their json file
/datum/log_holder/proc/shutdown_logging()
if(shutdown)
CRASH("Attempted to call shutdown_logging twice!")
shutdown = TRUE

/// This is Log because log is a byond internal proc
/datum/log_holder/proc/Log(category, message, list/data)
if(!initialized || shutdown)
CRASH("Attempted to perform logging before initializion or after shutdown!")

if(disabled_categories[category])
return

var/datum/log_category/log_category = log_categories[category]
if(!log_category)
Log(LOG_CATEGORY_NOT_FOUND, message, data)
CRASH("Attempted to log to a category that doesn't exist! [category]")
log_category.add_entry(message, data)

0 comments on commit 18b041b

Please sign in to comment.