Decompiled source of SpawnLoadout v1.1.0

Mods\SpawnLoadout.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using MelonLoader;
using MelonLoader.Preferences;
using Newtonsoft.Json;
using SpawnLoadout;
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(Main), "SpawnLoadout", "1.0.0", "zekeg", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SpawnLoadout;

public class Main : MelonMod
{
	internal static Main Instance;

	internal static MelonPreferences_Category PrefCategory;

	internal static MelonPreferences_Entry<bool> PrefAutoLoad;

	internal static MelonPreferences_Entry<string> PrefActivePreset;

	private Page _mainPage;

	private Page _presetsPage;

	private bool _isDead;

	private bool _respawnWatcherRunning;

	public override void OnInitializeMelon()
	{
		Instance = this;
		PrefCategory = MelonPreferences.CreateCategory("SpawnLoadout");
		PrefAutoLoad = PrefCategory.CreateEntry<bool>("AutoLoad", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PrefActivePreset = PrefCategory.CreateEntry<string>("ActivePreset", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		PresetManager.Initialize();
		SetupBoneMenu();
		Hooking.OnLevelLoaded += delegate
		{
			if (PrefAutoLoad.Value && !string.IsNullOrEmpty(PrefActivePreset.Value))
			{
				MelonCoroutines.Start(DelayedLoad(3f));
			}
		};
		Hooking.OnPlayerDeath += delegate
		{
			_isDead = true;
			if (!_respawnWatcherRunning)
			{
				_respawnWatcherRunning = true;
				MelonCoroutines.Start(RespawnWatcher());
			}
		};
	}

	private IEnumerator RespawnWatcher()
	{
		while (_isDead)
		{
			yield return (object)new WaitForSeconds(0.5f);
			if (!PrefAutoLoad.Value || string.IsNullOrEmpty(PrefActivePreset.Value))
			{
				_isDead = false;
				break;
			}
			bool ready = false;
			try
			{
				ready = (Object)(object)Player.RigManager != (Object)null && (Object)(object)Player.RigManager.inventory != (Object)null && (Object)(object)Player.Head != (Object)null;
			}
			catch
			{
			}
			if (ready)
			{
				_isDead = false;
				yield return (object)new WaitForSeconds(1.5f);
				TryLoadActivePreset();
				break;
			}
		}
		_respawnWatcherRunning = false;
	}

	private void SetupBoneMenu()
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		_mainPage = Page.Root.CreatePage("SpawnLoadout", new Color(0.2f, 0.6f, 1f), 0, true);
		_mainPage.CreateBool("Auto Load", Color.green, PrefAutoLoad.Value, (Action<bool>)delegate(bool val)
		{
			PrefAutoLoad.Value = val;
		});
		StringElement nameElement = _mainPage.CreateString("Preset Name", Color.white, "", (Action<string>)null);
		_mainPage.CreateFunction("Save Current as Preset", Color.cyan, (Action)delegate
		{
			string text = nameElement.Value.Trim();
			if (string.IsNullOrEmpty(text))
			{
				SendNotification("Error", "Enter a name first", (NotificationType)2);
			}
			else if (PresetManager.PresetExists(text))
			{
				SendNotification("Error", "Preset name already exists", (NotificationType)2);
			}
			else
			{
				PresetManager.SavePreset(text);
				RefreshPresetsPage();
				SendNotification("Saved", "Preset \"" + text + "\" saved", (NotificationType)3);
			}
		});
		_mainPage.CreateFunction("Load Active Preset Now", Color.yellow, (Action)delegate
		{
			TryLoadActivePreset();
		});
		_presetsPage = _mainPage.CreatePage("Presets", Color.cyan, 0, true);
		RefreshPresetsPage();
	}

	private void RefreshPresetsPage()
	{
		//IL_002c: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		_presetsPage.RemoveAll();
		List<Preset> allPresets = PresetManager.GetAllPresets();
		if (allPresets.Count == 0)
		{
			_presetsPage.CreateFunction("(no presets saved)", Color.gray, (Action)delegate
			{
			});
			return;
		}
		foreach (Preset preset in allPresets)
		{
			bool flag = preset.Name == PrefActivePreset.Value;
			Page val = _presetsPage.CreatePage(preset.Name, flag ? Color.green : Color.white, 0, true);
			val.CreateFunction("Load Now", Color.green, (Action)delegate
			{
				PresetManager.LoadPreset(preset);
				SendNotification("Loaded", "Preset \"" + preset.Name + "\" loaded", (NotificationType)3);
			});
			if (!flag)
			{
				val.CreateFunction("Set as Auto Load", Color.yellow, (Action)delegate
				{
					PrefActivePreset.Value = preset.Name;
					RefreshPresetsPage();
					SendNotification("Active", "\"" + preset.Name + "\" set as auto-load", (NotificationType)0);
				});
			}
			else
			{
				val.CreateFunction("(active)", Color.green, (Action)delegate
				{
				});
			}
			val.CreateFunction("Delete", Color.red, (Action)delegate
			{
				Menu.DisplayDialog("Delete Preset", "Delete \"" + preset.Name + "\"?", Dialog.WarningIcon, (Action)delegate
				{
					bool flag2 = preset.Name == PrefActivePreset.Value;
					PresetManager.DeletePreset(preset.Name);
					if (flag2)
					{
						PrefActivePreset.Value = "";
					}
					RefreshPresetsPage();
					SendNotification("Deleted", "\"" + preset.Name + "\" deleted", (NotificationType)1);
				}, (Action)null);
			});
		}
	}

	private IEnumerator DelayedLoad(float delay)
	{
		yield return (object)new WaitForSeconds(delay);
		TryLoadActivePreset();
	}

	private void TryLoadActivePreset()
	{
		if (!string.IsNullOrEmpty(PrefActivePreset.Value))
		{
			Preset preset = PresetManager.GetPreset(PrefActivePreset.Value);
			if (preset == null)
			{
				SendNotification("Error", "Preset \"" + PrefActivePreset.Value + "\" not found", (NotificationType)2);
			}
			else
			{
				PresetManager.LoadPreset(preset);
			}
		}
	}

	internal static void SendNotification(string title, string message, NotificationType type)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit(title),
			Message = NotificationText.op_Implicit(message),
			Type = type,
			PopupLength = 3f,
			ShowTitleOnPopup = true
		});
	}
}
public class Preset
{
	public string Name;

