using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet.Connection;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SaveBackups;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.atomic.stackableitems")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.5.0")]
[assembly: AssemblyInformationalVersion("0.1.5+831e86f97f144393d6b28deac7ad3f90753dd12b")]
[assembly: AssemblyProduct("com.atomic.stackableitems")]
[assembly: AssemblyTitle("StackableItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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]
[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]
[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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace StackableItems
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.atomic.stackableitems", "StackableItems", "0.1.5")]
public class Plugin : BaseUnityPlugin
{
private Harmony harmony;
public static ConfigEntry<int> MaxStackSize;
public const string Id = "com.atomic.stackableitems";
internal static ManualLogSource Log { get; private set; }
public static string Name => "StackableItems";
public static string Version => "0.1.5";
private void Awake()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
MaxStackSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Stack Size", 64, new ConfigDescription("The maximum amount of objects you can have in a given slot. The more you have, the more data can be tracked per player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
harmony = new Harmony("com.atomic.stackableitems");
harmony.PatchAll();
if (ModInstalled("dazed.howtofish.savebackups"))
{
TryRegister();
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
private void TryRegister()
{
try
{
Companions.Register("stackableitems", "Stackable Items", (Func<string, string>)((string saveName) => Path.Combine(Paths.ConfigPath, "StackableItems", "Saves", Companions.SanitiseSaveName(saveName) + ".json")));
}
catch (Exception ex)
{
Log.LogError((object)("Failed to register with SaveBackups: " + ex.Message));
}
}
public static bool ModInstalled(string GUID)
{
bool flag = Chainloader.PluginInfos.ContainsKey(GUID);
if (!flag)
{
Log.LogWarning((object)(GUID + " is not enabled."));
}
return flag;
}
}
public static class StackManager
{
public static Item ItemBeingStored;
public static byte LastRemovedSlot = byte.MaxValue;
public static Dictionary<ulong, Dictionary<byte, List<Item>>> ServerStacks = new Dictionary<ulong, Dictionary<byte, List<Item>>>();
public static Dictionary<ulong, Dictionary<byte, List<Item>>> ClientStacks = new Dictionary<ulong, Dictionary<byte, List<Item>>>();
public static int MaxStackSize => Plugin.MaxStackSize.Value;
private static ulong GetSteamID(PlayerInventory inv)
{
Player player = inv._player;
if (player == null)
{
return 0uL;
}
return player.SteamID;
}
public static int GetStackCount(PlayerInventory inv, byte index)
{
ulong steamID = GetSteamID(inv);
if (steamID == 0L)
{
return 0;
}
if (((NetworkBehaviour)inv).IsServerInitialized && ServerStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value) && value.TryGetValue(index, out var value2))
{
return value2.Count;
}
if (((NetworkBehaviour)inv).Owner != (NetworkConnection)null && ((NetworkBehaviour)inv).Owner.IsLocalClient && ClientStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value3) && value3.TryGetValue(index, out var value4))
{
return value4.Count;
}
return 0;
}
public static bool PushServerStack(PlayerInventory inv, byte index, Item item)
{
ulong steamID = GetSteamID(inv);
if (steamID == 0L)
{
return false;
}
if (!ServerStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value))
{
value = new Dictionary<byte, List<Item>>();
ServerStacks[steamID] = value;
}
if (!value.TryGetValue(index, out var value2))
{
value2 = (value[index] = new List<Item>());
}
if (value2.Count < MaxStackSize - 1 && (Object)(object)item.Weapon == (Object)null)
{
value2.Add(item);
return true;
}
return false;
}
public static Item PopServerStack(PlayerInventory inv, byte index)
{
ulong steamID = GetSteamID(inv);
if (steamID == 0L)
{
return null;
}
if (!ServerStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value) || !value.TryGetValue(index, out var value2))
{
return null;
}
while (value2.Count > 0)
{
Item val = value2[value2.Count - 1];
value2.RemoveAt(value2.Count - 1);
if (!((Object)(object)val == (Object)null) && !((NetworkBehaviour)val).IsDeinitializing)
{
if (!((Object)(object)val.SyncedHolder != (Object)(object)inv._player))
{
return val;
}
Plugin.Log.LogWarning((object)$"Discarded a stacked '{((Object)val).name}' in slot {index} that no longer belongs to this player. It is loose in the world rather than in the stack.");
}
}
return null;
}
public static void Forget(Item item)
{
if (!((Object)(object)item == (Object)null))
{
Purge(ServerStacks, item);
Purge(ClientStacks, item);
}
}
private static void Purge(Dictionary<ulong, Dictionary<byte, List<Item>>> source, Item item)
{
foreach (Dictionary<byte, List<Item>> value in source.Values)
{
foreach (List<Item> value2 in value.Values)
{
for (int num = value2.Count - 1; num >= 0; num--)
{
if ((Object)(object)value2[num] == (Object)(object)item)
{
value2.RemoveAt(num);
}
}
}
}
}
public static void SyncClientStack(PlayerInventory inv, byte index, Item newItem, Item oldItem)
{
ulong steamID = GetSteamID(inv);
if (steamID != 0L)
{
if (!ClientStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value))
{
value = new Dictionary<byte, List<Item>>();
ClientStacks[steamID] = value;
}
if (!value.TryGetValue(index, out var value2))
{
value2 = (value[index] = new List<Item>());
}
if ((Object)(object)newItem == (Object)null)
{
value2.Clear();
}
else if (value2.Count > 0 && (Object)(object)value2[value2.Count - 1] == (Object)(object)newItem)
{
value2.RemoveAt(value2.Count - 1);
}
else if ((Object)(object)oldItem != (Object)null && (Object)(object)oldItem != (Object)(object)newItem)
{
value2.Add(oldItem);
}
}
}
}
[Serializable]
public class SavedPlayerStacks
{
public ulong SteamID { get; set; }
public List<SavedItem> StackedItems { get; set; } = new List<SavedItem>();
}
[Serializable]
public class StackSaveFile
{
public List<SavedPlayerStacks> Players { get; set; } = new List<SavedPlayerStacks>();
}
public static class StackSaveManager
{
private static readonly string SaveFolder = Path.Combine(Paths.ConfigPath, "StackableItems", "Saves");
private static Dictionary<ulong, List<SavedItem>> PendingRestores = new Dictionary<ulong, List<SavedItem>>();
public static void Save()
{
if (SaveManager.CurServerSave == null)
{
return;
}
foreach (Player player in PlayerManager.Players)
{
SavePlayer(player);
}
}
public static void SavePlayer(Player player)
{
if (SaveManager.CurServerSave == null)
{
return;
}
StackSaveFile stackSaveFile = ReadFile(SaveManager.CurServerSave.Name);
stackSaveFile.Players.RemoveAll((SavedPlayerStacks playerStacks) => playerStacks.SteamID == player.SteamID);
SavedPlayerStacks savedPlayerStacks = new SavedPlayerStacks
{
SteamID = player.SteamID
};
if (StackManager.ServerStacks.TryGetValue(player.SteamID, out Dictionary<byte, List<Item>> value))
{
foreach (KeyValuePair<byte, List<Item>> item in value)
{
foreach (Item item2 in item.Value)
{
if ((Object)(object)item2 != (Object)null)
{
savedPlayerStacks.StackedItems.Add(SaveManager.ItemToSavedItem(item.Key, item2));
}
}
}
}
if (savedPlayerStacks.StackedItems.Count > 0)
{
stackSaveFile.Players.Add(savedPlayerStacks);
}
Write(SaveManager.CurServerSave.Name, stackSaveFile);
}
public static void Load()
{
PendingRestores.Clear();
if (SaveManager.CurServerSave == null)
{
return;
}
StackSaveFile stackSaveFile = ReadFile(SaveManager.CurServerSave.Name);
foreach (SavedPlayerStacks player in stackSaveFile.Players)
{
PendingRestores[player.SteamID] = new List<SavedItem>(player.StackedItems);
}
}
private static StackSaveFile ReadFile(string serverName)
{
string path = GetPath(serverName);
if (!File.Exists(path))
{
return new StackSaveFile();
}
try
{
string text = File.ReadAllText(path);
StackSaveFile stackSaveFile = JsonConvert.DeserializeObject<StackSaveFile>(text);
return stackSaveFile ?? new StackSaveFile();
}
catch
{
return new StackSaveFile();
}
}
public static List<SavedItem> GetPending(ulong steamID)
{
if (!PendingRestores.TryGetValue(steamID, out List<SavedItem> value))
{
return null;
}
PendingRestores.Remove(steamID);
return value;
}
public static void SetStats(Item item, SavedItem savedItem)
{
item._cookness.Value = savedItem.Cookness;
item._bettingMultiplier.Value = savedItem.BettingMultiplier;
item._killScoreMultiplier.Value = savedItem.KillScoreMultiplier;
item._curSkin.Value = savedItem.SkinIndex;
if ((Object)(object)item._weapon != (Object)null)
{
item._weapon._attachments._syncedSight.Value = savedItem.Sight;
item._weapon._attachments._syncedBarrelAttachment.Value = savedItem.BarrelAttachment;
item._weapon._attachments._syncedBulletIndex.Value = savedItem.AmmoType;
item._weapon._attachments._syncedExtendedMag.Value = savedItem.ExtendedMag;
item._weapon._attachments._syncedLaserSight.Value = savedItem.LaserSight;
}
if ((Object)(object)item._melee != (Object)null)
{
item._melee._syncedSharpnessIndex.Value = savedItem.Sharpness;
}
if ((Object)(object)item._creature != (Object)null)
{
((Item)item._creature)._syncedRandomWeight.Value = savedItem.Weight;
}
}
public static void Delete(string serverName)
{
string path = GetPath(serverName);
if (File.Exists(path))
{
File.Delete(path);
}
}
private static void Write(string serverName, StackSaveFile saveFile)
{
try
{
Directory.CreateDirectory(SaveFolder);
string path = GetPath(serverName);
string contents = JsonConvert.SerializeObject((object)saveFile, (Formatting)1);
File.WriteAllText(path, contents);
}
catch
{
}
}
public static string GetPath(string serverName)
{
string text = serverName;
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
foreach (char oldChar in invalidFileNameChars)
{
text = text.Replace(oldChar, '_');
}
return Path.Combine(SaveFolder, text + ".json");
}
}
[HarmonyPatch]
public static class StackableItemsPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "ServerTryStoreHeldItem")]
public static void ServerTryStoreHeldItem_Prefix(Item item, out Item __state)
{
__state = StackManager.ItemBeingStored;
StackManager.ItemBeingStored = item;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "ServerTryStoreHeldItem")]
public static void ServerTryStoreHeldItem_Postfix(Item __state)
{
StackManager.ItemBeingStored = __state;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "ResolveHeldItemReplacement")]
public static void ResolveHeldItemReplacement_Prefix(Item item, out Item __state)
{
__state = StackManager.ItemBeingStored;
StackManager.ItemBeingStored = item;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "ResolveHeldItemReplacement")]
public static void ResolveHeldItemReplacement_Postfix(Item __state)
{
StackManager.ItemBeingStored = __state;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "LocalTrySelectSlot")]
public static void LocalTrySelectSlot_Prefix(PlayerInventory __instance, out Item __state)
{
__state = StackManager.ItemBeingStored;
Player player = __instance._player;
object itemBeingStored;
if (player == null)
{
itemBeingStored = null;
}
else
{
PlayerHolding holding = player.Holding;
itemBeingStored = ((holding != null) ? holding.HeldItem : null);
}
StackManager.ItemBeingStored = (Item)itemBeingStored;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "LocalTrySelectSlot")]
public static void LocalTrySelectSlot_Postfix(Item __state)
{
StackManager.ItemBeingStored = __state;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "UpdateHeldItem")]
public static void UpdateHeldItem_Prefix(PlayerInventory __instance, out Item __state)
{
__state = StackManager.ItemBeingStored;
Player player = __instance._player;
object itemBeingStored;
if (player == null)
{
itemBeingStored = null;
}
else
{
PlayerHolding holding = player.Holding;
itemBeingStored = ((holding != null) ? holding.HeldItem : null);
}
StackManager.ItemBeingStored = (Item)itemBeingStored;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "UpdateHeldItem")]
public static void UpdateHeldItem_Postfix(Item __state)
{
StackManager.ItemBeingStored = __state;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "GetOpenSlot")]
public static bool GetOpenSlot(PlayerInventory __instance, int selected, ref int __result)
{
if ((Object)(object)StackManager.ItemBeingStored != (Object)null)
{
string text = ((Object)StackManager.ItemBeingStored).name.Replace("(Clone)", "").Trim();
for (byte b = 0; b < __instance._availableSlots.Count; b++)
{
Item val = __instance._items[b];
if ((Object)(object)val != (Object)null)
{
string text2 = ((Object)val).name.Replace("(Clone)", "").Trim();
int num = 1 + StackManager.GetStackCount(__instance, b);
if (text2 == text && num < StackManager.MaxStackSize && (Object)(object)val.Weapon == (Object)null)
{
__result = b;
return false;
}
}
}
}
return true;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "AddItem")]
public static bool AddItem(PlayerInventory __instance, byte index, Item item)
{
if (!((NetworkBehaviour)__instance).IsServerInitialized || (Object)(object)item == (Object)null)
{
return true;
}
if (!__instance._items.ContainsKey(index))
{
return true;
}
if ((Object)(object)item.SyncedHolder != (Object)(object)__instance._player)
{
return true;
}
foreach (KeyValuePair<byte, Item> item2 in __instance._items)
{
if ((Object)(object)item2.Value == (Object)(object)item)
{
return false;
}
}
Item val = __instance._items[index];
if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)item && !StackManager.PushServerStack(__instance, index, val))
{
return false;
}
__instance._items[index] = item;
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "LoadFromSave")]
public static void LoadFromSave(PlayerInventory __instance)
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
if (!((NetworkBehaviour)__instance).IsServerInitialized || (Object)(object)__instance._player == (Object)null)
{
return;
}
ulong steamID = __instance._player.SteamID;
List<SavedItem> pending = StackSaveManager.GetPending(steamID);
if (pending == null || pending.Count == 0)
{
return;
}
if (!StackManager.ServerStacks.TryGetValue(steamID, out Dictionary<byte, List<Item>> value))
{
value = new Dictionary<byte, List<Item>>();
StackManager.ServerStacks[steamID] = value;
}
foreach (SavedItem item in pending)
{
Item spawnable = GameInfo.GetSpawnable(item.ItemID);
if (!Object.op_Implicit((Object)(object)spawnable))
{
continue;
}
Item val = ItemManager.Instance.SpawnNewItem(spawnable, SpawnManager._mainPlayerSpawnPoint.position, Quaternion.identity);
StackSaveManager.SetStats(val, item);
if ((Object)(object)val.Creature != (Object)null)
{
val.Creature.ServerKillOnSpawn();
if (item.IsDripCreature)
{
val.Creature.SetDrip();
}
}
if ((Object)(object)val.Weapon != (Object)null)
{
val.SetSyncedHolder(__instance._player, true);
byte? b = null;
for (byte b2 = 0; b2 < __instance._items.Count; b2++)
{
if ((Object)(object)__instance._items[b2] == (Object)null)
{
b = b2;
break;
}
}
if (b.HasValue)
{
__instance._items[b.Value] = val;
continue;
}
val.Drop(false, default(Vector3), default(Vector3));
Plugin.Log.LogWarning((object)("Dropped stacked weapon for " + ((Object)__instance._player).name + " because inventory was full."));
}
else
{
val.SetSyncedHolder(__instance._player, true);
val.PutInInventory();
if (!value.TryGetValue(item.InventorySlot, out var value2))
{
value2 = new List<Item>();
value[item.InventorySlot] = value2;
}
value2.Add(val);
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "RemoveItem")]
public static bool RemoveItem(PlayerInventory __instance, Item item, out int __state)
{
__state = -1;
if (!((NetworkBehaviour)__instance).IsServerInitialized || (Object)(object)item == (Object)null)
{
return true;
}
byte b = byte.MaxValue;
foreach (KeyValuePair<byte, Item> item2 in __instance._items)
{
if ((Object)(object)item2.Value == (Object)(object)item)
{
b = item2.Key;
break;
}
}
StackManager.LastRemovedSlot = b;
if (b != byte.MaxValue)
{
Item val = StackManager.PopServerStack(__instance, b);
if ((Object)(object)val != (Object)null)
{
__instance._items[b] = val;
__state = b;
return false;
}
}
return true;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "RemoveItem")]
public static void RemoveItem_Postfix(PlayerInventory __instance, int __state)
{
StackManager.LastRemovedSlot = byte.MaxValue;
if (__state >= 0 && !(((NetworkBehaviour)__instance).Owner == (NetworkConnection)null) && ((NetworkBehaviour)__instance).Owner.IsLocalClient && __instance._localCurSlot != __state)
{
__instance.ApplySlot(__state);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Item), "DestroyByEating")]
public static void EatItem(Item __instance)
{
Player lastHolder = __instance.LastHolder;
if (!((Object)(object)lastHolder == (Object)null) && !((Object)(object)Player.LocalPlayer != (Object)(object)lastHolder))
{
PlayerInventory inventory = lastHolder.Inventory;
if (!((Object)(object)inventory == (Object)null) && !(((NetworkBehaviour)inventory).Owner == (NetworkConnection)null) && ((NetworkBehaviour)inventory).Owner.IsLocalClient)
{
inventory.ApplySlot(inventory._localCurSlot);
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Item), "SetSyncedHolder")]
public static void Item_SetSyncedHolder_Postfix(Item __instance)
{
if ((Object)(object)__instance.SyncedHolder == (Object)null)
{
StackManager.Forget(__instance);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Item), "OnStopServer")]
public static void Item_OnStopServer_Postfix(Item __instance)
{
StackManager.Forget(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "ServerDropAll")]
public static void ServerDropAll(PlayerInventory __instance, Vector3 pos, Quaternion rot)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
if (!((NetworkBehaviour)__instance).IsServerInitialized || Plugin.ModInstalled("kvasir.keepinventory"))
{
return;
}
Player player = __instance._player;
ulong num = ((player != null) ? player.SteamID : 0);
if (num == 0L || !StackManager.ServerStacks.TryGetValue(num, out Dictionary<byte, List<Item>> value))
{
return;
}
Vector3 val = Vector3.zero;
foreach (KeyValuePair<byte, List<Item>> item in value)
{
Item[] array = item.Value.ToArray();
item.Value.Clear();
Item[] array2 = array;
foreach (Item val2 in array2)
{
if ((Object)(object)val2 != (Object)null)
{
val += Vector3.up * val2.ModelHeight;
val2.SetSyncedHolder((Player)null, false);
if (!val2.RigidbodySync.IsSimulatedLocal)
{
val2.RigidbodySync.StartSimulateLocal(pos + val, rot);
}
else
{
((Component)val2).transform.position = pos + val;
val2.Rig.linearVelocity = Vector3.zero;
val2.Rig.angularVelocity = Vector3.zero;
}
val += Vector3.up * val2.ModelHeight;
}
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerInventory), "OnItemsChange")]
public static void OnItemsChange(PlayerInventory __instance, SyncDictionaryOperation op, byte index, Item item, bool asServer)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Invalid comparison between Unknown and I4
if (!asServer && (int)op == 3 && ((NetworkBehaviour)__instance).Owner != (NetworkConnection)null && ((NetworkBehaviour)__instance).Owner.IsLocalClient)
{
Item item2 = __instance._itemSlots[index].Item;
StackManager.SyncClientStack(__instance, index, item, item2);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "OnStopServer")]
public static void OnStopServer(PlayerInventory __instance)
{
if ((Object)(object)__instance._player != (Object)null)
{
StackSaveManager.SavePlayer(__instance._player);
ulong steamID = __instance._player.SteamID;
StackManager.ServerStacks.Remove(steamID);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerInventory), "OnStopClient")]
public static void OnStopClient(PlayerInventory __instance)
{
Player player = __instance._player;
ulong num = ((player != null) ? player.SteamID : 0);
if (num != 0L)
{
StackManager.ClientStacks.Remove(num);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(InventorySlot), "SetItem")]
public static void SetItem(InventorySlot __instance, Item item)
{
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
((TMP_Text)__instance._itemText).text = "";
return;
}
PlayerInventory inventory = Player.LocalPlayer.Inventory;
if ((Object)(object)inventory == (Object)null)
{
return;
}
byte b = byte.MaxValue;
for (byte b2 = 0; b2 < inventory._itemSlots.Count; b2++)
{
if ((Object)(object)inventory._itemSlots[b2] == (Object)(object)__instance)
{
b = b2;
break;
}
}
if (b == byte.MaxValue)
{
return;
}
int num = StackManager.GetStackCount(inventory, b) + 1;
if (num > 1)
{
if ((Object)(object)item.Mesh == (Object)null)
{
((TMP_Text)__instance._itemText).text = $"{((Object)item).name} ({num})";
}
else
{
((TMP_Text)__instance._itemText).text = num.ToString();
}
((Component)__instance._itemText).gameObject.SetActive(true);
}
else if ((Object)(object)item.Mesh != (Object)null)
{
((TMP_Text)__instance._itemText).text = "";
}
((TMP_Text)__instance._itemText).verticalAlignment = (VerticalAlignmentOptions)1024;
((TMP_Text)__instance._itemText).horizontalAlignment = (HorizontalAlignmentOptions)1;
((TMP_Text)__instance._itemText).fontSize = 16f;
((TMP_Text)__instance._itemText).fontSizeMax = 18f;
((TMP_Text)__instance._itemText).fontSizeMin = 10f;
((Graphic)__instance._itemText).color = Color.white;
((TMP_Text)__instance._itemText).transform.localPosition = new Vector3(7.25f, 5f, 0f);
((TMP_Text)__instance._itemText).transform.SetAsLastSibling();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SaveManager), "SaveServer")]
public static void SaveServer()
{
StackSaveManager.Save();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SaveManager), "OnServerLoaded")]
public static void OnServerLoaded()
{
StackSaveManager.Load();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(SaveManager), "DeleteServer")]
public static void DeleteServer()
{
if (SaveManager.CurServerSave != null)
{
StackSaveManager.Delete(SaveManager.CurServerSave.Name);
}
}
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}