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 Fairer Fire Exits v80 v1.2.2
OreoM.FairerFireExits.dll
Decompiled 3 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using DunGen.Graph; using FairerFireExits.Networking; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using Microsoft.CodeAnalysis; using OreoM.FairerFireExits.NetcodePatcher; using Unity.Netcode; 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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("OreoM.FairerFireExits")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+7486ca21a11b9c310c8c11a6b190def0c9a2c0d2")] [assembly: AssemblyProduct("FairerFireExits")] [assembly: AssemblyTitle("OreoM.FairerFireExits")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>(); } } 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 FairerFireExits { [BepInPlugin("OreoM.FairerFireExits", "FairerFireExits", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class FairerFireExits : BaseUnityPlugin { public const string LethalConfigGUID = "ainavt.lc.lethalconfig"; public static FairerFireExits Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static FairerFireExitsConfig FireConfig { get; set; } internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); NetcodePatch(); Logger.LogInfo((object)"OreoM.FairerFireExits v1.2.0 has loaded!"); } private static void NetcodePatch() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("OreoM.FairerFireExits"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public class FairerFireExitsConfig { internal Dictionary<DungeonFlow, ConfigEntry<bool>> ApplyFireExitChangePerInterior; private bool? lethalConfigLoaded; public FairerFireExitsConfig(ConfigFile cfg, DungeonFlow[] AllInteriors) { if (!lethalConfigLoaded.HasValue) { lethalConfigLoaded = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"); } ApplyFireExitChangePerInterior = new Dictionary<DungeonFlow, ConfigEntry<bool>>(); cfg.SaveOnConfigSet = false; foreach (DungeonFlow val in AllInteriors) { ConfigEntry<bool> val2 = cfg.Bind<bool>("General", Regex.Replace(((Object)val).name, "Flow$", "", RegexOptions.None), true, "Apply Fairer Fire Exits patch to this interior"); if (ApplyFireExitChangePerInterior.TryGetValue(val, out ConfigEntry<bool> _)) { FairerFireExits.Logger.LogError((object)(((Object)val).name + " has duplicate entries, this shouldn't happen... skipping this entry")); continue; } if (lethalConfigLoaded.Value) { AddLethalConfigItem(val2); } ApplyFireExitChangePerInterior[val] = val2; } ClearOrphanedEntries(cfg); cfg.Save(); cfg.SaveOnConfigSet = true; if (lethalConfigLoaded.Value) { ConfigLethalConfigModEntry(); } } private void ClearOrphanedEntries(ConfigFile cfg) { PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries"); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg); dictionary.Clear(); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private void AddLethalConfigItem(ConfigEntry<bool> entry) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown BoolCheckBoxConfigItem val = new BoolCheckBoxConfigItem(entry, false); LethalConfigManager.AddConfigItem((BaseConfigItem)(object)val); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private void ConfigLethalConfigModEntry() { LethalConfigManager.SetModDescription("Choose what modded interiors are affected by this mod!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "OreoM.FairerFireExits"; public const string PLUGIN_NAME = "FairerFireExits"; public const string PLUGIN_VERSION = "1.2.0"; } } namespace FairerFireExits.Patches { [HarmonyPatch(typeof(DungeonGenerator))] internal class DungeonGeneratorPatches { [HarmonyPatch("Generate")] [HarmonyPrefix] private static void PreGenerate(DungeonGenerator __instance) { if (((NetworkBehaviour)FFENetworkManager.Instance).IsServer || ((NetworkBehaviour)FFENetworkManager.Instance).IsHost) { if (FairerFireExits.FireConfig.ApplyFireExitChangePerInterior.TryGetValue(__instance.DungeonFlow, out ConfigEntry<bool> value) && !value.Value) { FairerFireExits.Logger.LogInfo((object)("Found current DungeonFlow (" + ((Object)__instance.DungeonFlow).name + ") config but patch is set to false")); FFENetworkManager.Instance.shouldUseFireExitPatch.Value = false; } else { FFENetworkManager.Instance.shouldUseFireExitPatch.Value = true; } } } [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")] [HarmonyPrefix] private static void PreProcessGlobalProps(DungeonGenerator __instance) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown if (!FFENetworkManager.Instance.shouldUseFireExitPatch.Value) { return; } foreach (Tile allTile in __instance.CurrentDungeon.AllTiles) { GlobalProp[] componentsInChildren = ((Component)allTile).GetComponentsInChildren<GlobalProp>(); GlobalProp[] array = componentsInChildren; foreach (GlobalProp val in array) { if (val.PropGroupID == 1231) { val.DepthWeightScale = new AnimationCurve(DungeonGeneratorHelper.fireExitKeyframes); } } SpawnSyncedObject componentInChildren = ((Component)allTile).GetComponentInChildren<SpawnSyncedObject>(); if (!((Object)(object)componentInChildren == (Object)null) && ((Object)componentInChildren.spawnPrefab).name == "EntranceTeleportA") { DungeonGeneratorHelper.mainDoorDepth = allTile.Placement.NormalizedPathDepth; FairerFireExits.Logger.LogInfo((object)$"Found Main exit at {DungeonGeneratorHelper.mainDoorDepth} of the main path"); } } } [HarmonyPatch(typeof(DungeonGenerator), "ProcessGlobalProps")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> TranspileProcessGlobalProps(IEnumerable<CodeInstruction> codes) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(codes, (ILGenerator)null); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.PropertyGetter(typeof(TilePlacementData), "NormalizedDepth"), (string)null) }); if (val.IsInvalid) { FairerFireExits.Logger.LogError((object)"Could not the ending pattern. Aborting TranspileProcessGlobalProps transpiler."); return codes; } int pos = val.Pos; val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldloc_3, (object)null, (string)null) }); if (val.IsInvalid) { FairerFireExits.Logger.LogError((object)"Could not the starting pattern. Aborting TranspileProcessGlobalProps transpiler."); return codes; } val.Advance(1); int pos2 = val.Pos; val.RemoveInstructionsInRange(pos2, pos); val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_S, (object)6), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DungeonGeneratorHelper), "GetNormalizedPathDepthForFireExit", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } } internal static class DungeonGeneratorHelper { public const int fireExitGroupID = 1231; public static float mainDoorDepth = 0f; public static readonly Keyframe[] fireExitKeyframes = (Keyframe[])(object)new Keyframe[5] { new Keyframe(0f, 0f, 0f, 0f), new Keyframe(0.2f, 0f, 7.952512E-06f, 0.04168295f), new Keyframe(0.5f, 0.3f, 7.952512E-06f, 0.04168295f), new Keyframe(0.8f, 1f, 0.02613646f, 0.02613646f), new Keyframe(1f, 1f, 0.02613646f, 0.02613646f) }; public static float GetAdjustedDistanceFromMain(float NormalizedPathDepth) { mainDoorDepth = 0f; float num = Mathf.Max(mainDoorDepth, 1f - mainDoorDepth); return Mathf.Abs(NormalizedPathDepth - mainDoorDepth) / num; } public static float GetNormalizedPathDepthForFireExit(Tile currTile, GlobalProp currProp, DungeonGenerator instance) { if (!FFENetworkManager.Instance.shouldUseFireExitPatch.Value) { return currTile.Placement.NormalizedDepth; } return (currProp.PropGroupID == 1231) ? GetAdjustedDistanceFromMain(currTile.Placement.NormalizedPathDepth) : currTile.Placement.NormalizedDepth; } } [HarmonyPatch(typeof(GameNetworkManager))] internal class GameNetworkManagerPatches { [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void PostStart(GameNetworkManager __instance) { FFENetworkManager.CreateAndRegisterPrefab(); DungeonFlow[] allInteriors = Resources.FindObjectsOfTypeAll<DungeonFlow>(); FairerFireExits.FireConfig = new FairerFireExitsConfig(((BaseUnityPlugin)FairerFireExits.Instance).Config, allInteriors); } [HarmonyPatch("Disconnect")] [HarmonyPrefix] private static void PreDisconnect(GameNetworkManager __instance) { FFENetworkManager.DespawnNetworkHandler(); } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatches { [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPrefix] private static void PreAwake(StartOfRound __instance) { FFENetworkManager.SpawnNetworkHandler(); } } } namespace FairerFireExits.Networking { internal class FFENetworkManager : NetworkBehaviour { private static GameObject prefab; private const bool default_shouldUseFireExitPatch = true; public NetworkVariable<bool> shouldUseFireExitPatch = new NetworkVariable<bool>(true, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public static FFENetworkManager Instance { get; private set; } public static void CreateAndRegisterPrefab() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)prefab != (Object)null)) { prefab = new GameObject("OreoM.FairerFireExits Prefab"); GameObject obj = prefab; ((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x3D); NetworkObject obj2 = prefab.AddComponent<NetworkObject>(); FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(obj2, GetHash("OreoM.FairerFireExits")); prefab.AddComponent<FFENetworkManager>(); NetworkManager.Singleton.AddNetworkPrefab(prefab); FairerFireExits.Logger.LogInfo((object)"Network prefab created and registered"); } } private static uint GetHash(string value) { return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0; } public static void SpawnNetworkHandler() { if (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost) { Object.Instantiate<GameObject>(prefab).GetComponent<NetworkObject>().Spawn(false); FairerFireExits.Logger.LogInfo((object)"Network handler spawned"); } } public static void DespawnNetworkHandler() { if ((Object)(object)Instance != (Object)null && ((Component)Instance).gameObject.GetComponent<NetworkObject>().IsSpawned && (NetworkManager.Singleton.IsServer || NetworkManager.Singleton.IsHost)) { ((Component)Instance).gameObject.GetComponent<NetworkObject>().Despawn(true); FairerFireExits.Logger.LogInfo((object)"Network handler despawned"); } } private void Awake() { Instance = this; } protected override void __initializeVariables() { if (shouldUseFireExitPatch == null) { throw new Exception("FFENetworkManager.shouldUseFireExitPatch cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)shouldUseFireExitPatch).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)shouldUseFireExitPatch, "shouldUseFireExitPatch"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)shouldUseFireExitPatch); ((NetworkBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "FFENetworkManager"; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace OreoM.FairerFireExits.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }