using 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 HarmonyLib; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("LethalLibPrefabGuard")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LethalLibPrefabGuard")] [assembly: AssemblyTitle("LethalLibPrefabGuard")] [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 LethalLibPrefabGuard { [BepInPlugin("Harvy.LethalLibPrefabGuard", "LethalLib Prefab Guard", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PrefabGuardPlugin : BaseUnityPlugin { public const string Guid = "Harvy.LethalLibPrefabGuard"; internal static PrefabGuardPlugin Instance; private static Hook _startHook; private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Instance = this; MethodInfo method = typeof(StartOfRound).GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"StartOfRound.Start not found; guard inactive."); return; } _startHook = new Hook((MethodBase)method, typeof(PrefabGuardPlugin).GetMethod("StartOfRoundStartHook", BindingFlags.Static | BindingFlags.NonPublic)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Prefab guard hook installed around StartOfRound.Start (outside LethalLib's)."); } private static void StartOfRoundStartHook(Action orig, StartOfRound self) { try { CleanLists(self); } catch (Exception arg) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Guard cleanup failed (continuing anyway): {arg}"); } orig(self); } private static void CleanLists(StartOfRound self) { ReportBrokenRegistrations(); Type type = AccessTools.TypeByName("LethalLib.Modules.Utilities"); if (type != null && AccessTools.Field(type, "prefabsToFix")?.GetValue(null) is List list) { int num = list.RemoveAll((GameObject go) => (Object)(object)go == (Object)null); if (num > 0) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Removed {num} null prefab(s) from LethalLib's fix list — some mod registered a null prefab; without this guard the landing sequence would soft-lock."); } } if (!((Object)(object)self.allItemsList != (Object)null)) { return; } IList itemsList = self.allItemsList.itemsList; if (itemsList == null) { return; } int num2 = 0; for (int num3 = itemsList.Count - 1; num3 >= 0; num3--) { object? obj = itemsList[num3]; Object val = (Object)((obj is Object) ? obj : null); if (val == null || val == (Object)null) { itemsList.RemoveAt(num3); num2++; } } if (num2 > 0) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Removed {num2} null entry(ies) from StartOfRound.allItemsList — a mod registered a broken item."); } } private static void ReportBrokenRegistrations() { Type type = AccessTools.TypeByName("LethalLib.Modules.Items"); if (type != null) { string[] array = new string[3] { "scrapItems", "shopItems", "plainItems" }; foreach (string text in array) { if (!(AccessTools.Field(type, text)?.GetValue(null) is IEnumerable enumerable)) { continue; } foreach (object item in enumerable) { if (item != null) { Type type2 = item.GetType(); string text2 = (AccessTools.Field(type2, "modName")?.GetValue(item) as string) ?? "Unknown"; object? obj = AccessTools.Field(type2, "item")?.GetValue(item); Item val = (Item)((obj is Item) ? obj : null); if (val == null || (Object)(object)val == (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("CULPRIT: '" + text2 + "' registered a null Item in Items." + text + ".")); } else if ((Object)(object)val.spawnPrefab == (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("CULPRIT: '" + text2 + "' registered item '" + val.itemName + "' with a NULL spawnPrefab in Items." + text + ".")); } } } } } Type type3 = AccessTools.TypeByName("LethalLib.Modules.Enemies"); if (!(type3 != null) || !(AccessTools.Field(type3, "spawnableEnemies")?.GetValue(null) is IEnumerable enumerable2)) { return; } foreach (object item2 in enumerable2) { if (item2 != null) { Type type4 = item2.GetType(); string text3 = (AccessTools.Field(type4, "modName")?.GetValue(item2) as string) ?? "Unknown"; object? obj2 = AccessTools.Field(type4, "enemy")?.GetValue(item2); EnemyType val2 = (EnemyType)((obj2 is EnemyType) ? obj2 : null); if (val2 == null || (Object)(object)val2 == (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("CULPRIT: '" + text3 + "' registered a null EnemyType in Enemies.spawnableEnemies.")); } else if ((Object)(object)val2.enemyPrefab == (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)("CULPRIT: '" + text3 + "' registered enemy '" + val2.enemyName + "' with a NULL enemyPrefab.")); } } } } } }