	public Dictionary<string, string> Slots = new Dictionary<string, string>();
}
public static class PresetManager
{
	private static string _presetsDir;

	public static void Initialize()
	{
		_presetsDir = Path.Combine(Directory.GetCurrentDirectory(), "UserData", "SpawnLoadout", "Presets");
		Directory.CreateDirectory(_presetsDir);
	}

	private static string GetFilePath(string presetName)
	{
		string text = string.Join("_", presetName.Split(Path.GetInvalidFileNameChars()));
		return Path.Combine(_presetsDir, text + ".json");
	}

	public static bool PresetExists(string name)
	{
		return File.Exists(GetFilePath(name));
	}

	public static List<Preset> GetAllPresets()
	{
		if (!Directory.Exists(_presetsDir))
		{
			return new List<Preset>();
		}
		List<Preset> list = new List<Preset>();
		string[] files = Directory.GetFiles(_presetsDir, "*.json");
		foreach (string path in files)
		{
			try
			{
				Preset preset = JsonConvert.DeserializeObject<Preset>(File.ReadAllText(path));
				if (preset != null && !string.IsNullOrEmpty(preset.Name))
				{
					list.Add(preset);
				}
			}
			catch
			{
			}
		}
		return list;
	}

	public static Preset GetPreset(string name)
	{
		string filePath = GetFilePath(name);
		if (!File.Exists(filePath))
		{
			return null;
		}
		try
		{
			return JsonConvert.DeserializeObject<Preset>(File.ReadAllText(filePath));
		}
		catch
		{
			return null;
		}
	}

	public static void SavePreset(string name)
	{
		Dictionary<string, string> currentInventoryBarcodes = GetCurrentInventoryBarcodes();
		string contents = JsonConvert.SerializeObject((object)new Preset
		{
			Name = name,
			Slots = currentInventoryBarcodes
		}, (Formatting)1);
		File.WriteAllText(GetFilePath(name), contents);
	}

