using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Adapters;
using DunGen.Graph;
using HarmonyLib;
using HarmonyLib.Public.Patching;
using LCSoundTool;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalExpansionCore.Patches;
using Loadstone.Config;
using Loadstone.Patches;
using Loadstone.Patches.ExpansionCore;
using Loadstone.Patches.LCSoundTool;
using Microsoft.CodeAnalysis;
using Unity.AI.Navigation;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.adibtw.loadstone")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyDescription("Reduces stuttering during level loading")]
[assembly: AssemblyFileVersion("0.1.16.0")]
[assembly: AssemblyInformationalVersion("0.1.16+40c7ad10254c26303752eb3a80d82a595c9e87d1")]
[assembly: AssemblyProduct("LoadstoneNightly")]
[assembly: AssemblyTitle("com.adibtw.loadstone")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.16.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 Loadstone
{
public static class ObjectPool
{
private static Dictionary<GameObject, Stack<GameObject>> availableObjects = new Dictionary<GameObject, Stack<GameObject>>(256);
private static Dictionary<GameObject, GameObject> inUseObjects = new Dictionary<GameObject, GameObject>(1024);
public static GameObject InstantiateTransparently(GameObject original, Vector3 position, Quaternion rotation, Transform parent)
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
if (!availableObjects.TryAdd(original, new Stack<GameObject>(4)) && availableObjects[original].TryPop(out var result) && (Object)(object)result != (Object)null)
{
inUseObjects[result] = original;
result.SetActive(true);
((Object)result).hideFlags = (HideFlags)0;
result.transform.parent = parent;
result.transform.localPosition = position;
result.transform.localRotation = rotation;
return result;
}
result = Object.Instantiate<GameObject>(original, position, rotation, parent);
inUseObjects[result] = original;
return result;
}
public static GameObject InstantiateTransparently(GameObject original, Transform parent)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return InstantiateTransparently(original, Vector3.zero, Quaternion.identity, parent);
}
public static GameObject InstantiateTransparently(GameObject original)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return InstantiateTransparently(original, Vector3.zero, Quaternion.identity, null);
}
public static void InstantiateInvisibly(GameObject original)
{
GameObject val = Object.Instantiate<GameObject>(original);
Object.DontDestroyOnLoad((Object)(object)val);
val.SetActive(false);
((Object)val).hideFlags = (HideFlags)52;
availableObjects[original].Push(val);
}
public static void ReleaseObject(GameObject toRelease)
{
if ((Object)(object)toRelease == (Object)null)
{
return;
}
if (!inUseObjects.Remove(toRelease, out var value))
{
NetworkObject val = default(NetworkObject);
if (toRelease.TryGetComponent<NetworkObject>(ref val))
{
val.Despawn(true);
}
else
{
Object.DestroyImmediate((Object)(object)toRelease, false);
}
}
else
{
toRelease.transform.parent = null;
Object.DontDestroyOnLoad((Object)(object)toRelease);
toRelease.SetActive(false);
((Object)toRelease).hideFlags = (HideFlags)52;
availableObjects[value].Push(toRelease);
}
}
public static void ReleaseAllObjects()
{
foreach (GameObject key in inUseObjects.Keys)
{
if ((Object)(object)key == (Object)null)
{
Loadstone.LogDebug("A pooled object for " + ((Object)inUseObjects[key]).name + " being mass released was null!");
continue;
}
key.transform.parent = null;
Object.DontDestroyOnLoad((Object)(object)key);
key.SetActive(false);
((Object)key).hideFlags = (HideFlags)52;
availableObjects[inUseObjects[key]].Push(key);
}
inUseObjects.Clear();
}
}
[BepInPlugin("com.adibtw.loadstone.Nightly", "LoadstoneNightly", "0.1.16")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Loadstone : BaseUnityPlugin
{
private static ManualLogSource CurrentLog;
private static ManualLogSource HarmonyLog;
private static ManualLogSource TranspilerLog;
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogDebug((object)"Loading Loadstone...");
HarmonyLog = Logger.CreateLogSource(" LoadstoneNightly(Harmony)");
TranspilerLog = Logger.CreateLogSource(" LoadstoneNightly(Transpiler)");
CurrentLog = TranspilerLog;
((BaseUnityPlugin)this).Logger.LogDebug((object)"Loading Configs...");
LoadstoneConfig.BindAllTo(((BaseUnityPlugin)this).Config);
((BaseUnityPlugin)this).Logger.LogDebug((object)"Patching Methods...");
if (LoadstoneConfig.StatusChangeFix.Value)
{
ConflictResolver.TryPatch(typeof(StatusChangedFixer));
if (LoadstoneConfig.AsyncDungeon.Value)
{
ConflictResolver.TryPatch(typeof(AsyncDungeonPatches));
if (LoadstoneConfig.DungeonRealization.Value)
{
ConflictResolver.TryPatch(typeof(FromProxyPatches));
}
}
}
if (LoadstoneConfig.AsyncNavmesh.Value)
{
ConflictResolver.TryPatch(typeof(NavmeshPatches));
}
ConflictResolver.TryPatch(typeof(ScreenDarkenPatches));
ConflictResolver.TryPatch(typeof(ObjectFindPatches));
if (LoadstoneConfig.ObjectPooling.Value)
{
ConflictResolver.TryPatch(typeof(PoolingPatches));
}
if (LoadstoneConfig.DunGenOptimizations.Value)
{
ConflictResolver.TryPatch(typeof(DungenOptimizationPatches));
}
if (LoadstoneConfig.LocalPerformanceReports.Value)
{
ConflictResolver.TryPatch(typeof(PerformanceReportPatches));
}
CheckModded();
CurrentLog = HarmonyLog;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Loadstone is loaded!");
}
private void Start()
{
ConflictResolver.CheckUnknownPatches();
}
private void CheckModded()
{
OptionalModPatcher();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loadstone modded compat is loaded!");
}
private void OptionalModPatcher()
{
using Dictionary<string, PluginInfo>.KeyCollection.Enumerator enumerator = Chainloader.PluginInfos.Keys.GetEnumerator();
while (enumerator.MoveNext())
{
switch (enumerator.Current)
{
case "com.github.lethalmods.lethalexpansioncore":
PatchExpansionCore();
break;
case "LCSoundTool":
PatchLCSoundTool();
break;
case "ainavt.lc.lethalconfig":
LoadstoneDynamicConfig.RegisterDynamicConfig();
break;
}
}
}
private void PatchExpansionCore()
{
((BaseUnityPlugin)this).Logger.LogDebug((object)"Patching ExpansionCore");
ConflictResolver.TryPatch(typeof(DungeonGenerator_PatchPatches));
}
private void PatchLCSoundTool()
{
((BaseUnityPlugin)this).Logger.LogDebug((object)"Patching with LCSoundTool");
ConflictResolver.TryPatch(typeof(RoundManagerMusicPatches));
}
internal static void Log(LogLevel level, object data)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
CurrentLog.Log(level, data);
}
internal static void LogDebug(object data)
{
CurrentLog.LogDebug(data);
}
internal static void LogError(object data)
{
CurrentLog.LogError(data);
}
internal static void LogFatal(object data)
{
CurrentLog.LogFatal(data);
}
internal static void LogInfo(object data)
{
CurrentLog.LogInfo(data);
}
internal static void LogMessage(object data)
{
CurrentLog.LogMessage(data);
}
internal static void LogWarning(object data)
{
CurrentLog.LogWarning(data);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.adibtw.loadstone.Nightly";
public const string PLUGIN_NAME = "LoadstoneNightly";
public const string PLUGIN_VERSION = "0.1.16";
}
}
namespace Loadstone.Patches
{
public class AsyncDungeonPatches
{
[HarmonyPatch(typeof(DungeonGenerator), "ShouldSkipFrame")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> ShouldSkipFrameTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Expected O, but got Unknown
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to inject modified frame skip transpiler into DungeonGenerator::ShouldSkipFrame");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(typeof(DungeonGenerator), "yieldTimer")),
new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.DeclaredMethod(typeof(Stopwatch), "Start", (Type[])null, (Type[])null))
}).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
{
new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.DeclaredMethod(typeof(Stopwatch), "Restart", (Type[])null, (Type[])null), (string)null)
})
.Advance(2)
.SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(Stopwatch), "Reset", (Type[])null, (Type[])null))
.InstructionEnumeration();
Loadstone.LogDebug("Validating injected frame skip transpiler into DungeonGenerator::ShouldSkipFrame");
return result;
}
[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
[HarmonyPrefix]
private static void GenerateNewFloorPatch(RoundManager __instance)
{
if ((Object)(object)__instance.dungeonGenerator == (Object)null)
{
Loadstone.LogWarning("Runtime dungeon was null, not forcing Async dungeon for this landing");
return;
}
__instance.dungeonGenerator.Generator.GenerateAsynchronously = LoadstoneConfig.AsyncDungeon.Value;
__instance.dungeonGenerator.Generator.PauseBetweenRooms = 0f;
__instance.dungeonGenerator.Generator.MaxAsyncFrameMilliseconds = LoadstoneConfig.DungeonAsyncMaxTime.Value;
}
}
public static class ConflictResolver
{
private static Harmony HarmonyInstance;
private static bool HasOurs;
static ConflictResolver()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Expected O, but got Unknown
HarmonyInstance = new Harmony("com.adibtw.loadstone.Nightly");
}
public static void CheckUnknownPatches()
{
foreach (MethodBase method in PatchManager.GetPatchedMethods())
{
PatchInfo patchInfo = PatchManager.GetPatchInfo(method);
patchInfo.transpilers.Where((Patch patch) => !IsPatchOurs(patch, method)).ToList().ForEach(delegate(Patch patch)
{
WarnPatch(patch, method, "transpiler");
});
HasOurs = false;
patchInfo.ilmanipulators.Where((Patch patch) => !IsPatchOurs(patch, method)).ToList().ForEach(delegate(Patch patch)
{
WarnPatch(patch, method, "IL manipulator");
});
HasOurs = false;
patchInfo.prefixes.Where((Patch patch) => !IsPatchOurs(patch, method)).ToList().ForEach(delegate(Patch patch)
{
WarnPatch(patch, method, "prefix");
});
HasOurs = false;
patchInfo.postfixes.Where((Patch patch) => !IsPatchOurs(patch, method)).ToList().ForEach(delegate(Patch patch)
{
WarnPatch(patch, method, "postfix");
});
HasOurs = false;
patchInfo.finalizers.Where((Patch patch) => !IsPatchOurs(patch, method)).ToList().ForEach(delegate(Patch patch)
{
WarnPatch(patch, method, "finalizer");
});
HasOurs = false;
}
}
public static bool IsPatchOurs(Patch patch, MethodBase method)
{
string name = patch.GetMethod(method).DeclaringType.Assembly.GetName().Name;
HasOurs = HasOurs || name == "com.adibtw.loadstone";
return name == "com.adibtw.loadstone";
}
public static void WarnPatch(Patch patch, MethodBase method, string patchType)
{
if (HasOurs)
{
Loadstone.LogWarning("The assembly \"" + patch.GetMethod(method).DeclaringType.Assembly.GetName().Name + "\" has patched the method \"" + method.ToString() + "\" with a " + patchType + " using \"" + patch.GetMethod(method).ToString() + "\", which we also modify. Unexpected behaviour may occur");
}
}
public static void TryPatch(Type type)
{
try
{
HarmonyInstance.CreateClassProcessor(type, true).Patch();
}
catch (Exception ex)
{
Loadstone.LogFatal($"Loadstone failed to patch {type}. The following exception was received:\n{ex.ToString()}");
}
}
}
public class DungenOptimizationPatches
{
internal static Dictionary<Tile, Dictionary<Tile, bool>> DungeonTagMatchTemp = null;
internal static Dictionary<DungeonFlow, Dictionary<Tile, Dictionary<Tile, bool>>> TagMatchDictionary = new Dictionary<DungeonFlow, Dictionary<Tile, Dictionary<Tile, bool>>>();
[HarmonyPatch(typeof(DungeonFlow), "HasMatchingTagPair")]
[HarmonyPrefix]
private static bool HasMatchingTagPairEarlyOut(DungeonFlow __instance, Tile tileA, Tile tileB, ref bool __result)
{
if (tileA.Tags.Tags.Count == 0 || tileB.Tags.Tags.Count == 0)
{
__result = false;
return false;
}
try
{
__result = DungeonTagMatchTemp[tileA][tileB];
}
catch (KeyNotFoundException)
{
Loadstone.LogWarning("The tile pair of \"" + ((Object)tileA).name + "\" and \"" + ((Object)tileB).name + "\" was not found in the tag cache! This pair is now being cached, which will cause a small performance penalty");
if (!TagMatchDictionary.ContainsKey(__instance))
{
TagMatchDictionary[__instance] = new Dictionary<Tile, Dictionary<Tile, bool>>();
DungeonTagMatchTemp = TagMatchDictionary[__instance];
}
if (!DungeonTagMatchTemp.ContainsKey(tileA))
{
DungeonTagMatchTemp[tileA] = new Dictionary<Tile, bool>();
}
if (!DungeonTagMatchTemp.ContainsKey(tileB))
{
DungeonTagMatchTemp[tileB] = new Dictionary<Tile, bool>();
}
__result = HasMatchingTagPairOriginal(__instance, tileA, tileB);
DungeonTagMatchTemp[tileA][tileB] = __result;
DungeonTagMatchTemp[tileB][tileA] = HasMatchingTagPairOriginal(__instance, tileB, tileA);
}
return false;
}
[HarmonyPatch(typeof(DungeonFlow), "HasMatchingTagPair")]
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
private static bool HasMatchingTagPairOriginal(DungeonFlow flow, Tile tileA, Tile tileB)
{
throw new NotImplementedException("Reverse Patch Stub");
}
private static void GenerateTileHashSet(ref HashSet<Tile> tiles, List<TileSet> tileSets)
{
foreach (TileSet tileSet in tileSets)
{
foreach (GameObjectChance weight in tileSet.TileWeights.Weights)
{
Tile component = weight.Value.GetComponent<Tile>();
if (!((Object)(object)component == (Object)null))
{
tiles.Add(component);
}
}
}
}
private static Dictionary<Tile, Dictionary<Tile, bool>> TileConnectionTagOptimization(HashSet<Tile> tiles, DungeonFlow flow)
{
Dictionary<Tile, Dictionary<Tile, bool>> dictionary = new Dictionary<Tile, Dictionary<Tile, bool>>();
foreach (Tile tile in tiles)
{
Dictionary<Tile, bool> dictionary2 = new Dictionary<Tile, bool>();
foreach (Tile tile2 in tiles)
{
dictionary2.Add(tile2, HasMatchingTagPairOriginal(flow, tile, tile2));
}
dictionary.Add(tile, dictionary2);
}
return dictionary;
}
[HarmonyPatch(typeof(DungeonGenerator), "Generate")]
[HarmonyPrefix]
private static void TileTagPrecalcPatch(DungeonGenerator __instance)
{
DungeonFlow dungeonFlow = __instance.DungeonFlow;
if (!Object.op_Implicit((Object)(object)dungeonFlow))
{
Loadstone.LogWarning("The dungeon generator's flow is null or deleted!");
return;
}
if (TagMatchDictionary.ContainsKey(dungeonFlow))
{
if (!TagMatchDictionary[dungeonFlow].Values.Any((Dictionary<Tile, bool> tile) => tile == null))
{
return;
}
Loadstone.LogWarning("At least one tile in " + ((Object)dungeonFlow).name + " has been deleted since the flow was last cached! The cache will be fully recalculated as a result");
}
HashSet<Tile> tiles = new HashSet<Tile>();
foreach (GraphNode node in dungeonFlow.Nodes)
{
GenerateTileHashSet(ref tiles, node.TileSets);
}
foreach (GraphLine line in dungeonFlow.Lines)
{
foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
{
GenerateTileHashSet(ref tiles, dungeonArchetype.TileSets);
GenerateTileHashSet(ref tiles, dungeonArchetype.BranchCapTileSets);
}
}
TagMatchDictionary.Add(dungeonFlow, TileConnectionTagOptimization(tiles, dungeonFlow));
DungeonTagMatchTemp = TagMatchDictionary[dungeonFlow];
}
}
public class FromProxyPatches
{
public static bool ConversionComplete;
[HarmonyPatch(typeof(Dungeon), "FromProxy")]
[HarmonyPrefix]
private static bool FromProxyPre(Dungeon __instance, DungeonProxy proxyDungeon, DungeonGenerator generator)
{
ConversionComplete = false;
((MonoBehaviour)__instance).StartCoroutine(FromProxyEnumerator(generator, proxyDungeon, __instance));
return false;
}
private static IEnumerator FromProxyEnumerator(DungeonGenerator generator, DungeonProxy proxyDungeon, Dungeon __instance)
{
__instance.Clear();
Dictionary<TileProxy, Tile> dictionary = new Dictionary<TileProxy, Tile>();
MethodInfo shouldSkip = typeof(DungeonGenerator).GetMethod("ShouldSkipFrame", BindingFlags.Instance | BindingFlags.NonPublic);
foreach (TileProxy allTile in proxyDungeon.AllTiles)
{
FromProxyIteration(__instance, dictionary, generator, allTile);
if ((bool)shouldSkip.Invoke(generator, new object[1] { false }))
{
yield return null;
}
}
FromProxyEnd(__instance, proxyDungeon, generator, dictionary);
ConversionComplete = true;
}
[HarmonyPatch(typeof(Dungeon), "FromProxy")]
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
private static void FromProxyIteration(Dungeon __instance, Dictionary<TileProxy, Tile> dictionary, DungeonGenerator generator, TileProxy tile)
{
StartTranspiler(null, null);
static IEnumerable<CodeInstruction> StartTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Expected O, but got Unknown
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Expected O, but got Unknown
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to reverse-patch Dungeon::FromProxy's first inner for loop");
CodeMatcher val = new CodeMatcher(instructions, generator);
int pos = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Br, (object)null, (string)null)
}).Advance(4).Pos;
val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
{
new CodeInstruction(OpCodes.Ldarg_3, (object)null),
new CodeInstruction(OpCodes.Stloc_2, (object)null),
new CodeInstruction(OpCodes.Ldarg_1, (object)null),
new CodeInstruction(OpCodes.Stloc_0, (object)null)
});
int pos2 = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
{
new CodeMatch((OpCode?)OpCodes.Endfinally, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null)
}).Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ret, (object)null)
})
.Pos;
Label label = default(Label);
val.CreateLabel(ref label);
val.MatchBack(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Leave, (object)null, (string)null)
}).Advance(1).SetOperandAndAdvance((object)label);
IEnumerable<CodeInstruction> enumerable = val.InstructionsInRange(pos, pos2).AsEnumerable();
if (LoadstoneConfig.ObjectPooling.Value)
{
enumerable = PoolingPatches.FromProxyPoolingPatch(enumerable);
}
Loadstone.LogDebug("Validating reverse-patched Dungeon::FromProxy's first inner for loop");
return enumerable;
}
}
[HarmonyPatch(typeof(Dungeon), "FromProxy")]
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
private static void FromProxyEnd(Dungeon __instance, DungeonProxy proxyDungeon, DungeonGenerator generator, Dictionary<TileProxy, Tile> dictionary)
{
EndTranspiler(null);
static IEnumerable<CodeInstruction> EndTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to reverse-patch Dungeon::FromProxy's final code");
CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
int pos = val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Endfinally, (object)null, (string)null)
}).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldarg_1, (object)null, (string)null)
}).Pos;
val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
{
new CodeInstruction(OpCodes.Ldarg_3, (object)null),
new CodeInstruction(OpCodes.Stloc_0, (object)null),
new CodeInstruction(OpCodes.Ldtoken, (object)typeof(GameObject)),
new CodeInstruction(OpCodes.Pop, (object)null)
});
int pos2 = val.End().Pos;
List<CodeInstruction> source = val.InstructionsInRange(pos, pos2);
Loadstone.LogDebug("Validating reverse-patched Dungeon::FromProxy's final code");
return source.AsEnumerable();
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> PostProcessPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to inject async check into DungeonGenerator::PostProcess");
Type[] array = new Type[1] { typeof(Func<bool>) };
Type[] array2 = new Type[2]
{
typeof(object),
typeof(IntPtr)
};
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldnull, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Stfld, (object)null, (string)null)
}).SetOpcodeAndAdvance(OpCodes.Nop).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[4]
{
new CodeInstruction(OpCodes.Ldloc_2, (object)null),
new CodeInstruction(OpCodes.Ldftn, (object)AccessTools.Method(typeof(FromProxyPatches), "PostProcessCheck", (Type[])null, (Type[])null)),
new CodeInstruction(OpCodes.Newobj, (object)AccessTools.Constructor(typeof(Func<bool>), array2, false)),
new CodeInstruction(OpCodes.Newobj, (object)AccessTools.Constructor(typeof(WaitUntil), array, false))
})
.InstructionEnumeration();
Loadstone.LogDebug("Validating injected async check into DungeonGenerator::PostProcess");
return result;
}
private static bool PostProcessCheck()
{
return ConversionComplete;
}
}
public class NavmeshPatches
{
[HarmonyPatch(typeof(RoundManager), "SpawnOutsideHazards")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> SpawnOutsideHazardsPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
Loadstone.LogDebug("Writing SpawnOutsideHazards Transpiler");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(GameObject), "GetComponent", (Type[])null, new Type[1] { typeof(NavMeshSurface) }), (string)null)
}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null)
})
.Set(OpCodes.Call, (object)AccessTools.Method(typeof(NavmeshPatches), "GenerateNavMeshAsync", new Type[2]
{
typeof(NavMeshSurface),
typeof(RoundManager)
}, (Type[])null))
.InstructionEnumeration();
Loadstone.LogDebug("Verifying SpawnOutsideHazards Transpiler");
return result;
}
[HarmonyPatch(typeof(UnityNavMeshAdapter), "BakeFullDungeon")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> BakeFullDungeonPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
Loadstone.LogDebug("Writing UnityNavMeshAdapter Transpiler");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.DeclaredMethod(typeof(NavMeshSurface), "BuildNavMesh", (Type[])null, (Type[])null), (string)null)
}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
matcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null)
}).SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(NavmeshPatches), "GenerateNavMeshAsync", (Type[])null, (Type[])null));
}, (Action<string>)null).InstructionEnumeration();
Loadstone.LogDebug("Verifying UnityNavMeshAdapter Transpiler");
return result;
}
private static void GenerateNavMeshAsync(NavMeshSurface navMeshSurface, MonoBehaviour coroutineHijack)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Invalid comparison between Unknown and I4
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//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_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
List<NavMeshBuildSource> list = (List<NavMeshBuildSource>)typeof(NavMeshSurface).GetMethod("CollectSources", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(navMeshSurface, new object[0]);
Bounds val = default(Bounds);
((Bounds)(ref val))..ctor(navMeshSurface.center, navMeshSurface.size);
if ((int)navMeshSurface.collectObjects != 1)
{
val = (Bounds)typeof(NavMeshSurface).GetMethod("CalculateWorldBounds", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(navMeshSurface, new object[1] { list });
}
Loadstone.LogDebug($"Updating navmesh with {list.Count} obstacles");
NavMeshBuildSettings buildSettings = navMeshSurface.GetBuildSettings();
if ((Object)(object)navMeshSurface.navMeshData != (Object)null)
{
navMeshSurface.navMeshData.position = ((Component)navMeshSurface).transform.position;
navMeshSurface.navMeshData.rotation = ((Component)navMeshSurface).transform.rotation;
}
else
{
navMeshSurface.navMeshData = new NavMeshData(((NavMeshBuildSettings)(ref buildSettings)).agentTypeID)
{
position = ((Component)navMeshSurface).transform.position,
rotation = ((Component)navMeshSurface).transform.rotation
};
}
coroutineHijack.StartCoroutine(NavMeshUpdateCheck(NavMeshBuilder.UpdateNavMeshDataAsync(navMeshSurface.navMeshData, buildSettings, list, val), navMeshSurface));
}
private static IEnumerator NavMeshUpdateCheck(AsyncOperation asyncOperation, NavMeshSurface navMeshSurface)
{
while (!asyncOperation.isDone)
{
yield return null;
}
navMeshSurface.RemoveData();
navMeshSurface.AddData();
Loadstone.LogDebug("Updated navmesh");
}
}
public class ObjectFindPatches
{
[HarmonyPatch(typeof(InteractTrigger), "Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> InteractTriggerPatch(IEnumerable<CodeInstruction> instructions)
{
Loadstone.LogDebug("Attempting to replace InteractTrigger's StartOfRound finding function");
IEnumerable<CodeInstruction> result = StartOfRoundFixer(instructions);
Loadstone.LogDebug("Verifying InteractTrigger's replaced StartOfRound finding function");
return result;
}
[HarmonyPatch(typeof(OutOfBoundsTrigger), "Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> OutOfBoundsTriggerPatch(IEnumerable<CodeInstruction> instructions)
{
Loadstone.LogDebug("Attempting to replace OutOfBoundsTrigger's StartOfRound finding function");
IEnumerable<CodeInstruction> result = StartOfRoundFixer(instructions);
Loadstone.LogDebug("Verifying OutOfBoundsTrigger's replaced StartOfRound finding function");
return result;
}
[HarmonyPatch(typeof(FoliageDetailDistance), "Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> FoliageDetailDistancePatch(IEnumerable<CodeInstruction> instructions)
{
Loadstone.LogDebug("Attempting to replace FoliageDetailDistance's StartOfRound finding function");
IEnumerable<CodeInstruction> result = StartOfRoundFixer(instructions);
Loadstone.LogDebug("Verifying FoliageDetailDistance's replaced StartOfRound finding function");
return result;
}
[HarmonyPatch(typeof(ItemDropship), "Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> ItemDropshipPatch(IEnumerable<CodeInstruction> instructions)
{
Loadstone.LogDebug("Attempting to replace ItemDropship's StartOfRound finding function");
IEnumerable<CodeInstruction> result = StartOfRoundFixer(instructions);
Loadstone.LogDebug("Verifying ItemDropship's replaced StartOfRound finding function");
return result;
}
[HarmonyPatch(typeof(animatedSun), "Start")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> animatedSunPatch(IEnumerable<CodeInstruction> instructions)
{
Loadstone.LogDebug("Attempting to replace animatedSun's TImeOfDay finding function");
IEnumerable<CodeInstruction> result = InstanceFixer(instructions, typeof(TimeOfDay));
Loadstone.LogDebug("Verifying animatedSun's replaced TImeOfDay finding function");
return result;
}
private static IEnumerable<CodeInstruction> StartOfRoundFixer(IEnumerable<CodeInstruction> instructions)
{
return InstanceFixer(instructions, typeof(StartOfRound));
}
private static IEnumerable<CodeInstruction> InstanceFixer(IEnumerable<CodeInstruction> instructions, Type instanceType)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Object), "FindObjectOfType", new Type[0], new Type[1] { instanceType }), (string)null)
}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
{
matcher.SetOperandAndAdvance((object)AccessTools.DeclaredMethod(instanceType, "get_Instance", (Type[])null, (Type[])null));
}, (Action<string>)null).InstructionEnumeration();
}
}
public class PerformanceReportPatches
{
private static Stopwatch timer = new Stopwatch();
private static double DungeonWaitStartedAt = 0.0;
private static double DungeonWaitEndedAt = 0.0;
private static double FinishGeneratingLevelCalledAt = 0.0;
private static DungeonGenerator CurrentGenerator = null;
[HarmonyPatch(typeof(StartOfRound), "StartGame")]
[HarmonyPrefix]
private static void StartGameCalled()
{
timer.Reset();
timer.Start();
}
[HarmonyPatch(typeof(RoundManager), "RefreshEnemiesList")]
[HarmonyPrefix]
private static void FinishGeneratingLevel()
{
FinishGeneratingLevelCalledAt = timer.Elapsed.TotalMilliseconds;
timer.Stop();
GenerationStats val = null;
if (CurrentGenerator != null)
{
val = CurrentGenerator.GenerationStats;
}
Loadstone.LogInfo("Level Loading Stats:");
if (val != null)
{
Loadstone.LogInfo(" DunGen");
Loadstone.LogInfo($" MainPathRoomCount: {val.MainPathRoomCount}");
Loadstone.LogInfo($" BranchPathRoomCount: {val.BranchPathRoomCount}");
Loadstone.LogInfo($" MaxBranchDepth: {val.MaxBranchDepth}");
Loadstone.LogInfo($" TotalRetries: {val.TotalRetries}");
Loadstone.LogInfo($" PrunedBranchTileCount: {val.PrunedBranchTileCount}");
Loadstone.LogInfo($" PreProcessTime: {val.PreProcessTime / 1000f} seconds");
Loadstone.LogInfo($" MainPathGenerationTime: {val.MainPathGenerationTime / 1000f} seconds");
Loadstone.LogInfo($" BranchPathGenerationTime: {val.BranchPathGenerationTime / 1000f} seconds");
Loadstone.LogInfo($" PostProcessTime: {val.PostProcessTime / 1000f} seconds");
Loadstone.LogInfo($" TotalTime: {val.TotalTime / 1000f} seconds");
}
else
{
Loadstone.LogInfo(" No DunGen timing stats present");
}
Loadstone.LogInfo($" Started Waiting for Others' Dungeons to Finish after {DungeonWaitStartedAt / 1000.0} seconds");
Loadstone.LogInfo($" Finished Waiting for Others' Dungeons to Finish after {DungeonWaitEndedAt / 1000.0} seconds");
Loadstone.LogInfo($" Total generation time took {FinishGeneratingLevelCalledAt / 1000.0} seconds");
}
private static void DungeonWaitStarted()
{
DungeonWaitStartedAt = timer.Elapsed.TotalMilliseconds;
}
private static void DungeonWaitEnded()
{
DungeonWaitEndedAt = timer.Elapsed.TotalMilliseconds;
}
[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
[HarmonyPostfix]
private static void GetDungeonReference(RoundManager __instance)
{
CurrentGenerator = __instance.dungeonGenerator.Generator;
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> DungeonWaitDetection(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to patch Dungeon Wait Detection into RoundManager::LoadNewLevelWait");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldftn, (object)null, (string)null)
}).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldftn, (object)null, (string)null)
}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(PerformanceReportPatches), "DungeonWaitStarted", (Type[])null, (Type[])null))
})
.Advance(10)
.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(PerformanceReportPatches), "DungeonWaitEnded", (Type[])null, (Type[])null))
})
.InstructionEnumeration();
Loadstone.LogDebug("Validating Dungeon Wait Detection patch in RoundManager::LoadNewLevelWait");
return result;
}
}
public class PoolingPatches
{
private static CodeMatch InstantiateMatcher = new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && ((MethodInfo)i.operand).Name == "Instantiate" && ((MethodInfo)i.operand).DeclaringType == typeof(Object)), (string)null);
[HarmonyPatch(typeof(DungeonGenerator), "Generate")]
[HarmonyPostfix]
private static void GenerateHijack(DungeonGenerator __instance)
{
GenerationStats generationStats = __instance.GenerationStats;
Loadstone.LogDebug($"DunGen Stats:\nPre-process Time: {generationStats.PreProcessTime}\nMain Path Generation Time: {generationStats.MainPathGenerationTime}\nBranch Path Generation Time: {generationStats.BranchPathGenerationTime}\nPost-process Time: {generationStats.PostProcessTime}\nTotal Time: {generationStats.TotalTime}");
}
[HarmonyPatch(typeof(RoundManager), "UnloadSceneObjectsEarly")]
[HarmonyPostfix]
private static void RoundManagerStartHijack()
{
ObjectPool.ReleaseAllObjects();
}
[HarmonyPatch(typeof(DungeonProxy), "AddTile")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> AddTilePoolingPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
Loadstone.LogDebug("Attempting to inject pooling patches into DungeonProxy::AddTile");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateMatcher }).SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "InstantiateTransparently", new Type[2]
{
typeof(GameObject),
typeof(Transform)
}, (Type[])null)).InstructionEnumeration();
Loadstone.LogDebug("Validating injected pooling patches into DungeonProxy::AddTile");
return result;
}
[HarmonyPatch(typeof(DungeonProxy), "RemoveTile")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> RemoveTilePoolingPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to inject pooling patches into DungeonProxy::RemoveTile");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Object), "DestroyImmediate", new Type[1] { typeof(Object) }, (Type[])null), (string)null)
}).SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "ReleaseObject", (Type[])null, (Type[])null)).InstructionEnumeration();
Loadstone.LogDebug("Validating injected pooling patches into DungeonProxy::RemoveTile");
return result;
}
[HarmonyPatch(typeof(UnityUtil), "Destroy")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> DestroyPoolingPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to inject pooling patches into UnityUtil::Destroy");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Object), "Destroy", new Type[1] { typeof(Object) }, (Type[])null), (string)null)
}).SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "ReleaseObject", (Type[])null, (Type[])null)).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Object), "DestroyImmediate", new Type[1] { typeof(Object) }, (Type[])null), (string)null)
})
.SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "ReleaseObject", (Type[])null, (Type[])null))
.InstructionEnumeration();
Loadstone.LogDebug("Validating injected pooling patches into UnityUtil::Destroy");
return result;
}
[HarmonyPatch(typeof(Dungeon), "FromProxy")]
[HarmonyTranspiler]
public static IEnumerable<CodeInstruction> FromProxyPoolingPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to inject pooling patches into Dungeon::FromProxy");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateMatcher }).SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "InstantiateTransparently", new Type[2]
{
typeof(GameObject),
typeof(Transform)
}, (Type[])null)).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateMatcher })
.SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(ObjectPool), "InstantiateTransparently", new Type[1] { typeof(GameObject) }, (Type[])null))
.Start()
.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(Object), "DestroyImmediate", new Type[2]
{
typeof(Object),
typeof(bool)
}, (Type[])null), (string)null)
})
.Repeat((Action<CodeMatcher>)delegate(CodeMatcher matcher)
{
matcher.SetOperandAndAdvance((object)AccessTools.DeclaredMethod(typeof(PoolingPatches), "DestroyImmediateTransparently", (Type[])null, (Type[])null));
}, (Action<string>)null)
.InstructionEnumeration();
Loadstone.LogDebug("Validating injected pooling patches into Dungeon::FromProxy");
return result;
}
private static void DestroyImmediateTransparently(Object obj, bool allowDestroyingAssets)
{
if (!((object)obj).GetType().IsAssignableFrom(typeof(GameObject)))
{
Object.DestroyImmediate(obj, allowDestroyingAssets);
}
else
{
ObjectPool.ReleaseObject((GameObject)(object)((obj is GameObject) ? obj : null));
}
}
}
public class ScreenDarkenPatches
{
[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> GenerateNewLevelPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
if (LoadstoneConfig.SeedDisplayConfig.Value == LoadstoneConfig.SeedDisplayType.Darken)
{
return instructions;
}
Loadstone.LogDebug("Attempting to disable screen overlay on scene load in \"RoundManager::GenerateNewLevelClientRpc\"");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null)
}).SetOpcodeAndAdvance(OpCodes.Ldc_I4_0).InstructionEnumeration();
Loadstone.LogDebug("Validating disabled screen overlay on scene load in \"RoundManager::GenerateNewLevelClientRpc\"");
return result;
}
[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
[HarmonyPostfix]
private static void GenerateNewLevelClientRpcPrefixPath(int randomSeed)
{
Loadstone.LogInfo($"Random seed: {randomSeed}");
if (LoadstoneConfig.SeedDisplayConfig.Value == LoadstoneConfig.SeedDisplayType.Popup)
{
HUDManager.Instance.DisplayTip("Random Seed", $"{randomSeed}", false, false, "LC_Tip1");
}
}
[HarmonyPatch(typeof(StartOfRound), "SceneManager_OnLoadComplete1")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> OnLoadCompletePatch(IEnumerable<CodeInstruction> instructions)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
if (LoadstoneConfig.SeedDisplayConfig.Value == LoadstoneConfig.SeedDisplayType.Darken)
{
return instructions;
}
Loadstone.LogDebug("Attempting to disable screen overlay on scene load in \"StartOfRound::SceneManager_OnLoadComplete1\"");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null)
}).SetOpcodeAndAdvance(OpCodes.Ldc_I4_0).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null)
})
.SetOpcodeAndAdvance(OpCodes.Ldc_I4_0)
.InstructionEnumeration();
Loadstone.LogDebug("Validating disabled screen overlay on scene load in \"StartOfRound::SceneManager_OnLoadComplete1\"");
return result;
}
[HarmonyPatch(typeof(StartOfRound), "SceneManager_OnLoad")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> OnLoadPatch(IEnumerable<CodeInstruction> instructions)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
if (LoadstoneConfig.SeedDisplayConfig.Value == LoadstoneConfig.SeedDisplayType.Darken)
{
return instructions;
}
Loadstone.LogDebug("Attempting to disable screen overlay on scene load in \"StartOfRound::SceneManager_OnLoad\"");
IEnumerable<CodeInstruction> result = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
{
new CodeMatch((OpCode?)OpCodes.Ldc_I4_1, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Callvirt, (object)null, (string)null)
}).SetOpcodeAndAdvance(OpCodes.Ldc_I4_0).InstructionEnumeration();
Loadstone.LogDebug("Validating disabled screen overlay on scene load in \"StartOfRound::SceneManager_OnLoad\"");
return result;
}
}
public class StatusChangedFixer
{
[HarmonyPatch(typeof(RoundManager), "Generator_OnGenerationStatusChanged")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> StatusChangedPatch(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
Loadstone.LogDebug("Attempting to fix Generator_OnGenerationStatusChanged");
Label label = default(Label);
return new CodeMatcher(instructions, ilGenerator).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ret, (object)null, (string)null)
}).CreateLabel(ref label).Start()
.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Bne_Un, (object)null, (string)null)
})
.SetOperandAndAdvance((object)label)
.InstructionEnumeration();
}
}
}
namespace Loadstone.Patches.LCSoundTool
{
[HarmonyPatch(typeof(RoundManager))]
public class RoundManagerMusicPatches
{
internal static AudioSource loadingAudioSource;
internal static AudioClip loadingAudioClip = SoundTool.GetAudioClip("AdiBTW-LoadstoneNightly", "LoadstoneLoading.ogg");
[HarmonyPatch("Awake")]
[HarmonyPrefix]
private static void CreateAudioSource()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Invalid comparison between Unknown and I4
if ((Object)(object)loadingAudioSource != (Object)null)
{
Object.Destroy((Object)(object)loadingAudioSource);
}
if (!((Object)(object)loadingAudioClip == (Object)null))
{
if ((int)loadingAudioClip.loadState != 2)
{
loadingAudioClip.LoadAudioData();
}
loadingAudioSource = Object.Instantiate<AudioSource>(StartOfRound.Instance.speakerAudioSource);
((Object)loadingAudioSource).name = "LoadstoneLoading";
loadingAudioSource.clip = loadingAudioClip;
((Component)loadingAudioSource).transform.parent = ((Component)StartOfRound.Instance.speakerAudioSource).transform;
}
}
[HarmonyPatch("GenerateNewLevelClientRpc")]
[HarmonyPrefix]
private static void PlayWaitingMusicPatch()
{
if (LoadstoneConfig.ShouldLoadingMusicPlay.Value)
{
loadingAudioSource.volume = LoadstoneConfig.LoadingMusicVolume.Value;
loadingAudioSource.Play();
}
}
[HarmonyPatch("ResetEnemySpawningVariables")]
[HarmonyPostfix]
private static void StopWaitingMusicPatch()
{
((MonoBehaviour)RoundManager.Instance).StartCoroutine(FadeOutMusic(loadingAudioSource));
}
private static IEnumerator FadeOutMusic(AudioSource source)
{
float originalVolume = source.volume;
float timeElapsed = 0f;
while ((double)source.volume > 0.01)
{
source.volume = Mathf.Lerp(originalVolume, 0f, timeElapsed);
timeElapsed += Time.deltaTime / LoadstoneConfig.LoadingMusicFadeTime.Value;
yield return null;
}
source.Stop();
source.volume = originalVolume;
Loadstone.LogDebug("Music fully faded and stopped");
}
}
}
namespace Loadstone.Patches.ExpansionCore
{
public class DungeonGenerator_PatchPatches
{
[HarmonyPatch(typeof(DungeonGenerator_Patch), "Generate_Postfix")]
[HarmonyPrefix]
private static bool Generate_PostfixPrefix()
{
return false;
}
}
}
namespace Loadstone.Config
{
public static class LoadstoneConfig
{
public enum SeedDisplayType
{
Popup,
Darken,
JustLog
}
public static ConfigFile LoadstoneFile;
public static ConfigEntry<bool> AsyncDungeon;
public static ConfigEntry<float> DungeonAsyncMaxTime;
public static ConfigEntry<bool> AsyncNavmesh;
public static ConfigEntry<bool> DungeonRealization;
public static ConfigEntry<SeedDisplayType> SeedDisplayConfig;
public static ConfigEntry<bool> StatusChangeFix;
public static ConfigEntry<bool> ObjectPooling;
public static ConfigEntry<bool> DunGenOptimizations;
public static ConfigEntry<bool> LocalPerformanceReports;
public static ConfigEntry<bool> ShouldLoadingMusicPlay;
public static ConfigEntry<float> LoadingMusicFadeTime;
public static ConfigEntry<float> LoadingMusicVolume;
public static void BindAllTo(ConfigFile config)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected O, but got Unknown
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Expected O, but got Unknown
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Expected O, but got Unknown
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Expected O, but got Unknown
LoadstoneFile = config;
AsyncDungeon = LoadstoneFile.Bind<bool>("AsyncDungeon", "Enabled", true, "Whether or not the dungeon should generate asynchronously. The vanilla value is false. This option requires StatusChangeFix to be enabled");
DungeonAsyncMaxTime = LoadstoneFile.Bind<float>("AsyncDungeon", "Dungeon Target Frametime", 20f, new ConfigDescription("How long to spend generating the dungeon each frame, in milliseconds. There is no vanilla value", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()));
AsyncNavmesh = LoadstoneFile.Bind<bool>("AsyncNavmesh", "Enabled", true, "Whether or not the navmesh should be generated asynchrounously. The vanilla value is false");
DungeonRealization = LoadstoneFile.Bind<bool>("DungeonRealization", "Spread Over Multiple Frames", true, "Whether or not to spread dungeon realization over multiple frames. The vanilla value is false");
SeedDisplayConfig = LoadstoneFile.Bind<SeedDisplayType>("ScreenDarkening", "Seed Display Type", SeedDisplayType.Popup, "Decides how the random seed should appear when loading into a level. The vanilla value is \"Darken\"");
StatusChangeFix = LoadstoneFile.Bind<bool>("StatusChangeFix", "Enabled", true, "Enables a fix for the game's status change callback, which is non-functional in vanilla. The vanilla value is false");
DunGenOptimizations = LoadstoneFile.Bind<bool>("DunGenOptimizations", "Enabled", true, "Enables a number of optmizations for DunGen's dungeon generator");
ObjectPooling = LoadstoneFile.Bind<bool>("ObjectPooling", "Enabled", false, "!!! EXPERIMENTAL FEATURE !!!\nEnables object pooling for dungeon spawning and certain parts of initial level generation. This can greatly improve load times, but may increase ram usage in modpacks with many custom interiors. This feature is currently very experimental. The vanilla value is false");
LocalPerformanceReports = LoadstoneFile.Bind<bool>("LocalPerformanceReports", "Enabled", false, "Enables local performance reports, which will appear in the logs every time the ship lands");
ShouldLoadingMusicPlay = LoadstoneFile.Bind<bool>("LCSoundTool", "Should Loading Music Play", false, new ConfigDescription("Should we play loading music as the level loads in? Requires LCSoundTool to be installed", (AcceptableValueBase)null, Array.Empty<object>()));
LoadingMusicFadeTime = LoadstoneFile.Bind<float>("LCSoundTool", "Loading Music Fade Time", 15f, new ConfigDescription("How long should it take for the loading music to fade out", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
LoadingMusicVolume = LoadstoneFile.Bind<float>("LCSoundTool", "Loading Music Volume", 0.75f, new ConfigDescription("The volume of the loading music", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1.5f), Array.Empty<object>()));
}
}
internal static class LoadstoneDynamicConfig
{
internal static void RegisterDynamicConfig()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_0034: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_007c: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
//IL_00ab: Expected O, but got Unknown
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
BaseConfigItem[] array = new BaseConfigItem[4];
ConfigEntry<float> dungeonAsyncMaxTime = LoadstoneConfig.DungeonAsyncMaxTime;
FloatSliderOptions val = new FloatSliderOptions
{
RequiresRestart = false
};
((BaseRangeOptions<float>)val).Min = 0f;
((BaseRangeOptions<float>)val).Max = 1000f;
array[0] = (BaseConfigItem)new FloatSliderConfigItem(dungeonAsyncMaxTime, val);
array[1] = (BaseConfigItem)new BoolCheckBoxConfigItem(LoadstoneConfig.ShouldLoadingMusicPlay, new BoolCheckBoxOptions
{
RequiresRestart = false
});
ConfigEntry<float> loadingMusicFadeTime = LoadstoneConfig.LoadingMusicFadeTime;
FloatSliderOptions val2 = new FloatSliderOptions
{
RequiresRestart = false
};
((BaseRangeOptions<float>)val2).Min = 0f;
((BaseRangeOptions<float>)val2).Max = 30f;
array[2] = (BaseConfigItem)new FloatSliderConfigItem(loadingMusicFadeTime, val2);
ConfigEntry<float> loadingMusicVolume = LoadstoneConfig.LoadingMusicVolume;
FloatSliderOptions val3 = new FloatSliderOptions
{
RequiresRestart = false
};
((BaseRangeOptions<float>)val3).Min = 0f;
((BaseRangeOptions<float>)val3).Max = 1.5f;
array[3] = (BaseConfigItem)new FloatSliderConfigItem(loadingMusicVolume, val3);
AddConfigItems((IEnumerable<BaseConfigItem>)(object)array);
}
internal static void AddConfigItems(IEnumerable<BaseConfigItem> configItems)
{
foreach (BaseConfigItem configItem in configItems)
{
LethalConfigManager.AddConfigItem(configItem);
}
}
}
}