Decompiled source of MightyOaks v1.1.4

MightyOaks.dll

Decompiled 3 days 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 System.Security;
using System.Security.Permissions;
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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("MightyOaks")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Scales Oak trees in Valheim.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+3d6b0fe69cba0d8d3a763e070fcc23b4c620f9d7")]
[assembly: AssemblyProduct("MightyOaks")]
[assembly: AssemblyTitle("MightyOaks")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 MightyOaks
{
	[BepInPlugin("com.lailoken.mightyoaks", "MightyOaks", "1.1.4")]
	public class MightyOaksPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZNet), "Awake")]
		private static class ZNet_Awake_Patch
		{
			private static void Postfix(ZNet __instance)
			{
				ZRoutedRpc.instance.Register<ZPackage>("MightyOaks_ConfigSync", (Action<long, ZPackage>)RPC_MightyOaks_ConfigSync);
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class ZNet_OnNewConnection_Patch
		{
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				peer.m_rpc.Register<string>("MightyOaks_VersionCheck", (Action<ZRpc, string>)RPC_MightyOaks_VersionCheck);
				object value;
				if (!__instance.IsServer())
				{
					peer.m_rpc.Invoke("MightyOaks_VersionCheck", new object[1] { "1.1.4" });
				}
				else if (!VerificationStarted.TryGetValue(peer, out value))
				{
					VerificationStarted.Add(peer, null);
					if (peer.m_uid != 0)
					{
						SendConfigToPeer(peer);
					}
					((MonoBehaviour)__instance).StartCoroutine(VerifyPeer(peer));
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		private static class ZNet_Disconnect_Patch
		{
			private static void Prefix(ZNetPeer peer)
			{
				if (ZNet.instance.IsServer() && peer == null)
				{
				}
			}
		}

		[HarmonyPatch(typeof(ZNetView), "Awake")]
		private static class ZNetView_Awake_Patch
		{
			private static void Postfix(ZNetView __instance)
			{
				//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0283: Unknown result type (might be due to invalid IL or missing references)
				if (!Enabled.Value || !Object.op_Implicit((Object)(object)__instance) || !__instance.IsValid())
				{
					return;
				}
				ZDO zDO = __instance.GetZDO();
				if (zDO == null)
				{
					return;
				}
				string text = "";
				if (Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(zDO.GetPrefab());
					if (Object.op_Implicit((Object)(object)prefab))
					{
						text = ((Object)prefab).name;
					}
				}
				if (string.IsNullOrEmpty(text))
				{
					text = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", "");
				}
				if (text != "Oak1")
				{
					return;
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode("OakScaleFactor");
				float @float = zDO.GetFloat(stableHashCode, 0f);
				if (@float > 0.1f)
				{
					ApplyScale(__instance, @float);
				}
				else
				{
					if (!zDO.IsOwner())
					{
						return;
					}
					int num = 0;
					if (WorldGenerator.instance != null)
					{
						World value = Traverse.Create((object)WorldGenerator.instance).Field("m_world").GetValue<World>();
						if (value != null)
						{
							num = value.m_seed;
						}
					}
					if (num == 0 && (Object)(object)ZNet.instance != (Object)null)
					{
						World value2 = Traverse.Create((object)ZNet.instance).Field("m_world").GetValue<World>();
						if (value2 != null)
						{
							num = value2.m_seed;
						}
					}
					if (num == 0)
					{
						num = 123456;
					}
					Vector3 position = ((Component)__instance).transform.position;
					int num2 = num + (int)(position.x * 1000f) + (int)(position.z * 1000f);
					State state = Random.state;
					Random.InitState(num2);
					float num3 = 1f;
					if (Random.Range(0f, 100f) <= ScalingChance.Value)
					{
						float value3 = Random.value;
						float num4 = Mathf.Pow(value3, ScaleExponent.Value);
						num3 = Mathf.Lerp(MinScale.Value, MaxScale.Value, num4);
						ApplyScale(__instance, num3);
						zDO.Set(stableHashCode, num3);
						float num5 = value3 * 100f;
						_Logger.LogInfo((object)$"New Mighty Oak created! Scale: {num3:F2}x (Rolled {num5:F1}% percentile)");
					}
					Random.state = state;
					zDO.Set(stableHashCode, num3);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <VerifyPeer>d__18 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public ZNetPeer peer;

			private object <dummy>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <VerifyPeer>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<dummy>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(10f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (peer.m_socket.IsConnected())
					{
						if (!ValidatedPeers.TryGetValue(peer, out <dummy>5__1))
						{
							_Logger.LogWarning((object)$"Peer {peer.m_uid} failed to validate MightyOaks version (Timeout). Kicking.");
							ZNet.instance.Disconnect(peer);
						}
						<dummy>5__1 = null;
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGUID = "com.lailoken.mightyoaks";

		public const string PluginName = "MightyOaks";

		public const string PluginVersion = "1.1.4";

		private static ConfigEntry<float> ScalingChance;

		private static ConfigEntry<float> MinScale;

		private static ConfigEntry<float> MaxScale;

		private static ConfigEntry<float> ScaleExponent;

		private static ConfigEntry<bool> ScaleToughness;

		private static ConfigEntry<bool> MakeInvulnerable;

		private static ConfigEntry<float> InvulnerabilityThreshold;

		private static ConfigEntry<bool> Enabled;

		private static ManualLogSource _Logger;

		private static readonly ConditionalWeakTable<ZNetPeer, object> ValidatedPeers = new ConditionalWeakTable<ZNetPeer, object>();

		private static readonly ConditionalWeakTable<ZNetPeer, object> VerificationStarted = new ConditionalWeakTable<ZNetPeer, object>();

		private void Awake()
		{
			_Logger = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the plugin.");
			ScalingChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScalingChance", 25f, "Chance (0-100) to scale an Oak tree.");
			MinScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MinScale", 1f, "Minimum scale factor.");
			MaxScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxScale", 12f, "Maximum scale factor.");
			ScaleExponent = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ScaleExponent", 2f, "Exponent for scale distribution. 1.0 is linear (uniform). Higher values (e.g. 2.0, 3.0) make large trees rarer.");
			ScaleToughness = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ScaleToughness", true, "If true, scales the tree's health/toughness along with its size.");
			MakeInvulnerable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MakeInvulnerable", true, "Enable invulnerability for trees above a certain size.");
			InvulnerabilityThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "InvulnerabilityThreshold", 2f, "Scale threshold above which trees become invulnerable (if MakeInvulnerable is true).");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.lailoken.mightyoaks");
		}

		[IteratorStateMachine(typeof(<VerifyPeer>d__18))]
		private static IEnumerator VerifyPeer(ZNetPeer peer)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <VerifyPeer>d__18(0)
			{
				peer = peer
			};
		}

		private static void RPC_MightyOaks_VersionCheck(ZRpc rpc, string clientVersion)
		{
			if (!ZNet.instance.IsServer())
			{
				return;
			}
			ZNetPeer val = null;
			foreach (ZNetPeer peer in ZNet.instance.GetPeers())
			{
				if (peer.m_rpc == rpc)
				{
					val = peer;
					break;
				}
			}
			if (val == null)
			{
				_Logger.LogWarning((object)"Received version check from unknown RPC connection.");
				return;
			}
			long uid = val.m_uid;
			_Logger.LogInfo((object)$"Peer {uid} (Socket: {val.m_socket.GetHostName()}) has MightyOaks version: {clientVersion}");
			object value;
			if (!IsVersionCompatible(clientVersion, "1.1.4"))
			{
				_Logger.LogWarning((object)string.Format("Peer {0} has incompatible version {1} (Server: {2}). Disconnecting.", uid, clientVersion, "1.1.4"));
				ZNet.instance.Disconnect(val);
			}
			else if (!ValidatedPeers.TryGetValue(val, out value))
			{
				ValidatedPeers.Add(val, null);
				if (val.m_uid != 0)
				{
					SendConfigToPeer(val);
				}
			}
		}

		private static bool IsVersionCompatible(string v1, string v2)
		{
			try
			{
				Version version = new Version(v1);
				Version version2 = new Version(v2);
				return version.Major == version2.Major && version.Minor == version2.Minor;
			}
			catch
			{
				return false;
			}
		}

		private static void SendConfigToPeer(ZNetPeer peer)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			_Logger.LogInfo((object)$"Sending config to peer {peer.m_uid}");
			ZPackage val = new ZPackage();
			val.Write(ScalingChance.Value);
			val.Write(MinScale.Value);
			val.Write(MaxScale.Value);
			val.Write(ScaleExponent.Value);
			val.Write(ScaleToughness.Value);
			val.Write(MakeInvulnerable.Value);
			val.Write(InvulnerabilityThreshold.Value);
			ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "MightyOaks_ConfigSync", new object[1] { val });
		}

		private static void RPC_MightyOaks_ConfigSync(long sender, ZPackage pkg)
		{
			if (!ZNet.instance.IsServer())
			{
				_Logger.LogInfo((object)"Received config from server.");
				ScalingChance.Value = pkg.ReadSingle();
				MinScale.Value = pkg.ReadSingle();
				MaxScale.Value = pkg.ReadSingle();
				ScaleExponent.Value = pkg.ReadSingle();
				ScaleToughness.Value = pkg.ReadBool();
				MakeInvulnerable.Value = pkg.ReadBool();
				InvulnerabilityThreshold.Value = pkg.ReadSingle();
				_Logger.LogInfo((object)"Config synced with server.");
			}
		}

		private static void ApplyScale(ZNetView view, float scale)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			if (scale <= 1.01f || Mathf.Abs(((Component)view).transform.localScale.x - scale) < 0.01f)
			{
				return;
			}
			((Component)view).transform.localScale = Vector3.one * scale;
			if (ScaleToughness.Value)
			{
				Destructible component = ((Component)view).GetComponent<Destructible>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.m_health *= scale * scale;
				}
				TreeBase component2 = ((Component)view).GetComponent<TreeBase>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					component2.m_health *= scale * scale;
				}
			}
			if (MakeInvulnerable.Value && scale >= InvulnerabilityThreshold.Value)
			{
				Destructible component3 = ((Component)view).GetComponent<Destructible>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					component3.m_minToolTier = 1000;
					component3.m_damages.m_chop = (DamageModifier)3;
					component3.m_damages.m_pickaxe = (DamageModifier)3;
				}
				TreeBase component4 = ((Component)view).GetComponent<TreeBase>();
				if (Object.op_Implicit((Object)(object)component4))
				{
					component4.m_minToolTier = 1000;
					component4.m_damageModifiers.m_chop = (DamageModifier)3;
					component4.m_damageModifiers.m_pickaxe = (DamageModifier)3;
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MightyOaks";

		public const string PLUGIN_NAME = "MightyOaks";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}