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 LethalLevelLoader v1.7.5
LethalLevelLoader.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dawn; using Dawn.Internal; using Dawn.Utils; using DunGen; using DunGen.Adapters; using DunGen.Graph; using GameNetcodeStuff; using HarmonyLib; using LethalLevelLoader; using LethalLevelLoader.AssetBundles; using LethalLevelLoader.Compatibility; using LethalLevelLoader.NetcodePatcher; using LethalLevelLoader.Patcher; using LethalLevelLoader.Tools; using LethalLib.Modules; using LethalModDataLib.Base; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("LethalLib")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalLevelLoader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A Custom API to support the manual and dynamic integration of custom levels and dungeons in Lethal Company.")] [assembly: AssemblyFileVersion("1.7.5.0")] [assembly: AssemblyInformationalVersion("1.7.5+91ce948550bf16502208ab52512cca78b892665c")] [assembly: AssemblyProduct("LethalLevelLoader")] [assembly: AssemblyTitle("LethalLevelLoader")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/IAmBatby/LethalLevelLoader/")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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; } } } public enum ContentType { Vanilla, Custom, Any, External } internal static class HookHelper { public sealed class DisposableHookCollection { private readonly List<ILHook> ilHooks = new List<ILHook>(); private readonly List<Hook> hooks = new List<Hook>(); public void Clear() { foreach (Hook hook in hooks) { hook.Dispose(); } hooks.Clear(); foreach (ILHook ilHook in ilHooks) { ilHook.Dispose(); } ilHooks.Clear(); } public void ILHook<T>(string methodName, Manipulator to, Type[] parameters = null) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown ilHooks.Add(new ILHook((MethodBase)EzGetMethod<T>(methodName, parameters), to)); } public void Hook<T>(string methodName, Delegate to, Type[] parameters = null) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown hooks.Add(new Hook((MethodBase)EzGetMethod<T>(methodName, parameters), to)); } } public static MethodInfo MethodOf(Delegate method) { return method.Method; } public static MethodInfo EzGetMethod(Type type, string name, Type[] parameters = null) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; if (parameters == null) { return type.GetMethod(name, bindingAttr); } return type.GetMethod(name, bindingAttr, null, parameters, null); } public static MethodInfo EzGetMethod<T>(string name, Type[] parameters = null) { return EzGetMethod(typeof(T), name, parameters); } } public static class NetworkScenePatcher { [CompilerGenerated] private static class <>O { public static Action<Action<NetworkSceneManager>, NetworkSceneManager> <0>__GenerateScenesInBuild_Hook; public static Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string> <1>__SceneNameFromHash_Hook; public static Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool> <2>__ValidateSceneBeforeLoading_Hook; public static Manipulator <3>__ReplaceBuildIndexByScenePath; public static Manipulator <4>__ReplaceScenePathByBuildIndex; public static Func<int, string> <5>__GetScenePathByBuildIndex; public static Func<string, int> <6>__GetBuildIndexByScenePath; } private static List<string> scenePaths = new List<string>(); internal static Dictionary<string, int> scenePathToBuildIndex = new Dictionary<string, int>(); internal static Dictionary<int, string> buildIndexToScenePath = new Dictionary<int, string>(); private static Dictionary<uint, string> sceneHashToScenePath = new Dictionary<uint, string>(); private static Dictionary<int, string> levelSceneDict = new Dictionary<int, string>(); private static Dictionary<int, string> fullSceneIndexToPathDict = new Dictionary<int, string>(); private static Dictionary<string, int> fullScenePathToIndexDict = new Dictionary<string, int>(); private static HookHelper.DisposableHookCollection hooks = new HookHelper.DisposableHookCollection(); internal static bool patched { get; private set; } public static Dictionary<int, string> GetLevelSceneDict() { return new Dictionary<int, string>(levelSceneDict); } public static void AddScenePath(string scenePath) { if (!scenePaths.Contains(scenePath)) { DebugHelper.Log("Adding ScenePath: " + scenePath, DebugType.Developer); scenePaths.Add(scenePath); } } public static bool TryGetSceneIndex(int levelSceneIndex, string levelScenePath, out int sceneIndex) { sceneIndex = -1; int[] array = levelSceneDict.Keys.ToArray(); if (levelSceneDict.TryGetValue(array[levelSceneIndex], out var value)) { if (value == levelScenePath) { if (fullScenePathToIndexDict.TryGetValue(levelScenePath, out var value2)) { sceneIndex = value2; } else { DebugHelper.LogError("Failed At Full Scene Path", DebugType.User); } } else { DebugHelper.LogError("Failed At Path. Path 1: " + levelScenePath + ", Path 2: " + value, DebugType.User); } } else { DebugHelper.LogError("Failed At Level Scene Dict", DebugType.User); } return sceneIndex != -1; } internal static void Patch() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown if (!patched) { patched = true; hooks.Hook<NetworkSceneManager>("GenerateScenesInBuild", new Action<Action<NetworkSceneManager>, NetworkSceneManager>(GenerateScenesInBuild_Hook)); hooks.Hook<NetworkSceneManager>("SceneNameFromHash", new Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string>(SceneNameFromHash_Hook)); hooks.Hook<NetworkSceneManager>("ValidateSceneBeforeLoading", new Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool>(ValidateSceneBeforeLoading_Hook), new Type[3] { typeof(int), typeof(string), typeof(LoadSceneMode) }); HookHelper.DisposableHookCollection disposableHookCollection = hooks; object obj = <>O.<3>__ReplaceBuildIndexByScenePath; if (obj == null) { Manipulator val = ReplaceBuildIndexByScenePath; <>O.<3>__ReplaceBuildIndexByScenePath = val; obj = (object)val; } disposableHookCollection.ILHook<NetworkSceneManager>("SceneHashFromNameOrPath", (Manipulator)obj); HookHelper.DisposableHookCollection disposableHookCollection2 = hooks; object obj2 = <>O.<3>__ReplaceBuildIndexByScenePath; if (obj2 == null) { Manipulator val2 = ReplaceBuildIndexByScenePath; <>O.<3>__ReplaceBuildIndexByScenePath = val2; obj2 = (object)val2; } disposableHookCollection2.ILHook<NetworkSceneManager>("ValidateSceneEvent", (Manipulator)obj2); HookHelper.DisposableHookCollection disposableHookCollection3 = hooks; object obj3 = <>O.<4>__ReplaceScenePathByBuildIndex; if (obj3 == null) { Manipulator val3 = ReplaceScenePathByBuildIndex; <>O.<4>__ReplaceScenePathByBuildIndex = val3; obj3 = (object)val3; } disposableHookCollection3.ILHook<NetworkSceneManager>("ScenePathFromHash", (Manipulator)obj3); } } internal static void Unpatch() { if (patched) { patched = false; hooks.Clear(); } } private static void ReplaceScenePathByBuildIndex(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodInfo methodInfo = HookHelper.MethodOf(new Func<int, string>(GetScenePathByBuildIndex)); while (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetScenePathByBuildIndex") })) { val.Remove(); val.Emit(OpCodes.Call, (MethodBase)methodInfo); } } private static void ReplaceBuildIndexByScenePath(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodInfo methodInfo = HookHelper.MethodOf(new Func<string, int>(GetBuildIndexByScenePath)); while (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetBuildIndexByScenePath") })) { val.Remove(); val.Emit(OpCodes.Call, (MethodBase)methodInfo); } } private static string GetScenePathByBuildIndex(int buildIndex) { if (buildIndexToScenePath.TryGetValue(buildIndex, out var value)) { return value; } return SceneUtility.GetScenePathByBuildIndex(buildIndex); } private static int GetBuildIndexByScenePath(string scenePath) { int num = SceneUtility.GetBuildIndexByScenePath(scenePath); if (num == -1 && scenePathToBuildIndex.TryGetValue(scenePath, out var value)) { num = value; } return num; } private static void GenerateScenesInBuild_Hook(Action<NetworkSceneManager> orig, NetworkSceneManager self) { scenePathToBuildIndex.Clear(); buildIndexToScenePath.Clear(); sceneHashToScenePath.Clear(); fullScenePathToIndexDict.Clear(); fullSceneIndexToPathDict.Clear(); levelSceneDict.Clear(); orig(self); for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++) { string scenePathByBuildIndex = SceneUtility.GetScenePathByBuildIndex(i); fullSceneIndexToPathDict.Add(i, scenePathByBuildIndex); fullScenePathToIndexDict.Add(scenePathByBuildIndex, i); if (scenePathByBuildIndex.Contains("Level")) { levelSceneDict.Add(i, scenePathByBuildIndex); } } int sceneCountInBuildSettings = SceneManager.sceneCountInBuildSettings; for (int j = 0; j < scenePaths.Count; j++) { int num = sceneCountInBuildSettings + j; string text = scenePaths[j]; uint num2 = XXHash.Hash32(text); self.HashToBuildIndex.Add(num2, num); self.BuildIndexToHash.Add(num, num2); scenePathToBuildIndex.Add(text, num); buildIndexToScenePath.Add(num, text); sceneHashToScenePath.Add(num2, text); fullSceneIndexToPathDict.Add(num, text); fullScenePathToIndexDict.Add(text, num); levelSceneDict.Add(num, text); DebugHelper.Log("Added modded scene path: " + text, DebugType.Developer); } } private static string SceneNameFromHash_Hook(Func<NetworkSceneManager, uint, string> orig, NetworkSceneManager self, uint sceneHash) { if (sceneHash == 0) { return "No Scene"; } if (sceneHashToScenePath.TryGetValue(sceneHash, out var value)) { return value; } return orig(self, sceneHash); } private static bool ValidateSceneBeforeLoading_Hook(Func<NetworkSceneManager, int, string, LoadSceneMode, bool> orig, NetworkSceneManager self, int sceneIndex, string sceneName, LoadSceneMode loadSceneMode) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) bool flag = orig(self, sceneIndex, sceneName, loadSceneMode); return true; } } namespace LethalLevelLoader { public static class LethalBundleManager { public enum ModProcessingStatus { Inactive, Loading, Complete } private static readonly Dictionary<AssetBundleGroup, List<ExtendedMod>> obtainedExtendedModsDict = new Dictionary<AssetBundleGroup, List<ExtendedMod>>(); private static readonly List<ExtendedMod> obtainedExtendedModsList = new List<ExtendedMod>(); internal static Dictionary<string, List<Action<ExtendedMod>>> onExtendedModLoadedRequestDict = new Dictionary<string, List<Action<ExtendedMod>>>(); public static ModProcessingStatus CurrentStatus { get; internal set; } = ModProcessingStatus.Inactive; public static ExtendedEvent OnFinishedProcessing { get; private set; } = new ExtendedEvent(); public static bool HasFinalisedFoundContent { get; internal set; } internal static void Start() { DebugHelper.Log("LethalBundleManger: Starting!", DebugType.User); PatchedContent.VanillaMod = ExtendedMod.Create("LethalCompany", "Zeekerss"); ReadKnownSceneBundles(); TryLoadLethalBundles(); } private static void ReadKnownSceneBundles() { if (!File.Exists(LethalLevelLoader.AssetBundles.AssetBundleLoader.KnownSceneBundlesPath)) { return; } string[] array = File.ReadAllLines(LethalLevelLoader.AssetBundles.AssetBundleLoader.KnownSceneBundlesPath); if (array.Length < 1 || !int.TryParse(array[0], out var result) || result != LethalBundleManifest.ManifestVersion) { DebugHelper.LogWarning("Invalid or different manifest version found, it will be remade.'", DebugType.User); return; } for (int i = 1; i < array.Length; i++) { LethalBundleManifest value = new LethalBundleManifest(array[i]); LethalLevelLoader.AssetBundles.AssetBundleLoader.knownSceneBundles.TryAdd(value.fileName, value); } } private static void WriteKnownSceneBundles() { List<string> list = new List<string>(1) { $"{LethalBundleManifest.ManifestVersion}" }; foreach (LethalBundleManifest value in LethalLevelLoader.AssetBundles.AssetBundleLoader.knownSceneBundles.Values) { list.Add($"{value}"); } File.WriteAllLines(LethalLevelLoader.AssetBundles.AssetBundleLoader.KnownSceneBundlesPath, list, Encoding.UTF8); LethalLevelLoader.AssetBundles.AssetBundleLoader.knownSceneBundles = null; } private static bool TryLoadLethalBundles() { DebugHelper.Log("LethalBundleManger: Now Loading Bundles!", DebugType.User); if (LethalLevelLoader.AssetBundles.AssetBundleLoader.LoadAllBundlesRequest(null, null, ".lethalbundle", OnAssetBundleGroupCreated)) { CurrentStatus = ModProcessingStatus.Loading; LethalLevelLoader.AssetBundles.AssetBundleLoader.OnBundlesFinishedProcessing.AddListener(OnAssetBundleLoadRequestFinished); return true; } return false; } private static void OnAssetBundleGroupCreated(AssetBundleGroup newGroup) { DebugHelper.Log("LethalBundleManger Recieved Group: " + newGroup.GroupName, DebugType.User); FindContentInAssetBundleGroup(newGroup); } private static void OnAssetBundleLoadRequestFinished() { DebugHelper.Log("LethalBundleManger Finished Requested Load", DebugType.User); LethalLevelLoader.AssetBundles.AssetBundleLoader.OnBundlesFinishedProcessing.RemoveListener(OnAssetBundleLoadRequestFinished); FinialiseFoundContent(); } private static void FindContentInAssetBundleGroup(AssetBundleGroup group) { List<ExtendedMod> list = group.LoadAllAssets<ExtendedMod>(); if (list.Count > 0) { foreach (ExtendedMod item in list) { RegisterExtendedMod(item, group); } return; } foreach (ExtendedContent item2 in group.LoadAllAssets<ExtendedContent>()) { RegisterNewExtendedContent(item2, group); } } internal static void RegisterExtendedMod(ExtendedMod extendedMod, AssetBundleGroup source) { DebugHelper.Log("Found ExtendedMod: " + ((Object)extendedMod).name, DebugType.User); extendedMod.ModNameAliases.Add(extendedMod.ModName); ExtendedMod extendedMod2 = null; foreach (ExtendedMod obtainedExtendedMods in obtainedExtendedModsList) { if (extendedMod.ModMergeSetting == ModMergeSetting.MatchingModName && obtainedExtendedMods.ModMergeSetting == ModMergeSetting.MatchingModName) { if (obtainedExtendedMods.ModName == extendedMod.ModName) { extendedMod2 = obtainedExtendedMods; } } else if (extendedMod.ModMergeSetting == ModMergeSetting.MatchingAuthorName && obtainedExtendedMods.ModMergeSetting == ModMergeSetting.MatchingAuthorName && obtainedExtendedMods.AuthorName == extendedMod.AuthorName) { extendedMod2 = obtainedExtendedMods; } } if ((Object)(object)extendedMod2 != (Object)null) { if (!extendedMod2.ModName.Contains(extendedMod2.AuthorName)) { DebugHelper.Log("Renaming ExtendedMod: " + extendedMod2.ModName + " To: " + extendedMod2.AuthorName + "sMod Due To Upcoming ExtendedMod Merge!", DebugType.Developer); extendedMod2.ModNameAliases.Add(extendedMod.ModName); extendedMod2.ModName = extendedMod2.AuthorName + "sMod"; } DebugHelper.Log("Merging ExtendedMod: " + extendedMod.ModName + " (" + extendedMod.AuthorName + ") With Already Obtained ExtendedMod: " + extendedMod2.ModName + " (" + extendedMod2.AuthorName + ")", DebugType.Developer); { foreach (ExtendedContent extendedContent in extendedMod.ExtendedContents) { try { extendedMod2.RegisterExtendedContent(extendedContent); } catch (Exception exception) { DebugHelper.LogError(exception, DebugType.User); } } return; } } obtainedExtendedModsList.Add(extendedMod); if (source != null) { if (!obtainedExtendedModsDict.TryGetValue(source, out var value)) { obtainedExtendedModsDict.Add(source, new List<ExtendedMod>(1) { extendedMod }); } else if (!value.Contains(extendedMod)) { value.Add(extendedMod); } } List<ExtendedContent> extendedContents = extendedMod.ExtendedContents; extendedMod.UnregisterAllExtendedContent(); foreach (ExtendedContent item in extendedContents) { try { extendedMod.RegisterExtendedContent(item); } catch (Exception exception2) { DebugHelper.LogError(exception2, DebugType.User); } } } internal static void RegisterNewExtendedContent(ExtendedContent extendedContent, AssetBundleGroup source) { if ((Object)(object)extendedContent == (Object)null) { DebugHelper.LogError("Failed to register new ExtendedContent as it was null!", DebugType.User); return; } string contentSourceName = ((source == null) ? ((Object)extendedContent).name : source.GroupName); ExtendedMod extendedMod = null; if (extendedContent is ExtendedLevel extendedLevel) { if (string.IsNullOrEmpty(extendedLevel.contentSourceName)) { extendedLevel.contentSourceName = contentSourceName; } extendedMod = GetOrCreateExtendedMod(source, extendedLevel.contentSourceName); } else if (extendedContent is ExtendedDungeonFlow extendedDungeonFlow) { if (string.IsNullOrEmpty(extendedDungeonFlow.contentSourceName)) { extendedDungeonFlow.contentSourceName = contentSourceName; } extendedMod = GetOrCreateExtendedMod(source, extendedDungeonFlow.contentSourceName); } else if (extendedContent is ExtendedItem extendedItem) { extendedMod = GetOrCreateExtendedMod(source, extendedItem.Item.itemName.RemoveWhitespace()); } else if (extendedContent is ExtendedEnemyType extendedEnemyType) { extendedMod = GetOrCreateExtendedMod(source, extendedEnemyType.EnemyType.enemyName.RemoveWhitespace()); } else if (extendedContent is ExtendedBuyableVehicle extendedBuyableVehicle) { extendedMod = GetOrCreateExtendedMod(source, ((Object)extendedBuyableVehicle).name.RemoveWhitespace()); } else if (extendedContent is ExtendedUnlockableItem extendedUnlockableItem) { extendedMod = GetOrCreateExtendedMod(source, ((Object)extendedUnlockableItem).name.RemoveWhitespace()); } else if (extendedContent is ExtendedFootstepSurface extendedFootstepSurface) { extendedMod = GetOrCreateExtendedMod(source, ((Object)extendedFootstepSurface).name.RemoveWhitespace()); } if (!((Object)(object)extendedMod != (Object)null)) { return; } try { extendedMod.RegisterExtendedContent(extendedContent); } catch (Exception exception) { DebugHelper.LogError(exception, DebugType.User); } } internal static ExtendedMod GetOrCreateExtendedMod(AssetBundleGroup source, string contentSourceName) { if (source == null) { DebugHelper.Log("Creating New ExtendedMod: " + contentSourceName, DebugType.Developer); ExtendedMod extendedMod = ExtendedMod.Create(contentSourceName); obtainedExtendedModsList.Add(extendedMod); return extendedMod; } if (obtainedExtendedModsDict.TryGetValue(source, out var value)) { return value[0]; } DebugHelper.Log("Creating New ExtendedMod: " + contentSourceName, DebugType.Developer); ExtendedMod extendedMod2 = ExtendedMod.Create(contentSourceName); obtainedExtendedModsList.Add(extendedMod2); if (!obtainedExtendedModsDict.TryGetValue(source, out var value2)) { obtainedExtendedModsDict.Add(source, new List<ExtendedMod>(1) { extendedMod2 }); } else if (!value2.Contains(extendedMod2)) { value2.Add(extendedMod2); } return extendedMod2; } internal static void FinialiseFoundContent() { foreach (ExtendedMod obtainedExtendedMods in obtainedExtendedModsList) { PatchedContent.ExtendedMods.Add(obtainedExtendedMods); DebugHelper.DebugExtendedMod(obtainedExtendedMods); } PatchedContent.ExtendedMods.Sort(default(ExtendedMod.ExtendedModComparer)); foreach (ExtendedMod extendedMod in PatchedContent.ExtendedMods) { extendedMod.SortRegisteredContent(); } foreach (KeyValuePair<string, List<Action<ExtendedMod>>> item in onExtendedModLoadedRequestDict) { foreach (ExtendedMod extendedMod2 in PatchedContent.ExtendedMods) { if (!extendedMod2.ModNameAliases.Contains(item.Key) && !(extendedMod2.AuthorName == item.Key)) { continue; } foreach (Action<ExtendedMod> item2 in item.Value) { item2(extendedMod2); } } } WriteKnownSceneBundles(); NetworkRegisterCustomScenes(); LethalLevelLoader.AssetBundles.AssetBundleLoader.ClearCache(); DebugHelper.Log("Custom Content Processed. Unlocking Main Menu.", DebugType.User); HasFinalisedFoundContent = true; CurrentStatus = ModProcessingStatus.Complete; OnFinishedProcessing.Invoke(); } internal static void NetworkRegisterCustomScenes() { List<string> list = new List<string>(); List<string> list2 = new List<string>(); for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++) { list.Add(AssetBundleUtilities.GetSceneName(SceneUtility.GetScenePathByBuildIndex(i))); } foreach (AssetBundleGroup assetBundleGroup in LethalLevelLoader.AssetBundles.AssetBundleLoader.Instance.AssetBundleGroups) { foreach (LethalLevelLoader.AssetBundles.AssetBundleInfo assetBundleInfo in assetBundleGroup.GetAssetBundleInfos()) { foreach (string sceneName in assetBundleInfo.GetSceneNames()) { if (!list2.Contains(sceneName)) { list2.Add(sceneName); } } } } foreach (string item in list2) { if (!list.Contains(item)) { NetworkScenePatcher.AddScenePath(item); if (!PatchedContent.AllLevelSceneNames.Contains(item)) { PatchedContent.AllLevelSceneNames.Add(item); } } } foreach (string allLevelSceneName in PatchedContent.AllLevelSceneNames) { DebugHelper.Log("Loaded SceneName: " + allLevelSceneName, DebugType.Developer); } } } [CreateAssetMenu(fileName = "ExtendedBuyableVehicle", menuName = "Lethal Level Loader/Extended Content/ExtendedBuyableVehicle", order = 21)] public class ExtendedBuyableVehicle : ExtendedContent { [field: SerializeField] public BuyableVehicle BuyableVehicle { get; set; } [field: SerializeField] public string TerminalKeywordName { get; set; } = string.Empty; public int VehicleID { get; set; } public TerminalNode VehicleBuyNode { get; set; } public TerminalNode VehicleBuyConfirmNode { get; set; } public TerminalNode VehicleInfoNode { get; set; } internal static ExtendedBuyableVehicle Create(BuyableVehicle newBuyableVehicle) { ExtendedBuyableVehicle extendedBuyableVehicle = ScriptableObject.CreateInstance<ExtendedBuyableVehicle>(); ((Object)extendedBuyableVehicle).name = ((Object)newBuyableVehicle.vehiclePrefab).name; extendedBuyableVehicle.BuyableVehicle = newBuyableVehicle; return extendedBuyableVehicle; } public void Initialize() { ContentRestorer.RestoreAudioAssetReferencesInParent(BuyableVehicle.vehiclePrefab); ContentRestorer.RestoreAudioAssetReferencesInParent(BuyableVehicle.secondaryPrefab); } internal override (bool result, string log) TryValidateContent() { if (BuyableVehicle == null) { return (false, "BuyableVehicle Was Null Or Empty"); } if ((Object)(object)BuyableVehicle.vehiclePrefab == (Object)null) { return (false, "Vehicle Prefab Was Null Or Empty"); } if ((Object)(object)BuyableVehicle.secondaryPrefab == (Object)null) { return (false, "Vehicle Secondary Prefab Was Null Or Empty"); } NetworkObject val = default(NetworkObject); if (!BuyableVehicle.vehiclePrefab.TryGetComponent<NetworkObject>(ref val)) { return (false, "Vehicle Prefab Is Missing NetworkObject Component"); } if (!BuyableVehicle.secondaryPrefab.TryGetComponent<NetworkObject>(ref val)) { return (false, "Vehicle Secondary Prefab Is Missing NetworkObject Component"); } return base.TryValidateContent(); } } public class ExtendedContent : ScriptableObject { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct ExtendedContentComparer : IComparer<ExtendedContent> { public readonly int Compare(ExtendedContent a, ExtendedContent b) { return ((Object)a).name.AsSpan().CompareTo(((Object)b).name.AsSpan(), StringComparison.OrdinalIgnoreCase); } } public ExtendedMod ExtendedMod { get; internal set; } public ContentType ContentType { get; internal set; } [field: SerializeField] public List<ContentTag> ContentTags { get; internal set; } = new List<ContentTag>(); public string ModName => ExtendedMod.ModName; public string AuthorName => ExtendedMod.AuthorName; public string UniqueIdentificationName => AuthorName.ToLowerInvariant() + "." + ModName.ToLowerInvariant() + "." + ((Object)this).name.ToLowerInvariant(); [Obsolete] public List<string> ContentTagStrings { get; internal set; } = new List<string>(); internal virtual void TryCreateMatchingProperties() { } internal virtual (bool result, string log) TryValidateContent() { int num = ContentTags.RemoveAll((ContentTag tag) => (Object)(object)tag == (Object)null || string.IsNullOrEmpty(tag.contentTagName)); if (num > 0) { DebugHelper.LogWarning($"Removed '{num}' missing or empty tags in ExtendedContent: {((Object)this).name}", DebugType.User); } return (true, string.Empty); } internal virtual void ConvertObsoleteValues() { } public bool TryGetTag(string tag) { foreach (ContentTag contentTag in ContentTags) { if (contentTag.contentTagName == tag) { return true; } } return false; } public bool TryGetTag(string tag, out ContentTag returnTag) { returnTag = null; foreach (ContentTag contentTag in ContentTags) { if (contentTag.contentTagName == tag) { returnTag = contentTag; return true; } } return false; } public bool TryAddTag(string tag) { if (!TryGetTag(tag)) { ContentTags.Add(ContentTag.Create(tag)); return true; } return false; } } [Serializable] public class StringWithRarity { [SerializeField] private string _name; [SerializeField] [Range(0f, 300f)] private int _rarity; [HideInInspector] public string Name { get { return _name; } set { _name = value; } } [HideInInspector] public int Rarity { get { return _rarity; } set { _rarity = value; } } public StringWithRarity(string newName, int newRarity) { _name = newName; _rarity = newRarity; base..ctor(); } } [Serializable] public class Vector2WithRarity { [SerializeField] private Vector2 _minMax = new Vector2(newMin, newMax); [SerializeField] private int _rarity; [HideInInspector] public float Min { get { return _minMax.x; } set { _minMax.x = value; } } [HideInInspector] public float Max { get { return _minMax.y; } set { _minMax.y = value; } } [HideInInspector] public int Rarity { get { return _rarity; } set { _rarity = value; } } public Vector2WithRarity(float newMin, float newMax, int newRarity) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) _rarity = newRarity; base..ctor(); } public Vector2WithRarity(Vector2 vector2, int newRarity) : this(vector2.x, vector2.y, newRarity) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) } [Serializable] public struct ClipWithRarity { [SerializeField] private AnimationClip _clip; [SerializeField] [Range(0f, 300f)] private int _rarity; [HideInInspector] public AnimationClip Clip { readonly get { return _clip; } set { _clip = value; } } [HideInInspector] public int Rarity { readonly get { return _rarity; } set { _rarity = value; } } public ClipWithRarity(AnimationClip clip, int rarity) { _clip = clip; _rarity = rarity; } } [CreateAssetMenu(fileName = "ExtendedDungeonFlow", menuName = "Lethal Level Loader/Extended Content/ExtendedDungeonFlow", order = 21)] public class ExtendedDungeonFlow : ExtendedContent { [Space(25f)] [Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")] [Obsolete] public bool generateAutomaticConfigurationOptions = true; [Obsolete] public bool enableDynamicDungeonSizeRestriction; [Obsolete] public float dungeonSizeMin = 1f; [Obsolete] public float dungeonSizeMax = 1f; [Obsolete] [Range(0f, 1f)] public float dungeonSizeLerpPercentage = 1f; [Obsolete] public AudioClip dungeonFirstTimeAudio; [Obsolete] public DungeonFlow dungeonFlow; [Obsolete] public string dungeonDisplayName = string.Empty; [Obsolete] public string contentSourceName = string.Empty; [Obsolete] public List<StringWithRarity> dynamicLevelTagsList = new List<StringWithRarity>(); [Obsolete] public List<Vector2WithRarity> dynamicRoutePricesList = new List<Vector2WithRarity>(); [Obsolete] public List<StringWithRarity> dynamicCurrentWeatherList = new List<StringWithRarity>(); [Obsolete] public List<StringWithRarity> manualPlanetNameReferenceList = new List<StringWithRarity>(); [Obsolete] public List<StringWithRarity> manualContentSourceNameReferenceList = new List<StringWithRarity>(); [Obsolete] [Range(0.1f, 10000f)] public float OverrideCameraMaxDistance = 400f; [CompilerGenerated] private Tile[] <AllTiles>k__BackingField; [field: Header("General Settings")] [field: SerializeField] public DungeonFlow DungeonFlow { get; set; } [field: SerializeField] public string DungeonName { get; set; } = string.Empty; [field: SerializeField] [field: Min(0f)] public float MapTileSize { get; set; } = 1f; [field: SerializeField] public AudioClip FirstTimeDungeonAudio { get; set; } [field: SerializeField] public Vector3 RestrictBounds { get; set; } = Vector3.zero; [field: SerializeField] [field: Min(0f)] public int CullingTileDepth { get; set; } = 6; [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Extended Feature Settings")] [field: SerializeField] public GameObject OverrideKeyPrefab { get; set; } [field: SerializeField] public List<IndoorMapHazard> IndoorMapHazards { get; set; } = new List<IndoorMapHazard>(); [field: SerializeField] public List<GlobalPropCountOverride> GlobalPropCountOverridesList { get; set; } = new List<GlobalPropCountOverride>(); [field: Space(5f)] [field: SerializeField] public bool IsDynamicDungeonSizeRestrictionEnabled { get; set; } [field: SerializeField] public Vector2 DynamicDungeonSizeMinMax { get; set; } = new Vector2(1f, 1f); [field: SerializeField] [field: Range(0f, 1f)] public float DynamicDungeonSizeLerpRate { get; set; } = 1f; public float DynamicDungeonSizeMin => DynamicDungeonSizeMinMax.x; public float DynamicDungeonSizeMax => DynamicDungeonSizeMinMax.y; [field: Tooltip("Lower the kill floor of any Level this Dungeon generates on down to the lowest point of the generation.")] [field: SerializeField] public bool IsDynamicOutOfBoundsTriggerEnabled { get; set; } [field: Space(5f)] [field: SerializeField] public AudioClip[] OverrideCreakOpenDoorSFX { get; set; } [field: SerializeField] public AudioClip[] OverrideCreakShutDoorSFX { get; set; } [field: Space(5f)] [field: Tooltip("Overrides Vanilla Camera Far Plane Clip Distance Inside.")] [field: Range(0.1f, 10000f)] [field: SerializeField] public float OverrideCameraFarPlaneDistanceInside { get; set; } = 400f; [field: Space(10f)] [field: Header("Misc. Settings")] [field: SerializeField] public bool GenerateAutomaticConfigurationOptions { get; set; } = true; [Obsolete] [field: SerializeField] public List<SpawnableMapObject> SpawnableMapObjects { get; set; } = new List<SpawnableMapObject>(); [Obsolete] [field: SerializeField] public Vector3 OverrideRestrictedTilePlacementBounds { get; set; } = Vector3.zero; public int DungeonID { get; internal set; } public bool IsCurrentDungeon => (Object)(object)DungeonManager.CurrentExtendedDungeonFlow == (Object)(object)this; [HideInInspector] public DungeonEvents DungeonEvents { get; internal set; } = new DungeonEvents(); [HideInInspector] public Tile[] AllTiles { get { if (<AllTiles>k__BackingField == null) { <AllTiles>k__BackingField = DungeonFlow.GetTiles().ToArray(); } return <AllTiles>k__BackingField; } } internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip newFirstTimeDungeonAudio, Vector3 newRestrictBounds, int newCullingTileDepth) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) ExtendedDungeonFlow extendedDungeonFlow = ScriptableObject.CreateInstance<ExtendedDungeonFlow>(); extendedDungeonFlow.DungeonFlow = newDungeonFlow; extendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio; extendedDungeonFlow.RestrictBounds = newRestrictBounds; extendedDungeonFlow.CullingTileDepth = newCullingTileDepth; extendedDungeonFlow.TryCreateMatchingProperties(); return extendedDungeonFlow; } internal void Initialize() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } GetDungeonFlowID(); if (string.IsNullOrEmpty(DungeonName)) { DungeonName = ((Object)DungeonFlow).name; } ((Object)this).name = ((Object)DungeonFlow).name.Replace("Flow", "") + "ExtendedDungeonFlow"; if ((Object)(object)FirstTimeDungeonAudio == (Object)null) { DebugHelper.LogWarning("Custom Dungeon: " + DungeonName + " Is Missing A DungeonFirstTimeAudio Reference! Assigning Facility Audio To Prevent Errors.", DebugType.Developer); FirstTimeDungeonAudio = Patches.RoundManager.firstTimeDungeonAudios[0]; } } private void GetDungeonFlowID() { if (base.ContentType == ContentType.Custom) { DungeonID = PatchedContent.ExtendedDungeonFlows.Count; } ContentType contentType = base.ContentType; if ((contentType != 0 && contentType != ContentType.External) || 1 == 0) { return; } for (int i = 0; i < Patches.RoundManager.dungeonFlowTypes.Length; i++) { if (Patches.RoundManager.dungeonFlowTypes[i] != null && (Object)(object)Patches.RoundManager.dungeonFlowTypes[i].dungeonFlow == (Object)(object)DungeonFlow) { DungeonID = i; } } } internal override void TryCreateMatchingProperties() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } LevelMatchingProperties.ApplyValues(null, manualContentSourceNameReferenceList, newPlanetNames: manualPlanetNameReferenceList, newLevelTags: dynamicLevelTagsList, newRoutePrices: dynamicRoutePricesList, newCurrentWeathers: dynamicCurrentWeatherList); } internal override (bool result, string log) TryValidateContent() { int num = IndoorMapHazards.RemoveAll((IndoorMapHazard mapHazard) => mapHazard == null || (Object)(object)mapHazard.hazardType == (Object)null || (Object)(object)mapHazard.hazardType.prefabToSpawn == (Object)null); if (num > 0) { DebugHelper.LogWarning($"Removed '{num}' missing or empty IndoorMapHazard spawns in ExtendedDungeonFlow: {((Object)this).name}", DebugType.User); } if (base.ContentType == ContentType.Custom) { if ((Object)(object)DungeonFlow == (Object)null) { return (false, "DungeonFlow Was Null"); } if (DungeonFlow.Nodes == null || DungeonFlow.Nodes.Count == 0) { return (false, "DungeonFlow Nodes List Was Null Or Empty"); } if (DungeonFlow.Lines == null || DungeonFlow.Lines.Count == 0) { return (false, "DungeonFlow Lines List Was Null Or Empty"); } } for (int i = 0; i < AllTiles.Length; i++) { Tile val = AllTiles[i]; if (val.AllDoorways.Count > 0 || val.UsedDoorways.Count > 0 || val.UnusedDoorways.Count > 0) { DebugHelper.LogWarning("Tile '" + ((Object)val).name + "' does not have its 'AllDoorways', 'UsedDoorways', or 'UnusedDoorways' lists empty! Clearing them all to avoid generation issues...", DebugType.Developer); val.AllDoorways.Clear(); val.UsedDoorways.Clear(); val.UnusedDoorways.Clear(); } } return base.TryValidateContent(); } internal override void ConvertObsoleteValues() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown if ((Object)(object)DungeonFlow == (Object)null && (Object)(object)dungeonFlow != (Object)null) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFlow is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonFlow instead.", DebugType.Developer); DungeonFlow = dungeonFlow; dungeonFlow = null; } if (string.IsNullOrEmpty(DungeonName) && !string.IsNullOrEmpty(dungeonDisplayName)) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonDisplayName is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonName instead.", DebugType.Developer); DungeonName = dungeonDisplayName; dungeonDisplayName = string.Empty; } if ((Object)(object)FirstTimeDungeonAudio == (Object)null && (Object)(object)dungeonFirstTimeAudio != (Object)null) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFirstTimeAudio is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.FirstTimeDungeonAudio instead.", DebugType.Developer); FirstTimeDungeonAudio = dungeonFirstTimeAudio; dungeonFirstTimeAudio = null; } if (dungeonSizeLerpPercentage != 1f) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeLerpPercentage is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicDungeonSizeLerpRate instead.", DebugType.Developer); } if (dungeonSizeMax != 1f || dungeonSizeMin != 1f) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeMin and ExtendedDungeonFlow.dungeonSizeMax are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicSungeonSizeMinMax instead.", DebugType.Developer); DynamicDungeonSizeMinMax = new Vector2(dungeonSizeMin, dungeonSizeMax); } if (!string.IsNullOrEmpty(contentSourceName)) { DebugHelper.LogWarning("ExtendedDungeonFlow.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer); } if ((Object)(object)LevelMatchingProperties == (Object)null && (dynamicLevelTagsList.Count > 0 || dynamicRoutePricesList.Count > 0 || dynamicCurrentWeatherList.Count > 0 || manualContentSourceNameReferenceList.Count > 0 || manualContentSourceNameReferenceList.Count > 0)) { DebugHelper.LogWarning("ExtendedDungeonFlow dynamic and manual match reference lists are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.LevelMatchingProperties instead.", DebugType.Developer); TryCreateMatchingProperties(); } if (enableDynamicDungeonSizeRestriction || IsDynamicDungeonSizeRestrictionEnabled != enableDynamicDungeonSizeRestriction) { DebugHelper.LogWarning("ExtendedDungeonFlow.enableDynamicDungeonSizeRestriction Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.IsDynamicDungeonRestrictionEnabled instead.", DebugType.Developer); IsDynamicDungeonSizeRestrictionEnabled = enableDynamicDungeonSizeRestriction; } if (!generateAutomaticConfigurationOptions || GenerateAutomaticConfigurationOptions != generateAutomaticConfigurationOptions) { DebugHelper.LogWarning("ExtendedDungeonFlow.generateAutomaticConfigurationOptions Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.GenerateAutomaticConfigurationOptions instead.", DebugType.Developer); GenerateAutomaticConfigurationOptions = generateAutomaticConfigurationOptions; } if (SpawnableMapObjects.Count > 0) { DebugHelper.LogWarning("ExtendedDungeonFlow.SpawnableMapObjects Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.IndoorMapHazards instead.", DebugType.Developer); foreach (SpawnableMapObject spawnableMapObject in SpawnableMapObjects) { IndoorMapHazardType val = ScriptableObject.CreateInstance<IndoorMapHazardType>(); val.prefabToSpawn = spawnableMapObject.prefabToSpawn; val.spawnFacingAwayFromWall = spawnableMapObject.spawnFacingAwayFromWall; val.spawnFacingWall = spawnableMapObject.spawnFacingWall; val.spawnWithBackToWall = spawnableMapObject.spawnWithBackToWall; val.spawnWithBackFlushAgainstWall = spawnableMapObject.spawnWithBackFlushAgainstWall; val.requireDistanceBetweenSpawns = spawnableMapObject.requireDistanceBetweenSpawns; val.disallowSpawningNearEntrances = spawnableMapObject.disallowSpawningNearEntrances; IndoorMapHazard item = new IndoorMapHazard { hazardType = val, numberToSpawn = spawnableMapObject.numberToSpawn }; IndoorMapHazards.Add(item); } } Vector3 overrideRestrictedTilePlacementBounds = OverrideRestrictedTilePlacementBounds; if (((Vector3)(ref overrideRestrictedTilePlacementBounds)).sqrMagnitude > 1f) { DebugHelper.LogWarning("ExtendedDungeonFlow.OverrideRestrictedTilePlacementBounds Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.RestrictBounds instead.", DebugType.Developer); RestrictBounds = OverrideRestrictedTilePlacementBounds; } if (OverrideCameraMaxDistance != 400f && OverrideCameraFarPlaneDistanceInside == 400f) { DebugHelper.LogWarning("ExtendedDungeonFlow.OverrideCameraMaxDistance Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.OverrideCameraFarPlaneDistanceInside instead.", DebugType.Developer); OverrideCameraFarPlaneDistanceInside = OverrideCameraMaxDistance; } } } [Serializable] public class GlobalPropCountOverride { public int globalPropID; [Range(0f, 1f)] public float globalPropCountScaleRate; } [Serializable] public class DungeonEvents { public ExtendedEvent<RoundManager> onBeforeDungeonGenerate = new ExtendedEvent<RoundManager>(); public ExtendedEvent onShipLand = new ExtendedEvent(); public ExtendedEvent onShipLeave = new ExtendedEvent(); public ExtendedEvent<List<GameObject>> onSpawnedSyncedObjects = new ExtendedEvent<List<GameObject>>(); public ExtendedEvent<List<GameObject>> onSpawnedMapObjects = new ExtendedEvent<List<GameObject>>(); public ExtendedEvent<List<GrabbableObject>> onSpawnedScrapObjects = new ExtendedEvent<List<GrabbableObject>>(); public ExtendedEvent<(EnemyVent, EnemyAI)> onEnemySpawnedFromVent = new ExtendedEvent<(EnemyVent, EnemyAI)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>(); public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>(); } [CreateAssetMenu(fileName = "ExtendedEnemyType", menuName = "Lethal Level Loader/Extended Content/ExtendedEnemyType", order = 24)] public class ExtendedEnemyType : ExtendedContent { [field: Header("General Settings")] [field: SerializeField] public EnemyType EnemyType { get; set; } [field: SerializeField] public string EnemyDisplayName { get; set; } [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties OutsideDungeonMatchingProperties { get; set; } [field: SerializeField] public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties DaytimeDungeonMatchingProperties { get; set; } [field: SerializeField] public LevelMatchingProperties InsideLevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Terminal Bestiary Override Settings")] [field: SerializeField] [field: TextArea(2, 20)] public string InfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] public VideoClip InfoNodeVideoClip { get; set; } public ScanNodeProperties ScanNodeProperties { get; internal set; } public int EnemyID { get; internal set; } public TerminalNode EnemyInfoNode { get; internal set; } public static ExtendedEnemyType Create(EnemyType enemyType, ExtendedMod extendedMod, ContentType contentType) { ExtendedEnemyType extendedEnemyType = ScriptableObject.CreateInstance<ExtendedEnemyType>(); extendedEnemyType.EnemyType = enemyType; ((Object)extendedEnemyType).name = enemyType.enemyName.Sanitized(toLower: false) + "ExtendedEnemyType"; extendedEnemyType.ContentType = contentType; extendedMod.RegisterExtendedContent(extendedEnemyType); extendedEnemyType.TryCreateMatchingProperties(); return extendedEnemyType; } public void Initalize() { DebugHelper.Log("Initializing Custom Enemy: " + EnemyType.enemyName, DebugType.Developer); TryCreateMatchingProperties(); ContentRestorer.RestoreAudioAssetReferencesInParent(EnemyType.enemyPrefab); } internal override void TryCreateMatchingProperties() { if ((Object)(object)InsideLevelMatchingProperties == (Object)null) { InsideLevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)InsideDungeonMatchingProperties == (Object)null) { InsideDungeonMatchingProperties = DungeonMatchingProperties.Create(this); } if ((Object)(object)OutsideLevelMatchingProperties == (Object)null) { OutsideLevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)OutsideDungeonMatchingProperties == (Object)null) { OutsideDungeonMatchingProperties = DungeonMatchingProperties.Create(this); } if ((Object)(object)DaytimeLevelMatchingProperties == (Object)null) { DaytimeLevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)DaytimeDungeonMatchingProperties == (Object)null) { DaytimeDungeonMatchingProperties = DungeonMatchingProperties.Create(this); } } internal override (bool result, string log) TryValidateContent() { if ((Object)(object)EnemyType == (Object)null) { return (false, "EnemyType Was Null"); } if ((Object)(object)EnemyType.enemyPrefab == (Object)null) { return (false, "EnemyPrefab Was Null"); } if (!Object.op_Implicit((Object)(object)EnemyType.enemyPrefab.GetComponent<NetworkObject>())) { return (false, "EnemyPrefab Did Not Contain A NetworkObject"); } EnemyAI componentInChildren = EnemyType.enemyPrefab.GetComponentInChildren<EnemyAI>(false); if ((Object)(object)componentInChildren == (Object)null) { return (false, "EnemyPrefab Did Not Contain A Component Deriving From EnemyAI"); } if ((Object)(object)componentInChildren.enemyType == (Object)null) { return (false, "EnemyAI.enemyType Was Null"); } if ((Object)(object)componentInChildren.enemyType != (Object)(object)EnemyType) { return (false, "EnemyAI.enemyType Did Not Match ExtendedEnemyType.EnemyType"); } return base.TryValidateContent(); } } [CreateAssetMenu(fileName = "ExtendedFootstepSurface", menuName = "Lethal Level Loader/Extended Content/ExtendedFootstepSurface", order = 27)] public class ExtendedFootstepSurface : ExtendedContent { [Space(25f)] [Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")] [Obsolete] public FootstepSurface footstepSurface; [Obsolete] public List<Material> associatedMaterials; [field: Header("General Settings")] [field: SerializeField] public FootstepSurface FootstepSurface { get; set; } [field: Header("Extended Feature Settings")] [field: Tooltip("Allow Quicksand to affect players while on this ExtendedFootstepSurface.")] [field: SerializeField] public bool AllowSinking { get; set; } = true; [field: Tooltip("Allow Earth Leviathans to emerge out of this ExtendedFootstepSurface.")] [field: SerializeField] public bool AllowEarthLeviathanEmerge { get; set; } = true; [field: Tooltip("Allow Masked to use this ExtendedFootstepSurface, otherwise GameObject tag is used.")] [field: SerializeField] public bool AllowMaskedFootsteps { get; set; } = true; [HideInInspector] public Dictionary<string, byte> AssociatedTerrainNames { get; } = new Dictionary<string, byte>(); [HideInInspector] public int SurfaceIndex { get; internal set; } = -1; internal static ExtendedFootstepSurface Create(FootstepSurface newFootstepSurface, bool allowSinking, params TerrainWithIndices[] newAssociatedTerrains) { ExtendedFootstepSurface extendedFootstepSurface = ScriptableObject.CreateInstance<ExtendedFootstepSurface>(); extendedFootstepSurface.FootstepSurface = newFootstepSurface; extendedFootstepSurface.AllowSinking = allowSinking; for (int i = 0; i < newAssociatedTerrains?.Length; i++) { TerrainWithIndices terrainWithIndices = newAssociatedTerrains[i]; if (!string.IsNullOrEmpty(terrainWithIndices.terrainName)) { int[] layerIndices = terrainWithIndices.layerIndices; if (layerIndices != null && layerIndices.Length != 0) { extendedFootstepSurface.AssociatedTerrainNames[terrainWithIndices.terrainName] = terrainWithIndices.GetIndexMask(); } } } return extendedFootstepSurface; } internal void Initialize() { ((Object)this).name = FootstepSurface.surfaceTag.Sanitized(toLower: false) + "ExtendedFootstepSurface"; if (base.ContentType == ContentType.Custom) { string text = base.ExtendedMod.ModMergeSetting switch { ModMergeSetting.MatchingAuthorName => base.ExtendedMod.AuthorName, ModMergeSetting.MatchingModName => base.ExtendedMod.ModName, _ => base.UniqueIdentificationName, }; FootstepSurface.surfaceTag = text + "/" + FootstepSurface.surfaceTag; } } internal bool IsTerrainMatch(TerrainData terrainData) { return AssociatedTerrainNames.ContainsKey(((Object)terrainData).name); } internal bool IsTerrainMatch(TerrainData terrainData, int terrainLayer) { if (AssociatedTerrainNames.TryGetValue(((Object)terrainData).name, out var value)) { return ((byte)(1 << terrainLayer) & value) != 0; } return false; } internal override (bool result, string log) TryValidateContent() { if (FootstepSurface == null) { return (false, "FootstepSurface Was Null"); } if (string.IsNullOrEmpty(FootstepSurface.surfaceTag)) { FootstepSurface.surfaceTag = "Untagged"; } return base.TryValidateContent(); } internal override void ConvertObsoleteValues() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown if (footstepSurface == null) { return; } AudioClip[] clips = footstepSurface.clips; if (clips == null || clips.Length == 0) { AudioClip[] jumpLandSFX = footstepSurface.jumpLandSFX; if ((jumpLandSFX == null || jumpLandSFX.Length == 0) && !((Object)(object)footstepSurface.hitSurfaceSFX != (Object)null)) { return; } } DebugHelper.LogWarning("ExtendedFootstepSurface.footstepSurface is Obsolete and will be removed in following releases, Please use ExtendedFootstepSurface.FootstepSurface instead.", DebugType.Developer); FootstepSurface = new FootstepSurface { surfaceTag = footstepSurface.surfaceTag, clips = (footstepSurface.clips ?? Array.Empty<AudioClip>()).ToArray(), hitSurfaceSFX = footstepSurface.hitSurfaceSFX, jumpLandSFX = (footstepSurface.jumpLandSFX ?? Array.Empty<AudioClip>()).ToArray() }; footstepSurface = null; } } [Serializable] public struct TerrainWithIndices { public string terrainName; [Range(0f, 7f)] public int[] layerIndices; public TerrainWithIndices(string terrainName, params int[] layerIndices) { this.terrainName = terrainName; this.layerIndices = layerIndices; } public readonly byte GetIndexMask() { HashSet<int> hashSet = new HashSet<int>(); int[] array = layerIndices; foreach (int item in array) { hashSet.Add(item); } HashSet<int> hashSet2 = hashSet; int num = hashSet2.RemoveWhere((int index) => (index < 0 || index > 7) ? true : false); if (num > 0) { DebugHelper.LogWarning($"Removed {num} indices for Terrain: {terrainName}", DebugType.Developer); } byte b = 0; foreach (int item2 in hashSet2) { b += (byte)(1 << item2); } return b; } } public enum VanillaSurfaceTags : sbyte { None = -1, Concrete, Gravel, Catwalk, Aluminum, Grass, Rock, Puddle, Tiles, Snow, Carpet, Untagged, Wood, Slime, Tree } [CreateAssetMenu(fileName = "ExtendedItem", menuName = "Lethal Level Loader/Extended Content/ExtendedItem", order = 23)] public class ExtendedItem : ExtendedContent { [field: Header("General Settings")] [field: SerializeField] public Item Item { get; set; } [field: SerializeField] public string PluralisedItemName { get; set; } = string.Empty; [field: SerializeField] public bool IsBuyableItem { get; set; } [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties DungeonMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Terminal Store & Info Override Settings")] [field: SerializeField] public string OverrideInfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] public string OverrideBuyNodeDescription { get; set; } = string.Empty; [field: SerializeField] public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty; public TerminalNode BuyNode { get; internal set; } public TerminalNode BuyConfirmNode { get; internal set; } public TerminalNode BuyInfoNode { get; internal set; } public int CreditsWorth { get { if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null) { BuyNode.itemCost = Item.creditsWorth; BuyConfirmNode.itemCost = Item.creditsWorth; } else { Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!"); } return Item.creditsWorth; } set { if (value >= 0) { if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null) { BuyNode.itemCost = value; BuyConfirmNode.itemCost = value; } else { Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!"); } Item.creditsWorth = value; } } } public static ExtendedItem Create(Item newItem, ExtendedMod extendedMod, ContentType contentType) { ExtendedItem extendedItem = ScriptableObject.CreateInstance<ExtendedItem>(); extendedItem.Item = newItem; ((Object)extendedItem).name = newItem.itemName.Sanitized(toLower: false) + "ExtendedItem"; extendedItem.ContentType = contentType; extendedMod.RegisterExtendedContent(extendedItem); extendedItem.TryCreateMatchingProperties(); return extendedItem; } public void Initialize() { DebugHelper.Log("Initializing Custom Item: " + Item.itemName + ". Is Buyable: " + IsBuyableItem + ". Is Scrap: " + Item.isScrap, DebugType.Developer); TryCreateMatchingProperties(); if (!Patches.StartOfRound.allItemsList.itemsList.Contains(Item)) { Patches.StartOfRound.allItemsList.itemsList.Add(Item); } if (IsBuyableItem) { TerminalManager.CreateItemTerminalData(this); } for (int i = 0; i < Item.spawnPositionTypes?.Count; i++) { ItemGroup targetItemGroup = Item.spawnPositionTypes[i]; if ((Object)(object)targetItemGroup != (Object)null) { ItemGroup val = OriginalContent.ItemGroups.Find((ItemGroup itemGroup) => string.Equals(((Object)itemGroup).name, ((Object)targetItemGroup).name, StringComparison.Ordinal)); if ((Object)(object)val != (Object)null) { Item.spawnPositionTypes[i] = ContentRestorer.RestoreAsset<ItemGroup>((Object)(object)targetItemGroup, val, debugAction: false, destroyOnReplace: true); } } } ContentRestorer.RestoreAudioAssetReferencesInParent(Item.spawnPrefab); } internal override void TryCreateMatchingProperties() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)DungeonMatchingProperties == (Object)null) { DungeonMatchingProperties = DungeonMatchingProperties.Create(this); } } internal override (bool result, string log) TryValidateContent() { if ((Object)(object)Item == (Object)null) { return (false, "Item Was Null"); } if ((Object)(object)Item.spawnPrefab == (Object)null) { return (false, "SpawnPrefab Was Null"); } return base.TryValidateContent(); } public void SetLevelMatchingProperties(LevelMatchingProperties newLevelMatchingProperties) { if ((Object)(object)Plugin.Instance != (Object)null) { Debug.LogError((object)"SetLevelMatchingProperties() Should Only Be Used In Editor!"); } LevelMatchingProperties = newLevelMatchingProperties; } } [CreateAssetMenu(fileName = "ExtendedLevel", menuName = "Lethal Level Loader/Extended Content/ExtendedLevel", order = 20)] public class ExtendedLevel : ExtendedContent { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct ExtendedLevelDifficultyComparer : IComparer<ExtendedLevel> { public readonly int Compare(ExtendedLevel a, ExtendedLevel b) { return a.CalculatedDifficultyRating - b.CalculatedDifficultyRating; } } [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct ExtendedLevelRoutePriceComparer : IComparer<ExtendedLevel> { public readonly int Compare(ExtendedLevel a, ExtendedLevel b) { return a.RoutePrice - b.RoutePrice; } } [Space(5f)] [SerializeField] [Min(0f)] private int routePrice; [Space(25f)] [Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")] [Obsolete] public SelectableLevel selectableLevel; [Obsolete] [Range(0.1f, 10000f)] public float OverrideCameraMaxDistance = 400f; [Obsolete] [Space(5f)] public string contentSourceName = string.Empty; [Obsolete] [Space(5f)] public List<string> levelTags = new List<string>(); [CompilerGenerated] private string <NumberlessPlanetName>k__BackingField; [CompilerGenerated] private int <CalculatedDifficultyRating>k__BackingField; [field: Header("General Settings")] [field: SerializeField] public SelectableLevel SelectableLevel { get; set; } [field: Header("Extended Feature Settings")] [field: SerializeField] public bool OverrideDynamicRiskLevelAssignment { get; set; } [field: Tooltip("Enable to use Terrain layers for Player footstep sound effects instead of GameObject tags, when applicable. Disabled by default for older moons to keep their intended (original) footstep sounds.")] [field: SerializeField] public bool UseTerrainFootsteps { get; set; } [field: Space(5f)] [field: SerializeField] public bool IsRouteHidden { get; set; } [field: SerializeField] public bool IsRouteLocked { get; set; } public bool IsRouteRemoved { get; set; } [field: SerializeField] public string LockedRouteNodeText { get; set; } = string.Empty; [field: Space(5f)] [field: SerializeField] public List<ClipWithRarity> ShipFlyToMoonClips { get; set; } = new List<ClipWithRarity>(); [field: SerializeField] public List<ClipWithRarity> ShipFlyFromMoonClips { get; set; } = new List<ClipWithRarity>(); [field: Space(5f)] [field: SerializeField] public List<StringWithRarity> SceneSelections { get; set; } = new List<StringWithRarity>(); [field: Space(5f)] [field: Tooltip("Overrides Vanilla Camera Far Plane Clip Distance Outside.")] [field: Range(0.1f, 10000f)] [field: SerializeField] public float OverrideCameraFarPlaneDistanceOutside { get; set; } = 400f; [field: Space(5f)] [field: Tooltip("Overrides Vanilla Camera Far Plane Clip Distance In Orbit.")] [field: Range(0.1f, 10000f)] [field: SerializeField] public float OverrideCameraFarPlaneDistanceInOrbit { get; set; } = 400f; [field: Space(5f)] [field: Header("Weather Effect Override Settings")] [field: SerializeField] public Vector3 OverrideDustStormVolumeSize { get; set; } = Vector3.zero; [field: Space(5f)] [field: SerializeField] public GameObject OverrideQuicksandPrefab { get; set; } [field: SerializeField] public GameObject OverrideRainPrefab { get; set; } [field: SerializeField] public AudioClip OverrideRainAmbience { get; set; } [field: Space(5f)] [field: SerializeField] public ParticleSystem OverrideStormyLightningStrikeExplosion { get; set; } [field: SerializeField] public ParticleSystem OverrideStormyStaticElectricityParticle { get; set; } [field: SerializeField] public AudioClip[] OverrideStormyLightningStrikeSFX { get; set; } [field: SerializeField] public AudioClip[] OverrideStormyDistantThunderSFX { get; set; } [field: SerializeField] public AudioClip OverrideStormyStaticElectricitySFX { get; set; } [field: Space(5f)] [field: SerializeField] public GameObject OverrideStormyRainPrefab { get; set; } [field: SerializeField] public AudioClip OverrideStormyRainAmbience { get; set; } [field: Space(5f)] [field: SerializeField] public Vector3 OverrideFoggyVolumeSize { get; set; } = Vector3.zero; [field: Space(5f)] [field: SerializeField] public GameObject OverrideFloodedPrefab { get; set; } [field: SerializeField] public AudioClip OverrideFloodedAmbience { get; set; } [field: Space(5f)] [field: SerializeField] public AudioClip OverrideEclipsedMusic { get; set; } [field: Space(5f)] [field: Header("Time Of Day Music Override Settings")] [field: SerializeField] public AudioClip OverrideStartOfDayMusic { get; set; } [field: SerializeField] public AudioClip OverrideMidDayMusic { get; set; } [field: SerializeField] public AudioClip OverrideLateDayMusic { get; set; } [field: SerializeField] public AudioClip OverrideNightMusic { get; set; } [field: Space(5f)] [field: Header("Entrance Teleport SFX Override Settings")] [field: SerializeField] public AudioClip[] OverrideCreakOpenDoorSFX { get; set; } [field: SerializeField] public AudioClip[] OverrideCreakShutDoorSFX { get; set; } [field: Space(5f)] [field: Header("Terminal Route Override Settings")] [field: SerializeField] public string OverrideRouteNoun { get; set; } = string.Empty; [field: SerializeField] [field: TextArea(2, 20)] public string OverrideInfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] [field: TextArea(2, 20)] public string OverrideRouteNodeDescription { get; set; } = string.Empty; [field: SerializeField] [field: TextArea(2, 20)] public string OverrideRouteConfirmNodeDescription { get; set; } = string.Empty; [field: Space(10f)] [field: Header("Misc. Settings")] [field: Space(5f)] [field: SerializeField] public bool GenerateAutomaticConfigurationOptions { get; set; } = true; [Obsolete] [field: SerializeField] public AnimationClip ShipFlyToMoonClip { get; set; } [Obsolete] [field: SerializeField] public AnimationClip ShipFlyFromMoonClip { get; set; } public int RoutePrice { get { if ((Object)(object)RouteNode != (Object)null) { routePrice = RouteNode.itemCost; RouteConfirmNode.itemCost = routePrice; return RouteNode.itemCost; } DebugHelper.LogWarning("routeNode Is Missing! Using internal value!", DebugType.Developer); return routePrice; } set { if ((Object)(object)RouteNode != (Object)null && (Object)(object)RouteConfirmNode != (Object)null) { RouteNode.itemCost = value; RouteConfirmNode.itemCost = value; } else { DebugHelper.LogWarning("routeNode Is Missing! Only setting internal value!", DebugType.Developer); } routePrice = value; } } public string TerminalNoun { get { if (!string.IsNullOrEmpty(OverrideRouteNoun)) { return OverrideRouteNoun.StripSpecialCharacters().RemoveWhitespace().ToLowerInvariant(); } return NumberlessPlanetName.StripSpecialCharacters().RemoveWhitespace().ToLowerInvariant(); } } public string NumberlessPlanetName { get { if (string.IsNullOrEmpty(<NumberlessPlanetName>k__BackingField)) { <NumberlessPlanetName>k__BackingField = GetNumberlessPlanetName(SelectableLevel); } return <NumberlessPlanetName>k__BackingField; } } public int CalculatedDifficultyRating { get { if (<CalculatedDifficultyRating>k__BackingField == 0) { <CalculatedDifficultyRating>k__BackingField = LevelManager.CalculateExtendedLevelDifficultyRating(this); } return <CalculatedDifficultyRating>k__BackingField; } } public bool IsCurrentLevel => (Object)(object)LevelManager.CurrentExtendedLevel == (Object)(object)this; public bool IsLevelLoaded { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (IsCurrentLevel) { Scene sceneByName = SceneManager.GetSceneByName(SelectableLevel.sceneName); return ((Scene)(ref sceneByName)).isLoaded; } return false; } } [HideInInspector] public LevelEvents LevelEvents { get; internal set; } = new LevelEvents(); public TerminalNode RouteNode { get; internal set; } public TerminalNode RouteConfirmNode { get; internal set; } public TerminalNode InfoNode { get; internal set; } public TerminalNode SimulateNode { get; internal set; } public List<ExtendedWeatherEffect> EnabledExtendedWeatherEffects { get; set; } = new List<ExtendedWeatherEffect>(); public ExtendedWeatherEffect CurrentExtendedWeatherEffect { get; set; } internal static ExtendedLevel Create(SelectableLevel newSelectableLevel) { ExtendedLevel extendedLevel = ScriptableObject.CreateInstance<ExtendedLevel>(); extendedLevel.SelectableLevel = newSelectableLevel; return extendedLevel; } internal void Initialize(string _, bool generateTerminalAssets) { bool flag = false; foreach (StringWithRarity sceneSelection in SceneSelections) { if (sceneSelection.Name == SelectableLevel.sceneName) { flag = true; } } if (!flag) { StringWithRarity item = new StringWithRarity(SelectableLevel.sceneName, 300); SceneSelections.Add(item); } foreach (StringWithRarity item2 in new List<StringWithRarity>(SceneSelections)) { if (!PatchedContent.AllLevelSceneNames.Contains(item2.Name)) { DebugHelper.LogWarning("Removing SceneSelection From: " + SelectableLevel.PlanetName + " As SceneName: " + item2.Name + " Is Not Loaded!", DebugType.Developer); SceneSelections.Remove(item2); } } if (ShipFlyToMoonClips.Count == 0) { ShipFlyToMoonClips.Add(new ClipWithRarity(LevelLoader.defaultShipFlyToMoonClip, 300)); } if (ShipFlyFromMoonClips.Count == 0) { ShipFlyFromMoonClips.Add(new ClipWithRarity(LevelLoader.defaultShipFlyFromMoonClip, 300)); } if ((Object)(object)OverrideStartOfDayMusic == (Object)null) { OverrideStartOfDayMusic = LevelLoader.defaultStartOfDayMusic; } if ((Object)(object)OverrideMidDayMusic == (Object)null) { OverrideMidDayMusic = LevelLoader.defaultMidDayMusic; } if ((Object)(object)OverrideLateDayMusic == (Object)null) { OverrideLateDayMusic = LevelLoader.defaultLateDayMusic; } if ((Object)(object)OverrideNightMusic == (Object)null) { OverrideNightMusic = LevelLoader.defaultNightMusic; } ContentType contentType = base.ContentType; if ((contentType == ContentType.Custom || contentType == ContentType.External) ? true : false) { ((Object)this).name = NumberlessPlanetName.StripSpecialCharacters() + "ExtendedLevel"; ((Object)SelectableLevel).name = NumberlessPlanetName.StripSpecialCharacters() + "Level"; if (generateTerminalAssets) { TerminalManager.CreateLevelTerminalData(this, routePrice); } } SelectableLevel val = SelectableLevel; if (val.spawnableMapObjects == null) { val.spawnableMapObjects = Array.Empty<SpawnableMapObject>(); } val = SelectableLevel; if (val.indoorMapHazards == null) { val.indoorMapHazards = Array.Empty<IndoorMapHazard>(); } if (base.ContentType == ContentType.Vanilla) { GetVanillaInfoNode(); } SetExtendedDungeonFlowMatches(); } internal override (bool result, string log) TryValidateContent() { int num = SceneSelections.RemoveAll((StringWithRarity sceneSelection) => sceneSelection == null || string.IsNullOrEmpty(sceneSelection.Name)); if (num > 0) { DebugHelper.LogWarning($"Removed '{num}' missing or empty scene selections in ExtendedLevel: {((Object)this).name}", DebugType.User); } int num2 = ShipFlyToMoonClips.RemoveAll((ClipWithRarity clipSelection) => (Object)(object)clipSelection.Clip == (Object)null || clipSelection.Rarity == 0); if (num2 > 0) { DebugHelper.LogWarning($"Removed '{num2}' missing, empty, or zero-rarity ShipFlyToMoon clip overrides in ExtendedLevel: {((Object)this).name}", DebugType.User); } int num3 = ShipFlyFromMoonClips.RemoveAll((ClipWithRarity clipSelection) => (Object)(object)clipSelection.Clip == (Object)null || clipSelection.Rarity == 0); if (num3 > 0) { DebugHelper.LogWarning($"Removed '{num3}' missing, empty, or zero-rarity ShipFlyFromMoon clip overrides in ExtendedLevel: {((Object)this).name}", DebugType.User); } if ((Object)(object)SelectableLevel == (Object)null) { return (false, "SelectableLevel Was Null"); } if (string.IsNullOrEmpty(SelectableLevel.sceneName)) { return (false, "SelectableLevel SceneName Was Null Or Empty"); } if ((Object)(object)SelectableLevel.planetPrefab == (Object)null) { return (false, "SelectableLevel PlanetPrefab Was Null"); } Animator val = default(Animator); if (!SelectableLevel.planetPrefab.TryGetComponent<Animator>(ref val)) { return (false, "SelectableLevel PlanetPrefab Animator Was Null"); } if ((Object)(object)val.runtimeAnimatorController == (Object)null) { return (false, "SelectableLevel PlanetPrefab Animator AnimatorController Was Null"); } return base.TryValidateContent(); } internal override void ConvertObsoleteValues() { if (levelTags.Count > 0 && base.ContentTags.Count == 0) { DebugHelper.LogWarning("ExtendedLevel.levelTags Is Obsolete and will be removed in following releases, Please use .ContentTags instead.", DebugType.Developer); foreach (ContentTag item in ContentTagManager.CreateNewContentTags(levelTags)) { base.ContentTags.Add(item); } } levelTags.Clear(); if ((Object)(object)SelectableLevel == (Object)null && (Object)(object)selectableLevel != (Object)null) { DebugHelper.LogWarning("ExtendedLevel.selectableLevel Is Obsolete and will be removed in following releases, Please use .SelectableLevel instead.", DebugType.Developer); SelectableLevel = selectableLevel; } if (!string.IsNullOrEmpty(contentSourceName)) { DebugHelper.LogWarning("ExtendedLevel.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer); } if ((Object)(object)ShipFlyToMoonClip != (Object)null) { DebugHelper.LogWarning("ExtendedLevel.ShipFlyToMoonClip Is Obsolete and will be removed in following releases, Please use ExtendedLevel.ShipFlyToMoonClips instead.", DebugType.Developer); if (ShipFlyToMoonClips.Count == 0) { ShipFlyToMoonClips.Add(new ClipWithRarity(ShipFlyToMoonClip, 300)); } } if ((Object)(object)ShipFlyFromMoonClip != (Object)null) { DebugHelper.LogWarning("ExtendedLevel.ShipFlyFromMoonClip Is Obsolete and will be removed in following releases, Please use ExtendedLevel.ShipFlyFromMoonClips instead.", DebugType.Developer); if (ShipFlyFromMoonClips.Count == 0) { ShipFlyFromMoonClips.Add(new ClipWithRarity(ShipFlyFromMoonClip, 300)); } } if (OverrideCameraMaxDistance != 400f && OverrideCameraFarPlaneDistanceOutside == 400f && OverrideCameraFarPlaneDistanceInOrbit == 400f) { DebugHelper.LogWarning("ExtendedLevel.OverrideCameraMaxDistance Is Obsolete and will be removed in following releases, Please use ExtendedLevel.OverrideCameraFarPlaneDistanceOutside instead.", DebugType.Developer); OverrideCameraFarPlaneDistanceOutside = OverrideCameraMaxDistance; OverrideCameraFarPlaneDistanceInOrbit = OverrideCameraMaxDistance; } } internal static string GetNumberlessPlanetName(SelectableLevel selectableLevel) { if (!((Object)(object)selectableLevel != (Object)null) || string.IsNullOrEmpty(selectableLevel.PlanetName)) { return string.Empty; } return selectableLevel.PlanetName.SkipToLetters(); } internal void SetLevelID(int levelId) { if (base.ContentType == ContentType.Custom) { SelectableLevel.levelID = levelId; if ((Object)(object)RouteNode != (Object)null) { RouteNode.displayPlanetInfo = levelId; } if ((Object)(object)RouteConfirmNode != (Object)null) { RouteConfirmNode.buyRerouteToMoon = levelId; } } } internal void SetExtendedDungeonFlowMatches() { List<IntWithRarity> list = SelectableLevel.dungeonFlowTypes.ToList(); for (int i = 0; i < list.Count; i++) { IntWithRarity dungeonWithRarity = list[i]; if (dungeonWithRarity != null) { ExtendedDungeonFlow extendedDungeonFlow2 = PatchedContent.ExtendedDungeonFlows.Find((ExtendedDungeonFlow extendedDungeonFlow) => extendedDungeonFlow.DungeonID == dungeonWithRarity.id); if ((Object)(object)extendedDungeonFlow2 != (Object)null) { extendedDungeonFlow2.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, dungeonWithRarity.rarity)); continue; } } Debug.LogWarning((object)$"Invalid DungeonFlow entry at index '{i}' for SelectableLevel: {((Object)SelectableLevel).name}"); list.RemoveAt(i--); } if (string.Equals(((Object)SelectableLevel).name, "MarchLevel", StringComparison.Ordinal)) { ExtendedDungeonFlow extendedDungeonFlow3 = PatchedContent.ExtendedDungeonFlows.Find((ExtendedDungeonFlow extendedDungeonFlow) => string.Equals(((Object)extendedDungeonFlow.DungeonFlow).name, "Level1Flow3Exits", StringComparison.Ordinal)); if ((Object)(object)extendedDungeonFlow3 != (Object)null) { extendedDungeonFlow3.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, 300)); } } SelectableLevel.dungeonFlowTypes = list.ToArray(); } internal void GetVanillaInfoNode() { CompatibleNoun[] compatibleNouns = TerminalManager.routeInfoKeyword.compatibleNouns; foreach (CompatibleNoun val in compatibleNouns) { if (string.Equals(val.noun.word, NumberlessPlanetName, StringComparison.OrdinalIgnoreCase)) { InfoNode = val.result; break; } } } public void ForceSetRoutePrice(int newValue) { if ((Object)(object)Plugin.Instance != (Object)null) { Debug.LogWarning((object)"ForceSetRoutePrice Should Only Be Used In Editor! Consider Using RoutePrice Property To Sync TerminalNode's With New Value."); } routePrice = newValue; } } [Serializable] public class LevelEvents { public ExtendedEvent onLevelLoaded = new ExtendedEvent(); public ExtendedEvent onShipLand = new ExtendedEvent(); public ExtendedEvent onShipLeave = new ExtendedEvent(); public ExtendedEvent<EnemyAI> onDaytimeEnemySpawn = new ExtendedEvent<EnemyAI>(); public ExtendedEvent<EnemyAI> onNighttimeEnemySpawn = new ExtendedEvent<EnemyAI>(); public ExtendedEvent<StoryLog> onStoryLogCollected = new ExtendedEvent<StoryLog>(); public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>(); public ExtendedEvent<DayMode> onDayModeToggle = new ExtendedEvent<DayMode>(); } public enum ModMergeSetting { MatchingAuthorName, MatchingModName, Disabled } [CreateAssetMenu(fileName = "ExtendedMod", menuName = "Lethal Level Loader/ExtendedMod", order = 30)] public class ExtendedMod : ScriptableObject { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct ExtendedModComparer : IComparer<ExtendedMod> { public readonly int Compare(ExtendedMod a, ExtendedMod b) { return a.ModName.AsSpan().CompareTo(b.ModName.AsSpan(), StringComparison.OrdinalIgnoreCase); } } [CompilerGenerated] private static ContentTag <VanillaContentTag>k__BackingField; [CompilerGenerated] private static ContentTag <CustomContentTag>k__BackingField; [field: SerializeField] public string ModName { get; internal set; } = "Unspecified"; [field: SerializeField] public string AuthorName { get; internal set; } = "Unknown"; public List<string> ModNameAliases { get; internal set; } = new List<string>(); [field: SerializeField] public ModMergeSetting ModMergeSetting { get; internal set; } [field: SerializeField] public List<ExtendedLevel> ExtendedLevels { get; private set; } = new List<ExtendedLevel>(); [field: SerializeField] public List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; private set; } = new List<ExtendedDungeonFlow>(); [field: SerializeField] public List<ExtendedItem> ExtendedItems { get; private set; } = new List<ExtendedItem>(); [field: SerializeField] public List<ExtendedEnemyType> ExtendedEnemyTypes { get; private set; } = new List<ExtendedEnemyType>(); [field: SerializeField] public List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; private set; } = new List<ExtendedWeatherEffect>(); [field: SerializeField] public List<ExtendedFootstepSurface> ExtendedFootstepSurfaces { get; private set; } = new List<ExtendedFootstepSurface>(); [field: SerializeField] public List<ExtendedStoryLog> ExtendedStoryLogs { get; private set; } = new List<ExtendedStoryLog>(); [field: SerializeField] public List<ExtendedBuyableVehicle> ExtendedBuyableVehicles { get; private set; } = new List<ExtendedBuyableVehicle>(); [field: SerializeField] public List<ExtendedUnlockableItem> ExtendedUnlockableItems { get; private set; } = new List<ExtendedUnlockableItem>(); [field: SerializeField] public List<string> StreamingLethalBundleNames { get; private set; } = new List<string>(); public static ContentTag VanillaContentTag { get { if ((Object)(object)<VanillaContentTag>k__BackingField == (Object)null) { <VanillaContentTag>k__BackingField = ContentTag.Create("Vanilla"); } return <VanillaContentTag>k__BackingField; } } public static ContentTag CustomContentTag { get { if ((Object)(object)<CustomContentTag>k__BackingField == (Object)null) { <CustomContentTag>k__BackingField = ContentTag.Create("Custom"); } return <CustomContentTag>k__BackingField; } } public List<ExtendedContent> ExtendedContents { get { List<ExtendedContent> list = new List<ExtendedContent>(); foreach (ExtendedLevel extendedLevel in ExtendedLevels) { list.Add(extendedLevel); } foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows) { list.Add(extendedDungeonFlow); } foreach (ExtendedItem extendedItem in ExtendedItems) { list.Add(extendedItem); } foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes) { list.Add(extendedEnemyType); } foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects) { list.Add(extendedWeatherEffect); } foreach (ExtendedFootstepSurface extendedFootstepSurface in ExtendedFootstepSurfaces) { list.Add(extendedFootstepSurface); } foreach (ExtendedStoryLog extendedStoryLog in ExtendedStoryLogs) { list.Add(extendedStoryLog); } foreach (ExtendedBuyableVehicle extendedBuyableVehicle in ExtendedBuyableVehicles) { list.Add(extendedBuyableVehicle); } foreach (ExtendedUnlockableItem extendedUnlockableItem in ExtendedUnlockableItems) { list.Add(extendedUnlockableItem); } List<ExtendedContent> list2 = list; list2.Sort(default(ExtendedContent.ExtendedContentComparer)); return list2; } } internal static ExtendedMod Create(string modName) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.Sanitized(toLower: false) + "Mod"; DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName, DebugType.Developer); return extendedMod; } public static ExtendedMod Create(string modName, string authorName) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.Sanitized(toLower: false) + "Mod"; extendedMod.AuthorName = authorName; if ((Object)(object)Plugin.Instance != (Object)null) { DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer); } return extendedMod; } public static ExtendedMod Create(string modName, string authorName, ExtendedContent[] extendedContents) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.Sanitized(toLower: false) + "Mod"; extendedMod.AuthorName = authorName; foreach (ExtendedContent newExtendedContent in extendedContents) { extendedMod.RegisterExtendedContent(newExtendedContent); } if ((Object)(object)Plugin.Instance != (Object)null) { DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer); } return extendedMod; } internal void RegisterExtendedContent(ExtendedContent newExtendedContent) { if ((Object)(object)newExtendedContent != (Object)null) { if (!ExtendedContents.Contains(newExtendedContent)) { if (newExtendedContent is ExtendedLevel extendedLevel) { RegisterExtendedContent(extendedLevel); return; } if (newExtendedContent is ExtendedDungeonFlow extendedDungeonFlow) { RegisterExtendedContent(extendedDungeonFlow); return; } if (newExtendedContent is ExtendedItem extendedItem) { RegisterExtendedContent(extendedItem); return; } if (newExtendedContent is ExtendedEnemyType extendedEnemyType) { RegisterExtendedContent(extendedEnemyType); return; } if (newExtendedContent is ExtendedWeatherEffect extendedWeatherEffect) { RegisterExtendedContent(extendedWeatherEffect); return; } if (newExtendedContent is ExtendedFootstepSurface extendedFootstepSurface) { RegisterExtendedContent(extendedFootstepSurface); return; } if (newExtendedContent is ExtendedStoryLog extendedStoryLog) { RegisterExtendedContent(extendedStoryLog); return; } if (newExtendedContent is ExtendedBuyableVehicle extendedBuyableVehicle) { RegisterExtendedContent(extendedBuyableVehicle); return; } if (newExtendedContent is ExtendedUnlockableItem extendedUnlockableItem) { RegisterExtendedContent(extendedUnlockableItem); return; } throw new ArgumentException(((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Unimplemented Registration Check!", "newExtendedContent"); } throw new ArgumentException(((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Already Being Registered To This Mod!", "newExtendedContent"); } throw new ArgumentNullException("newExtendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check!"); } internal void RegisterExtendedContent<T>(T extendedContent, List<T> extendedContentList) where T : ExtendedContent { if ((Object)(object)extendedContent == (Object)null) { DebugHelper.LogError($"{((object)extendedContent).GetType()} Was Null", DebugType.User); return; } if (extendedContentList == null) { DebugHelper.LogError($"{((object)extendedContent).GetType()} Content List Was Null", DebugType.User); return; } extendedContent.ConvertObsoleteValues(); TryThrowInvalidContentException(extendedContent, extendedContent.TryValidateContent()); extendedContentList.Add(extendedContent); extendedContent.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedLevel extendedLevel) { RegisterExtendedContent(extendedLevel, ExtendedLevels); } internal void RegisterExtendedContent(ExtendedDungeonFlow extendedDungeonFlow) { RegisterExtendedContent(extendedDungeonFlow, ExtendedDungeonFlows); } internal void RegisterExtendedContent(ExtendedItem extendedItem) { RegisterExtendedContent(extendedItem, ExtendedItems); } internal void RegisterExtendedContent(ExtendedEnemyType extendedEnemyType) { RegisterExtendedContent(extendedEnemyType, ExtendedEnemyTypes); } internal void RegisterExtendedContent(ExtendedWeatherEffect extendedWeatherEffect) { RegisterExtendedContent(extendedWeatherEffect, ExtendedWeatherEffects); } internal void RegisterExtendedContent(ExtendedFootstepSurface extendedFootstepSurface) { RegisterExtendedContent(extendedFootstepSurface, ExtendedFootstepSurfaces); } internal void RegisterExtendedContent(ExtendedStoryLog extendedStoryLog) { RegisterExtendedContent(extendedStoryLog, ExtendedStoryLogs); } internal void RegisterExtendedContent(ExtendedBuyableVehicle extendedBuyableVehicle) { RegisterExtendedContent(extendedBuyableVehicle, ExtendedBuyableVehicles); } internal void RegisterExtendedContent(ExtendedUnlockableItem extendedUnlockableItem) { RegisterExtendedContent(extendedUnlockableItem, ExtendedUnlockableItems); } internal void TryThrowInvalidContentException(ExtendedContent extendedContent, (bool, string) result) { if (!result.Item1) { if ((Object)(object)extendedContent == (Object)null) { throw new ArgumentNullException("extendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2); } throw new ArgumentException(((Object)extendedContent).name + " (" + ((object)extendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2, "extendedContent"); } } internal void UnregisterExtendedContent(ExtendedContent currentExtendedContent) { if (currentExtendedContent is ExtendedLevel item) { ExtendedLevels.Remove(item); } else if (currentExtendedContent is ExtendedDungeonFlow item2) { ExtendedDungeonFlows.Remove(item2); } else if (currentExtendedContent is ExtendedItem item3) { ExtendedItems.Remove(item3); } else if (currentExtendedContent is ExtendedUnlockableItem item4) { ExtendedUnlockableItems.Remove(item4); } currentExtendedContent.ExtendedMod = null; DebugHelper.LogWarning("Unregistered ExtendedContent: " + ((Object)currentExtendedContent).name + " In ExtendedMod: " + ModName, DebugType.Developer); } internal void UnregisterAllExtendedContent() { ExtendedLevels.Clear(); ExtendedDungeonFlows.Clear(); ExtendedItems.Clear(); ExtendedEnemyTypes.Clear(); ExtendedWeatherEffects.Clear(); ExtendedFootstepSurfaces.Clear(); ExtendedStoryLogs.Clear(); ExtendedBuyableVehicles.Clear(); ExtendedUnlockableItems.Clear(); } internal void SortRegisteredContent() { ExtendedContent.ExtendedContentComparer extendedContentComparer = default(ExtendedContent.ExtendedContentComparer); ExtendedLevels.Sort(extendedContentComparer); ExtendedDungeonFlows.Sort(extendedContentComparer); ExtendedItems.Sort(extendedContentComparer); ExtendedEnemyTypes.Sort(extendedContentComparer); ExtendedWeatherEffects.Sort(extendedContentComparer); ExtendedFootstepSurfaces.Sort(extendedContentComparer); ExtendedStoryLogs.Sort(extendedContentComparer); ExtendedBuyableVehicles.Sort(extendedContentComparer); ExtendedUnlockableItems.Sort(extendedContentComparer); } } [CreateAssetMenu(fileName = "ExtendedStoryLog", menuName = "Lethal Level Loader/Extended Content/ExtendedStoryLog", order = 26)] public class ExtendedStoryLog : ExtendedContent { public string sceneName = string.Empty; public int storyLogID; [Space(5f)] public string terminalKeywordNoun = string.Empty; [Space(5f)] public string storyLogTitle = string.Empty; [TextArea(2, 20)] public string storyLogDescription = string.Empty; [HideInInspector] internal int newStoryLogID; [HideInInspector] internal TerminalNode assignedNode; internal override (bool result, string log) TryValidateContent() { if (string.IsNullOrEmpty(sceneName)) { return (false, "StoryLog SceneName Was Null Or Empty"); } if (string.IsNullOrEmpty(terminalKeywordNoun)) { return (false, "StoryLog TerminalKeywordNoun Was Null Or Empty"); } if (string.IsNullOrEmpty(storyLogTitle)) { return (false, "StoryLog Title Was Null Or Empty"); } if (string.IsNullOrEmpty(storyLogDescription)) { return (false, "StoryLog Description Was Null Or Empty"); } return base.TryValidateContent(); } } [CreateAssetMenu(fileName = "ExtendedUnlockableItem", menuName = "Lethal Level Loader/Extended Content/ExtendedUnlockableItem", order = 21)] public class ExtendedUnlockableItem : ExtendedContent { [field: Header("General Settings")] [field: SerializeField] public UnlockableItem UnlockableItem { get; set; } [field: SerializeField] public int ItemCost { get; set; } [field: Space(5f)] [field: Header("Terminal Store & Info Override Settings")] [field: TextArea(2, 20)] [field: SerializeField] public string OverrideInfoNodeDescription { get; set; } = string.Empty; [field: TextArea(2, 20)] [field: SerializeField] public string OverrideBuyNodeDescription { get; set; } = string.Empty; [field: TextArea(2, 20)] [field: SerializeField] public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty; public int UnlockableItemID { get; set; } = -1; public TerminalNode BuyNode { get; internal set; } public TerminalNode BuyConf
patchers/LethalLevelLoader.Patcher.dll
Decompiled a week ago#define TRACE using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx.Bootstrap; using HarmonyLib; using HarmonyLib.Internal.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("0Harmony")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LethalLevelLoader.Patcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+91ce948550bf16502208ab52512cca78b892665c")] [assembly: AssemblyProduct("LethalLevelLoader.Patcher")] [assembly: AssemblyTitle("LethalLevelLoader.Patcher")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/IAmBatby/LethalLevelLoader/")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalLevelLoader.Patcher { public class LethalLevelLoaderPatcher { public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>(); internal static Harmony Harmony { get; } = new Harmony("imabatby.lethallevelloader.patcher"); public static event Action onChainloaderFinish; private static void Initialize() { Trace.TraceInformation("[LethalLevelLoader.Patcher] Initializing..."); } private static void Finish() { Trace.TraceInformation("[LethalLevelLoader.Patcher] Patching..."); Harmony.PatchAll(typeof(ChainloaderEventPatch)); Harmony.PatchAll(typeof(CursedHarmonyPatch)); Trace.TraceInformation("[LethalLevelLoader.Patcher] Done!"); } private static void ChainloaderFinish() { try { LethalLevelLoaderPatcher.onChainloaderFinish?.Invoke(); LethalLevelLoaderPatcher.onChainloaderFinish = null; } catch (Exception ex) { Trace.TraceError("[LethalLevelLoader.Patcher] Error during Chainloader event invokation: " + ex); } } public static void Patch(AssemblyDefinition _) { } } [HarmonyPatch] internal static class ChainloaderEventPatch { [HarmonyPatch(typeof(Chainloader), "Initialize")] [HarmonyPostfix] [HarmonyPriority(0)] private static void ChainloaderInitialize_Postfix() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown MethodInfo method = typeof(Chainloader).GetMethod("Start", BindingFlags.Static | BindingFlags.Public); MethodInfo method2 = typeof(LethalLevelLoaderPatcher).GetMethod("ChainloaderFinish", BindingFlags.Static | BindingFlags.NonPublic); LethalLevelLoaderPatcher.Harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } internal static class CursedHarmonyPatch { private static void ReadInstruction_Prefix(Instruction ins) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (ins.Operand is DynamicMethod dynamicMethod) { ModuleDefinition val = ModuleDefinition.ReadModule(typeof(object).Module.FullyQualifiedName); ins.Operand = (object)new DynamicMethodReference(val, (MethodInfo)dynamicMethod); Trace.TraceInformation("[LethalLevelLoader.Patcher] DynamicMethod '" + dynamicMethod.Name + "' replaced!"); } } [HarmonyPatch(typeof(Chainloader), "Initialize")] [HarmonyPostfix] [HarmonyPriority(800)] private static void ChainloaderInitialize_Postfix() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown string environmentVariable = Environment.GetEnvironmentVariable("MONOMOD_DMD_TYPE"); if (!string.IsNullOrEmpty(environmentVariable) && !string.Equals(environmentVariable, "dynamicmethod", StringComparison.Ordinal)) { return; } Type type = null; MethodInfo methodInfo = null; Assembly assembly = Assembly.GetAssembly(typeof(ILManipulator)); Type[] types = assembly.GetTypes(); for (int num = types.Length - 1; num >= 0; num--) { type = types[num]; MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic); methodInfo = Array.Find(methods, (MethodInfo method) => method.Name.Contains("ReadInstruction", StringComparison.Ordinal)); if (methodInfo != null) { Trace.TraceInformation("[LethalLevelLoader.Patcher] Found Method '" + type.FullName + "/" + methodInfo.Name + "'!"); break; } } if (!(methodInfo == null)) { HarmonyMethod val = new HarmonyMethod(typeof(CursedHarmonyPatch), "ReadInstruction_Prefix", (Type[])null); LethalLevelLoaderPatcher.Harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }