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 Merged Levels v1.3.1
Omniscye.MergedLevels2.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; 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 Microsoft.CodeAnalysis; using Photon.Pun; 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: AssemblyCompany("Omniscye.MergedLevels2")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MergedLevels2")] [assembly: AssemblyTitle("Omniscye.MergedLevels2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } } [HarmonyPatch(typeof(MenuPageLobby))] public static class MenuPageLobby_Start_Patch { [HarmonyPostfix] [HarmonyPatch("Start")] private static void Postfix() { if ((Object)(object)Object.FindObjectOfType<NetworkConnect>() == (Object)null && (Object)(object)MainMenuOpen.instance != (Object)null) { MainMenuOpen.instance.NetworkConnect(); } } } namespace MergedLevels { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Omniscye.MergedLevels", "MergedLevels", "2.7.0")] public class MergedLevels : BaseUnityPlugin { public enum ValuablesMode { Global, ThemeLocked } [CompilerGenerated] private sealed class <<BuildExactPrefabKeys>g__FromList|40_0>d : IEnumerable<(string key, GameObject go)>, IEnumerable, IEnumerator<(string key, GameObject go)>, IEnumerator, IDisposable { private int <>1__state; private (string key, GameObject go) <>2__current; private int <>l__initialThreadId; private IEnumerable<PrefabRef> list; public IEnumerable<PrefabRef> <>3__list; private IEnumerator<PrefabRef> <>s__1; private PrefabRef <pr>5__2; private string <key>5__3; private GameObject <go>5__4; (string, GameObject) IEnumerator<(string, GameObject)>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <<BuildExactPrefabKeys>g__FromList|40_0>d(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>s__1 = null; <pr>5__2 = null; <key>5__3 = null; <go>5__4 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; goto IL_00ef; } <>1__state = -1; <>s__1 = (list ?? Enumerable.Empty<PrefabRef>()).GetEnumerator(); <>1__state = -3; goto IL_0105; IL_0105: do { if (<>s__1.MoveNext()) { <pr>5__2 = <>s__1.Current; continue; } <>m__Finally1(); <>s__1 = null; return false; } while (<pr>5__2 == null || !<pr>5__2.IsValid()); <key>5__3 = <pr>5__2.ResourcePath; <go>5__4 = <pr>5__2.Prefab; if (!string.IsNullOrEmpty(<key>5__3) && Object.op_Implicit((Object)(object)<go>5__4)) { <>2__current = (<key>5__3, <go>5__4); <>1__state = 1; return true; } goto IL_00ef; IL_00ef: <key>5__3 = null; <go>5__4 = null; <pr>5__2 = null; goto IL_0105; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__1 != null) { <>s__1.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<(string key, GameObject go)> IEnumerable<(string, GameObject)>.GetEnumerator() { <<BuildExactPrefabKeys>g__FromList|40_0>d <<BuildExactPrefabKeys>g__FromList|40_0>d; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <<BuildExactPrefabKeys>g__FromList|40_0>d = this; } else { <<BuildExactPrefabKeys>g__FromList|40_0>d = new <<BuildExactPrefabKeys>g__FromList|40_0>d(0); } <<BuildExactPrefabKeys>g__FromList|40_0>d.list = <>3__list; return <<BuildExactPrefabKeys>g__FromList|40_0>d; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<(string, GameObject)>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <>c__DisplayClass41_0 { public string targetPath; } [CompilerGenerated] private sealed class <BuildCrossLevelKeys>d__41 : IEnumerable<(string key, GameObject go)>, IEnumerable, IEnumerator<(string key, GameObject go)>, IEnumerator, IDisposable { private int <>1__state; private (string key, GameObject go) <>2__current; private int <>l__initialThreadId; private Level source; public Level <>3__source; private string targetLevelPath; public string <>3__targetLevelPath; private <>c__DisplayClass41_0 <>8__1; private IEnumerator<(string key, GameObject go)> <>s__2; private (string key, GameObject go) <e>5__3; private IEnumerator<(string key, GameObject go)> <>s__4; private (string key, GameObject go) <e>5__5; private IEnumerator<(string key, GameObject go)> <>s__6; private (string key, GameObject go) <e>5__7; private IEnumerator<(string key, GameObject go)> <>s__8; private (string key, GameObject go) <e>5__9; private IEnumerator<(string key, GameObject go)> <>s__10; private (string key, GameObject go) <e>5__11; private IEnumerator<(string key, GameObject go)> <>s__12; private (string key, GameObject go) <e>5__13; private IEnumerator<(string key, GameObject go)> <>s__14; private (string key, GameObject go) <e>5__15; private IEnumerator<(string key, GameObject go)> <>s__16; private (string key, GameObject go) <e>5__17; private IEnumerator<(string key, GameObject go)> <>s__18; private (string key, GameObject go) <e>5__19; private IEnumerator<(string key, GameObject go)> <>s__20; private (string key, GameObject go) <e>5__21; private IEnumerator<(string key, GameObject go)> <>s__22; private (string key, GameObject go) <e>5__23; private IEnumerator<(string key, GameObject go)> <>s__24; private (string key, GameObject go) <e>5__25; private IEnumerator<(string key, GameObject go)> <>s__26; private (string key, GameObject go) <e>5__27; (string, GameObject) IEnumerator<(string, GameObject)>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <BuildCrossLevelKeys>d__41(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; case -5: case 3: try { } finally { <>m__Finally3(); } break; case -6: case 4: try { } finally { <>m__Finally4(); } break; case -7: case 5: try { } finally { <>m__Finally5(); } break; case -8: case 6: try { } finally { <>m__Finally6(); } break; case -9: case 7: try { } finally { <>m__Finally7(); } break; case -10: case 8: try { } finally { <>m__Finally8(); } break; case -11: case 9: try { } finally { <>m__Finally9(); } break; case -12: case 10: try { } finally { <>m__Finally10(); } break; case -13: case 11: try { } finally { <>m__Finally11(); } break; case -14: case 12: try { } finally { <>m__Finally12(); } break; case -15: case 13: try { } finally { <>m__Finally13(); } break; } <>8__1 = null; <>s__2 = null; <e>5__3 = default((string, GameObject)); <>s__4 = null; <e>5__5 = default((string, GameObject)); <>s__6 = null; <e>5__7 = default((string, GameObject)); <>s__8 = null; <e>5__9 = default((string, GameObject)); <>s__10 = null; <e>5__11 = default((string, GameObject)); <>s__12 = null; <e>5__13 = default((string, GameObject)); <>s__14 = null; <e>5__15 = default((string, GameObject)); <>s__16 = null; <e>5__17 = default((string, GameObject)); <>s__18 = null; <e>5__19 = default((string, GameObject)); <>s__20 = null; <e>5__21 = default((string, GameObject)); <>s__22 = null; <e>5__23 = default((string, GameObject)); <>s__24 = null; <e>5__25 = default((string, GameObject)); <>s__26 = null; <e>5__27 = default((string, GameObject)); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass41_0(); if ((Object)(object)source == (Object)null) { return false; } <>8__1.targetPath = (targetLevelPath ?? "").Trim(); if (string.IsNullOrEmpty(<>8__1.targetPath)) { return false; } <>s__2 = <>8__1.<BuildCrossLevelKeys>g__From|0("Start Room", source.StartRooms).GetEnumerator(); <>1__state = -3; goto IL_0166; case 1: <>1__state = -3; <e>5__3 = default((string, GameObject)); goto IL_0166; case 2: <>1__state = -4; <e>5__5 = default((string, GameObject)); goto IL_01f1; case 3: <>1__state = -5; <e>5__7 = default((string, GameObject)); goto IL_027c; case 4: <>1__state = -6; <e>5__9 = default((string, GameObject)); goto IL_0307; case 5: <>1__state = -7; <e>5__11 = default((string, GameObject)); goto IL_0392; case 6: <>1__state = -8; <e>5__13 = default((string, GameObject)); goto IL_041d; case 7: <>1__state = -9; <e>5__15 = default((string, GameObject)); goto IL_04a8; case 8: <>1__state = -10; <e>5__17 = default((string, GameObject)); goto IL_0533; case 9: <>1__state = -11; <e>5__19 = default((string, GameObject)); goto IL_05bf; case 10: <>1__state = -12; <e>5__21 = default((string, GameObject)); goto IL_064b; case 11: <>1__state = -13; <e>5__23 = default((string, GameObject)); goto IL_06d7; case 12: <>1__state = -14; <e>5__25 = default((string, GameObject)); goto IL_0763; case 13: { <>1__state = -15; <e>5__27 = default((string, GameObject)); break; } IL_0763: if (<>s__24.MoveNext()) { <e>5__25 = <>s__24.Current; <>2__current = <e>5__25; <>1__state = 12; return true; } <>m__Finally12(); <>s__24 = null; <>s__26 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesExtraction3).GetEnumerator(); <>1__state = -15; break; IL_0392: if (<>s__10.MoveNext()) { <e>5__11 = <>s__10.Current; <>2__current = <e>5__11; <>1__state = 5; return true; } <>m__Finally5(); <>s__10 = null; <>s__12 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesNormal2).GetEnumerator(); <>1__state = -8; goto IL_041d; IL_041d: if (<>s__12.MoveNext()) { <e>5__13 = <>s__12.Current; <>2__current = <e>5__13; <>1__state = 6; return true; } <>m__Finally6(); <>s__12 = null; <>s__14 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesPassage2).GetEnumerator(); <>1__state = -9; goto IL_04a8; IL_064b: if (<>s__20.MoveNext()) { <e>5__21 = <>s__20.Current; <>2__current = <e>5__21; <>1__state = 10; return true; } <>m__Finally10(); <>s__20 = null; <>s__22 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesPassage3).GetEnumerator(); <>1__state = -13; goto IL_06d7; IL_0533: if (<>s__16.MoveNext()) { <e>5__17 = <>s__16.Current; <>2__current = <e>5__17; <>1__state = 8; return true; } <>m__Finally8(); <>s__16 = null; <>s__18 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesExtraction2).GetEnumerator(); <>1__state = -11; goto IL_05bf; IL_04a8: if (<>s__14.MoveNext()) { <e>5__15 = <>s__14.Current; <>2__current = <e>5__15; <>1__state = 7; return true; } <>m__Finally7(); <>s__14 = null; <>s__16 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesDeadEnd2).GetEnumerator(); <>1__state = -10; goto IL_0533; IL_0166: if (<>s__2.MoveNext()) { <e>5__3 = <>s__2.Current; <>2__current = <e>5__3; <>1__state = 1; return true; } <>m__Finally1(); <>s__2 = null; <>s__4 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesNormal1).GetEnumerator(); <>1__state = -4; goto IL_01f1; IL_05bf: if (<>s__18.MoveNext()) { <e>5__19 = <>s__18.Current; <>2__current = <e>5__19; <>1__state = 9; return true; } <>m__Finally9(); <>s__18 = null; <>s__20 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesNormal3).GetEnumerator(); <>1__state = -12; goto IL_064b; IL_01f1: if (<>s__4.MoveNext()) { <e>5__5 = <>s__4.Current; <>2__current = <e>5__5; <>1__state = 2; return true; } <>m__Finally2(); <>s__4 = null; <>s__6 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesPassage1).GetEnumerator(); <>1__state = -5; goto IL_027c; IL_027c: if (<>s__6.MoveNext()) { <e>5__7 = <>s__6.Current; <>2__current = <e>5__7; <>1__state = 3; return true; } <>m__Finally3(); <>s__6 = null; <>s__8 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesDeadEnd1).GetEnumerator(); <>1__state = -6; goto IL_0307; IL_06d7: if (<>s__22.MoveNext()) { <e>5__23 = <>s__22.Current; <>2__current = <e>5__23; <>1__state = 11; return true; } <>m__Finally11(); <>s__22 = null; <>s__24 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesDeadEnd3).GetEnumerator(); <>1__state = -14; goto IL_0763; IL_0307: if (<>s__8.MoveNext()) { <e>5__9 = <>s__8.Current; <>2__current = <e>5__9; <>1__state = 4; return true; } <>m__Finally4(); <>s__8 = null; <>s__10 = <>8__1.<BuildCrossLevelKeys>g__From|0("Modules", source.ModulesExtraction1).GetEnumerator(); <>1__state = -7; goto IL_0392; } if (<>s__26.MoveNext()) { <e>5__27 = <>s__26.Current; <>2__current = <e>5__27; <>1__state = 13; return true; } <>m__Finally13(); <>s__26 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__2 != null) { <>s__2.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>s__4 != null) { <>s__4.Dispose(); } } private void <>m__Finally3() { <>1__state = -1; if (<>s__6 != null) { <>s__6.Dispose(); } } private void <>m__Finally4() { <>1__state = -1; if (<>s__8 != null) { <>s__8.Dispose(); } } private void <>m__Finally5() { <>1__state = -1; if (<>s__10 != null) { <>s__10.Dispose(); } } private void <>m__Finally6() { <>1__state = -1; if (<>s__12 != null) { <>s__12.Dispose(); } } private void <>m__Finally7() { <>1__state = -1; if (<>s__14 != null) { <>s__14.Dispose(); } } private void <>m__Finally8() { <>1__state = -1; if (<>s__16 != null) { <>s__16.Dispose(); } } private void <>m__Finally9() { <>1__state = -1; if (<>s__18 != null) { <>s__18.Dispose(); } } private void <>m__Finally10() { <>1__state = -1; if (<>s__20 != null) { <>s__20.Dispose(); } } private void <>m__Finally11() { <>1__state = -1; if (<>s__22 != null) { <>s__22.Dispose(); } } private void <>m__Finally12() { <>1__state = -1; if (<>s__24 != null) { <>s__24.Dispose(); } } private void <>m__Finally13() { <>1__state = -1; if (<>s__26 != null) { <>s__26.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<(string key, GameObject go)> IEnumerable<(string, GameObject)>.GetEnumerator() { <BuildCrossLevelKeys>d__41 <BuildCrossLevelKeys>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <BuildCrossLevelKeys>d__ = this; } else { <BuildCrossLevelKeys>d__ = new <BuildCrossLevelKeys>d__41(0); } <BuildCrossLevelKeys>d__.source = <>3__source; <BuildCrossLevelKeys>d__.targetLevelPath = <>3__targetLevelPath; return <BuildCrossLevelKeys>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<(string, GameObject)>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <BuildExactPrefabKeys>d__40 : IEnumerable<(string key, GameObject go)>, IEnumerable, IEnumerator<(string key, GameObject go)>, IEnumerator, IDisposable { private int <>1__state; private (string key, GameObject go) <>2__current; private int <>l__initialThreadId; private Level lvl; public Level <>3__lvl; private IEnumerator<(string key, GameObject go)> <>s__1; private (string key, GameObject go) <e>5__2; private IEnumerator<(string key, GameObject go)> <>s__3; private (string key, GameObject go) <e>5__4; private IEnumerator<(string key, GameObject go)> <>s__5; private (string key, GameObject go) <e>5__6; private IEnumerator<(string key, GameObject go)> <>s__7; private (string key, GameObject go) <e>5__8; private IEnumerator<(string key, GameObject go)> <>s__9; private (string key, GameObject go) <e>5__10; private IEnumerator<(string key, GameObject go)> <>s__11; private (string key, GameObject go) <e>5__12; private IEnumerator<(string key, GameObject go)> <>s__13; private (string key, GameObject go) <e>5__14; private IEnumerator<(string key, GameObject go)> <>s__15; private (string key, GameObject go) <e>5__16; private IEnumerator<(string key, GameObject go)> <>s__17; private (string key, GameObject go) <e>5__18; private IEnumerator<(string key, GameObject go)> <>s__19; private (string key, GameObject go) <e>5__20; private IEnumerator<(string key, GameObject go)> <>s__21; private (string key, GameObject go) <e>5__22; private IEnumerator<(string key, GameObject go)> <>s__23; private (string key, GameObject go) <e>5__24; private IEnumerator<(string key, GameObject go)> <>s__25; private (string key, GameObject go) <e>5__26; (string, GameObject) IEnumerator<(string, GameObject)>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <BuildExactPrefabKeys>d__40(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 1: try { } finally { <>m__Finally1(); } break; case -4: case 2: try { } finally { <>m__Finally2(); } break; case -5: case 3: try { } finally { <>m__Finally3(); } break; case -6: case 4: try { } finally { <>m__Finally4(); } break; case -7: case 5: try { } finally { <>m__Finally5(); } break; case -8: case 6: try { } finally { <>m__Finally6(); } break; case -9: case 7: try { } finally { <>m__Finally7(); } break; case -10: case 8: try { } finally { <>m__Finally8(); } break; case -11: case 9: try { } finally { <>m__Finally9(); } break; case -12: case 10: try { } finally { <>m__Finally10(); } break; case -13: case 11: try { } finally { <>m__Finally11(); } break; case -14: case 12: try { } finally { <>m__Finally12(); } break; case -15: case 13: try { } finally { <>m__Finally13(); } break; } <>s__1 = null; <e>5__2 = default((string, GameObject)); <>s__3 = null; <e>5__4 = default((string, GameObject)); <>s__5 = null; <e>5__6 = default((string, GameObject)); <>s__7 = null; <e>5__8 = default((string, GameObject)); <>s__9 = null; <e>5__10 = default((string, GameObject)); <>s__11 = null; <e>5__12 = default((string, GameObject)); <>s__13 = null; <e>5__14 = default((string, GameObject)); <>s__15 = null; <e>5__16 = default((string, GameObject)); <>s__17 = null; <e>5__18 = default((string, GameObject)); <>s__19 = null; <e>5__20 = default((string, GameObject)); <>s__21 = null; <e>5__22 = default((string, GameObject)); <>s__23 = null; <e>5__24 = default((string, GameObject)); <>s__25 = null; <e>5__26 = default((string, GameObject)); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)lvl == (Object)null) { return false; } <>s__1 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.StartRooms).GetEnumerator(); <>1__state = -3; goto IL_0116; case 1: <>1__state = -3; <e>5__2 = default((string, GameObject)); goto IL_0116; case 2: <>1__state = -4; <e>5__4 = default((string, GameObject)); goto IL_0196; case 3: <>1__state = -5; <e>5__6 = default((string, GameObject)); goto IL_0216; case 4: <>1__state = -6; <e>5__8 = default((string, GameObject)); goto IL_0296; case 5: <>1__state = -7; <e>5__10 = default((string, GameObject)); goto IL_0316; case 6: <>1__state = -8; <e>5__12 = default((string, GameObject)); goto IL_0396; case 7: <>1__state = -9; <e>5__14 = default((string, GameObject)); goto IL_0416; case 8: <>1__state = -10; <e>5__16 = default((string, GameObject)); goto IL_0496; case 9: <>1__state = -11; <e>5__18 = default((string, GameObject)); goto IL_0517; case 10: <>1__state = -12; <e>5__20 = default((string, GameObject)); goto IL_0598; case 11: <>1__state = -13; <e>5__22 = default((string, GameObject)); goto IL_0619; case 12: <>1__state = -14; <e>5__24 = default((string, GameObject)); goto IL_069a; case 13: { <>1__state = -15; <e>5__26 = default((string, GameObject)); break; } IL_0496: if (<>s__15.MoveNext()) { <e>5__16 = <>s__15.Current; <>2__current = <e>5__16; <>1__state = 8; return true; } <>m__Finally8(); <>s__15 = null; <>s__17 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesExtraction2).GetEnumerator(); <>1__state = -11; goto IL_0517; IL_0416: if (<>s__13.MoveNext()) { <e>5__14 = <>s__13.Current; <>2__current = <e>5__14; <>1__state = 7; return true; } <>m__Finally7(); <>s__13 = null; <>s__15 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesDeadEnd2).GetEnumerator(); <>1__state = -10; goto IL_0496; IL_0116: if (<>s__1.MoveNext()) { <e>5__2 = <>s__1.Current; <>2__current = <e>5__2; <>1__state = 1; return true; } <>m__Finally1(); <>s__1 = null; <>s__3 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesNormal1).GetEnumerator(); <>1__state = -4; goto IL_0196; IL_0517: if (<>s__17.MoveNext()) { <e>5__18 = <>s__17.Current; <>2__current = <e>5__18; <>1__state = 9; return true; } <>m__Finally9(); <>s__17 = null; <>s__19 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesNormal3).GetEnumerator(); <>1__state = -12; goto IL_0598; IL_0196: if (<>s__3.MoveNext()) { <e>5__4 = <>s__3.Current; <>2__current = <e>5__4; <>1__state = 2; return true; } <>m__Finally2(); <>s__3 = null; <>s__5 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesPassage1).GetEnumerator(); <>1__state = -5; goto IL_0216; IL_0216: if (<>s__5.MoveNext()) { <e>5__6 = <>s__5.Current; <>2__current = <e>5__6; <>1__state = 3; return true; } <>m__Finally3(); <>s__5 = null; <>s__7 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesDeadEnd1).GetEnumerator(); <>1__state = -6; goto IL_0296; IL_0619: if (<>s__21.MoveNext()) { <e>5__22 = <>s__21.Current; <>2__current = <e>5__22; <>1__state = 11; return true; } <>m__Finally11(); <>s__21 = null; <>s__23 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesDeadEnd3).GetEnumerator(); <>1__state = -14; goto IL_069a; IL_0296: if (<>s__7.MoveNext()) { <e>5__8 = <>s__7.Current; <>2__current = <e>5__8; <>1__state = 4; return true; } <>m__Finally4(); <>s__7 = null; <>s__9 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesExtraction1).GetEnumerator(); <>1__state = -7; goto IL_0316; IL_069a: if (<>s__23.MoveNext()) { <e>5__24 = <>s__23.Current; <>2__current = <e>5__24; <>1__state = 12; return true; } <>m__Finally12(); <>s__23 = null; <>s__25 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesExtraction3).GetEnumerator(); <>1__state = -15; break; IL_0316: if (<>s__9.MoveNext()) { <e>5__10 = <>s__9.Current; <>2__current = <e>5__10; <>1__state = 5; return true; } <>m__Finally5(); <>s__9 = null; <>s__11 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesNormal2).GetEnumerator(); <>1__state = -8; goto IL_0396; IL_0598: if (<>s__19.MoveNext()) { <e>5__20 = <>s__19.Current; <>2__current = <e>5__20; <>1__state = 10; return true; } <>m__Finally10(); <>s__19 = null; <>s__21 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesPassage3).GetEnumerator(); <>1__state = -13; goto IL_0619; IL_0396: if (<>s__11.MoveNext()) { <e>5__12 = <>s__11.Current; <>2__current = <e>5__12; <>1__state = 6; return true; } <>m__Finally6(); <>s__11 = null; <>s__13 = <BuildExactPrefabKeys>g__FromList|40_0(lvl.ModulesPassage2).GetEnumerator(); <>1__state = -9; goto IL_0416; } if (<>s__25.MoveNext()) { <e>5__26 = <>s__25.Current; <>2__current = <e>5__26; <>1__state = 13; return true; } <>m__Finally13(); <>s__25 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__1 != null) { <>s__1.Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<>s__3 != null) { <>s__3.Dispose(); } } private void <>m__Finally3() { <>1__state = -1; if (<>s__5 != null) { <>s__5.Dispose(); } } private void <>m__Finally4() { <>1__state = -1; if (<>s__7 != null) { <>s__7.Dispose(); } } private void <>m__Finally5() { <>1__state = -1; if (<>s__9 != null) { <>s__9.Dispose(); } } private void <>m__Finally6() { <>1__state = -1; if (<>s__11 != null) { <>s__11.Dispose(); } } private void <>m__Finally7() { <>1__state = -1; if (<>s__13 != null) { <>s__13.Dispose(); } } private void <>m__Finally8() { <>1__state = -1; if (<>s__15 != null) { <>s__15.Dispose(); } } private void <>m__Finally9() { <>1__state = -1; if (<>s__17 != null) { <>s__17.Dispose(); } } private void <>m__Finally10() { <>1__state = -1; if (<>s__19 != null) { <>s__19.Dispose(); } } private void <>m__Finally11() { <>1__state = -1; if (<>s__21 != null) { <>s__21.Dispose(); } } private void <>m__Finally12() { <>1__state = -1; if (<>s__23 != null) { <>s__23.Dispose(); } } private void <>m__Finally13() { <>1__state = -1; if (<>s__25 != null) { <>s__25.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<(string key, GameObject go)> IEnumerable<(string, GameObject)>.GetEnumerator() { <BuildExactPrefabKeys>d__40 <BuildExactPrefabKeys>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <BuildExactPrefabKeys>d__ = this; } else { <BuildExactPrefabKeys>d__ = new <BuildExactPrefabKeys>d__40(0); } <BuildExactPrefabKeys>d__.lvl = <>3__lvl; return <BuildExactPrefabKeys>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<(string, GameObject)>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <PrewarmRoutine>d__26 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MergedLevels <>4__this; private int <i>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PrewarmRoutine>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <i>5__1 = 0; goto IL_0083; case 2: <>1__state = -1; <i>5__1++; goto IL_0083; case 3: { <>1__state = -1; TryPrewarmAliases(); return false; } IL_0083: if (<i>5__1 < 10) { TryPrewarmAliases(); <>2__current = null; <>1__state = 2; return true; } <>2__current = (object)new WaitForSeconds(1f); <>1__state = 3; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const bool CFG_ENABLED = true; private const bool CFG_STRICT_CONNECTORS_ONLY = true; private const string CFG_WHITELIST = ""; private const string CFG_BLACKLIST = "Lobby Menu, Shop, Lobby, Main Menu, Splash Screen"; private const ValuablesMode CFG_VALUABLES_MODE = ValuablesMode.Global; private ConfigEntry<bool> _cfgSpawnDoors = null; internal static bool MergeAppliedThisRun = false; internal static bool PrefabsRegisteredThisRun = false; internal static readonly HashSet<string> RegisteredThisRun = new HashSet<string>(StringComparer.Ordinal); internal static string LastRegisteredLevelPath = string.Empty; internal static readonly HashSet<string> PrewarmedTargetPaths = new HashSet<string>(StringComparer.Ordinal); internal static MergedLevels Instance { get; private set; } = null; internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal static bool DoorsEnabled() { return (Instance?._cfgSpawnDoors?.Value).GetValueOrDefault(true); } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; _cfgSpawnDoors = ((BaseUnityPlugin)this).Config.Bind<bool>("Generation", "SpawnDoors", false, "If false, door/connector prefabs (SpawnConnectObject) will not be spawned."); HookGenCompat.Install(Logger); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded"); ((MonoBehaviour)this).StartCoroutine(PrewarmRoutine()); } [IteratorStateMachine(typeof(<PrewarmRoutine>d__26))] private IEnumerator PrewarmRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PrewarmRoutine>d__26(0) { <>4__this = this }; } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static bool IsEnabled() { return true; } internal static bool StrictConnectorsOnly() { return true; } internal static bool IsAllowed(Level lvl) { if ((Object)(object)lvl == (Object)null) { return false; } if (LooksLikeNonPlayable(lvl)) { return false; } string text = SafeLower(lvl.NarrativeName); string text2 = SafeLower(lvl.ResourcePath); foreach (string item in SplitTerms("Lobby Menu, Shop, Lobby, Main Menu, Splash Screen")) { if (text.Contains(item) || text2.Contains(item)) { return false; } } List<string> list = SplitTerms(""); if (list.Count == 0) { return true; } foreach (string item2 in list) { if (text.Contains(item2) || text2.Contains(item2)) { return true; } } return false; } internal static bool LooksLikeNonPlayable(Level lvl) { string text = SafeLower(lvl.NarrativeName); string text2 = SafeLower(lvl.ResourcePath); if (text.Contains("lobby menu") || text2.Contains("lobby menu")) { return true; } if (text.Contains("main menu") || text2.Contains("main menu")) { return true; } if (text.Contains("splash screen") || text2.Contains("splash")) { return true; } if (text.Contains("shop") || text2.Contains("shop") || text2.Contains("store")) { return true; } if (text2.Contains("/menu/")) { return true; } return false; } private static string SafeLower(string s) { return (s ?? string.Empty).Trim().ToLowerInvariant(); } private static List<string> SplitTerms(string s) { return (from t in (s ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) select t.Trim().ToLowerInvariant() into t where t.Length > 0 select t).Distinct().ToList(); } internal static Level BuildMergedLevel(Level template, List<Level> sources, ManualLogSource log) { Level val = ScriptableObject.CreateInstance<Level>(); ((Object)val).name = "MergedLevels_Runtime"; Type typeFromHandle = typeof(Level); FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (!IsModulesField(fieldInfo) && !IsValuablesField(fieldInfo)) { try { fieldInfo.SetValue(val, fieldInfo.GetValue(template)); } catch (Exception ex) { log.LogWarning((object)("Field copy failed for " + fieldInfo.Name + ": " + ex.Message)); } } } val.StartRooms = MergePrefabRefs(sources.Select((Level s) => s.StartRooms), ValidateModule); val.ModulesNormal1 = MergePrefabRefs(sources.Select((Level s) => s.ModulesNormal1), ValidateModule); val.ModulesPassage1 = MergePrefabRefs(sources.Select((Level s) => s.ModulesPassage1), ValidateModule); val.ModulesDeadEnd1 = MergePrefabRefs(sources.Select((Level s) => s.ModulesDeadEnd1), ValidateModule); val.ModulesExtraction1 = MergePrefabRefs(sources.Select((Level s) => s.ModulesExtraction1), ValidateModule); val.ModulesNormal2 = MergePrefabRefs(sources.Select((Level s) => s.ModulesNormal2), ValidateModule); val.ModulesPassage2 = MergePrefabRefs(sources.Select((Level s) => s.ModulesPassage2), ValidateModule); val.ModulesDeadEnd2 = MergePrefabRefs(sources.Select((Level s) => s.ModulesDeadEnd2), ValidateModule); val.ModulesExtraction2 = MergePrefabRefs(sources.Select((Level s) => s.ModulesExtraction2), ValidateModule); val.ModulesNormal3 = MergePrefabRefs(sources.Select((Level s) => s.ModulesNormal3), ValidateModule); val.ModulesPassage3 = MergePrefabRefs(sources.Select((Level s) => s.ModulesPassage3), ValidateModule); val.ModulesDeadEnd3 = MergePrefabRefs(sources.Select((Level s) => s.ModulesDeadEnd3), ValidateModule); val.ModulesExtraction3 = MergePrefabRefs(sources.Select((Level s) => s.ModulesExtraction3), ValidateModule); bool flag = true; val.ValuablePresets = new List<LevelValuables>(); foreach (LevelValuables item in from v in sources.SelectMany((Level s) => s.ValuablePresets ?? new List<LevelValuables>()) where (Object)(object)v != (Object)null select v) { val.ValuablePresets.Add(item); } return val; } private static bool IsModulesField(FieldInfo f) { if (f.FieldType == typeof(List<PrefabRef>)) { string name = f.Name; if (name.StartsWith("ModulesNormal") || name.StartsWith("ModulesPassage") || name.StartsWith("ModulesDeadEnd") || name.StartsWith("ModulesExtraction") || name == "StartRooms") { return true; } } return false; } private static bool IsValuablesField(FieldInfo f) { return f.FieldType == typeof(List<LevelValuables>); } private static List<PrefabRef> MergePrefabRefs(IEnumerable<List<PrefabRef>> lists, Func<PrefabRef, bool> validator) { List<PrefabRef> list = new List<PrefabRef>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (List<PrefabRef> list2 in lists) { if (list2 == null) { continue; } foreach (PrefabRef item in list2) { if (item != null && item.IsValid() && (validator == null || validator(item))) { string resourcePath = item.ResourcePath; if (!string.IsNullOrEmpty(resourcePath) && !hashSet.Contains(resourcePath)) { list.Add(item); hashSet.Add(resourcePath); } } } } return list; } private static bool ValidateModule(PrefabRef prefabRef) { if (prefabRef == null || !prefabRef.IsValid()) { return false; } if (!StrictConnectorsOnly()) { return true; } try { GameObject prefab = prefabRef.Prefab; if (!Object.op_Implicit((Object)(object)prefab)) { return false; } LevelPoint[] componentsInChildren = prefab.GetComponentsInChildren<LevelPoint>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } int num = 0; LevelPoint[] array = componentsInChildren; foreach (LevelPoint val in array) { if ((Object)(object)val != (Object)null && val.ModuleConnect) { num++; } } return num >= 1; } catch { return false; } } [IteratorStateMachine(typeof(<BuildExactPrefabKeys>d__40))] internal static IEnumerable<(string key, GameObject go)> BuildExactPrefabKeys(Level lvl) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <BuildExactPrefabKeys>d__40(-2) { <>3__lvl = lvl }; } [IteratorStateMachine(typeof(<BuildCrossLevelKeys>d__41))] internal static IEnumerable<(string key, GameObject go)> BuildCrossLevelKeys(Level source, string targetLevelPath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <BuildCrossLevelKeys>d__41(-2) { <>3__source = source, <>3__targetLevelPath = targetLevelPath }; } internal static void EnsurePrefabsRegisteredWithPhoton(IEnumerable<(string key, GameObject go)> entries, ManualLogSource log) { try { IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool; if (prefabPool == null) { log.LogWarning((object)"PhotonNetwork.PrefabPool is null; cannot register prefabs."); return; } Type type = ((object)prefabPool).GetType(); MethodInfo method = type.GetMethod("RegisterPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(GameObject) }, null); MethodInfo method2 = type.GetMethod("RegisterPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(GameObject) }, null); FieldInfo fieldInfo = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((FieldInfo f) => typeof(Dictionary<string, GameObject>).IsAssignableFrom(f.FieldType)); Dictionary<string, GameObject> dictionary = ((fieldInfo != null) ? ((Dictionary<string, GameObject>)fieldInfo.GetValue(prefabPool)) : null); int num = 0; int num2 = 0; foreach (var (text, val) in entries) { if (!Object.op_Implicit((Object)(object)val)) { num2++; continue; } if (string.IsNullOrEmpty(text)) { num2++; continue; } if (RegisteredThisRun.Contains(text)) { num2++; continue; } if ((Object)(object)Resources.Load<GameObject>(text) != (Object)null) { RegisteredThisRun.Add(text); num2++; continue; } bool flag = dictionary?.ContainsKey(text) ?? false; try { if (!flag && method != null) { method.Invoke(prefabPool, new object[2] { text, val }); RegisteredThisRun.Add(text); num++; } else if (!flag && method2 != null) { method2.Invoke(prefabPool, new object[1] { val }); RegisteredThisRun.Add(text); num++; } else if (!flag && dictionary != null) { dictionary[text] = val; RegisteredThisRun.Add(text); num++; } else { RegisteredThisRun.Add(text); num2++; } } catch (Exception ex) { log.LogWarning((object)("PrefabPool register failed for '" + text + "': " + ex.Message)); num2++; } } PrefabsRegisteredThisRun = true; log.LogInfo((object)$"Photon prefab preflight: registered {num} keys, skipped {num2}."); } catch (Exception arg) { Logger.LogWarning((object)$"EnsurePrefabsRegisteredWithPhoton failed: {arg}"); } } internal static void TryPrewarmAliases() { RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null || instance.levels == null || instance.levels.Count == 0) { return; } List<Level> list = instance.levels.Where(IsAllowed).ToList(); if (list.Count == 0) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (string item2 in from l in list select (l?.ResourcePath ?? string.Empty).Trim() into p where !string.IsNullOrEmpty(p) select p) { hashSet.Add(item2); string item = item2.ToLowerInvariant(); if (!hashSet.Contains(item)) { hashSet.Add(item); } } List<string> list2 = hashSet.Where((string p) => !PrewarmedTargetPaths.Contains(p)).ToList(); if (list2.Count == 0) { return; } List<(string, GameObject)> list3 = new List<(string, GameObject)>(4096); foreach (Level item3 in list) { foreach (var item4 in BuildExactPrefabKeys(item3)) { list3.Add(item4); } } foreach (Level item5 in list) { foreach (string item6 in list2) { foreach (var item7 in BuildCrossLevelKeys(item5, item6)) { list3.Add(item7); } } } if (list3.Count > 0) { EnsurePrefabsRegisteredWithPhoton(list3, Logger); Logger.LogInfo((object)$"MergedLevels: alias prewarm — new targets: {list2.Count}, entries considered: {list3.Count}."); } foreach (string item8 in list2) { PrewarmedTargetPaths.Add(item8); } } [IteratorStateMachine(typeof(<<BuildExactPrefabKeys>g__FromList|40_0>d))] [CompilerGenerated] internal static IEnumerable<(string key, GameObject go)> <BuildExactPrefabKeys>g__FromList|40_0(IEnumerable<PrefabRef> list) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <<BuildExactPrefabKeys>g__FromList|40_0>d(-2) { <>3__list = list }; } } [HarmonyPatch(typeof(LevelGenerator))] public static class LevelGenerator_MergeAndRegister_Patch { [HarmonyPrefix] [HarmonyPatch("ModuleGeneration")] private static void Prefix(LevelGenerator __instance) { try { ManualLogSource logger = MergedLevels.Logger; Level val = __instance.Level; if ((Object)(object)val == (Object)null) { return; } MergedLevels.TryPrewarmAliases(); string text = (val.ResourcePath ?? string.Empty).Trim(); if (!string.Equals(text, MergedLevels.LastRegisteredLevelPath, StringComparison.Ordinal)) { MergedLevels.MergeAppliedThisRun = false; MergedLevels.PrefabsRegisteredThisRun = false; MergedLevels.RegisteredThisRun.Clear(); MergedLevels.LastRegisteredLevelPath = text; logger.LogInfo((object)("MergedLevels: level path changed -> '" + text + "'. Resetting guards.")); } if (SemiFunc.IsMasterClientOrSingleplayer() && MergedLevels.IsEnabled() && !MergedLevels.MergeAppliedThisRun) { RunManager instance = RunManager.instance; if ((Object)(object)instance != (Object)null && instance.levels != null && instance.levels.Count > 0) { List<Level> list = instance.levels.Where((Level l) => (Object)(object)l != (Object)null).Where(MergedLevels.IsAllowed).Distinct() .ToList(); if (!MergedLevels.IsAllowed(val)) { logger.LogWarning((object)("Current level '" + val?.NarrativeName + "' looks like a hub/non-playable. Skipping merge.")); } else if (list.Count > 0) { if (!list.Contains(val)) { list.Insert(0, val); } Level val2 = MergedLevels.BuildMergedLevel(val, list, logger); if (HasAny(val2.StartRooms) && (HasAny(val2.ModulesNormal1) || HasAny(val2.ModulesPassage1) || HasAny(val2.ModulesDeadEnd1) || HasAny(val2.ModulesExtraction1))) { __instance.Level = val2; val = val2; MergedLevels.MergeAppliedThisRun = true; logger.LogInfo((object)$"MergedLevels: applied mixed level. Sources merged: {list.Count}"); } else { logger.LogWarning((object)"MergedLevels: merged level had empty critical pools. Skipping swap."); } } } } if (!MergedLevels.PrefabsRegisteredThisRun && !MergedLevels.LooksLikeNonPlayable(val)) { IEnumerable<(string, GameObject)> entries = MergedLevels.BuildExactPrefabKeys(val); MergedLevels.EnsurePrefabsRegisteredWithPhoton(entries, logger); } } catch (Exception arg) { MergedLevels.Logger.LogWarning((object)$"Merge/Register Prefix failed: {arg}"); } } [HarmonyPostfix] [HarmonyPatch("GenerateDone")] private static void Postfix() { MergedLevels.MergeAppliedThisRun = false; MergedLevels.PrefabsRegisteredThisRun = false; MergedLevels.RegisteredThisRun.Clear(); } private static bool HasAny(List<PrefabRef> list) { return list != null && list.Count > 0; } } [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGenerator_SpawnConnectObject_Patch { [HarmonyPrefix] [HarmonyPatch("SpawnConnectObject")] private static bool Prefix() { return MergedLevels.DoorsEnabled(); } } internal static class HookGenCompat { private static bool _installed; private static readonly object _lock = new object(); public static void Install(ManualLogSource log) { lock (_lock) { if (_installed) { return; } _installed = true; try { AppDomain.CurrentDomain.AssemblyResolve += OnResolve; string text = string.Join(", ", (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetName().Name into n where n != null && (n.StartsWith("MMHOOK_") || n.StartsWith("MonoMod")) select n).Distinct()); if (!string.IsNullOrEmpty(text)) { log.LogInfo((object)("HookGenCompat: detected loaded hook assemblies: " + text)); } } catch (Exception arg) { log.LogWarning((object)$"HookGenCompat: failed to install resolver: {arg}"); } } } private static Assembly? OnResolve(object? sender, ResolveEventArgs args) { string text = new AssemblyName(args.Name).Name ?? string.Empty; if (!text.StartsWith("MMHOOK_") && !text.StartsWith("MonoMod")) { return null; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string name = assembly.GetName().Name; if (string.Equals(name, text, StringComparison.Ordinal)) { return assembly; } } try { string[] array = new string[4] { Paths.BepInExRootPath, Path.Combine(Paths.BepInExRootPath, "plugins"), Path.Combine(Paths.BepInExRootPath, "patchers"), Path.Combine(Paths.BepInExRootPath, "core") }; string[] array2 = array; foreach (string path in array2) { string text2 = Path.Combine(path, text + ".dll"); if (File.Exists(text2)) { return Assembly.LoadFrom(text2); } } } catch { } return null; } } }