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 CraftingSort v0.2.2
CraftingSort.dll
Decompiled 12 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CraftingSort")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.2.0")] [assembly: AssemblyInformationalVersion("0.2.2")] [assembly: AssemblyProduct("CraftingSort")] [assembly: AssemblyTitle("CraftingSort")] [assembly: AssemblyVersion("0.2.2.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 CraftingSort { [BepInPlugin("com.skyowner.craftingsort", "CraftingSort", "0.2.2")] [BepInDependency("seneaL.valheim.ui", "1.1.6")] public sealed class Plugin : BaseUnityPlugin { private sealed class ViewState { public readonly Dictionary<object, int> Original = new Dictionary<object, int>(); public bool Rebuilding; public RectTransform Button; public TextMeshProUGUI Label; public int LabelMode = -1; public bool LabelRussian; } private sealed class Entry { public object Row; public int Rank; public int Tier; public string Material; public string Name; } private static ConfigEntry<int> Mode; private static readonly ConditionalWeakTable<object, ViewState> States = new ConditionalWeakTable<object, ViewState>(); private static Type View; private static WeakReference<object> CurrentView; private Harmony harmony; private static object Field(object obj, string name) { return AccessTools.Field(obj.GetType(), name).GetValue(obj); } private void Awake() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown if (!Chainloader.PluginInfos.TryGetValue("seneaL.valheim.ui", out var value) || (value.Metadata.Version != new Version(1, 1, 6) && value.Metadata.Version != new Version(1, 1, 7))) { ((BaseUnityPlugin)this).Logger.LogError((object)"CraftingSort 0.2.2 requires SeneaL UI 1.1.6 or 1.1.7; addon disabled."); return; } Mode = ((BaseUnityPlugin)this).Config.Bind<int>("Sorting", "DescendingOrderMode", 2, new ConfigDescription("0: SeneaL order, 1: materials, 2: unified list with tier headers (default).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); Mode.Value = Mathf.Clamp(Mode.Value, 0, 2); View = AccessTools.TypeByName("SeneaLUI.Inv.CraftView"); if (View == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"SeneaL CraftView missing; addon disabled."); return; } string[] array = new string[5] { "Rebuild", "Filter", "Tick", "LayoutFrame", "FillHead" }; foreach (string text in array) { if (AccessTools.Method(View, text, (Type[])null, (Type[])null) == null) { throw new MissingMethodException(View.FullName, text); } } array = new string[10] { "_rows", "_panel", "_tabs", "_tabTexts", "_filtered", "_listContent", "_listView", "_listW", "_first", "_selIndex" }; foreach (string text2 in array) { if (AccessTools.Field(View, text2) == null) { throw new MissingFieldException(View.FullName, text2); } } Type type = AccessTools.Inner(View, "Row"); Type type2 = AccessTools.Inner(View, "RowUi"); array = new string[5] { "Recipe", "Item", "Name", "Visible", "Index" }; foreach (string text3 in array) { if (type == null || AccessTools.Field(type, text3) == null) { throw new MissingFieldException("SeneaL CraftView.Row", text3); } } if (type2 == null || AccessTools.Field(type2, "Head") == null) { throw new MissingFieldException("SeneaL CraftView.RowUi", "Head"); } harmony = new Harmony("com.skyowner.craftingsort"); try { Patch(AccessTools.Constructor(View, new Type[2] { typeof(InventoryGui), typeof(RectTransform) }, false), null, "Created"); Patch(AccessTools.Method(View, "Rebuild", (Type[])null, (Type[])null), "Rebuilding", null); Patch(AccessTools.Method(View, "Filter", (Type[])null, (Type[])null), "Sort", "GroupTiers"); Patch(AccessTools.Method(View, "FillHead", (Type[])null, (Type[])null), "HeaderPrefix", "HeaderPostfix"); Patch(AccessTools.Method(View, "Tick", (Type[])null, (Type[])null), null, "UpdateControl"); Patch(AccessTools.Method(View, "LayoutFrame", (Type[])null, (Type[])null), null, "UpdateControl"); if (value.Metadata.Version == new Version(1, 1, 6)) { Patch(AccessTools.Method(typeof(InventoryGui), "UpdateRecipeGamepadInput", (Type[])null, (Type[])null), "Gamepad", null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Crafting material and tier sorting enabled for SeneaL UI."); } catch { harmony.UnpatchSelf(); throw; } } private void Patch(MethodBase target, string prefix, string postfix) { //IL_0016: 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) harmony.Patch(target, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), prefix, (Type[])null), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), postfix, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private static void Rebuilding(object __instance) { States.GetOrCreateValue(__instance).Rebuilding = true; } private static void Created(object __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown CurrentView = new WeakReference<object>(__instance); ViewState orCreateValue = States.GetOrCreateValue(__instance); RectTransform val = (RectTransform)Field(__instance, "_panel"); GameObject val2 = new GameObject("CraftingSort", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform val3 = (RectTransform)val2.transform; ((Transform)val3).SetParent((Transform)(object)val, false); Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(1f, 1f); val3.pivot = val4; Vector2 anchorMin = (val3.anchorMax = val4); val3.anchorMin = anchorMin; val3.sizeDelta = new Vector2(190f, 30f); ((Graphic)val2.GetComponent<Image>()).color = new Color(0.17f, 0.15f, 0.12f, 0.95f); ((Selectable)val2.GetComponent<Button>()).targetGraphic = (Graphic)(object)val2.GetComponent<Image>(); GameObject val6 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val6.transform.SetParent((Transform)(object)val3, false); TextMeshProUGUI component = val6.GetComponent<TextMeshProUGUI>(); TMP_Text val7 = ((TMP_Text[])Field(__instance, "_tabTexts"))[0]; ((TMP_Text)component).font = val7.font; ((TMP_Text)component).fontSharedMaterial = val7.fontSharedMaterial; ((TMP_Text)component).fontSize = 14f; ((TMP_Text)component).alignment = (TextAlignmentOptions)514; ((Graphic)component).color = new Color(0.94f, 0.8f, 0.5f); ((Graphic)component).raycastTarget = false; ((TMP_Text)component).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)component).rectTransform.anchorMax = Vector2.one; RectTransform rectTransform = ((TMP_Text)component).rectTransform; anchorMin = (((TMP_Text)component).rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = anchorMin; orCreateValue.Button = val3; orCreateValue.Label = component; ((UnityEvent)val2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { Mode.Value = (Mode.Value + 1) % 3; AccessTools.Method(View, "Filter", (Type[])null, (Type[])null).Invoke(__instance, null); UpdateControl(__instance); }); UpdateControl(__instance); } private static void UpdateControl(object __instance) { //IL_0039: 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) ViewState orCreateValue = States.GetOrCreateValue(__instance); if (Object.op_Implicit((Object)(object)orCreateValue.Button)) { RectTransform[] array = (RectTransform[])Field(__instance, "_tabs"); orCreateValue.Button.anchoredPosition = new Vector2(-22f, array[0].anchoredPosition.y - 3f); bool flag = Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Russian"; if (orCreateValue.LabelMode != Mode.Value || orCreateValue.LabelRussian != flag) { string[] array2 = ((!flag) ? new string[3] { "Order: SeneaL", "Order: materials", "Order: tiers" } : new string[3] { "Порядок: SeneaL", "Порядок: материалы", "Порядок: тиры" }); ((TMP_Text)orCreateValue.Label).text = array2[Mode.Value]; orCreateValue.LabelMode = Mode.Value; orCreateValue.LabelRussian = flag; } } } private static int RecipeTier(object row) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Recipe val = (Recipe)Field(row, "Recipe"); if ((Object)(object)val == (Object)null) { ItemData val2 = (ItemData)Field(row, "Item"); if ((Object)(object)val2?.m_dropPrefab != (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { val = ObjectDB.instance.GetRecipe(val2); } } if (!((Object)(object)val == (Object)null)) { return SortKeys.Tier(from r in val.m_resources where r != null && (Object)(object)r.m_resItem != (Object)null && (r.m_amount > 0 || r.m_amountPerLevel > 0) select ((Object)((Component)r.m_resItem).gameObject).name.Replace("(Clone)", "")); } return 0; } private static void GroupTiers(object __instance) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if (Mode.Value != 2) { return; } IList list = (IList)Field(__instance, "_rows"); List<int> list2 = (List<int>)Field(__instance, "_filtered"); list2.Clear(); List<(int, int)> list3 = new List<(int, int)>(); for (int i = 0; i < list.Count; i++) { if ((bool)Field(list[i], "Visible")) { list3.Add((i, RecipeTier(list[i]))); } } list2.AddRange(TierList.Build(list3)); RectTransform val = (RectTransform)Field(__instance, "_listContent"); val.sizeDelta = new Vector2((float)Field(__instance, "_listW"), Mathf.Max(0f, (float)list2.Count * 48f - 4f)); float num = Mathf.Max(0f, val.sizeDelta.y - ((RectTransform)Field(__instance, "_listView")).sizeDelta.y); val.anchoredPosition = new Vector2(val.anchoredPosition.x, Mathf.Clamp(val.anchoredPosition.y, 0f, num)); AccessTools.Field(View, "_first").SetValue(__instance, -1); AccessTools.Field(View, "_selIndex").SetValue(__instance, -2); } private static bool Gamepad(InventoryGui __instance) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (Mode.Value != 2 || CurrentView == null || !CurrentView.TryGetTarget(out var target) || !((Component)(RectTransform)Field(target, "_panel")).gameObject.activeInHierarchy) { return true; } int num = ((ZInput.GetButtonDown("JoyLStickDown") || ZInput.GetButtonDown("JoyDPadDown")) ? 1 : ((ZInput.GetButtonDown("JoyLStickUp") || ZInput.GetButtonDown("JoyDPadUp")) ? (-1) : 0)); if (num == 0) { return false; } IList rows = (IList)Field(target, "_rows"); List<int> list = (from i in (List<int>)Field(target, "_filtered") where i >= 0 select (int)Field(rows[i], "Index") into i where i >= 0 select i).ToList(); if (list.Count == 0) { return false; } int item = (int)AccessTools.Method(typeof(InventoryGui), "GetSelectedRecipeIndex", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { false }); int num2 = list.IndexOf(item); int index = ((num2 >= 0) ? Mathf.Clamp(num2 + num, 0, list.Count - 1) : ((num <= 0) ? (list.Count - 1) : 0)); AccessTools.Method(typeof(InventoryGui), "SetRecipe", (Type[])null, (Type[])null).Invoke(__instance, new object[2] { list[index], false }); return false; } private static void HeaderPrefix(ref int group, out int __state) { __state = group; if (group >= 100) { group = 0; } } private static void HeaderPostfix(object __instance, object ui, int __state) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (__state >= 100) { int num = __state - 100; bool flag = Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Russian"; string[] array = ((!flag) ? new string[8] { "Unclassified", "Meadows", "Black Forest", "Swamp", "Mountains", "Plains", "Mistlands", "Ashlands" } : new string[8] { "Без тира", "Луга", "Чёрный лес", "Болота", "Горы", "Равнины", "Туманные земли", "Пепельные земли" }); string text = ((num == 0) ? array[0] : ((flag ? "Тир " : "Tier ") + num + " — " + array[num])); TMP_Text val = (TMP_Text)Field(ui, "Head"); val.text = text; ((Graphic)val).color = new Color(0.94f, 0.8f, 0.5f); } } private static void Sort(object __instance) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown ViewState state = States.GetOrCreateValue(__instance); IList list = (IList)Field(__instance, "_rows"); if (state.Rebuilding) { state.Original.Clear(); for (int i = 0; i < list.Count; i++) { state.Original[list[i]] = i; } state.Rebuilding = false; } if (Mode.Value == 0) { int value2; object[] array = (from object row in list orderby (!state.Original.TryGetValue(row, out value2)) ? int.MaxValue : value2 select row).ToArray(); for (int num = 0; num < array.Length; num++) { list[num] = array[num]; } return; } List<Entry> list2 = new List<Entry>(list.Count); for (int num2 = 0; num2 < list.Count; num2++) { object obj = list[num2]; Recipe val = (Recipe)Field(obj, "Recipe"); string[] resourcePrefabs = (((Object)(object)val == (Object)null) ? Array.Empty<string>() : (from r in val.m_resources where r != null && (Object)(object)r.m_resItem != (Object)null && (r.m_amount > 0 || r.m_amountPerLevel > 0) select ((Object)((Component)r.m_resItem).gameObject).name.Replace("(Clone)", "")).ToArray()); int num3 = RecipeTier(obj); list2.Add(new Entry { Row = obj, Rank = (state.Original.TryGetValue(obj, out var value) ? value : num2), Tier = ((num3 == 0) ? int.MaxValue : num3), Material = SortKeys.MaterialKey(resourcePrefabs), Name = (((string)Field(obj, "Name")) ?? "") }); } list2.Sort(delegate(Entry a, Entry b) { int num5 = ((Mode.Value == 2) ? (((a.Tier == int.MaxValue) ? (-1) : a.Tier).CompareTo((b.Tier == int.MaxValue) ? (-1) : b.Tier) * -1) : ((Mode.Value == 1) ? StringComparer.Ordinal.Compare(a.Material, b.Material) : 0)); if (num5 == 0 && Mode.Value != 0) { num5 = StringComparer.CurrentCultureIgnoreCase.Compare(a.Name, b.Name); } return (num5 == 0) ? a.Rank.CompareTo(b.Rank) : num5; }); for (int num4 = 0; num4 < list2.Count; num4++) { list[num4] = list2[num4].Row; } } } public static class SortKeys { private const char Separator = '\u001f'; private const int UnknownSortTier = 8; private static readonly IReadOnlyDictionary<string, int> VanillaTiers = new Dictionary<string, int>(StringComparer.Ordinal) { ["Wood"] = 1, ["Stone"] = 1, ["Flint"] = 1, ["Resin"] = 1, ["LeatherScraps"] = 1, ["DeerHide"] = 1, ["HardAntler"] = 1, ["Feather"] = 1, ["Feathers"] = 1, ["Honey"] = 1, ["QueenBee"] = 1, ["Dandelion"] = 1, ["Raspberry"] = 1, ["Mushroom"] = 1, ["RawMeat"] = 1, ["BoarMeat"] = 1, ["DeerMeat"] = 1, ["NeckTail"] = 1, ["RoundLog"] = 2, ["CoreWood"] = 2, ["FineWood"] = 2, ["Copper"] = 2, ["CopperOre"] = 2, ["Tin"] = 2, ["TinOre"] = 2, ["Bronze"] = 2, ["BronzeNails"] = 2, ["TrollHide"] = 2, ["GreydwarfEye"] = 2, ["BoneFragments"] = 2, ["SurtlingCore"] = 2, ["AncientSeed"] = 2, ["CryptKey"] = 2, ["Chitin"] = 2, ["Thistle"] = 2, ["Carrot"] = 2, ["CarrotSeeds"] = 2, ["Blueberries"] = 2, ["MushroomYellow"] = 2, ["YmirRemains"] = 2, ["ElderBark"] = 3, ["AncientBark"] = 3, ["Iron"] = 3, ["ScrapIron"] = 3, ["IronScrap"] = 3, ["IronNails"] = 3, ["Chain"] = 3, ["Guck"] = 3, ["Root"] = 3, ["Bloodbag"] = 3, ["Entrails"] = 3, ["Ooze"] = 3, ["WitheredBone"] = 3, ["Turnip"] = 3, ["TurnipSeeds"] = 3, ["TrophyDraugrElite"] = 3, ["Silver"] = 4, ["SilverOre"] = 4, ["Obsidian"] = 4, ["Crystal"] = 4, ["WolfPelt"] = 4, ["WolfFang"] = 4, ["FreezeGland"] = 4, ["DragonEgg"] = 4, ["DragonTear"] = 4, ["FenrisHair"] = 4, ["FenrisClaw"] = 4, ["WolfHairBundle"] = 4, ["JuteRed"] = 4, ["Onion"] = 4, ["OnionSeeds"] = 4, ["TrophyCultist"] = 4, ["BlackMetal"] = 5, ["BlackMetalScrap"] = 5, ["LinenThread"] = 5, ["Flax"] = 5, ["Barley"] = 5, ["BarleyFlour"] = 5, ["LoxPelt"] = 5, ["Needle"] = 5, ["Tar"] = 5, ["Cloudberry"] = 5, ["GoblinTotem"] = 5, ["YagluthDrop"] = 5, ["YggdrasilWood"] = 6, ["Carapace"] = 6, ["ScaleHide"] = 6, ["Mandible"] = 6, ["BlackCore"] = 6, ["Softtissue"] = 6, ["Sap"] = 6, ["Eitr"] = 6, ["RefinedEitr"] = 6, ["Bilebag"] = 6, ["RoyalJelly"] = 6, ["JuteBlue"] = 6, ["DvergrKeyFragment"] = 6, ["DvergrKey"] = 6, ["SealbreakerFragment"] = 6, ["Sealbreaker"] = 6, ["QueenDrop"] = 6, ["MechanicalSpring"] = 6, ["Magecap"] = 6, ["JotunPuffs"] = 6, ["Ashwood"] = 7, ["Blackwood"] = 7, ["Grausten"] = 7, ["Flametal"] = 7, ["FlametalOre"] = 7, ["FlametalNew"] = 7, ["FlametalOreNew"] = 7, ["AskHide"] = 7, ["AsksvinHide"] = 7, ["AskBladder"] = 7, ["MorgenSinew"] = 7, ["MorgenHeart"] = 7, ["CelestialFeather"] = 7, ["VoltureFeather"] = 7, ["CharredBone"] = 7, ["CharredCogwheel"] = 7, ["CeramicPlate"] = 7, ["SulfurStone"] = 7, ["ProustitePowder"] = 7, ["GemstoneBlue"] = 7, ["GemstoneGreen"] = 7, ["GemstoneRed"] = 7, ["Bloodstone"] = 7, ["Jade"] = 7, ["Iolite"] = 7, ["BonemawSerpentTooth"] = 7, ["BonemawSerpentScale"] = 7, ["BellFragment"] = 7, ["DyrnwynBladeFragment"] = 7, ["DyrnwynHiltFragment"] = 7, ["DyrnwynTipFragment"] = 7, ["Fiddlehead"] = 7, ["Vineberry"] = 7 }; public static int TierOf(string prefab) { if (string.IsNullOrEmpty(prefab)) { return 0; } if (!VanillaTiers.TryGetValue(prefab, out var value)) { return 0; } return value; } public static int Tier(IEnumerable<string> resourcePrefabs) { if (resourcePrefabs == null) { throw new ArgumentNullException("resourcePrefabs"); } int num = 0; foreach (string resourcePrefab in resourcePrefabs) { num = Math.Max(num, TierOf(resourcePrefab)); } return num; } public static string MaterialKey(IEnumerable<string> resourcePrefabs) { if (resourcePrefabs == null) { throw new ArgumentNullException("resourcePrefabs"); } string[] array = resourcePrefabs.Select((string prefab) => prefab ?? string.Empty).OrderBy<string, string>((string prefab) => prefab, StringComparer.Ordinal).ToArray(); int tier = Tier(array); string text = array.Where((string prefab) => TierOf(prefab) == tier).FirstOrDefault() ?? string.Empty; int num = ((tier == 0) ? 8 : tier); string text2 = string.Join('\u001f'.ToString(), array); return num.ToString("D2") + "\u001f" + text + "\u001f" + text2; } } public static class TierList { private const int HeaderBase = -101; private const int FirstKnownTier = 1; private const int LastKnownTier = 7; public static List<int> Build(IEnumerable<(int Index, int Tier)> entries) { if (entries == null) { throw new ArgumentNullException("entries"); } List<int>[] array = new List<int>[8]; for (int i = 0; i < array.Length; i++) { array[i] = new List<int>(); } foreach (var entry in entries) { int item = entry.Index; int item2 = entry.Tier; int num = ((item2 >= 1 && item2 <= 7) ? item2 : 0); array[num].Add(item); } List<int> result = new List<int>(); for (int num2 = 7; num2 >= 1; num2--) { AppendTier(result, array[num2], num2); } AppendTier(result, array[0], 0); return result; } private static void AppendTier(List<int> result, List<int> indexes, int tier) { if (indexes.Count != 0) { result.Add(-101 - tier); result.AddRange(indexes); } } } }