Decompiled source of KeepInventory v1.3.0
Mods/KeepInventory.dll
Decompiled 2 weeks 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.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; using BoneLib; using BoneLib.BoneMenu; using BoneLib.Notifications; using HarmonyLib; using Il2CppCysharp.Threading.Tasks; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.SceneStreaming; using Il2CppSLZ.Marrow.Utilities; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSystem; using KeepInventory; using KeepInventory.Fusion; using KeepInventory.Fusion.Managers; using KeepInventory.Helper; using KeepInventory.Managers; using KeepInventory.Menu; using KeepInventory.Patches; using KeepInventory.Saves.V0; using KeepInventory.Saves.V1; using KeepInventory.Saves.V2; using KeepInventory.Utilities; using LabFusion.Entities; using LabFusion.Extensions; using LabFusion.Marrow.Extenders; using LabFusion.Network; using LabFusion.Player; using LabFusion.RPC; using LabFusion.SDK.Gamemodes; using LabFusion.UI.Popups; using LabFusion.Utilities; using MelonLoader; using MelonLoader.Pastel; using MelonLoader.Preferences; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Semver; using Tomlet; using Tomlet.Attributes; using Tomlet.Models; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(Core), "KeepInventory", "1.3.0", "HAHOOS", "https://thunderstore.io/c/bonelab/p/HAHOOS/KeepInventory/")] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: MelonAuthorColor(0, 255, 165, 0)] [assembly: MelonColor(0, 255, 255, 0)] [assembly: MelonOptionalDependencies(new string[] { "LabFusion", "KeepInventory.Fusion" })] [assembly: AssemblyTitle("Keep your inventory when switching between mod levels, as well as when quitting the game!")] [assembly: AssemblyDescription("Keep your inventory when switching between mod levels, as well as when quitting the game!")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("HAHOOS")] [assembly: AssemblyProduct("KeepInventory")] [assembly: AssemblyFileVersion("1.3.0")] [assembly: AssemblyInformationalVersion("1.3.0")] [assembly: ComVisible(false)] [assembly: Guid("b45d7a48-e5c2-49b2-a7a2-331de9c55d26")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.3.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] internal sealed class ParamCollectionAttribute : Attribute { } [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 KeepInventory { public class Core : MelonMod { public const string Version = "1.3.0"; internal static FunctionElement statusElement; internal static LevelInfo levelInfo; private bool InitialLoad = true; public static KeepInventory.Saves.V2.Save CurrentSave { get { return SaveManager.Saves.FirstOrDefault((KeepInventory.Saves.V2.Save x) => x.ID == PreferencesManager.DefaultSave.Value); } set { if (value == null) { PreferencesManager.DefaultSave.Value = string.Empty; } PreferencesManager.DefaultSave.Value = value.ID; PreferencesManager.Save(); Core.DefaultSaveChanged?.Invoke(); } } public static Core Instance { get; internal set; } internal static Instance Logger { get; private set; } public static bool HasFusion => MelonBase.FindMelon("LabFusion", "Lakatrazz") != null; public static bool IsFusionLibraryInitialized { get; internal set; } = false; public static bool FailedFLLoad { get; internal set; } = false; internal static Thunderstore ThunderstoreInstance { get; private set; } internal static bool IsLatestVersion { get; private set; } = true; internal static Package ThunderstorePackage { get; private set; } internal static bool Deinit { get; private set; } = false; public static event Action DefaultSaveChanged; public override void OnInitializeMelon() { Deinit = false; Logger = ((MelonBase)this).LoggerInstance; Instance = this; ((MelonBase)this).LoggerInstance.Msg("Setting up KeepInventory"); CheckVersion(); if (!HasFusion) { ((MelonBase)this).LoggerInstance.Warning("Could not find LabFusion, the mod will not use any of Fusion's functionality"); } if (HasFusion) { ((MelonBase)this).LoggerInstance.Msg("Attempting to load the Fusion Support Library"); if (DependencyManager.TryLoadDependency("KeepInventory.Fusion")) { IsFusionLibraryInitialized = true; } else { FailedFLLoad = true; } } if (!HasFusion) { Hooking.OnLevelLoaded += LevelLoadedEvent; } else { Fusion.TargetLevelLoadEvent(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) LevelLoadedEvent(new LevelInfo(SceneStreamer.Session.Level)); }); } Hooking.OnLevelUnloaded += LevelUnloadedEvent; if (IsFusionLibraryInitialized) { Fusion.SetupFusionLibrary(); } if (HasFusion) { Fusion.Setup(); } BlacklistManager.Add(new Blacklist("default_labworks", "LABWORKS", enabled: true, new List<Level>(16) { new Level("volx4.LabWorksBoneworksPort.Level.BoneworksLoadingScreen"), new Level("volx4.LabWorksBoneworksPort.Level.BoneworksMainMenu"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks01Breakroom"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks02Museum"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks03Streets"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks04Runoff"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks05Sewers"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks06Warehouse"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks07CentralStation"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks08Tower"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks09TimeTower"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks10Dungeon"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks11Arena"), new Level("volx4.LabWorksBoneworksPort.Level.Boneworks12ThroneRoom"), new Level("volx4.LabWorksBoneworksPort.Level.BoneworksCutscene01"), new Level("volx4.LabWorksBoneworksPort.Level.sceneTheatrigonMovie02") })); BlacklistManager.Add(new Blacklist("default_bonelab", "BONELAB", enabled: true, new List<Level>(19) { new Level("SLZ.BONELAB.Content.Level.LevelOutro"), new Level("c2534c5a-db71-49cf-b694-24584c657665"), new Level("c2534c5a-4197-4879-8cd3-4a695363656e"), new Level("c2534c5a-54df-470b-baaf-741f4c657665"), new Level("c2534c5a-56a6-40ab-a8ce-23074c657665"), new Level("c2534c5a-7601-4443-bdfe-7f235363656e"), new Level("SLZ.BONELAB.Content.Level.LevelBigAnomalyB"), new Level("SLZ.BONELAB.Content.Level.LevelStreetPunch"), new Level("SLZ.BONELAB.Content.Level.SprintBridge04"), new Level("SLZ.BONELAB.Content.Level.SceneMagmaGate"), new Level("SLZ.BONELAB.Content.Level.MoonBase"), new Level("SLZ.BONELAB.Content.Level.LevelKartRace"), new Level("c2534c5a-c056-4883-ac79-e051426f6964"), new Level("c2534c5a-162f-4661-a04d-975d5363656e"), new Level("fa534c5a868247138f50c62e424c4144.Level.LevelArenaMin"), new Level("c2534c5a-c180-40e0-b2b7-325c5363656e"), new Level("c2534c5a-de61-4df9-8f6c-416954726547"), new Level("c2534c5a-4f3b-480e-ad2f-69175363656e"), new Level("c2534c5a-80e1-4a29-93ca-f3254d656e75") })); PreferencesManager.Setup(); SaveManager.Setup(); BoneMenu.Setup(); AmmoManager.Track("light"); AmmoManager.Track("medium"); AmmoManager.Track("heavy"); AmmoManager.Init(); ((MelonBase)this).LoggerInstance.Msg("Initialized."); } public override void OnDeinitializeMelon() { Deinit = true; ((MelonBase)this).LoggerInstance.Msg("Deinitialize requested, cleaning up."); AmmoManager.Destroy(); PreferencesManager.Save(); SaveManager.Saves.ForEach(delegate(KeepInventory.Saves.V2.Save x) { x.IsFileWatcherEnabled = false; x.TrySaveToFile(); }); } private void CheckVersion() { ThunderstoreInstance = new Thunderstore("KeepInventory / 1.3.0 A BONELAB MelonLoader Mod"); try { ThunderstorePackage = ThunderstoreInstance.GetPackage("HAHOOS", "KeepInventory"); if (ThunderstorePackage != null) { if (ThunderstorePackage.Latest != null && !string.IsNullOrWhiteSpace(ThunderstorePackage.Latest.Version)) { IsLatestVersion = ThunderstorePackage.IsLatestVersion("1.3.0"); if (!IsLatestVersion) { ((MelonBase)this).LoggerInstance.Warning($"A new version of KeepInventory is available: v{ThunderstorePackage.Latest.Version} while the current is v{"1.3.0"}. It is recommended that you update"); } else if (SemVersion.Parse("1.3.0", false) == ThunderstorePackage.Latest.SemanticVersion) { ((MelonBase)this).LoggerInstance.Msg("Latest version of KeepInventory is installed! --> v1.3.0"); } else { ((MelonBase)this).LoggerInstance.Msg($"Beta release of KeepInventory is installed (v{ThunderstorePackage.Latest.Version} is newest, v{"1.3.0"} is installed)"); } } else { ((MelonBase)this).LoggerInstance.Warning("Latest version could not be found or the version is empty"); } } else { ((MelonBase)this).LoggerInstance.Warning("Could not find thunderstore package for KeepInventory"); } } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Error("An unexpected error has occurred while trying to check if KeepInventory is the latest version", ex); } } private void LevelUnloadedEvent() { if (!PreferencesManager.SaveOnLevelUnload.Value) { return; } if (!IsBlacklisted(((ScannableReference)levelInfo.levelReference).Barcode)) { if (CurrentSave != null) { InventoryManager.SaveInventory(CurrentSave); } else { ((MelonBase)this).LoggerInstance.Warning("No default save is set, cannot save"); } } else { ((MelonBase)this).LoggerInstance.Warning("Not saving due to the level being blacklisted"); } } private void LevelLoadedEvent(LevelInfo obj) { //IL_0005: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) BoneMenu.SetupPredefinedBlacklists(); levelInfo = obj; if (InitialLoad) { if (FailedFLLoad) { BLHelper.SendNotification("Failure", "The Fusion Library has failed to load, which will cause the Sharing feature to not work. If this occurs again, create an issue on Github or DM the developer (@hahoos)", showTitleOnPopup: true, 10f, (NotificationType)2); IsFusionLibraryInitialized = false; } if (!IsLatestVersion && ThunderstorePackage != null) { BLHelper.SendNotification(NotificationText.op_Implicit("Update!"), new NotificationText("There is a new version of KeepInventory. Go to Thunderstore and download the latest version which is <color=#00FF00>v" + ThunderstorePackage.Latest.Version + "</color>", Color.white, true), showTitleOnPopup: true, 5f, (NotificationType)1); } InitialLoad = false; } if (CurrentSave == null) { return; } if (!IsBlacklisted(((ScannableReference)obj.levelReference).Barcode)) { if (PreferencesManager.LoadOnLevelLoad.Value) { try { ((Element)statusElement).ElementName = "Current level is not blacklisted"; ((Element)statusElement).ElementColor = Color.green; InventoryManager.LoadSavedInventory(CurrentSave); } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Error("An error occurred while loading the inventory", ex); BLHelper.SendNotification("Failure", "Failed to load the inventory, check the logs or console for more details", showTitleOnPopup: true, 5f, (NotificationType)2); } } } else { ((MelonBase)this).LoggerInstance.Warning("Not loading inventory because level is blacklisted"); BLHelper.SendNotification("This level is blacklisted from loading/saving inventory", "Blacklisted", showTitleOnPopup: true, 5f, (NotificationType)1); ((Element)statusElement).ElementName = "Current level is blacklisted"; ((Element)statusElement).ElementColor = Color.red; } } private static bool IsBlacklisted(Barcode barcode) { if (!BlacklistManager.IsLevelBlacklisted(barcode)) { return PreferencesManager.BlacklistedLevels.Value.Contains(barcode.ID); } return true; } } } namespace KeepInventory.Utilities { public static class Fusion { [CompilerGenerated] private static class <>O { public static ServerEvent <0>__OnJoinLeave; } [CompilerGenerated] private sealed class <Internal_GetPlayers>d__13 : IEnumerable<FusionPlayer>, IEnumerable, IEnumerator<FusionPlayer>, IEnumerator, IDisposable { private int <>1__state; private FusionPlayer <>2__current; private int <>l__initialThreadId; private HashSet<NetworkPlayer>.Enumerator <>7__wrap1; FusionPlayer IEnumerator<FusionPlayer>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Internal_GetPlayers>d__13(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } <>7__wrap1 = default(HashSet<NetworkPlayer>.Enumerator); <>1__state = -2; } private bool MoveNext() { try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>7__wrap1 = NetworkPlayer.Players.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; } if (<>7__wrap1.MoveNext()) { NetworkPlayer current = <>7__wrap1.Current; <>2__current = new FusionPlayer(current.PlayerID.SmallID, current.PlayerID.PlatformID, current.Username); <>1__state = 1; return true; } <>m__Finally1(); <>7__wrap1 = default(HashSet<NetworkPlayer>.Enumerator); return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>7__wrap1).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<FusionPlayer> IEnumerable<FusionPlayer>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <Internal_GetPlayers>d__13(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<FusionPlayer>)this).GetEnumerator(); } } public static bool IsConnected { get { if (Core.HasFusion) { return Internal_IsConnected(); } return false; } } public static bool SharingEnabled { get { if (Core.IsFusionLibraryInitialized && Core.HasFusion) { return Internal_SharingEnabled(); } return false; } } public static bool IsGamemodeStarted { get { if (!IsConnected) { return false; } return Internal_IsGamemodeStarted(); } } internal static void SetupFusionLibrary() { Core.Logger.Msg("Setting up the library"); try { FusionModule.Setup(Core.Logger); FusionModule.LoadModule(); ShareManager.Setup(); } catch (Exception ex) { Core.FailedFLLoad = true; Core.Logger.Error("An unexpected error has occurred while setting up and/or loading the fusion module", ex); } } internal static void Setup() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_005f: Expected O, but got Unknown //IL_0074: 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_007f: Expected O, but got Unknown ShareManager.OnShared += delegate(KeepInventory.Saves.V2.Save save, byte sender) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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) //IL_00f0: 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) //IL_012c: Expected O, but got Unknown NetworkPlayer val4 = default(NetworkPlayer); string value = default(string); if (NetworkPlayerManager.TryGetPlayer(sender, ref val4) && !SaveManager.Saves.Any((KeepInventory.Saves.V2.Save x) => x.ID == save.ID) && MetadataHelper.TryGetDisplayName(val4.PlayerID, ref value)) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("KeepInventory | Save shared!"), SaveToMenu = true, ShowPopup = true, Message = NotificationText.op_Implicit($"{value} has shared a save with you called '<color=#{save.DrawingColor.ToHEX()}>{save.Name}</color>'. Go to the LabFusion notifications menu, press accept to add save, decline will disregard this"), PopupLength = 15f, Type = (NotificationType)0, OnAccepted = delegate { SaveManager.RegisterSave(save); }, OnDeclined = delegate { Core.Logger.Msg("Save share ignored"); } }); } }; object obj = <>O.<0>__OnJoinLeave; if (obj == null) { ServerEvent val = OnJoinLeave; <>O.<0>__OnJoinLeave = val; obj = (object)val; } MultiplayerHooking.OnStartedServer += (ServerEvent)obj; object obj2 = <>O.<0>__OnJoinLeave; if (obj2 == null) { ServerEvent val2 = OnJoinLeave; <>O.<0>__OnJoinLeave = val2; obj2 = (object)val2; } MultiplayerHooking.OnJoinedServer += (ServerEvent)obj2; object obj3 = <>O.<0>__OnJoinLeave; if (obj3 == null) { ServerEvent val3 = OnJoinLeave; <>O.<0>__OnJoinLeave = val3; obj3 = (object)val3; } MultiplayerHooking.OnDisconnected += (ServerEvent)obj3; } private static bool Internal_SharingEnabled() { return ShareManager.Entry_SharingEnabled?.Value ?? false; } private static void OnJoinLeave() { BoneMenu.SetupSaves(); } internal static bool Internal_IsConnected() { return NetworkInfo.HasServer; } internal static void Internal_ShareSave(byte SmallID, KeepInventory.Saves.V2.Save save) { NetworkPlayer val = default(NetworkPlayer); if (NetworkPlayerManager.TryGetPlayer(SmallID, ref val)) { ShareManager.Share(save, PlayerID.op_Implicit(val.PlayerID)); return; } throw new Exception($"Player with small ID {SmallID} could not be found"); } public static void ShareSave(byte SmallID, KeepInventory.Saves.V2.Save save) { if (Core.HasFusion && Core.IsFusionLibraryInitialized && IsConnected) { Internal_ShareSave(SmallID, save); } } internal static List<FusionPlayer> Internal_GetShareablePlayers() { List<byte> allShareablePlayers = ShareManager.GetAllShareablePlayers(); List<FusionPlayer> list = new List<FusionPlayer>(); string displayName = default(string); foreach (byte item in allShareablePlayers) { PlayerID playerID = PlayerIDManager.GetPlayerID(item); if (playerID != null && MetadataHelper.TryGetDisplayName(playerID, ref displayName)) { list.Add(new FusionPlayer(item, playerID.PlatformID, displayName)); } } return list; } public static List<FusionPlayer> GetShareablePlayers() { if (Core.HasFusion && Core.IsFusionLibraryInitialized && IsConnected) { return Internal_GetShareablePlayers(); } return new List<FusionPlayer>(); } [IteratorStateMachine(typeof(<Internal_GetPlayers>d__13))] internal static IEnumerable<FusionPlayer> Internal_GetPlayers() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Internal_GetPlayers>d__13(-2); } public static List<FusionPlayer> GetPlayers() { if (Core.HasFusion && IsConnected) { return Internal_GetPlayers().ToList(); } return new List<FusionPlayer>(); } internal static byte Internal_GetLocalPlayerSmallID() { return PlayerIDManager.LocalSmallID; } public static byte GetLocalPlayerSmallID() { if (Core.HasFusion && IsConnected) { return Internal_GetLocalPlayerSmallID(); } return 0; } public static bool IsLocalPlayer(this RigManager rigManager) { if (!IsConnected) { return true; } return rigManager.Internal_IsLocalPlayer(); } private static bool Internal_IsLocalPlayer(this RigManager rigManager) { return FusionPlayer.IsLocalPlayer(rigManager); } internal static bool GamemodeCheck() { if (!IsConnected) { return false; } return Internal_GamemodeCheck(); } internal static bool Internal_GamemodeCheck() { if (!GamemodeManager.IsGamemodeStarted && !GamemodeManager.StartTimerActive) { return GamemodeManager.IsGamemodeReady; } return true; } internal static void TargetLevelLoadEvent(Action action) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown MultiplayerHooking.OnTargetLevelLoaded += (UpdateEvent)delegate { action(); }; } internal static bool Internal_IsGamemodeStarted() { return GamemodeManager.IsGamemodeStarted; } internal static bool DoesGamemodeAllow() { if (!IsConnected) { return false; } Gamemode activeGamemode = GamemodeManager.ActiveGamemode; if (activeGamemode == null) { return true; } if (!GamemodeCheck()) { return true; } string text = default(string); bool result = default(bool); return activeGamemode.Metadata != null && activeGamemode.Metadata.TryGetMetadata("AllowKeepInventory", ref text) && text != null && bool.TryParse(text, out result) && result; } internal static void Fusion_LoadMagazine(this Gun gun, int rounds = -1, Action callback = null) { //IL_001d: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) SpawnRequestInfo val = default(SpawnRequestInfo); val.Position = Player.Head.position; val.Rotation = Player.Head.rotation; val.Spawnable = gun.defaultMagazine.spawnable; val.SpawnEffect = false; val.SpawnCallback = delegate(SpawnCallbackInfo spawn) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) NetworkEntity val2 = GunExtender.Cache.Get(gun); if (val2 != null) { AmmoSocketExtender extender = val2.GetExtender<AmmoSocketExtender>(); Magazine component = spawn.Spawned.GetComponent<Magazine>(); if (extender != null && !((Object)(object)component == (Object)null)) { object obj; if (extender == null) { obj = null; } else { AmmoSocket component2 = ((EntityComponentExtender<AmmoSocket>)(object)extender).Component; obj = ((component2 != null) ? component2._magazinePlug : null); } AmmoPlug val3 = (AmmoPlug)obj; if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)component.magazinePlug) { AlignPlugExtensions.ForceEject((AlignPlug)(object)val3); } InteractableHostExtensions.TryDetach(((Plug)component.magazinePlug).host); ((AlignPlug)component.magazinePlug).InsertPlug((Socket)(object)((EntityComponentExtender<AmmoSocket>)(object)extender).Component); gun.MagazineState.SetCartridge(rounds); callback?.Invoke(); } } }; NetworkAssetSpawner.Spawn(val); } public static void LoadMagazine(this Gun gun, int rounds = -1, Action callback = null) { //IL_0064: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown if (rounds == -1) { rounds = gun.defaultMagazine.rounds; } if (IsConnected) { gun.Fusion_LoadMagazine(rounds, callback); return; } gun.ammoSocket.ForceLoadAsync(new MagazineData { spawnable = gun.defaultMagazine.spawnable, rounds = rounds, platform = gun.defaultMagazine.platform }).GetAwaiter().OnCompleted((Action)something); void something() { gun.MagazineState.SetCartridge(rounds); callback?.Invoke(); } } internal static void MsgFusionPrefix(string message) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) MsgPrefix("Fusion", message, Color.cyan); } internal static void Warn(string message) { Core.Logger.Warning("[Fusion] " + message); } internal static void Error(string message) { Core.Logger.Warning("[Fusion] " + message); } internal static void MsgPrefix(string prefix, string message, Color color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) Core.Logger.Msg("[" + ConsoleExtensions.Pastel(prefix, color.ToHEX()) + "] " + message); } } public class FusionPlayer { public string DisplayName { get; } public byte SmallID { get; } public ulong PlatformID { get; } public FusionPlayer(byte SmallID, ulong PlatformID, string displayName) { DisplayName = displayName; this.SmallID = SmallID; this.PlatformID = PlatformID; base..ctor(); } } public class SynchronousFileSystemWatcher : IDisposable { private readonly FileSystemWatcher _watcher = new FileSystemWatcher(); private readonly List<EventArgs> _Queue = new List<EventArgs>(); public bool EnableRaisingEvents { get { return _watcher.EnableRaisingEvents; } set { _watcher.EnableRaisingEvents = value; } } public NotifyFilters NotifyFilter { get { return _watcher.NotifyFilter; } set { _watcher.NotifyFilter = value; } } public string Filter { get { return _watcher.Filter; } set { _watcher.Filter = value; } } public Collection<string> Filters => _watcher.Filters; public string Path { get { return _watcher.Path; } set { _watcher.Path = value; } } public IReadOnlyList<EventArgs> Queue => _Queue.AsReadOnly(); public event EventHandler<RenamedEventArgs> Renamed; public event EventHandler<FileSystemEventArgs> Created; public event EventHandler<FileSystemEventArgs> Deleted; public event EventHandler<FileSystemEventArgs> Changed; public event EventHandler Disposed; public event EventHandler<ErrorEventArgs> Error; public SynchronousFileSystemWatcher() { Init(); } public SynchronousFileSystemWatcher(string path) { _watcher.Path = path; Init(); } public SynchronousFileSystemWatcher(string path, string filter) { _watcher.Path = path; _watcher.Filter = filter; Init(); } private void Init() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown _watcher.Renamed += delegate(object sender, RenamedEventArgs e) { _Queue.Add(e); }; _watcher.Created += delegate(object sender, FileSystemEventArgs e) { _Queue.Add(e); }; _watcher.Deleted += delegate(object sender, FileSystemEventArgs e) { _Queue.Add(e); }; _watcher.Changed += delegate(object sender, FileSystemEventArgs e) { _Queue.Add(e); }; _watcher.Disposed += delegate(object? sender, EventArgs e) { _Queue.Add(e); }; _watcher.Error += delegate(object sender, ErrorEventArgs e) { _Queue.Add(e); }; ((MelonEventBase<LemonAction>)(object)MelonEvents.OnUpdate).Subscribe(new LemonAction(Update), 0, false); } private void Update() { if (Queue.Count <= 0) { return; } for (int num = Queue.Count - 1; num >= 0; num--) { EventArgs eventArgs = _Queue[num]; try { if (eventArgs is RenamedEventArgs e) { this.Renamed?.Invoke(this, e); } else if (eventArgs is FileSystemEventArgs fileSystemEventArgs) { if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Created) { this.Created?.Invoke(this, fileSystemEventArgs); } else if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Deleted) { this.Deleted?.Invoke(this, fileSystemEventArgs); } else if (fileSystemEventArgs.ChangeType == WatcherChangeTypes.Changed) { this.Changed?.Invoke(this, fileSystemEventArgs); } } else if (eventArgs is ErrorEventArgs e2) { this.Error?.Invoke(this, e2); } else if (eventArgs != null) { EventArgs e3 = eventArgs; try { this.Disposed?.Invoke(this, e3); } catch (Exception ex) { MelonLogger.Error("SynchronousFileSystemWatcher | An unexpected error has occurred while running Disposed event", ex); } finally { Dispose(); } } } catch (Exception ex2) { MelonLogger.Error("SynchronousFileSystemWatcher | An unexpected error has occurred while triggering file system watcher events", ex2); } finally { _Queue.RemoveAt(num); } } } public void Dispose() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown try { _watcher.Dispose(); } catch (Exception ex) { MelonLogger.Error("SynchronousFileSystemWatcher | An exception occurred while disposing of FileSystemWatcher", ex); } ((MelonEventBase<LemonAction>)(object)MelonEvents.OnUpdate).Unsubscribe(new LemonAction(Update)); GC.SuppressFinalize(this); } } public class Thunderstore { public readonly string UserAgent; public bool IsV1Deprecated; public Thunderstore(string userAgent) { UserAgent = userAgent; } public Thunderstore(string userAgent, bool isV1Deprecated) : this(userAgent) { IsV1Deprecated = isV1Deprecated; } public Thunderstore() { Assembly executingAssembly = Assembly.GetExecutingAssembly(); if (executingAssembly != null) { AssemblyName name = executingAssembly.GetName(); if (name != null) { UserAgent = $"{name.Name} / {name.Version} C# Application"; } } } public Thunderstore(bool isV1Deprecated) { IsV1Deprecated = isV1Deprecated; Assembly executingAssembly = Assembly.GetExecutingAssembly(); if (executingAssembly != null) { AssemblyName name = executingAssembly.GetName(); if (name != null) { UserAgent = $"{name.Name} / {name.Version}"; } } } public Package GetPackage(string @namespace, string name) { Task<HttpResponseMessage> async = new HttpClient { DefaultRequestHeaders = { { "User-Agent", UserAgent }, { "Accept", "application/json" } } }.GetAsync($"https://thunderstore.io/api/experimental/package/{@namespace}/{name}/"); async.Wait(); HttpResponseMessage httpResponseMessage = async?.Result; if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully) { if (httpResponseMessage.IsSuccessStatusCode) { Task<string> task = httpResponseMessage.Content.ReadAsStringAsync(); task.Wait(); string text = task?.Result; if (task != null && text != null && task.IsCompletedSuccessfully) { Package package = JsonSerializer.Deserialize<Package>(text); if (!IsV1Deprecated && package != null) { V1PackageMetrics packageMetrics = GetPackageMetrics(@namespace, name); if (packageMetrics != null) { package.TotalDownloads = packageMetrics.Downloads; package.RatingScore = packageMetrics.RatingScore; } } return package; } } else { if (IsThunderstoreError(httpResponseMessage)) { if (IsPackageNotFound(httpResponseMessage)) { throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}' & namespace '{@namespace}'", @namespace, name, httpResponseMessage); } throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage); } httpResponseMessage.EnsureSuccessStatusCode(); } } return null; } public V1PackageMetrics GetPackageMetrics(string @namespace, string name) { if (IsV1Deprecated) { return null; } Task<HttpResponseMessage> async = new HttpClient { DefaultRequestHeaders = { { "User-Agent", UserAgent }, { "Accept", "application/json" } } }.GetAsync($"https://thunderstore.io/api/v1/package-metrics/{@namespace}/{name}/"); async.Wait(); HttpResponseMessage httpResponseMessage = async?.Result; if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully) { if (httpResponseMessage.IsSuccessStatusCode) { Task<string> task = httpResponseMessage.Content.ReadAsStringAsync(); task.Wait(); string text = task?.Result; if (task != null && text != null && task.IsCompletedSuccessfully) { return JsonSerializer.Deserialize<V1PackageMetrics>(text); } } else { if (IsThunderstoreError(httpResponseMessage)) { if (IsPackageNotFound(httpResponseMessage)) { throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}' & namespace '{@namespace}'", @namespace, name, httpResponseMessage); } throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage); } httpResponseMessage.EnsureSuccessStatusCode(); } } return null; } public PackageVersion GetPackage(string @namespace, string name, string version) { Task<HttpResponseMessage> async = new HttpClient { DefaultRequestHeaders = { { "User-Agent", UserAgent }, { "Accept", "application/json" } } }.GetAsync($"https://thunderstore.io/api/experimental/package/{@namespace}/{name}/{version}"); async.Wait(); HttpResponseMessage httpResponseMessage = async?.Result; if (async != null && httpResponseMessage != null && async.IsCompletedSuccessfully) { if (httpResponseMessage.IsSuccessStatusCode) { Task<string> task = httpResponseMessage.Content.ReadAsStringAsync(); task.Wait(); string text = task?.Result; if (task != null && text != null && task.IsCompletedSuccessfully) { return JsonSerializer.Deserialize<PackageVersion>(text); } } else { if (IsThunderstoreError(httpResponseMessage)) { if (IsPackageNotFound(httpResponseMessage)) { throw new ThunderstorePackageNotFoundException($"Thunderstore could not find a package with name '{name}', namespace '{@namespace}' & version '{version}'", @namespace, name, version, httpResponseMessage); } throw new ThunderstoreErrorException("Thunderstore API has thrown an unexpected error!", httpResponseMessage); } httpResponseMessage.EnsureSuccessStatusCode(); } } return null; } public bool IsLatestVersion(string @namespace, string name, string currentVersion) { SemVersion currentVersion2 = default(SemVersion); if (SemVersion.TryParse(currentVersion, ref currentVersion2, false)) { return IsLatestVersion(@namespace, name, currentVersion2); } return false; } public bool IsLatestVersion(string @namespace, string name, Version currentVersion) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown return IsLatestVersion(@namespace, name, new SemVersion(currentVersion)); } public bool IsLatestVersion(string @namespace, string name, SemVersion currentVersion) { if (!IsV1Deprecated) { return GetPackageMetrics(@namespace, name)?.IsLatestVersion(currentVersion) ?? false; } return GetPackage(@namespace, name)?.IsLatestVersion(currentVersion) ?? false; } private static bool IsPackageNotFound(HttpResponseMessage response) { if (response.StatusCode != HttpStatusCode.NotFound) { return false; } Task<string> task = response.Content.ReadAsStringAsync(); task.Wait(); string result = task.Result; if (string.IsNullOrWhiteSpace(result)) { return false; } ThunderstoreErrorResponse thunderstoreErrorResponse; try { thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result); } catch (JsonException) { return false; } if (thunderstoreErrorResponse != null) { return string.Equals(thunderstoreErrorResponse.Details, "Not found.", StringComparison.OrdinalIgnoreCase); } return false; } private static bool IsThunderstoreError(HttpResponseMessage response) { if (response.IsSuccessStatusCode) { return false; } Task<string> task = response.Content.ReadAsStringAsync(); task.Wait(); string result = task.Result; if (string.IsNullOrWhiteSpace(result)) { return false; } ThunderstoreErrorResponse thunderstoreErrorResponse; try { thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result); } catch (JsonException) { return false; } if (thunderstoreErrorResponse != null) { return !string.IsNullOrWhiteSpace(thunderstoreErrorResponse.Details); } return false; } } public class Package { [JsonPropertyName("namespace")] [JsonInclude] public string Namespace { get; internal set; } [JsonPropertyName("name")] [JsonInclude] public string Name { get; internal set; } [JsonPropertyName("full_name")] [JsonInclude] public string FullName { get; internal set; } [JsonPropertyName("owner")] [JsonInclude] public string Owner { get; internal set; } [JsonPropertyName("package_url")] [JsonInclude] public string PackageUrl { get; internal set; } [JsonPropertyName("date_created")] [JsonInclude] public DateTime CreatedAt { get; internal set; } [JsonPropertyName("date_updated")] [JsonInclude] public DateTime UpdatedAt { get; internal set; } [JsonPropertyName("rating_score")] [JsonInclude] public int RatingScore { get; internal set; } [JsonPropertyName("is_pinned")] [JsonInclude] public bool IsPinned { get; internal set; } [JsonPropertyName("is_deprecated")] [JsonInclude] public bool IsDeprecated { get; internal set; } [JsonPropertyName("total_downloads")] [JsonInclude] public int TotalDownloads { get; internal set; } [JsonPropertyName("latest")] [JsonInclude] public PackageVersion Latest { get; internal set; } [JsonPropertyName("community_listings")] [JsonInclude] public PackageListing[] CommunityListings { get; internal set; } public bool IsLatestVersion(string current) { if (string.IsNullOrWhiteSpace(current)) { return false; } if (Latest == null || Latest.SemanticVersion == (SemVersion)null) { return false; } SemVersion val = default(SemVersion); if (SemVersion.TryParse(current, ref val, false)) { return val >= Latest.SemanticVersion; } return false; } public bool IsLatestVersion(SemVersion current) { if (current == (SemVersion)null) { return false; } if (Latest == null || Latest.SemanticVersion == (SemVersion)null) { return false; } return current >= Latest.SemanticVersion; } public bool IsLatestVersion(Version current) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (current == null) { return false; } if (Latest == null || Latest.SemanticVersion == (SemVersion)null) { return false; } return new SemVersion(current) >= Latest.SemanticVersion; } } public class PackageVersion { [JsonPropertyName("namespace")] [JsonInclude] public string Namespace { get; internal set; } [JsonPropertyName("name")] [JsonInclude] public string Name { get; internal set; } [JsonPropertyName("version_number")] [JsonInclude] public string Version { get { return ((object)SemanticVersion).ToString(); } internal set { SemanticVersion = SemVersion.Parse(value, false); } } [JsonIgnore] public SemVersion SemanticVersion { get; internal set; } [JsonPropertyName("full_name")] [JsonInclude] public string FullName { get; internal set; } [JsonPropertyName("description")] [JsonInclude] public string Description { get; internal set; } [JsonPropertyName("icon")] [JsonInclude] public string Icon { get; internal set; } [JsonPropertyName("dependencies")] [JsonInclude] public List<string> Dependencies { get; internal set; } [JsonPropertyName("download_url")] [JsonInclude] public string DownloadUrl { get; internal set; } [JsonPropertyName("date_created")] [JsonInclude] public DateTime CreatedAt { get; internal set; } [JsonPropertyName("downloads")] [JsonInclude] public int Downloads { get; internal set; } [JsonPropertyName("website_url")] [JsonInclude] public string WebsiteURL { get; internal set; } [JsonPropertyName("is_active")] [JsonInclude] public bool IsActive { get; internal set; } } public class PackageListing { public enum ReviewStatusEnum { UNREVIEWED, APPROVED, REJECTED } [JsonPropertyName("has_nsfw_content")] [JsonInclude] public bool HasNSFWContent { get; internal set; } [JsonPropertyName("categories")] [JsonInclude] public List<string> Categories { get; internal set; } [JsonPropertyName("community")] [JsonInclude] public string Community { get; internal set; } [JsonPropertyName("review_status")] [JsonInclude] public string ReviewStatusString { get { return ReviewStatus.ToString(); } internal set { if (value == null) { throw new ArgumentNullException("value"); } if (string.Equals(value, "unreviewed", StringComparison.OrdinalIgnoreCase)) { ReviewStatus = ReviewStatusEnum.UNREVIEWED; } else if (string.Equals(value, "approved", StringComparison.OrdinalIgnoreCase)) { ReviewStatus = ReviewStatusEnum.APPROVED; } else if (string.Equals(value, "rejected", StringComparison.OrdinalIgnoreCase)) { ReviewStatus = ReviewStatusEnum.REJECTED; } } } [JsonIgnore] public ReviewStatusEnum ReviewStatus { get; internal set; } } public class V1PackageMetrics { [JsonPropertyName("downloads")] [JsonInclude] public int Downloads { get; internal set; } [JsonPropertyName("rating_score")] [JsonInclude] public int RatingScore { get; internal set; } [JsonPropertyName("latest_version")] [JsonInclude] public string LatestVersion { get { return ((object)LatestSemanticVersion).ToString(); } internal set { LatestSemanticVersion = SemVersion.Parse(value, false); } } [JsonIgnore] public SemVersion LatestSemanticVersion { get; internal set; } public bool IsLatestVersion(string current) { if (string.IsNullOrWhiteSpace(current)) { return false; } if (LatestSemanticVersion == (SemVersion)null) { return false; } SemVersion val = default(SemVersion); if (SemVersion.TryParse(current, ref val, false)) { return val >= LatestSemanticVersion; } return false; } public bool IsLatestVersion(SemVersion current) { if (current == (SemVersion)null) { return false; } if (LatestSemanticVersion == (SemVersion)null) { return false; } return current >= LatestSemanticVersion; } public bool IsLatestVersion(Version current) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (current == null) { return false; } if (LatestSemanticVersion == (SemVersion)null) { return false; } return new SemVersion(current) >= LatestSemanticVersion; } } public class ThunderstoreErrorResponse { [JsonPropertyName("detail")] [JsonInclude] public string Details { get; internal set; } } public class ThunderstoreErrorException : Exception { public string Details { get; } public HttpStatusCode HttpStatusCode { get; } public ThunderstoreErrorException() { } public ThunderstoreErrorException(string message) : base(message) { } public ThunderstoreErrorException(string message, Exception innerException) : base(message, innerException) { } public ThunderstoreErrorException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException) : base(message, innerException) { Details = details; HttpStatusCode = httpStatusCode; } public ThunderstoreErrorException(string message, HttpResponseMessage response) : base(message) { if (response.IsSuccessStatusCode) { return; } HttpStatusCode = response.StatusCode; Task<string> task = response.Content.ReadAsStringAsync(); task.Wait(); string result = task.Result; if (string.IsNullOrWhiteSpace(result)) { Details = string.Empty; return; } ThunderstoreErrorResponse thunderstoreErrorResponse; try { thunderstoreErrorResponse = JsonSerializer.Deserialize<ThunderstoreErrorResponse>(result); } catch (JsonException) { Details = string.Empty; return; } if (thunderstoreErrorResponse != null) { Details = thunderstoreErrorResponse.Details; } } } public class ThunderstorePackageNotFoundException : ThunderstoreErrorException { public string Namespace { get; } public string Name { get; } public string Version { get; } public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string details, HttpStatusCode httpStatusCode, Exception innerException) : base(message, details, httpStatusCode, innerException) { Namespace = @namespace; Name = name; } public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, string details, HttpStatusCode httpStatusCode, Exception innerException) : base(message, details, httpStatusCode, innerException) { Namespace = @namespace; Name = name; Version = version; } public ThunderstorePackageNotFoundException(string message, string @namespace, string name, HttpResponseMessage response) : base(message, response) { Namespace = @namespace; Name = name; } public ThunderstorePackageNotFoundException(string message, string @namespace, string name, string version, HttpResponseMessage response) : base(message, response) { Namespace = @namespace; Name = name; Version = version; } public ThunderstorePackageNotFoundException() { } public ThunderstorePackageNotFoundException(string message) : base(message) { } public ThunderstorePackageNotFoundException(string message, Exception innerException) : base(message, innerException) { } public ThunderstorePackageNotFoundException(string message, string details, HttpStatusCode httpStatusCode, Exception innerException) : base(message, details, httpStatusCode, innerException) { } public ThunderstorePackageNotFoundException(string message, HttpResponseMessage response) : base(message, response) { } } } namespace KeepInventory.Saves.V2 { [JsonSourceGenerationOptions(WriteIndented = false)] public class GunInfo { [JsonPropertyName("IsMag")] public bool IsMag { get; set; } [JsonPropertyName("IsBulletInChamber")] public bool IsBulletInChamber { get; set; } [JsonPropertyName("FireMode")] public FireMode FireMode { get; set; } [JsonPropertyName("RoundsLeft")] public int RoundsLeft { get; set; } [JsonPropertyName("HammerState")] public HammerStates HammerState { get; set; } [JsonPropertyName("SlideState")] public SlideStates SlideState { get; set; } [JsonPropertyName("CartridgeState")] public CartridgeStates CartridgeState { get; set; } [JsonPropertyName("HasFiredOnce")] public bool HasFiredOnce { get; set; } [JsonConstructor] public GunInfo() { } public static GunInfo Parse(Gun gun) { //IL_0025: 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_003d: 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) GunInfo gunInfo = new GunInfo { IsMag = gun.HasMagazine(), IsBulletInChamber = ((Object)(object)gun.chamberedCartridge != (Object)null), FireMode = gun.fireMode, HammerState = gun.hammerState, SlideState = gun.slideState, HasFiredOnce = gun.hasFiredOnce, CartridgeState = gun.cartridgeState }; if (gun.MagazineState != null) { gunInfo.RoundsLeft = gun.MagazineState.AmmoCount; } return gunInfo; } public static GunInfo Parse(KeepInventory.Saves.V1.GunInfo gunInfoV1) { //IL_0024: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (gunInfoV1 == null) { return null; } return new GunInfo { IsMag = gunInfoV1.IsMag, IsBulletInChamber = gunInfoV1.IsBulletInChamber, FireMode = gunInfoV1.FireMode, HammerState = gunInfoV1.HammerState, SlideState = gunInfoV1.SlideState, HasFiredOnce = gunInfoV1.HasFiredOnce, CartridgeState = gunInfoV1.CartridgeState, RoundsLeft = gunInfoV1.RoundsLeft }; } public MagazineData GetMagazineData(Gun gun) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown return new MagazineData { spawnable = gun.defaultMagazine.spawnable, rounds = RoundsLeft, platform = gun.defaultMagazine.platform }; } public string Serialize() { return JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = false }); } public static string Serialize(GunInfo gunInfo) { return JsonSerializer.Serialize(gunInfo, new JsonSerializerOptions { WriteIndented = false }); } public static GunInfo Deserialize(string json) { return JsonSerializer.Deserialize<GunInfo>(json); } } [JsonSourceGenerationOptions(WriteIndented = true, IncludeFields = true, IgnoreReadOnlyFields = false, IgnoreReadOnlyProperties = false)] public class Save { [JsonPropertyName("Version")] public readonly int Version = 2; [JsonIgnore] private string _name; [JsonIgnore] private string _id; [JsonIgnore] public Color DrawingColor = Color.white; [JsonIgnore] private string _filePath; [JsonIgnore] private int _lightAmmo = -1; [JsonIgnore] private int _mediumAmmo = -1; [JsonIgnore] private int _heavyAmmo = -1; private List<SaveSlot> _inventorySlots; internal bool Saving; [JsonPropertyName("Name")] public string Name { get { return _name; } set { string name = _name; _name = value; this.OnPropertyChanged?.Invoke("Name", name, value); } } [JsonPropertyName("ID")] public string ID { get { return _id; } set { string id = _id; _id = value; this.OnPropertyChanged?.Invoke("ID", id, value); } } [JsonPropertyName("Color")] public float[] Color { get { return new float[3] { DrawingColor.r * 255f, DrawingColor.g * 255f, DrawingColor.b * 255f }; } set { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) if (value == null || value.Length != 3) { DrawingColor = Color.white; return; } Color drawingColor = DrawingColor; DrawingColor = new Color(value[0] / 255f, value[1] / 255f, value[2] / 255f); this.OnPropertyChanged?.Invoke("Color", drawingColor, DrawingColor); } } [JsonIgnore] public bool IsFileWatcherEnabled { get; set; } = true; [JsonIgnore] public string FilePath { get { return _filePath; } internal set { string filePath = _filePath; _filePath = value; this.OnPropertyChanged?.Invoke("FilePath", filePath, value); } } [JsonPropertyName("LightAmmo")] public int LightAmmo { get { return _lightAmmo; } set { int lightAmmo = _lightAmmo; _lightAmmo = value; this.OnPropertyChanged?.Invoke("LightAmmo", lightAmmo, value); } } [JsonPropertyName("MediumAmmo")] public int MediumAmmo { get { return _mediumAmmo; } set { int mediumAmmo = _mediumAmmo; _mediumAmmo = value; this.OnPropertyChanged?.Invoke("MediumAmmo", mediumAmmo, value); } } [JsonPropertyName("HeavyAmmo")] public int HeavyAmmo { get { return _heavyAmmo; } set { int heavyAmmo = _heavyAmmo; _heavyAmmo = value; this.OnPropertyChanged?.Invoke("HeavyAmmo", heavyAmmo, value); } } [JsonPropertyName("InventorySlots")] public List<SaveSlot> InventorySlots { get { return _inventorySlots; } set { List<SaveSlot> inventorySlots = _inventorySlots; _inventorySlots = value; this.OnPropertyChanged?.Invoke("InventorySlots", inventorySlots, value); } } public event Action<string, object, object> OnPropertyChanged; [JsonConstructor] public Save() { }//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) public Save(Save old) { //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) _name = old.Name; _id = old.ID; Color = old.Color; _lightAmmo = old.LightAmmo; _mediumAmmo = old.MediumAmmo; _heavyAmmo = old.HeavyAmmo; _inventorySlots = old.InventorySlots.ToList(); } public Save(int Version, string Name, string ID, float[] Color, int LightAmmo, int MediumAmmo, int HeavyAmmo, List<SaveSlot> InventorySlots) { //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) if (Version != 2) { throw new ArgumentException($"The V2 save object is not made for saves with version '{Version}'"); } this.Version = Version; _name = Name; _id = ID; this.Color = Color; _lightAmmo = LightAmmo; _mediumAmmo = MediumAmmo; _heavyAmmo = HeavyAmmo; _inventorySlots = InventorySlots; if (string.IsNullOrWhiteSpace(_id)) { throw new Exception("ID cannot be null or empty"); } } public Save(string id, string name, Color color, KeepInventory.Saves.V1.Save v1save) { //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_0049: 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) _id = id; _name = name; DrawingColor = color; _lightAmmo = v1save.LightAmmo; _mediumAmmo = v1save.MediumAmmo; _heavyAmmo = v1save.HeavyAmmo; List<SaveSlot> _new = new List<SaveSlot>(); v1save.InventorySlots?.ForEach(delegate(KeepInventory.Saves.V1.SaveSlot x) { _new.Add(new SaveSlot(x)); }); _inventorySlots = _new; } public Save(string id, string name, Color color, KeepInventory.Saves.V0.Save v0save) { //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_0049: 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) _id = id; _name = name; DrawingColor = color; _lightAmmo = v0save.AmmoLight; _mediumAmmo = v0save.AmmoMedium; _heavyAmmo = v0save.AmmoHeavy; List<SaveSlot> _new = new List<SaveSlot>(); v0save.ItemSlots?.ForEach(delegate(KeyValuePair<string, string> x) { _new.Add(new SaveSlot { Barcode = x.Value, SlotName = x.Key, Type = SaveSlot.SpawnableType.Other, GunInfo = null }); }); _inventorySlots = _new; } internal void Update(Save save) { ArgumentNullException.ThrowIfNull(save, "save"); if (!string.IsNullOrWhiteSpace(save.ID)) { if (SaveManager.Saves.Any((Save x) => x.ID == save.ID && x != this)) { Core.Logger.Error("The new ID is already used in another save, will not overwrite"); throw new ArgumentException("The new ID is already used in another save, will not overwrite"); } ID = save.ID; if (Name != save.Name) { Name = save.Name; } if (Color != save.Color) { Color = save.Color; } if (InventorySlots != save.InventorySlots) { InventorySlots = save.InventorySlots; } if (HeavyAmmo != save.HeavyAmmo) { HeavyAmmo = save.HeavyAmmo; } if (MediumAmmo != save.MediumAmmo) { MediumAmmo = save.MediumAmmo; } if (LightAmmo != save.LightAmmo) { LightAmmo = save.LightAmmo; } return; } Core.Logger.Error("The new ID is null or empty, will not overwrite"); throw new ArgumentException("The new ID is null or empty, will not overwrite"); } public void SaveToFile(bool printMessage = true) { if (!string.IsNullOrWhiteSpace(FilePath) && File.Exists(FilePath)) { Saving = true; if (printMessage) { Core.Logger.Msg("Saving '" + ID + "' to file..."); } try { string value = JsonSerializer.Serialize(this, SaveManager.SerializeOptions); FileStream fileStream = File.Create(FilePath); using StreamWriter streamWriter = new StreamWriter(fileStream) { AutoFlush = true }; fileStream.Position = 0L; streamWriter.Write(value); streamWriter.DisposeAsync().AsTask().ContinueWith(delegate(Task task) { if (task.IsCompletedSuccessfully) { if (printMessage) { Core.Logger.Msg("Saved '" + ID + "' to file successfully!"); } } else if (printMessage) { Core.Logger.Error("Failed to save '" + ID + "' to file", (Exception)task.Exception); } Saving = false; }); return; } catch (Exception ex) { if (printMessage) { Core.Logger.Error("Failed to save '" + ID + "' to file", ex); } Saving = false; throw; } } if (printMessage) { Core.Logger.Error("Save '" + ID + "' does not have a file set or it doesn't exist!"); } throw new FileNotFoundException("Save does not have a file!"); } public bool TrySaveToFile(bool printMessage = true) { try { SaveToFile(printMessage); return true; } catch (Exception) { return false; } } internal void Update(string path) { SaveManager.IgnoredFilePaths.Add(FilePath); if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } if (!File.Exists(path)) { throw new FileNotFoundException("Save file at '" + path + "' could be found"); } string text = SaveManager.ReadAllTextUsedFile(path); if (string.IsNullOrWhiteSpace(text) || !SaveManager.IsJSON(text)) { Core.Logger.Error("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content"); throw new Exception("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content"); } Save save = JsonSerializer.Deserialize<Save>(text, SaveManager.SerializeOptions); if (save != null) { Update(save); return; } Core.Logger.Error("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content"); throw new Exception("A save file at '" + path + "' was changed and the content are no longer suitable for loading as a save. This means that the save at runtime will not be overwritten by new content"); } public override string ToString() { return Name; } } public class SaveSlot { public enum SpawnableType { Gun, Other } [JsonPropertyName("SlotName")] public string SlotName { get; set; } [JsonPropertyName("Barcode")] public string Barcode { get; set; } [JsonPropertyName("Type")] public SpawnableType Type { get; set; } [JsonPropertyName("GunInfo")] public GunInfo GunInfo { get; set; } [JsonConstructor] public SaveSlot() { } public SaveSlot(string slotName, Barcode barcode) { SlotName = slotName; Barcode = barcode.ID; Type = SpawnableType.Other; GunInfo = null; } public SaveSlot(string slotName, Barcode barcode, SpawnableType type) { SlotName = slotName; Barcode = barcode.ID; Type = type; GunInfo = null; } public SaveSlot(string slotName, Barcode barcode, SpawnableType type, GunInfo gunInfo) { SlotName = slotName; Barcode = barcode.ID; Type = type; GunInfo = gunInfo; } public SaveSlot(string slotName, Barcode barcode, GunInfo gunInfo) { SlotName = slotName; Barcode = barcode.ID; Type = SpawnableType.Gun; GunInfo = gunInfo; } public SaveSlot(KeepInventory.Saves.V1.SaveSlot v1) { SlotName = v1.SlotName; Barcode = v1.Barcode; Type = (SpawnableType)v1.Type; GunInfo = GunInfo.Parse(v1.GunInfo); } } } namespace KeepInventory.Saves.V1 { [JsonSourceGenerationOptions(WriteIndented = false)] public class GunInfo { [JsonPropertyName("IsMag")] public bool IsMag { get; set; } [JsonPropertyName("IsBulletInChamber")] public bool IsBulletInChamber { get; set; } [JsonPropertyName("FireMode")] public FireMode FireMode { get; set; } [JsonPropertyName("RoundsLeft")] public int RoundsLeft { get; set; } [JsonPropertyName("HammerState")] public HammerStates HammerState { get; set; } [JsonPropertyName("SlideState")] public SlideStates SlideState { get; set; } [JsonPropertyName("CartridgeState")] public CartridgeStates CartridgeState { get; set; } [JsonPropertyName("HasFiredOnce")] public bool HasFiredOnce { get; set; } [JsonConstructor] public GunInfo() { } public static GunInfo Parse(Gun gun) { //IL_0025: 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_003d: 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) GunInfo gunInfo = new GunInfo { IsMag = gun.HasMagazine(), IsBulletInChamber = ((Object)(object)gun.chamberedCartridge != (Object)null), FireMode = gun.fireMode, HammerState = gun.hammerState, SlideState = gun.slideState, HasFiredOnce = gun.hasFiredOnce, CartridgeState = gun.cartridgeState }; if (gun.MagazineState != null) { gunInfo.RoundsLeft = gun.MagazineState.AmmoCount; } return gunInfo; } public MagazineData GetMagazineData(Gun gun) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown return new MagazineData { spawnable = gun.defaultMagazine.spawnable, rounds = RoundsLeft, platform = gun.defaultMagazine.platform }; } public string Serialize() { return JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = false }); } public static string Serialize(GunInfo gunInfo) { return JsonSerializer.Serialize(gunInfo, new JsonSerializerOptions { WriteIndented = false }); } public static GunInfo Deserialize(string json) { return JsonSerializer.Deserialize<GunInfo>(json); } } public class Save { [TomlPrecedingComment("The version of the save")] public readonly int Version = 1; [TomlPrecedingComment("The amount of light ammo left")] public int LightAmmo; [TomlPrecedingComment("The amount of medium ammo left")] public int MediumAmmo; [TomlPrecedingComment("The amount of heavy ammo left")] public int HeavyAmmo; [TomlPrecedingComment("List of all slots & the spawnables stored in them")] public List<SaveSlot> InventorySlots = new List<SaveSlot>(); public Save() { } public Save(Save old) { LightAmmo = old.LightAmmo; MediumAmmo = old.MediumAmmo; HeavyAmmo = old.HeavyAmmo; InventorySlots = old.InventorySlots.ToList(); } } public class SaveSlot { public enum SpawnableType { Gun, Other } public string SlotName { get; set; } public string Barcode { get; set; } public SpawnableType Type { get; set; } [TomlNonSerialized] public GunInfo GunInfo { get; set; } [TomlProperty("GunInfo")] public string GunInfo_JSON { get { return JsonSerializer.Serialize(GunInfo, new JsonSerializerOptions { WriteIndented = false }); } set { if (!string.IsNullOrWhiteSpace(value) && value != "null" && IsJSON(value)) { GunInfo = JsonSerializer.Deserialize<GunInfo>(value); } } } public SaveSlot() { } public SaveSlot(string slotName, Barcode barcode) { SlotName = slotName; Barcode = barcode.ID; Type = SpawnableType.Other; GunInfo = null; } public SaveSlot(string slotName, Barcode barcode, SpawnableType type) { SlotName = slotName; Barcode = barcode.ID; Type = type; GunInfo = null; } public SaveSlot(string slotName, Barcode barcode, SpawnableType type, GunInfo gunInfo) { SlotName = slotName; Barcode = barcode.ID; Type = type; GunInfo = gunInfo; } public SaveSlot(string slotName, Barcode barcode, SpawnableType type, string gunInfoJSON) { SlotName = slotName; Barcode = barcode.ID; Type = type; GunInfo_JSON = gunInfoJSON; } public SaveSlot(string slotName, Barcode barcode, GunInfo gunInfo) { SlotName = slotName; Barcode = barcode.ID; Type = SpawnableType.Gun; GunInfo = gunInfo; } public SaveSlot(string slotName, Barcode barcode, string gunInfoJSON) { SlotName = slotName; Barcode = barcode.ID; Type = SpawnableType.Gun; GunInfo_JSON = gunInfoJSON; } private static bool IsJSON(string text) { try { using (JsonDocument.Parse(text)) { return true; } } catch (JsonException) { return false; } } } } namespace KeepInventory.Saves.V0 { public class Save { [TomlPrecedingComment("The version of the save")] public readonly int Version; [TomlPrecedingComment("The amount of light ammo left")] public int AmmoLight; [TomlPrecedingComment("The amount of medium ammo left")] public int AmmoMedium; [TomlPrecedingComment("The amount of heavy ammo left")] public int AmmoHeavy; [TomlPrecedingComment("List of all slots & the spawnables stored in them")] public Dictionary<string, string> ItemSlots = new Dictionary<string, string>(); } } namespace KeepInventory.Patches { [HarmonyPatch(typeof(AmmoInventory), "Awake")] public static class AmmoInventoryPatches { public static KeepInventory.Saves.V2.Save Save { get; set; } public static void Postfix(AmmoInventory __instance) { if (Save == null || !PreferencesManager.AmmoSaving.Value || (Object)(object)__instance != (Object)(object)AmmoInventory.Instance) { return; } try { InventoryManager.AddSavedAmmo(Save); } catch (Exception ex) { Core.Logger.Error("An unexpected error has occurred while attempting to add saved ammo", ex); } finally { Save = null; } } } [HarmonyPatch(typeof(Player_Health), "Death")] public static class HealthPatches { private static void HolsterItem(Hand hand) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) GameObject currentAttachedGO = hand.m_CurrentAttachedGO; if ((Object)(object)currentAttachedGO == (Object)null) { return; } Grip component = currentAttachedGO.GetComponent<Grip>(); if ((Object)(object)component == (Object)null) { return; } IGrippable host = ((HandReciever)component).Host; GameObject hostGameObject = host.GetHostGameObject(); WeaponSlot val = ((hostGameObject != null) ? hostGameObject.GetComponentInChildren<WeaponSlot>() : null); if ((Object)(object)val == (Object)null) { return; } List<InventorySlotReceiver> list = Player.RigManager?.GetAllSlots(); if (list == null || list.Count == 0) { return; } foreach (InventorySlotReceiver item in list) { if (!((Object)(object)item._slottedWeapon != (Object)null) && item.slotType == val.slotType) { ((InventoryHandReceiver)item).OnHandDrop(host); } } } public static void Prefix(Player_Health __instance) { RigManager rigManager = ((Health)__instance)._rigManager; if (rigManager != null && rigManager.IsLocalPlayer() && PreferencesManager.HolsterHeldWeaponsOnDeath.Value && !Fusion.IsGamemodeStarted) { HolsterItem(Player.LeftHand); HolsterItem(Player.RightHand); } } } } namespace KeepInventory.Menu { public class BlankElement { public readonly FunctionElement Element; public BlankElement() { //IL_000c: 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_001c: Expected O, but got Unknown Element = new FunctionElement(string.Empty, Color.white, (Action)null); ((Element)Element).SetProperty((ElementProperties)1); } } public static class BoneMenu { [CompilerGenerated] private static class <>O { public static Action <0>__UpdatePresetsPage; public static Action <1>__ClearInventory; public static Action <2>__SetupBlacklistView; public static ServerEvent <3>__SetupSharingBlacklist; public static Action <4>__SetupSharingBlacklist; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__52_0; public static Action <>9__52_1; public static Action <>9__52_2; public static Action<bool> <>9__58_0; public static PlayerUpdate <>9__58_1; public static PlayerUpdate <>9__58_2; public static Predicate<FusionPlayer> <>9__59_0; public static Action <>9__60_3; public static Action <>9__62_3; internal void <Setup>b__52_0() { //IL_00fb: 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) if (BlacklistManager.IsCurrentLevelInBlacklist()) { BLHelper.SendNotification("Failure", "The current level is already in a predefined blacklist. Use the predefined blacklist to blacklist this level instead", showTitleOnPopup: true, 4f, (NotificationType)2); return; } List<string> value = PreferencesManager.BlacklistedLevels.Value; if (value.Contains(Core.levelInfo.barcode)) { try { int num = value.IndexOf(Core.levelInfo.barcode); if (num != -1) { value.RemoveAt(num); ((Element)Core.statusElement).ElementName = "Current Level is not blacklisted"; ((Element)Core.statusElement).ElementColor = Color.green; BLHelper.SendNotification("Success", "Successfully unblacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3); } return; } catch (Exception ex) { Core.Logger.Error("An unexpected error has occurred while unblacklisting the current level", ex); BLHelper.SendNotification("Failure", "An unexpected error has occurred while unblacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2); return; } } try { value.Add(Core.levelInfo.barcode); ((Element)Core.statusElement).ElementName = "Current Level is blacklisted"; ((Element)Core.statusElement).ElementColor = Color.red; BLHelper.SendNotification("Success", "Successfully blacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3); } catch (Exception ex2) { Core.Logger.Error("An unexpected error has occurred while removing the current level from blacklist", ex2); BLHelper.SendNotification("Failure", "An unexpected error has occurred while blacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2); } } internal void <Setup>b__52_1() { if (Core.CurrentSave != null) { InventoryManager.LoadSavedInventory(Core.CurrentSave); } else { BLHelper.SendNotification("Failure", "There is no default save!", showTitleOnPopup: true, 2f, (NotificationType)2); } } internal void <Setup>b__52_2() { Core.Logger.Msg("The current version is v1.3.0!!!!"); } internal void <SetupSharing>b__58_0(bool val) { ShareManager.Entry_SharingEnabled.Value = val; ShareManager.Category.SaveToFile(false); } internal void <SetupSharing>b__58_1(PlayerID _) { SetupSharingBlacklist(); } internal void <SetupSharing>b__58_2(PlayerID _) { SetupSharingBlacklist(); } internal bool <SetupSharingBlacklist>b__59_0(FusionPlayer x) { return x.SmallID == Fusion.GetLocalPlayerSmallID(); } internal void <SetupSaves>b__60_3() { SetupSaves(); } internal void <UpdatePresetsPage>b__62_3() { Core.Logger.Msg("Save removal denied"); } } private static readonly Dictionary<string, Page> PredefinedBlacklistPages = new Dictionary<string, Page>(); private static readonly List<Element> defaultSaveElements = new List<Element>(); private static readonly List<SavePage> SavePages = new List<SavePage>(); public static Page AuthorPage { get; private set; } public static Page ModPage { get; private set; } public static Page SavesPage { get; private set; } public static Page SavingConfigPage { get; private set; } public static Page EventsPage { get; private set; } public static Page SharingPage { get; private set; } public static Page SharingBlacklistPage { get; private set; } public static Page BlacklistPage { get; private set; } public static Page BlacklistViewPage { get; private set; } public static Page PredefinedBlacklistPage { get; private set; } public static Page OtherPage { get; private set; } public static bool IsSetup { get; private set; } public static bool RemoveSavesOnPress { get; private set; } internal static void Setup() { //IL_000a: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) AuthorPage = Page.Root.CreatePage("HAHOOS", Color.white, 0, true); ModPage = AuthorPage.CreatePage("KeepInventory", Color.yellow, 0, true); SetupSaves(); Core.DefaultSaveChanged += UpdatePresetsPage; EventsPage = ModPage.CreatePage("Events", Color.yellow, 0, true); EventsPage.CreateBoolPref("Save on Level Unload", Color.red, ref PreferencesManager.SaveOnLevelUnload, null, null, null, prefDefaultValue: true); EventsPage.CreateBoolPref("Load on Level Load", Color.green, ref PreferencesManager.LoadOnLevelLoad, null, null, null, prefDefaultValue: true); if (Core.HasFusion && Core.IsFusionLibraryInitialized) { SetupSharing(); } BlacklistPage = ModPage.CreatePage("Blacklist", Color.red, 0, true); PredefinedBlacklistPage = BlacklistPage.CreatePage("Predefined Blacklists", Color.cyan, 0, true); SetupPredefinedBlacklists(); BlacklistViewPage = BlacklistPage.CreatePage("View All", Color.magenta, 0, true); SetupBlacklistView(); Core.statusElement = BlacklistPage.CreateFunction("Blacklist Level from Saving/Loading", Color.red, (Action)delegate { //IL_00fb: 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) if (BlacklistManager.IsCurrentLevelInBlacklist()) { BLHelper.SendNotification("Failure", "The current level is already in a predefined blacklist. Use the predefined blacklist to blacklist this level instead", showTitleOnPopup: true, 4f, (NotificationType)2); return; } List<string> value = PreferencesManager.BlacklistedLevels.Value; if (value.Contains(Core.levelInfo.barcode)) { try { int num = value.IndexOf(Core.levelInfo.barcode); if (num != -1) { value.RemoveAt(num); ((Element)Core.statusElement).ElementName = "Current Level is not blacklisted"; ((Element)Core.statusElement).ElementColor = Color.green; BLHelper.SendNotification("Success", "Successfully unblacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3); } return; } catch (Exception ex) { Core.Logger.Error("An unexpected error has occurred while unblacklisting the current level", ex); BLHelper.SendNotification("Failure", "An unexpected error has occurred while unblacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2); return; } } try { value.Add(Core.levelInfo.barcode); ((Element)Core.statusElement).ElementName = "Current Level is blacklisted"; ((Element)Core.statusElement).ElementColor = Color.red; BLHelper.SendNotification("Success", "Successfully blacklisted current level (" + Core.levelInfo.title + ") from having the inventory saved and/or loaded!", showTitleOnPopup: true, 2.5f, (NotificationType)3); } catch (Exception ex2) { Core.Logger.Error("An unexpected error has occurred while removing the current level from blacklist", ex2); BLHelper.SendNotification("Failure", "An unexpected error has occurred while blacklisting the current level, check the console or logs for more details", showTitleOnPopup: true, 3f, (NotificationType)2); } }); SavingConfigPage = ModPage.CreatePage("Saving Config", Color.yellow, 4, true); SavingConfigPage.CreateBoolPref("Save Items", Color.white, ref PreferencesManager.ItemSaving, null, null, null, prefDefaultValue: true); SavingConfigPage.CreateBoolPref("Save Ammo", Color.white, ref PreferencesManager.AmmoSaving, null, null, null, prefDefaultValue: true); SavingConfigPage.CreateBoolPref("Save Gun Data", Color.white, ref PreferencesManager.SaveGunData, null, null, null, prefDefaultValue: true); OtherPage = ModPage.CreatePage("Other", Color.white, 0, true); OtherPage.CreateBoolPref("Show Notifications", Color.green, ref PreferencesManager.ShowNotifications, null, null, null, prefDefaultValue: true); OtherPage.CreateBoolPref("Holster Held Weapons on Death", Color.magenta, ref PreferencesManager.HolsterHeldWeaponsOnDeath); OtherPage.CreateFunction("Clear Inventory", Color.yellow, (Action)InventoryManager.ClearInventory); ModPage.CreateBlank(); ModPage.CreateFunction("Load inventory from default save", Color.yellow, (Action)delegate { if (Core.CurrentSave != null) { InventoryManager.LoadSavedInventory(Core.CurrentSave); } else { BLHelper.SendNotification("Failure", "There is no default save!", showTitleOnPopup: true, 2f, (NotificationType)2); } }); ((Element)ModPage.CreateFunction((Core.IsLatestVersion || Core.ThunderstorePackage == null) ? "Current Version: v1.3.0" : "Current Version: v1.3.0<br><color=#00FF00>(Update available!)</color>", Color.white, (Action)delegate { Core.Logger.Msg("The current version is v1.3.0!!!!"); })).SetProperty((ElementProperties)1); IsSetup = true; } internal static void SetupPredefinedBlacklists() { //IL_0114: 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_008e: 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) if (PredefinedBlacklistPage == null) { return; } PredefinedBlacklistPage.RemoveAll(); foreach (Blacklist blacklist in BlacklistManager.Blacklist) { if (!PredefinedBlacklistPages.ContainsKey(blacklist.ID)) { PredefinedBlacklistPages.Add(blacklist.ID, PredefinedBlacklistPage.CreatePage(blacklist.DisplayName, (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f)), 0, false)); } PredefinedBlacklistPage.CreateFunction($"{blacklist.DisplayName} ({blacklist.Levels.Length})", (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f)), (Action)delegate { Menu.OpenPage(PredefinedBlacklistPages[blacklist.ID]); }); SetupPredefinedBlacklistPage(blacklist.ID); } } internal static void SetupPredefinedBlacklistPage(string id) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0185: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) Page val2 = PredefinedBlacklistPages[id]; if (val2 == null) { return; } Blacklist blacklist = BlacklistManager.Blacklist.FirstOrDefault((Blacklist x) => x.ID == id); if (blacklist == null) { return; } val2.Name = blacklist.DisplayName; val2.Color = (Color)(blacklist.Enabled ? Color.red : new Color(0f, 1f, 0f)); val2.RemoveAll(); val2.CreateLabel("ID: " + blacklist.ID, Color.white); val2.CreateLabel("DisplayName: " + blacklist.DisplayName, Color.white); val2.CreateLabel($"Level Count: {blacklist.Levels.Length}", Color.white); val2.CreateBool("Enabled", Color.green, blacklist.Enabled, (Action<bool>)delegate(bool val) { BlacklistManager.SetEnabled(id, val); }); val2.CreateBlank(); Level[] levels = blacklist.Levels; foreach (Level level in levels) { LevelCrateReference val3 = new LevelCrateReference(level.Barcode); object obj; if ((int)val3 == 0) { obj = null; } else { LevelCrate crate = ((CrateReferenceT<LevelCrate>)val3).Crate; obj = ((crate != null) ? ((Scannable)crate).Title : null); } string text = (string)obj; ToggleFunctionElement toggleFunctionElement = val2.CreateToggleFunction(string.IsNullOrWhiteSpace(text) ? level.Barcode : (text + " (" + level.Barcode + ")"), Color.red, new Color(0f, 1f, 0f), null, !level.IsBlacklisted); toggleFunctionElement.OnStart += delegate { BlacklistManager.SetLevelBlacklisted(blacklist.ID, level.Barcode, blacklisted: false); }; toggleFunctionElement.OnCancel += delegate { BlacklistManager.SetLevelBlacklisted(blacklist.ID, level.Barcode, blacklisted: true); }; } } private static void SetupBlacklistView() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (BlacklistViewPage == null) { return; } BlacklistViewPage.RemoveAll(); BlacklistViewPage.CreateFunction("Refresh", Color.yellow, (Action)SetupBlacklistView); BlacklistViewPage.CreateBlank(); LevelCrate val = default(LevelCrate); foreach (string level in PreferencesManager.BlacklistedLevels.Value) { if (!((CrateReferenceT<LevelCrate>)new LevelCrateReference(level)).TryGetCrate(ref val)) { continue; } FunctionElement element = null; element = BlacklistViewPage.CreateFunction(((Scannable)val).Title, Color.white, (Action)delegate { //IL_0051: Unknown result type (might be due to invalid IL or missing references) PreferencesManager.BlacklistedLevels.Value.Remove(level); BlacklistViewPage.Remove((Element)(object)element); if (Core.levelInfo.barcode == level) { ((Element)Core.statusElement).ElementName = "Current level is not blacklisted"; ((Element)Core.statusElement).ElementColor = Color.green; } }); } } internal static void SetupSharing() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown if (SharingPage == null) { SharingPage = ModPage.CreatePage("Sharing", Color.cyan, 0, true); } SharingPage.CreateBool("Enabled", Color.red, ShareManager.Entry_SharingEnabled.Value, (Action<bool>)delegate(bool val) { ShareManager.Entry_SharingEnabled.Value = val; ShareManager.Category.SaveToFile(false); }); if (SharingBlacklistPage == null) { SharingBlacklistPage = SharingPage.CreatePage("Blacklist", Color.red, 0, true); } SetupSharingBlacklist(); object obj = <>O.<3>__SetupSharingBlacklist; if (obj == null) { ServerEvent val2 = SetupSharingBlacklist; <>O.<3>__SetupSharingBlacklist = val2; obj = (object)val2; } MultiplayerHooking.OnDisconnected += (ServerEvent)obj; object obj2 = <>O.<3>__SetupSharingBlacklist; if (obj2 == null) { ServerEvent val3 = SetupSharingBlacklist; <>O.<3>__SetupSharingBlacklist = val3; obj2 = (object)val3; } MultiplayerHooking.OnJoinedServer += (ServerEvent)obj2; object obj3 = <>O.<3>__SetupSharingBlacklist; if (obj3 == null) { ServerEvent val4 = SetupSharingBlacklist; <>O.<3>__SetupSharingBlacklist = val4; obj3 = (object)val4; } MultiplayerHooking.OnStartedServer += (ServerEvent)obj3; object obj4 = <>c.<>9__58_1; if (obj4 == null) { PlayerUpdate val5 = delegate { SetupSharingBlacklist(); }; <>c.<>9__58_1 = val5; obj4 = (object)val5; } MultiplayerHooking.OnPlayerJoined += (PlayerUpdate)obj4; object obj5 = <>c.<>9__58_2; if (obj5 == null) { PlayerUpdate val6 = delegate { SetupSharingBlacklist(); }; <>c.<>9__58_2 = val6; obj5 = (object)val6; } MultiplayerHooking.OnPlayerLeft += (PlayerUpdate)obj5; } internal static void SetupSharingBlacklist() { //IL_0014: 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) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) SharingBlacklistPage.RemoveAll(); SharingBlacklistPage.CreateFunction("Refresh", Color.yellow, (Action)SetupSharingBlacklist); SharingBlacklistPage.CreateBlank(); List<FusionPlayer> players = Fusion.GetPlayers(); players.RemoveAll((FusionPlayer x) => x.SmallID == Fusion.GetLocalPlayerSmallID()); if (players.Count == 0) { SharingBlacklistPage.CreateLabel("Nothing to show here :(", Color.white); return; } foreach (FusionPlayer player in players) { ToggleFunctionElement toggleFunctionElement = SharingBlacklistPage.CreateToggleFunction(player.DisplayName, Color.white, null, ShareManager.Entry_SharingBlacklist.Value.Contains(player.PlatformID)); toggleFunctionElement.OnStart += delegate { ShareManager.Entry_SharingBlacklist.Value.Add(player.PlatformID); ShareManager.Category.SaveToFile(false); }; toggleFunctionElement.OnCancel += delegate { ShareManager.Entry_SharingBlacklist.Value.Remove(player.PlatformID); ShareManager.Category.SaveToFile(false); }; } } internal static void SetupSaves() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (SavesPage == null) { SavesPage = ModPage.CreatePage("Saves", Color.cyan, 0, true); } SavesPage.RemoveAll(); StringElement nameElement = SavesPage.CreateString("Name", Color.white, string.Empty, (Action<string>)null); FunctionElement item = SavesPage.CreateFunction("<color=#00FF00>Create</color>", Color.white, (Action)delegate { SaveManager.RegisterSave(new KeepInventory.Saves.V2.Save { Name = nameElement.Value, InventorySlots = new List<KeepInventory.Saves.V2.SaveSlot>(), HeavyAmmo = 0, LightAmmo = 0, MediumAmmo = 0, ID = nameElement.Value.ToLower() + "-" + SaveManager.GenerateRandomID(6) }); }); ToggleFunctionElement func = SavesPage.CreateToggleFunction("Remove [OFF]", Color.cyan, Color.red, null); func.OnStart += delegate { ((Element)func.Element).ElementName = "Remove [ON]"; RemoveSavesOnPress = true; }; func.OnCancel += delegate { ((Element)func.Element).ElementName = "Remove [OFF]"; RemoveSavesOnPress = false; }; FunctionElement item2 = SavesPage.CreateFunction("Refresh", Color.yellow, (Action)delegate { SetupSaves(); }); BlankElement blankElement = SavesPage.CreateBlank(); if (defaultSaveElements.Count == 0) { defaultSaveElements.Add((Element)(object)nameElement); defaultSaveElements.Add((Element)(object)item); defaultSaveElements.Add((Element)(object)item2); defaultSaveElements.Add((Element)(object)func.Element); defaultSaveElements.Add((Element)(object)blankElement.Element); } UpdatePresetsPage(); } internal static void UpdatePresetsPage() { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) if (SavesPage == null) { return; } SavesPage.RemoveAll(); defaultSaveElements.ForEach((Action<Element>)SavesPage.Add); foreach (KeepInventory.Saves.V2.Save save in SaveManager.Saves) { if (save == null) { Core.Logger.Error("Save is null, cannot generate element"); continue; } if (string.IsNullOrWhiteSpace(save.ID)) { Core.Logger.Error("ID is null or empty, cannot generate element"); } Page page = null; SavePage savePage = SavePages.FirstOrDefault((SavePage x) => x.CurrentSave == save && x.Page != null); if (savePage == null) { page = SavesPage.CreatePage($"<color=#{save.Color}>{save.Name}</color>", Color.white, 0, false); savePage = new SavePage(page, save); SavePages.Add(savePage); } else { page = savePage.Page; savePage.Setup(); } FunctionElement link = null; link = SavesPage.CreateFunction((Core.CurrentSave == save) ? $"<color=#{save.DrawingColor.ToHEX() ?? "FFFFFF"}>+ {save.Name} +</color>" : $"<color=#{save.DrawingColor.ToHEX() ?? "FFFFFF"}>{save.Name}</color>", Color.white, (Action)delegate { if (RemoveSavesOnPress) { Menu.DisplayDialog("Destructive action", "You are about to delete a save file which after done, cannot be reversed. Are you sure?", Dialog.WarningIcon, (Action)delegate { try { SaveManager.UnregisterSave(save.ID); SavesPage.Remove((Element)(object)link); } catch (Exception ex) { BLHelper.SendNotification("Error", "Failed to remove save, check logs or console for more information", showTitleOnPopup: true, 2f, (NotificationType)2); Core.Logger.Error("An unexpected error has occurred while attempting to remove save", ex); } }, (Action)delegate { Core.Logger.Msg("Save removal denied"); }); } else { Menu.OpenPage(page); } }); } } } public class