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 FreeFuelSource v1.0.0
FreeFuelSource.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("FreeFuelSource")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0")] [assembly: AssemblyProduct("FreeFuelSource")] [assembly: AssemblyTitle("FreeFuelSource")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 FreeFuelSource { [BepInPlugin("Moopfam.FreeFuelSource", "FreeFuelSource", "1.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "Moopfam.FreeFuelSource"; public const string PluginName = "FreeFuelSource"; public const string PluginVersion = "1.0"; private const string SectionGeneral = "01 - General"; private const string SectionFireSources = "02 - Fire Sources"; private const string SectionLighting = "03 - Lighting"; private const string SectionProductionFuel = "04 - Production Fuel"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> Campfires; internal static ConfigEntry<bool> Bonfires; internal static ConfigEntry<bool> Hearths; internal static ConfigEntry<bool> Fireplaces; internal static ConfigEntry<bool> OtherFireSources; internal static ConfigEntry<bool> Torches; internal static ConfigEntry<bool> Sconces; internal static ConfigEntry<bool> Braziers; internal static ConfigEntry<bool> Candles; internal static ConfigEntry<bool> JackOTurnip; internal static ConfigEntry<bool> Smelters; internal static ConfigEntry<bool> BlastFurnaces; internal static ConfigEntry<bool> CharcoalKilns; internal static ConfigEntry<bool> StoneOvens; internal static ConfigEntry<bool> EitrRefineries; internal static ConfigEntry<bool> OtherProductionFuelSources; internal static ManualLogSource Log; private Harmony _harmony; internal static FuelConfigSnapshot EffectiveSettings { get { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer() && VersionHandshake.ServerSettings != null) { return VersionHandshake.ServerSettings; } return LocalSnapshot(); } } private void Awake() { //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Enabled = Bind("01 - General", "Enabled", defaultValue: true, "Master switch for FreeFuelSource. On multiplayer servers the server value is authoritative."); Campfires = Bind("02 - Fire Sources", "Campfires", defaultValue: true, "Basic Campfire / Fire Pit (fire_pit) and other campfire-named Fireplace sources."); Bonfires = Bind("02 - Fire Sources", "Bonfires", defaultValue: false, "Bonfire fuel is free."); Hearths = Bind("02 - Fire Sources", "Hearths", defaultValue: false, "Hearth fuel is free."); Fireplaces = Bind("02 - Fire Sources", "Fireplaces", defaultValue: false, "Other fireplace-named fire sources."); OtherFireSources = Bind("02 - Fire Sources", "OtherFireSources", defaultValue: false, "Make any other Fireplace component source fuel-free. Enable this for modded/unknown fire sources."); Torches = Bind("03 - Lighting", "Torches", defaultValue: true, "Torch fuel is free."); Sconces = Bind("03 - Lighting", "Sconces", defaultValue: true, "Sconce fuel is free."); Braziers = Bind("03 - Lighting", "Braziers", defaultValue: true, "Brazier fuel is free."); Candles = Bind("03 - Lighting", "Candles", defaultValue: true, "Candle-style Fireplace sources use free fuel."); JackOTurnip = Bind("03 - Lighting", "JackOTurnip", defaultValue: true, "Jack-o-Turnip-style lights use free fuel."); Smelters = Bind("04 - Production Fuel", "Smelters", defaultValue: false, "Standard Smelter coal is treated as unlimited."); BlastFurnaces = Bind("04 - Production Fuel", "BlastFurnaces", defaultValue: false, "Blast Furnace coal is treated as unlimited."); CharcoalKilns = Bind("04 - Production Fuel", "CharcoalKilns", defaultValue: false, "Charcoal Kiln fuel is treated as unlimited."); StoneOvens = Bind("04 - Production Fuel", "StoneOvens", defaultValue: false, "Stone Oven fuel is treated as unlimited."); EitrRefineries = Bind("04 - Production Fuel", "EitrRefineries", defaultValue: false, "Eitr Refinery fuel source is treated as unlimited where it uses Valheim's Smelter fuel system."); OtherProductionFuelSources = Bind("04 - Production Fuel", "OtherProductionFuelSources", defaultValue: false, "Treat other/modded Smelter-component fuel sources as unlimited."); _harmony = new Harmony("Moopfam.FreeFuelSource"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FreeFuelSource 1.0 loaded. Multiplayer requires the same mod version on the server and every client."); } private ConfigEntry<bool> Bind(string section, string key, bool defaultValue, string description) { ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>(section, key, defaultValue, description); val.SettingChanged += delegate { VersionHandshake.BroadcastServerState(); }; return val; } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static FuelConfigSnapshot LocalSnapshot() { return new FuelConfigSnapshot { Enabled = Value(Enabled), Campfires = Value(Campfires), Bonfires = Value(Bonfires), Hearths = Value(Hearths), Fireplaces = Value(Fireplaces), OtherFireSources = Value(OtherFireSources), Torches = Value(Torches), Sconces = Value(Sconces), Braziers = Value(Braziers), Candles = Value(Candles), JackOTurnip = Value(JackOTurnip), Smelters = Value(Smelters), BlastFurnaces = Value(BlastFurnaces), CharcoalKilns = Value(CharcoalKilns), StoneOvens = Value(StoneOvens), EitrRefineries = Value(EitrRefineries), OtherProductionFuelSources = Value(OtherProductionFuelSources) }; } private static bool Value(ConfigEntry<bool> entry) { return entry?.Value ?? false; } } internal sealed class FuelConfigSnapshot { internal bool Enabled; internal bool Campfires; internal bool Bonfires; internal bool Hearths; internal bool Fireplaces; internal bool OtherFireSources; internal bool Torches; internal bool Sconces; internal bool Braziers; internal bool Candles; internal bool JackOTurnip; internal bool Smelters; internal bool BlastFurnaces; internal bool CharcoalKilns; internal bool StoneOvens; internal bool EitrRefineries; internal bool OtherProductionFuelSources; internal void Write(ZPackage package) { package.Write(Enabled); package.Write(Campfires); package.Write(Bonfires); package.Write(Hearths); package.Write(Fireplaces); package.Write(OtherFireSources); package.Write(Torches); package.Write(Sconces); package.Write(Braziers); package.Write(Candles); package.Write(JackOTurnip); package.Write(Smelters); package.Write(BlastFurnaces); package.Write(CharcoalKilns); package.Write(StoneOvens); package.Write(EitrRefineries); package.Write(OtherProductionFuelSources); } internal static FuelConfigSnapshot Read(ZPackage package) { return new FuelConfigSnapshot { Enabled = package.ReadBool(), Campfires = package.ReadBool(), Bonfires = package.ReadBool(), Hearths = package.ReadBool(), Fireplaces = package.ReadBool(), OtherFireSources = package.ReadBool(), Torches = package.ReadBool(), Sconces = package.ReadBool(), Braziers = package.ReadBool(), Candles = package.ReadBool(), JackOTurnip = package.ReadBool(), Smelters = package.ReadBool(), BlastFurnaces = package.ReadBool(), CharcoalKilns = package.ReadBool(), StoneOvens = package.ReadBool(), EitrRefineries = package.ReadBool(), OtherProductionFuelSources = package.ReadBool() }; } } internal static class VersionHandshake { internal const string RpcName = "Moopfam.FreeFuelSource.VersionCheck"; private static readonly HashSet<ZRpc> ValidatedPeers = new HashSet<ZRpc>(); private static readonly MethodInfo GetPeersMethod = AccessTools.Method(typeof(ZNet), "GetPeers", Type.EmptyTypes, (Type[])null); internal static FuelConfigSnapshot ServerSettings { get; private set; } internal static void RegisterAndSend(ZNetPeer peer) { if (peer != null && peer.m_rpc != null) { peer.m_rpc.Register<ZPackage>("Moopfam.FreeFuelSource.VersionCheck", (Action<ZRpc, ZPackage>)ReceiveVersion); SendState(peer); } } internal static bool IsValidated(ZRpc rpc) { return rpc != null && ValidatedPeers.Contains(rpc); } internal static void Reset() { ValidatedPeers.Clear(); ServerSettings = null; } private static void ReceiveVersion(ZRpc rpc, ZPackage package) { if (rpc == null || package == null) { return; } string text = package.ReadString(); FuelConfigSnapshot serverSettings = FuelConfigSnapshot.Read(package); if (!string.Equals(text, "1.0", StringComparison.OrdinalIgnoreCase)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("FreeFuelSource: rejected peer with version " + text + ". Required version is 1.0.")); } return; } ValidatedPeers.Add(rpc); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { ServerSettings = serverSettings; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("FreeFuelSource: server version/config validated (" + text + ").")); } } else { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("FreeFuelSource: client version validated (" + text + ").")); } } } private static void SendState(ZNetPeer peer) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (peer != null && peer.m_rpc != null) { ZPackage val = new ZPackage(); val.Write("1.0"); Plugin.LocalSnapshot().Write(val); peer.m_rpc.Invoke("Moopfam.FreeFuelSource.VersionCheck", new object[1] { val }); } } internal static void BroadcastServerState() { try { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null || !instance.IsServer() || GetPeersMethod == null) { return; } object obj = GetPeersMethod.Invoke(instance, null); if (!(obj is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { ZNetPeer val = (ZNetPeer)((item is ZNetPeer) ? item : null); if (val != null) { SendState(val); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("FreeFuelSource: could not broadcast server config: " + ex.Message)); } } } internal static void RejectUnvalidatedPeer(ZNet znet, ZRpc rpc) { if ((Object)(object)znet == (Object)null || rpc == null) { return; } string text = (znet.IsServer() ? "client" : "server"); ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("FreeFuelSource: the " + text + " did not provide the required FreeFuelSource 1.0 handshake.")); } if (znet.IsServer()) { rpc.Invoke("Error", new object[1] { 3 }); return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ZNet), "m_connectionStatus"); if (fieldInfo != null) { fieldInfo.SetValue(null, (object)(ConnectionStatus)3); } try { ISocket socket = rpc.GetSocket(); if (socket != null) { socket.Close(); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("FreeFuelSource: failed to close incompatible connection: " + ex.Message)); } } } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class ZNetAwakePatch { private static void Prefix() { VersionHandshake.Reset(); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] internal static class ZNetOnNewConnectionPatch { private static void Prefix(ZNetPeer peer) { VersionHandshake.RegisterAndSend(peer); } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] internal static class ZNetPeerInfoPatch { private static bool Prefix(ZNet __instance, ZRpc rpc) { if (VersionHandshake.IsValidated(rpc)) { return true; } VersionHandshake.RejectUnvalidatedPeer(__instance, rpc); return false; } } internal static class FuelSourceClassifier { internal static string PrefabName(Component component) { if ((Object)(object)component == (Object)null || (Object)(object)component.gameObject == (Object)null) { return string.Empty; } return (((Object)component.gameObject).name ?? string.Empty).Replace("(Clone)", string.Empty).Trim(); } internal static bool IsFireplaceEnabled(Fireplace fireplace) { FuelConfigSnapshot effectiveSettings = Plugin.EffectiveSettings; if (!effectiveSettings.Enabled || (Object)(object)fireplace == (Object)null) { return false; } string value = PrefabName((Component)(object)fireplace); if (EqualsName(value, "fire_pit")) { return effectiveSettings.Campfires; } if (Contains(value, "jackoturnip")) { return effectiveSettings.JackOTurnip; } if (Contains(value, "torch")) { return effectiveSettings.Torches; } if (Contains(value, "sconce")) { return effectiveSettings.Sconces; } if (Contains(value, "brazier")) { return effectiveSettings.Braziers; } if (Contains(value, "candle")) { return effectiveSettings.Candles; } if (Contains(value, "bonfire")) { return effectiveSettings.Bonfires; } if (Contains(value, "hearth")) { return effectiveSettings.Hearths; } if (Contains(value, "campfire")) { return effectiveSettings.Campfires; } if (Contains(value, "fireplace")) { return effectiveSettings.Fireplaces; } return effectiveSettings.OtherFireSources; } internal static bool IsSmelterEnabled(Smelter smelter) { FuelConfigSnapshot effectiveSettings = Plugin.EffectiveSettings; if (!effectiveSettings.Enabled || (Object)(object)smelter == (Object)null) { return false; } string value = PrefabName((Component)(object)smelter); if (Contains(value, "blast") && Contains(value, "furnace")) { return effectiveSettings.BlastFurnaces; } if (Contains(value, "charcoal") || Contains(value, "kiln")) { return effectiveSettings.CharcoalKilns; } if (Contains(value, "oven")) { return effectiveSettings.StoneOvens; } if (Contains(value, "eitr") || Contains(value, "refinery")) { return effectiveSettings.EitrRefineries; } if (Contains(value, "smelter")) { return effectiveSettings.Smelters; } return effectiveSettings.OtherProductionFuelSources; } private static bool EqualsName(string value, string text) { return string.Equals(value, text, StringComparison.OrdinalIgnoreCase); } private static bool Contains(string value, string text) { return value.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0; } } [HarmonyPatch(typeof(Fireplace), "Awake")] internal static class FireplaceAwakePatch { private static void Postfix(Fireplace __instance) { FireplaceFuelController.Apply(__instance); } } [HarmonyPatch(typeof(Fireplace), "UpdateFireplace")] internal static class FireplaceUpdatePatch { private static void Prefix(Fireplace __instance) { FireplaceFuelController.Apply(__instance); } } internal static class FireplaceFuelController { private static readonly FieldInfo InfiniteFuelField = AccessTools.Field(typeof(Fireplace), "m_infiniteFuel"); internal static void Apply(Fireplace fireplace) { if (!((Object)(object)fireplace == (Object)null) && !(InfiniteFuelField == null)) { InfiniteFuelField.SetValue(fireplace, FuelSourceClassifier.IsFireplaceEnabled(fireplace)); } } } [HarmonyPatch] internal static class SmelterGetFuelPatch { private static readonly FieldInfo MaxFuelField = AccessTools.Field(typeof(Smelter), "m_maxFuel"); private static MethodBase TargetMethod() { return AccessTools.Method(typeof(Smelter), "GetFuel", Type.EmptyTypes, (Type[])null); } private static void Postfix(Smelter __instance, ref float __result) { if (!FuelSourceClassifier.IsSmelterEnabled(__instance) || MaxFuelField == null) { return; } try { object value = MaxFuelField.GetValue(__instance); if (value != null) { float num = Convert.ToSingle(value); if (num > __result) { __result = num; } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("FreeFuelSource: failed to override production fuel: " + ex.Message)); } } } } }