Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of XStorage v1.1.7
plugins/XStorage/XStorage.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Managers; using Jotunn.Utils; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using XStorage.Components; using XStorage.GUI; using XStorage.Patches; using XStorage.RPC; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: Guid("5ad119f9-7a24-4686-b3ee-90fc6a3cee9f")] [assembly: AssemblyTitle("XStorage")] [assembly: AssemblyDescription("Open multiple chests at once, rename them, and move items/stacks to the most suitable chest.")] [assembly: AssemblyCompany("SpikeHimself")] [assembly: AssemblyProduct("XStorage")] [assembly: AssemblyFileVersion("1.1.7")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.7.0")] namespace Mod { public static class Info { public const string GUID = "yay.spikehimself.xstorage"; public const string HarmonyGUID = "yay.spikehimself.xstorage.harmony"; public const string Author = "SpikeHimself"; public const string Name = "XStorage"; public const string GitHubRepo = "SpikeHimself/XStorage"; public const string Version = "1.1.7"; public const string Description = "Open multiple chests at once, rename them, and move items/stacks to the most suitable chest."; public const string WebsiteUrl = "https://github.com/SpikeHimself/XStorage"; public const int NexusId = 2290; public const string BepInExPackVersion = "5.4.2200"; public const string JotunnVersion = "2.14.6"; } } namespace XStorage { internal static class Environment { internal static bool IsServer { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } internal static bool IsHeadless => GUIManager.IsHeadless(); internal static bool GameStarted { get; set; } internal static bool ShuttingDown => Game.instance.m_shuttingDown; internal static long ServerPeerId => ZRoutedRpc.instance.GetServerPeerID(); } internal static class Log { public static void Debug(object message) { MethodBase? method = new StackTrace().GetFrame(1).GetMethod(); string name = method.DeclaringType.Name; string name2 = method.Name; Logger.LogDebug((object)$"[{name}.{name2}] {message}"); } public static void Info(object message) { Logger.LogInfo(message); } public static void Warning(object message) { Logger.LogWarning(message); } public static void Error(object message) { Logger.LogError(message); } public static void Fatal(object message) { Logger.LogFatal(message); } } internal class PanelManager { private static readonly Lazy<PanelManager> lazy = new Lazy<PanelManager>(() => new PanelManager()); public RootPanel RootPanel; private List<ContainerGui> containerPanels; public static PanelManager Instance => lazy.Value; public ContainerGridPanel ContentPanel => RootPanel.ContentPanel; private int VisiblePanelsCount => containerPanels.Where((ContainerGui c) => c.IsContainerOpen()).Count(); private PanelManager() { containerPanels = new List<ContainerGui>(); } internal void Reset() { Clear(); RootPanel = null; } public void Clear() { containerPanels.Clear(); } public bool IsVisible() { if (RootPanel != null && RootPanel.IsVisible()) { return VisiblePanelsCount > 0; } return false; } public void Show(Container container) { CreateRootPanel(); if (!IsVisible()) { Log.Debug("Opening ContainersPanel, resetting scroll view"); RootPanel.ScrollablePanel.ScrollUp(); } AddOrEnablePanel(container).Show(container); RootPanel.UpdateSize(VisiblePanelsCount); RootPanel.SetActive(active: true); } public void Hide() { if (RootPanel != null && Object.op_Implicit((Object)(object)RootPanel.GameObject)) { RootPanel.SavePosition(); Log.Debug("Hiding"); containerPanels.ForEach(delegate(ContainerGui c) { c.Hide(); }); RootPanel.SetActive(active: false); } } public void AddPanel() { ContainerPanel containerPanel = new ContainerPanel(ContentPanel, string.Format("{0} Container{1}", "XStorage", containerPanels.Count)); containerPanels.Add(containerPanel.ContainerGui); Log.Debug($"Total container panels: {containerPanels.Count}"); } private ContainerGui AddOrEnablePanel(Container container) { ContainerGui containerGui = FindPanel(container); if (Object.op_Implicit((Object)(object)containerGui)) { return containerGui; } ContainerGui containerGui2 = FindInactivePanel(); if ((Object)(object)containerGui2 != (Object)null) { return containerGui2; } AddPanel(); return AddOrEnablePanel(container); } public bool ContainsPanel(Container container) { return containerPanels.Where((ContainerGui c) => (Object)(object)c.m_currentContainer == (Object)(object)container).Any(); } public ContainerGui FindPanel(Container container) { return containerPanels.Where((ContainerGui c) => (Object)(object)c.m_currentContainer == (Object)(object)container).FirstOrDefault(); } public ContainerGui FindInactivePanel() { return containerPanels.Where((ContainerGui c) => !c.IsContainerOpen()).FirstOrDefault(); } public List<Container> GetContainerList() { return (from c in containerPanels where c.IsContainerOpen() select c.m_currentContainer).ToList(); } private void CreateRootPanel() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (RootPanel == null || !Object.op_Implicit((Object)(object)RootPanel.GameObject)) { Log.Debug("Creating root panel"); GameObject val = GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/Inventory_screen/root"); if (!Object.op_Implicit((Object)(object)val)) { Log.Error("Can't find inventory screen root"); } else { RootPanel = new RootPanel(val.transform, ContainerPanel.SinglePanelSize); } } } } internal static class Extensions { internal static Vector3 GetPosition(this Character character) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return character.m_nview.GetZDO().GetPosition(); } internal static float Distance(this Container container, Character character) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(container.GetPosition(), character.GetPosition()); } internal static float Distance(this Container container, Container other) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(container.GetPosition(), other.GetPosition()); } internal static Vector3 GetPosition(this Container container) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return container.GetZDO().GetPosition(); } internal static ZDO GetZDO(this Container container) { return container.m_nview.GetZDO(); } internal static ZDOID GetZDOID(this Container container) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return container.GetZDO().m_uid; } internal static string GetXStorageName(this Container container) { return container.GetZDO().GetString("XStorage_Name", string.Empty); } internal static string GetXStorageNameOrDefault(this Container container) { return container.GetZDO().GetString("XStorage_Name", Localization.instance.Localize(container.m_name)); } internal static bool GetXStorageSkipMark(this Container container) { return container.GetZDO().GetBool("XStorage_SkipMark", false); } internal static bool HasRoomFor(this Container container, string itemName, float worldLevel) { Inventory inventory = container.GetInventory(); if (inventory.FindFreeStackSpace(itemName, worldLevel) <= 0) { return inventory.HaveEmptySlot(); } return true; } internal static bool IsPlacedByPlayer(this Container container) { if (Object.op_Implicit((Object)(object)container.m_piece)) { return container.m_piece.IsPlacedByPlayer(); } return false; } internal static void FillParent(this GameObject go, RectOffset padding) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)go.transform; val.pivot = new Vector2(0.5f, 0.5f); val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(1f, 1f); val.anchoredPosition = new Vector2(0f, 0f); val.offsetMin = new Vector2((float)padding.left, (float)padding.bottom); val.offsetMax = new Vector2((float)padding.right, (float)checked(-padding.top)); } internal static void FillParent(this GameObject go) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown go.FillParent(new RectOffset()); } internal static void AnchorToRightEdge(this GameObject go, float width, float padding = 0f) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0076: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)go.transform; val.pivot = new Vector2(1f, 0.5f); val.anchorMin = new Vector2(1f, 0f); val.anchorMax = new Vector2(1f, 1f); float num = width * 2f; val.offsetMin = new Vector2(0f - num, padding); val.offsetMax = new Vector2(0f - width, 0f - padding); val.anchoredPosition = new Vector2(0f - num, 0f); } internal static float Distance(this Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(a, b); } } internal class Util { public static Vector3 StringToVector3(string sVector) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) float[] array = Array.ConvertAll(sVector.Split(", ()".ToCharArray(), StringSplitOptions.RemoveEmptyEntries), float.Parse); return new Vector3(array[0], array[1], array[2]); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("yay.spikehimself.xstorage", "XStorage", "1.1.7")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class XStorage : BaseUnityPlugin { public const string Key_ContainerName = "XStorage_Name"; public const string Key_SkipMark = "XStorage_SkipMark"; private void Awake() { Log.Debug("oooh chesty!"); XConfig.Instance.LoadLocalConfig(((BaseUnityPlugin)this).Config); Patcher.Patch(); } private void Update() { } private void OnDestroy() { PanelManager.Instance.Clear(); Patcher.Unpatch(); } public static void GameStarted() { PanelManager.Instance.Reset(); RPCManager.Register(); } public static void OpenNearbyContainers(Container container) { List<Container> list = FindNearbyContainers(container); if (list.Count <= 0) { return; } Log.Info($"Found {list.Count} extra chests near `{container.GetXStorageNameOrDefault()}`"); Player localPlayer = Player.m_localPlayer; foreach (Container item in list) { Log.Debug("Calling .Interact() on extra container `" + item.GetXStorageNameOrDefault() + "`"); item.Interact((Humanoid)(object)localPlayer, false, false); } } public static List<Container> FindNearbyContainers(Container container) { int maxDistance = XConfig.Instance.NearbyChestRadius.Value; int value = XConfig.Instance.MaxOpenChests.Value; List<Container> list = (from c in Object.FindObjectsOfType<Container>() where (Object)(object)c != (Object)(object)container && !PanelManager.Instance.ContainsPanel(c) && c.IsPlacedByPlayer() && !c.IsInUse() && c.Distance(container) <= (float)maxDistance orderby c.GetInventory().GetTotalWeight() descending select c).ToList(); if (value > 0) { list = list.Take(value).ToList(); } return list; } public static void SetXStorageName(ZDOID containerId, string newName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDOMan.instance.GetZDO(containerId).Set("XStorage_Name", newName); } public static void UpdateContainerAndInventoryName(Container container) { string xStorageName = container.GetXStorageName(); if (!string.IsNullOrEmpty(xStorageName) && (!container.m_name.Equals(xStorageName) || !container.GetInventory().m_name.Equals(xStorageName))) { UpdateContainerAndInventoryName(container, xStorageName); } } public static void UpdateContainerAndInventoryName(Container container, string newName) { Log.Debug("Updating `" + container.m_name + "`: `" + newName + "`"); container.m_name = newName; container.GetInventory().m_name = newName; } public static bool MoveItemToSuitableContainer(InventoryGrid grid, ItemData item) { string name = item.m_shared.m_name; int worldLevel = item.m_worldLevel; Container val = FindSuitableContainer(name, worldLevel); if (!Object.op_Implicit((Object)(object)val)) { return false; } string text = Localization.instance.Localize(item.m_shared.m_name); Log.Debug("Moving `" + text + "` to `" + val.GetXStorageNameOrDefault() + "`"); val.GetInventory().MoveItemToThis(grid.GetInventory(), item); return true; } private static Container FindSuitableContainer(string itemName, float worldLevel) { string text = Localization.instance.Localize(itemName); Log.Debug("Looking for containers containing `" + text + "`"); List<Container> list = new List<Container>(); list.Add(InventoryGui.instance.m_currentContainer); list.AddRange(PanelManager.Instance.GetContainerList()); IOrderedEnumerable<Container> source = from c in list where c.HasRoomFor(itemName, worldLevel) orderby c.GetInventory().CountItems(itemName, -1, true) descending select c; if (source.Any()) { Log.Debug($"Found {source.Count()} container(s) containing `{text}` with room for more"); return source.First(); } return null; } } public class XConfig { private static readonly Lazy<XConfig> lazy = new Lazy<XConfig>(() => new XConfig()); private ConfigFile configFile; private ConfigEntry<int> MaxColumns; private ConfigEntry<int> MaxRows; public ConfigEntry<int> NearbyChestRadius; public ConfigEntry<int> MaxOpenChests; private ConfigEntry<float> PanelScale; public static XConfig Instance => lazy.Value; public float PanelScaleValue { get { PanelScale.Value = Mathf.Clamp(PanelScale.Value, 0.5f, 1.5f); return PanelScale.Value; } set { PanelScale.Value = Mathf.Clamp(value, 0.5f, 1.5f); } } public GridSize MaxSize => new GridSize(MaxColumns.Value, MaxRows.Value); public void LoadLocalConfig(ConfigFile configFile) { this.configFile = configFile; configFile.Bind<int>("General", "NexusID", 2290, "Nexus mod ID for updates (do not change)"); MaxColumns = configFile.Bind<int>("UI", "MaxColumns", 2, "The maximum amount of columns XStorage can expand the containers panel to."); MaxRows = configFile.Bind<int>("UI", "MaxRows", 3, "The maximum amount of rows XStorage can expand the containers panel to."); NearbyChestRadius = configFile.Bind<int>("Algorithm", "NearbyChestRange", 4, "The radius in meters within which to look for nearby chests. Setting this too high might cause performance issues!"); MaxOpenChests = configFile.Bind<int>("General", "MaxOpenChests", 0, "The maximum amount of chests to open at once. 0 or fewer means infinite."); PanelScale = configFile.Bind<float>("UI", "PanelScale", 1f, "The relative size of XStorage's panel. Can be any value between 0.5 and 1.5, where 0.5 = 50%, 1 = 100%, and 1.5 = 150%"); BindPanelPosition(GridSize.OneByOne); } private ConfigEntry<Vector2> BindPanelPosition(GridSize gridSize) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) string text = $"Position_{gridSize}"; return configFile.Bind<Vector2>("Panel Position", text, Vector2.zero, $"The position on the screen when the panel is sized `{gridSize}`"); } public void SavePanelPosition(GridSize gridSize, Vector2 position) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) BindPanelPosition(gridSize).Value = position; configFile.Save(); } public Vector2 GetPanelPosition(GridSize gridSize) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return BindPanelPosition(gridSize).Value; } } } namespace XStorage.RPC { internal static class RPCManager { internal const string RPC_RENAMEREQUEST = "XStorage_RenameRequest"; internal static void Register() { ZRoutedRpc.instance.Register<ZDOID, string>("XStorage_RenameRequest", (Action<long, ZDOID, string>)ServerEvents.RPC_RenameRequest); } } internal static class SendToServer { internal static void RenameRequest(ZDOID containerId, string newName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Log.Debug($"Requesting server to rename `{containerId}` to `{newName}`"); ZRoutedRpc.instance.InvokeRoutedRPC(Environment.ServerPeerId, "XStorage_RenameRequest", new object[2] { containerId, newName }); } } internal static class ServerEvents { internal static void RPC_RenameRequest(long sender, ZDOID containerId, string newName) { //IL_002f: 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_0012: Unknown result type (might be due to invalid IL or missing references) if (!Environment.IsServer) { Log.Debug($"{sender} wants to rename container `{containerId}` to `{newName}`, but I am not the server"); return; } Log.Debug($"{sender} wants to rename container `{containerId}` to `{newName}`"); XStorage.SetXStorageName(containerId, newName); } } } namespace XStorage.Patches { [HarmonyPatch(typeof(Container), "Awake")] internal static class Container_Awake { private static void Postfix(Container __instance) { if (!Object.op_Implicit((Object)(object)__instance.m_piece)) { Log.Debug("Ignoring `" + __instance.m_name + "` (this is fine)"); } else { XStorage.UpdateContainerAndInventoryName(__instance); } } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class Container_GetHoverText { [HarmonyPatch(typeof(Container), "Interact")] private static class Container_Interact { private static bool Prefix(Container __instance, Humanoid character, bool alt) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!alt) { return true; } if (!__instance.IsPlacedByPlayer()) { return true; } if (__instance.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false)) { return false; } long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); if (!__instance.CheckAccess(playerID)) { ((Character)character).Message((MessageType)2, "$msg_cantopen", 0, (Sprite)null); return false; } ContainerTextReceiver orAddComponent = ExposedGameObjectExtension.GetOrAddComponent<ContainerTextReceiver>(((Component)__instance).gameObject); TextInput.instance.RequestText((TextReceiver)(object)orAddComponent, "$hud_rename", 127); return false; } } private static void Prefix(Container __instance) { if (Environment.ShuttingDown) { Log.Debug("Shutting down, ignoring hover"); } else if (__instance.IsPlacedByPlayer()) { XStorage.UpdateContainerAndInventoryName(__instance); } } private static void Postfix(Container __instance, ref string __result) { if (__instance.IsPlacedByPlayer()) { string value = Localization.instance.Localize("$piece_noaccess"); if (!__result.Contains(value)) { __result += Localization.instance.Localize("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $hud_rename"); } } } } [HarmonyPatch(typeof(Container), "RPC_OpenRespons")] internal static class Container_RPCOpenRespons { private static bool Prefix(Container __instance, bool granted) { string xStorageNameOrDefault = __instance.GetXStorageNameOrDefault(); if (!Object.op_Implicit((Object)(object)InventoryGui.instance.m_currentContainer)) { Log.Debug("Opening container `" + xStorageNameOrDefault + "` into the vanilla UI"); return true; } if (!granted) { Log.Debug("No access to container `" + xStorageNameOrDefault + "`"); return false; } Log.Debug("Opening container `" + xStorageNameOrDefault + "` into XStorage panel"); PanelManager.Instance.Show(__instance); return false; } } [HarmonyPatch(typeof(Game), "Awake")] internal static class Game_Awake { private static void Prefix(ref bool ___isModded) { ___isModded = true; } } [HarmonyPatch(typeof(Game), "Start")] internal static class Game_Start { private static void Postfix() { Environment.GameStarted = true; XStorage.GameStarted(); } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class InventoryGui_Show { private static void Postfix(Container container) { if (Object.op_Implicit((Object)(object)container)) { Log.Debug("Showing container `" + container.GetXStorageNameOrDefault() + "`"); if (container.GetXStorageSkipMark()) { Log.Debug("This container has the SkipMark set. Not opening nearby containers."); } else { XStorage.OpenNearbyContainers(container); } } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide { private static void Prefix(InventoryGui __instance) { if (__instance.m_animator.GetBool("visible")) { PanelManager.Instance.Hide(); } } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class InventoryGui_OnSelectedItem { private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 if ((Object)(object)grid != (Object)(object)InventoryGui.instance.m_playerGrid) { return true; } if (!Object.op_Implicit((Object)(object)__instance.m_currentContainer)) { return true; } if ((int)mod == 2 && item != null && !item.m_shared.m_questItem && XStorage.MoveItemToSuitableContainer(grid, item)) { return false; } return true; } } internal static class Patcher { private static readonly Harmony patcher = new Harmony("yay.spikehimself.xstorage.harmony"); public static void Patch() { patcher.PatchAll(); } public static void Unpatch() { Harmony obj = patcher; if (obj != null) { obj.UnpatchSelf(); } } } [HarmonyPatch(typeof(UITooltip), "OnHoverStart")] internal static class UITooltip_OnHoverStart { private static void Postfix(ref GameObject ___m_tooltip) { if (Object.op_Implicit((Object)(object)___m_tooltip) && Object.op_Implicit((Object)(object)___m_tooltip.transform.parent) && PanelManager.Instance.IsVisible() && (Object)(object)___m_tooltip.transform.parent == (Object)(object)PanelManager.Instance.ContentPanel.Transform) { GameObject val = Object.Instantiate<GameObject>(___m_tooltip, PanelManager.Instance.RootPanel.Transform); Object.Destroy((Object)(object)___m_tooltip); ___m_tooltip = val; } } } } namespace XStorage.GUI { public class ContainerGridPanel : XUIPanel { public GridLayoutGroup GridLayoutGroup => base.GameObject.GetComponent<GridLayoutGroup>(); public ContentSizeFitter ContentSizeFitter => base.GameObject.GetComponent<ContentSizeFitter>(); public ContainerGridPanel(Transform parent, Vector2 cellSize, float gridSpacing) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_007f: 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_00ad: Unknown result type (might be due to invalid IL or missing references) base.GameObject = new GameObject("ContainerGridPanel", new Type[5] { typeof(RectTransform), typeof(GridLayoutGroup), typeof(Canvas), typeof(GraphicRaycaster), typeof(ContentSizeFitter) }); base.GameObject.FillParent(); base.Parent = parent; base.RectTransform.pivot = new Vector2(0.5f, 1f); ContentSizeFitter.verticalFit = (FitMode)2; GridLayoutGroup.cellSize = cellSize; GridLayoutGroup.spacing = new Vector2(gridSpacing, 0f); GridLayoutGroup.constraint = (Constraint)1; GridLayoutGroup.constraintCount = 1; GridLayoutGroup.startAxis = (Axis)0; GridLayoutGroup.startCorner = (Corner)0; } } public class ContainerPanel : XUIPanel { public static readonly float WeightPanelWidth = 75f; public static readonly Vector2 SinglePanelSize = new Vector2(570f, 340f); public static readonly Vector2 SinglePanelWithWeightPanelSize = new Vector2(SinglePanelSize.x + WeightPanelWidth, SinglePanelSize.y); private ContainerGui containerGui; private static GameObject panelPrefab; public ContainerGui ContainerGui { get { if (!Object.op_Implicit((Object)(object)containerGui)) { containerGui = base.GameObject.GetComponent<ContainerGui>(); } return containerGui; } } public ContainerPanel(ContainerGridPanel parent, string name) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_0088: 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) base.GameObject = ClonePrefab(parent.Transform); SetActive(active: false); base.Name = name; base.RectTransform.anchorMin = new Vector2(0.5f, 0.5f); base.RectTransform.anchorMax = new Vector2(0.5f, 0.5f); base.RectTransform.pivot = new Vector2(0.5f, 0.5f); ((Transform)base.RectTransform).localPosition = Vector2.op_Implicit(new Vector2(0f, 0f)); ((Transform)base.RectTransform).localScale = new Vector3(0.94f, 0.94f, 0.94f); } private static GameObject ClonePrefab(Transform parent) { CreatePanelPrefab(parent); return Object.Instantiate<GameObject>(panelPrefab, parent); } private static void CreatePanelPrefab(Transform parent) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)panelPrefab)) { return; } Log.Debug("Cloning vanilla container panel.."); GameObject val = GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/Inventory_screen/root/Container"); if (!Object.op_Implicit((Object)(object)val)) { Log.Error("Vanilla container panel not found!"); return; } panelPrefab = Object.Instantiate<GameObject>(val, parent); panelPrefab.SetActive(false); ((Component)panelPrefab.transform.Find("ContainerScroll")).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)panelPrefab.transform.Find("ContainerGrid")).GetComponent<ScrollRect>()); foreach (Transform item in ((Component)panelPrefab.transform.Find("ContainerGrid/Root")).transform) { Object.Destroy((Object)(object)((Component)item).gameObject); } ((Component)panelPrefab.transform.Find("Bkg")).gameObject.AddComponent<CanvasGroup>().alpha = 0.2f; ((Component)panelPrefab.transform.Find("Weight/bkg")).gameObject.AddComponent<CanvasGroup>().alpha = 0.2f; panelPrefab.AddComponent<ContainerGui>(); } } public class GridSize { public static GridSize OneByOne = new GridSize(1, 1); public int Columns { get; } public int Rows { get; } public GridSize(int columns, int rows) { Columns = columns; Rows = rows; } public override bool Equals(object obj) { if (obj == null) { return false; } if (!(obj is GridSize)) { return false; } GridSize gridSize = obj as GridSize; if (Columns == gridSize.Columns) { return Rows == gridSize.Rows; } return false; } public override int GetHashCode() { return base.GetHashCode(); } public override string ToString() { return $"{Columns}x{Rows}"; } public static GridSize Calculate(int maxCols, int maxRows, int cells) { int num = Mathf.Min(maxCols, cells); int num2 = Mathf.CeilToInt((float)cells / (float)num); int rows = Mathf.Min(maxRows, num2); return new GridSize(num, rows); } } public abstract class XUIPanel { private RectTransform rt; public GameObject GameObject { get; protected set; } public string Name { get { return ((Object)GameObject).name; } set { ((Object)GameObject).name = value; } } public Transform Transform => GameObject.transform; public Transform Parent { get { return Transform.parent; } set { Transform.SetParent(value, false); } } public RectTransform RectTransform { get { if (!Object.op_Implicit((Object)(object)rt)) { ref RectTransform reference = ref rt; Transform transform = Transform; reference = (RectTransform)(object)((transform is RectTransform) ? transform : null); } return rt; } } public bool IsVisible() { if (Object.op_Implicit((Object)(object)GameObject)) { return GameObject.activeSelf; } return false; } public void SetActive(bool active) { GameObject.SetActive(active); } } public class RootPanel : XUIPanel { private static readonly RectOffset Padding = new RectOffset(15, 15, 40, 15); public ScrollablePanel ScrollablePanel; public ContainerGridPanel ContentPanel; public GridSize GridSize { get; private set; } public RootPanel(Transform parent, Vector2 gridCellSize) { //IL_0013: 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_005a: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Padding.left + gridCellSize.x + (float)Padding.right, (float)Padding.top + gridCellSize.y + (float)Padding.bottom); base.GameObject = GUIManager.Instance.CreateWoodpanel(parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), val.x, val.y, true); base.Name = "XStorage Root Panel"; RectTransform val2 = (RectTransform)GUIManager.Instance.CreateText("[ XStorage ] (you can drag this window!)", base.Transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, 0f), GUIManager.Instance.NorseBold, 18, GUIManager.Instance.ValheimBeige, true, Color.black, val.x, (float)Padding.top, false).transform; val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = new Vector2(24f, -12f); ScrollablePanel = new ScrollablePanel(base.Transform, Padding); ContentPanel = new ContainerGridPanel(ScrollablePanel.ViewPort.transform, gridCellSize, ContainerPanel.WeightPanelWidth); ScrollablePanel.ScrollRectContent = ContentPanel; } public void UpdateSize(int visiblePanelCount) { float screenSizeFactor = GuiScaler.m_scalers[0].GetScreenSizeFactor(); int val = Mathf.FloorToInt((float)Screen.width / screenSizeFactor / ContainerPanel.SinglePanelWithWeightPanelSize.x); int val2 = Mathf.FloorToInt((float)Screen.height / screenSizeFactor / ContainerPanel.SinglePanelWithWeightPanelSize.y); int maxCols = Math.Min(XConfig.Instance.MaxSize.Columns, val); int maxRows = Math.Min(XConfig.Instance.MaxSize.Rows, val2); GridSize = GridSize.Calculate(maxCols, maxRows, visiblePanelCount); UpdatePanelScale(); UpdatePanelSize(); RestorePosition(); } private void UpdatePanelScale() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) float panelScaleValue = XConfig.Instance.PanelScaleValue; ((Transform)base.RectTransform).localScale = new Vector3(panelScaleValue, panelScaleValue, panelScaleValue); } private Vector2 CalculatePanelSize() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) float num = (float)Padding.left + (float)GridSize.Columns * ContainerPanel.SinglePanelWithWeightPanelSize.x + (float)Padding.right; float num2 = (float)Padding.top + (float)GridSize.Rows * ContainerPanel.SinglePanelWithWeightPanelSize.y + (float)Padding.bottom; return new Vector2(num, num2); } private void UpdatePanelSize() { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Log.Debug($"Setting size based on {GridSize}"); Vector2 val = CalculatePanelSize(); base.RectTransform.SetSizeWithCurrentAnchors((Axis)0, val.x); base.RectTransform.SetSizeWithCurrentAnchors((Axis)1, val.y); ContentPanel.GridLayoutGroup.constraint = (Constraint)1; ContentPanel.GridLayoutGroup.constraintCount = GridSize.Columns; } public void SavePosition() { //IL_0011: 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) XConfig.Instance.SavePanelPosition(GridSize, Vector2.op_Implicit(base.Transform.position)); } private void RestorePosition() { //IL_0011: 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) base.Transform.position = Vector2.op_Implicit(XConfig.Instance.GetPanelPosition(GridSize)); ClampToScreen(); } private void ClampToScreen() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_00ab: 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) Vector2 val = Vector2.op_Implicit(base.Transform.position); Rect rect = base.RectTransform.rect; Vector2 val2 = Vector2.op_Implicit(((Transform)base.RectTransform).lossyScale); float num = ((Rect)(ref rect)).width / 2f * val2.x; float num2 = (float)Screen.width - num; float num3 = ((Rect)(ref rect)).height / 2f * val2.y; float num4 = (float)Screen.height - num3; val.x = Mathf.RoundToInt(Mathf.Clamp(val.x, num, num2)); val.y = Mathf.RoundToInt(Mathf.Clamp(val.y, num3, num4)); base.Transform.position = Vector2.op_Implicit(val); } } public class ScrollablePanel : XUIPanel { private ContainerGridPanel scrollRectContent; private ScrollRect ScrollRect => base.GameObject.GetComponent<ScrollRect>(); public GameObject ViewPort { get; } public ContainerGridPanel ScrollRectContent { get { return scrollRectContent; } set { scrollRectContent = value; ScrollRect.content = value.RectTransform; } } public ScrollablePanel(Transform parent, RectOffset padding) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0075: 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_011a: Expected O, but got Unknown base.GameObject = new GameObject("Scroll View", new Type[3] { typeof(Image), typeof(ScrollRect), typeof(Mask) }); base.GameObject.FillParent(padding); base.Parent = parent; ((Graphic)base.GameObject.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 1f); base.GameObject.GetComponent<Mask>().showMaskGraphic = false; ScrollRect.horizontal = false; ScrollRect.vertical = true; ScrollRect.horizontalScrollbarVisibility = (ScrollbarVisibility)1; ScrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)2; ScrollRect.scrollSensitivity = 35f; ScrollRect.movementType = (MovementType)2; ScrollRect.inertia = false; ViewPort = CreateViewPort(base.GameObject.transform); ScrollRect.viewport = (RectTransform)ViewPort.transform; GameObject val = CreateScrollbar(base.GameObject.transform, 8f, 8f); ScrollRect.verticalScrollbar = val.GetComponent<Scrollbar>(); } public void ScrollUp() { if (Object.op_Implicit((Object)(object)ScrollRect)) { ScrollRect.verticalNormalizedPosition = 1f; } } private GameObject CreateViewPort(Transform parent) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown GameObject val = new GameObject("ViewPort", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); Extensions.FillParent(val); ((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0f); return val; } private GameObject CreateScrollbar(Transform parent, float handleSize, float handleDistanceToBorder) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown GameObject val = new GameObject("Scrollbar", new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Scrollbar) }); val.transform.SetParent(parent, false); val.AnchorToRightEdge(handleSize, handleDistanceToBorder); ((Graphic)val.GetComponent<Image>()).color = ((ColorBlock)(ref GUIManager.Instance.ValheimScrollbarHandleColorBlock)).disabledColor; Scrollbar component = val.GetComponent<Scrollbar>(); ((Selectable)component).colors = GUIManager.Instance.ValheimScrollbarHandleColorBlock; component.size = handleSize; component.direction = (Direction)2; component.SetValueWithoutNotify(1f); GameObject val2 = new GameObject("Sliding Area", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); val2.FillParent(); GameObject val3 = CreateHandle(val2.transform, handleSize); component.handleRect = (RectTransform)val3.transform; ((Selectable)component).targetGraphic = (Graphic)(object)val3.GetComponent<Image>(); return val; } private GameObject CreateHandle(Transform parent, float handleSize) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown GameObject val = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(parent, false); Extensions.FillParent(val); Image component = val.GetComponent<Image>(); component.sprite = GUIManager.Instance.GetSprite("UISprite"); component.type = (Type)1; return val; } } } namespace XStorage.Components { public class ContainerGui : MonoBehaviour { public Container m_currentContainer; private InventoryGrid m_grid; private TextMeshProUGUI m_containerName; private TextMeshProUGUI m_containerWeight; private Button m_takeAllButton; private bool m_firstGridUpdate = true; public void Awake() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown Log.Debug("ContainerGui.Awake"); m_grid = ((Component)this).GetComponentInChildren<InventoryGrid>(); InventoryGrid grid = m_grid; grid.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Combine(grid.m_onSelected, new Action<InventoryGrid, ItemData, Vector2i, Modifier>(OnGridItemSelected)); InventoryGrid grid2 = m_grid; grid2.m_onRightClick = (Action<InventoryGrid, ItemData, Vector2i>)Delegate.Combine(grid2.m_onRightClick, new Action<InventoryGrid, ItemData, Vector2i>(OnGridItemRightClick)); m_takeAllButton = ((Component)((Component)this).transform.Find("TakeAll")).GetComponent<Button>(); ((UnityEvent)m_takeAllButton.onClick).AddListener(new UnityAction(OnTakeAll)); m_containerName = ((Component)((Component)this).transform.Find("container_name")).GetComponent<TextMeshProUGUI>(); m_containerWeight = ((Component)((Component)this).transform.Find("Weight/weight_text")).GetComponent<TextMeshProUGUI>(); } public void Update() { UpdateContainer(); UpdateContainerWeight(); } public void OnDestroy() { Log.Debug("ContainerGui.OnDestroy"); if (Object.op_Implicit((Object)(object)m_grid)) { InventoryGrid grid = m_grid; grid.m_onSelected = (Action<InventoryGrid, ItemData, Vector2i, Modifier>)Delegate.Remove(grid.m_onSelected, new Action<InventoryGrid, ItemData, Vector2i, Modifier>(OnGridItemSelected)); InventoryGrid grid2 = m_grid; grid2.m_onRightClick = (Action<InventoryGrid, ItemData, Vector2i>)Delegate.Remove(grid2.m_onRightClick, new Action<InventoryGrid, ItemData, Vector2i>(OnGridItemRightClick)); } } private void OnGridItemRightClick(InventoryGrid grid, ItemData item, Vector2i pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) InventoryGui.instance.OnRightClickItem(grid, item, pos); } private void OnGridItemSelected(InventoryGrid grid, ItemData item, Vector2i pos, Modifier mod) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0042: Unknown result type (might be due to invalid IL or missing references) if ((int)mod == 2 && item != null) { ((Humanoid)Player.m_localPlayer).GetInventory().MoveItemToThis(grid.GetInventory(), item); InventoryGui.instance.UpdateCraftingPanel(false); InventoryGui.instance.m_moveItemEffects.Create(((Component)InventoryGui.instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } else { InventoryGui.instance.OnSelectedItem(grid, item, pos, mod); } } public void OnTakeAll() { Player localPlayer = Player.m_localPlayer; if (!((Character)localPlayer).IsTeleporting() && IsContainerOpen()) { CancelDrag(); Inventory inventory = m_currentContainer.GetInventory(); ((Humanoid)localPlayer).GetInventory().MoveAll(inventory); InventoryGui.instance.UpdateCraftingPanel(false); } } public void UpdateContainer() { if (IsContainerOpen()) { m_currentContainer.SetInUse(true); m_grid.UpdateInventory(m_currentContainer.GetInventory(), (Player)null, (ItemData)null); ((TMP_Text)m_containerName).text = Localization.instance.Localize(m_currentContainer.GetInventory().GetName()); if (m_firstGridUpdate) { m_grid.ResetView(); m_firstGridUpdate = false; } } else { Hide(); } } public void UpdateContainerWeight() { if (IsContainerOpen()) { int num = Mathf.CeilToInt(m_currentContainer.GetInventory().GetTotalWeight()); ((TMP_Text)m_containerWeight).text = num.ToString(); } } public void Show(Container container) { m_firstGridUpdate = true; m_currentContainer = container; ((Component)this).gameObject.SetActive(true); } public void Hide() { ((Component)this).gameObject.SetActive(false); if (IsContainerOpen()) { m_currentContainer.SetInUse(false); m_currentContainer = null; } m_firstGridUpdate = true; } public bool IsContainerOpen() { return Object.op_Implicit((Object)(object)m_currentContainer); } public void CancelDrag() { InventoryGui.instance.SetupDragItem((ItemData)null, (Inventory)null, 1); } } public class ContainerTextReceiver : MonoBehaviour, TextReceiver { public Container m_Container; public void Awake() { m_Container = ((Component)this).GetComponent<Container>(); } public string GetText() { return m_Container.GetXStorageName(); } public void SetText(string text) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) XStorage.UpdateContainerAndInventoryName(m_Container, text); SendToServer.RenameRequest(m_Container.GetZDOID(), text); } } }