Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ServersideQoL Treesurrection v2.1.0
ServersideQoL.Treesurrection.dll
Decompiled a day agousing 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() { } } }