Please disclose if any significant portion of your mod was created 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 SmarterContainers v1.10.0
SmartContainers.dll
Decompiled 15 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SmartContainers")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SmartContainers")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6b695573-f20c-49d7-99c3-26f3bd0c12c1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 SmartContainers { internal static class ConfigMigration { private const int CurrentModVersion = 20; public const string Prefixes = "trophy,mead,arrow,cape,helmet,atgeir,bow,battleaxe,knife,mace,shield,sledge,spear,sword,tankard,axe,crossbow,bolt,turretbolt,feast,fishingbait,spice,asksvincarrion"; public const string Postfixes = "seeds"; public const string Valuables = "ruby,coins,coin,amber,amberpearl,ancientcoin,ancientgemstone_black,ancientgemstone_green,ancientgemstone_orange,ancientgemstone_purple,gemstone_blue,gemstone_green,gemstone_red,dragontear,thunderstone,silvernecklace"; public const string Ore = "copperore,tinore,ironore,silverore,flametalore,flametalore_old,ironscrap,blackmetalscrap,copperscrap,bronzescrap"; public const string Rock = "stone,flint,obsidian,grausten,sulfurstone,blackmarble"; public const string Ingots = "copper,tin,bronze,iron,silver,blackmetal,flametal,flametal_old"; public const string Wood = "wood,finewood,roundlog,elderbark,yggdrasilwood,blackwood,frostwood,barkabranch"; public const string Mushrooms = "mushroomcommon,mushroomblue,mushroomyellow,mushroom_bzerker,magecap,jotunpuffs"; public const string Berries = "blueberries,raspberries,cloudberries,lingonberries,pukeberries,vineberry,honey"; public const string Vegetables = "carrot,turnip,onion,fiddleheadfern,kale"; public const string CookedMeat = "meat_cooked,boar_meat_cooked,deer_meat_cooked,wolf_meat_cooked,necktailgrilled,fish_cooked,loxmeat_cooked,serpentmeatcooked,hare_meat_cooked,chicken_meat_cooked,asksvin_meat_cooked,volture_meat_cooked,bonemawmeat_cooked,bjorn_meat_cooked,bug_meat_cooked,moose_meat_cooked,blubber_cooked,egg_cooked,smokedfish,smokedmoosemeat"; public const string Crops = "barley,flax,oat,barleyflour,oatflour"; public const string Cones = "pinecone,fircone,fircone_big"; public const string Eggs = "chicken_egg,voltureegg,asksvin_egg"; public const string Fuel = "coal,resin,tar"; public const string Uncooked = "bakedpoteitr_uncooked,breaddough,fishandbreaduncooked,honeyglazedchickenuncooked,kalechips_uncooked,loxpie_uncooked,magicallystuffedmushroomuncooked,meatplatteruncooked,mistharesupremeuncooked,ovenpancake_uncooked,piquantpie_uncooked,roastedcrustpie_uncooked,vikingcupcake_uncooked"; public const string Soups = "blacksoup,carrotsoup,deerstew,fierysvinstew,fishsoup,onionsoup,sealsoup,serpentstew,sizzlingberrybroth,turnipstew"; public const string Food = "Sausages,QueensJam,BloodPudding"; private const string OldPrefixes = "trophy,mead,arrow,armor,cape,helmet,atgeir,bow,battleaxe,knife,mace,shield,sledge,spear,sword,tankard,club,mushroom,arrow"; private const string OldPostfixes = "cone,seeds,pelt,hide,berries"; private const string OldValuables = "ruby,coins,amber,amberpearl"; private const string OldOre = "copperore,flametalore,ironore,silverore,tinore,ironscrap,blackmetalscrap"; private const string OldRock = "stone,flint,obsidian"; private const string OldIngots = "copper,bronze,flametal,iron,silver,tin,blackmetal"; private const string OldWood = "wood,finewood,corewood,elderbark,roundlog"; private const string OldMushrooms = "Mushroom,MushroomBlue,MushroomYellow,mushroomcommon"; private const string OldBerries = "Blueberries,raspberries,cloudberries,honey"; private const string OldVegetables = "Carrot,Turnip"; private const string OldCookedMeat = "CookedLoxMeat,NeckTailGrilled,MeatCooked,FishCooked,SerpentMeatCooked"; private const string OldFood = "CarrotSoup,Sausages,QueensJam,SerpentStew,TurnipStew,BloodPudding"; private static readonly HashSet<string> DrinkExtraSc = new HashSet<string> { "barleywine", "barleywinebase", "lingondricka", "oatmilk", "shocklatesmoothie", "sparklingshroomshake" }; public static ConfigEntry<int> MigrateConcurrency(ConfigFile config, ConfigEntry<ConcurrentChestModificationWorkaround> concurrency) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown ConfigEntry<int> val = config.Bind<int>("General", "modVersion", 18, new ConfigDescription("Stored config version.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); if (val.Value >= 20) { return val; } if (val.Value < 19 && concurrency.Value == ConcurrentChestModificationWorkaround.ExcludeContainersOpenedByOthers) { concurrency.Value = ConcurrentChestModificationWorkaround.RequestOwnership; } return val; } public static void MigrateGroups(ConfigFile config, ConfigEntry<int> storedModVersion) { Dictionary<string, string> defaultGroupByItem; if (storedModVersion.Value < 20) { defaultGroupByItem = new Dictionary<string, string>(); AddDefaultGroup("ruby,coins,coin,amber,amberpearl,ancientcoin,ancientgemstone_black,ancientgemstone_green,ancientgemstone_orange,ancientgemstone_purple,gemstone_blue,gemstone_green,gemstone_red,dragontear,thunderstone,silvernecklace", "valuables"); AddDefaultGroup("copperore,tinore,ironore,silverore,flametalore,flametalore_old,ironscrap,blackmetalscrap,copperscrap,bronzescrap", "ore"); AddDefaultGroup("stone,flint,obsidian,grausten,sulfurstone,blackmarble", "rock"); AddDefaultGroup("copper,tin,bronze,iron,silver,blackmetal,flametal,flametal_old", "ingots"); AddDefaultGroup("wood,finewood,roundlog,elderbark,yggdrasilwood,blackwood,frostwood,barkabranch", "wood"); AddDefaultGroup("mushroomcommon,mushroomblue,mushroomyellow,mushroom_bzerker,magecap,jotunpuffs", "mushrooms"); AddDefaultGroup("blueberries,raspberries,cloudberries,lingonberries,pukeberries,vineberry,honey", "berries"); AddDefaultGroup("carrot,turnip,onion,fiddleheadfern,kale", "vegetables"); AddDefaultGroup("meat_cooked,boar_meat_cooked,deer_meat_cooked,wolf_meat_cooked,necktailgrilled,fish_cooked,loxmeat_cooked,serpentmeatcooked,hare_meat_cooked,chicken_meat_cooked,asksvin_meat_cooked,volture_meat_cooked,bonemawmeat_cooked,bjorn_meat_cooked,bug_meat_cooked,moose_meat_cooked,blubber_cooked,egg_cooked,smokedfish,smokedmoosemeat", "cookedMeat"); AddDefaultGroup("bakedpoteitr_uncooked,breaddough,fishandbreaduncooked,honeyglazedchickenuncooked,kalechips_uncooked,loxpie_uncooked,magicallystuffedmushroomuncooked,meatplatteruncooked,mistharesupremeuncooked,ovenpancake_uncooked,piquantpie_uncooked,roastedcrustpie_uncooked,vikingcupcake_uncooked", "uncooked"); AddDefaultGroup("blacksoup,carrotsoup,deerstew,fierysvinstew,fishsoup,onionsoup,sealsoup,serpentstew,sizzlingberrybroth,turnipstew", "soups"); AddDefaultGroup("Sausages,QueensJam,BloodPudding", "food"); AddDefaultGroup("barley,flax,oat,barleyflour,oatflour", "crops"); AddDefaultGroup("pinecone,fircone,fircone_big", "cones"); AddDefaultGroup("chicken_egg,voltureegg,asksvin_egg", "eggs"); AddDefaultGroup("coal,resin,tar", "fuel"); HashSet<string> newPrefixSet = ParseIdSet("trophy,mead,arrow,cape,helmet,atgeir,bow,battleaxe,knife,mace,shield,sledge,spear,sword,tankard,axe,crossbow,bolt,turretbolt,feast,fishingbait,spice,asksvincarrion"); MigrateIdList(config, "PrefixedItemGroups", "prefixes", "trophy,mead,arrow,armor,cape,helmet,atgeir,bow,battleaxe,knife,mace,shield,sledge,spear,sword,tankard,club,mushroom,arrow", "trophy,mead,arrow,cape,helmet,atgeir,bow,battleaxe,knife,mace,shield,sledge,spear,sword,tankard,axe,crossbow,bolt,turretbolt,feast,fishingbait,spice,asksvincarrion", null); MigrateIdList(config, "PostfixedItemGroups", "posfixes", "cone,seeds,pelt,hide,berries", "seeds", null); MigrateIdList(config, "ItemGroup", "valuables", "ruby,coins,amber,amberpearl", "ruby,coins,coin,amber,amberpearl,ancientcoin,ancientgemstone_black,ancientgemstone_green,ancientgemstone_orange,ancientgemstone_purple,gemstone_blue,gemstone_green,gemstone_red,dragontear,thunderstone,silvernecklace", (string id) => BelongsToAnotherGroup(id, "valuables", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "ore", "copperore,flametalore,ironore,silverore,tinore,ironscrap,blackmetalscrap", "copperore,tinore,ironore,silverore,flametalore,flametalore_old,ironscrap,blackmetalscrap,copperscrap,bronzescrap", (string id) => BelongsToAnotherGroup(id, "ore", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "rock", "stone,flint,obsidian", "stone,flint,obsidian,grausten,sulfurstone,blackmarble", (string id) => BelongsToAnotherGroup(id, "rock", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "ingots", "copper,bronze,flametal,iron,silver,tin,blackmetal", "copper,tin,bronze,iron,silver,blackmetal,flametal,flametal_old", (string id) => BelongsToAnotherGroup(id, "ingots", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "wood", "wood,finewood,corewood,elderbark,roundlog", "wood,finewood,roundlog,elderbark,yggdrasilwood,blackwood,frostwood,barkabranch", (string id) => BelongsToAnotherGroup(id, "wood", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "mushrooms", "Mushroom,MushroomBlue,MushroomYellow,mushroomcommon", "mushroomcommon,mushroomblue,mushroomyellow,mushroom_bzerker,magecap,jotunpuffs", (string id) => BelongsToAnotherGroup(id, "mushrooms", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "berries", "Blueberries,raspberries,cloudberries,honey", "blueberries,raspberries,cloudberries,lingonberries,pukeberries,vineberry,honey", (string id) => BelongsToAnotherGroup(id, "berries", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "vegetables", "Carrot,Turnip", "carrot,turnip,onion,fiddleheadfern,kale", (string id) => BelongsToAnotherGroup(id, "vegetables", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "cookedMeat", "CookedLoxMeat,NeckTailGrilled,MeatCooked,FishCooked,SerpentMeatCooked", "meat_cooked,boar_meat_cooked,deer_meat_cooked,wolf_meat_cooked,necktailgrilled,fish_cooked,loxmeat_cooked,serpentmeatcooked,hare_meat_cooked,chicken_meat_cooked,asksvin_meat_cooked,volture_meat_cooked,bonemawmeat_cooked,bjorn_meat_cooked,bug_meat_cooked,moose_meat_cooked,blubber_cooked,egg_cooked,smokedfish,smokedmoosemeat", (string id) => BelongsToAnotherGroup(id, "cookedMeat", defaultGroupByItem, newPrefixSet)); MigrateIdList(config, "ItemGroup", "food", "CarrotSoup,Sausages,QueensJam,SerpentStew,TurnipStew,BloodPudding", "Sausages,QueensJam,BloodPudding", (string id) => BelongsToAnotherGroup(id, "food", defaultGroupByItem, newPrefixSet)); storedModVersion.Value = 20; } void AddDefaultGroup(string itemCsv, string group) { foreach (string item in ParseIdSet(itemCsv)) { defaultGroupByItem[item] = group; } } } private static HashSet<string> ParseIdSet(string csv) { HashSet<string> hashSet = new HashSet<string>(); if (string.IsNullOrEmpty(csv)) { return hashSet; } string[] array = csv.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].SCName().Replace(" ", ""); if (text.Length > 0) { hashSet.Add(text); } } return hashSet; } private static void MigrateIdList(ConfigFile config, string section, string key, string oldDefault, string newDefault, Func<string, bool> dropAdded) { ConfigEntry<string> val = default(ConfigEntry<string>); if (!config.TryGetEntry<string>(section, key, ref val)) { return; } HashSet<string> hashSet = ParseIdSet(val.Value); HashSet<string> hashSet2 = ParseIdSet(oldDefault); HashSet<string> collection = ParseIdSet(newDefault); HashSet<string> hashSet3 = new HashSet<string>(hashSet2); hashSet3.ExceptWith(hashSet); HashSet<string> hashSet4 = new HashSet<string>(hashSet); hashSet4.ExceptWith(hashSet2); if (dropAdded != null) { hashSet4.RemoveWhere((string id) => dropAdded(id)); } HashSet<string> hashSet5 = new HashSet<string>(collection); hashSet5.ExceptWith(hashSet3); hashSet5.UnionWith(hashSet4); if (!hashSet5.SetEquals(hashSet)) { string text = string.Join(",", hashSet5.OrderBy((string id) => id)); Mod.log.LogInfo((object)("migrate " + section + "." + key + " -> " + text)); val.Value = text; } } private static bool BelongsToAnotherGroup(string itemId, string group, Dictionary<string, string> defaultGroupByItem, ISet<string> prefixes) { string text = GroupOfItem(itemId, defaultGroupByItem, prefixes); if (text != null) { return text != group; } return false; } private static string GroupOfItem(string itemId, Dictionary<string, string> defaultGroupByItem, ISet<string> prefixes) { if (defaultGroupByItem.TryGetValue(itemId, out var value)) { return value; } if (itemId.EndsWith("berries") || itemId == "vineberry") { return "berries"; } if (ScIsCooked(itemId)) { return "cookedMeat"; } if (ScIsRaw(itemId)) { return "rawMeat"; } if (ScIsSkin(itemId)) { return "skins"; } if (DrinkExtraSc.Contains(itemId)) { return "drinks"; } string text = LongestPrefixSc(itemId, prefixes); if (text == "mead") { return "drinks"; } if (text != null) { return "prefix:" + text; } if (itemId.EndsWith("seeds")) { return "seeds"; } return null; } private static bool ScIsRaw(string sc) { if (sc == "meatrotten" || sc == "mashedmeat" || sc.StartsWith("smoked")) { return false; } switch (sc) { case "meatraw": case "fishraw": case "loxmeat": case "serpentmeat": case "bonemawmeat": case "necktail": case "blubber": return true; default: if (sc.EndsWith("meat")) { return !sc.Contains("cooked"); } return false; } } private static bool ScIsCooked(string sc) { if (sc.Contains("uncooked")) { return false; } switch (sc) { case "necktailgrilled": case "smokedfish": case "smokedmoosemeat": return true; default: if (!sc.Contains("meatcooked")) { return sc.EndsWith("cooked"); } return true; } } private static bool ScIsSkin(string sc) { if (!sc.EndsWith("hide") && !sc.EndsWith("pelt") && !sc.EndsWith("scale")) { return false; } if (!sc.StartsWith("cape") && !sc.StartsWith("shield") && !sc.StartsWith("helmet") && !sc.StartsWith("chest") && !sc.StartsWith("legs") && !sc.StartsWith("trophy")) { return !sc.StartsWith("spear"); } return false; } private static string LongestPrefixSc(string sc, ISet<string> prefixes) { string text = null; foreach (string prefix in prefixes) { bool flag = ((prefix == "shield") ? (sc.StartsWith("shield") && sc != "shieldcore") : ((!(prefix == "axe")) ? sc.StartsWith(prefix) : (sc.StartsWith("axe") && !sc.StartsWith("axehead")))); if (flag && (text == null || prefix.Length > text.Length)) { text = prefix; } } return text; } } internal sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } public static class ContainersTracker { public static ICollection<Container> containerList = new List<Container>(); public static bool isRearrangingItem = false; public static bool teleportingInProgress = false; public static List<Container> GetNearbyContainers(Vector3 center, bool all = false) { //IL_0066: 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) List<Container> list = new List<Container>(); foreach (Container container in containerList) { int num = (all ? (Mod.range.Value * 2) : Mod.range.Value); if ((Object)(object)container != (Object)null && (Object)(object)((Component)container).transform != (Object)null && container.GetInventory() != null && (Object)(object)((Component)container).GetComponentInParent<Piece>() != (Object)null) { float num2 = Vector3.Distance(center, ((Component)container).transform.position); if ((num <= 0 || num2 < (float)num) && container.CheckAccess(Player.m_localPlayer.GetPlayerID())) { list.Add(container); } } } return list; } public static bool IsReliableRoutingTarget(Container container) { return GetRoutingExclusionReason(container) == null; } internal static bool ShouldTrackRoutingTarget(Container container) { if (Mod.unsafeTargetEnabled || IsReliableRoutingTarget(container)) { return true; } LogExcludedTarget(container); return false; } public static void RemoveUnsafeRoutingTargets() { if (Mod.unsafeTargetEnabled) { return; } foreach (Container item in containerList.ToList()) { if ((Object)(object)item != (Object)null && !IsReliableRoutingTarget(item)) { LogExcludedTarget(item); containerList.Remove(item); } } } private static void LogExcludedTarget(Container container) { Mod.log.LogWarning((object)("[SmartContainers excluded target] reason=" + GetRoutingExclusionReason(container) + " name=" + ((Object)container).name + " componentTypes=" + DescribeComponentHierarchy(container))); } private static string GetRoutingExclusionReason(Container container) { if ((Object)(object)container.m_rootObjectOverride != (Object)null) { return "uses m_rootObjectOverride"; } if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null) { return "has Ship host"; } if ((Object)(object)container.m_wagon != (Object)null || (Object)(object)((Component)container).GetComponentInParent<Vagon>() != (Object)null) { return "has Vagon host"; } if ((Object)(object)((Component)container).GetComponentInParent<Incinerator>() != (Object)null) { return "has Incinerator host"; } if ((Object)(object)((Component)container).GetComponentInParent<TombStone>() != (Object)null) { return "has TombStone host"; } if ((Object)(object)((Component)container).GetComponentInParent<Corpse>() != (Object)null) { return "has Corpse host"; } return null; } private static string DescribeComponentHierarchy(Container container) { List<string> list = new List<string>(); Transform val = ((Component)container).transform; while ((Object)(object)val != (Object)null) { string[] value = (from component in ((Component)val).GetComponents<Component>() where (Object)(object)component != (Object)null && !(component is Transform) select ((object)component).GetType().FullName).Distinct().ToArray(); list.Add(((Object)val).name + ":[" + string.Join(",", value) + "]"); val = val.parent; } return string.Join(" <- ", list); } public static void Init() { Container[] array = Object.FindObjectsOfType<Container>(); Mod.log.LogDebug((object)$"tracking {array.Length} discovered containers."); Container[] array2 = array; for (int i = 0; i < array2.Length; i++) { TryTrack(array2[i]); } } internal static bool TryTrack(Container container) { if ((Object)(object)container == (Object)null) { return false; } if (((Object)container).name.StartsWith("Treasure")) { return false; } if (container.GetInventory() == null) { return false; } if (!HasNetworkIdentityForTracking(container)) { return false; } if (!ShouldTrackRoutingTarget(container)) { return false; } if (!containerList.Contains(container)) { containerList.Add(container); } OwnerPut.Register(container); return true; } public static void CleanupContainersList() { Mod.log.LogDebug((object)$"cleanup containerList. size before: {containerList.Count}"); foreach (Container item in containerList.ToList()) { if (!((Object)(object)item != (Object)null) || !((Object)(object)((Component)item).transform != (Object)null) || item.GetInventory() == null) { containerList.Remove(item); } } Mod.log.LogDebug((object)$"cleanup containerList. size after: {containerList.Count}"); } internal static bool HasNetworkIdentityForTracking(Container container) { if ((Object)(object)container?.m_nview == (Object)null || !container.m_nview.IsValid()) { return false; } ZDO zDO = container.m_nview.GetZDO(); if (zDO != null) { if (zDO.GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) == 0L) { return zDO.GetOwner() != 0; } return true; } return false; } } [HarmonyPatch(typeof(Container), "Awake")] internal static class Container_Awake_Patch { private static void Postfix(Container __instance) { if (Mod.modEnabled.Value) { ContainersTracker.TryTrack(__instance); } } } [HarmonyPatch(typeof(Container), "OnDestroyed")] internal static class Container_OnDestroyed_Patch { private static void Prefix(Container __instance) { if (Mod.modEnabled.Value) { ContainersTracker.containerList.Remove(__instance); } } } [HarmonyPatch(typeof(ZNet), "OpenServer")] internal static class ZNet_OpenServer_Patch { private static void Postfix() { if (Mod.modEnabled.Value) { ContainersTracker.RemoveUnsafeRoutingTargets(); } } } [HarmonyPatch(typeof(Inventory), "StackAll")] internal static class Container_OnStackAll_Patch { private static void Postfix(Inventory __instance, Inventory fromInventory, bool message) { if (Mod.unloadAllEnabled.Value && Mod.unloadAllInsteadStackBtn.Value) { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_playerGrid == (Object)null) && !((Object)(object)instance.m_containerGrid == (Object)null) && !((Character)Player.m_localPlayer).IsTeleporting()) { UnloadItems.UnloadAllItems(((Humanoid)Player.m_localPlayer).GetInventory()); } } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] public static class PlayerUpdateTeleport_Patch_Cleanup_Containers { public static void Prefix(float dt) { if (Mod.modEnabled.Value) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && localPlayer.m_teleporting && !ContainersTracker.teleportingInProgress) { OwnerPut.RestoreAllPending(); OwnershipHandoff.Clear(); ContainersTracker.teleportingInProgress = true; } } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] public static class PlayerUpdateTeleport_Postfix { public static void Postfix(float dt) { if (Mod.modEnabled.Value) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && ContainersTracker.teleportingInProgress && !localPlayer.m_teleporting) { ContainersTracker.CleanupContainersList(); ContainersTracker.teleportingInProgress = false; } } } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData) })] public static class Inventory_Patch { internal enum DepositResult { Done, Pending, Failed } internal static bool LastMissInUse; public static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item) { if (BagStackBlocked(item)) { return false; } if (!ShouldHandle(__instance, fromInventory, item)) { return true; } if (__instance.HaveItem(item.m_shared.m_name, true)) { return true; } return !TryRouteFromPlayer(fromInventory, __instance, item); } public static void Postfix(Inventory __instance, Inventory fromInventory, ItemData item) { if (!BagStackBlocked(item) && ShouldHandle(__instance, fromInventory, item) && fromInventory.ContainsItem(item)) { TryRouteFromPlayer(fromInventory, __instance, item); } } private static bool ShouldHandle(Inventory dest, Inventory from, ItemData item) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if (!Mod.modEnabled.Value) { return false; } if (dest == null || from == null || item == null) { return false; } if ((Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).IsTeleporting()) { return false; } if (((object)dest).Equals((object?)((Humanoid)Player.m_localPlayer).GetInventory())) { return false; } if (from != ((Humanoid)Player.m_localPlayer).GetInventory()) { return false; } if (Mod.onlyStackableItems.Value && item.m_shared.m_maxStackSize == 1) { return false; } if (ContainersTracker.isRearrangingItem) { return false; } if (Input.GetKey((KeyCode)108)) { Console.instance.Print("SmartContainers tracked item [" + item.m_shared.m_name + "]"); } KeyboardShortcut value = Mod.keyModifier.Value; if (!((KeyboardShortcut)(ref value)).IsPressed()) { value = Mod.groupingKeyModifier.Value; if (!((KeyboardShortcut)(ref value)).IsPressed() && (!ZInput.GetButton(Mod.gamepadKey1.Value) || !ZInput.GetButton(Mod.gamepadKey2.Value.ToString()))) { return false; } } if ((Object)(object)InventoryGui.instance == (Object)null || !InventoryGui.instance.IsContainerOpen()) { return false; } if (InventoryGui.instance.m_currentContainer.GetInventory() != dest) { return false; } if (!Mod.unsafeTargetEnabled && !Mod.unsafeSourceEnabled.Value && !ContainersTracker.IsReliableRoutingTarget(InventoryGui.instance.m_currentContainer)) { return false; } return true; } private static bool TryRouteFromPlayer(Inventory fromInventory, Inventory dest, ItemData item) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) ContainersTracker.isRearrangingItem = true; try { if (TryHandleDrawers(item)) { fromInventory.RemoveItem(item); dest.Changed(false, false); fromInventory.Changed(false, false); Mod.PlayEffect(Mod.audioFeedbackEnabled.Value, "sfx_lootspawn", ((Character)Player.m_localPlayer).GetCenterPoint()); return true; } Container val = FindRouteTarget(item); if ((Object)(object)val == (Object)null) { OwnerPut.DebugCenter("SC route failed: no chest"); return false; } if (Mod.concurrencyWorkaround.Value.UsesRpc()) { int num = RouteNotice.Open(); DepositResult num2 = Deposit(val, item, fromInventory, allowCurrent: false, playAudio: true, num); if (num2 == DepositResult.Done) { RouteNotice.Moved(num); } RouteNotice.Close(num); if (num2 == DepositResult.Failed) { OwnerPut.DebugCenter("SC route failed: put"); return false; } dest.Changed(false, false); return true; } if (!AddItemToContainer(item, val)) { OwnerPut.DebugCenter("SC route failed: add"); return false; } fromInventory.RemoveItem(item); dest.Changed(false, false); fromInventory.Changed(false, false); PlayRoutedFeedback(item, val, playAudio: true); return true; } finally { ContainersTracker.isRearrangingItem = false; } } internal static bool TryHandleDrawers(ItemData item) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (!Mod.drawersIntegrationEnabled.Value) { return false; } if ((Object)(object)item?.m_dropPrefab == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } foreach (ItemDrawers_API.Drawer item2 in ItemDrawers_API.AllDrawersInRange(((Component)Player.m_localPlayer).transform.position, Mod.range.Value)) { if (((Object)item.m_dropPrefab).name.Equals(item2.Prefab)) { Console.instance.Print($"{item.m_stack}-of-{Localization.instance.Localize(item.m_shared.m_name)} routed because Drawer has same item stack"); item2.Add(item.m_stack); if (Mod.hudMessageEnabled.Value && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.QueueUnlockMsg(item.GetIcon(), item.m_shared.m_name, Mod.hudMessageText.Value); } Mod.PlayEffect(Mod.effectFeedbackEnabled.Value, "vfx_Potion_health_medium", item2.Position); return true; } } return false; } public static Container FindRouteTarget(ItemData item, bool allowCurrent = false, bool forceGrouping = false) { //IL_0125: 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_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) LastMissInUse = false; try { List<Container> nearbyRoutingCandidates = GetNearbyRoutingCandidates(); if (nearbyRoutingCandidates == null) { return null; } Container openedContainer = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_currentContainer : null); foreach (Container item2 in nearbyRoutingCandidates) { Inventory inventory = item2.GetInventory(); if (Accept(item2, inventory != null && (allowCurrent || (Object)(object)openedContainer == (Object)null || ((object)openedContainer).GetHashCode() != ((object)item2).GetHashCode()) && inventory.HaveItem(item.m_shared.m_name, true))) { Console.instance.Print(Localization.instance.Localize(item.m_shared.m_name) + " routed because target container has same item stack"); return item2; } } KeyboardShortcut value; if (Mod.groupingEnabled.Value) { if (!forceGrouping) { value = Mod.groupingKeyModifier.Value; if (!((KeyboardShortcut)(ref value)).IsPressed() && !ZInput.IsGamepadActive()) { goto IL_0420; } } List<Tuple<string, Container>> list = new List<Tuple<string, Container>>(); foreach (Container item3 in nearbyRoutingCandidates) { string text = ItemGroups.FindMatchingUserGroup(item3, item); if (text == null) { continue; } if (!CanRouteTo(item3, item, openedContainer, allowCurrent)) { if (InUseWithoutMod(item3)) { LastMissInUse = true; } } else { list.Add(Tuple.Create<string, Container>(text, item3)); } } if (list.Any()) { Tuple<string, Container> tuple = list.OrderByDescending((Tuple<string, Container> t) => t.Item1).First(); if (list.Count > 1) { Mod.log.LogWarning((object)("Ambiguous item-groups [" + string.Join(",", list) + "] found for " + ((Object)item.m_dropPrefab).name + " item. Using " + tuple.Item1)); } Console.instance.Print(Localization.instance.Localize(item.m_shared.m_name) + " routed because target container has item from group " + tuple.Item1 + " : [" + string.Join(",", ItemGroups.Groups[tuple.Item1]) + "]"); return tuple.Item2; } foreach (Container item4 in nearbyRoutingCandidates) { if (Accept(item4, ItemGroups.ContainerHasSame_SystemGroupItems(item4, item))) { return item4; } } foreach (Container item5 in nearbyRoutingCandidates) { if (Accept(item5, ItemGroups.ContainerHasSame_PatternItems(item5, item))) { return item5; } } foreach (Container item6 in nearbyRoutingCandidates) { if (Accept(item6, ItemGroups.ContainerHasSame_PostfixItems(item6, item))) { return item6; } } if (Mod.itemTypeGroupsEnabled.Value) { foreach (Container item7 in nearbyRoutingCandidates) { if (Accept(item7, ItemGroups.ContainerHasSameItemType(item7, item))) { return item7; } } } goto IL_0420; } goto IL_0496; IL_0496: return null; IL_0420: if (Mod.fuzzyGroupingEnabled.Value) { if (!forceGrouping) { value = Mod.groupingKeyModifier.Value; if (!((KeyboardShortcut)(ref value)).IsPressed() && !ZInput.IsGamepadActive()) { goto IL_0496; } } foreach (Container item8 in nearbyRoutingCandidates) { if (Accept(item8, ItemGroups.ContainerHasSimilarGroupItems(item8, item))) { return item8; } } } goto IL_0496; bool Accept(Container candidate, bool matched) { if (!matched) { return false; } if (CanRouteTo(candidate, item, openedContainer, allowCurrent)) { return true; } if (InUseWithoutMod(candidate)) { LastMissInUse = true; } return false; } } catch (Exception ex) { Mod.log.LogError((object)("Failed to rearrange container items: " + ex)); } return null; } internal static List<Container> GetNearbyRoutingCandidates() { //IL_009a: 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) if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)InventoryGui.instance == (Object)null) { return null; } Container openedContainer = InventoryGui.instance.m_currentContainer; if ((Object)(object)openedContainer == (Object)null) { return null; } if (Mod.concurrencyWorkaround.Value.BlockIfAnyOtherOpened() && ContainersTracker.GetNearbyContainers(((Component)Player.m_localPlayer).transform.position, all: true).Any((Container c) => ((object)openedContainer).GetHashCode() != ((object)c).GetHashCode() && c.m_nview.GetZDO().GetInt("InUse", 0) == 1)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Cant distribute items: other Player is using containers nearby.", 0, (Sprite)null, false); return null; } return ContainersTracker.GetNearbyContainers(((Component)Player.m_localPlayer).transform.position).Where(delegate(Container c) { if (((object)openedContainer).GetHashCode() == ((object)c).GetHashCode()) { return true; } if (Mod.concurrencyWorkaround.Value.Ignore()) { return true; } ZDO zDO = c.m_nview.GetZDO(); if (zDO == null) { return false; } bool flag = zDO.GetInt("InUse", 0) == 1; if (Mod.concurrencyWorkaround.Value.UsesRpc()) { if (zDO.GetOwner() == 0L) { return false; } if (flag) { return OwnerPut.PeerHasFlag(c); } return true; } return (Mod.concurrencyWorkaround.Value.SkipOpenedOthers() || Mod.concurrencyWorkaround.Value.BlockIfAnyOtherOpened()) && !flag; }).ToList(); } private static bool CanRouteTo(Container target, ItemData item, Container opened, bool allowCurrent) { if ((Object)(object)target == (Object)null || target.GetInventory() == null) { return false; } if (Mod.concurrencyWorkaround.Value.UsesRpc() && !target.IsOwner()) { ZDO val = (((Object)(object)target.m_nview != (Object)null) ? target.m_nview.GetZDO() : null); if (val == null || val.GetOwner() == 0L) { return false; } if (val.GetInt("InUse", 0) == 1 && !OwnerPut.PeerHasFlag(target)) { return false; } } if (!target.GetInventory().CanAddItem(item, -1)) { return false; } if (!allowCurrent && (Object)(object)opened != (Object)null && ((object)opened).GetHashCode() == ((object)target).GetHashCode()) { return false; } return true; } private static bool InUseWithoutMod(Container target) { if (!Mod.concurrencyWorkaround.Value.UsesRpc() || (Object)(object)target == (Object)null || target.IsOwner()) { return false; } ZDO val = (((Object)(object)target.m_nview != (Object)null) ? target.m_nview.GetZDO() : null); if (val == null || val.GetOwner() == 0L) { return false; } if (val.GetInt("InUse", 0) == 1) { return !OwnerPut.PeerHasFlag(target); } return false; } internal static DepositResult Deposit(Container target, ItemData item, Inventory from, bool allowCurrent, bool playAudio, int batch) { if (BagStackBlocked(item)) { return DepositResult.Pending; } if (target.IsOwner()) { if (!AddItemToContainer(item, target, allowCurrent)) { return DepositResult.Failed; } from.RemoveItem(item); PlayRoutedFeedback(item, target, playAudio); return DepositResult.Done; } ZDO val = (((Object)(object)target.m_nview != (Object)null) ? target.m_nview.GetZDO() : null); if (val == null || val.GetOwner() == 0L) { return DepositResult.Failed; } if (val.GetInt("InUse", 0) == 1) { if (!OwnerPut.PeerHasFlag(target)) { return DepositResult.Failed; } if (!OwnerPut.BeginRemotePut(target, item, from)) { return DepositResult.Failed; } return DepositResult.Pending; } if (!OwnershipHandoff.Begin(target, item, from, playAudio, batch)) { return DepositResult.Failed; } return DepositResult.Pending; } internal static bool BagStackBlocked(ItemData item) { if (item != null) { if (!OwnerPut.IsAwaitingLateOk(item)) { return OwnershipHandoff.Holds(item); } return true; } return false; } internal static bool AddItemToContainer(ItemData item, Container targetContainer, bool allowCurrent = false) { if ((Object)(object)targetContainer == (Object)null || item == null) { return false; } if (Mod.concurrencyWorkaround.Value.UsesRpc() && !targetContainer.IsOwner()) { return false; } Container val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_currentContainer : null); if (allowCurrent || (Object)(object)val == (Object)null || ((object)val).GetHashCode() != ((object)targetContainer).GetHashCode()) { bool num = targetContainer.GetInventory().AddItem(item); if (num && (!Mod.concurrencyWorkaround.Value.UsesRpc() || !targetContainer.IsOwner())) { targetContainer.Save(); } return num; } return false; } internal static void PlayRoutedFeedback(ItemData item, Container targetContainer, bool playAudio) { //IL_0028: 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) if (item != null) { if (playAudio && (Object)(object)Player.m_localPlayer != (Object)null) { Mod.PlayEffect(Mod.audioFeedbackEnabled.Value, "sfx_lootspawn", ((Character)Player.m_localPlayer).GetCenterPoint()); } Container val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_currentContainer : null); if (Mod.hudMessageEnabled.Value && (Object)(object)MessageHud.instance != (Object)null && ((Object)(object)val == (Object)null || !((object)val).Equals((object?)targetContainer))) { MessageHud.instance.QueueUnlockMsg(item.GetIcon(), item.m_shared.m_name, Mod.hudMessageText.Value); } if ((Object)(object)targetContainer != (Object)null) { Mod.PlayEffect(Mod.effectFeedbackEnabled.Value, "vfx_Potion_health_medium", ((Component)targetContainer).transform.position); } } } } internal static class RouteNotice { private sealed class Batch { public int Moved; public int Busy; public int Pending; } private static int next; private static readonly Dictionary<int, Batch> OpenBatches = new Dictionary<int, Batch>(); public static int Open() { int num = ++next; OpenBatches[num] = new Batch(); return num; } public static void Moved(int id) { if (OpenBatches.TryGetValue(id, out var value)) { value.Moved++; } } public static void Busy(int id) { if (OpenBatches.TryGetValue(id, out var value)) { value.Busy++; } } public static void Pending(int id) { if (id != 0 && OpenBatches.TryGetValue(id, out var value)) { value.Pending++; } } public static void Settle(int id, bool moved) { if (OpenBatches.TryGetValue(id, out var value)) { if (value.Pending > 0) { value.Pending--; } if (moved) { value.Moved++; } else { value.Busy++; } Announce(id, value); } } public static void Drop(int id) { if (OpenBatches.TryGetValue(id, out var value)) { if (value.Pending > 0) { value.Pending--; } Announce(id, value); } } public static void Close(int id) { if (OpenBatches.TryGetValue(id, out var value)) { Announce(id, value); } } public static void Clear() { OpenBatches.Clear(); } private static void Announce(int id, Batch batch) { if (batch.Pending <= 0) { OpenBatches.Remove(id); if (batch.Busy != 0 && !((Object)(object)Player.m_localPlayer == (Object)null)) { ((Character)Player.m_localPlayer).Message((MessageType)2, (batch.Moved == 0) ? "$msg_inuse" : "Some items were not moved", 0, (Sprite)null, false); } } } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(int), typeof(int) })] internal static class Inventory_MoveItemToSlot_Patch { private static bool Prefix(ItemData item) { return !Inventory_Patch.BagStackBlocked(item); } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] internal static class InventoryGrid_DropItem_Patch { private static bool Prefix(ItemData item) { return !Inventory_Patch.BagStackBlocked(item); } } [HarmonyPatch(typeof(Humanoid), "DropItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int) })] internal static class Humanoid_DropItem_Patch { private static bool Prefix(ItemData item) { return !Inventory_Patch.BagStackBlocked(item); } } public static class ItemDrawers_API { public class Drawer { private readonly ZNetView znv; public readonly string Prefab; public readonly Vector3 Position; public readonly int Amount; public Drawer(ZNetView znv) { //IL_002b: 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) this.znv = znv; Amount = znv.m_zdo.GetInt("Amount", 0); Position = znv.m_zdo.GetPosition(); Prefab = znv.m_zdo.GetString("Prefab", ""); } public void Remove(int amount) { znv.ClaimOwnership(); znv.InvokeRPC("ForceRemove", new object[1] { amount }); } public void Withdraw(int amount) { znv.InvokeRPC("WithdrawItem_Request", new object[1] { amount }); } public void Add(int amount) { znv.InvokeRPC("AddItem_Request", new object[2] { Prefab, amount }); } } private static readonly bool _IsInstalled; private static readonly MethodInfo MI_GetAllDrawers; public static List<Drawer> AllDrawers { get { if (!_IsInstalled) { return new List<Drawer>(); } return ((List<ZNetView>)MI_GetAllDrawers.Invoke(null, null)).Select((ZNetView znv) => new Drawer(znv)).ToList(); } } public static List<Drawer> AllDrawersInRange(Vector3 pos, float range) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!_IsInstalled) { return new List<Drawer>(); } return (from znv in (List<ZNetView>)MI_GetAllDrawers.Invoke(null, null) where Vector3.Distance(((Component)znv).transform.position, pos) <= range select new Drawer(znv)).ToList(); } static ItemDrawers_API() { Type type = Type.GetType("API.ClientSide, kg_ItemDrawers"); if ((object)type == null) { _IsInstalled = false; return; } _IsInstalled = true; MI_GetAllDrawers = type.GetMethod("AllDrawers", BindingFlags.Static | BindingFlags.Public); } } public static class GuiFactory { public static Transform AddContainerGuiButton(string btnObjName, string text, Vector2 size, Vector2 pos) { //IL_0016: 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) return CreateButton(btnObjName, text, ((Component)InventoryGui.instance.m_takeAllButton).transform.parent, size, pos); } public static Transform CreateButton(string btnObjName, string text, Transform parent, Vector2 size, Vector2 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0062: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown _ = (RectTransform)parent.Find(btnObjName); Transform obj = Object.Instantiate<Transform>(((Component)InventoryGui.instance.m_takeAllButton).transform, parent); ((Object)obj).name = btnObjName; RectTransform val = (RectTransform)((Component)obj).transform; val.SetSizeWithCurrentAnchors((Axis)0, size.x); val.SetSizeWithCurrentAnchors((Axis)1, size.y); RectTransform val2 = (RectTransform)((Component)val).transform.Find("Text"); val2.SetSizeWithCurrentAnchors((Axis)0, size.x); val2.SetSizeWithCurrentAnchors((Axis)1, size.y); ((TMP_Text)((Component)val2).GetComponent<TextMeshProUGUI>()).text = text; val.pivot = pos; return (Transform)val; } public static void InitJoyKey(Transform btnComponent, string joyKeyCode, string tooltip) { //IL_0044: 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_0069: 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) UIGamePad component = ((Component)btnComponent).GetComponent<UIGamePad>(); Transform val = Object.Instantiate<Transform>(((Component)btnComponent).transform.Find("Text"), ((Component)component).transform); TextMeshProUGUI component2 = ((Component)val).GetComponent<TextMeshProUGUI>(); ((TMP_Text)component2).text = tooltip; ((Graphic)component2).color = new Color(0.8f, 0.8f, 0.8f, 1f); Transform transform = ((Component)val).transform; transform.position += new Vector3(0f, 13f, 0f); if ((Object)(object)component.m_hint != (Object)null) { Object.Destroy((Object)(object)component.m_hint); } ((Component)val).gameObject.SetActive(false); component.m_hint = ((Component)val).gameObject; component.m_zinputKey = joyKeyCode; component.m_availableForConsoleMouse = false; } public static void RefreshJoyHint(Transform btn) { if (!Object.op_Implicit((Object)(object)btn) || ZInput.instance == null) { return; } UIGamePad component = ((Component)btn).GetComponent<UIGamePad>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_hint) && !string.IsNullOrEmpty(component.m_zinputKey)) { TextMeshProUGUI component2 = component.m_hint.GetComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)component2)) { ((Behaviour)component2).enabled = true; ((TMP_Text)component2).text = ZInput.instance.GetBoundKeyString(component.m_zinputKey, false); } } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class Gui_Patch { public static bool initialized; private static Transform createGroupButton; private static Transform storeAllButton; private static TMP_Text routingDisabledLabel; private static void Postfix(InventoryGui __instance) { if (Mod.modEnabled.Value && !((Object)(object)__instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && __instance.IsContainerOpen()) { if (!initialized) { InitButtons(__instance); } RefreshJoyHints(); UpdateRoutingDisabledLabel(__instance); } } private static void InitButtons(InventoryGui __instance) { if (!Mod.modEnabled.Value) { return; } try { AddRoutingDisabledLabel(__instance); if ((Mod.groupingEnabled.Value || Mod.unloadAllEnabled.Value) && Mod.createGroupBtnEnabled.Value) { AddCreateGroupBtn(__instance); } if (Mod.unloadAllEnabled.Value && !Mod.unloadAllInsteadStackBtn.Value) { AddStoreAllBtn(__instance); } initialized = true; } catch (Exception ex) { Mod.log.LogError((object)("Failed to properly patch GUI with additional buttons: " + ex)); Clean(); } finally { Mod.log.LogInfo((object)"Initialized UI extensions."); } } private static void AddRoutingDisabledLabel(InventoryGui inventoryGui) { //IL_0069: 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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)routingDisabledLabel != (Object)null) && !((Object)(object)inventoryGui.m_containerName == (Object)null)) { routingDisabledLabel = Object.Instantiate<TMP_Text>(inventoryGui.m_containerName, (Transform)(object)inventoryGui.m_container); ((Object)routingDisabledLabel).name = "smartRoutingDisabledLabel"; routingDisabledLabel.text = "Smart Routing disabled"; ((Graphic)routingDisabledLabel).color = new Color(1f, 0.55f, 0.2f, 1f); routingDisabledLabel.fontSize = Mathf.Max(12f, inventoryGui.m_containerName.fontSize * 0.5f); ((Graphic)routingDisabledLabel).raycastTarget = false; RectTransform val = (RectTransform)routingDisabledLabel.transform; val.anchorMin = new Vector2(0f, 0f); val.anchorMax = new Vector2(0f, 0f); val.pivot = new Vector2(0f, 0f); val.anchoredPosition = new Vector2(-16f, -16f); ((Component)routingDisabledLabel).gameObject.SetActive(false); } } private static void UpdateRoutingDisabledLabel(InventoryGui inventoryGui) { if (!((Object)(object)routingDisabledLabel == (Object)null)) { Container currentContainer = inventoryGui.m_currentContainer; bool flag = (Object)(object)currentContainer != (Object)null && (Mod.unsafeTargetEnabled || Mod.unsafeSourceEnabled.Value || ContainersTracker.IsReliableRoutingTarget(currentContainer)); ((Component)routingDisabledLabel).gameObject.SetActive(!flag && Mod.unsafeSourceLabelDisplayed.Value); if ((Object)(object)createGroupButton != (Object)null) { ((Component)createGroupButton).gameObject.SetActive(flag); } if ((Object)(object)storeAllButton != (Object)null) { ((Component)storeAllButton).gameObject.SetActive(flag); } } } private static void RefreshJoyHints() { GuiFactory.RefreshJoyHint(createGroupButton); GuiFactory.RefreshJoyHint(storeAllButton); } public static void HideRoutingDisabledLabel() { if ((Object)(object)routingDisabledLabel != (Object)null) { ((Component)routingDisabledLabel).gameObject.SetActive(false); } } private static void AddCreateGroupBtn(InventoryGui __instance) { //IL_0021: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown createGroupButton = GuiFactory.AddContainerGuiButton("createGroupBtn", "☀", new Vector2(45f, 30f), Mod.createGroupBtnPos.Value); GuiFactory.InitJoyKey(createGroupButton, "JoyMap", ZInput.instance.GetBoundKeyString("JoyMap", false)); Button component = ((Component)createGroupButton).GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) if (!((Object)(object)__instance.m_playerGrid == (Object)null) && !((Object)(object)__instance.m_containerGrid == (Object)null) && !((Character)Player.m_localPlayer).IsTeleporting()) { Inventory inventory = __instance.m_containerGrid.GetInventory(); KeyboardShortcut value; if (Mod.unloadAllEnabled.Value) { value = Mod.unloadAllItemsGroupKeyModifier.Value; if (((KeyboardShortcut)(ref value)).IsPressed() || ZInput.GetButton("JoyRTrigger")) { UnloadItems.AddToUnloadAllItemsFilter(inventory); return; } } if (Mod.unloadAllEnabled.Value) { value = Mod.unloadAllSkipItemsGroupKeyModifier.Value; if (((KeyboardShortcut)(ref value)).IsPressed() || ZInput.GetButton("JoyLTrigger")) { UnloadItems.AddToUnloadAllItemsSkipList(inventory); return; } } if (Mod.groupingEnabled.Value) { GroupEditor.Open(inventory, __instance.m_currentContainer); } } }); } private static void AddStoreAllBtn(InventoryGui __instance) { //IL_0021: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown storeAllButton = GuiFactory.AddContainerGuiButton("storeAllButton", "↓↓↓", new Vector2(45f, 36f), Mod.unloadAllBtnPos.Value); GuiFactory.InitJoyKey(storeAllButton, "JoyMenu", ZInput.instance.GetBoundKeyString("JoyMenu", false)); ((UnityEvent)((Component)storeAllButton).GetComponent<Button>().onClick).AddListener((UnityAction)delegate { if (!((Object)(object)__instance.m_playerGrid == (Object)null) && !((Object)(object)__instance.m_containerGrid == (Object)null) && !((Character)Player.m_localPlayer).IsTeleporting()) { UnloadItems.UnloadAllItems(((Humanoid)Player.m_localPlayer).GetInventory()); } }); } public static void Init() { if ((Object)(object)InventoryGui.instance != (Object)null) { InitButtons(InventoryGui.instance); if (InventoryGui.instance.IsContainerOpen()) { UpdateRoutingDisabledLabel(InventoryGui.instance); } } } public static void Clean() { if ((Object)(object)createGroupButton != (Object)null) { Object.Destroy((Object)(object)((Component)createGroupButton).gameObject); } if ((Object)(object)storeAllButton != (Object)null) { Object.Destroy((Object)(object)((Component)storeAllButton).gameObject); } if ((Object)(object)routingDisabledLabel != (Object)null) { Object.Destroy((Object)(object)((Component)routingDisabledLabel).gameObject); } GroupEditor.Close(); initialized = false; routingDisabledLabel = null; Mod.log.LogInfo((object)"Cleaned up UI extensions."); } } [HarmonyPatch(typeof(UIGamePad), "Update")] internal static class ChestHintPatch { private static void Postfix(UIGamePad __instance) { if (Object.op_Implicit((Object)(object)__instance.m_hint)) { string name = ((Object)((Component)__instance).gameObject).name; if ((!(name != "createGroupBtn") || !(name != "storeAllButton")) && (!ZInput.IsGamepadActive() || ZInput.IsMouseActive())) { __instance.m_hint.SetActive(false); } } } } [HarmonyPatch(typeof(Game), "Start")] public static class Game_Start_Patch { private static void Postfix(Game __instance) { Gui_Patch.Clean(); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class Gui_Hide_Patch { private static void Postfix(InventoryGui __instance) { if (Gui_Patch.initialized) { GroupEditor.Close(); Gui_Patch.HideRoutingDisabledLabel(); } } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class InventoryGrid_UpdateGui_Patch { private static readonly Color Dim = new Color(0.35f, 0.5f, 0.75f, 1f); private static readonly Color Lit = new Color(0.75f, 0.9f, 1f, 1f); private static void Postfix(InventoryGrid __instance) { //IL_0030: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)__instance != (Object)(object)instance.m_playerGrid) { return; } Inventory inventory = __instance.m_inventory; if (inventory == null) { return; } int width = inventory.GetWidth(); Color color = Color.Lerp(Dim, Lit, 0.5f + 0.5f * Mathf.Sin(Time.time * 6f)); List<ItemData> inventory2 = inventory.m_inventory; for (int i = 0; i < inventory2.Count; i++) { ItemData val = inventory2[i]; if (Inventory_Patch.BagStackBlocked(val)) { InventoryElement element = __instance.GetElement(val.m_gridPos.x, val.m_gridPos.y, width); if (!((Object)(object)element?.m_icon == (Object)null)) { ((Graphic)element.m_icon).color = color; } } } } } public static class GroupEditor { private sealed class ItemInfo { internal string ScName; internal string Label; internal string Topic; internal string Description; internal Sprite Icon; internal ItemType ItemType; internal bool HasType; } private enum CellRole { Group, Chest, Search, Rule } private sealed class Cell { internal ItemInfo Info; internal CellRole Role; internal GameObject Root; internal Image Background; internal Image Icon; internal Image Dot; internal Image[] Marks; internal TextMeshProUGUI Name; internal TextMeshProUGUI More; internal GameObject Frame; } private sealed class Row { internal string Id; internal Image Background; internal Image Mark; internal TextMeshProUGUI Label; internal GameObject Frame; internal GameObject DeleteHint; } private enum RuleKind { Pattern, Postfix, Type, Fuzzy } private sealed class RuleSet { internal RuleKind Kind; internal string Id; internal string Label; internal readonly List<ItemInfo> Items = new List<ItemInfo>(); } private sealed class RuleRowUi { internal RuleSet Set; internal Image Background; internal Image Mark; internal TextMeshProUGUI Label; } [CompilerGenerated] private static class <>O { public static UnityAction <0>__CreateGroup; public static UnityAction <1>__AddAllSearch; public static UnityAction <2>__CloseSearch; public static UnityAction <3>__Close; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Comparison<ItemInfo> <>9__75_0; public static UnityAction <>9__80_0; public static UnityAction <>9__80_1; public static UnityAction<string> <>9__80_2; public static UnityAction<string> <>9__80_3; public static UnityAction <>9__80_4; public static UnityAction <>9__80_5; public static Func<string, ItemInfo> <>9__86_0; public static Func<ItemInfo, bool> <>9__86_1; public static Func<ItemInfo, string> <>9__86_2; public static Func<string, ItemInfo> <>9__87_0; public static Func<ItemInfo, bool> <>9__87_1; public static Func<ItemInfo, string> <>9__87_2; public static Func<string, int> <>9__88_0; public static Func<string, int> <>9__88_1; public static Func<string, int> <>9__88_2; public static Func<string, string> <>9__88_3; public static Func<Row, bool> <>9__120_0; public static Func<Row, int> <>9__120_1; public static Func<Row, int> <>9__120_2; public static Func<Row, int> <>9__120_3; public static Func<Row, string> <>9__120_4; public static Func<Cell, bool> <>9__122_0; public static Func<Cell, bool> <>9__122_1; public static Func<string, bool> <>9__129_0; public static Func<string, int> <>9__129_1; public static Func<string, string> <>9__129_2; public static Comparison<ItemInfo> <>9__175_0; public static Func<RuleSet, bool> <>9__178_0; public static Func<RuleSet, string> <>9__178_1; public static Func<Row, bool> <>9__241_0; public static Func<Row, int> <>9__241_1; public static Func<Row, int> <>9__241_2; public static Func<Row, int> <>9__241_3; public static Func<Row, string> <>9__241_4; public static Func<RuleRowUi, bool> <>9__243_0; internal int <Index>b__75_0(ItemInfo a, ItemInfo b) { return string.Compare(a.Label, b.Label, StringComparison.CurrentCultureIgnoreCase); } internal void <Build>b__80_0() { SetReference(on: false); } internal void <Build>b__80_1() { SetReference(on: true); } internal void <Build>b__80_2(string _) { RefreshSearch(); } internal void <Build>b__80_3(string text) { if (!string.IsNullOrEmpty(text.Trim())) { RefreshSearch(); } } internal void <Build>b__80_4() { AddChest(ungroupedOnly: false); } internal void <Build>b__80_5() { AddChest(ungroupedOnly: true); } internal ItemInfo <GroupSeed>b__86_0(string sc) { if (!known.TryGetValue(sc, out var value)) { return null; } return value; } internal bool <GroupSeed>b__86_1(ItemInfo info) { return info != null; } internal string <GroupSeed>b__86_2(ItemInfo info) { return info.Label; } internal ItemInfo <ChestItems>b__87_0(string sc) { if (!known.TryGetValue(sc, out var value)) { return null; } return value; } internal bool <ChestItems>b__87_1(ItemInfo info) { return info != null; } internal string <ChestItems>b__87_2(ItemInfo info) { return info.Label; } internal int <RebuildRows>b__88_0(string key) { return (!(key == fresh)) ? 1 : 0; } internal int <RebuildRows>b__88_1(string key) { return (!HitsChest(key)) ? 1 : 0; } internal int <RebuildRows>b__88_2(string key) { return Mod.isSystemGroup(key) ? 1 : 0; } internal string <RebuildRows>b__88_3(string key) { return key; } internal bool <OrderRows>b__120_0(Row row) { if (Object.op_Implicit((Object)(object)row.Background)) { return groups.ContainsKey(row.Id); } return false; } internal int <OrderRows>b__120_1(Row row) { return (!(row.Id == fresh)) ? 1 : 0; } internal int <OrderRows>b__120_2(Row row) { return (!HitsChest(row.Id)) ? 1 : 0; } internal int <OrderRows>b__120_3(Row row) { return Mod.isSystemGroup(row.Id) ? 1 : 0; } internal string <OrderRows>b__120_4(Row row) { return row.Id; } internal bool <ApplyVisibility>b__122_0(Cell cell) { if (selected != null) { if (!groups[selected].Contains(cell.Info.ScName)) { return pulled.Contains(cell.Info.ScName); } return true; } return false; } internal bool <ApplyVisibility>b__122_1(Cell _) { return true; } internal bool <RefreshChestLegend>b__129_0(string id) { if (HitsChest(id)) { return !legendSlot.ContainsKey(id); } return false; } internal int <RefreshChestLegend>b__129_1(string key) { return (!Mod.isSystemGroup(key)) ? 1 : 0; } internal string <RefreshChestLegend>b__129_2(string key) { return key; } internal int <IndexRules>b__175_0(ItemInfo a, ItemInfo b) { return string.Compare(a.Label, b.Label, StringComparison.CurrentCultureIgnoreCase); } internal bool <BuildRuleRows>b__178_0(RuleSet set) { return set.Kind == RuleKind.Fuzzy; } internal string <BuildRuleRows>b__178_1(RuleSet set) { return set.Label; } internal bool <GroupList>b__241_0(Row row) { if (Object.op_Implicit((Object)(object)row.Background)) { return groups.ContainsKey(row.Id); } return false; } internal int <GroupList>b__241_1(Row row) { return (!(row.Id == fresh)) ? 1 : 0; } internal int <GroupList>b__241_2(Row row) { return (!HitsChest(row.Id)) ? 1 : 0; } internal int <GroupList>b__241_3(Row row) { return Mod.isSystemGroup(row.Id) ? 1 : 0; } internal string <GroupList>b__241_4(Row row) { return row.Id; } internal bool <RuleList>b__243_0(RuleRowUi row) { if (Object.op_Implicit((Object)(object)row.Background)) { return Object.op_Implicit((Object)(object)row.Label); } return false; } } private const float Width = 960f; private const float Height = 630f; private const int Columns = 10; private const float GridWidth = 664f; private const float CellGap = 4f; private const int CellPad = 4; private static readonly Color Idle = new Color(0.12f, 0.09f, 0.06f, 0.95f); private static readonly Color OneGroup = new Color(0.24f, 0.18f, 0.12f, 1f); private static readonly Color ManyGroups = new Color(0.34f, 0.16f, 0.12f, 1f); private static readonly Color Error = new Color(1f, 0.45f, 0.35f, 1f); private static readonly Color Added = new Color(0.32f, 0.68f, 0.36f, 1f); private static readonly Color Pulled = new Color(0.28f, 0.3f, 0.32f, 0.45f); private static readonly Color PulledHover = new Color(0.42f, 0.44f, 0.46f, 0.72f); private static readonly Color[] GroupDots = (Color[])(object)new Color[5] { new Color(0.95f, 0.76f, 0.22f, 1f), new Color(0.3f, 0.72f, 0.95f, 1f), new Color(0.92f, 0.4f, 0.58f, 1f), new Color(0.62f, 0.45f, 0.95f, 1f), new Color(0.95f, 0.5f, 0.22f, 1f) }; private static readonly Color RowChest = new Color(0.28f, 0.48f, 0.3f, 1f); private static readonly Color ChestText = new Color(0.65f, 0.9f, 0.55f, 1f); private static readonly Dictionary<string, HashSet<string>> opened = new Dictionary<string, HashSet<string>>(); private static readonly HashSet<string> pulled = new HashSet<string>(); private static string pendingDelete; private static readonly Dictionary<string, ItemInfo> known = new Dictionary<string, ItemInfo>(); private static readonly List<ItemInfo> catalog = new List<ItemInfo>(); private static readonly List<Cell> groupCells = new List<Cell>(); private static readonly List<Cell> chestCells = new List<Cell>(); private static readonly List<Row> rows = new List<Row>(); private static readonly List<GameObject> searchRows = new List<GameObject>(); private static readonly List<Cell> searchCells = new List<Cell>(); private static readonly HashSet<string> chestNames = new HashSet<string>(); private static readonly List<string> legendOrder = new List<string>(); private static readonly Dictionary<string, int> legendSlot = new Dictionary<string, int>(); private static GameObject canvas; private static Container chest; private static string selected; private static string fresh; private static Cell hovered; private static Row hotRow; private static TMP_InputField nameInput; private static TMP_InputField searchInput; private static TMP_Text info; private static TMP_Text status; private static TMP_Text chestTitle; private static Button newButton; private static Button addAllButton; private static Button addLooseButton; private static Button groupsTab; private static Button patternsTab; private static ScrollRect itemScroll; private static ScrollRect chestScroll; private static RectTransform chestLegend; private static ScrollRect listScroll; private static RectTransform groupContent; private static bool rulesMode; private static GameObject searchPopup; private static RectTransform searchContent; private static ScrollRect searchScroll; private static GameObject tooltipPrefab; private static int blockFrame = -10; private static bool polling; private static readonly Color CellFrameColor = new Color(0.82f, 0.74f, 0.52f, 0.55f); private static Sprite dotSprite; private static Sprite cornerSprite; private static readonly List<RuleSet> ruleSets = new List<RuleSet>(); private static readonly Dictionary<string, RuleSet> ruleByKey = new Dictionary<string, RuleSet>(); private static readonly List<RuleRowUi> ruleRows = new List<RuleRowUi>(); private static readonly List<Cell> ruleCells = new List<Cell>(); private static readonly List<string> postfixScratch = new List<string>(); private static TMP_InputField composer; private static bool addingPrefix; private static bool addingPostfix; private static bool composerCommit; private static bool composerKeep; private static bool composerCancel; private static int composerCancelFrame = -1; private static bool editing; private static RuleKind editKind; private static string editKindId; private static readonly List<string> editPrefixes = new List<string>(); private static readonly List<string> editPostfixes = new List<string>(); private static RuleSet renaming; private static RectTransform ruleContent; private static RuleSet shownRule; private static string pendingToken; private static readonly Color FrameColor = new Color(1f, 0.86f, 0.2f, 1f); private static int groupArea; private static int groupFocus; private static int ruleArea; private static int ruleFocus; private static bool padLive; private static RectTransform areaFrame; private static Cell padTip; private static GameObject padTipRoot; private static readonly Vector3[] tipCorners = (Vector3[])(object)new Vector3[4]; private static float CellEdge => 62f; private static IDictionary<string, ISet<string>> groups => ItemGroups.Groups; internal static bool IsOpen => Object.op_Implicit((Object)(object)canvas); internal static bool BlockKeys { get { if (polling) { return false; } if (IsOpen) { blockFrame = Time.frameCount; return true; } return Time.frameCount <= blockFrame + 1; } } private static int AreaCount { get { if (!rulesMode) { return 3; } return 2; } } private static int Area { get { if (!rulesMode) { return groupArea; } return ruleArea; } set { if (rulesMode) { ruleArea = value; } else { groupArea = value; } } } private static int Focus { get { if (!rulesMode) { return groupFocus; } return ruleFocus; } set { if (rulesMode) { ruleFocus = value; } else { groupFocus = value; } } } internal static void Tick() { if (composerCancel && Time.frameCount > composerCancelFrame) { composerCancel = false; if (editing) { EndEdit(rebuild: true); } } if (!IsOpen) { return; } InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if (!Mod.modEnabled.Value || !Mod.groupingEnabled.Value || !Object.op_Implicit((Object)(object)instance) || !instance.IsContainerOpen() || (Object)(object)instance.m_currentContainer != (Object)(object)chest || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead()) { Close(); return; } if (Object.op_Implicit((Object)(object)searchPopup) && searchPopup.activeSelf && ZInput.GetKeyDown((KeyCode)323, false) && !PointerOverSearch()) { CloseSearch(); } PadTick(); if (BackPressed()) { if (pendingDelete != null || pendingToken != null) { pendingDelete = null; pendingToken = null; SetStatus("", error: false); } else { Close(); } } } public static void Open(Inventory inventory, Container container) { if (!IsOpen && inventory != null && Object.op_Implicit((Object)(object)container)) { InventoryGui instance = InventoryGui.instance; if (Object.op_Implicit((Object)(object)instance)) { GroupUi.Capture(instance); CaptureTooltip(instance); chest = container; selected = null; fresh = null; hovered = null; ResetFocus(); UITooltip.HideTooltip(); NoteOpened(); Index(inventory); Build(instance); Select(BestGroup(), resetItems: true); } } } public static void Close() { UITooltip.HideTooltip(); if (Object.op_Implicit((Object)(object)canvas)) { Object.Destroy((Object)(object)canvas); blockFrame = Time.frameCount; } canvas = null; chest = null; hovered = null; ResetFocus(); selected = null; fresh = null; pendingDelete = null; pendingToken = null; opened.Clear(); pulled.Clear(); known.Clear(); catalog.Clear(); groupCells.Clear(); chestCells.Clear(); rows.Clear(); searchRows.Clear(); searchCells.Clear(); chestNames.Clear(); legendOrder.Clear(); legendSlot.Clear(); if (editing) { ItemGroups.SetPrefixes(editPrefixes); ItemGroups.SetPostfixes(editPostfixes); } ruleSets.Clear(); ruleByKey.Clear(); ruleRows.Clear(); ruleCells.Clear(); rulesMode = false; shownRule = null; groupContent = null; ruleContent = null; composer = null; addingPrefix = false; addingPostfix = false; composerCommit = false; composerKeep = false; composerCancel = false; editing = false; renaming = null; } private static bool BackPressed() { polling = true; try { return ZInput.GetKeyDown((KeyCode)27, false) || ZInput.GetButtonDown("JoyButtonB"); } finally { polling = false; } } private static bool PadDown(string key) { polling = true; try { return ZInput.GetButtonDown(key); } finally { polling = false; } } private static void NoteOpened() { opened.Clear(); foreach (KeyValuePair<string, ISet<string>> group in groups) { opened[group.Key] = new HashSet<string>(group.Value); } } private static void Index(Inventory inventory) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) known.Clear(); catalog.Clear(); chestNames.Clear(); ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance != (Object)null && instance.m_items != null) { foreach (GameObject item in instance.m_items) { if (!Object.op_Implicit((Object)(object)item)) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); SharedData val = (((Object)(object)component != (Object)null && component.m_itemData != null) ? component.m_itemData.m_shared : null); if (val != null && StorableName(val.m_name)) { bool num = !known.ContainsKey(val.m_name.SCName()); ItemInfo itemInfo = Remember(val.m_name, val.m_description, val.m_icons, val.m_itemType); if (num && itemInfo != null && !val.m_questItem) { catalog.Add(itemInfo); } } } } foreach (ItemData item2 in inventory.m_inventory) { if (item2?.m_shared != null && StorableName(item2.m_shared.m_name)) { chestNames.Add(item2.m_shared.m_name.SCName()); Remember(item2.m_shared.m_name, item2.m_shared.m_description, item2.m_shared.m_icons, item2.m_shared.m_itemType); } } foreach (ISet<string> value in groups.Values) { foreach (string item3 in value) { if (!known.ContainsKey(item3)) { known[item3] = new ItemInfo { ScName = item3, Label = item3, Topic = item3 }; } } } catalog.Sort((ItemInfo a, ItemInfo b) => string.Compare(a.Label, b.Label, StringComparison.CurrentCultureIgnoreCase)); IndexRules(); } private static bool StorableName(string raw) { if (!string.IsNullOrEmpty(raw)) { if (!raw.StartsWith("$item_")) { return raw.StartsWith("$mod_"); } return true; } return false; } private static ItemInfo Remember(string raw, string description, Sprite[] icons, ItemType itemType) { //IL_0077: 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) if (!StorableName(raw)) { return null; } string text = raw.SCName(); if (known.TryGetValue(text, out var value)) { return value; } Sprite icon = null; if (icons != null && icons.Length != 0) { icon = icons[0]; } string label = ((Localization.instance != null) ? Localization.instance.Localize(raw) : raw); ItemInfo itemInfo = new ItemInfo { ScName = text, Label = label, Topic = raw, Description = (description ?? ""), Icon = icon, ItemType = itemType, HasType = true }; known[text] = itemInfo; return itemInfo; } private static void CaptureTooltip(InventoryGui gui) { tooltipPrefab = null; InventoryGrid playerGrid = gui.m_playerGrid; InventoryElement val = ((Object.op_Implicit((Object)(object)playerGrid) && Object.op_Implicit((Object)(object)playerGrid.m_elementPrefab)) ? playerGrid.m_elementPrefab.GetComponent<InventoryElement>() : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.m_tooltip)) { tooltipPrefab = val.m_tooltip.m_tooltipPrefab; } } private static string BestGroup() { string result = null; int num = 0; foreach (KeyValuePair<string, ISet<string>> group in groups) { int num2 = 0; foreach (string chestName in chestNames) { if (group.Value.Contains(chestName)) { num2++; } } if (num2 > num) { num = num2; result = group.Key; } } return result; } private static void Build(InventoryGui gui) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Expected O, but got Unknown //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_05fa: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0605: Expected O, but got Unknown //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0642: Unknown result type (might be due to invalid IL or missing references) //IL_0648: Expected O, but got Unknown //IL_071b: Unknown result type (might be due to invalid IL or missing references) //IL_076c: Unknown result type (might be due to invalid IL or missing references) //IL_07aa: Unknown result type (might be due to invalid IL or missing references) //IL_07af: Unknown result type (might be due to invalid IL or missing references) //IL_07b5: Expected O, but got Unknown //IL_07e5: Unknown result type (might be due to invalid IL or missing references) //IL_07ea: Unknown result type (might be due to invalid IL or missing references) //IL_07f0: Expected O, but got Unknown //IL_0869: Unknown result type (might be due to invalid IL or missing references) //IL_086e: Unknown result type (might be due to invalid IL or missing references) //IL_0874: Expected O, but got Unknown canvas = new GameObject("SmartContainersGroups", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Canvas component = canvas.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; Canvas componentInParent = ((Component)gui).GetComponentInParent<Canvas>(); component.sortingOrder = (Object.op_Implicit((Object)(object)componentInParent) ? (componentInParent.sortingOrder + 120) : 1020); CanvasScaler component2 = canvas.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.matchWidthOrHeight = 0.5f; GroupUi.Stretch(((Graphic)GroupUi.AddImage("Backdrop", canvas.transform, new Color(0f, 0f, 0f, 0.65f))).rectTransform); RectTransform rectTransform = ((Graphic)GroupUi.Panel(canvas.transform)).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0.5f); rectTransform.anchorMax = new Vector2(0.5f, 0.5f); rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = new Vector2(960f, 630f); object obj = <>c.<>9__80_0; if (obj == null) { UnityAction val = delegate { SetReference(on: false); }; <>c.<>9__80_0 = val; obj = (object)val; } groupsTab = GroupUi.Button((Transform)(object)rectTransform, "Groups", 20f, 14f, 118f, 30f, (UnityAction)obj); object obj2 = <>c.<>9__80_1; if (obj2 == null) { UnityAction val2 = delegate { SetReference(on: true); }; <>c.<>9__80_1 = val2; obj2 = (object)val2; } patternsTab = GroupUi.Button((Transform)(object)rectTransform, "Patterns", 144f, 14f, 118f, 30f, (UnityAction)obj2); BindTabGlyph(groupsTab); PaintTabs(); nameInput = GroupUi.Input((Transform)(object)rectTransform, "New group name", 20f, 50f, 168f, 32f, 48); object obj3 = <>O.<0>__CreateGroup; if (obj3 == null) { UnityAction val3 = CreateGroup; <>O.<0>__CreateGroup = val3; obj3 = (object)val3; } newButton = GroupUi.Button((Transform)(object)rectTransform, "New", 196f, 50f, 64f, 32f, (UnityAction)obj3); BindPadHint(newButton, "JoyMap"); searchInput = GroupUi.Input((Transform)(object)rectTransform, "Find an item to add", 276f, 50f, 664f, 32f, 40); ((UnityEvent<string>)(object)searchInput.onValueChanged).AddListener((UnityAction<string>)delegate { RefreshSearch(); }); ((UnityEvent<string>)(object)searchInput.onSelect).AddListener((UnityAction<string>)delegate(string text) { if (!string.IsNullOrEmpty(text.Trim())) { RefreshSearch(); } }); listScroll = Scroll((Transform)(object)rectTransform, "Groups", 20f, 94f, 240f, 468f, out groupContent); listScroll.scrollSensitivity = 500f; VerticalLayoutGroup obj4 = ((Component)groupContent).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj4).spacing = 4f; ((LayoutGroup)obj4).padding = new RectOffset(4, 4, 4, 4); ((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false; ((Component)groupContent).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; RebuildRows(groupContent); ruleContent = GroupUi.Rect("Rules", ((Component)listScroll).transform, 0f, 0f, 0f, 0f); ruleContent.anchorMin = new Vector2(0f, 1f); ruleContent.anchorMax = new Vector2(1f, 1f); ruleContent.pivot = new Vector2(0.5f, 1f); ruleContent.anchoredPosition = Vector2.zero; ruleContent.sizeDelta = Vector2.zero; VerticalLayoutGroup obj5 = ((Component)ruleContent).gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj5).spacing = 4f; ((LayoutGroup)obj5).padding = new RectOffset(4, 4, 4, 4); ((HorizontalOrVerticalLayoutGroup)obj5).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj5).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj5).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj5).childForceExpandHeight = false; ((Component)ruleContent).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; BuildRuleRows(); ((Component)ruleContent).gameObject.SetActive(false); info = (TMP_Text)(object)GroupUi.Text((Transform)(object)rectTransform, "", 276f, 88f, 664f, 22f, 16f); ((Graphic)info).color = Color.white; info.richText = true; info.overflowMode = (TextOverflowModes)0; itemScroll = Scroll((Transform)(object)rectTransform, "Items", 276f, 110f, 664f, 208f, out var content); SetupGrid(content); foreach (ItemInfo item in GroupSeed()) { groupCells.Add(MakeCell(content, item, CellRole.Group)); } chestTitle = (TMP_Text)(object)GroupUi.Text((Transform)(object)rectTransform, "This chest", 276f, 342f, 90f, 20f, 15f); chestLegend = GroupUi.Rect("ChestLegend", (Transform)(object)rectTransform, 370f, 342f, 566f, 20f); HorizontalLayoutGroup obj6 = ((Component)chestLegend).gameObject.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj6).spacing = 10f; ((LayoutGroup)obj6).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj6).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj6).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj6).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj6).childForceExpandHeight = false; object obj7 = <>c.<>9__80_4; if (obj7 == null) { UnityAction val4 = delegate { AddChest(ungroupedOnly: false); }; <>c.<>9__80_4 = val4; obj7 = (object)val4; } addAllButton = GroupUi.Button((Transform)(object)rectTransform, "Add all", 276f, 370f, 128f, 28f, (UnityAction)obj7); object obj8 = <>c.<>9__80_5; if (obj8 == null) { UnityAction val5 = delegate { AddChest(ungroupedOnly: true); }; <>c.<>9__80_5 = val5; obj8 = (object)val5; } addLooseButton = GroupUi.Button((Transform)(object)rectTransform, "Add ungrouped", 412f, 370f, 168f, 28f, (UnityAction)obj8); BindPadHint(addAllButton, "JoyLStick"); BindPadHint(addLooseButton, "JoyRStick"); chestScroll = Scroll((Transform)(object)rectTransform, "Chest", 276f, 406f, 664f, 136f, out var content2); SetupGrid(content2); foreach (ItemInfo item2 in ChestItems()) { chestCells.Add(MakeCell(content2, item2, CellRole.Chest)); } RectTransform obj9 = GroupUi.Rect("SearchOverlay", (Transform)(object)rectTransform, 276f, 86f, 664f, 232f); ((Graphic)((Component)obj9).gameObject.AddComponent<Image>()).color = new Color(0.12f, 0.08f, 0.05f, 0.98f); searchScroll = Scroll((Transform)(object)obj9, "SearchHits", 0f, 0f, 664f, 192f, out searchContent); ((Graphic)((Component)searchScroll).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0f); SetupGrid(searchContent); object obj10 = <>O.<1>__AddAllSearch; if (obj10 == null) { UnityAction val6 = AddAllSearch; <>O.<1>__AddAllSearch = val6; obj10 = (object)val6; } GroupUi.Button((Transform)(object)obj9, "ADD ALL", 8f, 196f, 150f, 32f, (UnityAction)obj10); object obj11 = <>O.<2>__CloseSearch; if (obj11 == null) { UnityAction val7 = CloseSearch; <>O.<2>__CloseSearch = val7; obj11 = (object)val7; } GroupUi.Button((Transform)(object)obj9, "CLOSE", 506f, 196f, 150f, 32f, (UnityAction)obj11); searchPopup = ((Component)obj9).gameObject; searchPopup.SetActive(false); status = (TMP_Text)(object)GroupUi.Text((Transform)(object)rectTransform, "", 276f, 542f, 530f, 40f, 17f); status.overflowMode = (TextOverflowModes)0; object obj12 = <>O.<3>__Close; if (obj12 == null) { UnityAction val8 = Close; <>O.<3>__Close = val8; obj12 = (object)val8; } GroupUi.Button((Transform)(object)rectTransform, "Close", 820f, 580f, 120f, 34f, (UnityAction)obj12); } private static void BindTabGlyph(Button button) { //IL_0049: 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_0073: 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_009c: Unknown result type (might be due to invalid IL or missing references) BindPadHint(button, "JoyMenu"); UIGamePad val = (Object.op_Implicit((Object)(object)button) ? ((Component)button).GetComponent<UIGamePad>() : null); GameObject val2 = (Object.op_Implicit((Object)(object)val) ? val.m_hint : null); if (Object.op_Implicit((Object)(object)val2)) { RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 0.5f); component.anchorMax = new Vector2(1f, 0.5f); component.pivot = new Vector2(1f, 0.5f); component.sizeDelta = new Vector2(26f, 26f); component.anchoredPosition = new Vector2(11f, 0f); TextMeshProUGUI component2 = val2.GetComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)component2)) { ((TMP_Text)component2).alignment = (TextAlignmentOptions)4100; ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).fontSize = 15f; ((TMP_Text)component2).overflowMode = (TextOverflowModes)0; ((Graphic)component2).raycastTarget = false; } } } private static void BindPadHint(Button button, string key) { if (Object.op_Implicit((Object)(object)button) && ZInput.instance != null) { ((Component)button).gameObject.AddComponent<UIGamePad>(); GuiFactory.InitJoyKey(((Component)button).transform, key, ZInput.instance.GetBoundKeyString(key, false)); ((Component)button).GetComponent<UIGamePad>().m_zinputKey = null; } } private static void BindDeleteHint(Button button) { BindPadHint(button, "JoyButtonX"); UIGamePad component = ((Component)button).GetComponent<UIGamePad>(); if (!Object.op_Implicit((Object)(object)component)) { return; } ((Behaviour)component).enabled = false; GameObject hint = component.m_hint; if (Object.op_Implicit((Object)(object)hint)) { TextMeshProUGUI component2 = hint.GetComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)component2)) { ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).fontSize = 13f; ((TMP_Text)component2).overflowMode = (TextOverflowModes)0; ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; } } } private static ScrollRect Scroll(Transform parent, string name, float x, float y, float width, float height, out RectTransform content) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) RectTransform val = GroupUi.Rect(name, parent, x, y, width, height); ((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.35f); ((Component)val).gameObject.AddComponent<RectMask2D>(); content = GroupUi.Rect("Content", (Transform)(object)val, 0f, 0f, 0f, 0f); content.anchorMin = new Vector2(0f, 1f); content.anchorMax = new Vector2(1f, 1f); content.pivot = new Vector2(0.5f, 1f); content.anchoredPosition = Vector2.zero; content.sizeDelta = Vector2.zero; ScrollRect obj = ((Component)val).gameObject.AddComponent<ScrollRect>(); obj.horizontal = false; obj.vertical = true; obj.movementType = (MovementType)2; obj.inertia = false; obj.scrollSensitivity = 500f; obj.viewport = val; obj.content = content; return obj; } private static void SetupGrid(RectTransform content) { //IL_0016: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown GridLayoutGroup obj = ((Component)content).gameObject.AddComponent<GridLayoutGroup>(); obj.cellSize = new Vector2(CellEdge, CellEdge); obj.spacing = new Vector2(4f, 4f); ((LayoutGroup)obj).padding = new RectOffset(4, 4, 4, 4); obj.constraint = (Constraint)1; obj.constraintCount = 10; ((LayoutGroup)obj).childAlignment = (TextAnchor)0; ((Component)content).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; } private static IEnumerable<ItemInfo> GroupSeed() { HashSet<string> hashSet = new HashSet<string>(chestNames); foreach (ISet<string> value2 in groups.Values) { hashSet.UnionWith(value2); } ItemInfo value; return (from sc in hashSet select (!known.TryGetValue(sc, out value)) ? null : value into info where info != null select info).OrderBy<ItemInfo, string>((ItemInfo info) => info.Label, StringComparer.CurrentCultureIgnoreCase); } private static IEnumerable<ItemInfo> ChestItems() { ItemInfo value; return (from sc in chestNames select (!known.TryGetValue(sc, out value)) ? null : value into info where info != null select info).OrderBy<ItemInfo, string>((ItemInfo info) => info.Label, StringComparer.CurrentCultureIgnoreCase); } private static void RebuildRows(RectTransform content) { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Expected O, but got Unknown hotRow = null; foreach (Row row2 in rows) { if (Object.op_Implicit((Object)(object)row2.Background)) { Object.Destroy((Object)(object)((Component)row2.Background).gameObject); } } rows.Clear(); foreach (string item in (from key in groups.Keys orderby (!(key == fresh)) ? 1 : 0, (!HitsChest(key)) ? 1 : 0, Mod.isSystemGroup(key) ? 1 : 0 select key).ThenBy<string, string>((string key) => key, StringComparer.OrdinalIgnoreCase)) { string groupId = item; Button val = GroupUi.Button((Transform)(object)content, groupId, 0f, 0f, 220f, 28f, (UnityAction)delegate { Select(groupId, resetItems: true); }); LayoutElement obj = ((Component)val).gameObject.AddComponent<LayoutElement>(); obj.preferredHeight = 28f; obj.minHeight = 28f; bool flag = !Mod.isSystemGroup(groupId); TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(); ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097; ((TMP_Text)componentInChildren).rectTransform.anchoredPosition = new Vector2(16f, 0f); ((TMP_Text)componentInChildren).rectTransform.sizeDelta = new Vector2(flag ? 160f : 196f, 28f); Image val2 = GroupUi.AddImage("Mark", ((Component)val).tr