Decompiled source of Matty Fixes Experimental v1.1.39
BepInEx/plugins/Matty's Fixes.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.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Security; 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 HarmonyLib; using HarmonyLib.Public.Patching; using InjectionLibrary.Attributes; using JetBrains.Annotations; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLevelLoader; using LethalLib.Modules; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using MattyFixes.Dependency; using MattyFixes.Interfaces; using MattyFixes.Utils; using MattyFixes.Utils.IL; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; using MonoMod.RuntimeDetour; using MonoMod.Utils; using Unity.Netcode; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Bindings; using UnityEngine.Rendering; using VertexLibrary; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: RequiresInjections] [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("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [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("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("mattymatty")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.39")] [assembly: AssemblyInformationalVersion("1.1.39+00dae62a702e974a9308bf9c83b3a72349b56425")] [assembly: AssemblyProduct("Matty's Fixes")] [assembly: AssemblyTitle("Matty's Fixes - Plugin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.39.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] internal sealed class IsUnmanagedAttribute : Attribute { } [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 MattyFixes { [BepInPlugin("mattymatty.MattyFixes", "Matty's Fixes", "1.1.39")] [BepInDependency("com.github.lethalcompanymodding.vertexlibrary", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class MattyFixes : BaseUnityPlugin { internal static class PluginConfig { internal static class ReadableMeshes { internal static ConfigEntry<bool> Enabled; } internal static class Particles { internal enum LightningType { Vanilla, Fixed, Alternate } internal static ConfigEntry<LightningType> Lightning; internal static ConfigEntry<bool> FixFlies; } internal static class BadgeFixes { internal static ConfigEntry<bool> Enabled; } internal static class CupBoard { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> Tolerance; internal static ConfigEntry<float> Shift; } internal static class Radar { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> RemoveDeleted; internal static ConfigEntry<bool> RemoveOnShip; } internal static class ItemClipping { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> RotateOnSpawn; internal static ConfigEntry<float> VerticalOffset; internal static ConfigEntry<string> ManualOffsets; internal static readonly Dictionary<string, float> ManualOffsetMap = new Dictionary<string, float>(StringComparer.InvariantCultureIgnoreCase); internal static readonly Dictionary<Item, ItemRotationConfig> ItemRotations = new Dictionary<Item, ItemRotationConfig>(); } internal static class OutOfBounds { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> VerticalOffset; internal static ConfigEntry<bool> SpawnInFurniture; } internal static class AlternateLightingParticle { } internal static class Debug { internal static ConfigEntry<LogLevel> VerboseMeshes; internal static ConfigEntry<LogLevel> VerboseCupboard; internal static ConfigEntry<LogLevel> VerboseItems; } internal static void Init() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown ConfigFile config = ((BaseUnityPlugin)Instance).Config; ReadableMeshes.Enabled = config.Bind<bool>("ReadableMeshes", "enabled", true, "convert all meshes to readable at runtime"); Particles.Lightning = config.Bind<Particles.LightningType>("Particles", "fix_lightning", Particles.LightningType.Fixed, "change rendering of the Lightning particles:\r\n- Vanilla: no changes!\r\n- Fixed: show lightning particles as dev intended! \r\n- Alternate: particles will show in a sphere around the item"); Particles.FixFlies = config.Bind<bool>("Particles", "fix_flies", true, "show crawling bugs particles as dev intended! ( affects Ear, Hand and Thigh )"); BadgeFixes.Enabled = config.Bind<bool>("BadgeFixes", "enabled", true, "show correct level tag"); CupBoard.Enabled = config.Bind<bool>("CupBoard", "enabled", true, "prevent items inside or above the Storage Closet from falling to the ground"); CupBoard.Tolerance = config.Bind<float>("CupBoard", "tolerance", 0.05f, new ConfigDescription("how loosely \"close\" the items have to be to the top of the closet for them to count X/Z", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); CupBoard.Shift = config.Bind<float>("CupBoard", "shift", 0.1f, new ConfigDescription("how much move the items inside the closet on load ( only if ItemClippingFix disabled )", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); Radar.Enabled = config.Bind<bool>("Radar", "enabled", true, "remove orphan radar icons from deleted/collected scrap"); Radar.RemoveDeleted = config.Bind<bool>("Radar", "deleted_scrap", true, "remove orphan radar icons from deleted scrap ( company building )"); Radar.RemoveOnShip = config.Bind<bool>("Radar", "ship_loot", true, "remove orphan radar icons from scrap on the ship in a recently created game"); ItemClipping.Enabled = config.Bind<bool>("ItemClipping", "enabled", true, "fix rotation and height of various items when on the Ground"); ItemClipping.RotateOnSpawn = config.Bind<bool>("ItemClipping", "rotate_on_spawn", true, "fix rotation of newly spawned items"); ItemClipping.VerticalOffset = config.Bind<float>("ItemClipping", "vertical_offset", 0f, new ConfigDescription("additional y offset for items on the ground", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>())); ItemClipping.ManualOffsets = config.Bind<string>("ItemClipping", "manual_offsets", "", "y offset for items on the ground\nDictionary Format: '[key]:[value],[key2]:[value2]'\neg: `Vanilla/Ammo:0.0`"); OutOfBounds.Enabled = config.Bind<bool>("OutOfBounds", "enabled", true, "prevent items from falling below the ship"); OutOfBounds.VerticalOffset = config.Bind<float>("OutOfBounds", "vertical_offset", 0.01f, new ConfigDescription("vertical offset to apply to objects on load to prevent them from clipping into the floor", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 1f), Array.Empty<object>())); OutOfBounds.SpawnInFurniture = config.Bind<bool>("OutOfBounds", "spawn_in_furniture", true, "Fix items generating inside furniture ( eg: lamps inside the kitchen counter )"); Debug.VerboseMeshes = config.Bind<LogLevel>("Debug", "Mesh Verbosity Level", (LogLevel)0, "Print A LOT more logs about Meshes"); Debug.VerboseCupboard = config.Bind<LogLevel>("Debug", "Cupboard Verbosity Level", (LogLevel)0, "Print A LOT more logs about Cupboard detection"); Debug.VerboseItems = config.Bind<LogLevel>("Debug", "Item Verbosity Level", (LogLevel)0, "Print A LOT more logs about Cupboard detection"); string value = ItemClipping.ManualOffsets.Value; string[] array = value.Split(','); foreach (string text in array) { string[] array2 = text.Split(':'); if (array2.Length > 1) { string key = array2[0].Trim(); if (float.TryParse(array2[1], NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.InvariantInfo, out var result)) { ItemClipping.ManualOffsetMap.Add(key, result); } } } if (LethalConfigProxy.Enabled) { LethalConfigProxy.AddButton("Cleanup", "Clear old entries", "remove unused entries in the config file\n(IF RUN FROM MENU WILL DELETE ALL ITEM OFFSETS!!)", "Clean&Save", RemoveOrphans); LethalConfigProxy.AddConfig(ReadableMeshes.Enabled, requiresRestart: true); LethalConfigProxy.AddConfig<Particles.LightningType>(Particles.Lightning, requiresRestart: true); LethalConfigProxy.AddConfig(Particles.FixFlies, requiresRestart: true); LethalConfigProxy.AddConfig(BadgeFixes.Enabled, requiresRestart: true); LethalConfigProxy.AddConfig(CupBoard.Enabled); LethalConfigProxy.AddConfig(CupBoard.Tolerance); LethalConfigProxy.AddConfig(CupBoard.Shift); LethalConfigProxy.AddConfig(Radar.Enabled); LethalConfigProxy.AddConfig(Radar.RemoveDeleted); LethalConfigProxy.AddConfig(Radar.RemoveOnShip); LethalConfigProxy.AddConfig(ItemClipping.Enabled); LethalConfigProxy.AddConfig(ItemClipping.RotateOnSpawn); LethalConfigProxy.AddConfig(ItemClipping.VerticalOffset); LethalConfigProxy.AddConfig(ItemClipping.ManualOffsets, requiresRestart: true); LethalConfigProxy.AddConfig(OutOfBounds.Enabled, requiresRestart: true); LethalConfigProxy.AddConfig(OutOfBounds.VerticalOffset); LethalConfigProxy.AddConfig(OutOfBounds.SpawnInFurniture, requiresRestart: true); LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseMeshes, requiresRestart: false); LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseCupboard, requiresRestart: false); LethalConfigProxy.AddConfig<LogLevel>(Debug.VerboseItems, requiresRestart: false); } } internal static void RemoveOrphans() { ConfigFile config = ((BaseUnityPlugin)Instance).Config; PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null); dictionary.Clear(); config.Save(); } } internal readonly struct ItemRotationConfig { public Vector3 Original { get; } public ConfigEntry<string> Config { get; } public ItemRotationConfig(Vector3 original, ConfigEntry<string> config) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Original = original; Config = config; } } public const string GUID = "mattymatty.MattyFixes"; public const string NAME = "Matty's Fixes"; public const string VERSION = "1.1.39"; internal static ManualLogSource Log; private static int? _visibleLayerMask; internal static Harmony Harmony { get; private set; } internal static HashSet<Hook> Hooks { get; } = new HashSet<Hook>(); internal static MattyFixes Instance { get; private set; } public static int VisibleLayerMask { get { int valueOrDefault = _visibleLayerMask.GetValueOrDefault(); if (!_visibleLayerMask.HasValue) { valueOrDefault = LayerMask.GetMask(new string[13] { "Default", "Player", "Water", "Props", "Room", "InteractableObject", "Foliage", "PhysicsObject", "Enemies", "PlayerRagdoll", "MapHazards", "MiscLevelGeometry", "Terrain" }); _visibleLayerMask = valueOrDefault; } return _visibleLayerMask.Value; } } private void Awake() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = ((BaseUnityPlugin)this).Logger; try { if (LobbyCompatibilityChecker.Enabled) { LobbyCompatibilityChecker.Init(); } Log.LogInfo((object)"Initializing Configs"); PluginConfig.Init(); Log.LogInfo((object)"Patching Methods"); Harmony = new Harmony("mattymatty.MattyFixes"); Harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)"Matty's Fixes v1.1.39 Loaded!"); } catch (Exception ex) { Log.LogError((object)("Exception while initializing: \n" + ex)); } } internal static void VerboseMeshLog(LogType logLevel, Func<string> message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Invalid comparison between Unknown and I4 //IL_0099: 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: Invalid comparison between Unknown and I4 //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) LogLevel val; if ((int)logLevel <= 128) { if ((int)logLevel <= 8) { if ((int)logLevel != 2) { if ((int)logLevel != 4) { if ((int)logLevel != 8) { goto IL_00a6; } val = (LogLevel)4; } else { val = (LogLevel)2; } } else { val = (LogLevel)1; } goto IL_00a8; } if ((int)logLevel <= 32) { if ((int)logLevel == 16 || (int)logLevel == 32) { goto IL_0097; } } else if ((int)logLevel == 64 || (int)logLevel == 128) { goto IL_0097; } } else if ((int)logLevel <= 512) { if ((int)logLevel == 240) { goto IL_0097; } if ((int)logLevel == 256 || (int)logLevel == 512) { goto IL_009c; } } else if ((int)logLevel <= 2048) { if ((int)logLevel == 1024 || (int)logLevel == 2048) { goto IL_009c; } } else { if ((int)logLevel == 3840) { goto IL_009c; } if ((int)logLevel == 4094) { val = (LogLevel)63; goto IL_00a8; } } goto IL_00a6; IL_0097: val = (LogLevel)16; goto IL_00a8; IL_00a6: val = (LogLevel)0; goto IL_00a8; IL_009c: val = (LogLevel)32; goto IL_00a8; IL_00a8: LogLevel logLevel2 = val; VerboseMeshLog(logLevel2, message); } internal static void VerboseMeshLog(LogLevel logLevel, Func<string> message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((PluginConfig.Debug.VerboseMeshes.Value & logLevel) != 0) { Log.Log(logLevel, (object)message()); } } internal static void VerboseCupboardLog(LogLevel logLevel, Func<string> message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((PluginConfig.Debug.VerboseCupboard.Value & logLevel) != 0) { Log.Log(logLevel, (object)message()); } } internal static void VerboseItemsLog(LogLevel logLevel, Func<string> message) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((PluginConfig.Debug.VerboseItems.Value & logLevel) != 0) { Log.Log(logLevel, (object)message()); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "mattymatty.MattyFixes"; public const string PLUGIN_NAME = "Matty's Fixes"; public const string PLUGIN_VERSION = "1.1.39"; } } namespace MattyFixes.Utils { public static class ItemCategory { public enum ItemType { Unknown, Vanilla, Modded } private static readonly Regex ConfigFilterRegex = new Regex("[\\n\\t\\\\\\'\\[\\]]"); [NotNull] public static string GetPath(this Item item) { string mattyFixes_Path = ((IInjectedItem)item).MattyFixes_Path; if (mattyFixes_Path != null) { return mattyFixes_Path; } ItemType itemType = ItemType.Unknown; mattyFixes_Path = item.ComputePath("Unknown"); if (DawnLibProxy.Enabled) { string path; ItemType itemType2 = DawnLibProxy.DefineItem(item, out path); if (itemType <= itemType2) { itemType = itemType2; mattyFixes_Path = path; } } ((IInjectedItem)item).MattyFixes_ItemType = itemType; ((IInjectedItem)item).MattyFixes_Path = mattyFixes_Path; return mattyFixes_Path; } public static string ComputePath(this Item item, [NotNull] string library, [NotNull] params string[] path) { List<string> list = new List<string>(2 + path.Length); list.Add(library); list.AddRange(path); list.Add(item.itemName ?? ((Object)item).name); return string.Join('/', list.Select((string p) => string.Join("_", p.Split(Path.GetInvalidPathChars(), StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.')).ToArray()).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); } public static string SanitizeForConfig(string input) { return ConfigFilterRegex.Replace(input, "").Trim(); } } public static class NgoUtils { private static readonly MethodInfo BeginSendClientRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendClientRpc", (Type[])null, (Type[])null); private static readonly MethodInfo BeginSendServerRpc = AccessTools.Method(typeof(NetworkBehaviour), "__beginSendServerRpc", (Type[])null, (Type[])null); private static readonly __RpcExecStage ClientRpcStage; private static readonly __RpcExecStage ServerRpcStage; public static bool IsRPCClientStage(this NetworkBehaviour self) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = self.NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return false; } if (self.__rpc_exec_stage != ClientRpcStage || (!networkManager.IsClient && !networkManager.IsHost)) { return false; } return true; } public static bool IsRPCServerStage(this NetworkBehaviour self) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = self.NetworkManager; if ((Object)(object)networkManager == (Object)null || !networkManager.IsListening) { return false; } if (self.__rpc_exec_stage != ServerRpcStage || (!networkManager.IsServer && !networkManager.IsHost)) { return false; } return true; } internal static bool TryGetRpcID(this MethodInfo methodInfo, out uint rpcID) { //IL_002c: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Collection<Instruction> instructions = PatchManager.GetMethodPatcher((MethodBase)methodInfo).CopyOriginal().Definition.Body.Instructions; rpcID = 0u; for (int i = 0; i < instructions.Count; i++) { if (instructions[i].OpCode == OpCodes.Ldc_I4 && instructions[i - 1].OpCode == OpCodes.Ldarg_0) { rpcID = (uint)(int)instructions[i].Operand; } if (!(instructions[i].OpCode != OpCodes.Call)) { object operand = instructions[i].Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && (Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendClientRpc) || Extensions.Is((MemberReference)(object)val, (MemberInfo)BeginSendServerRpc))) { MattyFixes.Log.LogDebug((object)$"Rpc Id found for {methodInfo.Name}: {rpcID}U"); return true; } } } MattyFixes.Log.LogFatal((object)("Cannot find Rpc ID for " + methodInfo.Name)); return false; } static NgoUtils() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) string unityVersion = Application.unityVersion; __RpcExecStage clientRpcStage = ((!(unityVersion == "2022.3.9f1")) ? ((__RpcExecStage)1) : ((__RpcExecStage)2)); ClientRpcStage = clientRpcStage; string unityVersion2 = Application.unityVersion; clientRpcStage = ((!(unityVersion2 == "2022.3.9f1")) ? ((__RpcExecStage)1) : ((__RpcExecStage)1)); ServerRpcStage = clientRpcStage; } } public static class ReflectionUtils { internal static Delegate FastGetter([NotNull("ArgumentNullException")] this FieldInfo field) { if ((object)field == null) { throw new ArgumentNullException("field"); } string name = field.ReflectedType.FullName + ".get_" + field.Name; DynamicMethod dynamicMethod = new DynamicMethod(name, field.FieldType, new Type[1] { field.DeclaringType }, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (field.IsStatic) { iLGenerator.Emit(OpCodes.Ldsfld, field); } else { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, field); } iLGenerator.Emit(OpCodes.Ret); if (field.IsStatic) { return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.FieldType)); } return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.DeclaringType, field.FieldType)); } internal static Delegate FastSetter([NotNull("ArgumentNullException")] this FieldInfo field) { if ((object)field == null) { throw new ArgumentNullException("field"); } string name = field.ReflectedType.FullName + ".get_" + field.Name; DynamicMethod dynamicMethod = new DynamicMethod(name, field.FieldType, new Type[2] { field.DeclaringType, field.FieldType }, restrictedSkipVisibility: true); ILGenerator iLGenerator = dynamicMethod.GetILGenerator(); if (field.IsStatic) { iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Stsfld, field); } else { iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Stfld, field); } iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Ret); if (field.IsStatic) { return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.FieldType, field.FieldType)); } return dynamicMethod.CreateDelegate(Expression.GetFuncType(field.DeclaringType, field.FieldType, field.FieldType)); } } } namespace MattyFixes.Utils.IL { internal class ILInjector { [CompilerGenerated] private sealed class <GetRelativeInstructions>d__34 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; public ILInjector <>4__this; private int offset; public int <>3__offset; private int size; public int <>3__size; private int <i>5__2; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRelativeInstructions>d__34(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; ILInjector iLInjector = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < size) { <>2__current = iLInjector.instructions[iLInjector.index + offset + <i>5__2]; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <GetRelativeInstructions>d__34 <GetRelativeInstructions>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRelativeInstructions>d__ = this; } else { <GetRelativeInstructions>d__ = new <GetRelativeInstructions>d__34(0) { <>4__this = <>4__this }; } <GetRelativeInstructions>d__.offset = <>3__offset; <GetRelativeInstructions>d__.size = <>3__size; return <GetRelativeInstructions>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } private const string INVALID = "Injector is invalid"; private List<CodeInstruction> instructions = instructions.ToList(); private ILGenerator generator; private int index; private int matchEnd; public int Index { get { return index; } set { index = value; } } public bool IsValid { get { if (instructions != null) { return IsIndexValid(index); } return false; } } public CodeInstruction Instruction { get { if (!IsIndexInRange(index)) { return null; } return instructions[index]; } set { if (!IsIndexInRange(index)) { throw new InvalidOperationException($"Current index {index} is out of range of instruction count {instructions.Count}"); } instructions[index] = value; } } public CodeInstruction LastMatchedInstruction { get { int num = matchEnd - 1; if (!IsIndexInRange(num)) { return null; } return instructions[num]; } set { int num = matchEnd - 1; if (!IsIndexInRange(num)) { throw new InvalidOperationException($"Last matched index {index} is out of range of instruction count {instructions.Count}"); } instructions[num] = value; } } public ICollection<CodeInstruction> Instructions => instructions.AsReadOnly(); public ILInjector(IEnumerable<CodeInstruction> instructions, ILGenerator generator = null) { this.generator = generator; matchEnd = -1; base..ctor(); } public ILInjector GoToStart() { matchEnd = index; index = 0; return this; } public ILInjector GoToEnd() { matchEnd = index; index = instructions.Count; return this; } public ILInjector Forward(int offset) { if (!IsValid) { return this; } matchEnd = index; index = Math.Clamp(index + offset, -1, instructions.Count); return this; } public ILInjector Back(int offset) { return Forward(-offset); } private void MarkInvalid() { index = -1; matchEnd = -1; } private void Search(bool forward, ILMatcher[] predicates) { if (!IsValid) { return; } int num = 1; if (!forward) { num = -1; index--; } while (forward ? (index < instructions.Count) : (index >= 0)) { if (forward && index + predicates.Length > instructions.Count) { index = instructions.Count; break; } int i; for (i = 0; i < predicates.Length && predicates[i].Matches(instructions[index + i]); i++) { } if (i == predicates.Length) { matchEnd = index + i; return; } index += num; } MarkInvalid(); } public ILInjector Find(params ILMatcher[] predicates) { Search(forward: true, predicates); return this; } public ILInjector ReverseFind(params ILMatcher[] predicates) { Search(forward: false, predicates); return this; } public ILInjector GoToPush(int popIndex) { if (!IsValid) { return this; } matchEnd = index; index--; int num = 0; while (index >= 0) { CodeInstruction instruction = instructions[index]; num += instruction.PushCount(); num -= instruction.PopCount(); if (num >= popIndex) { return this; } index--; } return this; } public ILInjector SkipBranch() { if (Instruction == null) { return this; } if (!(Instruction.operand is Label label)) { throw new InvalidOperationException($"Current instruction is not a branch: {Instruction}"); } return FindLabel(label); } public ILInjector FindLabel(Label label) { if (label == default(Label)) { return this; } matchEnd = index; for (index = 0; index < instructions.Count; index++) { if (instructions[index].labels.Contains(label)) { return this; } } MarkInvalid(); return this; } public ILInjector GoToMatchEnd() { index = matchEnd; return this; } public ILInjector GoToLastMatchedInstruction() { if (!IsIndexValid(matchEnd)) { return this; } index = matchEnd - 1; return this; } private bool IsIndexValid(int index) { return index != -1; } private bool IsIndexInRange(int index) { if (index >= 0) { return index < instructions.Count; } return false; } public CodeInstruction GetRelativeInstruction(int offset) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would read out of bounds at index {num}"); } return instructions[num]; } public ILInjector SetRelativeInstruction(int offset, CodeInstruction instruction) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } int num = index + offset; if (!IsIndexInRange(num)) { throw new IndexOutOfRangeException($"Offset {offset} would write out of bounds at index {num}"); } instructions[num] = instruction; return this; } [IteratorStateMachine(typeof(<GetRelativeInstructions>d__34))] public IEnumerable<CodeInstruction> GetRelativeInstructions(int offset, int size) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRelativeInstructions>d__34(-2) { <>4__this = this, <>3__offset = offset, <>3__size = size }; } public IEnumerable<CodeInstruction> GetRelativeInstructions(int size) { return GetRelativeInstructions(0, size); } private void GetLastMatchRangeAbsolute(out int start, out int end) { start = index; end = matchEnd; if (start > end) { int num = end; int num2 = start; start = num; end = num2; } } private void GetLastMatchRange(out int start, out int size) { GetLastMatchRangeAbsolute(out start, out var end); if (start < 0 || start >= instructions.Count) { throw new InvalidOperationException($"Last match range starts at invalid index {start}"); } if (end < 0 || end > instructions.Count) { throw new InvalidOperationException($"Last match range ends at invalid index {end}"); } size = end - start; } public List<CodeInstruction> GetLastMatch() { GetLastMatchRange(out var start, out var size); return instructions.GetRange(start, size); } public ILInjector DefineLabel(out Label label) { if (generator == null) { throw new InvalidOperationException("No ILGenerator was provided"); } label = generator.DefineLabel(); return this; } public ILInjector AddLabel(out Label label) { DefineLabel(out label); return AddLabel(label); } public ILInjector AddLabel(Label label) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Instruction = new CodeInstruction(Instruction); Instruction.labels.Add(label); return this; } public ILInjector InsertInPlace(params CodeInstruction[] instructions) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } this.instructions.InsertRange(index, instructions); if (matchEnd >= index) { matchEnd += instructions.Length; } return this; } public ILInjector Insert(params CodeInstruction[] instructions) { InsertInPlace(instructions); index += instructions.Length; return this; } public ILInjector InsertInPlaceAfterBranch(params CodeInstruction[] instructions) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } List<Label> labels = Instruction.labels; Instruction = new CodeInstruction(Instruction); Instruction.labels.Clear(); this.instructions.InsertRange(index, instructions); Instruction.labels.AddRange(labels); if (matchEnd >= index) { matchEnd += instructions.Length; } return this; } public ILInjector InsertAfterBranch(params CodeInstruction[] instructions) { InsertInPlaceAfterBranch(instructions); index += instructions.Length; return this; } public ILInjector RemoveAllPreviousInstructions() { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } instructions.RemoveRange(0, index); matchEnd -= index; if (matchEnd < 0) { matchEnd = 0; } index = 0; return this; } public ILInjector Remove(int count = 1) { if (!IsValid) { throw new InvalidOperationException("Injector is invalid"); } instructions.RemoveRange(index, count); if (matchEnd > index) { matchEnd = Math.Max(index, matchEnd - count); } return this; } public ILInjector RemoveLastMatch() { GetLastMatchRange(out var start, out var size); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); index = start; matchEnd = start; instructions[start].labels.AddRange(labels); return this; } public ILInjector ReplaceLastMatch(params CodeInstruction[] replacementInstructions) { if (replacementInstructions.Length == 0) { throw new ArgumentException("Cannot replace a match with an empty array."); } GetLastMatchRange(out var start, out var size); List<Label> labels = instructions[start].labels; instructions.RemoveRange(start, size); instructions.InsertRange(start, replacementInstructions); index = start; matchEnd = start + replacementInstructions.Length; instructions[start].labels.AddRange(labels); return this; } public List<CodeInstruction> ReleaseInstructions() { List<CodeInstruction> result = instructions; instructions = null; return result; } public ILInjector PrintContext(int context, string header = "") { if (!IsValid) { throw new InvalidOperationException("Injector is invalid (" + header + ")"); } StringBuilder stringBuilder = new StringBuilder(header); if (header.Length > 0) { stringBuilder.Append(':'); } stringBuilder.AppendLine(); GetLastMatchRangeAbsolute(out var start, out var end); int num = Math.Min(end + 1 + context, instructions.Count); for (int i = Math.Max(start - context, 0); i < num; i++) { if (end == -1 && i == index) { stringBuilder.Append("╶> "); } else { if (i >= start && i < end) { stringBuilder.Append("│"); } else { stringBuilder.Append(" "); } if (i == index) { stringBuilder.Append("╶> "); } else { stringBuilder.Append(" "); } } stringBuilder.AppendLine($"{i}: {instructions[i]}"); } MattyFixes.Log.LogFatal((object)stringBuilder); return this; } public ILInjector PrintContext(string header = "") { return PrintContext(4, header); } } internal interface ILMatcher { bool Matches(CodeInstruction instruction); ILMatcher CaptureAs(out CodeInstruction variable) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown variable = new CodeInstruction(OpCodes.Nop, (object)null); return new InstructionCapturingMatcher(this, variable); } unsafe ILMatcher CaptureOperandAs<T>(out T operand) where T : unmanaged { operand = default(T); fixed (T* operand2 = &operand) { return new OperandCapturingMatcher<T>(this, operand2); } } static ILMatcher Not(ILMatcher matcher) { return new NotMatcher(matcher); } static ILMatcher Opcode(OpCode opcode) { return new OpcodeMatcher(opcode); } static ILMatcher Opcodes(params OpCode[] opcodes) { return new OpcodesMatcher(opcodes); } static ILMatcher OpcodeOperand(OpCode opcode, object operand) { return new OpcodeOperandMatcher(opcode, operand); } static ILMatcher Instruction(CodeInstruction instruction) { return new InstructionMatcher(instruction); } static ILMatcher Ldarg(int? arg = null) { return new LdargMatcher(arg); } static ILMatcher Ldloc(int? loc = null) { return new LdlocMatcher(loc); } static ILMatcher Stloc(int? loc = null) { return new StlocMatcher(loc); } static ILMatcher Ldc(int? value = null) { return new LdcI32Matcher(value); } static ILMatcher Branch() { return new BranchMatcher(); } static ILMatcher Ldfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Ldfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldfld, field); } static ILMatcher Ldsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Ldsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Ldsfld, field); } static ILMatcher Stfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Stfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stfld, field); } static ILMatcher Stsfld(FieldInfo field, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (field == null) { MattyFixes.Log.LogWarning((object)$"Field passed to ILMatcher.Stsfld() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return new OpcodeOperandMatcher(OpCodes.Stsfld, field); } static ILMatcher Callvirt(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { MattyFixes.Log.LogWarning((object)$"Method passed to ILMatcher.Callvirt() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Callvirt, method); } static ILMatcher Call(MethodBase method, [CallerMemberName] string callerName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) { if (method == null) { MattyFixes.Log.LogWarning((object)$"Method passed to ILMatcher.Call() was null at {sourceFilePath}#{sourceLineNumber} ({callerName})"); } return OpcodeOperand(OpCodes.Call, method); } static ILMatcher Predicate(Func<CodeInstruction, bool> predicate) { return new PredicateMatcher(predicate); } static ILMatcher Predicate(Func<FieldInfo, bool> predicate) { return new PredicateMatcher((CodeInstruction insn) => insn.operand is FieldInfo arg && predicate(arg)); } } internal class NotMatcher : ILMatcher { private readonly ILMatcher matcher; public NotMatcher(ILMatcher matcher) { this.matcher = matcher; base..ctor(); } public bool Matches(CodeInstruction instruction) { return !matcher.Matches(instruction); } } internal class OpcodeMatcher : ILMatcher { private readonly OpCode opcode; public OpcodeMatcher(OpCode opcode) { this.opcode = opcode; base..ctor(); } public bool Matches(CodeInstruction instruction) { return instruction.opcode == opcode; } } internal class OpcodesMatcher : ILMatcher { private readonly OpCode[] opcodes; public OpcodesMatcher(OpCode[] opcodes) { this.opcodes = opcodes; base..ctor(); } public bool Matches(CodeInstruction instruction) { return opcodes.Contains(instruction.opcode); } } internal class OpcodeOperandMatcher : ILMatcher { private readonly OpCode opcode; private readonly object operand; public OpcodeOperandMatcher(OpCode opcode, object operand) { this.opcode = opcode; this.operand = operand; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (instruction.opcode == opcode) { return instruction.operand == operand; } return false; } } internal class InstructionMatcher : ILMatcher { private readonly OpCode opcode = instruction.opcode; private readonly object operand = instruction.operand; private readonly Label[] labels = instruction.labels.ToArray(); public InstructionMatcher(CodeInstruction instruction) { } public bool Matches(CodeInstruction instruction) { if (instruction.opcode != opcode) { return false; } if (instruction.operand != operand) { return false; } if (instruction.labels.Count != labels.Length) { return false; } for (int i = 0; i < labels.Length; i++) { if (labels[i] != instruction.labels[i]) { return false; } } return true; } } internal class LdargMatcher : ILMatcher { private readonly int? arg; public LdargMatcher(int? arg) { this.arg = arg; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!arg.HasValue) { return instruction.GetLdargIndex().HasValue; } return instruction.GetLdargIndex() == arg; } } internal class LdlocMatcher : ILMatcher { private readonly int? loc; public LdlocMatcher(int? loc) { this.loc = loc; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!loc.HasValue) { return instruction.GetLdlocIndex().HasValue; } return instruction.GetLdlocIndex() == loc; } } internal class StlocMatcher : ILMatcher { private readonly int? loc; public StlocMatcher(int? loc) { this.loc = loc; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!loc.HasValue) { return instruction.GetStlocIndex().HasValue; } return instruction.GetStlocIndex() == loc; } } internal class LdcI32Matcher : ILMatcher { private readonly int? value; public LdcI32Matcher(int? value) { this.value = value; base..ctor(); } public bool Matches(CodeInstruction instruction) { if (!value.HasValue) { return instruction.GetLdcI32().HasValue; } return instruction.GetLdcI32() == value; } } internal class BranchMatcher : ILMatcher { public bool Matches(CodeInstruction instruction) { Label? label = default(Label?); return CodeInstructionExtensions.Branches(instruction, ref label); } } internal class PredicateMatcher : ILMatcher { private readonly Func<CodeInstruction, bool> predicate; public PredicateMatcher(Func<CodeInstruction, bool> predicate) { this.predicate = predicate; base..ctor(); } public bool Matches(CodeInstruction instruction) { return predicate(instruction); } } internal class InstructionCapturingMatcher : ILMatcher { private readonly ILMatcher matcher; private readonly CodeInstruction variable; public InstructionCapturingMatcher(ILMatcher matcher, CodeInstruction variable) { this.matcher = matcher; this.variable = variable; base..ctor(); } public bool Matches(CodeInstruction instruction) { bool flag = matcher.Matches(instruction); if (flag) { variable.opcode = instruction.opcode; variable.operand = instruction.operand; variable.blocks = instruction.blocks.ToList(); variable.labels = instruction.labels.ToList(); } return flag; } } internal class OperandCapturingMatcher<T> : ILMatcher where T : unmanaged { private readonly ILMatcher matcher; private unsafe readonly T* operand; public unsafe OperandCapturingMatcher(ILMatcher matcher, T* operand) { this.matcher = matcher; this.operand = operand; base..ctor(); } public unsafe bool Matches(CodeInstruction instruction) { bool flag = matcher.Matches(instruction); if (flag) { *operand = (T)instruction.operand; } return flag; } } internal static class InstructionUtilities { public static CodeInstruction MakeLdarg(int index) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (index < 256) { return (CodeInstruction)(index switch { 0 => (object)new CodeInstruction(OpCodes.Ldarg_0, (object)null), 1 => (object)new CodeInstruction(OpCodes.Ldarg_1, (object)null), 2 => (object)new CodeInstruction(OpCodes.Ldarg_2, (object)null), 3 => (object)new CodeInstruction(OpCodes.Ldarg_3, (object)null), _ => (object)new CodeInstruction(OpCodes.Ldarg_S, (object)index), }); } return new CodeInstruction(OpCodes.Ldarg, (object)index); } public static int PopCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj) { MethodBase methodBase = (MethodBase)instruction.operand; int num = methodBase.GetParameters().Length; if (!methodBase.IsStatic) { num++; } return num; } if (instruction.opcode == OpCodes.Ret) { return 1; } return instruction.opcode.StackBehaviourPop switch { StackBehaviour.Pop0 => 0, StackBehaviour.Pop1 => 1, StackBehaviour.Pop1_pop1 => 2, StackBehaviour.Popi => 1, StackBehaviour.Popi_pop1 => 2, StackBehaviour.Popi_popi => 2, StackBehaviour.Popi_popi8 => 2, StackBehaviour.Popi_popi_popi => 3, StackBehaviour.Popi_popr4 => 2, StackBehaviour.Popi_popr8 => 2, StackBehaviour.Popref => 1, StackBehaviour.Popref_pop1 => 2, StackBehaviour.Popref_popi => 2, StackBehaviour.Popref_popi_popi => 3, StackBehaviour.Popref_popi_popi8 => 3, StackBehaviour.Popref_popi_popr4 => 3, StackBehaviour.Popref_popi_popr8 => 3, StackBehaviour.Popref_popi_popref => 3, StackBehaviour.Varpop => throw new NotImplementedException($"Variable pop on non-call instruction '{instruction}'"), StackBehaviour.Popref_popi_pop1 => 3, _ => throw new NotSupportedException($"StackBehaviourPop of {instruction.opcode.StackBehaviourPop} was not a pop for instruction '{instruction}'"), }; } public static int PushCount(this CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt || instruction.opcode == OpCodes.Newobj) { if (instruction.operand is MethodInfo methodInfo && methodInfo.ReturnType == typeof(void)) { return 0; } return 1; } return instruction.opcode.StackBehaviourPush switch { StackBehaviour.Push0 => 0, StackBehaviour.Push1 => 1, StackBehaviour.Push1_push1 => 2, StackBehaviour.Pushi => 1, StackBehaviour.Pushi8 => 1, StackBehaviour.Pushr4 => 1, StackBehaviour.Pushr8 => 1, StackBehaviour.Pushref => 1, StackBehaviour.Varpush => throw new NotImplementedException($"Variable push on non-call instruction '{instruction}'"), _ => throw new NotSupportedException($"StackBehaviourPush of {instruction.opcode.StackBehaviourPush} was not a push for instruction '{instruction}'"), }; } public static int? GetLdargIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldarg_0) { return 0; } if (opcode == OpCodes.Ldarg_1) { return 1; } if (opcode == OpCodes.Ldarg_2) { return 2; } if (opcode == OpCodes.Ldarg_3) { return 3; } if (opcode == OpCodes.Ldarg || opcode == OpCodes.Ldarg_S) { return instruction.operand as int?; } return null; } public static int? GetLdlocIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldloc_0) { return 0; } if (opcode == OpCodes.Ldloc_1) { return 1; } if (opcode == OpCodes.Ldloc_2) { return 2; } if (opcode == OpCodes.Ldloc_3) { return 3; } if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S) { return (instruction.operand as LocalBuilder)?.LocalIndex; } return null; } public static int? GetStlocIndex(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Stloc_0) { return 0; } if (opcode == OpCodes.Stloc_1) { return 1; } if (opcode == OpCodes.Stloc_2) { return 2; } if (opcode == OpCodes.Stloc_3) { return 3; } if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S) { return (instruction.operand as LocalBuilder)?.LocalIndex; } return null; } public static CodeInstruction LdlocToStloc(this CodeInstruction instruction) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldloc_0) { return new CodeInstruction(OpCodes.Stloc_0, (object)null); } if (opcode == OpCodes.Ldloc_1) { return new CodeInstruction(OpCodes.Stloc_1, (object)null); } if (opcode == OpCodes.Ldloc_2) { return new CodeInstruction(OpCodes.Stloc_2, (object)null); } if (opcode == OpCodes.Ldloc_3) { return new CodeInstruction(OpCodes.Stloc_3, (object)null); } if (opcode == OpCodes.Ldloc || opcode == OpCodes.Ldloc_S) { return new CodeInstruction(OpCodes.Stloc, instruction.operand); } return null; } public static CodeInstruction StlocToLdloc(this CodeInstruction instruction) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown OpCode opcode = instruction.opcode; if (opcode == OpCodes.Stloc_0) { return new CodeInstruction(OpCodes.Ldloc_0, (object)null); } if (opcode == OpCodes.Stloc_1) { return new CodeInstruction(OpCodes.Ldloc_1, (object)null); } if (opcode == OpCodes.Stloc_2) { return new CodeInstruction(OpCodes.Ldloc_2, (object)null); } if (opcode == OpCodes.Stloc_3) { return new CodeInstruction(OpCodes.Ldloc_3, (object)null); } if (opcode == OpCodes.Stloc || opcode == OpCodes.Stloc_S) { return new CodeInstruction(OpCodes.Ldloc, instruction.operand); } return null; } public static int? GetLdcI32(this CodeInstruction instruction) { OpCode opcode = instruction.opcode; if (opcode == OpCodes.Ldc_I4_M1) { return -1; } if (opcode == OpCodes.Ldc_I4_0) { return 0; } if (opcode == OpCodes.Ldc_I4_1) { return 1; } if (opcode == OpCodes.Ldc_I4_2) { return 2; } if (opcode == OpCodes.Ldc_I4_3) { return 3; } if (opcode == OpCodes.Ldc_I4_4) { return 4; } if (opcode == OpCodes.Ldc_I4_5) { return 5; } if (opcode == OpCodes.Ldc_I4_6) { return 6; } if (opcode == OpCodes.Ldc_I4_7) { return 7; } if (opcode == OpCodes.Ldc_I4_8) { return 8; } if (opcode == OpCodes.Ldc_I4_S) { return instruction.operand as sbyte?; } if (opcode == OpCodes.Ldc_I4) { return instruction.operand as int?; } return null; } } public static class ReflectionExtensions { public static MethodInfo GetGenericMethod(this Type type, string name, Type[] parameters, Type[] genericArgs) { MethodInfo[] methods = type.GetMethods(); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { if (!(methodInfo.Name != name) && methodInfo.IsGenericMethodDefinition) { return methodInfo.MakeGenericMethod(genericArgs); } } return null; } } } namespace MattyFixes.Patches { [HarmonyPatch] internal class CupBoardFix { internal struct ClosetHolder { public readonly UnlockableItem Unlockable; public readonly GameObject gameObject; public readonly List<ShelfHolder> Shelves; public readonly Collider Collider; public bool IsInitialized; public ClosetHolder() { IsInitialized = false; Unlockable = StartOfRound.Instance.unlockablesList.unlockables.Find((UnlockableItem u) => u.unlockableName == "Cupboard"); gameObject = GameObject.Find("/Environment/HangarShip/StorageCloset"); Collider = gameObject.GetComponent<Collider>(); Shelves = gameObject.GetComponentsInChildren<PlaceableObjectsSurface>().Select(delegate(PlaceableObjectsSurface s) { ShelfHolder result = default(ShelfHolder); result.Shelf = s; result.Collider = ((Component)s).GetComponent<Collider>(); return result; }).ToList(); } } internal struct ShelfHolder { public PlaceableObjectsSurface Shelf; public Collider Collider; } private static ClosetHolder? _closet; internal static ClosetHolder Closet { get { ClosetHolder valueOrDefault = _closet.GetValueOrDefault(); if (!_closet.HasValue) { valueOrDefault = new ClosetHolder(); _closet = valueOrDefault; } return _closet.Value; } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "OnLocalDisconnect")] [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] private static void ResetOnDisconnect() { _closet = null; } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SyncShipUnlockablesClientRpc")] private static void AfterCupboardSync(StartOfRound __instance) { if (!((NetworkBehaviour)(object)__instance).IsRPCClientStage() || ((NetworkBehaviour)__instance).IsServer) { return; } ClosetHolder closet = Closet; if (closet.IsInitialized) { MattyFixes.VerboseCupboardLog((LogLevel)4, () => "SyncShipUnlockablesClientRpc Cupboard Triggered but was already Initialized!"); return; } closet.IsInitialized = true; if (closet.Unlockable.inStorage) { return; } closet.gameObject.GetComponent<AutoParentToShip>().MoveToOffset(); Physics.SyncTransforms(); GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject item in source.Where((GrabbableObject g) => g.isInShipRoom)) { float offset = 0f; if (item.hasHitGround) { offset = item.itemProperties.verticalOffset; } ShelfCheck(item, offset); } } [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyPatch(typeof(StartOfRound), "LoadShipGrabbableItems")] private static void OnServerSpawn(GrabbableObject __instance) { ClosetHolder closet = Closet; if (closet.IsInitialized) { MattyFixes.VerboseCupboardLog((LogLevel)4, () => "LoadShipGrabbableItems Cupboard Triggered but was already Initialized!"); return; } closet.IsInitialized = true; if (closet.Unlockable.inStorage) { return; } closet.gameObject.GetComponent<AutoParentToShip>().MoveToOffset(); Physics.SyncTransforms(); GrabbableObject[] source = Object.FindObjectsOfType<GrabbableObject>(); foreach (GrabbableObject item in source.Where((GrabbableObject g) => g.isInShipRoom)) { ShelfCheck(item); } } private static void ShelfCheck(GrabbableObject grabbable, float offset = 0f) { //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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) MattyFixes.VerboseCupboardLog((LogLevel)16, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Cupboard Triggered!"); if (grabbable is ClipboardItem || (grabbable is PhysicsProp && grabbable.itemProperties.itemName == "Sticky note")) { return; } float value = MattyFixes.PluginConfig.CupBoard.Tolerance.Value; float num = value * value; try { Vector3 pos = ((Component)grabbable).transform.position + Vector3.down * offset; MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Item pos {pos}!"); ClosetHolder closet = Closet; float distance = float.MaxValue; PlaceableObjectsSurface val = null; Vector3? closest = null; MattyFixes.VerboseCupboardLog((LogLevel)32, delegate { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) string itemName = grabbable.itemProperties.itemName; object arg2 = ((NetworkBehaviour)grabbable).NetworkObjectId; Bounds bounds2 = closet.Collider.bounds; return $"{itemName}({arg2}) - Cupboard pos {((Bounds)(ref bounds2)).min}!"; }); Collider collider = closet.Collider; float y = pos.y; Bounds bounds = collider.bounds; if (y < ((Bounds)(ref bounds)).max.y) { bounds = collider.bounds; if (((Bounds)(ref bounds)).SqrDistance(pos) <= num) { foreach (ShelfHolder shelf in closet.Shelves) { Vector3 val2 = shelf.Collider.ClosestPointOnBounds(pos); float tmp = pos.y - val2.y; MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Shelve is {tmp} away!"); if (tmp >= 0f && tmp < distance) { val = shelf.Shelf; distance = tmp; closest = val2; } } MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Chosen Shelve is {distance} away!"); MattyFixes.VerboseCupboardLog((LogLevel)32, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - With hitpoint at {closest}!"); } } Transform transform = ((Component)grabbable).transform; if ((Object)(object)val != (Object)null) { Vector3 newPos = closest.Value + Vector3.up * grabbable.itemProperties.verticalOffset; transform.parent = closet.gameObject.transform; transform.position = newPos; grabbable.targetFloorPosition = transform.localPosition; MattyFixes.VerboseCupboardLog((LogLevel)16, () => $"{grabbable.itemProperties.itemName}({((NetworkBehaviour)grabbable).NetworkObjectId}) - Pos on shelf {newPos}!"); } } catch (Exception arg) { MattyFixes.Log.LogError((object)$"Exception while checking for Cupboard {arg}"); } } } [HarmonyPatch] internal class GrabbableStartPatch { [CompilerGenerated] private sealed class <>c__DisplayClass1_0 { public Animator[] animators; internal bool <ProcessGrabbable>b__0() { return animators.All(delegate(Animator a) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)a) && !Mathf.Approximately(a.speed, 0f)) { AnimatorStateInfo currentAnimatorStateInfo = a.GetCurrentAnimatorStateInfo(0); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f; } return true; }); } } [CompilerGenerated] private sealed class <ProcessGrabbable>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GrabbableObject grabbable; public bool updatePosition; private Item <itemType>5__2; private string <key>5__3; private float <oldOffset>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ProcessGrabbable>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <itemType>5__2 = null; <key>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>c__DisplayClass1_0 CS$<>8__locals0 = new <>c__DisplayClass1_0(); <itemType>5__2 = grabbable.itemProperties; <key>5__3 = <itemType>5__2.GetPath(); <oldOffset>5__4 = <itemType>5__2.verticalOffset; CS$<>8__locals0.animators = ((Component)grabbable).GetComponentsInChildren<Animator>(); <>2__current = (object)new WaitUntil((Func<bool>)(() => CS$<>8__locals0.animators.All(delegate(Animator a) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)a) && !Mathf.Approximately(a.speed, 0f)) { AnimatorStateInfo currentAnimatorStateInfo = a.GetCurrentAnimatorStateInfo(0); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f; } return true; }))); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (!((IInjectedItem)<itemType>5__2).MattyFixes_HasComputedOffset) { ((IInjectedItem)<itemType>5__2).MattyFixes_HasComputedOffset = true; MattyFixes.Log.LogDebug((object)$"{<key>5__3}({((NetworkBehaviour)grabbable).NetworkObjectId}) is computing vertical offset"); <itemType>5__2.verticalOffset = ComputeVerticalOffset(grabbable); bool flag = Mathf.Approximately(<oldOffset>5__4, <itemType>5__2.verticalOffset); MattyFixes.Log.LogDebug((object)string.Format("{0} {1} offset is {2}", <key>5__3, flag ? "original" : "new", <itemType>5__2.verticalOffset)); if (flag) { return false; } } if (!updatePosition) { return false; } Vector3 targetFloorPosition = grabbable.targetFloorPosition; GrabbableObject obj = grabbable; obj.targetFloorPosition -= Vector3.up * <oldOffset>5__4; GrabbableObject obj2 = grabbable; obj2.targetFloorPosition += Vector3.up * <itemType>5__2.verticalOffset; MattyFixes.Log.LogDebug((object)$"{<key>5__3}({((NetworkBehaviour)grabbable).NetworkObjectId}) position updated [{targetFloorPosition}] -> [{grabbable.targetFloorPosition}]"); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPrefix] [HarmonyPatch(typeof(GrabbableObject), "Start")] internal static void OnObjectSpawn(GrabbableObject __instance) { if (MattyFixes.PluginConfig.ItemClipping.Enabled.Value) { Item itemProperties = __instance.itemProperties; if (!((IInjectedItem)itemProperties).MattyFixes_HasComputedOffset) { string path = itemProperties.GetPath(); MattyFixes.Log.LogDebug((object)$"{path}({((NetworkBehaviour)__instance).NetworkObjectId}) needs to compute vertical offset - scheduled"); bool updatePosition = ShouldSpawnOnGround(__instance) || (Object)(object)((Component)__instance).transform.parent == (Object)(object)CupBoardFix.Closet.gameObject.transform; ((MonoBehaviour)__instance).StartCoroutine(ProcessGrabbable(__instance, updatePosition)); } } } [IteratorStateMachine(typeof(<ProcessGrabbable>d__1))] private static IEnumerator ProcessGrabbable(GrabbableObject grabbable, bool updatePosition = true) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ProcessGrabbable>d__1(0) { grabbable = grabbable, updatePosition = updatePosition }; } private static float ComputeVerticalOffset(GrabbableObject grabbable) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Item itemProperties = grabbable.itemProperties; string path = itemProperties.GetPath(); try { if (MattyFixes.PluginConfig.ItemClipping.ManualOffsetMap.TryGetValue(path, out var value)) { return value; } ExecutionOptions val = new ExecutionOptions(); ((ExecutionOptions)(ref val)).VertexCache = VertexesExtensions.GlobalPartialCache; ((ExecutionOptions)(ref val)).CullingMask = MattyFixes.VisibleLayerMask; ((ExecutionOptions)(ref val)).LogHandler = MattyFixes.VerboseMeshLog; ((ExecutionOptions)(ref val)).OverrideMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(grabbable.itemProperties.restingRotation.x, (float)grabbable.itemProperties.floorYOffset + 90f, grabbable.itemProperties.restingRotation.z), ((Component)grabbable).transform.lossyScale); ExecutionOptions val2 = val; Bounds val3 = default(Bounds); if (VertexesExtensions.TryGetBounds(((Component)grabbable).transform, ref val3, val2)) { value = 0f - ((Bounds)(ref val3)).min.y; value += MattyFixes.PluginConfig.ItemClipping.VerticalOffset.Value; } else { value = itemProperties.verticalOffset; } return value; } catch (Exception arg) { MattyFixes.Log.LogError((object)$"{path} Failed to compute vertical offset! {arg}"); } return itemProperties.verticalOffset; } [HarmonyTranspiler] [HarmonyPatch(typeof(GrabbableObject), "Start")] private static IEnumerable<CodeInstruction> RedirectSpawnOnGroundCheck(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); FieldInfo field = typeof(GrabbableObject).GetField("itemProperties", AccessTools.all); FieldInfo field2 = typeof(Item).GetField("itemSpawnsOnGround", AccessTools.all); MethodInfo method = typeof(GrabbableStartPatch).GetMethod("NewSpawnOnGroundCheck", AccessTools.all); CodeInstruction variable; ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "RedirectSpawnOnGroundCheck", "./Plugin/src/Patches/GrabbableStartPatch.cs", 144), ILMatcher.Ldfld(field2, "RedirectSpawnOnGroundCheck", "./Plugin/src/Patches/GrabbableStartPatch.cs", 145), ILMatcher.Branch().CaptureAs(out variable)); if (!iLInjector.IsValid) { MattyFixes.Log.LogWarning((object)"GrabbableObject.Start patch failed!!"); MattyFixes.Log.LogDebug((object)string.Join("\n", iLInjector.ReleaseInstructions())); return list; } iLInjector.ReplaceLastMatch(InstructionUtilities.MakeLdarg(0), new CodeInstruction(OpCodes.Call, (object)method), variable); MattyFixes.Log.LogDebug((object)"GrabbableObject.Start patched!"); return iLInjector.ReleaseInstructions(); } private static bool NewSpawnOnGroundCheck(GrabbableObject grabbableObject) { MattyFixes.VerboseItemsLog((LogLevel)32, () => $"{grabbableObject.itemProperties.itemName}({((NetworkBehaviour)grabbableObject).NetworkObjectId}) processing GrabbableObject pos {((Component)grabbableObject).transform.position}"); bool ret = ShouldSpawnOnGround(grabbableObject); MattyFixes.VerboseItemsLog((LogLevel)32, () => $"{grabbableObject.itemProperties.itemName}({((NetworkBehaviour)grabbableObject).NetworkObjectId}) processing GrabbableObject spawnState " + $"OnGround - was: {grabbableObject.itemProperties.itemSpawnsOnGround} new:{ret}"); return ret; } private static bool ShouldSpawnOnGround(GrabbableObject grabbableObject) { bool result = grabbableObject.itemProperties.itemSpawnsOnGround; if (!MattyFixes.PluginConfig.OutOfBounds.Enabled.Value && !MattyFixes.PluginConfig.CupBoard.Enabled.Value) { return result; } if (grabbableObject is ClipboardItem || (grabbableObject is PhysicsProp && grabbableObject.itemProperties.itemName == "Sticky note")) { return result; } if (Object.op_Implicit((Object)(object)StartOfRound.Instance.localPlayerController) && !StartOfRoundPatch.IsInitializingGame) { return result; } if (MattyFixes.PluginConfig.OutOfBounds.Enabled.Value) { result = ((NetworkBehaviour)StartOfRound.Instance).IsServer; } if (!MattyFixes.PluginConfig.CupBoard.Enabled.Value) { return result; } if (Object.op_Implicit((Object)(object)CupBoardFix.Closet.gameObject) && (Object)(object)((Component)grabbableObject).transform.parent == (Object)(object)CupBoardFix.Closet.gameObject.transform) { result = false; } return result; } } [HarmonyPatch] internal static class ItemPatches { [HarmonyPatch(typeof(NetworkBehaviour), "OnNetworkSpawn")] internal static class NetworkSpawnPatch { [HarmonyPrefix] [HarmonyPriority(900)] private static void Prefix(NetworkBehaviour __instance) { GrabbableObject val = (GrabbableObject)(object)((__instance is GrabbableObject) ? __instance : null); if (val == null) { return; } Item itemProperties = val.itemProperties; TryUpdateItemRotation(itemProperties); if (!ComputedItems.Add(itemProperties) || !itemProperties.isConductiveMetal || !MattyFixes.PluginConfig.ReadableMeshes.Enabled.Value) { return; } try { if ((Object)(object)itemProperties.spawnPrefab != (Object)null) { CacheReadableMeshes(itemProperties.spawnPrefab); } } catch (Exception arg) { string path = itemProperties.GetPath(); MattyFixes.Log.LogError((object)$"{path} Failed to mark prefab Mesh Readable! {arg}"); BrokenMeshItems.Add(itemProperties); MattyFixes.Log.LogWarning((object)(path + " Added to the ignored Meshes!")); } } [HarmonyPostfix] [HarmonyPriority(-900)] private static void Postfix(NetworkBehaviour __instance) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) GrabbableObject val = (GrabbableObject)(object)((__instance is GrabbableObject) ? __instance : null); if (val == null || val is ClipboardItem || (val is PhysicsProp && val.itemProperties.itemName == "Sticky note") || (Object.op_Implicit((Object)(object)StartOfRound.Instance.localPlayerController) && !StartOfRoundPatch.IsInitializingGame)) { return; } try { val.isInElevator = true; val.isInShipRoom = true; LungProp val2 = (LungProp)(object)((val is LungProp) ? val : null); if (val2 != null) { val2.isLungDocked = false; val2.isLungPowered = false; val2.isLungDockedInElevator = false; AudioSource component = ((Component)val2).GetComponent<AudioSource>(); if (component != null) { component.Stop(); } } if (MattyFixes.PluginConfig.ItemClipping.RotateOnSpawn.Value) { val.floorYRot = (int)Math.Floor(((Component)val).transform.eulerAngles.y - 90f - (float)val.itemProperties.floorYOffset); ((Component)val).transform.rotation = Quaternion.Euler(val.itemProperties.restingRotation.x, ((Component)val).transform.eulerAngles.y, val.itemProperties.restingRotation.z); } } catch (Exception arg) { MattyFixes.Log.LogError((object)$"Exception while setting rotation of {val.itemProperties.GetPath()} :{arg}"); } } } [HarmonyPatch] internal class StormyWeatherPatch { private static (ParentConstraint parent, ScaleConstraint scale) _staticElectricityConstraints; private static (Vector3 position, Vector3 rotation, Vector3 scale) _originalOffsets; [HarmonyPrefix] [HarmonyPatch(typeof(StormyWeather), "Start")] private static void Setup(StormyWeather __instance) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_009a: Unknown result type (might be due to invalid IL or missing references) if (MattyFixes.PluginConfig.Particles.Lightning.Value != 0) { ParticleSystem staticElectricityParticle = __instance.staticElectricityParticle; ShapeModule shape = staticElectricityParticle.shape; _originalOffsets = (((ShapeModule)(ref shape)).position, ((ShapeModule)(ref shape)).rotation, ((ShapeModule)(ref shape)).scale); ParentConstraint val = ((Component)staticElectricityParticle).gameObject.AddComponent<ParentConstraint>(); val.weight = 1f; val.translationAtRest = ((Component)staticElectricityParticle).transform.position; Quaternion rotation = ((Component)staticElectricityParticle).transform.rotation; val.rotationAtRest = ((Quaternion)(ref rotation)).eulerAngles; ScaleConstraint val2 = ((Component)val).gameObject.AddComponent<ScaleConstraint>(); val2.weight = 1f; val2.scaleAtRest = ((Component)staticElectricityParticle).transform.lossyScale; _staticElectricityConstraints = (val, val2); } } [HarmonyTranspiler] [HarmonyPatch(typeof(StormyWeather), "SetStaticElectricityWarning")] private static IEnumerable<CodeInstruction> SetStaticElectricityWarning(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator) { //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); FieldInfo field = typeof(StormyWeather).GetField("staticElectricityParticle", AccessTools.all); MethodInfo method = typeof(ParticleSystem).GetProperty("time", AccessTools.all)?.GetSetMethod(); MethodInfo method2 = typeof(ParticleSystem).GetMethod("Play", 0, Array.Empty<Type>()); MethodInfo method3 = typeof(StormyWeatherPatch).GetMethod("ChangeParticleShape", AccessTools.all); ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 354), ILMatcher.Ldarg(), ILMatcher.Callvirt(method, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 356), ILMatcher.Ldarg(), ILMatcher.Ldfld(field, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 358), ILMatcher.Callvirt(method2, "SetStaticElectricityWarning", "./Plugin/src/Patches/ItemPatches.cs", 359)); if (!iLInjector.IsValid) { MattyFixes.Log.LogWarning((object)"StormyWeather.SetStaticElectricityWarning patch failed!!"); MattyFixes.Log.LogDebug((object)string.Join("\n", iLInjector.ReleaseInstructions())); return list; } iLInjector.Insert(new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Call, (object)method3)); MattyFixes.Log.LogDebug((object)"StormyWeather.SetStaticElectricityWarning patched!"); return iLInjector.ReleaseInstructions(); } private static void ChangeParticleShape(StormyWeather __instance, NetworkObject warningObject) { //IL_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) try { GrabbableObject component = ((Component)warningObject).gameObject.GetComponent<GrabbableObject>(); ParticleSystem staticElectricityParticle = __instance.staticElectricityParticle; ShapeModule shape = staticElectricityParticle.shape; MainModule main = staticElectricityParticle.main; ConstraintSource val2; switch (MattyFixes.PluginConfig.Particles.Lightning.Value) { case MattyFixes.PluginConfig.Particles.LightningType.Fixed: { val2 = default(ConstraintSource); ((ConstraintSource)(ref val2)).sourceTransform = ((Component)warningObject).transform; ((ConstraintSource)(ref val2)).weight = 1f; ConstraintSource val4 = val2; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)2; _staticElectricityConstraints.parent.AddSource(val4); _staticElectricityConstraints.scale.AddSource(val4); _staticElectricityConstraints.parent.constraintActive = true; _staticElectricityConstraints.scale.constraintActive = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radiusThickness = 0.01f; ExecutionOptions val5 = new ExecutionOptions(); ((ExecutionOptions)(ref val5)).VertexCache = VertexesExtensions.GlobalPartialCache; ((ExecutionOptions)(ref val5)).CullingMask = MattyFixes.VisibleLayerMask; ((ExecutionOptions)(ref val5)).LogHandler = MattyFixes.VerboseMeshLog; ExecutionOptions val6 = val5; Vector3[] vertexes = VertexesExtensions.GetVertexes(((Component)warningObject).transform, val6); Bounds? bounds = VertexesExtensions.GetBounds((IEnumerable<Vector3>)vertexes); if (bounds.HasValue) { Bounds value = bounds.Value; float item = VertexesExtensions.GetFarthestPoint((IEnumerable<Vector3>)vertexes, ((Bounds)(ref value)).center).Item2; ((ShapeModule)(ref shape)).radius = item; value = bounds.Value; ((ShapeModule)(ref shape)).position = ((Bounds)(ref value)).center; } break; } case MattyFixes.PluginConfig.Particles.LightningType.Alternate: if (BrokenMeshItems.Contains(component.itemProperties)) { break; } try { GameObject gameObject = ((Component)((ShapeModule)(ref shape)).meshRenderer).gameObject; MeshFilter val = default(MeshFilter); if (gameObject.TryGetComponent<MeshFilter>(ref val)) { val2 = default(ConstraintSource); ((ConstraintSource)(ref val2)).sourceTransform = gameObject.transform; ((ConstraintSource)(ref val2)).weight = 1f; ConstraintSource val3 = val2; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)2; _staticElectricityConstraints.parent.AddSource(val3); _staticElectricityConstraints.scale.AddSource(val3); _staticElectricityConstraints.parent.constraintActive = true; _staticElectricityConstraints.scale.constraintActive = true; Mesh readableMesh = GetReadableMesh(val.sharedMesh); ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)6; ((ShapeModule)(ref shape)).mesh = readableMesh; ((ShapeModule)(ref shape)).meshRenderer = null; ((ShapeModule)(ref shape)).position = Vector3.zero; ((ShapeModule)(ref shape)).rotation = Vector3.zero; ((ShapeModule)(ref shape)).scale = Vector3.one; } break; } catch (Exception arg) { Item itemProperties = component.itemProperties; string path = itemProperties.GetPath(); MattyFixes.Log.LogError((object)$"{path} Failed to make prefab Mesh Readable! {arg}"); BrokenMeshItems.Add(itemProperties); MattyFixes.Log.LogWarning((object)(path + " Added to the ignored Meshes!")); break; } case MattyFixes.PluginConfig.Particles.LightningType.Vanilla: break; } } catch (Exception ex) { MattyFixes.Log.LogError((object)ex); } } [HarmonyPrefix] [HarmonyPatch(typeof(StormyWeather), "LightningStrike")] private static void ResetMeshes(StormyWeather __instance, bool useTargetedObject) { //IL_006d: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (MattyFixes.PluginConfig.Particles.Lightning.Value != 0 && !((Object)(object)__instance.setStaticToObject == (Object)null) && useTargetedObject) { _staticElectricityConstraints.parent.constraintActive = false; _staticElectricityConstraints.scale.constraintActive = false; _staticElectricityConstraints.parent.SetSources(new List<ConstraintSource>()); _staticElectricityConstraints.scale.SetSources(new List<ConstraintSource>()); ShapeModule shape = __instance.staticElectricityParticle.shape; MainModule main = __instance.staticElectricityParticle.main; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)1; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)13; ((ShapeModule)(ref shape)).position = _originalOffsets.position; ((ShapeModule)(ref shape)).rotation = _originalOffsets.rotation; ((ShapeModule)(ref shape)).scale = _originalOffsets.scale; } } } [HarmonyPatch] internal class RandomFlyParticlePatches { [HarmonyTranspiler] [HarmonyPatch(typeof(RandomFlyParticle), "InitializeAfterPositioning")] private static IEnumerable<CodeInstruction> InitializeAfterPositioning(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo method = typeof(ShapeModule).GetProperty("meshRenderer", AccessTools.all)?.GetSetMethod(); MethodInfo method2 = typeof(RandomFlyParticlePatches).GetMethod("ChangeParticleShape", AccessTools.all); ILInjector iLInjector = new ILInjector(list, ilGenerator).Find(ILMatcher.Call(method, "InitializeAfterPositioning", "./Plugin/src/Patches/ItemPatches.cs", 536)); if (!iLInjector.IsValid) { MattyFixes.Log.LogWarning((object)"RandomFlyParticle.InitializeAfterPositioning patch failed!!"); MattyFixes.Log.LogDebug((object)string.Join("\n", iLI