using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Player Activity")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Player Activity")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1de6cf76-b53d-47ab-b3b1-de02fa27f1a7")]
[assembly: AssemblyFileVersion("1.1.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.4.0")]
[module: UnverifiableCode]
internal class Log
{
private static Log _instance;
private ManualLogSource _source;
public static Log CreateInstance(ManualLogSource source)
{
_instance = new Log
{
_source = source
};
return _instance;
}
private Log()
{
}
public static void Info(object msg)
{
_instance._source.LogInfo((object)FormatMessage(msg));
}
public static void Message(object msg)
{
_instance._source.LogMessage((object)FormatMessage(msg));
}
public static void Debug(object msg)
{
_instance._source.LogDebug((object)FormatMessage(msg));
}
public static void Warning(object msg)
{
_instance._source.LogWarning((object)FormatMessage(msg));
}
public static void Error(object msg)
{
_instance._source.LogError((object)FormatMessage(msg));
}
public static void Fatal(object msg)
{
_instance._source.LogFatal((object)FormatMessage(msg));
}
private static string FormatMessage(object msg)
{
return $"[{DateTime.UtcNow}] {msg}";
}
}
internal static class ThreadingUtil
{
private class DisposableThread : IDisposable
{
private Thread _thread;
internal DisposableThread(Thread thread)
{
_thread = thread;
}
public void Dispose()
{
_thread.Abort();
}
}
private class MainThreadDispatcher : MonoBehaviour
{
private static MainThreadDispatcher _instance;
private ConcurrentQueue<Action> _queue = new ConcurrentQueue<Action>();
private ConcurrentQueue<IEnumerator> _coroutinesQueue = new ConcurrentQueue<IEnumerator>();
public static MainThreadDispatcher GetInstante()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
if ((Object)(object)_instance == (Object)null)
{
GameObject val = new GameObject("MainThreadDispatcher", new Type[1] { typeof(MainThreadDispatcher) });
Object.DontDestroyOnLoad((Object)val);
_instance = val.GetComponent<MainThreadDispatcher>();
}
return _instance;
}
public void AddAction(Action action)
{
_queue.Enqueue(action);
}
public void AddCoroutine(IEnumerator coroutine)
{
_coroutinesQueue.Enqueue(coroutine);
}
private void Update()
{
Action result;
while (_queue.Count > 0 && _queue.TryDequeue(out result))
{
result?.Invoke();
}
IEnumerator result2;
while (_coroutinesQueue.Count > 0 && _coroutinesQueue.TryDequeue(out result2))
{
((MonoBehaviour)this).StartCoroutine(result2);
}
}
}
internal static IDisposable RunPeriodical(Action action, int periodMilliseconds)
{
return new Timer(delegate
{
action?.Invoke();
}, null, 0, periodMilliseconds);
}
internal static IDisposable RunPeriodicalInSingleThread(Action action, int periodMilliseconds)
{
Thread thread = new Thread((ParameterizedThreadStart)delegate
{
while (true)
{
action?.Invoke();
Thread.Sleep(periodMilliseconds);
}
});
thread.Start();
return new DisposableThread(thread);
}
internal static void RunInMainThread(Action action)
{
MainThreadDispatcher.GetInstante().AddAction(action);
}
internal static void RunCoroutine(IEnumerator coroutine)
{
MainThreadDispatcher.GetInstante().AddCoroutine(coroutine);
}
internal static void RunDelayed(float delay, Action action)
{
MainThreadDispatcher.GetInstante().AddCoroutine(DelayedActionCoroutine(delay, action));
}
internal static IDisposable RunThread(Action action)
{
Thread thread = new Thread(action.Invoke);
thread.Start();
return new DisposableThread(thread);
}
internal static IEnumerator DelayedActionCoroutine(float delay, Action action)
{
yield return (object)new WaitForSeconds(delay);
action?.Invoke();
}
}
namespace PlayerActivity
{
public static class ActivityLog
{
private static ActivityLogger _logger => ActivityLogger.Instance;
public static void AddLog(string log)
{
if (!((Object)(object)_logger == (Object)null))
{
_logger.AddLog(log);
}
}
public static void AddLog(string log, Vector3 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
AddLog(ActivityLoggerUtil.FormatLog(log, position));
}
public static void AddLogWithPosition(string log, Component component)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)component != (Object)null)
{
AddLog(log, component.transform.position);
}
else
{
AddLog(log);
}
}
public static void AddLogWithPlayerPosition(string log)
{
if ((Object)(object)Player.m_localPlayer != (Object)null)
{
AddLogWithPosition(log, (Component)(object)Player.m_localPlayer);
}
else
{
AddLog(log);
}
}
}
internal class ActivityLogger : MonoBehaviour
{
private const int LogsPackageCount = 20;
private Queue<string> _logsQueue = new Queue<string>();
private ZPackage _package = new ZPackage();
public static ActivityLogger Instance { get; private set; }
private void Awake()
{
Instance = this;
((MonoBehaviour)this).InvokeRepeating("Flush", 30f, 30f);
((MonoBehaviour)this).InvokeRepeating("FlushLogsIfNeeded", 1f, 1f);
Log.Info("Activity logger initialized");
}
public void AddLog(string log)
{
if (!ZNet.instance.IsDedicated())
{
Log.Debug(log);
log = ActivityLoggerUtil.AddDateToLog(log);
_logsQueue.Enqueue(log);
}
}
internal void Flush()
{
if (_logsQueue.Count == 0)
{
return;
}
_package.Clear();
_package.Write(_logsQueue.Count);
foreach (string item in _logsQueue)
{
_package.Write(item);
}
Log.Debug($"Sent {_logsQueue.Count} user logs. Size: {_package.Size()}");
_logsQueue.Clear();
ZRoutedRpc instance = ZRoutedRpc.instance;
if (instance != null)
{
instance.InvokeRoutedRPC("RPC_PlayerActivityLogs", new object[1] { _package });
}
}
private void FlushLogsIfNeeded()
{
if (_logsQueue.Count >= 20)
{
Flush();
}
}
}
internal class ActivityStorageService : MonoBehaviour
{
public const string LogsRpc = "RPC_PlayerActivityLogs";
private IDisposable _writerThread;
private ConcurrentDictionary<string, ConcurrentQueue<string>> _logsToWrite = new ConcurrentDictionary<string, ConcurrentQueue<string>>();
internal static ActivityStorageService Instance { get; private set; }
private void Start()
{
Instance = this;
ZRoutedRpc.instance.Register<ZPackage>("RPC_PlayerActivityLogs", (Action<long, ZPackage>)OnPlayerLogsReceived);
_writerThread = ThreadingUtil.RunPeriodicalInSingleThread(WriteQueuedLogsToDisk, 500);
Log.Info("Storage initialized");
}
private void OnDestroy()
{
_writerThread?.Dispose();
}
private void OnPlayerLogsReceived(long uid, ZPackage package)
{
ZNetPeer peer = ZNet.instance.GetPeer(uid);
string steamId = ((peer != null) ? peer.m_socket.GetHostName() : null) ?? "local";
int num = package.ReadInt();
for (int i = 0; i < num; i++)
{
AppendPlayerLogs(steamId, package.ReadString());
}
}
internal void AppendPlayerLogs(string steamId, string message)
{
string key = Path.Combine(Utils.GetSaveDataPath((FileSource)1), "Player Activity", ActivityLoggerUtil.GetCurrentDateText("yyyy_MM_dd"), steamId + ".log");
if (!_logsToWrite.TryGetValue(key, out var value))
{
value = new ConcurrentQueue<string>();
_logsToWrite.AddOrUpdate(key, value, (string path, ConcurrentQueue<string> q2) => _logsToWrite[path]);
}
value.Enqueue(message);
}
private void WriteQueuedLogsToDisk()
{
foreach (KeyValuePair<string, ConcurrentQueue<string>> item in _logsToWrite)
{
if (item.Value.IsEmpty)
{
continue;
}
string directoryName = Path.GetDirectoryName(item.Key);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
using StreamWriter streamWriter = File.AppendText(item.Key);
string result;
while (item.Value.TryDequeue(out result))
{
streamWriter.WriteLine(result);
}
}
}
}
public static class ItemDataUtil
{
private const string CustomDataValueFormat = "[{0}]:[{1}]";
private static StringBuilder _builder = new StringBuilder();
private static StringBuilder _itemDataBuilder = new StringBuilder();
public static string ToPresentableString(this ItemData item)
{
return item.ToPresentableString(item.m_stack);
}
public static string ToPresentableString(this ItemData item, int count)
{
GameObject dropPrefab = item.m_dropPrefab;
string arg = ((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? item.m_shared.m_name;
_itemDataBuilder.Clear();
_itemDataBuilder.AppendFormat("{0} x{1} quality:{2}", arg, count, item.m_quality);
if (item.m_crafterID != 0L)
{
_itemDataBuilder.AppendFormat(" crafter:{0}({1})", item.m_crafterName, item.m_crafterID);
}
if (item.m_customData.Count > 0)
{
_itemDataBuilder.AppendFormat(" data:{0}", ToPresentableFormat(item.m_customData));
}
return _itemDataBuilder.ToString();
}
private static string ToPresentableFormat(Dictionary<string, string> customData)
{
_builder.Clear();
bool flag = false;
foreach (KeyValuePair<string, string> customDatum in customData)
{
if (flag)
{
_builder.Append(", ");
}
_builder.AppendFormat("[{0}]:[{1}]", customDatum.Key, customDatum.Value);
flag = true;
}
return _builder.ToString();
}
}
internal class PlayerLogger : MonoBehaviour
{
private Player _player;
private ActivityLogger _logger;
private void Start()
{
if (!ZNet.instance.IsDedicated())
{
_logger = ActivityLogger.Instance;
_player = ((Component)this).GetComponent<Player>();
((MonoBehaviour)this).InvokeRepeating("AddPeriodicallyLogs", 60f, 60f);
((MonoBehaviour)this).InvokeRepeating("AddInventoryLog", 1f, 600f);
Log.Info("Player logger created");
}
}
private void AddPeriodicallyLogs()
{
if (!((Character)_player).IsDead())
{
float num = default(float);
float num2 = default(float);
int num3 = default(int);
float num4 = default(float);
float num5 = default(float);
ZNet.instance.GetNetStats(ref num, ref num2, ref num3, ref num4, ref num5);
ActivityLog.AddLogWithPosition($"Ping {num3}", (Component)(object)_player);
}
}
private void AddInventoryLog()
{
if (!((Character)_player).IsDead())
{
ActivityLog.AddLogWithPosition("Inventory\n" + ActivityLoggerUtil.GetContainerData(((Humanoid)_player).GetInventory()), (Component)(object)_player);
}
}
}
public static class ActivityLoggerUtil
{
private const string DefaultDateFormat = "yyyy-MM-dd HH:mm:ss";
private static StringBuilder _builder = new StringBuilder();
public static bool CheckIsLocalPlayer(Character character)
{
return (Object)(object)character == (Object)(object)Player.m_localPlayer;
}
public static string GetContainerData(Container container)
{
return GetContainerData(container.GetInventory());
}
public static string GetContainerData(Inventory inventory)
{
_builder.Clear();
inventory.GetAllItems().ForEach(delegate(ItemData item)
{
_builder.AppendLine(item.ToPresentableString());
});
return _builder.ToString();
}
public static string GetDamageLog(HitData hit)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
_builder.Clear();
DamageTypes damage = hit.m_damage;
if (damage.m_damage > 0f)
{
AppendDamageToBuilder("damage", damage.m_damage);
}
if (damage.m_blunt > 0f)
{
AppendDamageToBuilder("blunt", damage.m_blunt);
}
if (damage.m_slash > 0f)
{
AppendDamageToBuilder("slash", damage.m_slash);
}
if (damage.m_pierce > 0f)
{
AppendDamageToBuilder("pierce", damage.m_pierce);
}
if (damage.m_fire > 0f)
{
AppendDamageToBuilder("fire", damage.m_fire);
}
if (damage.m_frost > 0f)
{
AppendDamageToBuilder("frost", damage.m_frost);
}
if (damage.m_lightning > 0f)
{
AppendDamageToBuilder("light", damage.m_lightning);
}
if (damage.m_poison > 0f)
{
AppendDamageToBuilder("poison", damage.m_poison);
}
if (damage.m_spirit > 0f)
{
AppendDamageToBuilder("spirit", damage.m_spirit);
}
if (damage.m_chop > 0f)
{
AppendDamageToBuilder("chop", damage.m_chop);
}
if (damage.m_pickaxe > 0f)
{
AppendDamageToBuilder("pickaxe", damage.m_pickaxe);
}
AppendDamageToBuilder("total", ((DamageTypes)(ref damage)).GetTotalDamage());
return _builder.ToString();
}
private static void AppendDamageToBuilder(string name, float damage)
{
_builder.AppendFormat("{0}:{1:0.0} ", name, damage);
}
public static string AddDateToLog(string log)
{
return $"[{GetCurrentDateText()}] {log}";
}
public static string FormatLog(string log, Vector3 position)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return $"{position.ToPresentableString()} {log}";
}
public static string GetCurrentDateText(string format = "yyyy-MM-dd HH:mm:ss")
{
return DateTime.UtcNow.ToString(format, CultureInfo.InvariantCulture);
}
public static string GetPlayerData(this Player player)
{
if ((Object)(object)player == (Object)null)
{
return string.Empty;
}
return $"{player.GetPlayerName()}({player.GetPlayerID()})";
}
public static string ToPresentableString(this Vector3 position)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
return $"({position.x:0.0} {position.y:0.0} {position.z:0.0})";
}
}
[BepInPlugin("org.tristan.playeractivity", "Player Activity", "1.1.4")]
internal class Plugin : BaseUnityPlugin
{
[HarmonyPatch]
private class InitializationPatch
{
private static ActivityLogger _logger;
[HarmonyPostfix]
[HarmonyPatch(typeof(Game), "Start")]
private static void Game_Start(Game __instance)
{
_logger = ((Component)__instance).gameObject.AddComponent<ActivityLogger>();
if (ZNet.instance.IsServer())
{
((Component)__instance).gameObject.AddComponent<ActivityStorageService>();
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "SetLocalPlayer")]
private static void Player_SetLocalPlayer(Player __instance)
{
((Component)__instance).gameObject.AddComponent<PlayerLogger>();
}
[HarmonyPriority(0)]
[HarmonyPrefix]
[HarmonyPatch(typeof(Game), "Shutdown")]
private static void Game_Shutdown()
{
_logger.Flush();
}
[HarmonyFinalizer]
[HarmonyPatch(typeof(Player), "OnDeath")]
private static void Player_OnDeath(Player __instance)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
_logger.Flush();
}
}
}
private const string Guid = "org.tristan.playeractivity";
public const string Name = "Player Activity";
public const string Version = "1.1.4";
private void Awake()
{
Log.CreateInstance(((BaseUnityPlugin)this).Logger);
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "org.tristan.playeractivity");
}
}
}
namespace PlayerActivity.ActivityPatches
{
[HarmonyPatch]
internal class CraftPatches
{
private static bool _isCrafting;
[HarmonyPriority(int.MinValue)]
[HarmonyPrefix]
[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
private static void InventoryGui_DoCrafting_Prefix(InventoryGui __instance)
{
_isCrafting = true;
}
[HarmonyPriority(int.MaxValue)]
[HarmonyPostfix]
[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
private static void InventoryGui_DoCrafting_Postfix(InventoryGui __instance)
{
_isCrafting = false;
}
[HarmonyPriority(int.MaxValue)]
[HarmonyFinalizer]
[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
{
typeof(string),
typeof(int),
typeof(int),
typeof(int),
typeof(long),
typeof(string),
typeof(bool)
})]
private static void Inventory_AddItem_Postfix(ref ItemData __result)
{
if (__result != null && _isCrafting)
{
ActivityLog.AddLogWithPlayerPosition("Craft " + __result.ToPresentableString());
}
}
}
[HarmonyPatch]
internal class CreateTombStonePatch
{
[HarmonyPostfix]
[HarmonyPatch(typeof(TombStone), "Setup")]
private static void TombStone_Setup(TombStone __instance)
{
Player localPlayer = Player.m_localPlayer;
Container component = ((Component)__instance).GetComponent<Container>();
ActivityLog.AddLogWithPosition("Grave items:\n" + ActivityLoggerUtil.GetContainerData(component.GetInventory()) + "\nplayer:\n" + ActivityLoggerUtil.GetContainerData(((Humanoid)localPlayer).GetInventory()), (Component)(object)__instance);
}
}
[HarmonyPatch]
internal class ServerPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(ZNet), "SendPeerInfo")]
private static void ZNet_SendPeerInfo(ZNet __instance, ZRpc rpc)
{
if (__instance.IsServer())
{
AppendServerLog(rpc.m_socket.GetHostName(), "Connected");
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ZNet), "Disconnect")]
private static void ZNet_Disconnect(ZNet __instance, ZNetPeer peer)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
if (__instance.IsServer())
{
string hostName = peer.m_rpc.m_socket.GetHostName();
if (peer.m_characterID != default(ZDOID))
{
AppendServerLog(hostName, ActivityLoggerUtil.FormatLog("Disconnected", peer.GetRefPos()));
}
else
{
AppendServerLog(hostName, "Disconnected");
}
}
}
private static void AppendServerLog(string steamId, string log)
{
ActivityStorageService.Instance.AppendPlayerLogs(steamId, ActivityLoggerUtil.AddDateToLog(log));
}
}
[HarmonyPatch(typeof(Player))]
internal class DodgePatches
{
private static bool _inDodge;
[HarmonyPrefix]
[HarmonyPatch("UpdateDodge")]
private static void Player_UpdateDodge_Prefix(Player __instance)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
_inDodge = ((Character)__instance).InDodge();
}
}
[HarmonyPostfix]
[HarmonyPatch("UpdateDodge")]
private static void Player_UpdateDodge_Postfix(Player __instance)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
if (!_inDodge && ((Character)__instance).InDodge())
{
ActivityLog.AddLogWithPosition("Dodge", (Component)(object)__instance);
}
_inDodge = ((Character)__instance).InDodge();
}
}
}
[HarmonyPatch]
internal class PickupPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Humanoid), "Pickup")]
private static void Humanoid_Pickup(Humanoid __instance, GameObject go, ref bool __result)
{
ItemDrop val = default(ItemDrop);
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance) && __result && go.TryGetComponent<ItemDrop>(ref val))
{
ActivityLog.AddLogWithPosition("Pickup " + val.m_itemData.ToPresentableString(), (Component)(object)val);
}
}
}
[HarmonyPatch]
internal class RepairBuildingPatches
{
[HarmonyPatch(typeof(Player), "Repair")]
private class PlayerRepairPatches
{
private static void Prefix()
{
_repairing = true;
}
private static void Postfix()
{
_repairing = false;
}
}
private static bool _repairing;
[HarmonyPostfix]
[HarmonyPatch(typeof(WearNTear), "Repair")]
private static void InventoryGui_CanRepair(WearNTear __instance, ref bool __result)
{
if (_repairing && __result)
{
ActivityLog.AddLogWithPosition("Repair building " + Utils.GetPrefabName(((Component)__instance).gameObject), (Component)(object)__instance);
}
}
}
[HarmonyPatch]
internal class RepairItemPatches
{
[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
private class RepairOneItemPatches
{
private static void Prefix()
{
_repairing = true;
}
private static void Postfix()
{
_repairing = false;
}
}
private static bool _repairing;
[HarmonyPostfix]
[HarmonyPatch(typeof(InventoryGui), "CanRepair")]
private static void InventoryGui_CanRepair(ItemData item, ref bool __result)
{
if (__result && _repairing)
{
ActivityLog.AddLogWithPlayerPosition("Repair item " + item.ToPresentableString());
}
}
}
[HarmonyPatch]
internal class TerminalPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(ConsoleCommand), "RunAction")]
private static void ConsoleCommand_RunAction(ConsoleCommand __instance, ConsoleEventArgs args)
{
if (!ZNet.instance.IsDedicated())
{
ActivityLog.AddLogWithPlayerPosition("Command " + args.FullLine);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(ZNet), "RemoteCommand")]
private static void ZNet_RemoteCommand(string command)
{
if (!ZNet.instance.IsDedicated())
{
ActivityLog.AddLogWithPlayerPosition("Command remote " + command);
}
}
}
[HarmonyPatch(typeof(Character))]
internal class DamagePatches
{
[HarmonyFinalizer]
[HarmonyPatch("ApplyDamage")]
private static void Character_ApplyDamage(Character __instance, HitData hit)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer(__instance))
{
string text;
if (!hit.HaveAttacker())
{
text = "none";
}
else
{
Character attacker = hit.GetAttacker();
Player val = (Player)(object)((attacker is Player) ? attacker : null);
text = ((val == null) ? Utils.GetPrefabName(((Component)hit.GetAttacker()).gameObject) : val.GetPlayerData());
}
float health = __instance.GetHealth();
ActivityLog.AddLogWithPosition($"Damaged by:{text} health:{health:0.0} {ActivityLoggerUtil.GetDamageLog(hit)}", (Component)(object)__instance);
if (!(__instance.GetHealth() > 0f))
{
ActivityLog.AddLogWithPosition("Dead by:" + text, (Component)(object)__instance);
}
}
}
}
[HarmonyPatch(typeof(Humanoid))]
internal class HumanoidPatches
{
[HarmonyFinalizer]
[HarmonyPatch("EquipItem")]
private static void Humanoid_EquipItem(Humanoid __instance, ItemData item, ref bool __result)
{
if (item != null && __result && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance) && item.IsEquipable())
{
ActivityLog.AddLogWithPosition("Equip " + item.ToPresentableString(), (Component)(object)__instance);
}
}
[HarmonyPrefix]
[HarmonyPatch("UnequipItem")]
private static void Humanoid_UnequipItem(Humanoid __instance, ItemData item)
{
if (item != null && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance) && item.IsEquipable() && item.m_equipped)
{
ActivityLog.AddLogWithPosition("Unequip " + item.ToPresentableString(), (Component)(object)__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch("DropItem")]
private static void Humanoid_DropItem(Humanoid __instance, Inventory inventory, ItemData item, int amount, ref bool __result)
{
if (__result && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLogWithPosition("Drop from:" + inventory.GetName() + " " + item.ToPresentableString(amount), (Component)(object)__instance);
}
}
}
[HarmonyPatch]
internal class InventoryPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(Inventory), "MoveAll")]
private static void Inventory_MoveAll(Inventory __instance, Inventory fromInventory)
{
ActivityLog.AddLogWithPlayerPosition("MoveAll from:" + fromInventory.GetName() + " to:" + __instance.GetName() + "\n" + ActivityLoggerUtil.GetContainerData(fromInventory));
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
{
typeof(Inventory),
typeof(ItemData)
})]
private static void Inventory_MoveItemToThis(Inventory __instance, Inventory fromInventory, ItemData item)
{
ActivityLog.AddLogWithPlayerPosition("Move from:" + fromInventory.GetName() + " to:" + __instance.GetName() + " " + item.ToPresentableString());
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
{
typeof(Inventory),
typeof(ItemData),
typeof(int),
typeof(int),
typeof(int)
})]
private static void Inventory_MoveItemToThisWithAmount(Inventory __instance, Inventory fromInventory, ItemData item, int amount)
{
if (__instance != fromInventory || item.m_stack != amount)
{
ActivityLog.AddLogWithPlayerPosition("Move from:" + fromInventory.GetName() + " to:" + __instance.GetName() + " " + item.ToPresentableString(amount));
}
}
}
[HarmonyPatch]
internal class PlayerDealsDamagePatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Character), "Damage")]
private static void Character_Damage(Character __instance, HitData hit)
{
if (IsLocalPlayerHit(hit))
{
Player val = (Player)(object)((__instance is Player) ? __instance : null);
string text = ((val != null) ? val.GetPlayerData() : $"{Utils.GetPrefabName(((Component)__instance).gameObject)} lvl:{__instance.GetLevel()} tamed:{__instance.IsTamed()}");
ActivityLog.AddLogWithPosition("Damage " + text + " " + ActivityLoggerUtil.GetDamageLog(hit), (Component)(object)__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Destructible), "Damage")]
private static void Destructible_Damage(Destructible __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(HitArea), "Damage")]
private static void HitArea_Damage(HitArea __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MineRock), "Damage")]
private static void MineRock_Damage(MineRock __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MineRock5), "Damage")]
private static void MineRock5_Damage(MineRock5 __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Raven), "Damage")]
private static void Raven_Damage(Raven __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(WearNTear), "Damage")]
private static void WearNTear_Damage(WearNTear __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TreeBase), "Damage")]
private static void TreeBase_Damage(TreeBase __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TreeLog), "Damage")]
private static void TreeLog_Damage(TreeLog __instance, HitData hit, bool __runOriginal)
{
if (__runOriginal)
{
TryLogStructureDamage((Component)(object)__instance, hit);
}
}
private static void TryLogStructureDamage(Component target, HitData hit)
{
if (IsLocalPlayerHit(hit))
{
ActivityLog.AddLogWithPosition("Damage " + Utils.GetPrefabName(target.gameObject) + " " + ActivityLoggerUtil.GetDamageLog(hit), target);
}
}
private static bool IsLocalPlayerHit(HitData hit)
{
if (hit.HaveAttacker())
{
return ActivityLoggerUtil.CheckIsLocalPlayer(hit.GetAttacker());
}
return false;
}
}
[HarmonyPatch]
public class PlayerInteractionPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Bed), "Interact")]
private static void Bed_Interact(Bed __instance, ref bool __result, Humanoid human)
{
TryLogInteraction((Component)(object)__instance, __result, human, __instance.GetOwnerName());
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Beehive), "Interact")]
private static void Beehive_Interact(Beehive __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Chair), "Interact")]
private static void Chair_Interact(Chair __instance, ref bool __result, Humanoid human)
{
TryLogInteraction((Component)(object)__instance, __result, human);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Container), "Interact")]
private static void Container_Interact(Container __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CookingStation), "Interact")]
private static void CookingStation_Interact(CookingStation __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CraftingStation), "Interact")]
private static void CraftingStation_Interact(CraftingStation __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Door), "Interact")]
private static void Door_Interact(Door __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Fermenter), "Interact")]
private static void Fermenter_Interact(Fermenter __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Fireplace), "Interact")]
private static void Fireplace_Interact(Fireplace __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ItemStand), "Interact")]
private static void ItemStand_Interact(ItemStand __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user, __instance.GetAttachedItem());
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Ladder), "Interact")]
private static void Ladder_Interact(Ladder __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(OfferingBowl), "Interact")]
private static void OfferingBowl_Interact(OfferingBowl __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Pickable), "Interact")]
private static void Pickable_Interact(Pickable __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PickableItem), "Interact")]
private static void PickableItem_Interact(PickableItem __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PrivateArea), "Interact")]
private static void PrivateArea_Interact(PrivateArea __instance, ref bool __result, Humanoid human)
{
TryLogInteraction((Component)(object)__instance, __result, human, $"{__instance.GetCreatorName()} active:{__instance.IsEnabled()}");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Raven), "Interact")]
private static void Raven_Interact(Raven __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(RuneStone), "Interact")]
private static void RuneStone_Interact(RuneStone __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ShipControlls), "Interact")]
private static void ShipControlls_Interact(ShipControlls __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Sign), "Interact")]
private static void Sign_Interact(Sign __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Switch), "Interact")]
private static void Switch_Interact(Switch __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Tameable), "Interact")]
private static void Tameable_Interact(Tameable __instance, ref bool __result, Humanoid user)
{
TryLogInteraction((Component)(object)__instance, __result, user);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Teleport), "Interact")]
private static void Teleport_Interact(Teleport __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TeleportWorld), "Interact")]
private static void TeleportWorld_Interact(TeleportWorld __instance, ref bool __result, Humanoid human)
{
TryLogInteraction((Component)(object)__instance, __result, human);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ToggleSwitch), "Interact")]
private static void ToggleSwitch_Interact(ToggleSwitch __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TombStone), "Interact")]
private static void TombStone_Interact(TombStone __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character, __instance.GetOwnerName());
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Trader), "Interact")]
private static void Trader_Interact(Trader __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Vagon), "Interact")]
private static void Vagon_Interact(Vagon __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Vegvisir), "Interact")]
private static void Vegvisir_Interact(Vegvisir __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(WayStone), "Interact")]
private static void WayStone_Interact(WayStone __instance, ref bool __result, Humanoid character)
{
TryLogInteraction((Component)(object)__instance, __result, character);
}
private static void TryLogInteraction(Component obj, bool result, Humanoid human, string info = null)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)human))
{
string arg = (string.IsNullOrEmpty(info) ? string.Empty : $"info:{info}");
ActivityLog.AddLogWithPosition($"Interact {Utils.GetPrefabName(obj.gameObject)} result:{result} {arg}", obj);
}
}
}
[HarmonyPatch(typeof(Player))]
public class PlayerPatches
{
[HarmonyPostfix]
[HarmonyPatch("OnSpawned")]
private static void Player_OnSpawned(Player __instance)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLogWithPosition("Spawned " + __instance.GetPlayerData(), (Component)(object)__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch("PlacePiece")]
private static void Player_PlacePiece(Player __instance, Piece piece)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLog("Place " + Utils.GetPrefabName(((Component)piece).gameObject), __instance.m_placementGhost.transform.position);
}
}
[HarmonyPostfix]
[HarmonyPatch("TeleportTo")]
private static void Player_TeleportTo(Player __instance, Vector3 pos, bool distantTeleport, ref bool __result)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (__result && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLogWithPosition($"Teleport distant:{distantTeleport} to:{pos.ToPresentableString()}", (Component)(object)__instance);
}
}
}
[HarmonyPatch(typeof(Player))]
public class PlayerRemovePiecePatches
{
private class RemovedPieceData
{
public string name;
public Vector3 positon;
}
private static bool _removingPiece;
private static RemovedPieceData _piece;
[HarmonyPrefix]
[HarmonyPatch("RemovePiece")]
private static void Player_RemovePiece_Prefix(Player __instance)
{
_removingPiece = ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance);
}
[HarmonyPostfix]
[HarmonyPatch("CheckCanRemovePiece")]
private static void Player_RemovePiece_Prefix(Player __instance, Piece piece, ref bool __result)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if (__result && _removingPiece && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
_piece = new RemovedPieceData
{
name = Utils.GetPrefabName(((Component)piece).gameObject),
positon = ((Component)piece).transform.position
};
}
}
[HarmonyPostfix]
[HarmonyPatch("RemovePiece")]
private static void Player_RemovePiece_Postfix(Player __instance, ref bool __result)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (__result && _piece != null && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLog("Remove " + _piece.name, _piece.positon);
_piece = null;
}
}
}
[HarmonyPatch]
public class PlayerUseItemPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "ConsumeItem")]
private static void Humanoid_UseItem(Player __instance, Inventory inventory, ItemData item)
{
if (ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)__instance))
{
ActivityLog.AddLogWithPosition("Consume " + item.ToPresentableString() + " inventory:" + ((inventory != null) ? inventory.GetName() : null), (Component)(object)__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CookingStation), "UseItem")]
private static void CookingStation_UseItem(CookingStation __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Fireplace), "UseItem")]
private static void Fireplace_UseItem(Fireplace __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Fermenter), "UseItem")]
private static void Fermenter_UseItem(Fermenter __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ItemStand), "UseItem")]
private static void ItemStand_UseItem(ItemStand __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(OfferingBowl), "UseItem")]
private static void OfferingBowl_UseItem(OfferingBowl __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Switch), "UseItem")]
private static void Switch_UseItem(Switch __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
[HarmonyFinalizer]
[HarmonyPatch(typeof(PrivateArea), "UseItem")]
private static void PrivateArea_UseItem(PrivateArea __instance, Humanoid user, ItemData item, ref bool __result)
{
TryLogUsingItem((Component)(object)__instance, user, item, __result);
}
private static void TryLogUsingItem(Component obj, Humanoid humanoid, ItemData item, bool result)
{
if (result && ActivityLoggerUtil.CheckIsLocalPlayer((Character)(object)humanoid))
{
ActivityLog.AddLogWithPosition("Use target:" + Utils.GetPrefabName(obj.gameObject) + " item:" + item.ToPresentableString(), obj);
}
}
}
[HarmonyPatch]
public class SettingTextPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Tameable), "SetText")]
private static void Tameable_SetText(Tameable __instance, string text)
{
if (__instance.m_nview.IsValid())
{
AddSetTextLog((Component)(object)__instance, text);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Sign), "SetText")]
private static void Sign_SetText(Sign __instance, string text)
{
if (__instance.m_nview.IsValid() && string.Equals(__instance.GetText(), text))
{
AddSetTextLog((Component)(object)__instance, text);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(TeleportWorld), "SetText")]
private static void TeleportWorld_SetText(TeleportWorld __instance, string text)
{
if (__instance.m_nview.IsValid())
{
AddSetTextLog((Component)(object)__instance, text);
}
}
private static void AddSetTextLog(Component obj, string text)
{
ActivityLog.AddLogWithPosition("Text target:" + Utils.GetPrefabName(obj.gameObject) + " text:" + text, obj);
}
}
}