Decompiled source of modbykou minechop v1.5.0

modbykou_minechop.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("modbykou_minechop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("KLX for King drip woo")]
[assembly: AssemblyDescription("Configurable hits-to-kill and stamina-per-hit for mining and chopping. Server-authoritative.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ConfigurableMineChop")]
[assembly: AssemblyTitle("modbykou_minechop")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ConfigurableMineChop
{
	[BepInPlugin("kou_minechop", "modbykou_minechop", "1.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal class SyncedValues
		{
			public bool Enabled = true;

			public int TreeMinHits = 2;

			public int TreeMaxHits = 2;

			public int RockMinHits = 3;

			public int RockMaxHits = 7;

			public float ChopStamina = 15f;

			public float PickaxeStamina = 15f;

			public string RockStaminaTable = "3:50,4:40,5:30,6:15,7:10";

			public string ActivationKey = "LeftAlt";
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		private static class ZNet_Awake_Patch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				s_receivedFromServer = false;
				s_rpcRegistered = false;
				RefreshEffectiveFromLocal();
				RegisterSyncRpcOnce();
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)string.Format("[{0}] ZNet.Awake — Effective: Trees={1}-{2}@{3}, Rocks={4}-{5}@{6}, Enabled={7}", "modbykou_minechop", Effective.TreeMinHits, Effective.TreeMaxHits, Effective.ChopStamina, Effective.RockMinHits, Effective.RockMaxHits, Effective.PickaxeStamina, Effective.Enabled));
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private static class ZNet_RPC_PeerInfo_Patch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZRpc rpc)
			{
				if (!IsServer() || rpc == null || (Object)(object)__instance == (Object)null || !cfgServerAuthoritative.Value)
				{
					return;
				}
				ZNetPeer val = null;
				foreach (ZNetPeer peer in __instance.GetPeers())
				{
					if (peer != null && peer.m_rpc == rpc)
					{
						val = peer;
						break;
					}
				}
				if (val != null && val.m_uid != 0L)
				{
					RefreshEffectiveFromLocal();
					PushConfigToPeer(val.m_uid);
				}
			}
		}

		[HarmonyPatch(typeof(TreeBase), "Damage")]
		private static class TreeBase_Damage_Patch
		{
			[HarmonyPrefix]
			private static void Prefix(TreeBase __instance, ref HitData hit)
			{
				if (Effective.Enabled && ActivationKeyHeld() && !((Object)(object)__instance == (Object)null) && hit != null && !(hit.m_damage.m_chop <= 0f))
				{
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					ZDO zdo = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
					int num = RollHitsForTarget(zdo, Effective.TreeMinHits, Effective.TreeMaxHits);
					int soFar;
					bool flag = CountSwing(zdo, num, out soFar);
					hit.m_damage.m_chop = (flag ? 9999f : 1f);
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)string.Format("[{0}] TreeBase '{1}' swing {2}/{3} final={4}", "modbykou_minechop", ((Object)((Component)__instance).gameObject).name, soFar, num, flag));
					}
				}
			}
		}

		[HarmonyPatch(typeof(TreeLog), "Damage")]
		private static class TreeLog_Damage_Patch
		{
			[HarmonyPrefix]
			private static void Prefix(TreeLog __instance, ref HitData hit)
			{
				if (Effective.Enabled && ActivationKeyHeld() && !((Object)(object)__instance == (Object)null) && hit != null && !(hit.m_damage.m_chop <= 0f))
				{
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					ZDO zdo = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
					int num = RollHitsForTarget(zdo, Effective.TreeMinHits, Effective.TreeMaxHits);
					int soFar;
					bool flag = CountSwing(zdo, num, out soFar);
					hit.m_damage.m_chop = (flag ? 9999f : 1f);
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)string.Format("[{0}] TreeLog '{1}' swing {2}/{3} final={4}", "modbykou_minechop", ((Object)((Component)__instance).gameObject).name, soFar, num, flag));
					}
				}
			}
		}

		[HarmonyPatch(typeof(MineRock), "Damage")]
		private static class MineRock_Damage_Patch
		{
			[HarmonyPrefix]
			private static void Prefix(MineRock __instance, ref HitData hit)
			{
				if (Effective.Enabled && ActivationKeyHeld() && !((Object)(object)__instance == (Object)null) && hit != null && !(hit.m_damage.m_pickaxe <= 0f))
				{
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					ZDO zdo = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
					int num = (s_lastRockHits = RollHitsForTarget(zdo, Effective.RockMinHits, Effective.RockMaxHits));
					int soFar;
					bool flag = CountSwing(zdo, num, out soFar);
					hit.m_damage.m_pickaxe = (flag ? 9999f : 1f);
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)string.Format("[{0}] MineRock '{1}' swing {2}/{3} final={4}", "modbykou_minechop", ((Object)((Component)__instance).gameObject).name, soFar, num, flag));
					}
				}
			}
		}

		[HarmonyPatch(typeof(MineRock5), "Damage")]
		private static class MineRock5_Damage_Patch
		{
			private static readonly MethodInfo DamageAreaMethod = AccessTools.Method(typeof(MineRock5), "DamageArea", (Type[])null, (Type[])null);

			private static readonly FieldInfo HitAreasField = AccessTools.Field(typeof(MineRock5), "m_hitAreas");

			private static readonly FieldInfo NViewField = AccessTools.Field(typeof(MineRock5), "m_nview");

			[HarmonyPrefix]
			private static bool Prefix(MineRock5 __instance, ref HitData hit)
			{
				if (!Effective.Enabled || !ActivationKeyHeld() || (Object)(object)__instance == (Object)null || hit == null)
				{
					return true;
				}
				if (hit.m_damage.m_pickaxe <= 0f)
				{
					return true;
				}
				if (DamageAreaMethod == null || HitAreasField == null || NViewField == null)
				{
					return true;
				}
				object? value = NViewField.GetValue(__instance);
				ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
				if ((Object)(object)val == (Object)null || !val.IsValid())
				{
					return true;
				}
				ZDO zDO = val.GetZDO();
				if (zDO == null)
				{
					return true;
				}
				if (!(HitAreasField.GetValue(__instance) is IList list))
				{
					return true;
				}
				int num = (s_lastRockHits = RollHitsForTarget(zDO, Effective.RockMinHits, Effective.RockMaxHits));
				if (!CountSwing(zDO, num, out var soFar))
				{
					hit.m_damage.m_pickaxe = 1f;
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)string.Format("[{0}] MineRock5 '{1}' swing {2}/{3}", "modbykou_minechop", ((Object)((Component)__instance).gameObject).name, soFar, num));
					}
					return true;
				}
				hit.m_damage.m_pickaxe = 9999f;
				int num2 = 0;
				for (int i = 0; i < list.Count; i++)
				{
					if (!val.IsValid())
					{
						break;
					}
					if (val.GetZDO() == null)
					{
						break;
					}
					try
					{
						DamageAreaMethod.Invoke(__instance, new object[2] { i, hit });
						num2++;
					}
					catch (Exception ex)
					{
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)string.Format("[{0}] DamageArea({1}) failed: {2}", "modbykou_minechop", i, ex.Message));
						}
					}
				}
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogInfo((object)string.Format("[{0}] MineRock5 '{1}' FINAL swing {2}/{3}, areasHit={4}", "modbykou_minechop", ((Object)((Component)__instance).gameObject).name, soFar, num, num2));
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Destructible), "Damage")]
		private static class Destructible_Damage_Patch
		{
			[HarmonyPrefix]
			private static void Prefix(Destructible __instance, ref HitData hit)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				//IL_002d: Invalid comparison between Unknown and I4
				if (!Effective.Enabled || !ActivationKeyHeld() || (Object)(object)__instance == (Object)null || hit == null)
				{
					return;
				}
				DestructibleType destructibleType = __instance.GetDestructibleType();
				bool flag = (int)destructibleType == 2;
				bool flag2 = (int)destructibleType == 1;
				if (!flag && !flag2)
				{
					return;
				}
				bool flag3 = flag && hit.m_damage.m_chop > 0f;
				bool flag4 = flag2 && hit.m_damage.m_pickaxe > 0f;
				if (flag3 || flag4)
				{
					ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
					ZDO zdo = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO() : null);
					int min = (flag ? Effective.TreeMinHits : Effective.RockMinHits);
					int max = (flag ? Effective.TreeMaxHits : Effective.RockMaxHits);
					int num = RollHitsForTarget(zdo, min, max);
					if (!flag3)
					{
						s_lastRockHits = num;
					}
					int soFar;
					bool flag5 = CountSwing(zdo, num, out soFar);
					if (flag3)
					{
						hit.m_damage.m_chop = (flag5 ? 9999f : 1f);
					}
					else
					{
						hit.m_damage.m_pickaxe = (flag5 ? 9999f : 1f);
					}
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)string.Format("[{0}] Destructible({1}) '{2}' swing {3}/{4} final={5}", "modbykou_minechop", flag3 ? "tree" : "rock", ((Object)((Component)__instance).gameObject).name, soFar, num, flag5));
					}
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
		private static class Attack_GetAttackStamina_Patch
		{
			[HarmonyPostfix]
			private static void Postfix(Attack __instance, ref float __result)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected I4, but got Unknown
				if (!Effective.Enabled || !ActivationKeyHeld() || __instance == null)
				{
					return;
				}
				ItemData weapon = __instance.GetWeapon();
				if (weapon == null || weapon.m_shared == null)
				{
					return;
				}
				switch ((int)weapon.m_shared.m_skillType)
				{
				case 7:
					__result = Effective.ChopStamina;
					break;
				case 12:
				{
					Player localPlayer = Player.m_localPlayer;
					float num = ((s_lastRockHits > 0) ? RockStaminaPercent(s_lastRockHits) : (-1f));
					if ((Object)(object)localPlayer != (Object)null && num >= 0f)
					{
						__result = ((Character)localPlayer).GetMaxStamina() * num;
					}
					else
					{
						__result = Effective.PickaxeStamina;
					}
					break;
				}
				}
			}
		}

		public const string PluginGuid = "kou_minechop";

		public const string PluginName = "modbykou_minechop";

		public const string PluginVersion = "1.5.0";

		private const string SyncRpcName = "CfgMineChop_Sync";

		internal static ManualLogSource Log;

		internal static Harmony HarmonyInstance;

		internal static ConfigEntry<bool> cfgEnabled;

		internal static ConfigEntry<bool> cfgServerAuthoritative;

		internal static ConfigEntry<int> cfgTreeMinHits;

		internal static ConfigEntry<int> cfgTreeMaxHits;

		internal static ConfigEntry<int> cfgRockMinHits;

		internal static ConfigEntry<int> cfgRockMaxHits;

		internal static ConfigEntry<float> cfgChopStamina;

		internal static ConfigEntry<float> cfgPickaxeStamina;

		internal static ConfigEntry<string> cfgRockStaminaTable;

		internal static ConfigEntry<string> cfgActivationKey;

		internal static SyncedValues Effective = new SyncedValues();

		private static bool s_receivedFromServer = false;

		private static bool s_rpcRegistered = false;

		private static KeyCode s_activationKeyCode = (KeyCode)308;

		private static string s_activationKeyRaw;

		private static readonly Dictionary<int, int> s_hitCounts = new Dictionary<int, int>();

		internal static int s_lastRockHits = 0;

		private const int SKILL_AXES = 7;

		private const int SKILL_PICKAXES = 12;

		internal static bool ActivationKeyHeld()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			string activationKey = Effective.ActivationKey;
			if (!string.Equals(activationKey, s_activationKeyRaw, StringComparison.Ordinal))
			{
				s_activationKeyRaw = activationKey;
				if (string.IsNullOrEmpty(activationKey) || !Enum.TryParse<KeyCode>(activationKey.Trim(), ignoreCase: true, out s_activationKeyCode))
				{
					s_activationKeyCode = (KeyCode)0;
					if (!string.IsNullOrEmpty(activationKey))
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)("[modbykou_minechop] ActivationKey '" + activationKey + "' is not a valid UnityEngine.KeyCode — mod stays always active."));
						}
					}
				}
			}
			if ((int)s_activationKeyCode != 0)
			{
				return Input.GetKey(s_activationKeyCode);
			}
			return true;
		}

		private void Awake()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			cfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. If false, mod behaves as if uninstalled.");
			cfgServerAuthoritative = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ServerAuthoritative", true, "When true, a joined client's values are overridden by the server's config on connect. Set both server and client to true (default).");
			cfgTreeMinHits = ((BaseUnityPlugin)this).Config.Bind<int>("Trees", "MinHits", 2, new ConfigDescription("Minimum hits to fell a tree/log. Set MinHits == MaxHits for fixed hit count.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			cfgTreeMaxHits = ((BaseUnityPlugin)this).Config.Bind<int>("Trees", "MaxHits", 2, new ConfigDescription("Maximum hits to fell a tree/log. If greater than MinHits, per-target hits are rolled uniformly (deterministic per target).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			cfgChopStamina = ((BaseUnityPlugin)this).Config.Bind<float>("Trees", "StaminaPerHit", 15f, new ConfigDescription("Stamina drained per axe swing (regardless of skill/perks).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>()));
			cfgRockMinHits = ((BaseUnityPlugin)this).Config.Bind<int>("Rocks", "MinHits", 3, new ConfigDescription("Minimum hits to destroy an ore vein/rock/mine-area. Set MinHits == MaxHits for fixed hit count.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			cfgRockMaxHits = ((BaseUnityPlugin)this).Config.Bind<int>("Rocks", "MaxHits", 7, new ConfigDescription("Maximum hits to destroy an ore vein/rock/mine-area. If greater than MinHits, per-target hits are rolled uniformly.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			cfgPickaxeStamina = ((BaseUnityPlugin)this).Config.Bind<float>("Rocks", "StaminaPerHit", 15f, new ConfigDescription("Fallback stamina per pickaxe swing when no entry matches in StaminaPercentTable.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>()));
			cfgRockStaminaTable = ((BaseUnityPlugin)this).Config.Bind<string>("Rocks", "StaminaPercentTable", "3:50,4:40,5:30,6:15,7:10", "Per-swing mining stamina as PERCENT of max stamina, keyed by the rock's rolled hit count. Format: hits:percent,hits:percent,...");
			cfgActivationKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ActivationKey", "LeftAlt", "The mod only takes effect while this key is HELD. Any UnityEngine.KeyCode name (e.g. LeftAlt, LeftControl, X). Empty or None = always active. Server-synced when ServerAuthoritative is true.");
			RefreshEffectiveFromLocal();
			HarmonyInstance = new Harmony("kou_minechop");
			HarmonyInstance.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"[modbykou_minechop] v1.5.0 loaded.");
			Log.LogInfo((object)(string.Format("[{0}] Effective config: Enabled={1} ", "modbykou_minechop", Effective.Enabled) + $"Trees={Effective.TreeMinHits}-{Effective.TreeMaxHits} hits @ {Effective.ChopStamina} stam, " + $"Rocks={Effective.RockMinHits}-{Effective.RockMaxHits} hits @ {Effective.PickaxeStamina} stam."));
		}

		private void OnDestroy()
		{
			Harmony harmonyInstance = HarmonyInstance;
			if (harmonyInstance != null)
			{
				harmonyInstance.UnpatchSelf();
			}
		}

		internal static void RefreshEffectiveFromLocal()
		{
			Effective.Enabled = cfgEnabled.Value;
			Effective.TreeMinHits = Math.Max(1, Math.Min(cfgTreeMinHits.Value, cfgTreeMaxHits.Value));
			Effective.TreeMaxHits = Math.Max(Effective.TreeMinHits, cfgTreeMaxHits.Value);
			Effective.RockMinHits = Math.Max(1, Math.Min(cfgRockMinHits.Value, cfgRockMaxHits.Value));
			Effective.RockMaxHits = Math.Max(Effective.RockMinHits, cfgRockMaxHits.Value);
			Effective.ChopStamina = Math.Max(0f, cfgChopStamina.Value);
			Effective.PickaxeStamina = Math.Max(0f, cfgPickaxeStamina.Value);
			Effective.RockStaminaTable = cfgRockStaminaTable.Value;
			Effective.ActivationKey = cfgActivationKey.Value;
		}

		internal static int RollHitsForTarget(ZDO zdo, int min, int max)
		{
			if (min >= max)
			{
				return min;
			}
			long num = ((zdo != null) ? ((object)zdo).GetHashCode() : 0);
			long num2 = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID() : 0);
			return new Random((int)(num ^ (num2 >> 3) ^ (num2 << 17))).Next(min, max + 1);
		}

		internal static float ModifierFactor(DamageModifier m)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected I4, but got Unknown
			return (m - 1) switch
			{
				0 => 0.5f, 
				4 => 0.25f, 
				6 => 0.75f, 
				1 => 1.5f, 
				5 => 2f, 
				7 => 1.25f, 
				2 => 0f, 
				3 => 0f, 
				_ => 1f, 
			};
		}

		internal static float ComputePerHit(float maxHealth, int hits, DamageModifier mod)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float num = ModifierFactor(mod);
			if (num <= 0.0001f)
			{
				return 9999f;
			}
			return (maxHealth / (float)hits + 0.5f) / num;
		}

		internal static float RockStaminaPercent(int hits)
		{
			string rockStaminaTable = Effective.RockStaminaTable;
			if (string.IsNullOrEmpty(rockStaminaTable))
			{
				return -1f;
			}
			string[] array = rockStaminaTable.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				if (array2.Length == 2 && int.TryParse(array2[0].Trim(), out var result) && result == hits && float.TryParse(array2[1].Trim(), out var result2))
				{
					return Mathf.Clamp(result2, 0f, 100f) / 100f;
				}
			}
			return -1f;
		}

		internal static bool CountSwing(ZDO zdo, int hitsNeeded, out int soFar)
		{
			int key = ((object)zdo)?.GetHashCode() ?? 0;
			s_hitCounts.TryGetValue(key, out soFar);
			soFar++;
			if (soFar >= hitsNeeded)
			{
				s_hitCounts.Remove(key);
				return true;
			}
			s_hitCounts[key] = soFar;
			return false;
		}

		internal static void RegisterSyncRpcOnce()
		{
			if (!s_rpcRegistered && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<ZPackage>("CfgMineChop_Sync", (Action<long, ZPackage>)OnSyncReceived);
				s_rpcRegistered = true;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"[modbykou_minechop] Registered ZRoutedRpc handler 'CfgMineChop_Sync'.");
				}
			}
		}

		private static void OnSyncReceived(long sender, ZPackage pkg)
		{
			if (pkg == null)
			{
				return;
			}
			try
			{
				SyncedValues syncedValues = new SyncedValues
				{
					Enabled = pkg.ReadBool(),
					TreeMinHits = pkg.ReadInt(),
					TreeMaxHits = pkg.ReadInt(),
					RockMinHits = pkg.ReadInt(),
					RockMaxHits = pkg.ReadInt(),
					ChopStamina = pkg.ReadSingle(),
					PickaxeStamina = pkg.ReadSingle()
				};
				try
				{
					syncedValues.RockStaminaTable = pkg.ReadString();
				}
				catch
				{
					syncedValues.RockStaminaTable = Effective.RockStaminaTable;
				}
				try
				{
					syncedValues.ActivationKey = pkg.ReadString();
				}
				catch
				{
					syncedValues.ActivationKey = Effective.ActivationKey;
				}
				Effective = syncedValues;
				s_receivedFromServer = true;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)string.Format("[{0}] Server sync applied: trees {1}-{2} @ {3} stam; rocks {4}-{5} @ {6} stam.", "modbykou_minechop", syncedValues.TreeMinHits, syncedValues.TreeMaxHits, syncedValues.ChopStamina, syncedValues.RockMinHits, syncedValues.RockMaxHits, syncedValues.PickaxeStamina));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[modbykou_minechop] Failed to parse sync package: " + ex.Message));
				}
			}
		}

		internal static void PushConfigToPeer(long peerUid)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			if (ZRoutedRpc.instance != null)
			{
				ZPackage val = new ZPackage();
				val.Write(Effective.Enabled);
				val.Write(Effective.TreeMinHits);
				val.Write(Effective.TreeMaxHits);
				val.Write(Effective.RockMinHits);
				val.Write(Effective.RockMaxHits);
				val.Write(Effective.ChopStamina);
				val.Write(Effective.PickaxeStamina);
				val.Write(Effective.RockStaminaTable);
				val.Write(Effective.ActivationKey);
				ZRoutedRpc.instance.InvokeRoutedRPC(peerUid, "CfgMineChop_Sync", new object[1] { val });
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)string.Format("[{0}] Pushed config to peer {1}.", "modbykou_minechop", peerUid));
				}
			}
		}

		internal static bool IsServer()
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance != (Object)null)
			{
				return instance.IsServer();
			}
			return false;
		}
	}
}