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 OrdemDoArtesao v1.0.3
OrdemDoArtesao.dll
Decompiled 15 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("OrdemDoArtesao")] [assembly: AssemblyProduct("Ordem do Artesao")] [assembly: AssemblyCompany("Ordem do Artesao contributors")] [assembly: AssemblyCopyright("Copyright (c) 2026")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3")] [assembly: AssemblyVersion("1.0.3.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 OrdemDoArtesao { internal enum CraftSortMode { Default, NameAscending, NameDescending, Category, Weight } internal enum CraftCategoryFilter { All, Weapons, Armor, Tools, Food, Materials, Other } internal static class CraftingUiController { [CompilerGenerated] private static class <>O { public static UnityAction <0>__NextCategory; public static UnityAction <1>__NextSort; } private const float RowHeight = 30f; private const float RowGap = 5f; private const float QueryDebounceSeconds = 0.12f; private const int MaxQueryLength = 60; private static object _gui; private static GameObject _row; private static Component _input; private static object _categoryLabel; private static object _sortLabel; private static RectTransform _listRect; private static RectTransform _scrollRect; private static Vector2 _originalListOffsetMax; private static Vector2 _originalScrollOffsetMax; private static string _query = string.Empty; private static CraftCategoryFilter _category = CraftCategoryFilter.All; private static CraftSortMode _sort = CraftSortMode.Default; private static bool _refreshing; private static bool _queryRefreshPending; private static float _queryRefreshAt; private static bool _recipeApplyPending; private static object _recipeApplyGui; private static Type _refreshGuiType; private static MethodInfo _refreshMethod; private static object[] _refreshArguments; private static int _creationFailures; internal static bool IsTyping { get { if ((Object)(object)_input == (Object)null) { return false; } return ReflectionTools.GetBool(_input, "isFocused"); } } internal static void Ensure(object gui) { if (gui == null || _creationFailures >= 3 || (_gui == gui && (Object)(object)_row != (Object)null)) { return; } Dispose(); _gui = gui; try { CreateControls(gui); RefreshLabels(); _creationFailures = 0; } catch (Exception ex) { _creationFailures++; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Os controles do crafting nao puderam ser criados nesta versao: " + ex)); } Dispose(); } } internal static void ScheduleRecipeList(object gui) { if (_gui == gui && (_sort != CraftSortMode.Default || _category != CraftCategoryFilter.All || !string.IsNullOrWhiteSpace(_query))) { _recipeApplyGui = gui; _recipeApplyPending = true; } } internal static void ApplyPendingRecipeList() { if (_recipeApplyPending) { object recipeApplyGui = _recipeApplyGui; _recipeApplyPending = false; _recipeApplyGui = null; if (_gui == recipeApplyGui) { RecipeListAdapter.Apply(recipeApplyGui, _sort, _category, _query); } } } internal static void Tick() { if (_queryRefreshPending && _gui != null && !_refreshing && !(Time.unscaledTime < _queryRefreshAt)) { RequestRefresh(); } } internal static void RefreshLabels() { SetText(_categoryLabel, CategoryLabel(_category)); SetText(_sortLabel, SortLabel(_sort)); } internal static void ClearSearch() { _queryRefreshPending = false; if (string.IsNullOrEmpty(_query) && (Object)(object)_input == (Object)null) { return; } _query = string.Empty; if ((Object)(object)_input != (Object)null) { MethodInfo methodInfo = ReflectionTools.FindCompatibleMethod(((object)_input).GetType(), "SetTextWithoutNotify", new object[1] { string.Empty }); if (methodInfo != null) { methodInfo.Invoke(_input, new object[1] { string.Empty }); } else { ReflectionTools.Set(_input, "text", string.Empty); } ReflectionTools.Invoke(_input, "DeactivateInputField"); } } internal static void Dispose() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_listRect != (Object)null) { _listRect.offsetMax = _originalListOffsetMax; } if ((Object)(object)_scrollRect != (Object)null) { _scrollRect.offsetMax = _originalScrollOffsetMax; } if ((Object)(object)_row != (Object)null) { Object.Destroy((Object)(object)_row); } _gui = null; _row = null; _input = null; _categoryLabel = null; _sortLabel = null; _listRect = null; _scrollRect = null; _refreshing = false; _queryRefreshPending = false; _recipeApplyPending = false; _recipeApplyGui = null; _refreshGuiType = null; _refreshMethod = null; _refreshArguments = null; } private static void CreateControls(object gui) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Expected O, but got Unknown //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Expected O, but got Unknown RectTransform val = ReflectionTools.AsRectTransform(ReflectionTools.Get(gui, "m_recipeListRoot")); _listRect = (RectTransform)(((Object)(object)val == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); RectTransform val2 = (RectTransform)(((Object)(object)_listRect == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)_listRect == (Object)null || (Object)(object)val2 == (Object)null) { throw new MissingMemberException("A area da lista de receitas nao foi encontrada."); } _originalListOffsetMax = _listRect.offsetMax; _row = new GameObject("OrdemDoArtesao.CraftingRow", new Type[1] { typeof(RectTransform) }); RectTransform val3 = (RectTransform)_row.transform; ((Transform)val3).SetParent((Transform)(object)val2, false); val3.anchorMin = new Vector2(_listRect.anchorMin.x, _listRect.anchorMax.y); val3.anchorMax = _listRect.anchorMax; val3.pivot = new Vector2(0.5f, 1f); val3.offsetMin = new Vector2(_listRect.offsetMin.x, _listRect.offsetMax.y - 30f); val3.offsetMax = _listRect.offsetMax; _listRect.offsetMax = new Vector2(_listRect.offsetMax.x, _listRect.offsetMax.y - 30f - 5f); _scrollRect = ReflectionTools.AsRectTransform(ReflectionTools.Get(gui, "m_recipeListScroll")); if ((Object)(object)_scrollRect != (Object)null && (Object)(object)((Transform)_scrollRect).parent == (Object)(object)val2) { _originalScrollOffsetMax = _scrollRect.offsetMax; _scrollRect.offsetMax = new Vector2(_scrollRect.offsetMax.x, _scrollRect.offsetMax.y - 30f - 5f); } else { _scrollRect = null; } object font = ReflectionTools.Get(ReflectionTools.Get(gui, "m_recipeName"), "font"); _input = CreateSearchInput(val3, font); SetStretch((RectTransform)_input.transform, 0f, 0.52f, 0f, -4f); GameObject obj = ReflectionTools.AsGameObject(ReflectionTools.Get(gui, "m_stackAllButton")); if ((Object)(object)obj == (Object)null) { throw new MissingMemberException("Botao-base do inventario nao encontrado."); } object obj2 = <>O.<0>__NextCategory; if (obj2 == null) { UnityAction val4 = NextCategory; <>O.<0>__NextCategory = val4; obj2 = (object)val4; } _categoryLabel = CreateButton(obj, val3, "FiltroCategoria", 0.52f, 0.76f, (UnityAction)obj2, ModText.Get("Filtrar receitas por categoria", "Filter recipes by category")); object obj3 = <>O.<1>__NextSort; if (obj3 == null) { UnityAction val5 = NextSort; <>O.<1>__NextSort = val5; obj3 = (object)val5; } _sortLabel = CreateButton(obj, val3, "OrdemReceitas", 0.76f, 1f, (UnityAction)obj3, ModText.Get("Alternar a ordem da lista de receitas", "Change recipe list sorting")); } private static Component CreateSearchInput(RectTransform row, object font) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) Type type = ReflectionTools.FindType("TMPro.TMP_InputField"); Type type2 = ReflectionTools.FindType("TMPro.TextMeshProUGUI"); if (type == null || type2 == null) { throw new TypeLoadException("TextMeshPro nao esta disponivel."); } GameObject val = new GameObject("BuscaReceitas", new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)row, false); Image val3 = val.AddComponent<Image>(); Sprite val4 = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite candidate) => (Object)(object)candidate != (Object)null && ((Object)candidate).name == "text_field")); if ((Object)(object)val4 != (Object)null) { val3.sprite = val4; val3.type = (Type)1; ((Graphic)val3).color = Color.white; } else { ((Graphic)val3).color = new Color(0f, 0f, 0f, 0.68f); } RectTransform component = new GameObject("TextArea", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)val2, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(8f, 2f); component.offsetMax = new Vector2(-8f, -2f); Component value = CreateTmpText(component, type2, "Placeholder", font, ModText.Get("Buscar nome ou ID...", "Search name or ID..."), new Color(0.8529f, 0.725f, 0.5331f, 0.5f), italic: true); Component value2 = CreateTmpText(component, type2, "Text", font, string.Empty, new Color(0.8529f, 0.725f, 0.5331f, 1f), italic: false); Component val5 = val.AddComponent(type); ReflectionTools.Set(val5, "textViewport", component); ReflectionTools.Set(val5, "textComponent", value2); ReflectionTools.Set(val5, "placeholder", value); ReflectionTools.Set(val5, "characterLimit", 60); ReflectionTools.Set(val5, "caretColor", (object)new Color(1f, 0.631f, 0.235f, 1f)); ReflectionTools.Set(val5, "selectionColor", (object)new Color(1f, 0.631f, 0.235f, 0.35f)); ReflectionTools.Set(val5, "targetGraphic", val3); if (font != null) { ReflectionTools.Set(val5, "fontAsset", font); } ReflectionTools.Set(val5, "pointSize", 16f); ReflectionTools.SetEnumProperty(val5, "lineType", "SingleLine"); object obj = ReflectionTools.Get(val5, "onValueChanged"); MethodInfo? obj2 = obj?.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name == "AddListener" && method.GetParameters().Length == 1); if (obj2 == null) { throw new MissingMethodException("TMP_InputField.onValueChanged.AddListener"); } obj2.Invoke(obj, new object[1] { new UnityAction<string>(OnQueryChanged) }); return val5; } private static Component CreateTmpText(RectTransform parent, Type textType, string name, object font, string value, Color color, bool italic) { //IL_0014: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)parent, false); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; Component val3 = val.AddComponent(textType); ReflectionTools.Set(val3, "text", value); ReflectionTools.Set(val3, "fontSize", 16f); ReflectionTools.Set(val3, "color", color); ReflectionTools.Set(val3, "raycastTarget", false); ReflectionTools.Set(val3, "enableWordWrapping", false); if (font != null) { ReflectionTools.Set(val3, "font", font); } ReflectionTools.SetEnumProperty(val3, "alignment", "Left"); ReflectionTools.SetEnumProperty(val3, "overflowMode", "Ellipsis"); if (italic) { ReflectionTools.SetEnumProperty(val3, "fontStyle", "Italic"); } return val3; } private static object CreateButton(GameObject source, RectTransform parent, string name, float minX, float maxX, UnityAction action, string tooltip) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(source, (Transform)(object)parent); ((Object)obj).name = "OrdemDoArtesao." + name; obj.SetActive(true); RemoveLocalization(obj); HideGamepadHints(obj); Transform transform = obj.transform; SetStretch((RectTransform)(object)((transform is RectTransform) ? transform : null), minX, maxX, 2f, -2f); Button component = obj.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { throw new MissingComponentException("Button"); } ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener(action); ((Selectable)component).interactable = true; SetTooltip(obj, tooltip); return FindTmpText(obj); } private static void NextCategory() { Array values = Enum.GetValues(typeof(CraftCategoryFilter)); _category = (CraftCategoryFilter)((int)(_category + 1) % values.Length); RefreshLabels(); RequestRefresh(); } private static void NextSort() { Array values = Enum.GetValues(typeof(CraftSortMode)); _sort = (CraftSortMode)((int)(_sort + 1) % values.Length); RefreshLabels(); RequestRefresh(); } private static void OnQueryChanged(string value) { _query = value ?? string.Empty; _queryRefreshPending = true; _queryRefreshAt = Time.unscaledTime + 0.12f; } private static void RequestRefresh() { _queryRefreshPending = false; if (_gui == null || _refreshing) { return; } _refreshing = true; try { ResolveRefreshMethod(); if (_refreshMethod != null) { _refreshMethod.Invoke(_gui, _refreshArguments); } } finally { _refreshing = false; } } private static void ResolveRefreshMethod() { Type type = _gui.GetType(); if ((object)_refreshGuiType == type) { return; } _refreshGuiType = type; _refreshMethod = (from method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where method.Name == "UpdateCraftingPanel" && method.GetParameters().All((ParameterInfo parameter) => parameter.ParameterType == typeof(bool)) orderby method.GetParameters().Length descending select method).FirstOrDefault(); if (_refreshMethod == null) { _refreshMethod = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name == "UpdateRecipeList"); } _refreshArguments = ((_refreshMethod == null) ? null : (from parameter in _refreshMethod.GetParameters() select (!parameter.ParameterType.IsValueType) ? null : Activator.CreateInstance(parameter.ParameterType)).ToArray()); } private static string CategoryLabel(CraftCategoryFilter category) { return ModText.Category(category); } private static string SortLabel(CraftSortMode mode) { return ModText.Sort(mode); } private static void SetStretch(RectTransform rect, float minX, float maxX, float left, float right) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(minX, 0f); rect.anchorMax = new Vector2(maxX, 1f); rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = new Vector2(left, 0f); rect.offsetMax = new Vector2(right, 0f); ((Transform)rect).localScale = Vector3.one; } internal static object FindTmpText(GameObject root) { Type type = ReflectionTools.FindType("TMPro.TMP_Text"); if (!(type == null)) { return root.GetComponentInChildren(type, true); } return null; } internal static void SetText(object label, string value) { ReflectionTools.Set(label, "text", value); ReflectionTools.Set(label, "fontSize", 14f); } internal static void RemoveLocalization(GameObject root) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Type type = ReflectionTools.FindType("Localize"); if (type == null) { return; } foreach (Object componentsInChild in ReflectionTools.GetComponentsInChildren(root, type)) { Object.DestroyImmediate(componentsInChild); } } internal static void HideGamepadHints(GameObject root) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown foreach (Transform item in root.transform) { Transform val = item; if (((Object)val).name.StartsWith("gamepad_hint", StringComparison.OrdinalIgnoreCase)) { ((Component)val).gameObject.SetActive(false); } } } internal static void SetTooltip(GameObject root, string value) { Type type = ReflectionTools.FindType("UITooltip"); Component val = ((type == null) ? null : root.GetComponent(type)); if ((Object)(object)val != (Object)null) { ReflectionTools.Set(val, "m_text", value); } } } internal static class InventoryButtons { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Predicate<GameObject> <>9__6_0; public static UnityAction <>9__6_1; public static UnityAction <>9__6_2; public static UnityAction <>9__6_3; public static UnityAction <>9__6_4; internal bool <Ensure>b__6_0(GameObject button) { return (Object)(object)button != (Object)null; } internal void <Ensure>b__6_1() { InventoryActions.OrganizeContainer(_gui, OrganizeMode.Alphabetical); } internal void <Ensure>b__6_2() { InventoryActions.OrganizeContainer(_gui, OrganizeMode.Stacks); } internal void <Ensure>b__6_3() { InventoryActions.OrganizePlayer(_gui, OrganizeMode.Alphabetical); } internal void <Ensure>b__6_4() { InventoryActions.OrganizePlayer(_gui, OrganizeMode.Stacks); } } private const float ButtonWidth = 64f; private const float ButtonHeight = 28f; private const float Gap = 4f; private static readonly List<GameObject> Buttons = new List<GameObject>(); private static object _gui; private static int _creationFailures; internal static void Ensure(object gui) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Expected O, but got Unknown //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown if (gui == null || _creationFailures >= 3 || (gui == _gui && Buttons.Count == 4 && Buttons.TrueForAll((GameObject button) => (Object)(object)button != (Object)null))) { return; } Dispose(); _gui = gui; try { GameObject val = ReflectionTools.AsGameObject(ReflectionTools.Get(gui, "m_stackAllButton")); RectTransform val2 = (RectTransform)(((Object)(object)val == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); RectTransform val3 = ReflectionTools.AsRectTransform(ReflectionTools.Get(gui, "m_playerGrid")); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)((Transform)val3).parent == (Object)null) { throw new MissingMemberException("Botoes-base ou grade do jogador nao encontrados."); } Transform parent = ((Transform)val2).parent; Transform parent2 = ((parent is RectTransform) ? parent : null); object obj = <>c.<>9__6_1; if (obj == null) { UnityAction val4 = delegate { InventoryActions.OrganizeContainer(_gui, OrganizeMode.Alphabetical); }; <>c.<>9__6_1 = val4; obj = (object)val4; } GameObject val5 = CloneButton(val, (RectTransform)(object)parent2, "BauAZ", "A-Z", (UnityAction)obj, ModText.Get("Organizar este baú em ordem alfabética", "Sort this chest alphabetically")); Buttons.Add(val5); Transform parent3 = ((Transform)val2).parent; Transform parent4 = ((parent3 is RectTransform) ? parent3 : null); string label = ModText.Get("Pilhas", "Stacks"); object obj2 = <>c.<>9__6_2; if (obj2 == null) { UnityAction val6 = delegate { InventoryActions.OrganizeContainer(_gui, OrganizeMode.Stacks); }; <>c.<>9__6_2 = val6; obj2 = (object)val6; } GameObject val7 = CloneButton(val, (RectTransform)(object)parent4, "BauPilhas", label, (UnityAction)obj2, ModText.Get("Juntar pilhas compatíveis e organizar este baú", "Merge compatible stacks and organize this chest")); Buttons.Add(val7); PlaceBeside(val2, (RectTransform)val5.transform, 0); PlaceBeside(val2, (RectTransform)val7.transform, 1); Transform parent5 = ((Transform)val3).parent; RectTransform parent6 = (RectTransform)(object)((parent5 is RectTransform) ? parent5 : null); object obj3 = <>c.<>9__6_3; if (obj3 == null) { UnityAction val8 = delegate { InventoryActions.OrganizePlayer(_gui, OrganizeMode.Alphabetical); }; <>c.<>9__6_3 = val8; obj3 = (object)val8; } GameObject val9 = CloneButton(val, parent6, "InventarioAZ", "A-Z", (UnityAction)obj3, ModText.Get("Organizar o inventário (preserva atalhos, equipados e slots bloqueados). Alt+L sobre um slot: bloquear/desbloquear", "Organize inventory (preserves hotbar, equipped items and locked slots). Hover a slot and press Alt+L to lock/unlock")); Buttons.Add(val9); string label2 = ModText.Get("Pilhas", "Stacks"); object obj4 = <>c.<>9__6_4; if (obj4 == null) { UnityAction val10 = delegate { InventoryActions.OrganizePlayer(_gui, OrganizeMode.Stacks); }; <>c.<>9__6_4 = val10; obj4 = (object)val10; } GameObject val11 = CloneButton(val, parent6, "InventarioPilhas", label2, (UnityAction)obj4, ModText.Get("Juntar pilhas e organizar (preserva atalhos, equipados e slots bloqueados). Alt+L: bloquear/desbloquear", "Merge stacks and organize (preserves hotbar, equipped items and locked slots). Alt+L: lock/unlock")); Buttons.Add(val11); PlaceAboveGrid(val3, (RectTransform)val9.transform, 1); PlaceAboveGrid(val3, (RectTransform)val11.transform, 0); _creationFailures = 0; } catch (Exception ex) { _creationFailures++; ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Os botoes de organizacao nao puderam ser criados; F6/F7 continuam disponiveis. " + ex)); } Dispose(); } } internal static void Dispose() { foreach (GameObject button in Buttons) { if ((Object)(object)button != (Object)null) { Object.Destroy((Object)(object)button); } } Buttons.Clear(); _gui = null; } private static GameObject CloneButton(GameObject source, RectTransform parent, string name, string label, UnityAction action, string tooltip) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { throw new MissingComponentException("RectTransform pai"); } GameObject obj = Object.Instantiate<GameObject>(source, (Transform)(object)parent); ((Object)obj).name = "OrdemDoArtesao." + name; obj.SetActive(true); obj.transform.SetAsLastSibling(); CraftingUiController.RemoveLocalization(obj); CraftingUiController.HideGamepadHints(obj); CraftingUiController.SetTooltip(obj, tooltip); Button component = obj.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { throw new MissingComponentException("Button"); } ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener(action); ((Selectable)component).interactable = true; CraftingUiController.SetText(CraftingUiController.FindTmpText(obj), label); return obj; } private static void PlaceBeside(RectTransform source, RectTransform button, int index) { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_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_0065: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_00ae: 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_00c3: Unknown result type (might be due to invalid IL or missing references) Rect rect = source.rect; float num; if (!(((Rect)(ref rect)).height > 8f)) { num = 28f; } else { rect = source.rect; num = ((Rect)(ref rect)).height; } float num2 = num; button.anchorMin = source.anchorMin; button.anchorMax = source.anchorMax; button.pivot = new Vector2(0f, source.pivot.y); button.sizeDelta = new Vector2(64f, num2); float x = source.anchoredPosition.x; float num3 = 1f - source.pivot.x; rect = source.rect; float num4 = x + num3 * ((Rect)(ref rect)).width; button.anchoredPosition = new Vector2(num4 + 4f + (float)index * 68f, source.anchoredPosition.y); ((Transform)button).localScale = Vector3.one; } private static void PlaceAboveGrid(RectTransform grid, RectTransform button, int indexFromRight) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a3: 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) Transform parent = ((Transform)grid).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); Vector3[] array = (Vector3[])(object)new Vector3[4]; grid.GetWorldCorners(array); Vector3 val2 = ((Transform)val).InverseTransformPoint(array[2]); button.anchorMin = Vector2.zero; button.anchorMax = Vector2.zero; button.pivot = new Vector2(1f, 0f); button.sizeDelta = new Vector2(64f, 28f); float x = val2.x; Rect rect = val.rect; float num = x - ((Rect)(ref rect)).xMin - (float)indexFromRight * 68f + Plugin.Instance.PlayerButtonsOffsetX.Value; float y = val2.y; rect = val.rect; button.anchoredPosition = new Vector2(num, y - ((Rect)(ref rect)).yMin + Plugin.Instance.PlayerButtonsOffsetY.Value); ((Transform)button).localScale = Vector3.one; } } internal enum OrganizeMode { Alphabetical, Stacks } internal enum ItemCategory { Weapons, Armor, Tools, Food, Materials, Other } internal struct GridPosition { internal readonly int X; internal readonly int Y; internal GridPosition(int x, int y) { X = x; Y = y; } internal int Key(int width) { return Y * width + X; } } internal static class ItemIdentity { private sealed class ItemMetadata { internal static readonly ItemMetadata Empty = new ItemMetadata { NameToken = string.Empty, InternalId = string.Empty, Category = ItemCategory.Other }; internal string NameToken; internal string InternalId; internal ItemCategory Category; internal float Weight; } private static readonly object TypeCacheLock = new object(); private static readonly Dictionary<Type, bool> ItemDataTypeCache = new Dictionary<Type, bool>(); private static readonly ConditionalWeakTable<object, ItemMetadata> MetadataCache = new ConditionalWeakTable<object, ItemMetadata>(); internal static bool IsItemData(object value) { Type type = value?.GetType(); if (type == null) { return false; } lock (TypeCacheLock) { if (ItemDataTypeCache.TryGetValue(type, out var value2)) { return value2; } } Type type2 = type; bool flag = false; while (type2 != null) { if (string.Equals(type2.FullName, "ItemDrop+ItemData", StringComparison.Ordinal)) { flag = true; break; } type2 = type2.BaseType; } lock (TypeCacheLock) { ItemDataTypeCache[type] = flag; return flag; } } internal static string GetNameToken(object item) { return GetMetadata(item).NameToken; } internal static string GetDisplayName(object item) { return LocalizedText.FromToken(GetNameToken(item)); } internal static string GetInternalId(object item) { if (item == null) { return string.Empty; } return GetMetadata(item).InternalId; } internal static ItemCategory GetCategory(object item) { return GetMetadata(item).Category; } internal static string GetCategoryLabel(ItemCategory category) { return ModText.Category(category); } internal static float GetWeight(object item) { return GetMetadata(item).Weight; } internal static string GetTooltipLine(object item) { ItemMetadata metadata = GetMetadata(item); if (string.IsNullOrEmpty(metadata.InternalId)) { return string.Empty; } return "<color=#8F9AA3><size=80%>" + ModText.Get("ID interno: ", "Internal ID: ") + metadata.InternalId + "</size></color>"; } private static ItemMetadata GetMetadata(object item) { if (item != null) { return MetadataCache.GetValue(item, CreateMetadata); } return ItemMetadata.Empty; } private static ItemMetadata CreateMetadata(object item) { object instance = ReflectionTools.Get(item, "m_shared"); string text = (ReflectionTools.Get(instance, "m_name") as string) ?? string.Empty; object obj = ReflectionTools.Get(item, "m_dropPrefab"); GameObject val = ReflectionTools.AsGameObject(obj); string text2 = (((Object)(object)val == (Object)null) ? null : ((Object)val).name); if (string.IsNullOrEmpty(text2) && obj != null) { text2 = ReflectionTools.Get(obj, "name") as string; } text2 = (string.IsNullOrEmpty(text2) ? (string.IsNullOrEmpty(text) ? item.GetType().Name : text.TrimStart(new char[1] { '$' })) : text2.Replace("(Clone)", string.Empty).Trim()); string type = ReflectionTools.Get(instance, "m_itemType")?.ToString() ?? string.Empty; return new ItemMetadata { NameToken = text, InternalId = text2, Category = ParseCategory(type), Weight = ReflectionTools.GetFloat(instance, "m_weight") }; } private static ItemCategory ParseCategory(string type) { switch (type) { case "OneHandedWeapon": case "TwoHandedWeapon": case "Ammo": case "Torch": case "Attach_Atgeir": case "TwoHandedWeaponLeft": case "Bow": case "AmmoNonEquipable": return ItemCategory.Weapons; case "Legs": case "Chest": case "Hands": case "Helmet": case "Shield": case "Shoulder": case "Utility": return ItemCategory.Armor; case "Tool": case "FishingRod": return ItemCategory.Tools; case "Fish": case "Consumable": return ItemCategory.Food; case "Customization": case "Material": case "Trophie": return ItemCategory.Materials; default: return ItemCategory.Other; } } } internal static class InventoryOrganizer { private sealed class SortEntry { internal object Item; internal int OriginalIndex; internal ItemCategory Category; internal string DisplayName; internal string InternalId; internal int Quality; internal int Variant; internal int Stack; } private sealed class StackState { internal object Item; internal int OriginalStack; internal int Stack; internal int MaxStack; } private sealed class ItemSnapshot { internal object Item; internal int Stack; internal object Position; } private sealed class PositionAccessor { internal FieldInfo Field; internal ConstructorInfo Constructor; } private sealed class ChangeNotifier { internal MethodInfo Method; internal object[] Arguments; } private struct MergeResult { internal bool Changed; internal int Emptied; } private static readonly object CacheLock = new object(); private static readonly Dictionary<Type, PositionAccessor> PositionAccessors = new Dictionary<Type, PositionAccessor>(); private static readonly Dictionary<Type, ChangeNotifier> ChangeNotifiers = new Dictionary<Type, ChangeNotifier>(); private static readonly StringComparer DisplayNameComparer = StringComparer.CurrentCultureIgnoreCase; private static readonly StringComparer InternalIdComparer = StringComparer.OrdinalIgnoreCase; internal static bool Organize(object inventory, bool playerInventory, OrganizeMode mode, out string summary) { summary = string.Empty; if (inventory == null) { summary = "inventario ausente"; return false; } IList list = ReflectionTools.AsList(ReflectionTools.Get(inventory, "m_inventory")); if (list == null) { summary = "lista de itens nao encontrada"; return false; } List<object> list2 = new List<object>(list.Count); for (int i = 0; i < list.Count; i++) { if (list[i] != null) { list2.Add(list[i]); } } if (list2.Count == 0) { summary = "inventario vazio"; return true; } int num = ReadDimension(inventory, "GetWidth", 8); int num2 = ReadDimension(inventory, "GetHeight", 4); if (num <= 0 || num2 <= 0) { summary = "dimensoes invalidas"; return false; } HashSet<int> hashSet = new HashSet<int>(); List<object> list3 = new List<object>(list2.Count); Plugin instance = Plugin.Instance; if (playerInventory && (Object)(object)instance != (Object)null && instance.PreserveHotbar.Value) { for (int j = 0; j < num; j++) { hashSet.Add(j); } } if (playerInventory && (Object)(object)instance != (Object)null && instance.PreserveSpecialSlots.Value) { for (int k = SpecialSlotCompatibility.GetSortableRows(num2); k < num2; k++) { for (int l = 0; l < num; l++) { hashSet.Add(k * num + l); } } } if (playerInventory) { SlotLockRegistry.ReserveInside(num, num2, hashSet); } foreach (object item4 in list2) { GridPosition gridPosition = GetGridPosition(item4); bool flag = gridPosition.X < 0 || gridPosition.X >= num || gridPosition.Y < 0 || gridPosition.Y >= num2; bool flag2 = !flag && hashSet.Contains(gridPosition.Key(num)); if (flag || flag2 || (playerInventory && ShouldPreservePlayerItem(item4))) { if (!flag) { hashSet.Add(gridPosition.Key(num)); } } else { list3.Add(item4); } } List<GridPosition> list4 = new List<GridPosition>(Math.Max(0, num * num2 - hashSet.Count)); for (int m = 0; m < num2; m++) { for (int n = 0; n < num; n++) { GridPosition item = new GridPosition(n, m); if (!hashSet.Contains(item.Key(num))) { list4.Add(item); } } } if (list3.Count > list4.Count) { summary = "nao ha posicoes livres suficientes sem mover slots protegidos"; return false; } List<ItemSnapshot> snapshot = CreateSnapshot(list2); MergeResult mergeResult = default(MergeResult); try { if (mode == OrganizeMode.Stacks) { mergeResult = MergeCompatibleStacks(list, list3); } List<SortEntry> list5 = new List<SortEntry>(list3.Count); for (int num3 = 0; num3 < list3.Count; num3++) { object item2 = list3[num3]; list5.Add(new SortEntry { Item = item2, OriginalIndex = num3, Category = ItemIdentity.GetCategory(item2), DisplayName = ItemIdentity.GetDisplayName(item2), InternalId = ItemIdentity.GetInternalId(item2), Quality = GetQuality(item2), Variant = GetVariant(item2), Stack = GetStack(item2) }); } list5.Sort((mode == OrganizeMode.Alphabetical) ? new Comparison<SortEntry>(CompareAlphabetical) : new Comparison<SortEntry>(CompareStacks)); if (list5.Count > list4.Count) { throw new InvalidOperationException("a lista organizada excedeu os slots livres"); } bool flag3 = false; for (int num4 = 0; num4 < list5.Count; num4++) { object item3 = list5[num4].Item; GridPosition position = list4[num4]; GridPosition gridPosition2 = GetGridPosition(item3); if (gridPosition2.X != position.X || gridPosition2.Y != position.Y) { SetGridPosition(item3, position); flag3 = true; } } if (flag3 || mergeResult.Changed) { NotifyChanged(inventory); } summary = ((mode == OrganizeMode.Stacks) ? $"{list5.Count} itens organizados; {mergeResult.Emptied} pilhas esvaziadas" : $"{list5.Count} itens organizados em A-Z"); return true; } catch { Restore(list, snapshot); NotifyChanged(inventory); throw; } } private static bool ShouldPreservePlayerItem(object item) { Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } if (instance.PreserveEquipped.Value) { if (!ReflectionTools.GetBool(item, "m_equiped")) { return ReflectionTools.GetBool(item, "m_equipped"); } return true; } return false; } private static MergeResult MergeCompatibleStacks(IList rawItems, List<object> movable) { Dictionary<string, List<StackState>> dictionary = new Dictionary<string, List<StackState>>(StringComparer.Ordinal); List<StackState> list = new List<StackState>(); foreach (object item in movable) { int maxStack = GetMaxStack(item); if (maxStack > 1 && HasNoCustomData(item)) { StackState stackState = new StackState { Item = item, OriginalStack = GetStack(item), MaxStack = maxStack }; stackState.Stack = stackState.OriginalStack; list.Add(stackState); string key = StackKey(item, maxStack); if (!dictionary.TryGetValue(key, out var value)) { value = new List<StackState>(); dictionary.Add(key, value); } value.Add(stackState); } } bool changed = false; foreach (List<StackState> value2 in dictionary.Values) { if (value2.Count < 2) { continue; } value2.Sort((StackState left, StackState right) => right.Stack.CompareTo(left.Stack)); int num = 0; for (int num2 = value2.Count - 1; num2 > num; num2--) { StackState stackState2 = value2[num2]; while (stackState2.Stack > 0 && num < num2) { StackState stackState3 = value2[num]; int num3 = stackState3.MaxStack - stackState3.Stack; if (num3 <= 0) { num++; continue; } int num4 = Math.Min(num3, stackState2.Stack); stackState3.Stack += num4; stackState2.Stack -= num4; changed = true; } } } HashSet<object> removed = new HashSet<object>(); foreach (StackState item2 in list) { if (item2.Stack != item2.OriginalStack) { SetStack(item2.Item, item2.Stack); } if (item2.Stack <= 0) { removed.Add(item2.Item); } } foreach (object item3 in removed) { rawItems.Remove(item3); } if (removed.Count > 0) { movable.RemoveAll((object item) => removed.Contains(item)); } return new MergeResult { Changed = changed, Emptied = removed.Count }; } private static string StackKey(object item, int maxStack) { return string.Join("|", ItemIdentity.GetInternalId(item), ItemIdentity.GetNameToken(item), GetQuality(item).ToString(CultureInfo.InvariantCulture), GetVariant(item).ToString(CultureInfo.InvariantCulture), maxStack.ToString(CultureInfo.InvariantCulture), ReflectionTools.GetInt(item, "m_worldLevel").ToString(CultureInfo.InvariantCulture), ReflectionTools.Get(item, "m_crafterID")?.ToString() ?? string.Empty, (ReflectionTools.Get(item, "m_crafterName") as string) ?? string.Empty); } private static bool HasNoCustomData(object item) { object obj = ReflectionTools.Get(item, "m_customData"); if (obj == null) { return true; } if (obj is IDictionary dictionary) { return dictionary.Count == 0; } if (ReflectionTools.Get(obj, "Count") is int num) { return num == 0; } return false; } private static int GetMaxStack(object item) { return Math.Max(1, ReflectionTools.GetInt(ReflectionTools.Get(item, "m_shared"), "m_maxStackSize", 1)); } private static int GetStack(object item) { return Math.Max(0, ReflectionTools.GetInt(item, "m_stack", 1)); } private static void SetStack(object item, int amount) { ReflectionTools.Set(item, "m_stack", amount); } private static int GetQuality(object item) { return ReflectionTools.GetInt(item, "m_quality", 1); } private static int GetVariant(object item) { return ReflectionTools.GetInt(item, "m_variant"); } private static int ReadDimension(object inventory, string methodName, int fallback) { try { return (ReflectionTools.Invoke(inventory, methodName) is int num) ? num : fallback; } catch { return fallback; } } private static GridPosition GetGridPosition(object item) { object instance = ReflectionTools.Get(item, "m_gridPos"); return new GridPosition(ReflectionTools.GetInt(instance, "x", -1), ReflectionTools.GetInt(instance, "y", -1)); } private static void SetGridPosition(object item, GridPosition position) { PositionAccessor positionAccessor = GetPositionAccessor(item.GetType()); Type fieldType = positionAccessor.Field.FieldType; object obj; if (positionAccessor.Constructor != null) { obj = positionAccessor.Constructor.Invoke(new object[2] { position.X, position.Y }); } else { obj = Activator.CreateInstance(fieldType); if (!ReflectionTools.Set(obj, "x", position.X) || !ReflectionTools.Set(obj, "y", position.Y)) { throw new MissingFieldException(fieldType.FullName, "x/y"); } } positionAccessor.Field.SetValue(item, obj); } private static void NotifyChanged(object inventory) { ChangeNotifier changeNotifier = GetChangeNotifier(inventory.GetType()); if (changeNotifier.Method != null) { changeNotifier.Method.Invoke(inventory, changeNotifier.Arguments); } else { (ReflectionTools.Get(inventory, "m_onChanged") as Delegate)?.DynamicInvoke(); } } private static List<ItemSnapshot> CreateSnapshot(List<object> items) { List<ItemSnapshot> list = new List<ItemSnapshot>(items.Count); foreach (object item in items) { list.Add(new ItemSnapshot { Item = item, Stack = GetStack(item), Position = ReflectionTools.Get(item, "m_gridPos") }); } return list; } private static void Restore(IList rawItems, List<ItemSnapshot> snapshot) { rawItems.Clear(); foreach (ItemSnapshot item in snapshot) { SetStack(item.Item, item.Stack); GetPositionAccessor(item.Item.GetType()).Field.SetValue(item.Item, item.Position); rawItems.Add(item.Item); } } private static int CompareAlphabetical(SortEntry left, SortEntry right) { int num = DisplayNameComparer.Compare(left.DisplayName, right.DisplayName); if (num != 0) { return num; } num = InternalIdComparer.Compare(left.InternalId, right.InternalId); if (num != 0) { return num; } num = right.Quality.CompareTo(left.Quality); if (num != 0) { return num; } num = left.Variant.CompareTo(right.Variant); if (num != 0) { return num; } num = right.Stack.CompareTo(left.Stack); if (num == 0) { return left.OriginalIndex.CompareTo(right.OriginalIndex); } return num; } private static int CompareStacks(SortEntry left, SortEntry right) { int num = left.Category.CompareTo(right.Category); if (num != 0) { return num; } num = DisplayNameComparer.Compare(left.DisplayName, right.DisplayName); if (num != 0) { return num; } num = InternalIdComparer.Compare(left.InternalId, right.InternalId); if (num != 0) { return num; } num = right.Quality.CompareTo(left.Quality); if (num != 0) { return num; } num = right.Stack.CompareTo(left.Stack); if (num != 0) { return num; } num = left.Variant.CompareTo(right.Variant); if (num == 0) { return left.OriginalIndex.CompareTo(right.OriginalIndex); } return num; } private static PositionAccessor GetPositionAccessor(Type itemType) { lock (CacheLock) { if (PositionAccessors.TryGetValue(itemType, out var value)) { return value; } FieldInfo fieldInfo = ReflectionTools.FindField(itemType, "m_gridPos"); if (fieldInfo == null) { throw new MissingFieldException(itemType.FullName, "m_gridPos"); } PositionAccessor positionAccessor = new PositionAccessor(); positionAccessor.Field = fieldInfo; positionAccessor.Constructor = fieldInfo.FieldType.GetConstructor(new Type[2] { typeof(int), typeof(int) }); PositionAccessor positionAccessor2 = positionAccessor; PositionAccessors[itemType] = positionAccessor2; return positionAccessor2; } } private static ChangeNotifier GetChangeNotifier(Type inventoryType) { lock (CacheLock) { if (ChangeNotifiers.TryGetValue(inventoryType, out var value)) { return value; } MethodInfo methodInfo = null; MethodInfo[] methods = inventoryType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name != "Changed") { continue; } ParameterInfo[] parameters = methodInfo2.GetParameters(); bool flag = true; ParameterInfo[] array = parameters; for (int j = 0; j < array.Length; j++) { if (array[j].ParameterType != typeof(bool)) { flag = false; break; } } if (flag && (methodInfo == null || parameters.Length > methodInfo.GetParameters().Length)) { methodInfo = methodInfo2; } } ChangeNotifier changeNotifier = new ChangeNotifier { Method = methodInfo }; if (methodInfo != null) { changeNotifier.Arguments = new object[methodInfo.GetParameters().Length]; for (int k = 0; k < changeNotifier.Arguments.Length; k++) { changeNotifier.Arguments[k] = false; } } ChangeNotifiers[inventoryType] = changeNotifier; return changeNotifier; } } } internal static class InventoryActions { private static Type _dragGuiType; private static MethodInfo _setupDragItem; private static readonly object[] ClearDragArguments = new object[3] { null, null, 1 }; internal static object GetInventoryGuiInstance() { return ReflectionTools.GetStatic(ReflectionTools.FindType("InventoryGui"), "instance"); } internal static bool IsInventoryVisible() { Type type = ReflectionTools.FindType("InventoryGui"); if (type == null) { return false; } MethodInfo methodInfo = ReflectionTools.FindStaticMethod(type, "IsVisible", 0); if (methodInfo != null) { object obj = methodInfo.Invoke(null, null); if (obj is bool) { return (bool)obj; } } return GetInventoryGuiInstance() != null; } internal static void OrganizePreferred(object gui, OrganizeMode mode) { if (GetCurrentContainer(gui) != null) { OrganizeContainer(gui, mode); } else { OrganizePlayer(gui, mode); } } internal static void OrganizePlayer(object gui, OrganizeMode mode) { if (CanRun(out var player)) { object inventory = ReflectionTools.Invoke(player, "GetInventory"); Run(gui, inventory, playerInventory: true, mode, "inventario"); } } internal static void OrganizeContainer(object gui, OrganizeMode mode) { if (!CanRun(out var _)) { return; } object currentContainer = GetCurrentContainer(gui); if (currentContainer == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"Nenhum bau esta aberto para organizar."); } return; } object obj = ReflectionTools.Invoke(currentContainer, "IsOwner"); if (!(obj is bool) || !(bool)obj) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)"O cliente ainda nao recebeu a posse temporaria deste bau; organizacao ignorada com seguranca."); } } else { object inventory = ReflectionTools.Invoke(currentContainer, "GetInventory"); Run(gui, inventory, playerInventory: false, mode, "bau"); } } internal static object GetCurrentContainer(object gui) { return ReflectionTools.Get(gui, "m_currentContainer"); } private static bool CanRun(out object player) { player = ReflectionTools.GetStatic(ReflectionTools.FindType("Player"), "m_localPlayer"); if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.Enabled.Value || player == null) { return false; } if (ReflectionTools.Invoke(player, "IsTeleporting") is bool flag) { return !flag; } return true; } private static void Run(object gui, object inventory, bool playerInventory, OrganizeMode mode, string target) { try { ClearDraggedItem(gui); if (InventoryOrganizer.Organize(inventory, playerInventory, mode, out var summary)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("Organizacao do " + target + ": " + summary + ".")); } } else { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("O " + target + " nao foi alterado: " + summary + ".")); } } } catch (Exception arg) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogError((object)$"Organizacao do {target} falhou; o estado anterior foi restaurado. {arg}"); } } } private static void ClearDraggedItem(object gui) { if (gui == null || ReflectionTools.Get(gui, "m_dragItem") == null) { return; } Type type = gui.GetType(); if ((object)_dragGuiType != type) { _dragGuiType = type; _setupDragItem = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name == "SetupDragItem" && method.GetParameters().Length == 3); } _setupDragItem?.Invoke(gui, ClearDragArguments); } } internal static class ModText { internal const string Portuguese = "Português"; internal const string English = "English"; internal static bool IsEnglish { get { if ((Object)(object)Plugin.Instance != (Object)null && Plugin.Instance.Language != null) { return Plugin.Instance.Language.Value == "English"; } return false; } } internal static string Get(string portuguese, string english) { if (!IsEnglish) { return portuguese; } return english; } internal static string Category(CraftCategoryFilter category) { return category switch { CraftCategoryFilter.Weapons => Get("Armas", "Weapons"), CraftCategoryFilter.Armor => Get("Armadura", "Armor"), CraftCategoryFilter.Tools => Get("Ferramentas", "Tools"), CraftCategoryFilter.Food => Get("Comida", "Food"), CraftCategoryFilter.Materials => Get("Materiais", "Materials"), CraftCategoryFilter.Other => Get("Outros", "Other"), _ => Get("Todos", "All"), }; } internal static string Category(ItemCategory category) { return category switch { ItemCategory.Weapons => Get("Armas", "Weapons"), ItemCategory.Armor => Get("Armaduras", "Armor"), ItemCategory.Tools => Get("Ferramentas", "Tools"), ItemCategory.Food => Get("Comida/consumíveis", "Food/consumables"), ItemCategory.Materials => Get("Materiais", "Materials"), _ => Get("Outros", "Other"), }; } internal static string Sort(CraftSortMode mode) { return mode switch { CraftSortMode.NameAscending => "A-Z", CraftSortMode.NameDescending => "Z-A", CraftSortMode.Category => Get("Categoria", "Category"), CraftSortMode.Weight => Get("Peso", "Weight"), _ => Get("Padrão", "Default"), }; } } [BepInPlugin("br.gleydson.valheim.ordemdoartesao", "Ordem do Artesao", "1.0.3")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "br.gleydson.valheim.ordemdoartesao"; public const string PluginName = "Ordem do Artesao"; public const string PluginVersion = "1.0.3"; private Harmony _harmony; private bool _languageRefreshPending; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get { if (!((Object)(object)Instance == (Object)null)) { return ((BaseUnityPlugin)Instance).Logger; } return null; } } internal ConfigEntry<bool> Enabled { get; private set; } internal ConfigEntry<string> Language { get; private set; } internal ConfigEntry<bool> ShowInternalId { get; private set; } internal ConfigEntry<bool> PreserveHotbar { get; private set; } internal ConfigEntry<bool> PreserveEquipped { get; private set; } internal ConfigEntry<bool> PreserveSpecialSlots { get; private set; } internal ConfigEntry<string> LockedPlayerSlots { get; private set; } internal ConfigEntry<bool> ClearSearchOnClose { get; private set; } internal ConfigEntry<KeyboardShortcut> OrganizeShortcut { get; private set; } internal ConfigEntry<KeyboardShortcut> StackShortcut { get; private set; } internal ConfigEntry<KeyboardShortcut> ToggleSlotLockShortcut { get; private set; } internal ConfigEntry<float> PlayerButtonsOffsetX { get; private set; } internal ConfigEntry<float> PlayerButtonsOffsetY { get; private set; } private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Instance = this; BindConfiguration(); SlotLockController.Initialize(); MarkGameAsModded(); try { _harmony = new Harmony("br.gleydson.valheim.ordemdoartesao"); int num = InstallPatches(_harmony); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} carregado: {2} metodos conectados. Tudo no cliente, cada item no seu quadrado.", "Ordem do Artesao", "1.0.3", num)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Nao foi possivel iniciar os recursos de interface. " + ex)); try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } _harmony = null; } } private void Update() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (Enabled == null || !Enabled.Value) { return; } if (_languageRefreshPending) { _languageRefreshPending = false; RefreshLocalizedInterface(); } try { CraftingUiController.Tick(); SlotLockController.Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogDebug((object)("Atualizacao adiada da interface falhou: " + ex.Message)); } KeyboardShortcut value = ToggleSlotLockShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !CraftingUiController.IsTyping) { try { if (InventoryActions.IsInventoryVisible()) { SlotLockController.ToggleHoveredSlot(); } return; } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Nao foi possivel alternar a trava deste slot: " + ex2.Message)); return; } } value = OrganizeShortcut.Value; bool flag = ((KeyboardShortcut)(ref value)).IsDown(); int num; if (!flag) { value = StackShortcut.Value; num = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0); } else { num = 0; } bool flag2 = (byte)num != 0; if (!flag && !flag2) { return; } try { if (InventoryActions.IsInventoryVisible()) { InventoryActions.OrganizePreferred(InventoryActions.GetInventoryGuiInstance(), (!flag) ? OrganizeMode.Stacks : OrganizeMode.Alphabetical); } } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Atalho de organizacao falhou sem alterar mais itens: " + ex3.Message)); } } private void OnDestroy() { try { if (Language != null) { Language.SettingChanged -= OnLanguageChanged; } CraftingUiController.Dispose(); InventoryButtons.Dispose(); SlotLockController.Dispose(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } finally { _harmony = null; Instance = null; } } private void LateUpdate() { if (Enabled == null || !Enabled.Value) { return; } try { CraftingUiController.ApplyPendingRecipeList(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Filtro adiado de receitas falhou sem afetar o inventario: " + ex.Message)); } } private void BindConfiguration() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) Language = ((BaseUnityPlugin)this).Config.Bind<string>("Geral", "Idioma / Language", "Português", new ConfigDescription("Idioma dos textos do mod. / Language used by the mod interface.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Português", "English" }), Array.Empty<object>())); Language.SettingChanged += OnLanguageChanged; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Geral", "Ativado", true, "Ativa as ferramentas de interface, busca e organizacao. / Enables the UI, search and organization tools."); ShowInternalId = ((BaseUnityPlugin)this).Config.Bind<bool>("Geral", "MostrarIdInterno", true, "Mostra o nome interno/prefab do item ao final do tooltip."); PreserveHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("Organizacao", "PreservarBarraRapida", true, "Nao move os oito atalhos da primeira linha ao organizar o inventario do jogador."); PreserveEquipped = ((BaseUnityPlugin)this).Config.Bind<bool>("Organizacao", "PreservarEquipados", true, "Nao move itens marcados como equipados ao organizar o inventario do jogador."); PreserveSpecialSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("Organizacao", "PreservarSlotsEspeciais", true, "Protege as areas de equipamento e atalhos do Equipment and Quick Slots, inclusive quando vazias."); LockedPlayerSlots = ((BaseUnityPlugin)this).Config.Bind<string>("Organizacao", "SlotsBloqueados", string.Empty, "Coordenadas dos slots bloqueados pelo jogador. Edite no jogo com o atalho BloquearSlot."); ClearSearchOnClose = ((BaseUnityPlugin)this).Config.Bind<bool>("Crafting", "LimparBuscaAoFechar", true, "Limpa o texto de busca quando a janela do inventario e fechada."); OrganizeShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Atalhos", "OrganizarAZ", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Organiza o bau aberto; sem bau aberto, organiza o inventario. Use KeyCode.None para desativar."); StackShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Atalhos", "JuntarPilhas", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Junta pilhas compativeis e organiza o bau aberto; sem bau aberto, usa o inventario."); ToggleSlotLockShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Atalhos", "BloquearSlot", new KeyboardShortcut((KeyCode)108, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Com o inventario aberto, passe o mouse sobre um slot e use este atalho para bloquear/desbloquear."); PlayerButtonsOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Interface", "BotoesInventarioX", 0f, "Ajuste horizontal dos botoes A-Z/Pilhas do inventario."); PlayerButtonsOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Interface", "BotoesInventarioY", 4f, "Ajuste vertical dos botoes A-Z/Pilhas do inventario."); } private void OnLanguageChanged(object sender, EventArgs eventArgs) { _languageRefreshPending = true; } private static void RefreshLocalizedInterface() { object inventoryGuiInstance = InventoryActions.GetInventoryGuiInstance(); CraftingUiController.Dispose(); InventoryButtons.Dispose(); if (inventoryGuiInstance != null && InventoryActions.IsInventoryVisible()) { CraftingUiController.Ensure(inventoryGuiInstance); InventoryButtons.Ensure(inventoryGuiInstance); } } private static void MarkGameAsModded() { try { Type type = ReflectionTools.FindType("Game"); ((type == null) ? null : AccessTools.Field(type, "isModded"))?.SetValue(null, true); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Nao foi necessario/possivel marcar Game.isModded: " + ex.Message)); } } } private static int InstallPatches(Harmony harmony) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Expected O, but got Unknown Type type = RequireType("InventoryGui"); int num = 0; num += PatchAllNamed(harmony, type, "Awake", null, "InventoryGuiAwakePostfix"); num += PatchAllNamed(harmony, type, "Show", null, "InventoryGuiShowPostfix"); num += PatchAllNamed(harmony, type, "Hide", "InventoryGuiHidePrefix", null); num += PatchAllNamed(harmony, type, "UpdateRecipeList", null, "UpdateRecipeListPostfix"); Type type2 = ReflectionTools.FindType("Chat"); if (type2 != null) { num += PatchAllNamed(harmony, type2, "HasFocus", null, "ChatHasFocusPostfix"); } Type itemData = RequireType("ItemDrop+ItemData"); List<MethodInfo> source = (from candidate in AccessTools.GetDeclaredMethods(itemData) where candidate.Name == "GetTooltip" && candidate.ReturnType == typeof(string) select candidate).ToList(); List<MethodInfo> list = source.Where((MethodInfo method) => method.IsStatic && method.GetParameters().Length != 0 && itemData.IsAssignableFrom(method.GetParameters()[0].ParameterType)).ToList(); IEnumerable<MethodInfo> enumerable; if (list.Count <= 0) { enumerable = source.Where((MethodInfo method) => !method.IsStatic); } else { IEnumerable<MethodInfo> enumerable2 = list; enumerable = enumerable2; } foreach (MethodInfo item in enumerable) { HarmonyMethod val = new HarmonyMethod(typeof(Plugin), item.IsStatic ? "StaticTooltipPostfix" : "InstanceTooltipPostfix", (Type[])null); harmony.Patch((MethodBase)item, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); num++; } return num; } private static int PatchAllNamed(Harmony harmony, Type type, string methodName, string prefixName, string postfixName) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) List<MethodInfo> list = (from method in AccessTools.GetDeclaredMethods(type) where method.Name == methodName select method).ToList(); if (list.Count == 0) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Metodo opcional " + type.Name + "." + methodName + " nao foi encontrado.")); } return 0; } HarmonyMethod val = ((prefixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), prefixName, (Type[])null)); HarmonyMethod val2 = ((postfixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), postfixName, (Type[])null)); foreach (MethodInfo item in list) { harmony.Patch((MethodBase)item, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } return list.Count; } private static Type RequireType(string name) { Type type = ReflectionTools.FindType(name); if (type == null) { throw new TypeLoadException("Tipo do Valheim nao encontrado: " + name); } return type; } private static void InventoryGuiAwakePostfix(object __instance) { SafeUi(delegate { LocalizedText.ClearCache(); CraftingUiController.Ensure(__instance); InventoryButtons.Ensure(__instance); SlotLockController.Ensure(__instance); }, "criacao dos controles"); } private static void InventoryGuiShowPostfix(object __instance) { SafeUi(delegate { CraftingUiController.Ensure(__instance); InventoryButtons.Ensure(__instance); CraftingUiController.RefreshLabels(); SlotLockController.Ensure(__instance); }, "abertura do inventario"); } private static void InventoryGuiHidePrefix() { if ((Object)(object)Instance != (Object)null && Instance.ClearSearchOnClose.Value) { SafeUi(CraftingUiController.ClearSearch, "limpeza da busca"); } } private static void UpdateRecipeListPostfix(object __instance) { if (!((Object)(object)Instance == (Object)null) && Instance.Enabled.Value) { CraftingUiController.ScheduleRecipeList(__instance); } } private static void ChatHasFocusPostfix(ref bool __result) { if (!__result && CraftingUiController.IsTyping) { __result = true; } } private static void InstanceTooltipPostfix(object __instance, ref string __result) { AppendInternalId(__instance, ref __result); } private static void StaticTooltipPostfix(object[] __args, ref string __result) { AppendInternalId((__args != null && __args.Length != 0) ? __args[0] : null, ref __result); } private static void AppendInternalId(object item, ref string tooltip) { if ((Object)(object)Instance == (Object)null || !Instance.Enabled.Value || !Instance.ShowInternalId.Value || item == null || (!string.IsNullOrEmpty(tooltip) && (tooltip.IndexOf("ID interno:", StringComparison.Ordinal) >= 0 || tooltip.IndexOf("Internal ID:", StringComparison.Ordinal) >= 0))) { return; } try { string tooltipLine = ItemIdentity.GetTooltipLine(item); if (!string.IsNullOrEmpty(tooltipLine)) { tooltip = (string.IsNullOrEmpty(tooltip) ? tooltipLine : (tooltip + "\n" + tooltipLine)); } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Nao foi possivel acrescentar o ID interno: " + ex.Message)); } } } private static void SafeUi(Action action, string operation) { try { action(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("Falha isolada na " + operation + ": " + ex.Message)); } } } } internal static class RecipeListAdapter { private sealed class RecipeEntry { internal object Pair; internal object Item; internal GameObject InterfaceElement; internal int OriginalIndex; internal ItemCategory Category; internal string DisplayName; internal string InternalId; internal string NameToken; internal float Weight; internal bool CanCraft; internal int Quality; } private static readonly CompareInfo SearchComparer = CultureInfo.InvariantCulture.CompareInfo; private static readonly StringComparer NameComparer = StringComparer.CurrentCultureIgnoreCase; internal static void Apply(object gui, CraftSortMode sort, CraftCategoryFilter category, string query) { string text = (string.IsNullOrWhiteSpace(query) ? string.Empty : query.Trim()); bool flag = text.Length > 0; bool flag2 = category != CraftCategoryFilter.All; bool flag3 = sort != CraftSortMode.Default; if (!flag && !flag2 && !flag3) { return; } IList list = ReflectionTools.AsList(ReflectionTools.Get(gui, "m_availableRecipes")); if (list == null || list.Count == 0) { return; } List<RecipeEntry> list2 = new List<RecipeEntry>(list.Count); for (int i = 0; i < list.Count; i++) { list2.Add(CreateEntry(list[i], i, flag || flag3, flag, flag3, sort == CraftSortMode.Weight)); } List<RecipeEntry> list3 = new List<RecipeEntry>(list2.Count); foreach (RecipeEntry item in list2) { if (Matches(item, category, text)) { list3.Add(item); } else if ((Object)(object)item.InterfaceElement != (Object)null) { Object.Destroy((Object)(object)item.InterfaceElement); } } if (flag3) { Sort(list3, sort); } if (HasSameOrder(list2, list3)) { return; } list.Clear(); foreach (RecipeEntry item2 in list3) { list.Add(item2.Pair); } Relayout(gui, list3); } private static RecipeEntry CreateEntry(object pair, int index, bool readDisplayName, bool readSearchFields, bool readRankFields, bool readWeight) { object itemData = GetItemData(pair); ItemCategory category = ((itemData == null) ? ItemCategory.Other : ItemIdentity.GetCategory(itemData)); return new RecipeEntry { Pair = pair, Item = itemData, InterfaceElement = ReflectionTools.AsGameObject(GetPairMember(pair, "InterfaceElement")), OriginalIndex = index, Category = category, DisplayName = ((itemData != null && readDisplayName) ? ItemIdentity.GetDisplayName(itemData) : string.Empty), InternalId = ((itemData != null && readSearchFields) ? ItemIdentity.GetInternalId(itemData) : string.Empty), NameToken = ((itemData != null && readSearchFields) ? ItemIdentity.GetNameToken(itemData) : string.Empty), Weight = ((itemData != null && readWeight) ? ItemIdentity.GetWeight(itemData) : 0f), CanCraft = (readRankFields && ReadCanCraft(pair)), Quality = ((!(itemData != null && readRankFields)) ? 1 : ReflectionTools.GetInt(itemData, "m_quality", 1)) }; } private static bool Matches(RecipeEntry entry, CraftCategoryFilter filter, string query) { if (entry.Item == null) { if (filter == CraftCategoryFilter.All) { return query.Length == 0; } return false; } if (!MatchesCategory(entry.Category, filter)) { return false; } if (query.Length == 0) { return true; } if (!Contains(entry.DisplayName, query, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) && !Contains(entry.InternalId, query, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) && !Contains(entry.NameToken, query, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace)) { return Contains(ItemIdentity.GetCategoryLabel(entry.Category), query, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace); } return true; } private static bool Contains(string value, string query, CompareOptions options) { if (!string.IsNullOrEmpty(value)) { return SearchComparer.IndexOf(value, query, options) >= 0; } return false; } private static bool MatchesCategory(ItemCategory category, CraftCategoryFilter filter) { return filter switch { CraftCategoryFilter.Weapons => category == ItemCategory.Weapons, CraftCategoryFilter.Armor => category == ItemCategory.Armor, CraftCategoryFilter.Tools => category == ItemCategory.Tools, CraftCategoryFilter.Food => category == ItemCategory.Food, CraftCategoryFilter.Materials => category == ItemCategory.Materials, CraftCategoryFilter.Other => category == ItemCategory.Other, _ => true, }; } private static void Sort(List<RecipeEntry> entries, CraftSortMode mode) { entries.Sort((RecipeEntry left, RecipeEntry right) => CompareEntries(left, right, mode)); } private static int CompareEntries(RecipeEntry left, RecipeEntry right, CraftSortMode mode) { int num = 0; switch (mode) { case CraftSortMode.Category: num = left.Category.CompareTo(right.Category); break; case CraftSortMode.Weight: num = left.Weight.CompareTo(right.Weight); break; } if (num != 0) { return num; } num = ((mode == CraftSortMode.NameDescending) ? NameComparer.Compare(right.DisplayName, left.DisplayName) : NameComparer.Compare(left.DisplayName, right.DisplayName)); if (num != 0) { return num; } num = right.CanCraft.CompareTo(left.CanCraft); if (num != 0) { return num; } num = right.Quality.CompareTo(left.Quality); if (num == 0) { return left.OriginalIndex.CompareTo(right.OriginalIndex); } return num; } private static bool HasSameOrder(IList<RecipeEntry> original, IList<RecipeEntry> visible) { if (original.Count != visible.Count) { return false; } for (int i = 0; i < original.Count; i++) { if (!object.Equals(original[i].Pair, visible[i].Pair)) { return false; } } return true; } private static void Relayout(object gui, IList<RecipeEntry> entries) { //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_0054: Unknown result type (might be due to invalid IL or missing references) float num = ReflectionTools.GetFloat(gui, "m_recipeListSpace", 64f); for (int i = 0; i < entries.Count; i++) { GameObject interfaceElement = entries[i].InterfaceElement; RectTransform val = (RectTransform)(((Object)(object)interfaceElement == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val != (Object)null) { val.anchoredPosition = new Vector2(0f, (float)i * (0f - num)); } } RectTransform val2 = ReflectionTools.AsRectTransform(ReflectionTools.Get(gui, "m_recipeListRoot")); if (!((Object)(object)val2 == (Object)null)) { Rect rect = val2.rect; float num2 = ReflectionTools.GetFloat(gui, "m_recipeListBaseSize", ((Rect)(ref rect)).height); val2.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(num2, (float)entries.Count * num)); } } private static object GetItemData(object pair) { object pairMember = GetPairMember(pair, "ItemData"); if (pairMember != null) { return pairMember; } return ReflectionTools.Get(ReflectionTools.Get(GetPairMember(pair, "Recipe"), "m_item"), "m_itemData"); } private static object GetPairMember(object pair, string name) { return ReflectionTools.Get(pair, name); } private static bool ReadCanCraft(object pair) { object pairMember = GetPairMember(pair, "CanCraft"); bool flag = default(bool); int num; if (pairMember is bool) { flag = (bool)pairMember; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } internal static class ReflectionTools { private struct MemberKey : IEquatable<MemberKey> { private readonly Type _type; private readonly string _name; private readonly bool _isStatic; internal MemberKey(Type type, string name, bool isStatic) { _type = type; _name = name; _isStatic = isStatic; } public bool Equals(MemberKey other) { if ((object)_type == other._type && _isStatic == other._isStatic) { return string.Equals(_name, other._name, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is MemberKey other) { return Equals(other); } return false; } public override int GetHashCode() { int num = ((((!(_type == null)) ? _type.GetHashCode() : 0) * 397) ^ ((_name != null) ? _name.GetHashCode() : 0)) * 397; bool isStatic = _isStatic; return num ^ isStatic.GetHashCode(); } } private struct MethodKey : IEquatable<MethodKey> { private readonly Type _type; private readonly string _name; private readonly int _parameterCount; private readonly bool _isStatic; internal MethodKey(Type type, string name, int parameterCount, bool isStatic) { _type = type; _name = name; _parameterCount = parameterCount; _isStatic = isStatic; } public bool Equals(MethodKey other) { if ((object)_type == other._type && _parameterCount == other._parameterCount && _isStatic == other._isStatic) { return string.Equals(_name, other._name, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is MethodKey other) { return Equals(other); } return false; } public override int GetHashCode() { int num = ((((((!(_type == null)) ? _type.GetHashCode() : 0) * 397) ^ ((_name != null) ? _name.GetHashCode() : 0)) * 397) ^ _parameterCount) * 397; bool isStatic = _isStatic; return num ^ isStatic.GetHashCode(); } } internal const BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal const BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly object CacheLock = new object(); private static readonly Dictionary<MemberKey, FieldInfo> FieldCache = new Dictionary<MemberKey, FieldInfo>(); private static readonly Dictionary<MemberKey, PropertyInfo> PropertyCache = new Dictionary<MemberKey, PropertyInfo>(); private static readonly Dictionary<MethodKey, MethodInfo> MethodCache = new Dictionary<MethodKey, MethodInfo>(); private static readonly Dictionary<string, Type> TypeCache = new Dictionary<string, Type>(StringComparer.Ordinal); internal static Type FindType(string name) { if (string.IsNullOrEmpty(name)) { return null; } lock (CacheLock) { if (TypeCache.TryGetValue(name, out var value)) { return value; } } Type type = AccessTools.TypeByName(name); if (type != null) { lock (CacheLock) { TypeCache[name] = type; } } return type; } internal static FieldInfo FindField(Type type, string name) { return FindField(type, name, isStatic: false); } internal static PropertyInfo FindProperty(Type type, string name) { return FindProperty(type, name, isStatic: false); } internal static object Get(object instance, string name) { if (instance == null) { return null; } Type type = instance.GetType(); FieldInfo fieldInfo = FindField(type, name, isStatic: false); if (fieldInfo != null) { return fieldInfo.GetValue(instance); } PropertyInfo propertyInfo = FindProperty(type, name, isStatic: false); if (!(propertyInfo == null)) { return propertyInfo.GetValue(instance, null); } return null; } internal static T Get<T>(object instance, string name, T fallback = default(T)) { object obj = Get(instance, name); if (obj is T) { return (T)obj; } try { return (obj == null) ? fallback : ((T)Convert.ChangeType(obj, typeof(T))); } catch { return fallback; } } internal static bool Set(object instance, string name, object value) { if (instance == null) { return false; } Type type = instance.GetType(); FieldInfo fieldInfo = FindField(type, name, isStatic: false); if (fieldInfo != null) { fieldInfo.SetValue(instance, value); return true; } PropertyInfo propertyInfo = FindProperty(type, name, isStatic: false); if (propertyInfo != null && propertyInfo.CanWrite) { propertyInfo.SetValue(instance, value, null); return true; } return false; } internal static object GetStatic(Type type, string name) { if (type == null) { return null; } FieldInfo fieldInfo = FindField(type, name, isStatic: true); if (fieldInfo != null) { return fieldInfo.GetValue(null); } PropertyInfo propertyInfo = FindProperty(type, name, isStatic: true); if (!(propertyInfo == null)) { return propertyInfo.GetValue(null, null); } return null; } internal static MethodInfo FindMethod(Type type, string name, int? parameterCount = null) { return FindMethod(type, name, parameterCount, isStatic: false); } internal static MethodInfo FindStaticMethod(Type type, string name, int? parameterCount = null) { return FindMethod(type, name, parameterCount, isStatic: true); } internal static object Invoke(object instance, string name, params object[] arguments) { if (instance == null) { return null; } object[] array = arguments ?? Array.Empty<object>(); MethodInfo methodInfo = ((array.Length == 0) ? FindMethod(instance.GetType(), name, 0) : FindCompatibleMethod(instance.GetType(), name, array)); if (!(methodInfo == null)) { return methodInfo.Invoke(instance, array); } return null; } internal static MethodInfo FindCompatibleMethod(Type type, string name, object[] arguments) { while (type != null) { foreach (MethodInfo item in from candidate in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where candidate.Name == name select candidate) { ParameterInfo[] parameters = item.GetParameters(); if (parameters.Length != arguments.Length) { continue; } bool flag = true; for (int num = 0; num < parameters.Length; num++) { object obj = arguments[num]; if (obj == null) { if (parameters[num].ParameterType.IsValueType && Nullable.GetUnderlyingType(parameters[num].ParameterType) == null) { flag = false; break; } } else if (!parameters[num].ParameterType.IsInstanceOfType(obj) && !CanNumericConvert(obj.GetType(), parameters[num].ParameterType)) { flag = false; break; } } if (flag) { return item; } } type = type.BaseType; } return null; } internal static GameObject AsGameObject(object value) { GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null) { return val; } Component val2 = (Component)((value is Component) ? value : null); if (val2 != null) { return val2.gameObject; } return null; } internal static RectTransform AsRectTransform(object value) { GameObject val = AsGameObject(value); if (!((Object)(object)val == (Object)null)) { Transform transform = val.transform; return (RectTransform)(object)((transform is RectTransform) ? transform : null); } return (RectTransform)((value is RectTransform) ? value : null); } internal static IList AsList(object value) { return value as IList; } internal static int GetInt(object instance, string name, int fallback = 0) { object obj = Get(instance, name); if (obj is int) { return (int)obj; } return fallback; } internal static float GetFloat(object instance, string name, float fallback = 0f) { object obj = Get(instance, name); if (obj is float) { return (float)obj; } if (!(obj is double num)) { return fallback; } return (float)num; } internal static bool GetBool(object instance, string name, bool fallback = false) { object obj = Get(instance, name); if (obj is bool) { return (bool)obj; } return fallback; } internal static IEnumerable<object> GetComponentsInChildren(GameObject root, Type type) { if ((Object)(object)root == (Object)null || type == null) { return Enumerable.Empty<object>(); } return root.GetComponentsInChildren(type, true).Cast<object>(); } internal static void SetEnumProperty(object instance, string propertyName, string enumName) { PropertyInfo propertyInfo = ((instance == null) ? null : FindProperty(instance.GetType(), propertyName)); if (propertyInfo == null || !propertyInfo.CanWrite || !propertyInfo.PropertyType.IsEnum) { return; } try { propertyInfo.SetValue(instance, Enum.Parse(propertyInfo.PropertyType, enumName, ignoreCase: true), null); } catch { } } private static FieldInfo FindField(Type type, string name, bool isStatic) { if (type == null || string.IsNullOrEmpty(name)) { return null; } MemberKey key = new MemberKey(type, name, isStatic); lock (CacheLock) { if (FieldCache.TryGetValue(key, out var value)) { return value; } } BindingFlags bindingAttr = (BindingFlags)((isStatic ? 56 : 52) | 2); Type type2 = type; FieldInfo fieldInfo = null; while (type2 != null && fieldInfo == null) { fieldInfo = type2.GetField(name, bindingAttr); type2 = type2.BaseType; } lock (CacheLock) { FieldCache[key] = fieldInfo; return fieldInfo; } } private static PropertyInfo FindProperty(Type type, string name, bool isStatic) { if (type == null || string.IsNullOrEmpty(name)) { return null; } MemberKey key = new MemberKey(type, name, isStatic); lock (CacheLock) { if (PropertyCache.TryGetValue(key, out var value)) { return value; } } BindingFlags bindingAttr = (BindingFlags)((isStatic ? 56 : 52) | 2); Type type2 = type; PropertyInfo propertyInfo = null; while (type2 != null && propertyInfo == null) { propertyInfo = type2.GetProperty(name, bindingAttr); type2 = type2.BaseType; } lock (CacheLock) { PropertyCache[key] = propertyInfo; return propertyInfo; } } private static MethodInfo FindMethod(Type type, string name, int? parameterCount, bool isStatic) { if (type == null || string.IsNullOrEmpty(name)) { return null; } MethodKey key = new MethodKey(type, name, parameterCount ?? (-1), isStatic); lock (CacheLock) { if (MethodCache.TryGetValue(key, out var value)) { return value; } } BindingFlags bindingAttr = (BindingFlags)((isStatic ? 56 : 52) | 2); Type type2 = type; MethodInfo methodInfo = null; while (type2 != null && methodInfo == null) { methodInfo = type2.GetMethods(bindingAttr).FirstOrDefault((MethodInfo candidate) => candidate.Name == name && (!parameterCount.HasValue || candidate.GetParameters().Length == parameterCount.Value)); type2 = type2.BaseType; } lock (CacheLock) { MethodCache[key] = methodInfo; return methodInfo; } } private static bool CanNumericConvert(Type from, Type to) { TypeCode typeCode = Type.GetTypeCode(from); TypeCode typeCode2 = Type.GetTypeCode(to); if (typeCode >= TypeCode.SByte && typeCode <= TypeCode.Decimal && typeCode2 >= TypeCode.SByte) { return typeCode2 <= TypeCode.Decimal; } return false; } } internal static class LocalizedText { private static readonly object CacheLock = new object(); private static readonly Dictionary<string, string> Cache = new Dictionary<string, string>(StringComparer.Ordinal); private static object _localization; private static MethodInfo _localize; internal static string FromToken(string token) { if (string.IsNullOrEmpty(token)) { return string.Empty; } lock (CacheLock) { if (Cache.TryGetValue(token, out var value)) { return value; } try { object obj = ReflectionTools.GetStatic(ReflectionTools.FindType("Localization"), "instance"); if (obj == null) { return token; } if (_localization != obj) { Cache.Clear(); _localization = obj; _localize = ReflectionTools.FindCompatibleMethod(obj.GetType(), "Localize", new object[1] { token }); } object obj2 = _localize?.Invoke(obj, new object[1] { token }); string text = (string.IsNullOrEmpty(obj2 as string) ? token : ((string)obj2)); Cache[token] = text; return text; } catch { return token; } } } internal static void ClearCache() { lock (CacheLock) { Cache.Clear(); _localization = null; _localize = null; } } } internal static class SlotLockController { private const string MarkerName = "OrdemDoArtesao.SlotBloqueado"; private static readonly List<GameObject> Markers = new List<GameObject>(); private static object _gui; private static bool _refreshPending; private static int _refreshFrame; internal static void Initialize() { SlotLockRegistry.Load(Plugin.Instance?.LockedPlayerSlots?.Value); } internal static void Ensure(object gui) { if (gui != null) { if (_gui != gui) { DestroyMarkers(); _gui = gui; } _refreshPending = SlotLockRegistry.Count > 0; _refreshFrame = Time.frameCount + 1; } } internal static void Tick() { if (_refreshPending && Time.frameCount >= _refreshFrame) { _refreshPending = false; RefreshMarkers(); } } internal static bool ToggleHoveredSlot() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if (_gui == null) { _gui = InventoryActions.GetInventoryGuiInstance(); } if (!TryGetGrid(_gui, out var elements, out var width, out var rows)) { return false; } Vector2 val = Vector2.op_Implicit(Input.mousePosition); int num = Math.Min(elements.Count, width * rows); for (int i = 0; i < num; i++) { GameObject val2 = ReflectionTools.AsGameObject(elements[i]); RectTransform val3 = (RectTransform)(((Object)(object)val2 == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if (!((Object)(object)val2 == (Object)null) && val2.activeInHierarchy && !((Object)(object)val3 == (Object)null) && RectTransformUtility.RectangleContainsScreenPoint(val3, val)) { int num2 = i % width; int num3 = i / width; bool flag = SlotLockRegistry.Toggle(num2, num3); if (Plugin.Instance?.LockedPlayerSlots != null) { Plugin.Instance.LockedPlayerSlots.Value = SlotLockRegistry.Serialize(); } RefreshMarkers(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)string.Format("Slot ({0}, {1}) {2}. A organizacao {3}.", num2 + 1, num3 + 1, flag ? "bloqueado" : "desbloqueado", flag ? "nao tocara nele" : "voltara a usa-lo")); } return true; } } return false; } internal static void Dispose() { DestroyMarkers(); _gui = null; _refreshPending = false; } private static void RefreshMarkers() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) DestroyMarkers(); if (SlotLockRegistry.Count == 0 || !TryGetGrid(_gui, out var elements, out var width, out var rows)) { return; } int num = Math.Min(elements.Count, width * rows); for (int i = 0; i < num; i++) { int x = i % width; int y = i / width; if (SlotLockRegistry.IsLocked(x, y)) { GameObject val = ReflectionTools.AsGameObject(elements[i]); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("OrdemDoArtesao.SlotBloqueado", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val3 = (RectTransform)val2.transform;