using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PEAKLib.UI;
using PEAKLib.UI.Elements;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Zorro.Core;
using Zorro.Core.CLI;
using Zorro.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.cherrycove.ItemBrowser")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.4.0")]
[assembly: AssemblyInformationalVersion("0.2.4+d197c5ba1ea75398d80ea31a27f4cc560ba8366d")]
[assembly: AssemblyProduct("com.github.cherrycove.ItemBrowser")]
[assembly: AssemblyTitle("ItemBrowser")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace ItemBrowser
{
internal static class CategorySystem
{
private sealed class WikiCategoryGroup
{
internal ItemCategory Category { get; }
internal string[] Names { get; }
internal WikiCategoryGroup(ItemCategory category, string[] names)
{
Category = category;
Names = names;
}
}
[CompilerGenerated]
private sealed class <GetCategoryCandidateKeys>d__8 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IEnumerator, IDisposable
{
private int <>1__state;
private string <>2__current;
private int <>l__initialThreadId;
private Item item;
public Item <>3__item;
private string displayName;
public string <>3__displayName;
private string <prefabName>5__2;
string IEnumerator<string>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GetCategoryCandidateKeys>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<prefabName>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<prefabName>5__2 = ((Object)item).name ?? string.Empty;
if (!string.IsNullOrWhiteSpace(<prefabName>5__2))
{
<>2__current = NormalizeCategoryKey(<prefabName>5__2);
<>1__state = 1;
return true;
}
goto IL_00ac;
case 1:
{
<>1__state = -1;
int num = <prefabName>5__2.IndexOf(" Variant", StringComparison.OrdinalIgnoreCase);
if (num > 0)
{
<>2__current = NormalizeCategoryKey(<prefabName>5__2.Substring(0, num));
<>1__state = 2;
return true;
}
goto IL_00ac;
}
case 2:
<>1__state = -1;
goto IL_00ac;
case 3:
{
<>1__state = -1;
break;
}
IL_00ac:
if (!string.IsNullOrWhiteSpace(displayName))
{
<>2__current = NormalizeCategoryKey(displayName);
<>1__state = 3;
return true;
}
break;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
<GetCategoryCandidateKeys>d__8 <GetCategoryCandidateKeys>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<GetCategoryCandidateKeys>d__ = this;
}
else
{
<GetCategoryCandidateKeys>d__ = new <GetCategoryCandidateKeys>d__8(0);
}
<GetCategoryCandidateKeys>d__.item = <>3__item;
<GetCategoryCandidateKeys>d__.displayName = <>3__displayName;
return <GetCategoryCandidateKeys>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<string>)this).GetEnumerator();
}
}
private static readonly WikiCategoryGroup[] _wikiCategoryGroups = BuildWikiCategoryGroups();
private static readonly Dictionary<string, ItemCategory> _wikiOverrides = BuildWikiCategoryOverrides();
private static readonly Dictionary<string, int> _wikiOrder = BuildWikiCategoryOrder();
private static readonly HashSet<string> _hiddenPrefabNames = BuildHiddenPrefabNameSet();
internal static bool ShouldHideItemFromBrowser(Item item)
{
if ((Object)(object)item == (Object)null)
{
return true;
}
string text = ((Object)item).name ?? string.Empty;
if (string.IsNullOrWhiteSpace(text))
{
return true;
}
string item2 = NormalizeCategoryKey(text);
if (_hiddenPrefabNames.Contains(item2))
{
return true;
}
if (text.StartsWith("C_", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (text.Contains("_Prop", StringComparison.OrdinalIgnoreCase) || text.Contains("_TEMP", StringComparison.OrdinalIgnoreCase) || text.Contains("_UNUSED", StringComparison.OrdinalIgnoreCase) || text.Contains("_Hidden", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
private static HashSet<string> BuildHiddenPrefabNameSet()
{
return new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
NormalizeCategoryKey("Lollipop_Prop"),
NormalizeCategoryKey("Lollipop_Prop Variant"),
NormalizeCategoryKey("FortifiedMilk_TEMP"),
NormalizeCategoryKey("Clusterberry_UNUSED"),
NormalizeCategoryKey("Mandrake_Hidden"),
NormalizeCategoryKey("BingBong_Prop Variant"),
NormalizeCategoryKey("Binoculars_Prop"),
NormalizeCategoryKey("Bugle_Prop Variant"),
NormalizeCategoryKey("Berrynana Peel Blue Variant"),
NormalizeCategoryKey("Berrynana Peel Brown Variant"),
NormalizeCategoryKey("Berrynana Peel Pink Variant"),
NormalizeCategoryKey("Berrynana Peel Yellow"),
NormalizeCategoryKey("GuidebookPage_4_BodyHeat Variant"),
NormalizeCategoryKey("GuidebookPage_5_Sleepy Variant"),
NormalizeCategoryKey("GuidebookPage_6_Awake Variant"),
NormalizeCategoryKey("GuidebookPage_7_Crashout Variant"),
NormalizeCategoryKey("Parasol_Roots Variant"),
NormalizeCategoryKey("ClimbingChalk"),
NormalizeCategoryKey("Skull")
};
}
internal static ItemCategory GetCategory(Item item, string displayName)
{
if ((Object)(object)item == (Object)null)
{
return ItemCategory.MiscEquipment;
}
if (TryGetCategoryOverride(item, displayName, out var category))
{
return category;
}
WarnFallbackCategory(item, displayName);
return ItemCategory.MiscEquipment;
}
private static bool TryGetCategoryOverride(Item item, string displayName, out ItemCategory category)
{
category = ItemCategory.NaturalFood;
if ((Object)(object)item == (Object)null)
{
return false;
}
List<string> list = (from x in GetCategoryCandidateKeys(item, displayName)
where !string.IsNullOrWhiteSpace(x)
select x).Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList();
for (int i = 0; i < list.Count; i++)
{
string text = list[i];
if (_wikiOverrides.TryGetValue(text, out category))
{
Plugin.VerboseLog($"Category override hit: key='{text}' -> {category} (prefab='{((Object)item).name}', display='{displayName}')");
return true;
}
}
return false;
}
[IteratorStateMachine(typeof(<GetCategoryCandidateKeys>d__8))]
private static IEnumerable<string> GetCategoryCandidateKeys(Item item, string displayName)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GetCategoryCandidateKeys>d__8(-2)
{
<>3__item = item,
<>3__displayName = displayName
};
}
private static WikiCategoryGroup[] BuildWikiCategoryGroups()
{
return new WikiCategoryGroup[8]
{
new WikiCategoryGroup(ItemCategory.NaturalFood, new string[34]
{
"Item_Coconut", "Item_Coconut_half", "Apple Berry Red", "Apple Berry Yellow", "Apple Berry Green", "Item_Honeycomb", "Pepper Berry", "Kingberry Purple", "Kingberry Yellow", "Kingberry Green",
"Berrynana Pink", "Berrynana Blue", "Berrynana Brown", "Clusterberry Yellow", "Clusterberry Red", "Clusterberry Black", "Winterberry Orange", "Winterberry Yellow", "Prickleberry_Red", "Prickleberry_Gold",
"MedicinalRoot", "Mandrake", "Marshmallow", "Glizzy", "Egg", "EggTurkey", "Bugfix", "Scorpion", "Napberry", "Shroomberry_Red",
"Shroomberry_Yellow", "Shroomberry_Green", "Shroomberry_Blue", "Shroomberry_Purple"
}),
new WikiCategoryGroup(ItemCategory.MysticalFood, new string[2] { "Cure-All", "PandorasBox" }),
new WikiCategoryGroup(ItemCategory.PackagedFood, new string[8] { "Airplane Food", "Lollipop", "Energy Drink", "FortifiedMilk", "Granola Bar", "ScoutCookies", "Sports Drink", "TrailMix" }),
new WikiCategoryGroup(ItemCategory.Mushroom, new string[7] { "Mushroom Lace", "Mushroom Lace Poison", "Mushroom Normie", "Mushroom Normie Poison", "Mushroom Chubby", "Mushroom Cluster", "Mushroom Cluster Poison" }),
new WikiCategoryGroup(ItemCategory.Consumable, new string[12]
{
"Antidote", "Balloon", "BalloonBunch", "Bandages", "HealingDart Variant", "FirstAidKit", "Flare", "Heat Pack", "HealingPuffShroom", "RescueHook",
"GuidebookPageScroll Variant", "Sunscreen"
}),
new WikiCategoryGroup(ItemCategory.Deployable, new string[11]
{
"BounceShroom", "ChainShooter", "Flag_Plantable_Checkpoint", "CloudFungus", "MagicBean", "ClimbingSpike", "PortableStovetopItem", "RopeShooter", "RopeSpool", "ScoutCannonItem",
"ShelfShroom"
}),
new WikiCategoryGroup(ItemCategory.MiscEquipment, new string[11]
{
"Backpack", "BingBong", "Binoculars", "Bugle", "Compass", "Frisbee", "Guidebook", "Lantern", "Parasol", "Pirate Compass",
"Torch"
}),
new WikiCategoryGroup(ItemCategory.MysticalItem, new string[9] { "AncientIdol", "RopeShooterAnti", "Anti-Rope Spool", "Bugle_Magic", "Cursed Skull", "Lantern_Faerie", "ScoutEffigy", "Bugle_Scoutmaster Variant", "BookOfBones" })
};
}
private static Dictionary<string, ItemCategory> BuildWikiCategoryOverrides()
{
Dictionary<string, ItemCategory> dictionary = new Dictionary<string, ItemCategory>(StringComparer.OrdinalIgnoreCase);
for (int i = 0; i < _wikiCategoryGroups.Length; i++)
{
WikiCategoryGroup wikiCategoryGroup = _wikiCategoryGroups[i];
AddWikiOverride(dictionary, wikiCategoryGroup.Category, wikiCategoryGroup.Names);
}
return dictionary;
}
private static Dictionary<string, int> BuildWikiCategoryOrder()
{
Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
int order = 0;
for (int i = 0; i < _wikiCategoryGroups.Length; i++)
{
AddWikiOrder(dictionary, ref order, _wikiCategoryGroups[i].Names);
}
return dictionary;
}
private static void AddWikiOverride(Dictionary<string, ItemCategory> map, ItemCategory category, params string[] names)
{
foreach (string value in names)
{
if (!string.IsNullOrWhiteSpace(value))
{
map[NormalizeCategoryKey(value)] = category;
}
}
}
private static void AddWikiOrder(Dictionary<string, int> map, ref int order, params string[] names)
{
foreach (string value in names)
{
if (!string.IsNullOrWhiteSpace(value))
{
map[NormalizeCategoryKey(value)] = order++;
}
}
}
private static string NormalizeCategoryKey(string value)
{
if (string.IsNullOrWhiteSpace(value))
{
return string.Empty;
}
List<char> list = new List<char>(value.Length);
foreach (char c in value)
{
if (char.IsLetterOrDigit(c))
{
list.Add(char.ToLowerInvariant(c));
}
}
return new string(list.ToArray());
}
internal static int GetCategoryOrder(ItemCategory category)
{
return category switch
{
ItemCategory.NaturalFood => 0,
ItemCategory.MysticalFood => 1,
ItemCategory.PackagedFood => 2,
ItemCategory.Mushroom => 3,
ItemCategory.Consumable => 4,
ItemCategory.Deployable => 5,
ItemCategory.MiscEquipment => 6,
ItemCategory.MysticalItem => 7,
_ => 8,
};
}
internal static bool IsFoodCategory(ItemCategory category)
{
if (category != 0 && category != ItemCategory.MysticalFood && category != ItemCategory.PackagedFood)
{
return category == ItemCategory.Mushroom;
}
return true;
}
internal static bool IsEntryInMajorCategory(ItemEntry entry, MajorCategory major)
{
if (major == MajorCategory.All)
{
return true;
}
bool flag = IsFoodCategory(entry.Category);
if (major != MajorCategory.Food)
{
return !flag;
}
return flag;
}
internal static int GetWikiSortOrder(ItemEntry entry)
{
if (entry == null)
{
return int.MaxValue;
}
foreach (string categoryCandidateKey in GetCategoryCandidateKeys(entry.Prefab, entry.DisplayName))
{
if (_wikiOrder.TryGetValue(categoryCandidateKey, out var value))
{
return value;
}
}
return int.MaxValue;
}
internal static ItemCategory[] GetSubCategories(MajorCategory major)
{
return major switch
{
MajorCategory.All => Array.Empty<ItemCategory>(),
MajorCategory.Food => new ItemCategory[4]
{
ItemCategory.NaturalFood,
ItemCategory.MysticalFood,
ItemCategory.PackagedFood,
ItemCategory.Mushroom
},
_ => new ItemCategory[4]
{
ItemCategory.Consumable,
ItemCategory.Deployable,
ItemCategory.MiscEquipment,
ItemCategory.MysticalItem
},
};
}
internal static string GetMajorCategoryLabel(MajorCategory category)
{
return category switch
{
MajorCategory.All => Localization.GetTextOrFallback("CATEGORY_ALL", "All"),
MajorCategory.Food => Localization.GetTextOrFallback("CATEGORY_FOOD", "Food"),
MajorCategory.Weapon => Localization.GetTextOrFallback("CATEGORY_WEAPON", "Weapon"),
_ => "Unknown",
};
}
internal static string GetCategoryLabel(ItemCategory category)
{
return category switch
{
ItemCategory.NaturalFood => Localization.GetTextOrFallback("CATEGORY_NATURAL_FOOD", "Natural Food"),
ItemCategory.MysticalFood => Localization.GetTextOrFallback("CATEGORY_MYSTICAL_FOOD", "Mystical Food"),
ItemCategory.PackagedFood => Localization.GetTextOrFallback("CATEGORY_PACKAGED_FOOD", "Packaged Food"),
ItemCategory.Mushroom => Localization.GetTextOrFallback("CATEGORY_MUSHROOM", "Mushroom"),
ItemCategory.Consumable => Localization.GetTextOrFallback("CATEGORY_CONSUMABLE", "Consumables"),
ItemCategory.Deployable => Localization.GetTextOrFallback("CATEGORY_DEPLOYABLE", "Deployable"),
ItemCategory.MiscEquipment => Localization.GetTextOrFallback("CATEGORY_MISC", "Misc"),
ItemCategory.MysticalItem => Localization.GetTextOrFallback("CATEGORY_MYSTICAL_ITEM", "Mystical Item"),
_ => "Other",
};
}
internal static string GetAllSubCategoryLabel()
{
return Localization.GetTextOrFallback("CATEGORY_ALL", "All");
}
private static void WarnFallbackCategory(Item item, string displayName)
{
Plugin.VerboseLog("Category fallback -> MiscEquipment. Prefab='" + (((item != null) ? ((Object)item).name : null) ?? "<null>") + "', Display='" + displayName + "'");
}
}
internal static class IconResolver
{
[CompilerGenerated]
private sealed class <WarmupMissingIconsGradually>d__9 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public string reason;
private int <budget>5__2;
private int <i>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WarmupMissingIconsGradually>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<budget>5__2 = 1;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<i>5__3 = 0;
goto IL_00e7;
case 2:
{
<>1__state = -1;
goto IL_00d7;
}
IL_00e7:
if (<i>5__3 < SharedState.ItemEntries.Count)
{
ItemEntry itemEntry = SharedState.ItemEntries[<i>5__3];
_iconPrewarmProcessedCount++;
if ((Object)(object)itemEntry.Icon == (Object)null)
{
Sprite itemIcon = GetItemIcon(itemEntry.Prefab);
if ((Object)(object)itemIcon != (Object)null)
{
itemEntry.UpdateIcon(itemIcon);
_iconPrewarmResolvedCount++;
}
}
<budget>5__2--;
if (<budget>5__2 <= 0)
{
<budget>5__2 = 1;
<>2__current = null;
<>1__state = 2;
return true;
}
goto IL_00d7;
}
_iconPrewarmRunning = false;
_iconPrewarmCoroutine = null;
_iconPrewarmCompleted = true;
Plugin.VerboseLog($"Icon prewarm completed ({reason}). Processed={_iconPrewarmProcessedCount}, Resolved={_iconPrewarmResolvedCount}");
return false;
IL_00d7:
<i>5__3++;
goto IL_00e7;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static Coroutine? _iconPrewarmCoroutine;
private static bool _iconPrewarmRunning;
private static bool _iconPrewarmCompleted;
private static int _iconPrewarmProcessedCount;
private static int _iconPrewarmResolvedCount;
private static float _nextIconPrewarmCheckTime;
internal static Sprite? ResolveEntryIcon(ItemEntry entry)
{
if ((Object)(object)entry.Icon != (Object)null)
{
return entry.Icon;
}
TryStartBackgroundIconPrewarm("VisibleEntryFallback");
return null;
}
internal static void TickBackgroundIconPrewarm()
{
if (SharedState.ItemListInitialized && !SharedState.ItemPreloadRunning && !_iconPrewarmRunning && !_iconPrewarmCompleted && !SharedState.PageOpen && SharedState.ItemEntries.Count != 0 && !(Time.unscaledTime < _nextIconPrewarmCheckTime))
{
_nextIconPrewarmCheckTime = Time.unscaledTime + 0.15f;
TryStartBackgroundIconPrewarm("AutoWarmup");
}
}
internal static bool TryStartBackgroundIconPrewarm(string reason)
{
if (!SharedState.ItemListInitialized || SharedState.ItemPreloadRunning || _iconPrewarmRunning || _iconPrewarmCompleted)
{
return false;
}
if ((Object)(object)SharedState.Instance == (Object)null || SharedState.ItemEntries.Count == 0)
{
return false;
}
_iconPrewarmRunning = true;
_iconPrewarmProcessedCount = 0;
_iconPrewarmResolvedCount = 0;
_iconPrewarmCoroutine = ((MonoBehaviour)SharedState.Instance).StartCoroutine(WarmupMissingIconsGradually(reason));
Plugin.VerboseLog($"Icon prewarm started ({reason}). Entries={SharedState.ItemEntries.Count}");
return true;
}
[IteratorStateMachine(typeof(<WarmupMissingIconsGradually>d__9))]
private static IEnumerator WarmupMissingIconsGradually(string reason)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WarmupMissingIconsGradually>d__9(0)
{
reason = reason
};
}
internal static void ResetIconPrewarmState(bool stopCoroutine)
{
if (stopCoroutine)
{
StopTrackedCoroutine(ref _iconPrewarmCoroutine);
}
else
{
_iconPrewarmCoroutine = null;
}
_iconPrewarmRunning = false;
_iconPrewarmCompleted = false;
_iconPrewarmProcessedCount = 0;
_iconPrewarmResolvedCount = 0;
_nextIconPrewarmCheckTime = 0f;
}
private static void StopTrackedCoroutine(ref Coroutine? coroutine)
{
if (coroutine != null)
{
if ((Object)(object)SharedState.Instance != (Object)null)
{
((MonoBehaviour)SharedState.Instance).StopCoroutine(coroutine);
}
coroutine = null;
}
}
internal static Sprite? GetItemIcon(Item item, bool allowHeavyFallback = true)
{
if ((Object)(object)item == (Object)null)
{
return null;
}
string key = ((Object)item).name ?? string.Empty;
if (SharedState.ItemIconCache.TryGetValue(key, out Sprite value))
{
return value;
}
Sprite val = null;
List<string> list = ((SharedState.ConfigVerboseLogs != null && SharedState.ConfigVerboseLogs.Value) ? new List<string>() : null);
HashSet<int> visited = new HashSet<int>();
try
{
val = TryExtractUiDataIcon(item, list);
if ((Object)(object)val == (Object)null)
{
val = TryExtractSprite(item, list, "Item", 0, visited);
}
if ((Object)(object)val == (Object)null)
{
Component[] components = ((Component)item).GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
if (!((Object)(object)val == (Object)null))
{
break;
}
Component val2 = components[i];
if (!((Object)(object)val2 == (Object)null))
{
val = TryExtractSprite(val2, list, ((object)val2).GetType().Name, 0, visited);
}
}
}
if ((Object)(object)val == (Object)null)
{
Image componentInChildren = ((Component)item).GetComponentInChildren<Image>(true);
if ((Object)(object)componentInChildren != (Object)null)
{
val = componentInChildren.sprite;
list?.Add(((Object)(object)val != (Object)null) ? ("UI.Image(sprite)=" + DescribeSprite(val)) : "UI.Image(sprite)=null");
}
else
{
list?.Add("UI.Image=missing");
}
}
if ((Object)(object)val == (Object)null)
{
SpriteRenderer componentInChildren2 = ((Component)item).GetComponentInChildren<SpriteRenderer>(true);
if ((Object)(object)componentInChildren2 != (Object)null)
{
val = componentInChildren2.sprite;
list?.Add(((Object)(object)val != (Object)null) ? ("SpriteRenderer(sprite)=" + DescribeSprite(val)) : "SpriteRenderer(sprite)=null");
}
else
{
list?.Add("SpriteRenderer=missing");
}
}
if (allowHeavyFallback && (Object)(object)val == (Object)null)
{
val = TryExtractMaterialTextureSprite(item, list);
if ((Object)(object)val == (Object)null)
{
list?.Add("HeavyFallback(material)=miss");
}
}
}
catch (Exception ex)
{
Plugin.VerboseLog("GetItemIcon failed for " + ((Object)item).name + ": " + ex.GetType().Name + " " + ex.Message);
}
if (list != null)
{
if ((Object)(object)val != (Object)null)
{
Plugin.VerboseLog("Icon resolved for '" + ((Object)item).name + "': " + DescribeSprite(val) + " | " + FormatProbe(list));
}
else
{
Plugin.Log.LogWarning((object)("[ItemBrowser] Icon missing for '" + ((Object)item).name + "'. Probe: " + FormatProbe(list)));
}
}
SharedState.ItemIconCache[key] = val;
return val;
}
private static Sprite? TryExtractUiDataIcon(Item item, List<string>? probe)
{
if ((Object)(object)item == (Object)null)
{
return null;
}
try
{
ItemUIData uIData = item.UIData;
Texture2D icon = uIData.icon;
if ((Object)(object)icon != (Object)null)
{
return ConvertTextureToSprite(icon, "Item.UIData.icon", probe);
}
if (uIData.hasAltIcon && (Object)(object)uIData.altIcon != (Object)null)
{
return ConvertTextureToSprite(uIData.altIcon, "Item.UIData.altIcon", probe);
}
probe?.Add("Item.UIData.icon=null");
}
catch (Exception ex)
{
probe?.Add("Item.UIData=failed(" + ex.GetType().Name + ")");
}
return null;
}
private static Sprite? TryExtractSprite(object target, List<string>? probe = null, string? source = null, int depth = 0, HashSet<int>? visited = null)
{
if (target == null || depth > 2)
{
return null;
}
if (visited == null)
{
visited = new HashSet<int>();
}
if (!(target is string) && !target.GetType().IsValueType)
{
int hashCode = RuntimeHelpers.GetHashCode(target);
if (!visited.Add(hashCode))
{
return null;
}
}
string text = (string.IsNullOrWhiteSpace(source) ? target.GetType().Name : source);
if (TryExtractSpriteFromValue(target, text, probe, depth, visited, out Sprite sprite))
{
return sprite;
}
Type type = target.GetType();
string[] array = new string[18]
{
"Icon", "icon", "ItemIcon", "itemIcon", "IconSprite", "iconSprite", "Sprite", "sprite", "Thumbnail", "thumbnail",
"Icons", "icons", "ItemIcons", "itemIcons", "Atlas", "atlas", "Texture", "texture"
};
foreach (string name in array)
{
FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
object value = null;
try
{
value = field.GetValue(target);
}
catch
{
}
if (TryExtractSpriteFromValue(value, text + "." + field.Name, probe, depth + 1, visited, out Sprite sprite2))
{
return sprite2;
}
probe?.Add(text + "." + field.Name + "<" + field.FieldType.Name + ">=" + DescribeProbeValue(value));
}
PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.CanRead && property.GetIndexParameters().Length == 0)
{
object obj2 = null;
try
{
obj2 = property.GetValue(target);
}
catch
{
obj2 = "<get_error>";
}
if (TryExtractSpriteFromValue(obj2, text + "." + property.Name, probe, depth + 1, visited, out Sprite sprite3))
{
return sprite3;
}
probe?.Add(text + "." + property.Name + "<" + property.PropertyType.Name + ">=" + DescribeProbeValue(obj2));
}
}
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (IsIconProbeMember(fieldInfo.Name, fieldInfo.FieldType))
{
object value2 = null;
try
{
value2 = fieldInfo.GetValue(target);
}
catch
{
}
if (TryExtractSpriteFromValue(value2, text + "." + fieldInfo.Name, probe, depth + 1, visited, out Sprite sprite4))
{
return sprite4;
}
probe?.Add(text + "." + fieldInfo.Name + "<" + fieldInfo.FieldType.Name + ">=" + DescribeProbeValue(value2));
}
}
PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (PropertyInfo propertyInfo in properties)
{
if (propertyInfo.CanRead && propertyInfo.GetIndexParameters().Length == 0 && IsIconProbeMember(propertyInfo.Name, propertyInfo.PropertyType))
{
object obj5 = null;
try
{
obj5 = propertyInfo.GetValue(target);
}
catch
{
obj5 = "<get_error>";
}
if (TryExtractSpriteFromValue(obj5, text + "." + propertyInfo.Name, probe, depth + 1, visited, out Sprite sprite5))
{
return sprite5;
}
probe?.Add(text + "." + propertyInfo.Name + "<" + propertyInfo.PropertyType.Name + ">=" + DescribeProbeValue(obj5));
}
}
return null;
}
private static bool TryExtractSpriteFromValue(object? value, string source, List<string>? probe, int depth, HashSet<int> visited, out Sprite? sprite)
{
sprite = null;
if (value == null)
{
return false;
}
Sprite val = (Sprite)((value is Sprite) ? value : null);
if (val != null)
{
probe?.Add(source + "=" + DescribeSprite(val));
sprite = val;
return true;
}
Texture2D val2 = (Texture2D)((value is Texture2D) ? value : null);
if (val2 != null)
{
sprite = ConvertTextureToSprite(val2, source, probe);
return (Object)(object)sprite != (Object)null;
}
Texture val3 = (Texture)((value is Texture) ? value : null);
if (val3 != null)
{
Texture2D val4 = (Texture2D)(object)((val3 is Texture2D) ? val3 : null);
if (val4 != null)
{
sprite = ConvertTextureToSprite(val4, source, probe);
return (Object)(object)sprite != (Object)null;
}
probe?.Add(source + "=texture('" + ((Object)val3).name + "') unsupported:" + ((object)val3).GetType().Name);
return false;
}
if (value is IEnumerable enumerable && !(value is string) && ShouldEnumerateIconCollection(source, value))
{
int num = 0;
foreach (object item in enumerable)
{
if (TryExtractSpriteFromValue(item, $"{source}[{num}]", probe, depth + 1, visited, out sprite))
{
return true;
}
num++;
if (num >= 8)
{
break;
}
}
return false;
}
if (depth >= 2)
{
return false;
}
Type type = value.GetType();
if (type.IsPrimitive || type.IsEnum || value is string || value is decimal)
{
return false;
}
if (!ShouldDeepProbeSource(source, type))
{
return false;
}
sprite = TryExtractSprite(value, probe, source, depth + 1, visited);
return (Object)(object)sprite != (Object)null;
}
private static Sprite? ConvertTextureToSprite(Texture2D texture, string source, List<string>? probe)
{
//IL_0093: 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)
if ((Object)(object)texture == (Object)null)
{
return null;
}
int instanceID = ((Object)texture).GetInstanceID();
if (SharedState.GeneratedTextureSpriteCache.TryGetValue(instanceID, out Sprite value) && (Object)(object)value != (Object)null)
{
probe?.Add(source + "=cached:" + DescribeSprite(value));
return value;
}
if (((Texture)texture).width <= 0 || ((Texture)texture).height <= 0)
{
probe?.Add(source + "=texture('" + ((Object)texture).name + "') invalid_size");
return null;
}
try
{
Sprite val = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
((Object)val).name = ((Object)texture).name + "_AutoIcon";
SharedState.GeneratedTextureSpriteCache[instanceID] = val;
probe?.Add(source + "=texture->sprite:" + DescribeSprite(val));
return val;
}
catch (Exception ex)
{
probe?.Add(source + "=texture_convert_failed(" + ex.GetType().Name + ")");
return null;
}
}
private static Sprite? TryExtractMaterialTextureSprite(Item item, List<string>? probe)
{
if ((Object)(object)item == (Object)null)
{
return null;
}
Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
if (componentsInChildren == null || componentsInChildren.Length == 0)
{
probe?.Add("Renderer=missing");
return null;
}
Texture2D bestTexture = null;
string bestSource = string.Empty;
int bestScore = int.MinValue;
foreach (Renderer val in componentsInChildren)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
if (ShouldSkipRendererForIcon(val))
{
probe?.Add("Renderer(" + ((object)val).GetType().Name + ":" + ((Object)val).name + ")=skip");
continue;
}
Material[] sharedMaterials = val.sharedMaterials;
if (sharedMaterials == null || sharedMaterials.Length == 0)
{
probe?.Add("Renderer(" + ((object)val).GetType().Name + ":" + ((Object)val).name + ").sharedMaterials=empty");
continue;
}
foreach (Material val2 in sharedMaterials)
{
if ((Object)(object)val2 == (Object)null)
{
continue;
}
if (ShouldSkipMaterialForIcon(val2))
{
probe?.Add("Renderer(" + ((object)val).GetType().Name + ":" + ((Object)val).name + ").Material(" + ((Object)val2).name + ")=skip");
continue;
}
string text = "Renderer(" + ((object)val).GetType().Name + ":" + ((Object)val).name + ").Material(" + ((Object)val2).name + ")";
string name = ((Object)item).name;
Texture mainTexture = val2.mainTexture;
EvaluateTextureCandidate(name, (Texture2D?)(object)((mainTexture is Texture2D) ? mainTexture : null), text + ".mainTexture", ref bestTexture, ref bestSource, ref bestScore, probe);
string[] array;
try
{
array = val2.GetTexturePropertyNames();
}
catch
{
array = Array.Empty<string>();
}
foreach (string text2 in array)
{
if (!string.IsNullOrWhiteSpace(text2))
{
Texture2D texture = null;
try
{
Texture texture2 = val2.GetTexture(text2);
texture = (Texture2D)(object)((texture2 is Texture2D) ? texture2 : null);
}
catch
{
}
EvaluateTextureCandidate(((Object)item).name, texture, text + "." + text2, ref bestTexture, ref bestSource, ref bestScore, probe);
}
}
}
}
if ((Object)(object)bestTexture == (Object)null)
{
probe?.Add("MaterialTexture=no_candidate");
return null;
}
if (bestScore < 80)
{
probe?.Add($"MaterialTexture.skip(score={bestScore})");
return null;
}
probe?.Add($"MaterialTexture=choose(score={bestScore}):{bestSource}");
return ConvertTextureToSprite(bestTexture, bestSource, probe);
}
private static bool ShouldSkipRendererForIcon(Renderer renderer)
{
if ((Object)(object)renderer == (Object)null)
{
return true;
}
string text = ((Object)renderer).name?.ToLowerInvariant() ?? string.Empty;
if (!text.Contains("hand") && !text.Contains("arm") && !text.Contains("player") && !text.Contains("viewmodel") && !text.Contains("firstperson") && !text.Contains("fp_"))
{
return text.Contains("character");
}
return true;
}
private static bool ShouldSkipMaterialForIcon(Material material)
{
if ((Object)(object)material == (Object)null)
{
return true;
}
string text = ((Object)material).name?.ToLowerInvariant() ?? string.Empty;
if (!text.Contains("m_player") && !text.Contains("player") && !text.Contains("hand") && !text.Contains("skin") && !text.Contains("hair") && !text.Contains("eye"))
{
return text.Contains("face");
}
return true;
}
private static void EvaluateTextureCandidate(string itemName, Texture2D? texture, string source, ref Texture2D? bestTexture, ref string bestSource, ref int bestScore, List<string>? probe)
{
if ((Object)(object)texture == (Object)null)
{
probe?.Add(source + "=null");
return;
}
int num = ScoreTextureCandidate(itemName, texture, source);
probe?.Add($"{source}=texture('{((Object)texture).name}') score={num}");
if (num > bestScore)
{
bestScore = num;
bestTexture = texture;
bestSource = source;
}
}
private static int ScoreTextureCandidate(string itemName, Texture2D texture, string source)
{
string text = source.ToLowerInvariant();
string text2 = ((Object)texture).name ?? string.Empty;
string text3 = text2.ToLowerInvariant();
string source2 = (itemName ?? string.Empty).ToLowerInvariant();
int num = 0;
if (text.Contains("icon") || text.Contains("thumb"))
{
num += 120;
}
if (text3.Contains("icon") || text3.Contains("thumb"))
{
num += 100;
}
if (text.Contains("atlas"))
{
num += 25;
}
string value = new string(source2.Where(char.IsLetterOrDigit).ToArray());
string text4 = new string(text3.Where(char.IsLetterOrDigit).ToArray());
if (!string.IsNullOrEmpty(value) && text4.Contains(value))
{
num += 90;
}
if (text.Contains("_basemap") || text.Contains("_maintex") || text.Contains("_basetexture"))
{
num += 15;
}
if (((Texture)texture).width <= 1024 && ((Texture)texture).height <= 1024)
{
num += 20;
}
if (((Texture)texture).width <= 512 && ((Texture)texture).height <= 512)
{
num += 20;
}
if (((Texture)texture).width <= 256 && ((Texture)texture).height <= 256)
{
num += 10;
}
if (text.Contains("renderer(meshrenderer:hand)") || text.Contains("material(m_player)"))
{
num -= 300;
}
if (text3.StartsWith("a_texture") || text3.StartsWith("a_paint") || text3.StartsWith("a_noise"))
{
num -= 80;
}
if (text3.Contains("default") || text3.Contains("fallback") || text3.Contains("noise"))
{
num -= 60;
}
if (text3.Contains("soft noise") || text3 == "t_leaves" || text3.Contains("leaves") || text3.Contains("foliage"))
{
num -= 80;
}
return num;
}
private static bool ShouldEnumerateIconCollection(string source, object value)
{
if (value == null)
{
return false;
}
if (value is Array array)
{
Type c = array.GetType().GetElementType() ?? typeof(object);
if (typeof(Sprite).IsAssignableFrom(c) || typeof(Texture).IsAssignableFrom(c))
{
return true;
}
}
if (source.IndexOf("icon", StringComparison.OrdinalIgnoreCase) < 0 && source.IndexOf("sprite", StringComparison.OrdinalIgnoreCase) < 0 && source.IndexOf("thumb", StringComparison.OrdinalIgnoreCase) < 0)
{
return source.IndexOf("texture", StringComparison.OrdinalIgnoreCase) >= 0;
}
return true;
}
private static bool ShouldDeepProbeSource(string source, Type valueType)
{
if (valueType == null)
{
return false;
}
if (typeof(Texture).IsAssignableFrom(valueType) || typeof(Sprite).IsAssignableFrom(valueType))
{
return true;
}
if (source.IndexOf("icon", StringComparison.OrdinalIgnoreCase) < 0 && source.IndexOf("sprite", StringComparison.OrdinalIgnoreCase) < 0 && source.IndexOf("thumb", StringComparison.OrdinalIgnoreCase) < 0 && source.IndexOf("atlas", StringComparison.OrdinalIgnoreCase) < 0)
{
return source.IndexOf("texture", StringComparison.OrdinalIgnoreCase) >= 0;
}
return true;
}
private static bool IsIconProbeMember(string name, Type memberType)
{
if (memberType == null)
{
return false;
}
if (typeof(Sprite).IsAssignableFrom(memberType) || typeof(Texture).IsAssignableFrom(memberType) || memberType.IsArray)
{
return true;
}
string text = name?.ToLowerInvariant() ?? string.Empty;
if (string.IsNullOrEmpty(text))
{
return false;
}
if (!text.Contains("icon") && !text.Contains("sprite") && !text.Contains("thumbnail") && !text.Contains("atlas") && !text.Contains("texture"))
{
return text.Contains("tex");
}
return true;
}
private static string DescribeSprite(Sprite sprite)
{
//IL_004b: 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_0061: 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)sprite == (Object)null)
{
return "sprite:null";
}
string text = (((Object)(object)sprite.texture != (Object)null) ? ((Object)sprite.texture).name : "null");
object[] obj = new object[4]
{
((Object)sprite).name,
text,
null,
null
};
Rect rect = sprite.rect;
obj[2] = ((Rect)(ref rect)).width;
rect = sprite.rect;
obj[3] = ((Rect)(ref rect)).height;
return string.Format("sprite='{0}', texture='{1}', rect={2}x{3}", obj);
}
private static string DescribeProbeValue(object? value)
{
if (value == null)
{
return "null";
}
Sprite val = (Sprite)((value is Sprite) ? value : null);
if (val != null)
{
return DescribeSprite(val);
}
Texture val2 = (Texture)((value is Texture) ? value : null);
if (val2 != null)
{
return "texture='" + ((Object)val2).name + "' (" + ((object)val2).GetType().Name + ")";
}
if (value is IEnumerable enumerable && !(value is string))
{
int num = 0;
foreach (object item in enumerable)
{
num++;
if (num >= 12)
{
break;
}
}
return $"enumerable<{value.GetType().Name}> count~{num}";
}
Object val3 = (Object)((value is Object) ? value : null);
if (val3 != null)
{
return "unity='" + val3.name + "' (" + ((object)val3).GetType().Name + ")";
}
string text = value.ToString() ?? value.GetType().Name;
if (text.Length > 80)
{
text = text.Substring(0, 80) + "...";
}
return text;
}
private static string FormatProbe(List<string> probe)
{
if (probe == null || probe.Count == 0)
{
return "probe=empty";
}
if (probe.Count <= 20)
{
return string.Join(" | ", probe);
}
return string.Join(" | ", probe.Take(20)) + $" | ...(+{probe.Count - 20})";
}
}
internal static class InputHandler
{
private static bool _inputSystemChecked;
private static bool _inputSystemAvailable;
private static PropertyInfo? _inputSystemKeyboardCurrentProp;
private static PropertyInfo? _inputSystemKeyboardItemProp;
private static PropertyInfo? _inputSystemKeyControlPressedProp;
private static Type? _inputSystemKeyType;
private static bool _legacyInputAvailable = true;
public static bool IsTogglePressed()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if (SharedState.ConfigToggleKey == null)
{
return false;
}
KeyCode value = SharedState.ConfigToggleKey.Value;
if (TryGetInputSystemKeyDown(value, out var pressed))
{
return pressed;
}
if (TryGetLegacyInputKeyDown(value, out var pressed2))
{
return pressed2;
}
return false;
}
private static bool TryGetInputSystemKeyDown(KeyCode keyCode, out bool pressed)
{
pressed = false;
if (!_inputSystemChecked)
{
_inputSystemAvailable = InitializeInputSystemReflection();
_inputSystemChecked = true;
}
if (!_inputSystemAvailable)
{
return false;
}
try
{
object obj = _inputSystemKeyboardCurrentProp?.GetValue(null, null);
if (obj == null)
{
return true;
}
object obj2 = Enum.Parse(_inputSystemKeyType, ((object)(KeyCode)(ref keyCode)).ToString());
object obj3 = _inputSystemKeyboardItemProp?.GetValue(obj, new object[1] { obj2 });
if (obj3 == null)
{
return true;
}
pressed = (bool)_inputSystemKeyControlPressedProp.GetValue(obj3, null);
return true;
}
catch
{
_inputSystemAvailable = false;
return false;
}
}
private static bool InitializeInputSystemReflection()
{
try
{
Type type = Type.GetType("UnityEngine.InputSystem.Keyboard, Unity.InputSystem");
_inputSystemKeyType = Type.GetType("UnityEngine.InputSystem.Key, Unity.InputSystem");
Type type2 = Type.GetType("UnityEngine.InputSystem.Controls.KeyControl, Unity.InputSystem");
if (type == null || _inputSystemKeyType == null || type2 == null)
{
return false;
}
_inputSystemKeyboardCurrentProp = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
_inputSystemKeyboardItemProp = type.GetProperty("Item", BindingFlags.Instance | BindingFlags.Public);
_inputSystemKeyControlPressedProp = type2.GetProperty("wasPressedThisFrame", BindingFlags.Instance | BindingFlags.Public);
return _inputSystemKeyboardCurrentProp != null && _inputSystemKeyboardItemProp != null && _inputSystemKeyControlPressedProp != null;
}
catch
{
return false;
}
}
private static bool TryGetLegacyInputKeyDown(KeyCode keyCode, out bool pressed)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
pressed = false;
if (!_legacyInputAvailable)
{
return false;
}
try
{
pressed = Input.GetKeyDown(keyCode);
return true;
}
catch
{
_legacyInputAvailable = false;
return false;
}
}
}
internal static class ItemLoader
{
[CompilerGenerated]
private sealed class <BuildItemListGradually>d__8 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ItemDatabase db;
public int dbId;
private int <budget>5__2;
private List<Item>.Enumerator <>7__wrap2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <BuildItemListGradually>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 2)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap2 = default(List<Item>.Enumerator);
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<budget>5__2 = 4;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>7__wrap2 = ((DatabaseAsset<ItemDatabase, Item>)(object)db).Objects.GetEnumerator();
<>1__state = -3;
break;
case 2:
<>1__state = -3;
break;
}
while (<>7__wrap2.MoveNext())
{
Item current = <>7__wrap2.Current;
_preloadProcessedCount++;
try
{
if ((Object)(object)current != (Object)null)
{
string resolvedItemDisplayName = GetResolvedItemDisplayName(current);
if (!CategorySystem.ShouldHideItemFromBrowser(current))
{
ItemCategory category = CategorySystem.GetCategory(current, resolvedItemDisplayName);
Sprite itemIcon = IconResolver.GetItemIcon(current, allowHeavyFallback: false);
SharedState.ItemEntries.Add(new ItemEntry(current, resolvedItemDisplayName, category, itemIcon));
_preloadAddedCount++;
}
else
{
Plugin.VerboseLog("Item hidden: prefab='" + ((Object)current).name + "', display='" + resolvedItemDisplayName + "'");
}
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[ItemBrowser] Preload item failed: " + ((current != null) ? ((Object)current).name : null) + " (" + ex.GetType().Name + " " + ex.Message + ")"));
}
<budget>5__2--;
if (<budget>5__2 <= 0)
{
<budget>5__2 = 4;
<>2__current = null;
<>1__state = 2;
return true;
}
}
<>m__Finally1();
<>7__wrap2 = default(List<Item>.Enumerator);
SharedState.ItemPreloadRunning = false;
_preloadCoroutine = null;
SharedState.ItemListInitialized = true;
SharedState.LoadedDatabaseId = ((SharedState.PreloadingDatabaseId != 0) ? SharedState.PreloadingDatabaseId : dbId);
SharedState.PreloadingDatabaseId = 0;
if (SharedState.ConfigVerboseLogs != null && SharedState.ConfigVerboseLogs.Value)
{
IEnumerable<string> values = from entry in SharedState.ItemEntries
group entry by entry.Category into @group
orderby CategorySystem.GetCategoryOrder(@group.Key)
select $"{CategorySystem.GetCategoryLabel(@group.Key)}={@group.Count()}";
Plugin.Log.LogInfo((object)string.Format("[ItemBrowser] Item list built in background. Total={0}, Added={1}, Categories: {2}", SharedState.ItemEntries.Count, _preloadAddedCount, string.Join(", ", values)));
}
VirtualList.MarkListDirty("Item preload completed");
IconResolver.TryStartBackgroundIconPrewarm("PostPreload");
VirtualList.TryStartBackgroundButtonPoolWarmup("PostPreload", VirtualList.CalculateButtonPoolWarmupTarget(SharedState.ItemEntries.Count));
if (SharedState.PageOpen)
{
VirtualList.RefreshListIfNeeded();
}
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>7__wrap2).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static Coroutine? _preloadCoroutine;
private static int _preloadTotalCount;
private static int _preloadProcessedCount;
private static int _preloadAddedCount;
private static float _nextPreloadCheckTime;
internal static void EnsureItemList()
{
if (!SharedState.ItemListInitialized && !SharedState.ItemPreloadRunning)
{
TryStartBackgroundItemPreload("EnsureItemList");
}
}
internal static void TickBackgroundItemPreload()
{
if (!SharedState.ItemListInitialized && !SharedState.ItemPreloadRunning && !(Time.unscaledTime < _nextPreloadCheckTime))
{
_nextPreloadCheckTime = Time.unscaledTime + 0.1f;
TryStartBackgroundItemPreload("AutoWarmup");
}
}
internal static bool TryStartBackgroundItemPreload(string reason)
{
if (SharedState.ItemListInitialized || SharedState.ItemPreloadRunning)
{
return false;
}
if ((Object)(object)SharedState.Instance == (Object)null)
{
return false;
}
ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
if ((Object)(object)instance == (Object)null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects == null || ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count == 0)
{
return false;
}
SharedState.ItemEntries.Clear();
SharedState.ItemIconCache.Clear();
SharedState.GeneratedTextureSpriteCache.Clear();
IconResolver.ResetIconPrewarmState(stopCoroutine: true);
VirtualList.ResetButtonPoolWarmupState(stopCoroutine: true);
VirtualList.MarkListDirty("Item preload started (" + reason + ")");
_preloadTotalCount = ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count;
_preloadProcessedCount = 0;
_preloadAddedCount = 0;
SharedState.ItemPreloadRunning = true;
SharedState.ItemNamesLanguageIndex = Localization.GetCurrentLanguageIndex();
SharedState.ItemNamesLanguageMarker = Localization.BuildLanguageMarker();
int dbId = (SharedState.PreloadingDatabaseId = ((Object)instance).GetInstanceID());
SharedState.LoadedDatabaseId = 0;
_preloadCoroutine = ((MonoBehaviour)SharedState.Instance).StartCoroutine(BuildItemListGradually(instance, dbId));
Plugin.VerboseLog($"Item preload started ({reason}). Total={_preloadTotalCount}");
return true;
}
[IteratorStateMachine(typeof(<BuildItemListGradually>d__8))]
private static IEnumerator BuildItemListGradually(ItemDatabase db, int dbId)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <BuildItemListGradually>d__8(0)
{
db = db,
dbId = dbId
};
}
internal static string GetPreloadStatusText()
{
if (SharedState.ItemPreloadRunning)
{
if (_preloadTotalCount > 0)
{
return string.Format("{0} {1}/{2}", Localization.GetText("STATUS_LOADING"), _preloadProcessedCount, _preloadTotalCount);
}
return Localization.GetText("STATUS_LOADING");
}
return Localization.GetText("STATUS_NOT_READY");
}
internal static string GetResolvedItemDisplayName(Item item)
{
if ((Object)(object)item == (Object)null)
{
return string.Empty;
}
string localizedItemName = Localization.GetLocalizedItemName(item);
string displayName = (string.IsNullOrWhiteSpace(localizedItemName) ? (((Object)item).name ?? string.Empty) : localizedItemName);
return GetDisplayNameOverride(item, displayName);
}
private static string GetDisplayNameOverride(Item item, string displayName)
{
if ((Object)(object)item == (Object)null)
{
return displayName;
}
string text = ((Object)item).name ?? string.Empty;
if (text.Equals("EggTurkey", StringComparison.OrdinalIgnoreCase))
{
string text2 = Localization.ResolveLocalizedText("NAME_COOKED BIRD");
if (!string.IsNullOrWhiteSpace(text2))
{
return text2;
}
return displayName;
}
return displayName;
}
internal static void RefreshItemDisplayNamesForCurrentLanguage(bool force = false, string? currentLanguageMarker = null)
{
if (!SharedState.ItemListInitialized || SharedState.ItemEntries.Count == 0)
{
return;
}
int currentLanguageIndex = Localization.GetCurrentLanguageIndex();
if (currentLanguageMarker == null)
{
currentLanguageMarker = Localization.BuildLanguageMarker();
}
bool flag = !string.Equals(currentLanguageMarker, SharedState.ItemNamesLanguageMarker, StringComparison.Ordinal);
if (!force && !flag && currentLanguageIndex == SharedState.ItemNamesLanguageIndex)
{
return;
}
int num = 0;
for (int i = 0; i < SharedState.ItemEntries.Count; i++)
{
ItemEntry itemEntry = SharedState.ItemEntries[i];
string resolvedItemDisplayName = GetResolvedItemDisplayName(itemEntry.Prefab);
if (!string.Equals(itemEntry.DisplayName, resolvedItemDisplayName, StringComparison.Ordinal))
{
itemEntry.UpdateDisplayName(resolvedItemDisplayName);
num++;
}
}
SharedState.ItemNamesLanguageIndex = currentLanguageIndex;
SharedState.ItemNamesLanguageMarker = currentLanguageMarker;
Plugin.VerboseLog($"Language refresh complete. index={currentLanguageIndex}, renamed={num}, total={SharedState.ItemEntries.Count}, markerChanged={flag}");
}
internal static void ResetState()
{
StopTrackedCoroutine(ref _preloadCoroutine);
_preloadTotalCount = 0;
_preloadProcessedCount = 0;
_preloadAddedCount = 0;
_nextPreloadCheckTime = 0f;
}
private static void StopTrackedCoroutine(ref Coroutine? coroutine)
{
if (coroutine != null)
{
if ((Object)(object)SharedState.Instance != (Object)null)
{
((MonoBehaviour)SharedState.Instance).StopCoroutine(coroutine);
}
coroutine = null;
}
}
}
[ConsoleClassCustomizer("ItemBrowser")]
internal static class ItemSpawner
{
[ConsoleCommand(false)]
public static void Spawn(Item item)
{
string statusMessage;
if ((Object)(object)item == (Object)null)
{
ReportConsoleWarning("[ItemBrowser] Spawn command failed: resolved item was null.");
}
else if (!TrySpawnItem(item, out statusMessage))
{
ReportConsoleWarning(statusMessage);
}
else
{
ReportConsoleInfo(statusMessage);
}
}
public static void SpawnItem(Item prefab)
{
TrySpawnItem(prefab, out string _);
}
private static bool IsCharacterDeadOrGhost(Character character)
{
if ((Object)(object)character == (Object)null)
{
return true;
}
if ((Object)(object)character.data == (Object)null)
{
return true;
}
if (!character.data.dead && !character.IsGhost)
{
return character.data.fullyPassedOut;
}
return true;
}
private static Character? ResolveSpawnTarget(Character localPlayer, out string? warningMessage)
{
warningMessage = null;
if (!SharedState.ConfigGhostSendToObserved.Value || !IsCharacterDeadOrGhost(localPlayer))
{
return localPlayer;
}
Character observedCharacter = Character.observedCharacter;
if ((Object)(object)observedCharacter == (Object)null)
{
warningMessage = "[ItemBrowser] You are dead/ghost but not spectating anyone. Cannot send item.";
return null;
}
if (IsCharacterDeadOrGhost(observedCharacter))
{
string text = ((Object)observedCharacter).name ?? "unknown";
warningMessage = "[ItemBrowser] Spectated player '" + text + "' is also dead or incapacitated. Cannot send item.";
return null;
}
return observedCharacter;
}
private static bool TrySpawnItem(Item prefab, out string statusMessage)
{
statusMessage = string.Empty;
if ((Object)(object)prefab == (Object)null)
{
statusMessage = "[ItemBrowser] Item prefab is null.";
return false;
}
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter == (Object)null)
{
statusMessage = "[ItemBrowser] No local character available. Enter a match to spawn items.";
Plugin.Log.LogWarning((object)statusMessage);
return false;
}
if (!SharedState.ConfigAllowOnline.Value && !PhotonNetwork.OfflineMode && (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom))
{
statusMessage = "[ItemBrowser] Online spawn disabled or not in room.";
Plugin.Log.LogWarning((object)statusMessage);
return false;
}
string warningMessage;
Character val = ResolveSpawnTarget(localCharacter, out warningMessage);
if ((Object)(object)val == (Object)null)
{
statusMessage = warningMessage ?? "[ItemBrowser] No valid spawn target found.";
Plugin.Log.LogWarning((object)statusMessage);
return false;
}
bool flag = (Object)(object)val != (Object)(object)localCharacter;
string text = (flag ? ("observed teammate '" + (((Object)val).name ?? "unknown") + "'") : "local player");
if (flag)
{
Plugin.VerboseLog("Ghost redirect -> " + text);
}
PhotonView photonView = ((MonoBehaviourPun)val).photonView;
string text2 = ((photonView != null) ? photonView.ViewID.ToString() : null) ?? "null";
Plugin.VerboseLog($"Spawn: '{((Object)prefab).name}', target={text}, viewId={text2}, online={PhotonNetwork.IsConnected}, inRoom={PhotonNetwork.InRoom}");
try
{
if ((Object)(object)GameUtils.instance != (Object)null)
{
GameUtils.instance.InstantiateAndGrab(prefab, val, 0);
Plugin.VerboseLog("Spawn completed: " + ((Object)prefab).name);
statusMessage = (flag ? ("[ItemBrowser] Spawned " + FormatItemCommandLabel(prefab) + " -> sent to " + text + ".") : ("[ItemBrowser] Spawned " + FormatItemCommandLabel(prefab) + "."));
return true;
}
statusMessage = "[ItemBrowser] GameUtils.instance is null, cannot spawn " + ((Object)prefab).name + ".";
Plugin.Log.LogError((object)statusMessage);
return false;
}
catch (Exception ex)
{
statusMessage = "[ItemBrowser] Spawn failed for " + ((Object)prefab).name + ": " + ex.Message;
Plugin.Log.LogError((object)statusMessage);
return false;
}
}
private static string FormatItemCommandLabel(Item item)
{
if ((Object)(object)item == (Object)null)
{
return "<null>";
}
string text = Localization.NormalizeItemNameForMap(((Object)item).name ?? string.Empty);
string text2 = ItemLoader.GetResolvedItemDisplayName(item).Trim();
if (string.IsNullOrWhiteSpace(text2) || string.Equals(text2, text, StringComparison.OrdinalIgnoreCase))
{
return "'" + text + "'";
}
return "'" + text2 + "' (" + text + ")";
}
private static void ReportConsoleInfo(string message)
{
if (!string.IsNullOrWhiteSpace(message))
{
Plugin.Log.LogInfo((object)message);
Debug.Log((object)message);
}
}
private static void ReportConsoleWarning(string message)
{
if (!string.IsNullOrWhiteSpace(message))
{
Plugin.Log.LogWarning((object)message);
Debug.LogWarning((object)message);
}
}
public static void RefreshConsoleCommands()
{
try
{
ConsoleHandler.Initialize(ConsoleHandler.ScanForConsoleCommands(), ConsoleHandler.ScanForTypeParsers());
Plugin.VerboseLog("Console commands refreshed.");
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[ItemBrowser] Failed to refresh console commands: " + ex.GetType().Name + " " + ex.Message));
}
}
}
internal static class Localization
{
private static readonly Dictionary<string, List<string>> _localizedTextTable = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, string> _itemNameKeyMap = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static bool _itemNameKeyMapInitialized;
private static int _lastRenderedLanguageIndex = -1;
internal static int LastRenderedLanguageIndex
{
get
{
return _lastRenderedLanguageIndex;
}
set
{
_lastRenderedLanguageIndex = value;
}
}
internal static string GetLocalizedItemName(Item item)
{
if ((Object)(object)item == (Object)null)
{
return string.Empty;
}
EnsureItemNameKeyMap();
string text = ((Object)item).name ?? string.Empty;
if (ContainsNonAscii(text))
{
return text.Trim();
}
string text2 = NormalizeItemNameForMap(text);
if (!string.IsNullOrEmpty(text2) && _itemNameKeyMap.TryGetValue(text2, out string value))
{
return ResolveLocalizedText(value);
}
return string.Empty;
}
private static void EnsureItemNameKeyMap()
{
if (!_itemNameKeyMapInitialized)
{
LoadItemNameKeyMap();
_itemNameKeyMapInitialized = true;
}
}
private static void LoadItemNameKeyMap()
{
_itemNameKeyMap.Clear();
try
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ItemNameKeyMap.json");
if (stream == null)
{
Plugin.Log.LogWarning((object)"[ItemBrowser] Embedded ItemNameKeyMap.json not found.");
return;
}
using StreamReader streamReader = new StreamReader(stream);
string text = streamReader.ReadToEnd();
Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(text);
if (dictionary == null)
{
return;
}
foreach (KeyValuePair<string, string> item in dictionary)
{
if (!string.IsNullOrWhiteSpace(item.Key) && !string.IsNullOrWhiteSpace(item.Value))
{
_itemNameKeyMap[item.Key] = item.Value;
}
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[ItemBrowser] Failed to load embedded ItemNameKeyMap.json: " + ex.GetType().Name + " " + ex.Message));
}
}
internal static string NormalizeItemNameForMap(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
return string.Empty;
}
string text = StripLocPrefix(name.Trim());
return text.Replace("(Clone)", "").Trim();
}
private static bool ContainsNonAscii(string text)
{
if (string.IsNullOrEmpty(text))
{
return false;
}
for (int i = 0; i < text.Length; i++)
{
if (text[i] > '\u007f')
{
return true;
}
}
return false;
}
private static string StripLocPrefix(string key)
{
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
if (key.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase))
{
return key.Substring("LOC:".Length).Trim();
}
return key;
}
internal static string ResolveLocalizedText(string key)
{
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
try
{
string text = StripLocPrefix(key.Trim());
if (string.IsNullOrEmpty(text))
{
return string.Empty;
}
string text2 = LocalizedText.GetText(text, true);
if (string.IsNullOrEmpty(text2))
{
return string.Empty;
}
string text3 = text2.Trim();
if (text3.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase))
{
return string.Empty;
}
if (string.Equals(text3, text, StringComparison.OrdinalIgnoreCase))
{
return string.Empty;
}
return text3;
}
catch
{
return string.Empty;
}
}
internal static string GetText(string key, params string[] args)
{
string text = (GetLocalizationPrefix() + "_" + key).ToUpperInvariant();
string text2 = LocalizedText.GetText(text, true);
if (IsMissingLocalization(text2, text))
{
EnsureLocalizedTextInjected();
text2 = LocalizedText.GetText(text, true);
}
if (IsMissingLocalization(text2, text))
{
text2 = GetCachedLocalizedText(key);
}
if (string.IsNullOrEmpty(text2))
{
text2 = key;
}
return string.Format(text2, args);
}
internal static void LoadLocalizedText()
{
try
{
using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Localized_Text.json");
if (stream == null)
{
Plugin.Log.LogWarning((object)"[ItemBrowser] Embedded Localized_Text.json not found.");
return;
}
using StreamReader streamReader = new StreamReader(stream);
string text = streamReader.ReadToEnd();
Dictionary<string, List<string>> dictionary = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(text);
if (dictionary == null)
{
Plugin.Log.LogWarning((object)"[ItemBrowser] Localized_Text.json deserialized to null.");
return;
}
_localizedTextTable.Clear();
foreach (KeyValuePair<string, List<string>> item in dictionary)
{
if (string.IsNullOrWhiteSpace(item.Key))
{
continue;
}
List<string> value = item.Value;
if (value == null || value.Count == 0)
{
_localizedTextTable[item.Key] = new List<string> { item.Key };
continue;
}
string firstValue = value.FirstOrDefault((string x) => !string.IsNullOrWhiteSpace(x)) ?? item.Key;
List<string> list = value.Select((string x) => (!string.IsNullOrWhiteSpace(x)) ? x : firstValue).ToList();
if (list.Count == 0)
{
list.Add(firstValue);
}
_localizedTextTable[item.Key] = list;
}
EnsureLocalizedTextInjected();
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[ItemBrowser] Failed to load Localized_Text.json: " + ex.GetType().Name + " " + ex.Message));
}
}
private static string GetLocalizationPrefix()
{
return "Mod_" + Plugin.Name;
}
internal static void EnsureLocalizedTextInjected()
{
if (_localizedTextTable.Count == 0)
{
return;
}
if (LocalizedText.MAIN_TABLE == null)
{
Plugin.Log.LogWarning((object)"[ItemBrowser] LocalizedText.MAIN_TABLE is null. Skip localization injection.");
return;
}
string localizationPrefix = GetLocalizationPrefix();
foreach (KeyValuePair<string, List<string>> item in _localizedTextTable)
{
if (!string.IsNullOrWhiteSpace(item.Key) && item.Value != null && item.Value.Count != 0)
{
string key = (localizationPrefix + "_" + item.Key).ToUpperInvariant();
LocalizedText.MAIN_TABLE[key] = item.Value;
}
}
}
private static bool IsMissingLocalization(string? text, string key)
{
if (string.IsNullOrWhiteSpace(text))
{
return true;
}
string text2 = text.Trim();
if (text2.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (string.Equals(text2, key, StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
private static string GetCachedLocalizedText(string key)
{
if (!_localizedTextTable.TryGetValue(key, out List<string> value) || value == null || value.Count == 0)
{
return string.Empty;
}
int num = GetCurrentLanguageIndex();
if (num < 0 || num >= value.Count)
{
num = 0;
}
string text = value[num];
if (string.IsNullOrWhiteSpace(text))
{
text = value[0];
}
return text?.Trim() ?? string.Empty;
}
internal static int GetCurrentLanguageIndex()
{
try
{
Type typeFromHandle = typeof(LocalizedText);
string[] array = new string[6] { "CurrentLanguageIndex", "CurrentLanguage", "LanguageIndex", "Language", "currentLanguageIndex", "currentLanguage" };
string[] array2 = array;
foreach (string name in array2)
{
PropertyInfo property = typeFromHandle.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (!(property == null))
{
object value = property.GetValue(null);
if (TryConvertLanguageIndex(value, out var index))
{
return NormalizeLanguageIndex(index);
}
}
}
string[] array3 = array;
foreach (string name2 in array3)
{
FieldInfo field = typeFromHandle.GetField(name2, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field == null))
{
object value2 = field.GetValue(null);
if (TryConvertLanguageIndex(value2, out var index2))
{
return NormalizeLanguageIndex(index2);
}
}
}
}
catch
{
}
return 0;
}
private static int NormalizeLanguageIndex(int index)
{
if (index >= 0)
{
return index;
}
return 0;
}
private static bool TryConvertLanguageIndex(object? value, out int index)
{
index = 0;
if (value == null)
{
return false;
}
if (value is int num)
{
index = num;
return true;
}
if (value is Enum value2)
{
index = Convert.ToInt32(value2);
return true;
}
if (value is byte b)
{
index = b;
return true;
}
if (value is short num2)
{
index = num2;
return true;
}
if (value is long num3)
{
index = (int)num3;
return true;
}
return false;
}
internal static string GetTextOrFallback(string key, string fallback)
{
string text = GetText(key);
if (string.IsNullOrWhiteSpace(text) || string.Equals(text, key, StringComparison.OrdinalIgnoreCase))
{
return fallback;
}
return text;
}
internal static string BuildLanguageMarker()
{
return GetText("TITLE") + "|" + GetText("SEARCH_PLACEHOLDER");
}
}
internal enum MajorCategory
{
All,
Food,
Weapon
}
internal enum ItemCategory
{
NaturalFood,
MysticalFood,
PackagedFood,
Mushroom,
Consumable,
Deployable,
MiscEquipment,
MysticalItem
}
internal sealed class ItemEntry
{
public Item Prefab { get; }
public string PrefabName { get; }
public string DisplayName { get; private set; } = string.Empty;
public ItemCategory Category { get; }
public Sprite? Icon { get; private set; }
public string SearchText { get; private set; } = string.Empty;
public ItemEntry(Item prefab, string displayName, ItemCategory category, Sprite? icon)
{
Prefab = prefab;
PrefabName = ((Object)prefab).name ?? string.Empty;
Category = category;
Icon = icon;
UpdateDisplayName(displayName);
}
public void UpdateIcon(Sprite? icon)
{
Icon = icon;
}
public void UpdateDisplayName(string displayName)
{
string text2 = (DisplayName = (string.IsNullOrWhiteSpace(displayName) ? PrefabName : displayName.Trim()));
SearchText = (text2 + " " + PrefabName).ToLowerInvariant();
}
}
internal sealed class PooledItemButton
{
public PeakMenuButton Button { get; }
public RectTransform ButtonRect { get; }
public Image IconImage { get; }
public ItemButtonBinder Binder { get; }
public int PoolIndex { get; }
public int BoundDataIndex { get; set; }
public PooledItemButton(PeakMenuButton button, RectTransform buttonRect, Image iconImage, ItemButtonBinder binder, int poolIndex)
{
Button = button;
ButtonRect = buttonRect;
IconImage = iconImage;
Binder = binder;
PoolIndex = poolIndex;
BoundDataIndex = -1;
}
}
internal sealed class ItemButtonBinder : MonoBehaviour
{
public Item? Prefab;
public void HandleClick()
{
if ((Object)(object)Prefab != (Object)null)
{
ItemSpawner.SpawnItem(Prefab);
}
}
}
internal sealed class CategoryTab
{
public ItemCategory? Category { get; }
public GameObject Root { get; }
public Button Button { get; }
public Image Background { get; }
public Image Selected { get; }
public PeakText Label { get; }
public CategoryTab(ItemCategory? category, GameObject root, Button button, Image background, Image selected, PeakText label)
{
Category = category;
Root = root;
Button = button;
Background = background;
Selected = selected;
Label = label;
}
}
internal sealed class MajorCategoryTab
{
public MajorCategory Category { get; }
public GameObject Root { get; }
public Button Button { get; }
public Image Background { get; }
public Image Selected { get; }
public PeakText Label { get; }
public MajorCategoryTab(MajorCategory category, GameObject root, Button button, Image background, Image selected, PeakText label)
{
Category = category;
Root = root;
Button = button;
Background = background;
Selected = selected;
Label = label;
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.github.cherrycove.ItemBrowser", "ItemBrowser", "0.2.4")]
public class Plugin : BaseUnityPlugin
{
private static float _nextUIWarmupCheckTime;
private static bool _firstOpenPrimed;
private static bool _hiddenMenuWindowPrimed;
private static bool _postSpawnPrimeLocked;
private static float _nextHiddenPrimeCheckTime;
private static float _nextPostSpawnPrimeCheckTime;
public const string Id = "com.github.cherrycove.ItemBrowser";
internal static ManualLogSource Log { get; private set; }
public static string Name => "ItemBrowser";
public static string Version => "0.2.4";
private void Awake()
{
SharedState.Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
SharedState.ConfigToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("ItemBrowser", "Toggle Key", (KeyCode)286, "Press to open/close the item browser.");
SharedState.ConfigAllowOnline = ((BaseUnityPlugin)this).Config.Bind<bool>("ItemBrowser", "Allow Online Spawn", true, "Allow spawning items while online.");
SharedState.ConfigVerboseLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("ItemBrowser", "Verbose Logs", false, "Enable detailed category/UI/spawn logs.");
SharedState.ConfigGhostSendToObserved = ((BaseUnityPlugin)this).Config.Bind<bool>("ItemBrowser", "Ghost Send To Observed", true, "When dead or in ghost/spectate mode, send spawned items to the currently observed teammate instead of the local (dead) character.");
Localization.LoadLocalizedText();
ItemSpawner.RefreshConsoleCommands();
}
private void OnDestroy()
{
if ((Object)(object)SharedState.Instance == (Object)(object)this)
{
SharedState.Instance = null;
}
ItemLoader.ResetState();
IconResolver.ResetIconPrewarmState(stopCoroutine: true);
VirtualList.ResetState();
}
private void Update()
{
ValidateRuntimeState();
VirtualList.TickVirtualizedScrollApply();
TickBackgroundUIWarmup();
ItemLoader.TickBackgroundItemPreload();
IconResolver.TickBackgroundIconPrewarm();
VirtualList.TickBackgroundButtonPoolWarmup();
TickHiddenFirstOpenPrime();
TickPostSpawnPrimeLock();
if (InputHandler.IsTogglePressed())
{
ToggleUI();
}
}
private static void ValidateRuntimeState()
{
if (SharedState.UiBuilt && (Object)(object)SharedState.Page == (Object)null)
{
UIBuilder.ResetState("Cached UI page was destroyed.");
}
ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance;
if (!((Object)(object)instance == (Object)null) && ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects != null && ((DatabaseAsset<ItemDatabase, Item>)(object)instance).Objects.Count != 0)
{
int instanceID = ((Object)instance).GetInstanceID();
if (SharedState.ItemPreloadRunning && SharedState.PreloadingDatabaseId != 0 && SharedState.PreloadingDatabaseId != instanceID)
{
InvalidateItemListState($"ItemDatabase changed while preloading ({SharedState.PreloadingDatabaseId}->{instanceID}).");
}
else if (!SharedState.ItemPreloadRunning && SharedState.ItemListInitialized && SharedState.LoadedDatabaseId != 0 && SharedState.LoadedDatabaseId != instanceID)
{
InvalidateItemListState($"ItemDatabase changed ({SharedState.LoadedDatabaseId}->{instanceID}). Re-preloading.");
}
}
}
private static void InvalidateItemListState(string reason)
{
ItemLoader.ResetState();
IconResolver.ResetIconPrewarmState(stopCoroutine: true);
SharedState.ItemListInitialized = false;
SharedState.PreloadingDatabaseId = 0;
SharedState.LoadedDatabaseId = 0;
SharedState.ItemNamesLanguageIndex = -1;
SharedState.ItemNamesLanguageMarker = string.Empty;
SharedState.ListNeedsRefresh = true;
SharedState.ListRenderRunning = false;
SharedState.ListRenderGeneration++;
_firstOpenPrimed = false;
_hiddenMenuWindowPrimed = false;
_postSpawnPrimeLocked = false;
_nextHiddenPrimeCheckTime = 0f;
_nextPostSpawnPrimeCheckTime = 0f;
SharedState.ItemEntries.Clear();
SharedState.ItemIconCache.Clear();
SharedState.GeneratedTextureSpriteCache.Clear();
SharedState.ItemButtonPool.Clear();
SharedState.ActiveRenderEntries.Clear();
VirtualList.ResetState();
VirtualList.ResetButtonPoolWarmupState(stopCoroutine: true);
VerboseLog(reason);
VirtualList.MarkListDirty(reason);
if (SharedState.PageOpen)
{
VirtualList.RefreshListIfNeeded(force: true);
}
}
private static void TickBackgroundUIWarmup()
{
if (!SharedState.UiBuilt && !(Time.unscaledTime < _nextUIWarmupCheckTime))
{
_nextUIWarmupCheckTime = Time.unscaledTime + 0.1f;
if (UIBuilder.IsUIReady(out string _))
{
UIBuilder.BuildUI();
SharedState.UiBuilt = true;
VerboseLog("UI warmup build completed.");
}
}
}
private static void ToggleUI()
{
if (EnsureUIBuilt())
{
if (SharedState.PageOpen)
{
UIBuilder.ClosePage();
}
else
{
UIBuilder.OpenPage();
}
}
}
private static bool EnsureUIBuilt()
{
if (SharedState.UiBuilt)
{
if ((Object)(object)SharedState.Page != (Object)null)
{
return true;
}
UIBuilder.ResetState("Cached UI page was destroyed.");
}
if (!UIBuilder.IsUIReady(out string reason))
{
Log.LogWarning((object)("[ItemBrowser] UI not ready yet (" + reason + "). Try again after fully entering a match."));
return false;
}
UIBuilder.BuildUI();
SharedState.UiBuilt = true;
VerboseLog("UI build completed.");
return true;
}
private static void TickHiddenFirstOpenPrime()
{
if (!_firstOpenPrimed && !SharedState.PageOpen && SharedState.UiBuilt && !((Object)(object)SharedState.ScrollContent == (Object)null) && SharedState.ItemListInitialized && !SharedState.ItemPreloadRunning && !((Object)(object)Character.localCharacter != (Object)null) && !(Time.unscaledTime < _nextHiddenPrimeCheckTime))
{
_nextHiddenPrimeCheckTime = Time.unscaledTime + 0.25f;
TabsManager.RefreshLanguageDependentContent();
VirtualList.RefreshListIfNeeded();
if (!_hiddenMenuWindowPrimed && (Object)(object)Character.localCharacter == (Object)null)
{
PrimeMenuWindowOpenClose();
}
if (!SharedState.ListNeedsRefresh && !SharedState.ListRenderRunning)
{
_firstOpenPrimed = true;
VerboseLog("Hidden first-open cache primed.");
}
}
}
private static void PrimeMenuWindowOpenClose()
{
if (_hiddenMenuWindowPrimed || (Object)(object)SharedState.Page == (Object)null || SharedState.PageOpen)
{
return;
}
try
{
UIBuilder.OpenPage();
Canvas.ForceUpdateCanvases();
RectTransform listContent = VirtualList.GetListContent();
if ((Object)(object)listContent != (Object)null)
{
LayoutRebuilder.ForceRebuildLayoutImmediate(listContent);
}
UIBuilder.ClosePage();
Canvas.ForceUpdateCanvases();
_hiddenMenuWindowPrimed = true;
VerboseLog("Menu window warmup completed before first manual F5.");
}
catch (Exception ex)
{
VerboseLog("Menu window warmup failed: " + ex.GetType().Name + " " + ex.Message);
}
}
private static void TickPostSpawnPrimeLock()
{
if (_postSpawnPrimeLocked || SharedState.PageOpen || !SharedState.UiBuilt || (Object)(object)SharedState.ScrollContent == (Object)null || (Object)(object)Character.localCharacter == (Object)null || Time.unscaledTime < _nextPostSpawnPrimeCheckTime)
{
return;
}
_nextPostSpawnPrimeCheckTime = Time.unscaledTime + 0.1f;
if (!_hiddenMenuWindowPrimed)
{
PrimeMenuWindowOpenClose();
}
if (SharedState.ItemListInitialized && !SharedState.ItemPreloadRunning)
{
TabsManager.RefreshLanguageDependentContent();
VirtualList.RefreshListIfNeeded();
if (!SharedState.ListNeedsRefresh && !SharedState.ListRenderRunning && _hiddenMenuWindowPrimed)
{
_postSpawnPrimeLocked = true;
VerboseLog("Post-spawn prime lock completed.");
}
}
}
internal static void VerboseLog(string message)
{
if (SharedState.ConfigVerboseLogs.Value)
{
Log.LogInfo((object)("[ItemBrowser] " + message));
}
}
}
internal static class SharedState
{
public static ConfigEntry<KeyCode>? ConfigToggleKey;
public static ConfigEntry<bool>? ConfigAllowOnline;
public static ConfigEntry<bool>? ConfigVerboseLogs;
public static ConfigEntry<bool>? ConfigGhostSendToObserved;
public static readonly Color TabInactiveBg = new Color(0.22f, 0.17f, 0.12f, 0.95f);
public static readonly Color TabActiveBg = new Color(0.95f, 0.92f, 0.86f, 1f);
public static readonly Color TabInactiveText = new Color(0.92f, 0.88f, 0.8f, 1f);
public static readonly Color TabActiveText = new Color(0.2f, 0.16f, 0.12f, 1f);
public static readonly Color TabHighlightedBg = new Color(0.26f, 0.2f, 0.14f, 1f);
public static readonly Color TabPressedBg = new Color(0.16f, 0.12f, 0.09f, 1f);
public static PeakCustomPage? Page;
public static PeakText? HeaderTitleText;
public static PeakMenuButton? CloseMenuButton;
public static PeakTextInput? SearchInput;
public static PeakScrollableContent? ScrollContent;
public static PeakHorizontalTabs? MajorTabs;
public static PeakHorizontalTabs? SubCategoryTabs;
public static GameObject? SubCategoryTabsRoot;
public static RectTransform? TopControlsRect;
public static RectTransform? ListContainerRect;
public static ScrollRect? ListScrollRect;
public static GridLayoutGroup? ItemGridLayout;
public static Plugin? Instance;
public static bool UiBuilt;
public static bool PageOpen;
public static bool ListNeedsRefresh = true;
public static bool ListRenderRunning;
public static int ListRenderGeneration;
public static readonly List<ItemEntry> ItemEntries = new List<ItemEntry>();
public static bool ItemListInitialized;
public static bool ItemPreloadRunning;
public static int PreloadingDatabaseId;
public static int LoadedDatabaseId;
public static int ItemNamesLanguageIndex = -1;
public static string ItemNamesLanguageMarker = string.Empty;
public static readonly Dictionary<string, Sprite?> ItemIconCache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase);
public static readonly Dictionary<int, Sprite> GeneratedTextureSpriteCache = new Dictionary<int, Sprite>();
public static readonly List<PooledItemButton> ItemButtonPool = new List<PooledItemButton>();
public static readonly List<ItemEntry> ActiveRenderEntries = new List<ItemEntry>();
public static string CurrentSearch = string.Empty;
public static MajorCategory CurrentMajorFilter = MajorCategory.All;
public static ItemCategory? CurrentSubCategoryFilter;
public static readonly List<MajorCategoryTab> MajorTabEntries = new List<MajorCategoryTab>();
public static readonly List<CategoryTab> SubCategoryTabEntries = new List<CategoryTab>();
public static string LastLanguageMarker = string.Empty;
}
internal static class TabsManager
{
internal static void BuildMajorTabs(PeakHorizontalTabs tabs)
{
if (!((Object)(object)tabs == (Object)null))
{
SharedState.MajorTabEntries.Clear();
AddMajorTab(tabs, CategorySystem.GetMajorCategoryLabel(MajorCategory.All), MajorCategory.All, 226.67f);
AddMajorTab(tabs, CategorySystem.GetMajorCategoryLabel(MajorCategory.Food), MajorCategory.Food, 226.67f);
AddMajorTab(tabs, CategorySystem.GetMajorCategoryLabel(MajorCategory.Weapon), MajorCategory.Weapon, 226.67f);
UpdateMajorTabs();
}
}
private static void AddMajorTab(PeakHorizontalTabs tabs, string label, MajorCategory category, float width)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
GameObject val = tabs.AddTab(label);
if (TrySetupTabVisual(val, width, 44f, out Button button, out Image background, out Image selected, out PeakText labelText))
{
MajorCategoryTab majorCategoryTab = new MajorCategoryTab(category, val, button, background, selected, labelText);
SharedState.MajorTabEntries.Add(majorCategoryTab);
((UnityEvent)button.onClick).AddListener((UnityAction)delegate
{
SharedState.CurrentMajorFilter = category;
SharedState.CurrentSubCategoryFilter = null;
UpdateMajorTabs();
RebuildSubCategoryTabs();
UpdateSubCategoryVisibility();
VirtualList.MarkListDirty("Major category changed");
VirtualList.RefreshListIfNeeded(force: true);
});
ApplyMajorTabStyle(majorCategoryTab, category == SharedState.CurrentMajorFilter);
}
}
internal static void UpdateMajorTabs()
{
for (int i = 0; i < SharedState.MajorTabEntries.Count; i++)
{
MajorCategoryTab majorCategoryTab = SharedState.MajorTabEntries[i];
bool selected = majorCategoryTab.Category == SharedState.CurrentMajorFilter;
ApplyMajorTabStyle(majorCategoryTab, selected);
}
}
internal static void RebuildSubCategoryTabs()
{
if ((Object)(object)SharedState.SubCategoryTabs == (Object)null)
{
return;
}
Transform val = ((Component)SharedState.SubCategoryTabs).transform.Find("Content");
if ((Object)(object)val != (Object)null)
{
for (int num = val.childCount - 1; num >= 0; num--)
{
Object.Destroy((Object)(object)((Component)val.GetChild(num)).gameObject);
}
}
SharedState.SubCategoryTabEntries.Clear();
ItemCategory[] subCategories = CategorySystem.GetSubCategories(SharedState.CurrentMajorFilter);
if (subCategories.Length != 0)
{
if (!SharedState.CurrentSubCategoryFilter.HasValue || !Array.Exists(subCategories, (ItemCategory c) => c == SharedState.CurrentSubCategoryFilter.Value))
{
SharedState.CurrentSubCategoryFilter = subCategories[0];
}
foreach (ItemCategory itemCategory in subCategories)
{
AddSubCategoryTab(SharedState.SubCategoryTabs, CategorySystem.GetCategoryLabel(itemCategory), itemCategory, 170f);
}
UpdateSubCategoryTabs();
}
}
private static void AddSubCategoryTab(PeakHorizontalTabs tabs, string label, ItemCategory? category, float width)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
GameObject val = tabs.AddTab(label);
if (TrySetupTabVisual(val, width, 40f, out Button button, out Image background, out Image selected, out PeakText labelText))
{
CategoryTab categoryTab = new CategoryTab(category, val, button, background, selected, labelText);
SharedState.SubCategoryTabEntries.Add(categoryTab);
((UnityEvent)button.onClick).AddListener((UnityAction)delegate
{
SharedState.CurrentSubCategoryFilter = category;
UpdateSubCategoryTabs();
VirtualList.MarkListDirty("Sub category changed");
VirtualList.RefreshListIfNeeded(force: true);
});
ApplySubCategoryTabStyle(categoryTab, category == SharedState.CurrentSubCategoryFilter);
}
}
private static bool TrySetupTabVisual(GameObject tab, float width, float height, out Button button, out Image background, out Image selected, out PeakText labelText)
{
button = null;
background = null;
selected = null;
labelText = null;
if ((Object)(object)tab == (Object)null)
{
return false;
}
LayoutElement val = tab.GetComponent<LayoutElement>();
if ((Object)(object)val == (Object)null)
{
val = tab.AddComponent<LayoutElement>();
}
val.minWidth = width;
val.preferredWidth = width;
val.flexibleWidth = 0f;
val.preferredHeight = height;
button = tab.GetComponent<Button>();
Transform obj = tab.transform.Find("Image");
background = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
Transform obj2 = tab.transform.Find("Selected");
selected = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
labelText = tab.GetComponentInChildren<PeakText>(true);
if ((Object)(object)button == (Object)null || (Object)(object)background == (Object)null || (Object)(object)selected == (Object)null || (Object)(object)labelText == (Object)null)
{
return false;
}
((TMP_Text)labelText.TextMesh).fontStyle = (FontStyles)0;
((TMP_Text)labelText.TextMesh).enableAutoSizing = false;
((TMP_Text)labelText.TextMesh).fontSize = 18f;
((TMP_Text)labelText.TextMesh).alignment = (TextAlignmentOptions)514;
((Graphic)background).raycastTarget = true;
((Graphic)selected).raycastTarget = false;
((Graphic)labelText.TextMesh).raycastTarget = false;
return true;
}
internal static void UpdateSubCategoryVisibility()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
bool flag = SharedState.CurrentMajorFilter != MajorCategory.All;
if ((Object)(object)SharedState.SubCategoryTabsRoot != (Object)null)
{
SharedState.SubCategoryTabsRoot.SetActive(flag);
}
if ((Object)(object)SharedState.TopControlsRect != (Object)null)
{
SharedState.TopControlsRect.sizeDelta = new Vector2(SharedState.TopControlsRect.sizeDelta.x, flag ? 166f : 122f);
}
if ((Object)(object)SharedState.ListContainerRect != (Object)null)
{
SharedState.ListContainerRect.offsetMax = (flag ? new Vector2(-20f, -236f) : new Vector2(-20f, -192f));
}
}
internal static void RefreshLanguageDependentContent(bool force = false)
{
int currentLanguageIndex = Localization.GetCurrentLanguageIndex();
string text = Localization.GetText("TITLE");
string text2 = Localization.GetText("SEARCH_PLACEHOLDER");
string text3 = text + "|" + text2;
bool flag = !string.Equals(text3, SharedState.LastLanguageMarker, StringComparison.Ordinal);
if (force || flag)
{
SharedState.LastLanguageMarker = text3;
Localization.LastRenderedLanguageIndex = currentLanguageIndex;
if ((Object)(object)SharedState.HeaderTitleText != (Object)null)
{
((TMP_Text)SharedState.HeaderTitleText.TextMesh).text = text;
}
PeakMenuButton? closeMenuButton = SharedState.CloseMenuButton;
if ((Object)(object)((closeMenuButton != null) ? ((PeakLocalizableElement)closeMenuButton).Text : null) != (Object)null)
{
((PeakLocalizableElement)SharedState.CloseMenuButton).Text.text = Localization.GetTextOrFallback("CLOSE_BUTTON", "Close");
}
if ((Object)(object)SharedState.SearchInput != (Object)null)
{
SharedState.SearchInput.SetPlaceholder(text2);
}
for (int i = 0; i < SharedState.MajorTabEntries.Count; i++)
{
MajorCategoryTab majorCategoryTab = SharedState.MajorTabEntries[i];
((TMP_Text)majorCategoryTab.Label.TextMesh).text = CategorySystem.GetMajorCategoryLabel(majorCategoryTab.Category);
}
for (int j = 0; j < SharedState.SubCategoryTabEntries.Count; j++)
{
CategoryTab categoryTab = SharedState.SubCategoryTabEntries[j];
string text4 = (categoryTab.Category.HasValue ? CategorySystem.GetCategoryLabel(categoryTab.Category.Value) : CategorySystem.GetAllSubCategoryLabel());
((TMP_Text)categoryTab.Label.TextMesh).text = text4;
}
ItemLoader.RefreshItemDisplayNamesForCurrentLanguage(force: false, text3);
VirtualList.MarkListDirty("Language changed");
}
}
private static void UpdateSubCategoryTabs()
{
for (int i = 0; i < SharedState.SubCategoryTabEntries.Count; i++)
{
CategoryTab categoryTab = SharedState.SubCategoryTabEntries[i];
bool selected = categoryTab.Category == SharedState.CurrentSubCategoryFilter;
ApplySubCategoryTabStyle(categoryTab, selected);
}
}
internal static void ApplyMajorTabStyle(MajorCategoryTab tab, bool selected)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
((Graphic)tab.Background).color = SharedState.TabInactiveBg;
((Graphic)tab.Selected).color = SharedState.TabActiveBg;
((Behaviour)tab.Selected).enabled = selected;
((Graphic)tab.Label.TextMesh).color = (selected ? SharedState.TabActiveText : SharedState.TabInactiveText);
ColorBlock colors = ((Selectable)tab.Button).colors;
((ColorBlock)(ref colors)).normalColor = SharedState.TabInactiveBg;
((ColorBlock)(ref colors)).highlightedColor = SharedState.TabHighlightedBg;
((ColorBlock)(ref colors)).pressedColor = SharedState.TabPressedBg;
((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).normalColor;
((Selectable)tab.Button).colors = colors;
}
internal static void ApplySubCategoryTabStyle(CategoryTab tab, bool selected)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
((Graphic)tab.Background).color = SharedState.TabInactiveBg;
((Graphic)tab.Selected).color = SharedState.TabActiveBg;
((Behaviour)tab.Selected).enabled = selected;
((Graphic)tab.Label.TextMesh).color = (selected ? SharedState.TabActiveText : SharedState.TabInactiveText);
ColorBlock colors = ((Selectable)tab.Button).colors;
((ColorBlock)(ref colors)).normalColor = SharedState.TabInactiveBg;
((ColorBlock)(ref colors)).highlightedColor = SharedState.TabHighlightedBg;
((ColorBlock)(ref colors)).pressedColor = SharedState.TabPressedBg;
((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).normalColor;
((Selectable)tab.Button).colors = colors;
}
internal static void ResetState()
{
SharedState.MajorTabEntries.Clear();
SharedState.SubCategoryTabEntries.Clear();
}
}
internal static class UIBuilder
{
[CompilerGenerated]
private static class <>O
{
public static UnityAction <0>__ClosePage;
public static UnityAction<string> <1>__OnSearchChanged;
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static Func<GameObject, bool> <>9__5_0;
public static Func<GameObject, bool> <>9__5_1;
public static UnityAction <>9__8_0;
public static UnityAction <>9__8_1;
public static UnityAction<Vector2> <>9__8_2;
public static Func<MethodInfo, bool> <>9__17_0;
public static Func<MethodInfo, bool> <>9__17_1;
internal bool <TryRecoverButtonTemplate>b__5_0(GameObject obj)
{
if ((Object)(object)obj != (Object)null)
{
return ((Object)obj).name == "UI_MainMenuButton_LeaveGame (2)";
}
return false;
}
internal bool <TryRecoverButtonTemplate>b__5_1(GameObject obj)
{
if ((Object)(object)obj != (Object)null)
{
return ((Object)obj).name.StartsWith("UI_MainMenuButton_LeaveGame", StringComparison.Ordinal);
}
return false;
}
internal void <BuildUI>b__8_0()
{
SharedState.PageOpen = true;
TabsManager.RefreshLanguageDependentContent();
ItemLoader.EnsureItemList();
VirtualList.RefreshListIfNeeded();
}
internal void <BuildUI>b__8_1()
{
SharedState.PageOpen = false;
}
internal void <BuildUI>b__8_2(Vector2 _)
{
VirtualList.OnVirtualizedScrollChanged();
}
internal bool <ClosePage>b__17_0(MethodInfo m)
{
if (m.Name == "Close")
{
return m.GetParameters().Length == 0;
}
return false;
}
internal bool <ClosePage>b__17_1(MethodInfo m)
{
if (m.Name == "Close")
{
return m.GetParameters().Length == 1;
}
return false;
}
}
private static bool _buttonTemplateRecovered;
private static Scrollbar? _listScrollbar;
private static MethodInfo? _menuWindowOpenMethod;
private static MethodInfo? _menuWindowCloseMethod;
internal static bool IsUIReady(out string reason)
{
List<string> list = new List<string>(3);
InputCellMapper instance = SingletonAsset<InputCellMapper>.Instance;
if ((Object)(object)instance == (Object)null)
{
list.Add("InputCellMapper.Instance == null");
}
else if ((Object)(object)instance.FloatSettingCell == (Object)null)
{
list.Add("InputCellMapper.FloatSettingCell == null");
}
if ((Object)(object)Templates.ButtonTemplate == (Object)null && !TryRecoverButtonTemplate(out string reason2))
{
if (string.IsNullOrWhiteSpace(reason2))
{
list.Add("Templates.ButtonTemplate == null");
}
else
{
list.Add("Templates.ButtonTemplate == null (" + reason2 + ")");
}
}
if (list.Count == 0)
{
reason = string.Empty;
return true;
}
reason = string.Join(", ", list);
return false;
}
private static bool TryRecoverButtonTemplate(out string reason)
{
reason = string.Empty;
if ((Object)(object)Templates.ButtonTemplate != (Object)null)
{
return true;
}
try
{
GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
if (array == null || array.Length == 0)
{
reason = "Resources empty";
return false;
}
GameObject val = ((IEnumerable<GameObject>)array).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => (Object)(object)obj != (Object)null && ((Object)obj).name == "UI_MainMenuButton_LeaveGame (2)"));
if ((Object)(object)val == (Object)null)
{
val = ((IEnumerable<GameObject>)array).FirstOrDefault((Func<GameObject, bool>)((GameObject obj) => (Object)(object)obj != (Object)null && ((Object)obj).name.StartsWith("UI_MainMenuBu