using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using BoneLib; using BoneLib.BoneMenu; using CustomBloodEffects; using HarmonyLib; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(CustomBloodMod), "custombloodeffects", "1.0.0", "LDB", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonOptionalDependencies(new string[] { "LabFusion" })] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CustomBloodEffects")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CustomBloodEffects")] [assembly: AssemblyTitle("CustomBloodEffects")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CustomBloodEffects { public class CustomBloodMod : MelonMod { private static MelonPreferences_Category? _prefsCategory; private static MelonPreferences_Entry? _prefDamageEnabled; private static MelonPreferences_Entry? _prefDamageBarcode; private static MelonPreferences_Entry? _prefDamageMultiplier; private static MelonPreferences_Entry? _prefDamageCooldown; private static readonly string DamagePresetsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UserData", "CustomBloodEffects_Presets.txt"); private static List<(string name, string barcode)> _damagePresets = new List<(string, string)>(); public static float LastDamageTime = -999f; private static Page? _rootPage; private static Page? _damagePage; private static Page? _damagePresetsPage; private static Page? _warehousePage; private static FunctionElement? _damageBarcodeDisplay; public static bool DamageEnabled => _prefDamageEnabled?.Value ?? false; public static string DamageBarcode => _prefDamageBarcode?.Value ?? string.Empty; public static float DamageMultiplier => _prefDamageMultiplier?.Value ?? 1f; public static float DamageCooldown => _prefDamageCooldown?.Value ?? 0.3f; public override void OnInitializeMelon() { _prefsCategory = MelonPreferences.CreateCategory("CustomBloodEffects"); _prefDamageEnabled = _prefsCategory.CreateEntry("DamageEnabled", false, "Damage Enabled", (string)null, false, false, (ValueValidator)null, (string)null); _prefDamageBarcode = _prefsCategory.CreateEntry("DamageBarcode", string.Empty, "Damage Barcode", (string)null, false, false, (ValueValidator)null, (string)null); _prefDamageMultiplier = _prefsCategory.CreateEntry("DamageMultiplier", 1f, "Damage Multiplier", (string)null, false, false, (ValueValidator)null, (string)null); _prefDamageCooldown = _prefsCategory.CreateEntry("DamageCooldown", 0.3f, "Damage Cooldown", (string)null, false, false, (ValueValidator)null, (string)null); _prefsCategory.SaveToFile(true); LoadPresets(DamagePresetsPath, _damagePresets); ((MelonBase)this).HarmonyInstance.PatchAll(); SetupMenu(); MelonLogger.Msg("[custombloodeffects] Initialised."); } private static void LoadPresets(string path, List<(string, string)> list) { list.Clear(); if (!File.Exists(path)) { return; } string[] array = File.ReadAllLines(path); foreach (string text in array) { int num = text.IndexOf('='); if (num >= 1) { string text2 = text.Substring(0, num).Trim(); string text3 = text.Substring(num + 1).Trim(); if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(text3)) { list.Add((text2, text3)); } } } } public static void SavePresets(string path, List<(string name, string barcode)> list) { List list2 = new List(); foreach (var (text, text2) in list) { list2.Add(text + "=" + text2); } File.WriteAllLines(path, list2); } public static string Short(string bc, int max = 28) { return (bc.Length > max) ? ("..." + bc.Substring(bc.Length - (max - 3))) : bc; } public static float ClampMult(float v) { return Mathf.Round(Mathf.Clamp(v, 0f, 3f) * 2f) / 2f; } public static float ClampCooldown(float v) { return Mathf.Round(Mathf.Clamp(v, 0.3f, 3f) * 10f) / 10f; } private void SetupMenu() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) _rootPage = Page.Root.CreatePage("custom bleeding", Color.red, 0, true); _damagePage = _rootPage.CreatePage("Damage Settings", Color.green, 0, true); _damagePage.CreateBool("Damage Spawn Enabled", Color.green, _prefDamageEnabled.Value, (Action)delegate(bool v) { _prefDamageEnabled.Value = v; _prefsCategory.SaveToFile(true); }); _damageBarcodeDisplay = _damagePage.CreateFunction(DamageLabel(), Color.yellow, (Action)delegate { MelonLogger.Msg("[custombloodeffects] Barcode: " + DamageBarcode); }); _damagePage.CreateFunction("Reload Barcode", Color.cyan, (Action)delegate { MelonPreferences.Load(); ((Element)_damageBarcodeDisplay).ElementName = DamageLabel(); }); _damagePage.CreateFunction("Clear Barcode", Color.red, (Action)delegate { _prefDamageBarcode.Value = string.Empty; _prefsCategory.SaveToFile(true); ((Element)_damageBarcodeDisplay).ElementName = DamageLabel(); }); FunctionElement multLbl = _damagePage.CreateFunction($"Multiplier: {DamageMultiplier:F1}", Color.white, (Action)delegate { }); _damagePage.CreateFunction("Multiplier +", Color.green, (Action)delegate { _prefDamageMultiplier.Value = ClampMult(DamageMultiplier + 0.5f); _prefsCategory.SaveToFile(true); ((Element)multLbl).ElementName = $"Multiplier: {DamageMultiplier:F1}"; }); _damagePage.CreateFunction("Multiplier -", Color.red, (Action)delegate { _prefDamageMultiplier.Value = ClampMult(DamageMultiplier - 0.5f); _prefsCategory.SaveToFile(true); ((Element)multLbl).ElementName = $"Multiplier: {DamageMultiplier:F1}"; }); FunctionElement cdLbl = _damagePage.CreateFunction($"Cooldown: {DamageCooldown:F1}s", Color.white, (Action)delegate { }); _damagePage.CreateFunction("Cooldown +", Color.green, (Action)delegate { _prefDamageCooldown.Value = ClampCooldown(DamageCooldown + 0.1f); _prefsCategory.SaveToFile(true); ((Element)cdLbl).ElementName = $"Cooldown: {DamageCooldown:F1}s"; }); _damagePage.CreateFunction("Cooldown -", Color.red, (Action)delegate { _prefDamageCooldown.Value = ClampCooldown(DamageCooldown - 0.1f); _prefsCategory.SaveToFile(true); ((Element)cdLbl).ElementName = $"Cooldown: {DamageCooldown:F1}s"; }); _damagePresetsPage = _rootPage.CreatePage("Damage Presets", Color.yellow, 0, true); SetupPresetsPage(_damagePresetsPage, _damagePresets, DamagePresetsPath, () => DamageBarcode, delegate(string bc) { _prefDamageBarcode.Value = bc; _prefsCategory.SaveToFile(true); ((Element)_damageBarcodeDisplay).ElementName = "Barcode: " + Short(bc); }); _warehousePage = _rootPage.CreatePage("Asset Warehouse", Color.white, 0, true); WarehouseBrowser.SetupWarehousePage(_warehousePage); static string DamageLabel() { return "Barcode: " + (string.IsNullOrEmpty(DamageBarcode) ? "" : Short(DamageBarcode)); } } private static void SetupPresetsPage(Page page, List<(string name, string barcode)> list, string filePath, Func getActive, Action applyBarcode) { //IL_0036: 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_007a: Unknown result type (might be due to invalid IL or missing references) Func getActive2 = getActive; List<(string name, string barcode)> list2 = list; string filePath2 = filePath; Page page2 = page; Action applyBarcode2 = applyBarcode; page2.CreateFunction("Save Current as Preset", Color.green, (Action)delegate { string text = getActive2(); if (string.IsNullOrEmpty(text)) { MelonLogger.Warning("[custombloodeffects] No barcode to save."); } else { string text2 = text.Split(new char[1] { '.' })[^1]; int num = 1; string final = text2; while (list2.Exists(((string name, string barcode) p) => p.name == final)) { final = text2 + "_" + num++; } list2.Add((final, text)); SavePresets(filePath2, list2); AddPresetButton(page2, list2, filePath2, final, text, applyBarcode2); MelonLogger.Msg("[custombloodeffects] Saved preset '" + final + "'."); } }); page2.CreateFunction("Delete All Presets", Color.red, (Action)delegate { list2.Clear(); SavePresets(filePath2, list2); MelonLogger.Msg("[custombloodeffects] All presets deleted. Restart to refresh."); }); page2.CreateFunction("-- Saved Presets --", Color.white, (Action)delegate { }); foreach (var (name, bc) in list2) { AddPresetButton(page2, list2, filePath2, name, bc, applyBarcode2); } } private static void AddPresetButton(Page page, List<(string name, string barcode)> list, string filePath, string name, string bc, Action applyBarcode) { //IL_0033: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) Action applyBarcode2 = applyBarcode; string bc2 = bc; string name2 = name; List<(string name, string barcode)> list2 = list; string filePath2 = filePath; Page val = page.CreatePage(name2, Color.yellow, 0, true); val.CreateFunction("Apply", Color.green, (Action)delegate { applyBarcode2(bc2); MelonLogger.Msg("[custombloodeffects] Applied '" + name2 + "'."); }); val.CreateFunction("Delete", Color.red, (Action)delegate { list2.RemoveAll(((string name, string barcode) p) => p.name == name2 && p.barcode == bc2); SavePresets(filePath2, list2); MelonLogger.Msg("[custombloodeffects] Deleted '" + name2 + "'. Restart to refresh."); }); val.CreateFunction(Short(bc2, 30), Color.white, (Action)delegate { }); } public static void DoSpawn(string barcode, Vector3 position, Quaternion rotation, int count) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_008e: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Barcode val = new Barcode(barcode); SpawnableCrate val2 = null; AssetWarehouse.Instance.TryGetCrate(val, ref val2); if ((Object)(object)val2 == (Object)null) { MelonLogger.Error("[custombloodeffects] Crate not found: " + barcode); return; } int num = Math.Max(1, Math.Min(count, 100)); for (int i = 0; i < num; i++) { SpawnableCrateReference crateRef = new SpawnableCrateReference(barcode); Spawnable val3 = new Spawnable { crateRef = crateRef }; AssetSpawner.Register(val3); if (FusionHelper.FusionInstalled && FusionHelper.IsConnected()) { FusionHelper.NetworkSpawn(barcode, position, rotation); } else { AssetSpawner.Spawn(val3, position, rotation, new Nullable(), (Transform)null, false, new Nullable(), (Action)null, (Action)null); } } } public static void SetDamageBarcode(string barcode) { _prefDamageBarcode.Value = barcode; _prefsCategory.SaveToFile(true); if (_damageBarcodeDisplay != null) { ((Element)_damageBarcodeDisplay).ElementName = "Barcode: " + Short(barcode); } } } [HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")] public static class DamagePatch { [HarmonyPostfix] public static void Postfix(PlayerDamageReceiver __instance, Attack attack) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) try { if (!CustomBloodMod.DamageEnabled || string.IsNullOrEmpty(CustomBloodMod.DamageBarcode)) { return; } float time = Time.time; if (time - CustomBloodMod.LastDamageTime < CustomBloodMod.DamageCooldown) { return; } CustomBloodMod.LastDamageTime = time; RigManager componentInParent = ((Component)__instance).gameObject.GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null)) { RigManager rigManager = Player.RigManager; if (!((Object)(object)rigManager == (Object)null) && ((Object)((Component)componentInParent).gameObject).GetInstanceID() == ((Object)((Component)rigManager).gameObject).GetInstanceID()) { Transform transform = ((Component)__instance).gameObject.transform; Vector3 position = transform.position; Quaternion rotation = transform.rotation; int count = Math.Max(1, (int)Mathf.Round(CustomBloodMod.DamageMultiplier)); CustomBloodMod.DoSpawn(CustomBloodMod.DamageBarcode, position, rotation, count); } } } catch (Exception ex) { MelonLogger.Error("[custombloodeffects] Damage patch: " + ex.Message); } } } public static class WarehouseBrowser { private static string _searchQuery = string.Empty; private static Page? _warehouseRootPage; private static FunctionElement? _statusLabel; private static int _searchSession = 0; public static void SetupWarehousePage(Page warehousePage) { //IL_000d: 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) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) _warehouseRootPage = warehousePage; warehousePage.CreateString("Search Query", Color.green, _searchQuery, (Action)delegate(string val) { _searchQuery = val ?? string.Empty; }); warehousePage.CreateFunction("Refresh / Search", Color.green, (Action)delegate { PopulateResults(); }); warehousePage.CreateFunction("Clear Search", Color.red, (Action)delegate { _searchQuery = string.Empty; PopulateResults(); }); _statusLabel = warehousePage.CreateFunction("[ Press Refresh / Search to load ]", Color.yellow, (Action)delegate { }); } private static void PopulateResults() { //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) if (_warehouseRootPage == null) { return; } try { AssetWarehouse instance = AssetWarehouse.Instance; if (instance == null) { if (_statusLabel != null) { ((Element)_statusLabel).ElementName = "Warehouse not ready — try again."; } return; } List crates = instance.GetCrates((ICrateFilter)null); if (crates == null || crates.Count == 0) { if (_statusLabel != null) { ((Element)_statusLabel).ElementName = "No crates found — try again."; } return; } string text = _searchQuery.ToLowerInvariant().Trim(); _searchSession++; int searchSession = _searchSession; Dictionary>> dictionary = new Dictionary>>(); Enumerator enumerator = crates.GetEnumerator(); while (enumerator.MoveNext()) { SpawnableCrate current = enumerator.Current; if ((Object)(object)current == (Object)null) { continue; } try { string text2 = ((Scannable)current).Barcode.ID ?? string.Empty; if (string.IsNullOrEmpty(text2)) { continue; } string text3 = ((Scannable)current).Title ?? text2; Pallet pallet = ((Crate)current).Pallet; string text4 = ((pallet != null) ? ((Scannable)pallet).Title : null) ?? "Unknown Pallet"; if (string.IsNullOrEmpty(text) || text3.ToLowerInvariant().Contains(text) || text4.ToLowerInvariant().Contains(text) || text2.ToLowerInvariant().Contains(text)) { if (!dictionary.ContainsKey(text4)) { dictionary[text4] = new List>(); } dictionary[text4].Add(Tuple.Create(text3, text2)); } } catch { } } int num = 0; foreach (KeyValuePair>> item in dictionary) { num += item.Value.Count; } string text5 = (string.IsNullOrEmpty(text) ? $"{dictionary.Count} pallets, {num} crates loaded" : $"{dictionary.Count} pallets, {num} crates matching [{text}]"); if (_statusLabel != null) { ((Element)_statusLabel).ElementName = text5; } string text6 = (string.IsNullOrEmpty(text) ? $"Results #{searchSession} (all)" : $"Results #{searchSession} [{text}]"); Page val = _warehouseRootPage.CreatePage(text6, Color.white, 0, true); val.CreateFunction(text5, Color.white, (Action)delegate { }); if (dictionary.Count == 0) { val.CreateFunction("No results found.", Color.red, (Action)delegate { }); return; } Page val2 = val.CreatePage("Pallets", Color.yellow, 0, true); val2.CreateFunction($"[ {dictionary.Count} pallet(s) ]", Color.white, (Action)delegate { }); foreach (KeyValuePair>> item2 in dictionary) { string key = item2.Key; List> value = item2.Value; string text7 = ((key.Length > 26) ? ("..." + key.Substring(key.Length - 23)) : key); Page val3 = val2.CreatePage(text7, Color.cyan, 0, true); val3.CreateFunction("[ " + text7 + " ]", Color.white, (Action)delegate { }); val3.CreateFunction($"{value.Count} spawnable(s)", Color.white, (Action)delegate { }); AddCrateButtons(val3, value); } Page val4 = val.CreatePage("Crates", Color.cyan, 0, true); List> list = new List>(); foreach (KeyValuePair>> item3 in dictionary) { list.AddRange(item3.Value); } val4.CreateFunction($"[ {list.Count} crate(s) ]", Color.white, (Action)delegate { }); AddCrateButtons(val4, list); MelonLogger.Msg($"[custombloodeffects] Search #{searchSession}: {num} crates, {dictionary.Count} pallets."); } catch (Exception ex) { MelonLogger.Error("[custombloodeffects] WarehouseBrowser: " + ex.Message); if (_statusLabel != null) { ((Element)_statusLabel).ElementName = "Error: " + ex.Message.Substring(0, Math.Min(30, ex.Message.Length)); } } } private static void AddCrateButtons(Page parentPage, List> crates) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) foreach (Tuple crate in crates) { string capTitle = crate.Item1; string capBarcode = crate.Item2; string text = ((capTitle.Length > 26) ? ("..." + capTitle.Substring(capTitle.Length - 23)) : capTitle); Page val = parentPage.CreatePage(text, Color.green, 0, true); val.CreateFunction("Send to Damage", Color.green, (Action)delegate { CustomBloodMod.SetDamageBarcode(capBarcode); MelonLogger.Msg("[custombloodeffects] -> Damage: " + capTitle); }); val.CreateFunction((capBarcode.Length > 26) ? ("..." + capBarcode.Substring(capBarcode.Length - 23)) : capBarcode, Color.white, (Action)delegate { }); } } } public static class FusionHelper { public static bool FusionInstalled { get; private set; } static FusionHelper() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.FullName.Contains("LabFusion")) { FusionInstalled = true; break; } } } catch { FusionInstalled = false; } } public static bool IsConnected() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!assembly.FullName.Contains("LabFusion")) { continue; } Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (!(type.Name != "NetworkInfo")) { PropertyInfo property = type.GetProperty("HasServer"); if (property != null) { return (bool)property.GetValue(null); } } } } return false; } catch { return false; } } public static void NetworkSpawn(string barcode, Vector3 position, Quaternion rotation) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0141: 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) try { Type type = null; Type type2 = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!assembly.FullName.Contains("LabFusion")) { continue; } Type[] types = assembly.GetTypes(); foreach (Type type3 in types) { if (type3.Name == "NetworkAssetSpawner") { type = type3; } if (type3.Name == "SpawnRequestInfo") { type2 = type3; } } if (type != null && type2 != null) { break; } } if (type == null || type2 == null) { MelonLogger.Error("[custombloodeffects] Fusion types not found."); return; } SpawnableCrateReference crateRef = new SpawnableCrateReference(barcode); Spawnable val = new Spawnable { crateRef = crateRef }; AssetSpawner.Register(val); object uninitializedObject = FormatterServices.GetUninitializedObject(type2); type2.GetField("Spawnable")?.SetValue(uninitializedObject, val); type2.GetField("Position")?.SetValue(uninitializedObject, position); type2.GetField("Rotation")?.SetValue(uninitializedObject, rotation); MethodInfo method = type.GetMethod("Spawn"); if (method == null) { MelonLogger.Error("[custombloodeffects] Spawn method not found."); return; } method.Invoke(null, new object[1] { uninitializedObject }); } catch (TargetInvocationException ex) { MelonLogger.Error("[custombloodeffects] Fusion spawn (inner): " + ex.InnerException?.Message); } catch (Exception ex2) { MelonLogger.Error("[custombloodeffects] Fusion spawn: " + ex2.Message); } } } }