Please disclose if your mod was created primarily 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 RootRegen v1.0.1
RootRegen.dll
Decompiled 9 months agousing System; using System.ComponentModel; using System.Diagnostics; using System.IO; 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 JetBrains.Annotations; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("RootRegen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+50a6c777714fa37208113e59d5a5318a8eca4ca9")] [assembly: AssemblyProduct("RootRegen")] [assembly: AssemblyTitle("RootRegen")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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; } } } namespace RootRegen { public enum RegenRate { [Description("Instant regeneration")] Instant = 0, [Description("10s")] [UsedImplicitly] Rate10 = 10, [Description("60s")] [UsedImplicitly] Rate60 = 60, [Description("100s")] [UsedImplicitly] Rate100 = 100, [Description("200s (Default)")] Rate200 = 200, [Description("300s")] [UsedImplicitly] Rate300 = 300, [Description("400s (Vanilla)")] [UsedImplicitly] Rate400 = 400, [Description("600s")] [UsedImplicitly] Rate600 = 600, [Description("1200s")] [UsedImplicitly] Rate1200 = 1200, [Description("Disable root sap regen")] Disabled = int.MaxValue } public static class RegenRateExt { public static float ToRatePerSec(this RegenRate rate) { return rate switch { RegenRate.Instant => 400f, RegenRate.Disabled => 0f, _ => 1f / (float)rate, }; } } [HarmonyPatch(typeof(ResourceRoot), "Awake")] public static class ResourceRoot_Awake_Patch { [UsedImplicitly] public static void Postfix(ResourceRoot __instance) { float num = RootRegen.RegenerationRate?.Value.ToRatePerSec() ?? RegenRate.Rate200.ToRatePerSec(); RootRegen.Log.LogDebug((object)$"Patching ResourceRoot with regen rate: {num}"); __instance.m_regenPerSec = num; } } [HarmonyPatch(typeof(ResourceRoot), "GetHoverText")] public static class ResourceRoot_GetHoverText_Patch { [UsedImplicitly] public static void Postfix(ResourceRoot __instance, ref string __result) { ConfigEntry<bool>? displayLevel = RootRegen.DisplayLevel; if (displayLevel == null || displayLevel.Value) { __result = __result + "\n" + FormatLevel(__instance); } } private static string FormatLevel(ResourceRoot __instance) { float maxLevel = __instance.m_maxLevel; float level = __instance.GetLevel(); float emptyTreshold = __instance.m_emptyTreshold; float highThreshold = __instance.m_highThreshold; string text = ((level > highThreshold) ? "#32CD32" : ((!(level < emptyTreshold)) ? "#FFFF00" : "#FF0000")); string arg = text; double num = Math.Round(100f * level / maxLevel); return $"<color={arg}>(level = {num}%)</color>"; } } [BepInPlugin("pulse0ne.rootregen", "RootRegen", "1.0.1")] public class RootRegen : BaseUnityPlugin { private const string PluginId = "pulse0ne.rootregen"; private const string PluginName = "RootRegen"; private const string ConfigFileName = "pulse0ne.rootregen.cfg"; private static readonly string ConfigFileFullPath = string.Format("{0}{1}{2}", Paths.ConfigPath, Path.DirectorySeparatorChar, "pulse0ne.rootregen.cfg"); public static readonly ManualLogSource Log = Logger.CreateLogSource("RootRegen"); public static ConfigEntry<RegenRate>? RegenerationRate; public static ConfigEntry<bool>? DisplayLevel; private DateTime _lastConfigReload; private const long RELOAD_DELAY = 10000000L; private Harmony? _harmony; [UsedImplicitly] private void Awake() { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; RegenerationRate = ((BaseUnityPlugin)this).Config.Bind<RegenRate>("Root Regeneration", "Regeneration Rate", RegenRate.Rate200, "How fast sap regenerates in the root. Default is 200s per sap, vanilla is 400s."); DisplayLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Root Regeneration", "Display Level", true, "Whether or not to display the percentage of sap remaining in the root."); ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; SetupWatcher(); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "pulse0ne.rootregen"); } [UsedImplicitly] private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.PluginPath, "pulse0ne.rootregen.cfg"); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { DateTime now = DateTime.Now; long num = now.Ticks - _lastConfigReload.Ticks; if (File.Exists(ConfigFileFullPath) && num >= 10000000) { try { Log.LogDebug((object)"Attempting to reload configuration..."); ((BaseUnityPlugin)this).Config.Reload(); } catch { Log.LogError((object)"There was an issue loading pulse0ne.rootregen.cfg"); } _lastConfigReload = now; } } } }