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 DecayControl v1.0.0
Landoria.DecayControl.dll
Decompiled 21 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Landoria.SharedLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Landoria.DecayControl")] [assembly: AssemblyDescription("Controls rain wear and fuel consumption for player-built pieces.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Landoria")] [assembly: AssemblyProduct("Landoria.DecayControl")] [assembly: AssemblyCopyright("Copyright © 2026 End3rbyte")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0F691AC2-F9E1-45CB-B34E-7B57171ADCE7")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.0.40036")] namespace Landoria.DecayControl { internal static class CreatorActivityPolicy { internal static HashSet<long> GetActiveCreators(IEnumerable<long> onlinePlayers) { return new HashSet<long>(onlinePlayers); } internal static bool IsCreatorActive(long creator, ISet<long> onlinePlayers) { return onlinePlayers.Contains(creator); } } internal static class DecayControlArgumentPolicy { internal static DecayControlMode Resolve(string[] arguments, string name, DecayControlMode configured) { string text = ReadValue(arguments, name); if (text == null) { return configured; } if (string.Equals(text, "default", StringComparison.OrdinalIgnoreCase)) { return DecayControlMode.Default; } if (string.Equals(text, "player-online", StringComparison.OrdinalIgnoreCase)) { return DecayControlMode.PlayerOnline; } if (string.Equals(text, "disabled", StringComparison.OrdinalIgnoreCase)) { return DecayControlMode.Disabled; } throw new InvalidOperationException("Command-line switch " + name + " requires default, player-online, or disabled."); } private static string ReadValue(string[] arguments, string name) { string text = null; for (int i = 0; i < arguments.Length; i++) { if (string.Equals(arguments[i], name, StringComparison.OrdinalIgnoreCase)) { if (text != null || i + 1 >= arguments.Length) { throw new InvalidOperationException("Command-line switch " + name + " is missing or duplicated."); } text = arguments[++i]; } } return text; } } internal enum DecayControlMode { Default, PlayerOnline, Disabled } internal static class DecayEffectPolicy { internal static bool ShouldApplyEnvironmentalWear(bool isVanillaRainTick, bool isPlayerBuilt, DecayControlMode mode, float activityMultiplier) { if (isVanillaRainTick && isPlayerBuilt) { switch (mode) { case DecayControlMode.Default: break; case DecayControlMode.PlayerOnline: return activityMultiplier > 0f; default: return false; } } return true; } internal static bool ShouldPauseFuel(bool isPlayerBuilt, bool firstUpdate, DecayControlMode mode, float activityMultiplier) { if (!isPlayerBuilt || mode == DecayControlMode.Default) { return false; } if (!(mode == DecayControlMode.Disabled || firstUpdate)) { return activityMultiplier <= 0f; } return true; } } internal static class DecayProtection { [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] private static class RainDamagePatch { private static bool Prefix(WearNTear __instance, float damage, HitData hitData) { float num = __instance.m_health * 0.05f; bool isVanillaRainTick = hitData == null && __instance.IsWet() && __instance.GetHealthPercentage() > 0.5f && Mathf.Approximately(damage, num); Piece component = ((Component)__instance).GetComponent<Piece>(); return DecayEffectPolicy.ShouldApplyEnvironmentalWear(isPlayerBuilt: (Object)(object)component != (Object)null && component.IsPlacedByPlayer(), activityMultiplier: GetActivityMultiplier(component), isVanillaRainTick: isVanillaRainTick, mode: DecayControlPlugin.Settings.EnvironmentalBuildingWear); } } [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] private static class FireplaceFuelPatch { private static void Prefix(Fireplace __instance, out float __state) { __state = __instance.m_secPerFuel; Piece component = ((Component)__instance).GetComponent<Piece>(); int num; int num2; if ((Object)(object)component != (Object)null) { num = (component.IsPlacedByPlayer() ? 1 : 0); if (num != 0) { num2 = ((!initializedFireplaces.TryGetValue(__instance, out var _)) ? 1 : 0); goto IL_0037; } } else { num = 0; } num2 = 0; goto IL_0037; IL_0037: bool flag = (byte)num2 != 0; if (flag) { initializedFireplaces.Add(__instance, new object()); } if (DecayEffectPolicy.ShouldPauseFuel(activityMultiplier: GetActivityMultiplier(component), isPlayerBuilt: (byte)num != 0, firstUpdate: flag, mode: DecayControlPlugin.Settings.FuelConsumption)) { __instance.m_secPerFuel = float.PositiveInfinity; } } private static void Postfix(Fireplace __instance, float __state) { __instance.m_secPerFuel = __state; } } private const float VanillaRainDamageFraction = 0.05f; private static readonly HashSet<long> ActiveCreators = new HashSet<long>(); private static ConditionalWeakTable<Fireplace, object> initializedFireplaces = new ConditionalWeakTable<Fireplace, object>(); private static bool hasServerState; internal static void Reset() { ActiveCreators.Clear(); hasServerState = false; initializedFireplaces = new ConditionalWeakTable<Fireplace, object>(); } internal static void WriteState(ZPackage package) { HashSet<long> activeCreators = GetActiveCreators(); package.Write(activeCreators.Count); foreach (long item in activeCreators) { package.Write(item); } } internal static void ReadState(ZPackage package) { ActiveCreators.Clear(); int num = package.ReadInt(); for (int i = 0; i < num; i++) { ActiveCreators.Add(package.ReadLong()); } hasServerState = true; } internal static float GetActivityMultiplier(Piece piece) { if ((Object)(object)piece == (Object)null || !piece.IsPlacedByPlayer()) { return 1f; } long creator = piece.GetCreator(); if (creator == 0L) { return 1f; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { if (!IsCreatorActive(creator, GetOnlinePlayers())) { return 0f; } return 1f; } if (hasServerState && !ActiveCreators.Contains(creator)) { return 0f; } return 1f; } private static HashSet<long> GetActiveCreators() { return CreatorActivityPolicy.GetActiveCreators(GetOnlinePlayers()); } private static bool IsCreatorActive(long creator, HashSet<long> onlinePlayers) { return CreatorActivityPolicy.IsCreatorActive(creator, onlinePlayers); } private static HashSet<long> GetOnlinePlayers() { HashSet<long> hashSet = new HashSet<long>(); if ((Object)(object)ZNet.instance == (Object)null) { return hashSet; } foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.IsReady() && !((ZDOID)(ref peer.m_characterID)).IsNone()) { hashSet.Add(((ZDOID)(ref peer.m_characterID)).UserID); } } if (!ServerRole.IsDedicatedServer && (Object)(object)Game.instance != (Object)null) { hashSet.Add(Game.instance.GetPlayerProfile().GetPlayerID()); } return hashSet; } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class DecayStateOnSpawnPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { DecayStateRpc.RequestOnSpawn(); } } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] internal static class DecayControlDisconnectPatch { private static void Prefix() { DecayStateRpc.ResetSession(); } } internal static class DecayStateRpc { private const string RequestRpc = "Landoria_DecayControl_Request"; private const string ResponseRpc = "Landoria_DecayControl_Response"; private static ZRoutedRpc registeredRpc; private static ZNetPeer serverPeer; private static bool requestSent; internal static void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != registeredRpc) { instance.Register("Landoria_DecayControl_Request", (Action<long>)ReceiveRequest); instance.Register<ZPackage>("Landoria_DecayControl_Response", (Action<long, ZPackage>)ReceiveResponse); registeredRpc = instance; } } internal static void RequestOnSpawn() { Update(); if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && ZRoutedRpc.instance != null && !requestSent) { serverPeer = ZNet.instance.GetServerPeer(); if (serverPeer != null) { requestSent = true; ZRoutedRpc.instance.InvokeRoutedRPC(serverPeer.m_uid, "Landoria_DecayControl_Request", Array.Empty<object>()); } } } internal static void ResetSession() { serverPeer = null; requestSent = false; DecayControlPlugin.Settings?.ResetState(); DecayProtection.Reset(); } private static void ReceiveRequest(long sender) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (ServerRole.IsDedicatedServer && ZNet.instance.GetPeer(sender) != null && ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); DecayControlPlugin.Settings.WriteState(val); DecayProtection.WriteState(val); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Landoria_DecayControl_Response", new object[1] { val }); } } private static void ReceiveResponse(long sender, ZPackage package) { if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && serverPeer != null && serverPeer.m_uid == sender) { DecayControlPlugin.Settings.ReadState(package); DecayProtection.ReadState(package); } } } [BepInPlugin("Landoria.DecayControl", "Landoria.DecayControl", "1.0.0")] public sealed class DecayControlPlugin : LandoriaPlugin { private const string PluginGuid = "Landoria.DecayControl"; private const string PluginName = "Landoria.DecayControl"; private const string PluginVersion = "1.0.0"; internal static ModLog Log { get; private set; } internal static DecayControlSettings Settings { get; private set; } private void Awake() { Log = InitializePlugin("Landoria.DecayControl"); Settings = new DecayControlSettings(); Settings.InitializeServer(Log); Log.LogInfo("Landoria.DecayControl 1.0.0 is loaded."); } private void Update() { DecayStateRpc.Update(); } private void OnDestroy() { DecayStateRpc.ResetSession(); DecayProtection.Reset(); Log?.LogInfo("Landoria.DecayControl 1.0.0 is unloaded."); ShutdownPlugin(); Settings = null; Log = null; } } internal sealed class DecayControlServerConfiguration { internal DecayControlMode FuelConsumption { get; private set; } internal DecayControlMode EnvironmentalBuildingWear { get; private set; } internal static DecayControlServerConfiguration FromArguments(string[] arguments) { return new DecayControlServerConfiguration { FuelConsumption = DecayControlArgumentPolicy.Resolve(arguments, "--decay-control-fuel-consumption", DecayControlMode.Default), EnvironmentalBuildingWear = DecayControlArgumentPolicy.Resolve(arguments, "--decay-control-environmental-building-wear", DecayControlMode.Default) }; } } internal sealed class DecayControlSettings { private bool serverInitialized; internal DecayControlMode FuelConsumption { get; private set; } internal DecayControlMode EnvironmentalBuildingWear { get; private set; } internal DecayControlSettings() { ResetState(); } internal void InitializeServer(ModLog logger) { if (!serverInitialized && ServerRole.IsDedicatedServer) { DecayControlServerConfiguration decayControlServerConfiguration = DecayControlServerConfiguration.FromArguments(Environment.GetCommandLineArgs()); FuelConsumption = decayControlServerConfiguration.FuelConsumption; EnvironmentalBuildingWear = decayControlServerConfiguration.EnvironmentalBuildingWear; serverInitialized = true; logger.LogInfo($"Effective decay settings: fuelConsumption={FuelConsumption}, " + $"environmentalBuildingWear={EnvironmentalBuildingWear}."); } } internal void WriteState(ZPackage package) { package.Write((int)FuelConsumption); package.Write((int)EnvironmentalBuildingWear); } internal void ReadState(ZPackage package) { FuelConsumption = (DecayControlMode)package.ReadInt(); EnvironmentalBuildingWear = (DecayControlMode)package.ReadInt(); } internal void ResetState() { if (!serverInitialized) { FuelConsumption = DecayControlMode.Default; EnvironmentalBuildingWear = DecayControlMode.Default; } } } } namespace Landoria.SharedLib { public abstract class LandoriaPlugin : BaseUnityPlugin { private Harmony _harmony; private bool _patchesApplied; protected ModLog InitializePlugin(string pluginGuid) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown ModLog modLog = new ModLog(((BaseUnityPlugin)this).Logger); Version version = ((object)this).GetType().Assembly.GetName().Version; modLog.LogInfo($"AssemblyVersion: {version}."); _harmony = new Harmony(pluginGuid); PatchOwnNamespace(modLog); return modLog; } protected void PatchOwnNamespace(ModLog log) { if (_patchesApplied) { log.LogDebug("Harmony patches are already active; skipping registration."); return; } string text = ((object)this).GetType().Namespace; Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { if (type.Namespace == text) { _harmony.CreateClassProcessor(type).Patch(); } } _patchesApplied = true; log.LogDebug("Harmony patches were applied for the plugin namespace."); } protected void ShutdownPlugin() { if (_patchesApplied) { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _patchesApplied = false; } } } public sealed class ModLog { private readonly ManualLogSource _logger; public ModLog(ManualLogSource logger) { _logger = logger; } public void LogFatal(object message) { Write((LogLevel)1, message); } public void LogError(object message) { Write((LogLevel)2, message); } public void LogWarning(object message) { Write((LogLevel)4, message); } public void LogMessage(object message) { Write((LogLevel)8, message); } public void LogInfo(object message) { Write((LogLevel)16, message); } public void LogDebug(object message) { Write((LogLevel)32, message); } public void Log(LogLevel level, object message) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Write(level, message); } private void Write(LogLevel level, object message) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) string arg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); _logger.Log(level, (object)$"[{arg}] {message}"); } } public static class ServerRole { public static bool IsDedicatedServer { get { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { return ZNet.instance.IsDedicated(); } return false; } } } }