	public static void DeletePreset(string name)
	{
		string filePath = GetFilePath(name);
		if (File.Exists(filePath))
		{
			File.Delete(filePath);
		}
	}

	public static Dictionary<string, string> GetCurrentInventoryBarcodes()
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		try
		{
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null || (Object)(object)rigManager.inventory == (Object)null)
			{
				return dictionary;
			}
			foreach (SlotContainer item in (Il2CppArrayBase<SlotContainer>)(object)rigManager.inventory.bodySlots)
			{
				if ((Object)(object)((item != null) ? item.inventorySlotReceiver : null) == (Object)null)
				{
					continue;
				}
				WeaponSlot slottedWeapon = item.inventorySlotReceiver._slottedWeapon;
				if ((Object)(object)((slottedWeapon != null) ? slottedWeapon.interactableHost : null) == (Object)null)
				{
					continue;
				}
				Poolee val = (((Object)(object)slottedWeapon.interactableHost.manager != (Object)null) ? ((Component)slottedWeapon.interactableHost.manager).GetComponent<Poolee>() : ((Component)slottedWeapon.interactableHost).GetComponent<Poolee>());
				if (!((Object)(object)((val != null) ? val.SpawnableCrate : null) == (Object)null))
				{
					string iD = ((Scannable)val.SpawnableCrate).Barcode.ID;
					if (!string.IsNullOrEmpty(iD) && !dictionary.ContainsKey(((Object)item).name))
					{
						dictionary[((Object)item).name] = iD;
					}
				}
			}
		}
		catch (Exception ex)
		{
			Main instance = Main.Instance;
			if (instance != null)
			{
				((MelonBase)instance).LoggerInstance.Error("GetInventory: " + ex.Message);
			}
		}
		return dictionary;
	}

	public static void LoadPreset(Preset preset)
	{
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Expected O, but got Unknown
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: 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_0145: Unknown result type (might be due to invalid IL or missing references)
		if (preset?.Slots == null || preset.Slots.Count == 0)
		{
			return;
		}
		try
		{
			RigManager rigManager = Player.RigManager;
			if ((Object)(object)rigManager == (Object)null)
			{
				Main instance = Main.Instance;
				if (instance != null)
				{
					((MelonBase)instance).LoggerInstance.Error("RigManager null");
				}
				return;
			}
			int num = 0;
			foreach (KeyValuePair<string, string> slot in preset.Slots)
			{
				string value = slot.Value;
				string key = slot.Key;
				if (string.IsNullOrEmpty(value))
				{
					continue;
				}
				InventorySlotReceiver val = null;
				foreach (SlotContainer item in (Il2CppArrayBase<SlotContainer>)(object)rigManager.inventory.bodySlots)
				{
					if ((Object)(object)item != (Object)null && ((Object)item).name == key)
					{
						val = item.inventorySlotReceiver;
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Vector3 val2 = Vector3.zero;
					try
					{
						val2 = Player.Head.position + Player.Head.forward * 1.5f;
					}
					catch
					{
						((Vector3)(ref val2))..ctor(0f, 1.5f, 0f);
					}
					HelperMethods.SpawnCrate(value, val2 + Vector3.right * ((float)num * 0.3f), Quaternion.identity, Vector3.one, true, (Action<GameObject>)null, (Action<GameObject>)null);
					num++;
				}
				else
				{
					if ((Object)(object)val._slottedWeapon != (Object)null)
					{
						val.DespawnContents();
					}
					val.SpawnInSlotAsync(new Barcode(value));
					num++;
				}
			}
			if (num > 0)
			{
				Main.SendNotification("SpawnLoadout", $"Loaded {num} items", (NotificationType)3);
			}
		}
		catch (Exception ex)
		{
			Main instance2 = Main.Instance;
			if (instance2 != null)
			{
				((MelonBase)instance2).LoggerInstance.Error("LoadPreset: " + ex.Message);
			}
		}
	}
}