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 LethalOptimizer v1.0.1
BepInEx/plugins/LethalOptimizer.dll
Decompiled 8 months agousing 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 System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalOptimizer.Patches; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [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("LethalOptimizer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Micro-optimizations for smoother gameplay")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("LethalOptimizer")] [assembly: AssemblyTitle("LethalOptimizer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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 LethalOptimizer { [BepInPlugin("mrbub.lethaloptimizer", "LethalOptimizer", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static ConfigFile ConfigFile; internal static ConfigEntry<bool> CacheCollisionComponents; internal static ConfigEntry<bool> OptimizeStringAllocations; internal static ConfigEntry<bool> CacheRepeatedLookups; private void Awake() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; ConfigFile = ((BaseUnityPlugin)this).Config; InitializeConfig(); Harmony val = new Harmony("mrbub.lethaloptimizer"); if (CacheCollisionComponents.Value) { val.PatchAll(typeof(CollisionCachePatches)); Logger.LogInfo((object)"Collision component caching enabled"); } if (OptimizeStringAllocations.Value) { val.PatchAll(typeof(StringOptimizationPatches)); Logger.LogInfo((object)"String allocation optimization enabled"); } if (CacheRepeatedLookups.Value) { val.PatchAll(typeof(ComponentLookupPatches)); Logger.LogInfo((object)"Component lookup caching enabled"); } val.PatchAll(typeof(ShipItemOptimizationPatches)); Logger.LogInfo((object)"Ship item collection optimization enabled"); Logger.LogInfo((object)"LethalOptimizer v1.0.1 loaded successfully!"); } private void InitializeConfig() { CacheCollisionComponents = ((BaseUnityPlugin)this).Config.Bind<bool>("Caching", "CacheCollisionComponents", true, "Cache PlayerControllerB lookups in collision/trigger handlers"); OptimizeStringAllocations = ((BaseUnityPlugin)this).Config.Bind<bool>("Strings", "OptimizeStringAllocations", true, "Use StringBuilder for string formatting to reduce allocations"); CacheRepeatedLookups = ((BaseUnityPlugin)this).Config.Bind<bool>("Caching", "CacheRepeatedLookups", true, "Cache NetworkObject lookups during enemy and scrap spawning"); } } public static class PluginInfo { public const string PLUGIN_GUID = "mrbub.lethaloptimizer"; public const string PLUGIN_NAME = "LethalOptimizer"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace LethalOptimizer.Patches { [HarmonyPatch] internal class CollisionCachePatches { private static readonly Dictionary<GameObject, PlayerControllerB> playerControllerCache = new Dictionary<GameObject, PlayerControllerB>(); public static PlayerControllerB GetCachedPlayerController(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return null; } if (!playerControllerCache.TryGetValue(gameObject, out var value)) { value = gameObject.GetComponent<PlayerControllerB>(); if ((Object)(object)value != (Object)null) { playerControllerCache[gameObject] = value; } } return value; } [HarmonyPatch(typeof(QuicksandTrigger), "OnTriggerStay")] [HarmonyPrefix] private static bool QuicksandTriggerStayPrefix(QuicksandTrigger __instance, Collider other) { try { if (__instance.movementHinderance < 1f) { return false; } PlayerControllerB cachedPlayerController = GetCachedPlayerController(((Component)other).gameObject); if ((Object)(object)cachedPlayerController != (Object)(object)GameNetworkManager.Instance.localPlayerController && (Object)(object)cachedPlayerController != (Object)null && (Object)(object)cachedPlayerController.underwaterCollider != (Object)(object)__instance) { cachedPlayerController.underwaterCollider = ((Component)__instance).gameObject.GetComponent<Collider>(); return false; } if (!__instance.sinkingLocalPlayer) { return false; } PlayerControllerB cachedPlayerController2 = GetCachedPlayerController(((Component)other).gameObject); if ((Object)(object)cachedPlayerController2 != (Object)(object)GameNetworkManager.Instance.localPlayerController) { return false; } if (cachedPlayerController2.isClimbingLadder || cachedPlayerController2.inSpecialInteractAnimation || StartOfRound.Instance.suckingPlayersOutOfShip) { return false; } if (__instance.isWater && !cachedPlayerController2.isUnderwater) { cachedPlayerController2.underwaterCollider = ((Component)__instance).gameObject.GetComponent<Collider>(); cachedPlayerController2.isUnderwater = true; } return false; } catch (Exception ex) { Plugin.Logger.LogError((object)("Error in QuicksandTriggerStay patch: " + ex.Message)); return true; } } [HarmonyPatch(typeof(QuicksandTrigger), "OnTriggerExit")] [HarmonyPrefix] private static bool QuicksandTriggerExitPrefix(QuicksandTrigger __instance, Collider other) { try { if (__instance.sinkingLocalPlayer) { if (!__instance.isWater && ((Component)other).gameObject.CompareTag("Player")) { PlayerControllerB cachedPlayerController = GetCachedPlayerController(((Component)other).gameObject); if ((Object)(object)cachedPlayerController == (Object)(object)GameNetworkManager.Instance.localPlayerController) { return false; } if ((Object)(object)cachedPlayerController != (Object)null) { cachedPlayerController.isUnderwater = false; } } __instance.sinkingLocalPlayer = false; return false; } return false; } catch (Exception ex) { Plugin.Logger.LogError((object)("Error in QuicksandTriggerExit patch: " + ex.Message)); return true; } } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPostfix] private static void ClearCacheOnLevelChange() { playerControllerCache.Clear(); } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] [HarmonyPostfix] private static void ClearCacheOnShipReset() { playerControllerCache.Clear(); } } [HarmonyPatch] internal class ComponentLookupPatches { private static readonly Dictionary<GameObject, NetworkObject> networkObjectCache = new Dictionary<GameObject, NetworkObject>(); public static NetworkObject GetCachedNetworkObject(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return null; } if (!networkObjectCache.TryGetValue(gameObject, out var value)) { value = gameObject.GetComponent<NetworkObject>(); if ((Object)(object)value != (Object)null) { networkObjectCache[gameObject] = value; } } return value; } public static NetworkObject GetCachedNetworkObjectInChildren(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return null; } NetworkObject cachedNetworkObject = GetCachedNetworkObject(gameObject); if ((Object)(object)cachedNetworkObject != (Object)null) { return cachedNetworkObject; } cachedNetworkObject = gameObject.GetComponentInChildren<NetworkObject>(); if ((Object)(object)cachedNetworkObject != (Object)null) { networkObjectCache[gameObject] = cachedNetworkObject; } return cachedNetworkObject; } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> OptimizeNetworkObjectLookups(IEnumerable<CodeInstruction> instructions) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(GameObject), "GetComponent", (Type[])null, new Type[1] { typeof(NetworkObject) }); MethodInfo methodInfo2 = AccessTools.Method(typeof(ComponentLookupPatches), "GetCachedNetworkObject", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Plugin.Logger.LogWarning((object)"Could not find methods for NetworkObject caching in SpawnScrapInLevel"); return list; } int num = 0; for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo)) { list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2); num++; } } if (num > 0) { Plugin.Logger.LogInfo((object)$"Replaced {num} GetComponent<NetworkObject> calls in SpawnScrapInLevel"); } return list; } [HarmonyPatch(typeof(RoundManager), "SpawnEnemyOnServer")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> OptimizeEnemySpawnLookups(IEnumerable<CodeInstruction> instructions) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(GameObject), "GetComponentInChildren", (Type[])null, new Type[1] { typeof(NetworkObject) }); MethodInfo methodInfo2 = AccessTools.Method(typeof(ComponentLookupPatches), "GetCachedNetworkObjectInChildren", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { Plugin.Logger.LogWarning((object)"Could not find methods for NetworkObject caching in SpawnEnemyOnServer"); return list; } int num = 0; for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo)) { list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo2); num++; } } if (num > 0) { Plugin.Logger.LogInfo((object)$"Replaced {num} GetComponentInChildren<NetworkObject> calls in SpawnEnemyOnServer"); } return list; } [HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")] [HarmonyPostfix] private static void ClearCacheOnRoundEnd() { networkObjectCache.Clear(); } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] [HarmonyPostfix] private static void ClearCacheOnShipReset() { networkObjectCache.Clear(); } } [HarmonyPatch] internal class DebugLogPatches { [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> RemoveDebugLogsFromSpawnScrap(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(Debug), "Log", new Type[1] { typeof(object) }, (Type[])null); if (methodInfo == null) { Plugin.Logger.LogWarning((object)"Could not find Debug.Log method, skipping transpiler"); return list; } int num = 0; for (int num2 = list.Count - 1; num2 >= 0; num2--) { if (CodeInstructionExtensions.Calls(list[num2], methodInfo)) { int num3 = 1; int num4 = num2 - 1; while (num4 >= 0 && num3 < 10 && (list[num4].opcode == OpCodes.Ldstr || list[num4].opcode == OpCodes.Ldarg || list[num4].opcode == OpCodes.Ldloc)) { num3++; num4--; } for (int i = 0; i < num3 && num2 - i >= 0; i++) { list[num2 - i].opcode = OpCodes.Nop; } num++; } } if (num > 0) { Plugin.Logger.LogInfo((object)$"Removed {num} Debug.Log calls from SpawnScrapInLevel"); } return list; } } [HarmonyPatch] internal class ShipItemOptimizationPatches { private static readonly HashSet<GrabbableObject> scrapCollectedSet = new HashSet<GrabbableObject>(); private static bool setInitialized = false; [HarmonyPatch(typeof(RoundManager), "CollectNewScrapForThisRound")] [HarmonyPrefix] private static bool CollectNewScrapPrefix(RoundManager __instance, GrabbableObject scrapObject) { try { if (!scrapObject.itemProperties.isScrap) { return false; } if (!setInitialized && __instance.scrapCollectedThisRound != null) { scrapCollectedSet.Clear(); foreach (GrabbableObject item in __instance.scrapCollectedThisRound) { if ((Object)(object)item != (Object)null) { scrapCollectedSet.Add(item); } } setInitialized = true; } if (scrapCollectedSet.Contains(scrapObject)) { return false; } if (scrapObject.scrapPersistedThroughRounds) { return false; } __instance.scrapCollectedThisRound.Add(scrapObject); scrapCollectedSet.Add(scrapObject); HUDManager.Instance.AddNewScrapFoundToDisplay(scrapObject); return false; } catch (Exception ex) { Plugin.Logger.LogError((object)("Error in CollectNewScrapForThisRound patch: " + ex.Message)); return true; } } [HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")] [HarmonyPostfix] private static void ClearScrapSetOnRoundEnd() { scrapCollectedSet.Clear(); setInitialized = false; } [HarmonyPatch(typeof(StartOfRound), "ResetShip")] [HarmonyPostfix] private static void ClearScrapSetOnShipReset() { scrapCollectedSet.Clear(); setInitialized = false; } } [HarmonyPatch] internal class StringOptimizationPatches { private static readonly StringBuilder stringBuilder = new StringBuilder(256); [HarmonyPatch(typeof(GrabbableObject), "SetScrapValue")] [HarmonyPrefix] private static bool OptimizeSetScrapValue(GrabbableObject __instance, int setValueTo) { try { __instance.scrapValue = setValueTo; ScanNodeProperties componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren == (Object)null) { return true; } stringBuilder.Clear(); stringBuilder.Append("Value: $"); stringBuilder.Append(setValueTo); componentInChildren.subText = stringBuilder.ToString(); componentInChildren.scrapValue = setValueTo; return false; } catch (Exception ex) { Plugin.Logger.LogError((object)("Error in SetScrapValue patch: " + ex.Message)); return true; } } } }