diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm
index 7fc2bee5074c..e83d53fae57f 100644
--- a/code/__HELPERS/_logging.dm
+++ b/code/__HELPERS/_logging.dm
@@ -51,70 +51,102 @@ GLOBAL_PROTECT(log_end)
if(GLOB.configuration.logging.vote_logging)
rustg_log_write(GLOB.world_game_log, "VOTE: [text][GLOB.log_end]")
+/proc/log_if_mismatch(mob/who, message)
+ if(!isnull(usr) && usr != who)
+ rustg_log_write(GLOB.world_game_log, "LOG USER MISMATCH: [usr.simple_info_line()] was usr for [message][GLOB.log_end]")
+
/proc/log_access_in(client/new_client)
if(GLOB.configuration.logging.access_logging)
- var/message = "[key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version].[new_client.byond_build]"
- rustg_log_write(GLOB.world_game_log, "ACCESS IN: [message][GLOB.log_end]")
+ var/message = "ACCESS IN: [key_name(new_client)] - IP:[new_client.address] - CID:[new_client.computer_id] - BYOND v[new_client.byond_version].[new_client.byond_build]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(new_client.mob, message)
/proc/log_access_out(mob/last_mob)
if(GLOB.configuration.logging.access_logging)
- var/message = "[key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out"
- rustg_log_write(GLOB.world_game_log, "ACCESS OUT: [message][GLOB.log_end]")
+ var/message = "ACCESS OUT: [key_name(last_mob)] - IP:[last_mob.lastKnownIP] - CID:[last_mob.computer_id] - BYOND Logged Out"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(last_mob, message)
/proc/log_say(text, mob/speaker)
if(GLOB.configuration.logging.say_logging)
- rustg_log_write(GLOB.world_game_log, "SAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "SAY: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_whisper(text, mob/speaker)
if(GLOB.configuration.logging.whisper_logging)
- rustg_log_write(GLOB.world_game_log, "WHISPER: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "WHISPER: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_ooc(text, client/user)
if(GLOB.configuration.logging.ooc_logging)
- rustg_log_write(GLOB.world_game_log, "OOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "OOC: [user.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(user, message)
/proc/log_aooc(text, client/user)
if(GLOB.configuration.logging.ooc_logging)
- rustg_log_write(GLOB.world_game_log, "AOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "AOOC: [user.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(user, message)
/proc/log_looc(text, client/user)
if(GLOB.configuration.logging.ooc_logging)
- rustg_log_write(GLOB.world_game_log, "LOOC: [user.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "LOOC: [user.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(user, message)
/proc/log_emote(text, mob/speaker)
if(GLOB.configuration.logging.emote_logging)
- rustg_log_write(GLOB.world_game_log, "EMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "EMOTE: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
-/proc/log_attack(attacker, defender, message)
+/proc/log_attack(attacker, defender, attack_message)
if(GLOB.configuration.logging.attack_logging)
- rustg_log_write(GLOB.world_game_log, "ATTACK: [attacker] against [defender]: [message][GLOB.log_end]") //Seperate attack logs? Why?
+ var/message = "ATTACK: [attacker] against [defender]: [attack_message]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(attacker, message)
/proc/log_adminsay(text, mob/speaker)
if(GLOB.configuration.logging.adminchat_logging)
- rustg_log_write(GLOB.world_game_log, "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "ADMINSAY: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_ping_all_admins(text, mob/speaker)
if(GLOB.configuration.logging.adminchat_logging)
- rustg_log_write(GLOB.world_game_log, "ALL ADMIN PING: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "ALL ADMIN PING: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_qdel(text)
rustg_log_write(GLOB.world_qdel_log, "QDEL: [text][GLOB.log_end]")
/proc/log_mentorsay(text, mob/speaker)
if(GLOB.configuration.logging.adminchat_logging)
- rustg_log_write(GLOB.world_game_log, "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "MENTORSAY: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_devsay(text, mob/speaker)
if(GLOB.configuration.logging.adminchat_logging)
- rustg_log_write(GLOB.world_game_log, "DEVSAY: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "DEVSAY: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_ghostsay(text, mob/speaker)
if(GLOB.configuration.logging.say_logging)
- rustg_log_write(GLOB.world_game_log, "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "DEADCHAT: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_ghostemote(text, mob/speaker)
if(GLOB.configuration.logging.emote_logging)
- rustg_log_write(GLOB.world_game_log, "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "DEADEMOTE: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_adminwarn(text)
if(GLOB.configuration.logging.admin_warning_logging)
@@ -122,11 +154,15 @@ GLOBAL_PROTECT(log_end)
/proc/log_pda(text, mob/speaker)
if(GLOB.configuration.logging.pda_logging)
- rustg_log_write(GLOB.world_game_log, "PDA: [speaker.simple_info_line()]: [html_decode(text)][GLOB.log_end]")
+ var/message = "PDA: [speaker.simple_info_line()]: [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_chat(text, mob/speaker)
if(GLOB.configuration.logging.pda_logging)
- rustg_log_write(GLOB.world_game_log, "CHAT: [speaker.simple_info_line()] [html_decode(text)][GLOB.log_end]")
+ var/message = "CHAT: [speaker.simple_info_line()] [html_decode(text)]"
+ rustg_log_write(GLOB.world_game_log, "[message][GLOB.log_end]")
+ log_if_mismatch(speaker, message)
/proc/log_tgs(text, level)
GLOB.tgs_log += "\[[time_stamp()]] \[[level]] [text]"
diff --git a/code/datums/log_record.dm b/code/datums/log_record.dm
index b550c24fc43b..5e672410aef1 100644
--- a/code/datums/log_record.dm
+++ b/code/datums/log_record.dm
@@ -3,6 +3,7 @@
var/raw_time // When did this happen?
var/what // What happened
var/who // Who did it
+ var/who_usr // The current usr, if not who.
var/target // Who/what was targeted
var/where // Where did it happen
@@ -10,6 +11,10 @@
log_type = _log_type
who = get_subject_text(_who, _log_type)
+ if(!isnull(usr) && usr != _who)
+ who_usr = "
FORCED by [get_subject_text(usr, _log_type)]"
+ else
+ who_usr = ""
what = _what
target = get_subject_text(_target, _log_type)
if(!istext(_where) && !isturf(_where))
@@ -55,3 +60,15 @@
if(!time_diff) // Same time
return cmp_text_asc(A.log_type, B.log_type)
return time_diff
+
+/datum/log_record/vv_edit_var(var_name, var_value)
+ message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.")
+ log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.")
+ GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.")
+ return FALSE
+
+/datum/log_record/can_vv_delete()
+ message_admins("[key_name_admin(src)] attempted to VV edit a logging object. Inform the host at once.")
+ log_admin("[key_name(src)] attempted to VV edit a logging object. Inform the host at once.")
+ GLOB.discord_manager.send2discord_simple(DISCORD_WEBHOOK_ADMIN, "[key_name(src)] attempted to VV edit a logging object. Inform the host at once.")
+ return FALSE
diff --git a/code/datums/log_viewer.dm b/code/datums/log_viewer.dm
index 4d2c266b23d3..843eb32bf068 100644
--- a/code/datums/log_viewer.dm
+++ b/code/datums/log_viewer.dm
@@ -186,7 +186,7 @@ if(!result || result.ckey != __ckey){\
var/time = gameTimestamp(wtime = L.raw_time - 9.99) // The time rounds up for some reason. Will result in weird filtering results
dat +="