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 ChestSorter v1.0.0
ChestSorter.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using ValheimShared; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [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 ValheimShared { internal static class Perf { internal readonly struct Scope : IDisposable { private readonly string _name; private readonly long _start; internal Scope(string name) { _name = name; _start = Stopwatch.GetTimestamp(); } public void Dispose() { Add(_name, (double)(Stopwatch.GetTimestamp() - _start) * 1000.0 / (double)Stopwatch.Frequency); } } private static readonly Dictionary<string, (double ms, int calls)> _current = new Dictionary<string, (double, int)>(); private static readonly List<string> _marks = new List<string>(); private static int _frame = -1; private static Dictionary<string, (double ms, int calls)> _previous = new Dictionary<string, (double, int)>(); private static List<string> _previousMarks = new List<string>(); private static int _gcCount; internal static bool Enabled = true; internal static void BeginFrame(Action<string> log, float thresholdMs) { Rotate(); int num = GC.CollectionCount(0); int num2 = num - _gcCount; _gcCount = num; if (!Enabled) { return; } float num3 = Time.unscaledDeltaTime * 1000f; if (!(num3 < thresholdMs) && Time.frameCount >= 2) { double num4 = _previous.Values.Sum(((double ms, int calls) v) => v.ms); string text = ((_previous.Count == 0) ? "none" : string.Join(", ", from kv in _previous orderby kv.Value.ms descending select $"{kv.Key} {kv.Value.ms:F1}ms" + ((kv.Value.calls > 1) ? $" x{kv.Value.calls}" : ""))); string text2 = ((_previousMarks.Count == 0) ? "" : (" | events: " + string.Join(", ", _previousMarks))); string text3 = ((num2 > 0) ? $" | GC ran {num2}x (heap {GC.GetTotalMemory(forceFullCollection: false) / 1048576} MB)" : ""); log($"[perf] slow frame {num3:F0}ms (frame {Time.frameCount - 1}), this plugin {num4:F1}ms: {text}{text2}{text3}"); } } internal static void Mark(string evt) { Rotate(); if (Enabled) { _marks.Add(evt); } } internal static Scope Measure(string name) { return new Scope(name); } internal static void Add(string name, double ms) { Rotate(); if (Enabled) { _current.TryGetValue(name, out (double, int) value); _current[name] = (value.Item1 + ms, value.Item2 + 1); } } private static void Rotate() { if (_frame != Time.frameCount) { _frame = Time.frameCount; _previous = new Dictionary<string, (double, int)>(_current); _previousMarks = new List<string>(_marks); _current.Clear(); _marks.Clear(); } } } internal static class UiClone { internal static Button Button(Button template, Transform parent, string name, string label, UnityAction onClick) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)obj).name = name; StripVanillaBehaviour(obj); SetLabel(obj, label); Button component = obj.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); if (onClick != null) { ((UnityEvent)component.onClick).AddListener(onClick); } ((Selectable)component).interactable = true; IgnoreLayout(obj); return component; } internal static TMP_Text Text(TMP_Text template, Transform parent, string name, string text) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = name; StripVanillaBehaviour(val); foreach (Transform item in val.transform) { Object.Destroy((Object)(object)((Component)item).gameObject); } TMP_Text component = val.GetComponent<TMP_Text>(); component.text = text; IgnoreLayout(val); return component; } internal static void SetLabel(GameObject go, string label) { TMP_Text componentInChildren = go.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = label; return; } Text componentInChildren2 = go.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = label; } } internal static TMP_Text LabelOf(GameObject go) { return go.GetComponentInChildren<TMP_Text>(true); } internal static void Place(RectTransform rt, float x, float y, float w, float h) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rt.anchorMax = val; rt.anchorMin = val; rt.pivot = new Vector2(0f, 1f); rt.anchoredPosition = new Vector2(x, 0f - y); rt.sizeDelta = new Vector2(w, h); } internal static void IgnoreLayout(GameObject go) { LayoutElement val = go.GetComponent<LayoutElement>(); if ((Object)(object)val == (Object)null) { val = go.AddComponent<LayoutElement>(); } val.ignoreLayout = true; } internal static void CopyBackground(RectTransform source, Image target) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Image val = (((Object)(object)source == (Object)null) ? null : (from i in ((Component)source).GetComponentsInChildren<Image>(true) where (Object)(object)i.sprite != (Object)null && (Object)(object)i != (Object)(object)target select i).OrderByDescending(delegate(Image i) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Rect rect = ((Graphic)i).rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = ((Graphic)i).rectTransform.rect; return width * ((Rect)(ref rect)).height; }).FirstOrDefault()); if ((Object)(object)val == (Object)null) { ((Graphic)target).color = new Color(0.12f, 0.1f, 0.08f, 0.95f); return; } target.sprite = val.sprite; target.type = val.type; ((Graphic)target).material = ((Graphic)val).material; ((Graphic)target).color = ((Graphic)val).color; target.pixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier; } internal static RectTransform ScrollArea(Transform parent, string name, float x, float y, float w, float h, Scrollbar scrollbarTemplate, out ScrollRect scroll) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0067: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00ad: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(parent, false); Place(val2, x, y, w - 14f - 4f, h); val.AddComponent<RectMask2D>(); ((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f); GameObject val3 = new GameObject("Content", new Type[1] { typeof(RectTransform) }); RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).SetParent((Transform)(object)val2, false); val4.anchorMin = new Vector2(0f, 1f); val4.anchorMax = new Vector2(1f, 1f); val4.pivot = new Vector2(0.5f, 1f); val4.anchoredPosition = Vector2.zero; val4.sizeDelta = Vector2.zero; VerticalLayoutGroup obj = val3.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; val3.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; scroll = val.AddComponent<ScrollRect>(); scroll.content = val4; scroll.viewport = val2; scroll.horizontal = false; scroll.vertical = true; scroll.movementType = (MovementType)2; scroll.inertia = false; scroll.scrollSensitivity = 30f; if ((Object)(object)scrollbarTemplate != (Object)null) { GameObject obj2 = Object.Instantiate<GameObject>(((Component)scrollbarTemplate).gameObject, parent, false); ((Object)obj2).name = name + "_Scrollbar"; IgnoreLayout(obj2); Place((RectTransform)obj2.transform, x + w - 14f, y, 14f, h); Scrollbar component = obj2.GetComponent<Scrollbar>(); component.onValueChanged = new ScrollEvent(); component.direction = (Direction)2; scroll.verticalScrollbar = component; scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0; } return val4; } private static void StripVanillaBehaviour(GameObject go) { Localize[] componentsInChildren = go.GetComponentsInChildren<Localize>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } UIGamePad[] componentsInChildren2 = go.GetComponentsInChildren<UIGamePad>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } } } } namespace ChestSorter { internal static class CategoryConfig { private static string _path; private static DateTime _loadedStampUtc; internal static CategoryRules Rules { get; private set; } internal static void Init(string configDir) { _path = Path.Combine(configDir, "ChestSorter.categories.txt"); try { if (!File.Exists(_path)) { File.WriteAllText(_path, "# ChestSorter category rules. Edit freely - the file is re-read automatically\n# the next time you press Push after saving it.\n#\n# Line formats (fields separated by |):\n# version | <n>\n# category | <id> | <display name> id is what gets stored on chests - never rename an id,\n# add an alias line instead\n# alias | <old id> | <new id> chests tagged with <old id> are treated as <new id>\n# itemtype | <ItemType> | <category id> fallback for an item type when no rule below matches\n# override | <scope> | <prefab> | <id> exact prefab (internal) name\n# prefix | <scope> | <text> | <id> prefab name starts with text\n# endswith | <scope> | <text> | <id> prefab name ends with text\n# contains | <scope> | <text> | <id> prefab name contains text\n# suffix | <scope> | <word> | <id> LAST PascalCase word of the prefab name equals word\n# foodcolor | <color> | <id> food by its icon colour in the game: Health (red),\n# Stamina (yellow), Eitr (blue), Balanced (white)\n# parent | <id> | <parent id> a chest tagged with the parent also takes this category;\n# Push prefers exact-category chests and uses parent-tagged\n# ones as overflow\n# <scope> is an item type (Material, Consumable, Misc, ...) or * for any.\n# Matching order: override, prefix, endswith, contains, suffix, foodcolor, itemtype.\n# Unmatched Material items land in Misc; unmatched items of other types use their item type name.\n\nversion | 4\n\ncategory | Trophy | Trophies\ncategory | Ammo | Ammo\ncategory | SiegeAmmo | Siege Ammo\ncategory | Chest | Armor: Chest\ncategory | Helmet | Armor: Helmets\ncategory | Legs | Armor: Legs\ncategory | Shoulder | Capes\ncategory | Shield | Shields\ncategory | OneHandedWeapon | One-Handed Weapons\ncategory | TwoHandedWeapon | Two-Handed Weapons\ncategory | TwoHandedWeaponLeft | Two-Handed (Left Hand)\ncategory | Bow | Bows & Crossbows\ncategory | Tool | Tools\ncategory | Utility | Utility\ncategory | Torch | Torches & Lanterns\ncategory | Trinket | Trinkets\ncategory | Fish | Fish\ncategory | Food | Food (all kinds)\ncategory | Produce | Food: Produce\ncategory | RawMeat | Food: Raw Meat\ncategory | CookingIngredients | Food: Cooking Ingredients\ncategory | CookedMeat | Food: Cooked Meat\ncategory | MealsHealth | Food: Meals (Health)\ncategory | MealsStamina | Food: Meals (Stamina)\ncategory | MealsEitr | Food: Meals (Eitr)\ncategory | MealsBalanced | Food: Meals (Balanced)\ncategory | Feasts | Food: Feasts\ncategory | Potions | Meads & Potions\ncategory | Customization | Cosmetics\ncategory | HidesAndFur | Hides & Fur\ncategory | BonesAndSkeleton | Bones\ncategory | Organs | Organs\ncategory | OresAndMetals | Ores & Metals\ncategory | BuildingStone | Building Stone\ncategory | Minerals | Minerals\ncategory | Wood | Wood\ncategory | PlantsAndSeeds | Plants & Seeds\ncategory | Textiles | Textiles\ncategory | Feathers | Feathers\ncategory | ResinAndTar | Resin & Tar\ncategory | ChitinAndScales | Chitin & Scales\ncategory | RareCores | Cores & Essences\ncategory | Valuables | Valuables\ncategory | QuestAndBoss | Quest & Boss Items\ncategory | Taming | Taming & Saddles\ncategory | CraftingParts | Crafting Parts\ncategory | MeadBases | Mead Bases\ncategory | UpgradeIdols | Upgrade Idols\ncategory | Spices | Spices\ncategory | Fireworks | Fireworks\ncategory | CastsAndMoulds | Casts & Moulds\ncategory | Misc | Misc\n\n# Old ids from earlier builds.\nalias | StoneAndGems | BuildingStone\nalias | Currency | Valuables\nalias | RawDishes | CookingIngredients\nalias | Consumable | Food\nalias | AmmoNonEquipable | SiegeAmmo\nalias | FeastIngredients | Feasts\n\n# --- Food family: a chest tagged \"Food\" takes all of these.\nparent | Produce | Food\nparent | RawMeat | Food\nparent | CookingIngredients | Food\nparent | CookedMeat | Food\nparent | MealsHealth | Food\nparent | MealsStamina | Food\nparent | MealsEitr | Food\nparent | MealsBalanced | Food\nparent | Feasts | Food\n\n# Prepared food not matched by a name rule below, by its icon colour.\nfoodcolor | Health | MealsHealth\nfoodcolor | Stamina | MealsStamina\nfoodcolor | Eitr | MealsEitr\nfoodcolor | Balanced | MealsBalanced\n\nitemtype | Consumable | Food\nitemtype | AmmoNonEquipable | SiegeAmmo\nitemtype | Material | Misc\nitemtype | Misc | Misc\n\n# --- Exact exceptions: merged-lowercase names the suffix rule can't split\n# (Leatherstraps, Bloodbag...), modifiers after the material word\n# (FlametalNew, OrbFrostFire...), and deliberate regroupings.\noverride | * | BoneFragments | BonesAndSkeleton\noverride | * | Charredskull | BonesAndSkeleton\noverride | * | NeckTail | BonesAndSkeleton\noverride | * | BonemawSerpentScale | ChitinAndScales\noverride | * | Leatherstraps | HidesAndFur\noverride | * | ElakingHairBundle | HidesAndFur\noverride | * | WolfHairBundle | HidesAndFur\noverride | * | Bilebag | Organs\noverride | * | Bloodbag | Organs\noverride | * | Softtissue | Organs\noverride | * | CuredSquirrelHamstring | Organs\noverride | * | Ironpit | OresAndMetals\noverride | * | CharredCogwheel | OresAndMetals\noverride | * | FlametalNew | OresAndMetals\noverride | * | FlametalOreNew | OresAndMetals\noverride | * | Grausten | BuildingStone\noverride | * | PungentPebbles | BuildingStone\noverride | * | Thunderstone | Minerals\noverride | * | SulfurStone | Minerals\noverride | * | SharpeningStone | CraftingParts\noverride | * | CandleWick | CraftingParts\noverride | * | Hook | CraftingParts\noverride | * | BarrelRings | CraftingParts\noverride | * | ScytheHandle | CraftingParts\noverride | * | Blackwood | Wood\noverride | * | Frostwood | Wood\noverride | * | FirConeFrost | PlantsAndSeeds\noverride | * | FragrantBundle | PlantsAndSeeds\noverride | * | Feathers | Feathers\noverride | * | CelestialFeather | Feathers\noverride | * | BreadDough | CookingIngredients\noverride | * | BarleyFlour | CookingIngredients\noverride | * | OatFlour | CookingIngredients\noverride | * | ChickenEgg | Produce\n# Edible as-is, but really crops, forage and cooking ingredients.\noverride | Consumable | Blueberries | Produce\noverride | Consumable | Raspberry | Produce\noverride | Consumable | Cloudberry | Produce\noverride | Consumable | Lingonberry | Produce\noverride | Consumable | Vineberry | Produce\noverride | Consumable | Pukeberries | Produce\noverride | Consumable | Carrot | Produce\noverride | Consumable | Onion | Produce\noverride | Consumable | Kale | Produce\noverride | Consumable | Oat | Produce\noverride | Consumable | Poteitr | Produce\noverride | Consumable | Honey | Produce\noverride | Consumable | RoyalJelly | Produce\noverride | Consumable | Fiddleheadfern | Produce\noverride | Consumable | GlowWorm | Produce\noverride | Consumable | Mushroom | Produce\noverride | Consumable | MushroomBlue | Produce\noverride | Consumable | MushroomBzerker | Produce\noverride | Consumable | MushroomJotunPuffs | Produce\noverride | Consumable | MushroomMagecap | Produce\noverride | Consumable | MushroomSmokePuff | Produce\noverride | Consumable | MushroomYellow | Produce\noverride | Consumable | NeckTailGrilled | CookedMeat\noverride | Consumable | RottenMeat | RawMeat\noverride | * | BarleyWineBase | MeadBases\noverride | * | BarleyWine | Potions\noverride | * | OozeMork | ResinAndTar\noverride | * | ShieldCore | RareCores\noverride | * | DvergrNeedle | RareCores\noverride | * | BlobVial | RareCores\noverride | * | Ectoplasm | RareCores\noverride | * | Voidplasm | RareCores\noverride | * | Wisp | RareCores\noverride | * | FaderEmber | RareCores\noverride | * | OrbFrostFire | RareCores\noverride | * | OrbThunderBlood | RareCores\noverride | * | PowderedDragonEgg | RareCores\noverride | * | HardAntler | QuestAndBoss\noverride | * | QueenDrop | QuestAndBoss\noverride | * | FaderDrop | QuestAndBoss\noverride | * | FrozenKingDrop | QuestAndBoss\noverride | * | DragonTear | QuestAndBoss\noverride | * | YagluthDrop | QuestAndBoss\noverride | * | DragonEgg | QuestAndBoss\noverride | * | AxeHead1 | QuestAndBoss\noverride | * | AxeHead2 | QuestAndBoss\noverride | * | Pot_Shard_Green | QuestAndBoss\noverride | * | Pot_Shard_Red | QuestAndBoss\noverride | * | CryptKey | QuestAndBoss\noverride | * | DvergrKey | QuestAndBoss\noverride | * | BloodGoldKey | QuestAndBoss\noverride | * | HildirKey_forestcrypt | QuestAndBoss\noverride | * | HildirKey_mountaincave | QuestAndBoss\noverride | * | HildirKey_plainsfortress | QuestAndBoss\noverride | * | chest_hildir1 | QuestAndBoss\noverride | * | chest_hildir2 | QuestAndBoss\noverride | * | chest_hildir3 | QuestAndBoss\noverride | * | GoblinTotem | QuestAndBoss\noverride | * | HatefulBlood | QuestAndBoss\noverride | * | Bell | QuestAndBoss\noverride | * | AncientSeed | QuestAndBoss\noverride | * | AsksvinEgg | Taming\noverride | * | VoltureEgg | Taming\noverride | * | SaddleLox | Taming\noverride | * | SaddleAsksvin | Taming\noverride | * | SaddleMoose | Taming\noverride | * | BombSiege | SiegeAmmo\noverride | * | Catapult_ammo | SiegeAmmo\noverride | * | Catapult_Ammo_BloodGold | SiegeAmmo\n\n# --- Name families where the type word is at the front.\nprefix | Material | MeadBase | MeadBases\nprefix | Material | Upgrader | UpgradeIdols\nprefix | Material | Spice | Spices\nprefix | Material | FireworksRocket_ | Fireworks\nprefix | Material | Mold | CastsAndMoulds\nprefix | Material | AncientGemstone | Valuables\nprefix | Material | Gemstone | Valuables\nprefix | Material | Jute | Textiles\nprefix | Material | Feast | Feasts\nprefix | Consumable | Feast | Feasts\nprefix | Consumable | Mead | Potions\nprefix | Consumable | Cooked | CookedMeat\n# \"Cast: ...\" armor and staff moulds are named *Uncooked like food - must win over the Uncooked rule.\nprefix | Material | ArmorGold | CastsAndMoulds\nprefix | Material | Staff | CastsAndMoulds\n\n# \"Cast: ...\" items are named *GoldUncooked - must win over the generic Uncooked rule below.\nendswith | Material | GoldUncooked | CastsAndMoulds\nendswith | Material | MoldUncooked | CastsAndMoulds\nendswith | Consumable | Cooked | CookedMeat\ncontains | Material | Uncooked | CookingIngredients\n\n# --- Last-word rules for Material items.\nsuffix | Material | Hide | HidesAndFur\nsuffix | Material | Pelt | HidesAndFur\nsuffix | Material | Leather | HidesAndFur\nsuffix | Material | Straps | HidesAndFur\nsuffix | Material | Scraps | HidesAndFur\nsuffix | Material | Meat | RawMeat\nsuffix | Material | Blubber | RawMeat\nsuffix | Material | Raw | RawMeat\nsuffix | Material | Bone | BonesAndSkeleton\nsuffix | Material | Bones | BonesAndSkeleton\nsuffix | Material | Skull | BonesAndSkeleton\nsuffix | Material | Ribcage | BonesAndSkeleton\nsuffix | Material | Pelvic | BonesAndSkeleton\nsuffix | Material | Neck | BonesAndSkeleton\nsuffix | Material | Tooth | BonesAndSkeleton\nsuffix | Material | Fang | BonesAndSkeleton\nsuffix | Material | Claw | BonesAndSkeleton\nsuffix | Material | Claws | BonesAndSkeleton\nsuffix | Material | Paw | BonesAndSkeleton\nsuffix | Material | Antler | BonesAndSkeleton\nsuffix | Material | Mandible | BonesAndSkeleton\nsuffix | Material | Bladder | Organs\nsuffix | Material | Bag | Organs\nsuffix | Material | Entrails | Organs\nsuffix | Material | Sinew | Organs\nsuffix | Material | Heart | Organs\nsuffix | Material | Tissue | Organs\nsuffix | Material | Sack | Organs\nsuffix | Material | Eye | Organs\nsuffix | Material | Gland | Organs\nsuffix | Material | Ore | OresAndMetals\nsuffix | Material | Scrap | OresAndMetals\nsuffix | Material | Nails | OresAndMetals\nsuffix | Material | Copper | OresAndMetals\nsuffix | Material | Bronze | OresAndMetals\nsuffix | Material | Iron | OresAndMetals\nsuffix | Material | Silver | OresAndMetals\nsuffix | Material | Tin | OresAndMetals\nsuffix | Material | Gold | OresAndMetals\nsuffix | Material | Flametal | OresAndMetals\nsuffix | Material | Metal | OresAndMetals\nsuffix | Material | Chain | OresAndMetals\nsuffix | Material | Spring | OresAndMetals\nsuffix | Material | Stone | BuildingStone\nsuffix | Material | Rock | BuildingStone\nsuffix | Material | Marble | BuildingStone\nsuffix | Material | Flint | Minerals\nsuffix | Material | Crystal | Minerals\nsuffix | Material | Coal | Minerals\nsuffix | Material | Obsidian | Minerals\nsuffix | Material | Powder | Minerals\nsuffix | Material | Plate | CraftingParts\nsuffix | Material | Wood | Wood\nsuffix | Material | Log | Wood\nsuffix | Material | Bark | Wood\nsuffix | Material | Branch | Wood\nsuffix | Material | Seeds | PlantsAndSeeds\nsuffix | Material | Flax | PlantsAndSeeds\nsuffix | Material | Barley | Produce\nsuffix | Material | Dandelion | PlantsAndSeeds\nsuffix | Material | Thistle | PlantsAndSeeds\nsuffix | Material | Acorn | PlantsAndSeeds\nsuffix | Material | Acorns | PlantsAndSeeds\nsuffix | Material | Cone | PlantsAndSeeds\nsuffix | Material | Root | PlantsAndSeeds\nsuffix | Material | Roots | PlantsAndSeeds\nsuffix | Material | Turnip | Produce\nsuffix | Material | Seaweed | PlantsAndSeeds\nsuffix | Material | Thread | Textiles\nsuffix | Material | Resin | ResinAndTar\nsuffix | Material | Sap | ResinAndTar\nsuffix | Material | Tar | ResinAndTar\nsuffix | Material | Ooze | ResinAndTar\nsuffix | Material | Pulp | ResinAndTar\nsuffix | Material | Guck | ResinAndTar\nsuffix | Material | Ice | ResinAndTar\nsuffix | Material | Fuel | ResinAndTar\nsuffix | Material | Carapace | ChitinAndScales\nsuffix | Material | Chitin | ChitinAndScales\nsuffix | Material | Scale | ChitinAndScales\nsuffix | Material | Needle | ChitinAndScales\nsuffix | Material | Bee | Taming\nsuffix | Material | Core | RareCores\nsuffix | Material | Eitr | RareCores\nsuffix | Material | Remains | RareCores\nsuffix | Material | Orb | RareCores\nsuffix | Material | Fragment | QuestAndBoss\nsuffix | Material | Coin | Valuables\nsuffix | Material | Coins | Valuables\nsuffix | Material | Necklace | Valuables\nsuffix | Material | Amber | Valuables\nsuffix | Material | Pearl | Valuables\nsuffix | Material | Pearls | Valuables\nsuffix | Material | Ruby | Valuables\nsuffix | Material | Jewel | Valuables\n"); ChestSorterPlugin.WriteLog("Wrote default category rules to " + _path + "."); } else { CategoryRules categoryRules = CategoryRules.Parse(File.ReadAllText(_path), new List<string>()); if (categoryRules.Version < 4) { string text = _path + $".v{categoryRules.Version}.bak"; File.Copy(_path, text, overwrite: true); File.WriteAllText(_path, "# ChestSorter category rules. Edit freely - the file is re-read automatically\n# the next time you press Push after saving it.\n#\n# Line formats (fields separated by |):\n# version | <n>\n# category | <id> | <display name> id is what gets stored on chests - never rename an id,\n# add an alias line instead\n# alias | <old id> | <new id> chests tagged with <old id> are treated as <new id>\n# itemtype | <ItemType> | <category id> fallback for an item type when no rule below matches\n# override | <scope> | <prefab> | <id> exact prefab (internal) name\n# prefix | <scope> | <text> | <id> prefab name starts with text\n# endswith | <scope> | <text> | <id> prefab name ends with text\n# contains | <scope> | <text> | <id> prefab name contains text\n# suffix | <scope> | <word> | <id> LAST PascalCase word of the prefab name equals word\n# foodcolor | <color> | <id> food by its icon colour in the game: Health (red),\n# Stamina (yellow), Eitr (blue), Balanced (white)\n# parent | <id> | <parent id> a chest tagged with the parent also takes this category;\n# Push prefers exact-category chests and uses parent-tagged\n# ones as overflow\n# <scope> is an item type (Material, Consumable, Misc, ...) or * for any.\n# Matching order: override, prefix, endswith, contains, suffix, foodcolor, itemtype.\n# Unmatched Material items land in Misc; unmatched items of other types use their item type name.\n\nversion | 4\n\ncategory | Trophy | Trophies\ncategory | Ammo | Ammo\ncategory | SiegeAmmo | Siege Ammo\ncategory | Chest | Armor: Chest\ncategory | Helmet | Armor: Helmets\ncategory | Legs | Armor: Legs\ncategory | Shoulder | Capes\ncategory | Shield | Shields\ncategory | OneHandedWeapon | One-Handed Weapons\ncategory | TwoHandedWeapon | Two-Handed Weapons\ncategory | TwoHandedWeaponLeft | Two-Handed (Left Hand)\ncategory | Bow | Bows & Crossbows\ncategory | Tool | Tools\ncategory | Utility | Utility\ncategory | Torch | Torches & Lanterns\ncategory | Trinket | Trinkets\ncategory | Fish | Fish\ncategory | Food | Food (all kinds)\ncategory | Produce | Food: Produce\ncategory | RawMeat | Food: Raw Meat\ncategory | CookingIngredients | Food: Cooking Ingredients\ncategory | CookedMeat | Food: Cooked Meat\ncategory | MealsHealth | Food: Meals (Health)\ncategory | MealsStamina | Food: Meals (Stamina)\ncategory | MealsEitr | Food: Meals (Eitr)\ncategory | MealsBalanced | Food: Meals (Balanced)\ncategory | Feasts | Food: Feasts\ncategory | Potions | Meads & Potions\ncategory | Customization | Cosmetics\ncategory | HidesAndFur | Hides & Fur\ncategory | BonesAndSkeleton | Bones\ncategory | Organs | Organs\ncategory | OresAndMetals | Ores & Metals\ncategory | BuildingStone | Building Stone\ncategory | Minerals | Minerals\ncategory | Wood | Wood\ncategory | PlantsAndSeeds | Plants & Seeds\ncategory | Textiles | Textiles\ncategory | Feathers | Feathers\ncategory | ResinAndTar | Resin & Tar\ncategory | ChitinAndScales | Chitin & Scales\ncategory | RareCores | Cores & Essences\ncategory | Valuables | Valuables\ncategory | QuestAndBoss | Quest & Boss Items\ncategory | Taming | Taming & Saddles\ncategory | CraftingParts | Crafting Parts\ncategory | MeadBases | Mead Bases\ncategory | UpgradeIdols | Upgrade Idols\ncategory | Spices | Spices\ncategory | Fireworks | Fireworks\ncategory | CastsAndMoulds | Casts & Moulds\ncategory | Misc | Misc\n\n# Old ids from earlier builds.\nalias | StoneAndGems | BuildingStone\nalias | Currency | Valuables\nalias | RawDishes | CookingIngredients\nalias | Consumable | Food\nalias | AmmoNonEquipable | SiegeAmmo\nalias | FeastIngredients | Feasts\n\n# --- Food family: a chest tagged \"Food\" takes all of these.\nparent | Produce | Food\nparent | RawMeat | Food\nparent | CookingIngredients | Food\nparent | CookedMeat | Food\nparent | MealsHealth | Food\nparent | MealsStamina | Food\nparent | MealsEitr | Food\nparent | MealsBalanced | Food\nparent | Feasts | Food\n\n# Prepared food not matched by a name rule below, by its icon colour.\nfoodcolor | Health | MealsHealth\nfoodcolor | Stamina | MealsStamina\nfoodcolor | Eitr | MealsEitr\nfoodcolor | Balanced | MealsBalanced\n\nitemtype | Consumable | Food\nitemtype | AmmoNonEquipable | SiegeAmmo\nitemtype | Material | Misc\nitemtype | Misc | Misc\n\n# --- Exact exceptions: merged-lowercase names the suffix rule can't split\n# (Leatherstraps, Bloodbag...), modifiers after the material word\n# (FlametalNew, OrbFrostFire...), and deliberate regroupings.\noverride | * | BoneFragments | BonesAndSkeleton\noverride | * | Charredskull | BonesAndSkeleton\noverride | * | NeckTail | BonesAndSkeleton\noverride | * | BonemawSerpentScale | ChitinAndScales\noverride | * | Leatherstraps | HidesAndFur\noverride | * | ElakingHairBundle | HidesAndFur\noverride | * | WolfHairBundle | HidesAndFur\noverride | * | Bilebag | Organs\noverride | * | Bloodbag | Organs\noverride | * | Softtissue | Organs\noverride | * | CuredSquirrelHamstring | Organs\noverride | * | Ironpit | OresAndMetals\noverride | * | CharredCogwheel | OresAndMetals\noverride | * | FlametalNew | OresAndMetals\noverride | * | FlametalOreNew | OresAndMetals\noverride | * | Grausten | BuildingStone\noverride | * | PungentPebbles | BuildingStone\noverride | * | Thunderstone | Minerals\noverride | * | SulfurStone | Minerals\noverride | * | SharpeningStone | CraftingParts\noverride | * | CandleWick | CraftingParts\noverride | * | Hook | CraftingParts\noverride | * | BarrelRings | CraftingParts\noverride | * | ScytheHandle | CraftingParts\noverride | * | Blackwood | Wood\noverride | * | Frostwood | Wood\noverride | * | FirConeFrost | PlantsAndSeeds\noverride | * | FragrantBundle | PlantsAndSeeds\noverride | * | Feathers | Feathers\noverride | * | CelestialFeather | Feathers\noverride | * | BreadDough | CookingIngredients\noverride | * | BarleyFlour | CookingIngredients\noverride | * | OatFlour | CookingIngredients\noverride | * | ChickenEgg | Produce\n# Edible as-is, but really crops, forage and cooking ingredients.\noverride | Consumable | Blueberries | Produce\noverride | Consumable | Raspberry | Produce\noverride | Consumable | Cloudberry | Produce\noverride | Consumable | Lingonberry | Produce\noverride | Consumable | Vineberry | Produce\noverride | Consumable | Pukeberries | Produce\noverride | Consumable | Carrot | Produce\noverride | Consumable | Onion | Produce\noverride | Consumable | Kale | Produce\noverride | Consumable | Oat | Produce\noverride | Consumable | Poteitr | Produce\noverride | Consumable | Honey | Produce\noverride | Consumable | RoyalJelly | Produce\noverride | Consumable | Fiddleheadfern | Produce\noverride | Consumable | GlowWorm | Produce\noverride | Consumable | Mushroom | Produce\noverride | Consumable | MushroomBlue | Produce\noverride | Consumable | MushroomBzerker | Produce\noverride | Consumable | MushroomJotunPuffs | Produce\noverride | Consumable | MushroomMagecap | Produce\noverride | Consumable | MushroomSmokePuff | Produce\noverride | Consumable | MushroomYellow | Produce\noverride | Consumable | NeckTailGrilled | CookedMeat\noverride | Consumable | RottenMeat | RawMeat\noverride | * | BarleyWineBase | MeadBases\noverride | * | BarleyWine | Potions\noverride | * | OozeMork | ResinAndTar\noverride | * | ShieldCore | RareCores\noverride | * | DvergrNeedle | RareCores\noverride | * | BlobVial | RareCores\noverride | * | Ectoplasm | RareCores\noverride | * | Voidplasm | RareCores\noverride | * | Wisp | RareCores\noverride | * | FaderEmber | RareCores\noverride | * | OrbFrostFire | RareCores\noverride | * | OrbThunderBlood | RareCores\noverride | * | PowderedDragonEgg | RareCores\noverride | * | HardAntler | QuestAndBoss\noverride | * | QueenDrop | QuestAndBoss\noverride | * | FaderDrop | QuestAndBoss\noverride | * | FrozenKingDrop | QuestAndBoss\noverride | * | DragonTear | QuestAndBoss\noverride | * | YagluthDrop | QuestAndBoss\noverride | * | DragonEgg | QuestAndBoss\noverride | * | AxeHead1 | QuestAndBoss\noverride | * | AxeHead2 | QuestAndBoss\noverride | * | Pot_Shard_Green | QuestAndBoss\noverride | * | Pot_Shard_Red | QuestAndBoss\noverride | * | CryptKey | QuestAndBoss\noverride | * | DvergrKey | QuestAndBoss\noverride | * | BloodGoldKey | QuestAndBoss\noverride | * | HildirKey_forestcrypt | QuestAndBoss\noverride | * | HildirKey_mountaincave | QuestAndBoss\noverride | * | HildirKey_plainsfortress | QuestAndBoss\noverride | * | chest_hildir1 | QuestAndBoss\noverride | * | chest_hildir2 | QuestAndBoss\noverride | * | chest_hildir3 | QuestAndBoss\noverride | * | GoblinTotem | QuestAndBoss\noverride | * | HatefulBlood | QuestAndBoss\noverride | * | Bell | QuestAndBoss\noverride | * | AncientSeed | QuestAndBoss\noverride | * | AsksvinEgg | Taming\noverride | * | VoltureEgg | Taming\noverride | * | SaddleLox | Taming\noverride | * | SaddleAsksvin | Taming\noverride | * | SaddleMoose | Taming\noverride | * | BombSiege | SiegeAmmo\noverride | * | Catapult_ammo | SiegeAmmo\noverride | * | Catapult_Ammo_BloodGold | SiegeAmmo\n\n# --- Name families where the type word is at the front.\nprefix | Material | MeadBase | MeadBases\nprefix | Material | Upgrader | UpgradeIdols\nprefix | Material | Spice | Spices\nprefix | Material | FireworksRocket_ | Fireworks\nprefix | Material | Mold | CastsAndMoulds\nprefix | Material | AncientGemstone | Valuables\nprefix | Material | Gemstone | Valuables\nprefix | Material | Jute | Textiles\nprefix | Material | Feast | Feasts\nprefix | Consumable | Feast | Feasts\nprefix | Consumable | Mead | Potions\nprefix | Consumable | Cooked | CookedMeat\n# \"Cast: ...\" armor and staff moulds are named *Uncooked like food - must win over the Uncooked rule.\nprefix | Material | ArmorGold | CastsAndMoulds\nprefix | Material | Staff | CastsAndMoulds\n\n# \"Cast: ...\" items are named *GoldUncooked - must win over the generic Uncooked rule below.\nendswith | Material | GoldUncooked | CastsAndMoulds\nendswith | Material | MoldUncooked | CastsAndMoulds\nendswith | Consumable | Cooked | CookedMeat\ncontains | Material | Uncooked | CookingIngredients\n\n# --- Last-word rules for Material items.\nsuffix | Material | Hide | HidesAndFur\nsuffix | Material | Pelt | HidesAndFur\nsuffix | Material | Leather | HidesAndFur\nsuffix | Material | Straps | HidesAndFur\nsuffix | Material | Scraps | HidesAndFur\nsuffix | Material | Meat | RawMeat\nsuffix | Material | Blubber | RawMeat\nsuffix | Material | Raw | RawMeat\nsuffix | Material | Bone | BonesAndSkeleton\nsuffix | Material | Bones | BonesAndSkeleton\nsuffix | Material | Skull | BonesAndSkeleton\nsuffix | Material | Ribcage | BonesAndSkeleton\nsuffix | Material | Pelvic | BonesAndSkeleton\nsuffix | Material | Neck | BonesAndSkeleton\nsuffix | Material | Tooth | BonesAndSkeleton\nsuffix | Material | Fang | BonesAndSkeleton\nsuffix | Material | Claw | BonesAndSkeleton\nsuffix | Material | Claws | BonesAndSkeleton\nsuffix | Material | Paw | BonesAndSkeleton\nsuffix | Material | Antler | BonesAndSkeleton\nsuffix | Material | Mandible | BonesAndSkeleton\nsuffix | Material | Bladder | Organs\nsuffix | Material | Bag | Organs\nsuffix | Material | Entrails | Organs\nsuffix | Material | Sinew | Organs\nsuffix | Material | Heart | Organs\nsuffix | Material | Tissue | Organs\nsuffix | Material | Sack | Organs\nsuffix | Material | Eye | Organs\nsuffix | Material | Gland | Organs\nsuffix | Material | Ore | OresAndMetals\nsuffix | Material | Scrap | OresAndMetals\nsuffix | Material | Nails | OresAndMetals\nsuffix | Material | Copper | OresAndMetals\nsuffix | Material | Bronze | OresAndMetals\nsuffix | Material | Iron | OresAndMetals\nsuffix | Material | Silver | OresAndMetals\nsuffix | Material | Tin | OresAndMetals\nsuffix | Material | Gold | OresAndMetals\nsuffix | Material | Flametal | OresAndMetals\nsuffix | Material | Metal | OresAndMetals\nsuffix | Material | Chain | OresAndMetals\nsuffix | Material | Spring | OresAndMetals\nsuffix | Material | Stone | BuildingStone\nsuffix | Material | Rock | BuildingStone\nsuffix | Material | Marble | BuildingStone\nsuffix | Material | Flint | Minerals\nsuffix | Material | Crystal | Minerals\nsuffix | Material | Coal | Minerals\nsuffix | Material | Obsidian | Minerals\nsuffix | Material | Powder | Minerals\nsuffix | Material | Plate | CraftingParts\nsuffix | Material | Wood | Wood\nsuffix | Material | Log | Wood\nsuffix | Material | Bark | Wood\nsuffix | Material | Branch | Wood\nsuffix | Material | Seeds | PlantsAndSeeds\nsuffix | Material | Flax | PlantsAndSeeds\nsuffix | Material | Barley | Produce\nsuffix | Material | Dandelion | PlantsAndSeeds\nsuffix | Material | Thistle | PlantsAndSeeds\nsuffix | Material | Acorn | PlantsAndSeeds\nsuffix | Material | Acorns | PlantsAndSeeds\nsuffix | Material | Cone | PlantsAndSeeds\nsuffix | Material | Root | PlantsAndSeeds\nsuffix | Material | Roots | PlantsAndSeeds\nsuffix | Material | Turnip | Produce\nsuffix | Material | Seaweed | PlantsAndSeeds\nsuffix | Material | Thread | Textiles\nsuffix | Material | Resin | ResinAndTar\nsuffix | Material | Sap | ResinAndTar\nsuffix | Material | Tar | ResinAndTar\nsuffix | Material | Ooze | ResinAndTar\nsuffix | Material | Pulp | ResinAndTar\nsuffix | Material | Guck | ResinAndTar\nsuffix | Material | Ice | ResinAndTar\nsuffix | Material | Fuel | ResinAndTar\nsuffix | Material | Carapace | ChitinAndScales\nsuffix | Material | Chitin | ChitinAndScales\nsuffix | Material | Scale | ChitinAndScales\nsuffix | Material | Needle | ChitinAndScales\nsuffix | Material | Bee | Taming\nsuffix | Material | Core | RareCores\nsuffix | Material | Eitr | RareCores\nsuffix | Material | Remains | RareCores\nsuffix | Material | Orb | RareCores\nsuffix | Material | Fragment | QuestAndBoss\nsuffix | Material | Coin | Valuables\nsuffix | Material | Coins | Valuables\nsuffix | Material | Necklace | Valuables\nsuffix | Material | Amber | Valuables\nsuffix | Material | Pearl | Valuables\nsuffix | Material | Pearls | Valuables\nsuffix | Material | Ruby | Valuables\nsuffix | Material | Jewel | Valuables\n"); ChestSorterPlugin.WriteLog($"Category rules updated to v{4}; your previous file was saved as {text}."); } } } catch (Exception ex) { ChestSorterPlugin.WriteLog("CategoryConfig init ERROR (falling back to built-in rules): " + ex.Message); } Load(); } internal static void ReloadIfChanged() { try { if (_path != null && File.Exists(_path) && File.GetLastWriteTimeUtc(_path) != _loadedStampUtc) { Load(); } } catch { } } private static void Load() { List<string> list = new List<string>(); string text = "# ChestSorter category rules. Edit freely - the file is re-read automatically\n# the next time you press Push after saving it.\n#\n# Line formats (fields separated by |):\n# version | <n>\n# category | <id> | <display name> id is what gets stored on chests - never rename an id,\n# add an alias line instead\n# alias | <old id> | <new id> chests tagged with <old id> are treated as <new id>\n# itemtype | <ItemType> | <category id> fallback for an item type when no rule below matches\n# override | <scope> | <prefab> | <id> exact prefab (internal) name\n# prefix | <scope> | <text> | <id> prefab name starts with text\n# endswith | <scope> | <text> | <id> prefab name ends with text\n# contains | <scope> | <text> | <id> prefab name contains text\n# suffix | <scope> | <word> | <id> LAST PascalCase word of the prefab name equals word\n# foodcolor | <color> | <id> food by its icon colour in the game: Health (red),\n# Stamina (yellow), Eitr (blue), Balanced (white)\n# parent | <id> | <parent id> a chest tagged with the parent also takes this category;\n# Push prefers exact-category chests and uses parent-tagged\n# ones as overflow\n# <scope> is an item type (Material, Consumable, Misc, ...) or * for any.\n# Matching order: override, prefix, endswith, contains, suffix, foodcolor, itemtype.\n# Unmatched Material items land in Misc; unmatched items of other types use their item type name.\n\nversion | 4\n\ncategory | Trophy | Trophies\ncategory | Ammo | Ammo\ncategory | SiegeAmmo | Siege Ammo\ncategory | Chest | Armor: Chest\ncategory | Helmet | Armor: Helmets\ncategory | Legs | Armor: Legs\ncategory | Shoulder | Capes\ncategory | Shield | Shields\ncategory | OneHandedWeapon | One-Handed Weapons\ncategory | TwoHandedWeapon | Two-Handed Weapons\ncategory | TwoHandedWeaponLeft | Two-Handed (Left Hand)\ncategory | Bow | Bows & Crossbows\ncategory | Tool | Tools\ncategory | Utility | Utility\ncategory | Torch | Torches & Lanterns\ncategory | Trinket | Trinkets\ncategory | Fish | Fish\ncategory | Food | Food (all kinds)\ncategory | Produce | Food: Produce\ncategory | RawMeat | Food: Raw Meat\ncategory | CookingIngredients | Food: Cooking Ingredients\ncategory | CookedMeat | Food: Cooked Meat\ncategory | MealsHealth | Food: Meals (Health)\ncategory | MealsStamina | Food: Meals (Stamina)\ncategory | MealsEitr | Food: Meals (Eitr)\ncategory | MealsBalanced | Food: Meals (Balanced)\ncategory | Feasts | Food: Feasts\ncategory | Potions | Meads & Potions\ncategory | Customization | Cosmetics\ncategory | HidesAndFur | Hides & Fur\ncategory | BonesAndSkeleton | Bones\ncategory | Organs | Organs\ncategory | OresAndMetals | Ores & Metals\ncategory | BuildingStone | Building Stone\ncategory | Minerals | Minerals\ncategory | Wood | Wood\ncategory | PlantsAndSeeds | Plants & Seeds\ncategory | Textiles | Textiles\ncategory | Feathers | Feathers\ncategory | ResinAndTar | Resin & Tar\ncategory | ChitinAndScales | Chitin & Scales\ncategory | RareCores | Cores & Essences\ncategory | Valuables | Valuables\ncategory | QuestAndBoss | Quest & Boss Items\ncategory | Taming | Taming & Saddles\ncategory | CraftingParts | Crafting Parts\ncategory | MeadBases | Mead Bases\ncategory | UpgradeIdols | Upgrade Idols\ncategory | Spices | Spices\ncategory | Fireworks | Fireworks\ncategory | CastsAndMoulds | Casts & Moulds\ncategory | Misc | Misc\n\n# Old ids from earlier builds.\nalias | StoneAndGems | BuildingStone\nalias | Currency | Valuables\nalias | RawDishes | CookingIngredients\nalias | Consumable | Food\nalias | AmmoNonEquipable | SiegeAmmo\nalias | FeastIngredients | Feasts\n\n# --- Food family: a chest tagged \"Food\" takes all of these.\nparent | Produce | Food\nparent | RawMeat | Food\nparent | CookingIngredients | Food\nparent | CookedMeat | Food\nparent | MealsHealth | Food\nparent | MealsStamina | Food\nparent | MealsEitr | Food\nparent | MealsBalanced | Food\nparent | Feasts | Food\n\n# Prepared food not matched by a name rule below, by its icon colour.\nfoodcolor | Health | MealsHealth\nfoodcolor | Stamina | MealsStamina\nfoodcolor | Eitr | MealsEitr\nfoodcolor | Balanced | MealsBalanced\n\nitemtype | Consumable | Food\nitemtype | AmmoNonEquipable | SiegeAmmo\nitemtype | Material | Misc\nitemtype | Misc | Misc\n\n# --- Exact exceptions: merged-lowercase names the suffix rule can't split\n# (Leatherstraps, Bloodbag...), modifiers after the material word\n# (FlametalNew, OrbFrostFire...), and deliberate regroupings.\noverride | * | BoneFragments | BonesAndSkeleton\noverride | * | Charredskull | BonesAndSkeleton\noverride | * | NeckTail | BonesAndSkeleton\noverride | * | BonemawSerpentScale | ChitinAndScales\noverride | * | Leatherstraps | HidesAndFur\noverride | * | ElakingHairBundle | HidesAndFur\noverride | * | WolfHairBundle | HidesAndFur\noverride | * | Bilebag | Organs\noverride | * | Bloodbag | Organs\noverride | * | Softtissue | Organs\noverride | * | CuredSquirrelHamstring | Organs\noverride | * | Ironpit | OresAndMetals\noverride | * | CharredCogwheel | OresAndMetals\noverride | * | FlametalNew | OresAndMetals\noverride | * | FlametalOreNew | OresAndMetals\noverride | * | Grausten | BuildingStone\noverride | * | PungentPebbles | BuildingStone\noverride | * | Thunderstone | Minerals\noverride | * | SulfurStone | Minerals\noverride | * | SharpeningStone | CraftingParts\noverride | * | CandleWick | CraftingParts\noverride | * | Hook | CraftingParts\noverride | * | BarrelRings | CraftingParts\noverride | * | ScytheHandle | CraftingParts\noverride | * | Blackwood | Wood\noverride | * | Frostwood | Wood\noverride | * | FirConeFrost | PlantsAndSeeds\noverride | * | FragrantBundle | PlantsAndSeeds\noverride | * | Feathers | Feathers\noverride | * | CelestialFeather | Feathers\noverride | * | BreadDough | CookingIngredients\noverride | * | BarleyFlour | CookingIngredients\noverride | * | OatFlour | CookingIngredients\noverride | * | ChickenEgg | Produce\n# Edible as-is, but really crops, forage and cooking ingredients.\noverride | Consumable | Blueberries | Produce\noverride | Consumable | Raspberry | Produce\noverride | Consumable | Cloudberry | Produce\noverride | Consumable | Lingonberry | Produce\noverride | Consumable | Vineberry | Produce\noverride | Consumable | Pukeberries | Produce\noverride | Consumable | Carrot | Produce\noverride | Consumable | Onion | Produce\noverride | Consumable | Kale | Produce\noverride | Consumable | Oat | Produce\noverride | Consumable | Poteitr | Produce\noverride | Consumable | Honey | Produce\noverride | Consumable | RoyalJelly | Produce\noverride | Consumable | Fiddleheadfern | Produce\noverride | Consumable | GlowWorm | Produce\noverride | Consumable | Mushroom | Produce\noverride | Consumable | MushroomBlue | Produce\noverride | Consumable | MushroomBzerker | Produce\noverride | Consumable | MushroomJotunPuffs | Produce\noverride | Consumable | MushroomMagecap | Produce\noverride | Consumable | MushroomSmokePuff | Produce\noverride | Consumable | MushroomYellow | Produce\noverride | Consumable | NeckTailGrilled | CookedMeat\noverride | Consumable | RottenMeat | RawMeat\noverride | * | BarleyWineBase | MeadBases\noverride | * | BarleyWine | Potions\noverride | * | OozeMork | ResinAndTar\noverride | * | ShieldCore | RareCores\noverride | * | DvergrNeedle | RareCores\noverride | * | BlobVial | RareCores\noverride | * | Ectoplasm | RareCores\noverride | * | Voidplasm | RareCores\noverride | * | Wisp | RareCores\noverride | * | FaderEmber | RareCores\noverride | * | OrbFrostFire | RareCores\noverride | * | OrbThunderBlood | RareCores\noverride | * | PowderedDragonEgg | RareCores\noverride | * | HardAntler | QuestAndBoss\noverride | * | QueenDrop | QuestAndBoss\noverride | * | FaderDrop | QuestAndBoss\noverride | * | FrozenKingDrop | QuestAndBoss\noverride | * | DragonTear | QuestAndBoss\noverride | * | YagluthDrop | QuestAndBoss\noverride | * | DragonEgg | QuestAndBoss\noverride | * | AxeHead1 | QuestAndBoss\noverride | * | AxeHead2 | QuestAndBoss\noverride | * | Pot_Shard_Green | QuestAndBoss\noverride | * | Pot_Shard_Red | QuestAndBoss\noverride | * | CryptKey | QuestAndBoss\noverride | * | DvergrKey | QuestAndBoss\noverride | * | BloodGoldKey | QuestAndBoss\noverride | * | HildirKey_forestcrypt | QuestAndBoss\noverride | * | HildirKey_mountaincave | QuestAndBoss\noverride | * | HildirKey_plainsfortress | QuestAndBoss\noverride | * | chest_hildir1 | QuestAndBoss\noverride | * | chest_hildir2 | QuestAndBoss\noverride | * | chest_hildir3 | QuestAndBoss\noverride | * | GoblinTotem | QuestAndBoss\noverride | * | HatefulBlood | QuestAndBoss\noverride | * | Bell | QuestAndBoss\noverride | * | AncientSeed | QuestAndBoss\noverride | * | AsksvinEgg | Taming\noverride | * | VoltureEgg | Taming\noverride | * | SaddleLox | Taming\noverride | * | SaddleAsksvin | Taming\noverride | * | SaddleMoose | Taming\noverride | * | BombSiege | SiegeAmmo\noverride | * | Catapult_ammo | SiegeAmmo\noverride | * | Catapult_Ammo_BloodGold | SiegeAmmo\n\n# --- Name families where the type word is at the front.\nprefix | Material | MeadBase | MeadBases\nprefix | Material | Upgrader | UpgradeIdols\nprefix | Material | Spice | Spices\nprefix | Material | FireworksRocket_ | Fireworks\nprefix | Material | Mold | CastsAndMoulds\nprefix | Material | AncientGemstone | Valuables\nprefix | Material | Gemstone | Valuables\nprefix | Material | Jute | Textiles\nprefix | Material | Feast | Feasts\nprefix | Consumable | Feast | Feasts\nprefix | Consumable | Mead | Potions\nprefix | Consumable | Cooked | CookedMeat\n# \"Cast: ...\" armor and staff moulds are named *Uncooked like food - must win over the Uncooked rule.\nprefix | Material | ArmorGold | CastsAndMoulds\nprefix | Material | Staff | CastsAndMoulds\n\n# \"Cast: ...\" items are named *GoldUncooked - must win over the generic Uncooked rule below.\nendswith | Material | GoldUncooked | CastsAndMoulds\nendswith | Material | MoldUncooked | CastsAndMoulds\nendswith | Consumable | Cooked | CookedMeat\ncontains | Material | Uncooked | CookingIngredients\n\n# --- Last-word rules for Material items.\nsuffix | Material | Hide | HidesAndFur\nsuffix | Material | Pelt | HidesAndFur\nsuffix | Material | Leather | HidesAndFur\nsuffix | Material | Straps | HidesAndFur\nsuffix | Material | Scraps | HidesAndFur\nsuffix | Material | Meat | RawMeat\nsuffix | Material | Blubber | RawMeat\nsuffix | Material | Raw | RawMeat\nsuffix | Material | Bone | BonesAndSkeleton\nsuffix | Material | Bones | BonesAndSkeleton\nsuffix | Material | Skull | BonesAndSkeleton\nsuffix | Material | Ribcage | BonesAndSkeleton\nsuffix | Material | Pelvic | BonesAndSkeleton\nsuffix | Material | Neck | BonesAndSkeleton\nsuffix | Material | Tooth | BonesAndSkeleton\nsuffix | Material | Fang | BonesAndSkeleton\nsuffix | Material | Claw | BonesAndSkeleton\nsuffix | Material | Claws | BonesAndSkeleton\nsuffix | Material | Paw | BonesAndSkeleton\nsuffix | Material | Antler | BonesAndSkeleton\nsuffix | Material | Mandible | BonesAndSkeleton\nsuffix | Material | Bladder | Organs\nsuffix | Material | Bag | Organs\nsuffix | Material | Entrails | Organs\nsuffix | Material | Sinew | Organs\nsuffix | Material | Heart | Organs\nsuffix | Material | Tissue | Organs\nsuffix | Material | Sack | Organs\nsuffix | Material | Eye | Organs\nsuffix | Material | Gland | Organs\nsuffix | Material | Ore | OresAndMetals\nsuffix | Material | Scrap | OresAndMetals\nsuffix | Material | Nails | OresAndMetals\nsuffix | Material | Copper | OresAndMetals\nsuffix | Material | Bronze | OresAndMetals\nsuffix | Material | Iron | OresAndMetals\nsuffix | Material | Silver | OresAndMetals\nsuffix | Material | Tin | OresAndMetals\nsuffix | Material | Gold | OresAndMetals\nsuffix | Material | Flametal | OresAndMetals\nsuffix | Material | Metal | OresAndMetals\nsuffix | Material | Chain | OresAndMetals\nsuffix | Material | Spring | OresAndMetals\nsuffix | Material | Stone | BuildingStone\nsuffix | Material | Rock | BuildingStone\nsuffix | Material | Marble | BuildingStone\nsuffix | Material | Flint | Minerals\nsuffix | Material | Crystal | Minerals\nsuffix | Material | Coal | Minerals\nsuffix | Material | Obsidian | Minerals\nsuffix | Material | Powder | Minerals\nsuffix | Material | Plate | CraftingParts\nsuffix | Material | Wood | Wood\nsuffix | Material | Log | Wood\nsuffix | Material | Bark | Wood\nsuffix | Material | Branch | Wood\nsuffix | Material | Seeds | PlantsAndSeeds\nsuffix | Material | Flax | PlantsAndSeeds\nsuffix | Material | Barley | Produce\nsuffix | Material | Dandelion | PlantsAndSeeds\nsuffix | Material | Thistle | PlantsAndSeeds\nsuffix | Material | Acorn | PlantsAndSeeds\nsuffix | Material | Acorns | PlantsAndSeeds\nsuffix | Material | Cone | PlantsAndSeeds\nsuffix | Material | Root | PlantsAndSeeds\nsuffix | Material | Roots | PlantsAndSeeds\nsuffix | Material | Turnip | Produce\nsuffix | Material | Seaweed | PlantsAndSeeds\nsuffix | Material | Thread | Textiles\nsuffix | Material | Resin | ResinAndTar\nsuffix | Material | Sap | ResinAndTar\nsuffix | Material | Tar | ResinAndTar\nsuffix | Material | Ooze | ResinAndTar\nsuffix | Material | Pulp | ResinAndTar\nsuffix | Material | Guck | ResinAndTar\nsuffix | Material | Ice | ResinAndTar\nsuffix | Material | Fuel | ResinAndTar\nsuffix | Material | Carapace | ChitinAndScales\nsuffix | Material | Chitin | ChitinAndScales\nsuffix | Material | Scale | ChitinAndScales\nsuffix | Material | Needle | ChitinAndScales\nsuffix | Material | Bee | Taming\nsuffix | Material | Core | RareCores\nsuffix | Material | Eitr | RareCores\nsuffix | Material | Remains | RareCores\nsuffix | Material | Orb | RareCores\nsuffix | Material | Fragment | QuestAndBoss\nsuffix | Material | Coin | Valuables\nsuffix | Material | Coins | Valuables\nsuffix | Material | Necklace | Valuables\nsuffix | Material | Amber | Valuables\nsuffix | Material | Pearl | Valuables\nsuffix | Material | Pearls | Valuables\nsuffix | Material | Ruby | Valuables\nsuffix | Material | Jewel | Valuables\n"; try { if (_path != null && File.Exists(_path)) { text = File.ReadAllText(_path); _loadedStampUtc = File.GetLastWriteTimeUtc(_path); } } catch (Exception ex) { list.Add("can't read file, using built-in rules: " + ex.Message); } Rules = CategoryRules.Parse(text, list); ChestSorterPlugin.WriteLog($"Category rules loaded: v{Rules.Version}, {Rules.Categories.Count} categories, {list.Count} problem(s)."); foreach (string item in list) { ChestSorterPlugin.WriteLog(" category rules: " + item); } } } internal static class CategoryPanel { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; public static UnityAction <1>__SetFromContents; public static UnityAction <2>__ClearAll; public static Func<string, bool> <3>__IsItemTag; public static Func<string, string> <4>__TagDisplayName; public static Func<ItemData, string> <5>__GetCategory; } private const float Width = 300f; private const float Height = 480f; private const float Pad = 12f; private const float RowHeight = 30f; private static readonly Color SelectedColor = new Color(1f, 0.72f, 0.2f, 1f); private static readonly Color UnselectedColor = new Color(0.78f, 0.78f, 0.78f, 1f); private static GameObject _root; private static RectTransform _content; private static TMP_Text _contentsText; private static ScrollRect _scroll; private static Container _current; private static HashSet<string> _selected = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly List<(string id, TMP_Text label)> _rows = new List<(string, TMP_Text)>(); internal static bool IsOpen { get { if ((Object)(object)_root != (Object)null) { return _root.activeSelf; } return false; } } internal static void Toggle(Container c) { if (IsOpen && (Object)(object)_current == (Object)(object)c) { Close(); } else { Open(c); } } internal static void Close() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } internal static void Open(Container c) { if (!((Object)(object)c == (Object)null) && Ensure()) { _current = c; _selected = ContainerCategoryTags.Get(c); UpdateContentsText(); RebuildRows(); _root.SetActive(true); _root.transform.SetAsLastSibling(); _scroll.verticalNormalizedPosition = 1f; } } private static bool Ensure() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Expected O, but got Unknown if ((Object)(object)_root != (Object)null) { return true; } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_container == (Object)null || (Object)(object)instance.m_stackAllButton == (Object)null || (Object)(object)instance.m_containerName == (Object)null) { return false; } _root = new GameObject("ChestSorter_CategoryPanel", new Type[1] { typeof(RectTransform) }); RectTransform val = (RectTransform)_root.transform; ((Transform)val).SetParent((Transform)(object)instance.m_container, false); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 1f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = new Vector2(0f, 1f); val.sizeDelta = new Vector2(300f, 480f); val.anchoredPosition = new Vector2(ContainerButtons.ColumnRight + 12f, 0f); UiClone.IgnoreLayout(_root); UiClone.CopyBackground(instance.m_container, _root.AddComponent<Image>()); TMP_Text obj = UiClone.Text(instance.m_containerName, _root.transform, "Title", "Categories"); UiClone.Place(obj.rectTransform, 12f, 12f, 236f, 36f); obj.alignment = (TextAlignmentOptions)514; Button stackAllButton = instance.m_stackAllButton; Transform transform = _root.transform; object obj2 = <>O.<0>__Close; if (obj2 == null) { UnityAction val3 = Close; <>O.<0>__Close = val3; obj2 = (object)val3; } UiClone.Place((RectTransform)((Component)UiClone.Button(stackAllButton, transform, "Close", "X", (UnityAction)obj2)).transform, 254f, 14f, 34f, 34f); _contentsText = UiClone.Text(((Object)(object)instance.m_recipeDecription != (Object)null) ? instance.m_recipeDecription : instance.m_containerName, _root.transform, "Contents", ""); UiClone.Place(_contentsText.rectTransform, 12f, 54f, 276f, 46f); _contentsText.alignment = (TextAlignmentOptions)257; _contentsText.enableAutoSizing = true; _contentsText.fontSizeMin = 10f; _contentsText.fontSizeMax = 16f; _contentsText.textWrappingMode = (TextWrappingModes)1; Button stackAllButton2 = instance.m_stackAllButton; Transform transform2 = _root.transform; object obj3 = <>O.<1>__SetFromContents; if (obj3 == null) { UnityAction val4 = SetFromContents; <>O.<1>__SetFromContents = val4; obj3 = (object)val4; } UiClone.Place((RectTransform)((Component)UiClone.Button(stackAllButton2, transform2, "FromContents", "From contents", (UnityAction)obj3)).transform, 12f, 104f, 168f, 32f); Button stackAllButton3 = instance.m_stackAllButton; Transform transform3 = _root.transform; object obj4 = <>O.<2>__ClearAll; if (obj4 == null) { UnityAction val5 = ClearAll; <>O.<2>__ClearAll = val5; obj4 = (object)val5; } UiClone.Place((RectTransform)((Component)UiClone.Button(stackAllButton3, transform3, "Clear", "Clear", (UnityAction)obj4)).transform, 186f, 104f, 102f, 32f); _content = UiClone.ScrollArea(_root.transform, "List", 12f, 144f, 276f, 324f, instance.m_recipeListScroll, out _scroll); _root.SetActive(false); return true; } private static void RebuildRows() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) foreach (Transform item in (Transform)_content) { Object.Destroy((Object)(object)((Component)item).gameObject); } _rows.Clear(); CategoryRules rules = CategoryConfig.Rules; Button stackAllButton = InventoryGui.instance.m_stackAllButton; foreach (string item2 in _selected.Where(CategoryRules.IsItemTag).OrderBy<string, string>(ItemCategory.TagDisplayName, StringComparer.OrdinalIgnoreCase).ToList()) { AddRow(stackAllButton, item2, "Item: " + ItemCategory.TagDisplayName(item2)); } foreach (string item3 in _selected.Where((string t) => !CategoryRules.IsItemTag(t) && !rules.IsKnown(t)).ToList()) { AddRow(stackAllButton, item3, item3 + " (not in rules file)"); } foreach (var (id, display) in rules.Categories) { AddRow(stackAllButton, id, display); } RefreshRows(); } private static void AddRow(Button template, string id, string display) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) Button obj = UiClone.Button(template, (Transform)(object)_content, "Row_" + id, display, (UnityAction)delegate { ToggleCategory(id); }); LayoutElement component = ((Component)obj).GetComponent<LayoutElement>(); component.ignoreLayout = false; float minHeight = (component.preferredHeight = 30f); component.minHeight = minHeight; TMP_Text val = UiClone.LabelOf(((Component)obj).gameObject); if ((Object)(object)val != (Object)null) { val.alignment = (TextAlignmentOptions)4097; val.margin = new Vector4(10f, 0f, 6f, 0f); val.enableAutoSizing = true; val.fontSizeMin = 10f; val.fontSizeMax = 18f; } _rows.Add((id, val)); } private static void RefreshRows() { //IL_0041: 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) foreach (var (item, val) in _rows) { if (!((Object)(object)val == (Object)null)) { bool flag = _selected.Contains(item); ((Graphic)val).color = (flag ? SelectedColor : UnselectedColor); val.fontStyle = (FontStyles)(flag ? 1 : 0); } } } private static void ToggleCategory(string id) { if (!_selected.Remove(id)) { _selected.Add(id); } Save(); } private static void SetFromContents() { _selected = new HashSet<string>(from t in ContentsCategories() select t.id, StringComparer.OrdinalIgnoreCase); Save(); } private static void ClearAll() { _selected.Clear(); Save(); } private static void Save() { if (!((Object)(object)_current == (Object)null)) { ChestGroups.SetTags(_current, _selected); RefreshRows(); } } private static List<(string id, int count)> ContentsCategories() { if (!((Object)(object)_current == (Object)null)) { return (from g in (from i in _current.GetInventory().GetAllItems() where i.m_shared != null select i).GroupBy(ItemCategory.GetCategory) select (Key: g.Key, g.Sum((ItemData i) => i.m_stack)) into t orderby t.Item2 descending select t).ToList(); } return new List<(string, int)>(); } private static void UpdateContentsText() { List<(string, int)> list = ContentsCategories(); _contentsText.text = ((list.Count == 0) ? "This chest is empty." : ("Contents: " + string.Join(", ", from t in list.Take(6) select $"{CategoryConfig.Rules.DisplayName(t.id)} ({t.count})") + ((list.Count > 6) ? ", ..." : ""))); } } internal sealed class CategoryRules { private sealed class Rule { public string Scope; public string Pattern; public string Category; } private static readonly Regex WordSplitter = new Regex("[A-Z][a-z0-9]*|[a-z0-9]+", RegexOptions.Compiled); private readonly List<(string id, string display)> _categories = new List<(string, string)>(); private readonly Dictionary<string, string> _display = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _aliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _itemTypes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _foodColors = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, string> _parents = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private readonly List<Rule> _overrides = new List<Rule>(); private readonly List<Rule> _prefixes = new List<Rule>(); private readonly List<Rule> _endsWith = new List<Rule>(); private readonly List<Rule> _contains = new List<Rule>(); private readonly List<Rule> _suffixes = new List<Rule>(); private readonly Dictionary<string, string> _cache = new Dictionary<string, string>(); internal const string ItemTagPrefix = "item:"; internal const int FitItem = 3; internal const int FitCategory = 2; internal const int FitParent = 1; internal int Version { get; private set; } internal IReadOnlyList<(string id, string display)> Categories => _categories; internal static CategoryRules Parse(string text, List<string> errors) { CategoryRules categoryRules = new CategoryRules(); int num = 0; string[] array = text.Split(new char[1] { '\n' }); foreach (string text2 in array) { num++; string text3 = text2; int num2 = text3.IndexOf('#'); if (num2 >= 0) { text3 = text3.Substring(0, num2); } text3 = text3.Trim(); if (text3.Length == 0) { continue; } string[] array2 = (from s in text3.Split(new char[1] { '|' }) select s.Trim()).ToArray(); string text4 = array2[0].ToLowerInvariant(); bool flag = true; switch (text4) { case "version": { if (array2.Length == 2 && int.TryParse(array2[1], out var result)) { categoryRules.Version = result; break; } goto default; } case "category": if (array2.Length == 3) { categoryRules.AddCategory(array2[1], array2[2]); break; } goto default; case "alias": if (array2.Length == 3) { categoryRules._aliases[array2[1]] = array2[2]; break; } goto default; case "itemtype": if (array2.Length == 3) { categoryRules._itemTypes[array2[1]] = array2[2]; break; } goto default; case "override": if (array2.Length == 4) { categoryRules._overrides.Add(new Rule { Scope = array2[1], Pattern = array2[2], Category = array2[3] }); break; } goto default; case "prefix": if (array2.Length == 4) { categoryRules._prefixes.Add(new Rule { Scope = array2[1], Pattern = array2[2], Category = array2[3] }); break; } goto default; case "endswith": if (array2.Length == 4) { categoryRules._endsWith.Add(new Rule { Scope = array2[1], Pattern = array2[2], Category = array2[3] }); break; } goto default; case "contains": if (array2.Length == 4) { categoryRules._contains.Add(new Rule { Scope = array2[1], Pattern = array2[2], Category = array2[3] }); break; } goto default; case "suffix": if (array2.Length == 4) { categoryRules._suffixes.Add(new Rule { Scope = array2[1], Pattern = array2[2], Category = array2[3] }); break; } goto default; case "foodcolor": if (array2.Length == 3) { categoryRules._foodColors[array2[1]] = array2[2]; break; } goto default; case "parent": if (array2.Length == 3) { categoryRules._parents[array2[1]] = array2[2]; break; } goto default; default: flag = false; break; } if (!flag) { errors.Add($"line {num}: can't parse \"{text2.Trim()}\""); } } foreach (string item in (from x in categoryRules._overrides.Concat(categoryRules._prefixes).Concat(categoryRules._endsWith).Concat(categoryRules._contains) .Concat(categoryRules._suffixes) select x.Category).Concat(categoryRules._itemTypes.Values).Concat(categoryRules._aliases.Values).Concat(categoryRules._foodColors.Values) .Concat(categoryRules._parents.Keys) .Concat(categoryRules._parents.Values) .Distinct<string>(StringComparer.OrdinalIgnoreCase)) { if (!categoryRules._display.ContainsKey(item)) { errors.Add("category id \"" + item + "\" is used by a rule but never declared with a \"category\" line"); } } return categoryRules; } private void AddCategory(string id, string display) { if (!_display.ContainsKey(id)) { _categories.Add((id, display)); _display[id] = display; } } internal bool IsKnown(string id) { return _display.ContainsKey(Resolve(id)); } internal static bool IsItemTag(string tag) { return tag?.StartsWith("item:", StringComparison.OrdinalIgnoreCase) ?? false; } internal string Resolve(string id) { for (int i = 0; i < 8; i++) { if (id == null) { break; } if (!_aliases.TryGetValue(id, out var value)) { break; } id = value; } return id; } internal string DisplayName(string id) { id = Resolve(id); if (id == null || !_display.TryGetValue(id, out var value)) { return id; } return value; } internal int Fit(ICollection<string> tags, string category, string itemName = null) { if (tags.Count == 0) { return 0; } if (itemName != null && tags.Contains("item:" + itemName)) { return 3; } if (category == null) { return 0; } if (tags.Contains(category)) { return 2; } string key = category; for (int i = 0; i < 8; i++) { if (!_parents.TryGetValue(key, out var value)) { break; } value = Resolve(value); if (tags.Contains(value)) { return 1; } key = value; } return 0; } internal string ParentOf(string id) { if (!_parents.TryGetValue(Resolve(id), out var value)) { return null; } return Resolve(value); } internal string GetCategory(string internalName, string itemType, string foodColor = null) { string key = itemType + "|" + foodColor + "|" + internalName; if (_cache.TryGetValue(key, out var value)) { return value; } string text = Resolve(Match(internalName ?? "", itemType ?? "", foodColor)); _cache[key] = text; return text; } private string Match(string name, string itemType, string foodColor) { foreach (Rule @override in _overrides) { if (InScope(@override, itemType) && string.Equals(name, @override.Pattern, StringComparison.OrdinalIgnoreCase)) { return @override.Category; } } foreach (Rule prefix in _prefixes) { if (InScope(prefix, itemType) && name.StartsWith(prefix.Pattern, StringComparison.OrdinalIgnoreCase)) { return prefix.Category; } } foreach (Rule item in _endsWith) { if (InScope(item, itemType) && name.EndsWith(item.Pattern, StringComparison.OrdinalIgnoreCase)) { return item.Category; } } foreach (Rule contain in _contains) { if (InScope(contain, itemType) && name.IndexOf(contain.Pattern, StringComparison.OrdinalIgnoreCase) >= 0) { return contain.Category; } } MatchCollection matchCollection = WordSplitter.Matches(name); string a = ((matchCollection.Count > 0) ? matchCollection[matchCollection.Count - 1].Value : name); foreach (Rule suffix in _suffixes) { if (InScope(suffix, itemType) && string.Equals(a, suffix.Pattern, StringComparison.OrdinalIgnoreCase)) { return suffix.Category; } } if (foodColor != null && _foodColors.TryGetValue(foodColor, out var value)) { return value; } if (_itemTypes.TryGetValue(itemType, out var value2)) { return value2; } if (!string.Equals(itemType, "Material", StringComparison.OrdinalIgnoreCase)) { return itemType; } return "Misc"; } private static bool InScope(Rule rule, string itemType) { if (!(rule.Scope == "*")) { return string.Equals(rule.Scope, itemType, StringComparison.OrdinalIgnoreCase); } return true; } } internal static class ChestGroups { private const string ZdoKey = "ChestSorter_Group"; private const float SameColumnTolerance = 0.6f; private const float MaxGapBelow = 4f; private const float MemberSearchRadius = 30f; internal static string GroupId(Container c) { ZDO val = GameUtil.Zdo(c); if (val == null) { return ""; } return val.GetString("ChestSorter_Group", ""); } internal static bool InGroup(Container c) { if ((Object)(object)c != (Object)null) { return GroupId(c).Length > 0; } return false; } private static void SetGroupId(Container c, string id) { ZDO val = GameUtil.Zdo(c); if (val != null) { GameUtil.ClaimOwnership(c); val.Set("ChestSorter_Group", id); } } internal static List<Container> Members(Container c) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) string id = GroupId(c); if (id.Length == 0) { return new List<Container> { c }; } Vector3 p = ((Component)c).transform.position; return (from x in Object.FindObjectsByType<Container>((FindObjectsSortMode)0) where (Object)(object)x != (Object)null && Vector3.Distance(((Component)x).transform.position, p) <= 30f && GroupId(x) == id orderby ((Component)x).transform.position.y select x).ToList(); } private static Container FindBelow(Container c) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Vector3 p = ((Component)c).transform.position; return (from x in Object.FindObjectsByType<Container>((FindObjectsSortMode)0) where (Object)(object)x != (Object)null && (Object)(object)x != (Object)(object)c && !Eligibility.IsMovable(x) && Eligibility.Writable(x, c) select (chest: x, dxz: Vector2.Distance(new Vector2(((Component)x).transform.position.x, ((Component)x).transform.position.z), new Vector2(p.x, p.z)), dy: p.y - ((Component)x).transform.position.y) into t where t.dxz <= 0.6f && t.dy > 0.05f && t.dy <= 4f orderby t.dy select t.chest).FirstOrDefault(); } internal static string JoinBelow(Container c) { if (InGroup(c)) { return "This chest is already in a group."; } Container val = FindBelow(c); if ((Object)(object)val == (Object)null) { return "There's no chest directly below this one."; } string text = GroupId(val); if (text.Length == 0) { text = Guid.NewGuid().ToString("N"); SetGroupId(val, text); } SetGroupId(c, text); HashSet<string> hashSet = ContainerCategoryTags.Get(val); if (hashSet.Count == 0) { hashSet = ContainerCategoryTags.Get(c); } SetTags(c, hashSet); int count = Members(c).Count; ChestSorterPlugin.WriteLog($"Joined {GameUtil.Where(c)} to the group of {GameUtil.Where(val)} ({count} chests)."); return $"Joined the group ({count} chests)."; } internal static string Leave(Container c) { if (!InGroup(c)) { return "This chest is not in a group."; } SetGroupId(c, ""); ChestSorterPlugin.WriteLog(GameUtil.Where(c) + " left its group."); return "Left the group (categories kept)."; } internal static void SetTags(Container c, IEnumerable<string> tags) { List<string> categories = tags.ToList(); foreach (Container item in Members(c)) { ContainerCategoryTags.Set(item, categories); ChestLabels.Refresh(item); } } } internal static class ChestLabels { private sealed class Entry { public GameObject Root; public string Text; } private sealed class Seen { public string Raw; public bool Movable; } private const string RootName = "ChestSorter_Label"; private static readonly Dictionary<Container, Entry> _labels = new Dictionary<Container, Entry>(); private static readonly Dictionary<Container, Seen> _seen = new Dictionary<Container, Seen>(); private static Dictionary<string, int> _order; private static CategoryRules _orderRules; private static float _nextScan; private static bool _labelsShown; private static bool _itemIndexDirty; private static readonly HashSet<string> _itemChests = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static TMP_FontAsset _font; private static Material _material; internal static bool HasItemChest(string itemTag) { return _itemChests.Contains(itemTag); } internal static void Tick() { bool value = ChestSorterPlugin.ShowLabels.Value; if (value != _labelsShown) { _labelsShown = value; if (!value) { DestroyLabels(); } foreach (Seen value3 in _seen.Values) { value3.Raw = "\0"; } } if ((Object)(object)Player.m_localPlayer == (Object)null || Time.time < _nextScan) { return; } _nextScan = Time.time + 1f; foreach (Container item in (from kv in _labels where (Object)(object)kv.Key == (Object)null || (Object)(object)kv.Value.Root == (Object)null select kv.Key).ToList()) { if ((Object)(object)_labels[item].Root != (Object)null) { Object.Destroy((Object)(object)_labels[item].Root); } _labels.Remove(item); } foreach (Container item2 in _seen.Keys.Where((Container k) => (Object)(object)k == (Object)null).ToList()) { _seen.Remove(item2); _itemIndexDirty = true; } if (_orderRules != null && _orderRules != CategoryConfig.Rules) { foreach (Seen value4 in _seen.Values) { value4.Raw = "\0"; } } Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); foreach (Container val in array) { ZDO val2 = GameUtil.Zdo(val); string text = ((val2 != null) ? val2.GetString("ChestSorter_Cats", "") : null); if (!_seen.TryGetValue(val, out var value2)) { value2 = new Seen { Raw = "\0", Movable = Eligibility.IsMovable(val) }; _seen[val] = value2; } if (!(value2.Raw == text)) { value2.Raw = text; _itemIndexDirty = true; if (!value2.Movable && value) { Apply(val); } } } if (_itemIndexDirty) { RebuildItemIndex(); } } private static void RebuildItemIndex() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 _itemIndexDirty = false; _itemChests.Clear(); foreach (KeyValuePair<Container, Seen> item in _seen) { string raw = item.Value.Raw; if ((Object)(object)item.Key == (Object)null || item.Value.Movable || string.IsNullOrEmpty(raw) || raw.IndexOf("item:", StringComparison.OrdinalIgnoreCase) < 0 || (int)item.Key.m_privacy != 2) { continue; } string[] array = raw.Split(new char[1] { ',' }); foreach (string text in array) { if (CategoryRules.IsItemTag(text)) { _itemChests.Add(text); } } } } internal static void Refresh(Container c) { if (!((Object)(object)c == (Object)null)) { if (_seen.TryGetValue(c, out var value)) { value.Raw = "\0"; } if (_labelsShown) { Apply(c); } } } private static void Apply(Container c) { string text = LabelText(c); _labels.TryGetValue(c, out var value); if (string.IsNullOrEmpty(text)) { if (value != null) { if ((Object)(object)value.Root != (Object)null) { Object.Destroy((Object)(object)value.Root); } _labels.Remove(c); } } else if (value == null || !((Object)(object)value.Root != (Object)null) || !(value.Text == text)) { if ((Object)(object)value?.Root != (Object)null) { Object.Destroy((Object)(object)value.Root); } _labels[c] = new Entry { Root = Build(c, text), Text = text }; } } internal static void Clear() { DestroyLabels(); _seen.Clear(); _itemChests.Clear(); } private static void DestroyLabels() { foreach (Entry value in _labels.Values) { if ((Object)(object)value.Root != (Object)null) { Object.Destroy((Object)(object)value.Root); } } _labels.Clear(); } private static string LabelText(Container c) { if (Eligibility.IsMovable(c) || GameUtil.Zdo(c) == null) { return null; } HashSet<string> hashSet = ContainerCategoryTags.Get(c); if (hashSet.Count == 0) { return null; } CategoryRules rules = CategoryConfig.Rules; if (_order == null || _orderRules != rules) { _order = rules.Categories.Select(((string id, string display) cat, int i) => (id: cat.id, i: i)).ToDictionary<(string, int), string, int>(((string id, int i) t) => t.id, ((string id, int i) t) => t.i, StringComparer.OrdinalIgnoreCase); _orderRules = rules; } int value; return string.Join("\n", from t in (from t in hashSet orderby (!CategoryRules.IsItemTag(t)) ? 1 : 0, (!_order.TryGetValue(t, out value)) ? int.MaxValue : value select t).ThenBy<string, string>((string t) => t, StringComparer.OrdinalIgnoreCase) select ItemCategory.TagDisplayName(t).ToUpperInvariant()); } private static GameObject Build(Container c, string text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_005d: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) Bounds val = LocalBounds(c); GameObject val2 = new GameObject("ChestSorter_Label"); val2.transform.SetParent(((Component)c).transform, false); int layer = (val2.layer = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).gameObject.layer : ((Component)c).gameObject.layer)); (Vector3, float, float)[] array = new(Vector3, float, float)[4] { (Vector3.forward, ((Bounds)(ref val)).extents.z, ((Bounds)(ref val)).size.x), (Vector3.back, ((Bounds)(ref val)).extents.z, ((Bounds)(ref val)).size.x), (Vector3.right, ((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).size.z), (Vector3.left, ((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).size.z) }; for (int i = 0; i < array.Length; i++) { (Vector3, float, float) tuple = array[i]; GameObject val3 = new GameObject("side") { layer = layer }; val3.transform.SetParent(val2.transform, false); val3.transform.localPosition = ((Bounds)(ref val)).center + tuple.Item1 * (tuple.Item2 + 0.03f); val3.transform.localRotation = Quaternion.LookRotation(-tuple.Item1, Vector3.up); TextMeshPro val4 = val3.AddComponent<TextMeshPro>(); TMP_FontAsset val5 = Font(); if ((Object)(object)val5 != (Object)null) { ((TMP_Text)val4).font = val5; } Material val6 = SharedMaterial(val5); if (val6 != null) { ((TMP_Text)val4).fontSharedMaterial = val6; } ((TMP_Text)val4).rectTransform.sizeDelta = new Vector2(Mathf.Max(0.3f, tuple.Item3 * 0.9f), Mathf.Max(0.2f, ((Bounds)(ref val)).size.y * 0.8f)); ((TMP_Text)val4).text = text; ((TMP_Text)val4).enableAutoSizing = true; ((TMP_Text)val4).fontSizeMin = 0.3f; ((TMP_Text)val4).fontSizeMax = 2.5f; ((TMP_Text)val4).alignment = (TextAlignmentOptions)514; ((TMP_Text)val4).textWrappingMode = (TextWrappingModes)1; ((Graphic)val4).color = new Color(1f, 0.55f, 0.1f, 1f); } return val2; } private static Bounds LocalBounds(Container c) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds result = default(Bounds); MeshRenderer[] componentsInChildren = ((Component)c).GetComponentsInChildren<MeshRenderer>(false); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)((Component)val).GetComponent<TMP_Text>() != (Object)null) { continue; } Bounds localBounds = ((Renderer)val).localBounds; for (int j = 0; j < 8; j++) { Vector3 val2 = ((Bounds)(ref localBounds)).center + Vector3.Scale(((Bounds)(ref localBounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val3 = ((Component)c).transform.InverseTransformPoint(((Component)val).transform.TransformPoint(val2)); if (!flag) { ((Bounds)(ref result))..ctor(val3, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val3); } } } if (!flag) { return new Bounds(new Vector3(0f, 0.5f, 0f), new Vector3(1.4f, 1f, 0.9f)); } return result; } private static TMP_FontAsset Font() { if ((Object)(object)_font != (Object)null) { return _font; } TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); _font = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("norse", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("averia", StringComparison.OrdinalIgnoreCase) >= 0)) ?? source.FirstOrDefault(); if ((Object)(object)_font != (Object)null) { ChestSorterPlugin.WriteLog("Chest labels use font \"" + ((Object)_font).name + "\"."); } return _font; } private static Material SharedMaterial(TMP_FontAsset font) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_material != (Object)null) { return _material; } if ((Object)(object)font == (Object)null || (Object)(object)((TMP_Asset)font).material == (Object)null) { return null; } _material = new Material(((TMP_Asset)font).material); _material.SetFloat("_OutlineWidth", 0.08f); _material.SetColor("_OutlineColor", Color.black); _material.EnableKeyword("GLOW_ON"); _material.SetColor("_GlowColor", new Color(1f, 0.65f, 0.15f, 1f)); _material.SetFloat("_GlowOffset", 0f); _material.SetFloat("_GlowInner", 0.2f); _material.SetFloat("_GlowOuter", 0.6f); _material.SetFloat("_GlowPower", 0.8f); return _material; } } internal static class ContainerButtons { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnPushPressed; public static UnityAction <1>__OnSortPressed; public static UnityAction <2>__OnCategoriesPressed; public static UnityAction <3>__OnOnlyThesePressed; public static UnityAction <4>__OnGroupPressed; public static UnityAction <5>__OnUndoPressed; } private const float Gap = 6f; private const float Offset = 12f; private const string JoinLabel = "Join below"; private const string LeaveLabel = "Leave group"; private static Button _push; private static Button _sort; private static Button _categories; private static Button _group; private static Button _undo; private static string _groupLabel; internal static float ColumnRight { get; private set; } = 180f; internal static void Ensure() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_006a: 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) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00c3: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_stackAllButton == (Object)null) && !((Object)(object)instance.m_container == (Object)null) && !((Object)(object)_push != (Object)null)) { Rect rect = ((RectTransform)((Component)instance.m_stackAllButton).transform).rect; Vector2 size = ((Rect)(ref rect)).size; ColumnRight = 12f + size.x; object obj = <>O.<0>__OnPushPressed; if (obj == null) { UnityAction val = SortActions.OnPushPressed; <>O.<0>__OnPushPressed = val; obj = (object)val; } _push = Create(instance, size, "ChestSorter_Push", "Push", 0, (UnityAction)obj); object obj2 = <>O.<1>__OnSortPressed; if (obj2 == null) { UnityAction val2 = SortActions.OnSortPressed; <>O.<1>__OnSortPressed = val2; obj2 = (object)val2; } _sort = Create(instance, size, "ChestSorter_Sort", "Sort", 1, (UnityAction)obj2); object obj3 = <>O.<2>__OnCategoriesPressed; if (obj3 == null) { UnityAction val3 = SortActions.OnCategoriesPressed; <>O.<2>__OnCategoriesPressed = val3; obj3 = (object)val3; } _categories = Create(instance, size, "ChestSorter_Categories", "Categories", 2, (UnityAction)obj3); object obj4 = <>O.<3>__OnOnlyThesePressed; if (obj4 == null) { UnityAction val4 = SortActions.OnOnlyThesePressed; <>O.<3>__OnOnlyThesePressed = val4; obj4 = (object)val4; } Create(instance, size, "ChestSorter_OnlyThese", "Only these items", 3, (UnityAction)obj4); object obj5 = <>O.<4>__OnGroupPressed; if (obj5 == null) { UnityAction val5 = SortActions.OnGroupPressed; <>O.<4>__OnGroupPressed = val5; obj5 = (object)val5; } _group = Create(instance, size, "ChestSorter_Group", "Join below", 4, (UnityAction)obj5); object obj6 = <>O.<5>__OnUndoPressed; if (obj6 == null) { UnityAction val6 = SortActions.OnUndoPressed; <>O.<5>__OnUndoPressed = val6; obj6 = (object)val6; } _undo = Create(instance, size, "ChestSorter_Undo", "Undo", 5, (UnityAction)obj6); _groupLabel = "Join below"; } } internal static void Refresh() { if ((Object)(object)_undo != (Object)null) { ((Selectable)_undo).interactable = PushEngine.CanUndo; } if (!((Object)(object)_group == (Object)null) && !((Object)(object)InventoryGui.instance == (Object)null) && InventoryGui.instance.IsContainerOpen()) { string text = (ChestGroups.InGroup(CurrentContainerPatch.Current) ? "Leave group" : "Join below"); if (!(text == _groupLabel)) { UiClone.SetLabel(((Component)_group).gameObject, text); _groupLabel = text; } } } private static Button Create(InventoryGui gui, Vector2 size, string name, string label, int index, UnityAction onClick) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055