Decompiled source of ServersideQoL Treesurrection v2.1.0

ServersideQoL.Treesurrection.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using ServersideQoL.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Lets tree stumps regrow")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+204f9f33466a3fbfe830fe172b162a96aaba64cd")]
[assembly: AssemblyProduct("ServersideQoL.Treesurrection")]
[assembly: AssemblyTitle("ServersideQoL.Treesurrection")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ServersideQoL.Treesurrection
{
	public sealed class Config : ConfigBase<Config>
	{
		public override ConfigEntry<bool> Enabled { get; } = ConfigBase<Config>.BindEx<bool>(cfg, true, "Enables/disables the entire mod", (AcceptableValueBase)null, (Deprecated<Config>)null, "Enabled");

		public ConfigEntry<int> SaplingDropChance { get; } = ConfigBase<Config>.BindEx<int>(cfg, 100, "The probability a destroyed tree stump will drop a sapling", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), (Deprecated<Config>)null, "SaplingDropChance");

		public ConfigEntry<float> SaplingInvulnerabilitySeconds { get; } = ConfigBase<Config>.BindEx<float>(cfg, 10f, "How long saplings will be invulnerable after being dropped", (AcceptableValueBase)null, (Deprecated<Config>)null, "SaplingInvulnerabilitySeconds");

		public ConfigEntry<float> GrowingTimeMultiplier { get; } = ConfigBase<Config>.BindEx<float>(cfg, 1f, "How long new saplings take to regrow as a factor of the time player planted trees take to grow", (AcceptableValueBase)null, (Deprecated<Config>)null, "GrowingTimeMultiplier");

		public Config(ConfigFile cfg, Logger logger)
			: base(cfg, logger)
		{
		}
	}
	[Processor("a17d6420-25d7-48bd-98ae-ca291083cfaa")]
	public sealed class StumpProcessor : Processor<StumpProcessor.PrefabInfo>
	{
		public sealed record PrefabInfo(Destructible Destructible) : ProcessorPrefabInfo()
		{
			[MemberNotNullWhen(true, "SaplingsByTree")]
			[MemberNotNullWhen(false, "Sapling")]
			public bool IsStump
			{
				[MemberNotNullWhen(true, "SaplingsByTree")]
				[MemberNotNullWhen(false, "Sapling")]
				get;
				[MemberNotNullWhen(true, "SaplingsByTree")]
				[MemberNotNullWhen(false, "Sapling")]
				private set;
			}

			public IReadOnlyDictionary<TreeBase, Plant>? SaplingsByTree { get; private set; }

			public Plant? Sapling { get; private set; }

			public override bool IsValid
			{
				get
				{
					if (((ProcessorPrefabInfo)this).PrefabInfo.Prefab == null)
					{
						return false;
					}
					if (__treesByStump == null || __saplingByTree == null || __saplings == null)
					{
						Initialize();
					}
					Plant value = ((ProcessorPrefabInfo)this).PrefabInfo.GetComponent<Plant>();
					if (value != null && __saplings.Contains(value))
					{
						Sapling = value;
						return true;
					}
					if (!__treesByStump.TryGetValue(((ProcessorPrefabInfo)this).PrefabInfo.Prefab, out HashSet<TreeBase> value2))
					{
						return false;
					}
					Dictionary<TreeBase, Plant> dictionary = new Dictionary<TreeBase, Plant>(value2.Count);
					foreach (TreeBase item in value2)
					{
						if (__saplingByTree.TryGetValue(item, out value))
						{
							dictionary.Add(item, value);
						}
					}
					if (dictionary.Count == 0)
					{
						return false;
					}
					SaplingsByTree = dictionary;
					IsStump = true;
					return true;
					[MemberNotNull(new string[] { "__treesByStump", "__saplingByTree", "__saplings" })]
					static void Initialize()
					{
						__treesByStump = new Dictionary<GameObject, HashSet<TreeBase>>();
						__saplingByTree = new Dictionary<TreeBase, Plant>();
						__saplings = new HashSet<Plant>();
						foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
						{
							TreeBase componentInChildren = prefab.GetComponentInChildren<TreeBase>();
							if (componentInChildren != null && componentInChildren.m_stubPrefab != null)
							{
								if (!__treesByStump.TryGetValue(componentInChildren.m_stubPrefab, out HashSet<TreeBase> value3))
								{
									__treesByStump.Add(componentInChildren.m_stubPrefab, value3 = new HashSet<TreeBase>());
								}
								value3.Add(componentInChildren);
							}
							else
							{
								Plant componentInChildren2 = prefab.GetComponentInChildren<Plant>();
								if (componentInChildren2 != null)
								{
									GameObject[] grownPrefabs = componentInChildren2.m_grownPrefabs;
									if (grownPrefabs != null && grownPrefabs.Length > 0)
									{
										GameObject[] grownPrefabs2 = componentInChildren2.m_grownPrefabs;
										foreach (GameObject val in grownPrefabs2)
										{
											TreeBase componentInChildren3 = val.GetComponentInChildren<TreeBase>();
											if (componentInChildren3 != null && componentInChildren3.m_stubPrefab != null)
											{
												__saplingByTree.Add(componentInChildren3, componentInChildren2);
												__saplings.Add(componentInChildren2);
											}
										}
									}
								}
							}
						}
					}
				}
			}

			private static Dictionary<GameObject, HashSet<TreeBase>>? __treesByStump;

			private static Dictionary<TreeBase, Plant>? __saplingByTree;

			private static HashSet<Plant>? __saplings;

			[CompilerGenerated]
			public override string ToString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("PrefabInfo");
				stringBuilder.Append(" { ");
				if (((ProcessorPrefabInfo)this).PrintMembers(stringBuilder))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append('}');
				return stringBuilder.ToString();
			}

			[CompilerGenerated]
			protected override bool PrintMembers(StringBuilder builder)
			{
				if (((ProcessorPrefabInfo)this).PrintMembers(builder))
				{
					builder.Append(", ");
				}
				builder.Append("Destructible = ");
				builder.Append(Destructible);
				builder.Append(", IsStump = ");
				builder.Append(IsStump.ToString());
				builder.Append(", SaplingsByTree = ");
				builder.Append(SaplingsByTree);
				builder.Append(", Sapling = ");
				builder.Append(Sapling);
				return true;
			}

			[CompilerGenerated]
			public override int GetHashCode()
			{
				return (((((ProcessorPrefabInfo)this).GetHashCode() * -1521134295 + EqualityComparer<Destructible>.Default.GetHashCode(Destructible)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(IsStump)) * -1521134295 + EqualityComparer<IReadOnlyDictionary<TreeBase, Plant>>.Default.GetHashCode(SaplingsByTree)) * -1521134295 + EqualityComparer<Plant>.Default.GetHashCode(Sapling);
			}

			[CompilerGenerated]
			public sealed override bool Equals(ProcessorPrefabInfo? other)
			{
				return ((object)this).Equals((object?)other);
			}

			[CompilerGenerated]
			public bool Equals(PrefabInfo? other)
			{
				if ((object)this != other)
				{
					if (((ProcessorPrefabInfo)this).Equals((ProcessorPrefabInfo)(object)other) && EqualityComparer<Destructible>.Default.Equals(Destructible, other.Destructible) && EqualityComparer<bool>.Default.Equals(IsStump, other.IsStump) && EqualityComparer<IReadOnlyDictionary<TreeBase, Plant>>.Default.Equals(SaplingsByTree, other.SaplingsByTree))
					{
						return EqualityComparer<Plant>.Default.Equals(Sapling, other.Sapling);
					}
					return false;
				}
				return true;
			}

			[CompilerGenerated]
			private PrefabInfo(PrefabInfo original)
				: base((ProcessorPrefabInfo)(object)original)
			{
				Destructible = original.Destructible;
				IsStump = original.IsStump;
				SaplingsByTree = original.SaplingsByTree;
				Sapling = original.Sapling;
			}
		}

		public const string Id = "a17d6420-25d7-48bd-98ae-ca291083cfaa";

		private readonly List<ZDO> _sectorObjects = new List<ZDO>();

		private static readonly ServerVar<long> __invulnerableUntilTicks = ServersideQoLPluginBaseCore<TreesurrectionPlugin, Config>.RegisterServerVar<long>("InvulnerableUntilTicks");

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (prefabInfo.IsStump)
			{
				zdo.Destroyed += OnStumpDestroyed;
				return (ProcessResult)2;
			}
			if (((Processor)this).PlacedObjects.Contains(zdo))
			{
				DateTimeOffset dateTimeOffset = new DateTimeOffset(__invulnerableUntilTicks.Get(zdo, 0L), default(TimeSpan));
				float num = (float)(dateTimeOffset - DateTimeOffset.UtcNow).TotalSeconds;
				if (num > 0f)
				{
					return ((Processor)this).ScheduleReprocessing(num);
				}
				ZDOVars vars = zdo.Vars;
				if (((ZDOVars)(ref vars)).GetHealth(0f) < 0f)
				{
					vars = zdo.Vars;
					((ZDOVars)(ref vars)).SetHealth(prefabInfo.Destructible.m_health, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 31);
				}
				return (ProcessResult)2;
			}
			return (ProcessResult)2;
		}

		private void OnStumpDestroyed(ServersideQoLZDO zdo)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			PrefabInfo processorPrefabInfo = Processor<PrefabInfo>.GetProcessorPrefabInfo(zdo);
			if ((object)processorPrefabInfo == null || !processorPrefabInfo.IsStump || Random.Range(0, 100) >= ConfigBase<Config>.Instance.SaplingDropChance.Value)
			{
				return;
			}
			Plant value = processorPrefabInfo.SaplingsByTree.Values.First();
			if (processorPrefabInfo.SaplingsByTree.Count > 1)
			{
				ZDOMan.instance.FindSectorObjects(zdo.ZDO.GetSector(), ZNet.instance.GetSyncedSimulationDistance(), _sectorObjects, (List<ZDO>)null);
				foreach (ZDO sectorObject in _sectorObjects)
				{
					TreeBase component = Processor.GetPrefabInfo(sectorObject.GetPrefab()).GetComponent<TreeBase>();
					if (component != null && processorPrefabInfo.SaplingsByTree.TryGetValue(component, out value))
					{
						break;
					}
				}
				_sectorObjects.Clear();
			}
			ServersideQoLZDO val = ((Processor)this).PlaceObject(zdo.ZDO.GetPosition(), StringExtensionMethods.GetStableHashCode(((Object)value).name), zdo.ZDO.GetRotation(), (CreatorMarkers)2);
			val.Fields<Plant>().Set((Func<Expression<Func<Plant, float>>>)(() => (Plant x) => x.m_growRadius), 0f, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 65).Set((Func<Expression<Func<Plant, bool>>>)(() => (Plant x) => x.m_destroyIfCantGrow), false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 66)
				.Set((Func<Expression<Func<Plant, bool>>>)(() => (Plant x) => x.m_needCultivatedGround), false, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 67)
				.Set((Func<Expression<Func<Plant, float>>>)(() => (Plant x) => x.m_growTime), value.m_growTime * ConfigBase<Config>.Instance.GrowingTimeMultiplier.Value, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 68)
				.Set((Func<Expression<Func<Plant, float>>>)(() => (Plant x) => x.m_growTimeMax), value.m_growTimeMax * ConfigBase<Config>.Instance.GrowingTimeMultiplier.Value, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.Treesurrection\\StumpProcessor.cs", 69);
			__invulnerableUntilTicks.Set(val, DateTimeOffset.UtcNow.AddSeconds(ConfigBase<Config>.Instance.SaplingInvulnerabilitySeconds.Value).Ticks);
		}
	}
	[BepInPlugin("ArgusMagnus.ServersideQoL.Treesurrection", "ServersideQoL.Treesurrection", "2.1.0")]
	public sealed class TreesurrectionPlugin : ServersideQoLPluginBase<TreesurrectionPlugin, Config>
	{
		public const string Author = "ArgusMagnus";

		public const string PluginName = "ServersideQoL.Treesurrection";

		public const string PluginGuid = "ArgusMagnus.ServersideQoL.Treesurrection";

		public const string PluginVersion = "2.1.0";

		public const string PluginInformationalVersion = "2.1.0";

		private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639259375553551233L, default(TimeSpan));

		protected override Config CreateConfigSingleton(ConfigFile configFile, Logger logger)
		{
			return new Config(configFile, logger);
		}

		protected override void RegisterProcessors(IProcessorCollection processors)
		{
			processors.Add<StumpProcessor>();
		}

		private void Awake()
		{
		}
	}
}