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 MoreUI v1.3.4
Zichen-MoreUI-1.3.4.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Zichen-MoreUI-1.3.4")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+85a78bb8de5017ffff90b08f70b8ac4c36537b87")] [assembly: AssemblyProduct("Zichen-MoreUI-1.3.4")] [assembly: AssemblyTitle("Zichen-MoreUI-1.3.4")] [assembly: AssemblyVersion("1.0.0.0")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public enum DisplayMode { 文字显示, 原生UI显示 } public enum DisplayLanguage { 中文, English } [BepInPlugin("zichen.moreui", "MoreUI", "1.3.4")] public class Plugin : BaseUnityPlugin { internal sealed class CfgI18N { public string SectionCN; public string SectionEN; public string KeyCN; public string KeyEN; public string DisplayEN; public string DescCN; public string DescEN; public ConfigurationManagerAttributes Attrs; public string ValueEN; public string ValueCN; public ConfigEntry<string> ReadOnlyEntry; public ConfigEntryBase Entry; public bool ChineseOnly; } internal sealed class LiveLabel { public WeakReference<TextMeshProUGUI> Tmp; public CfgI18N I18N; public bool IsSection; } internal sealed class LiveValue { public WeakReference<Object> InputField; public CfgI18N I18N; } internal sealed class LiveSliderOptions { public WeakReference<Object> Slider; public CfgI18N I18N; public string[] OptionsCN; public string[] OptionsEN; } internal sealed class LiveToggleButtons { public WeakReference<TextMeshProUGUI> LeftTmp; public WeakReference<TextMeshProUGUI> RightTmp; } public const string PluginGuid = "zichen.moreui"; public const string PluginVersion = "1.3.4"; public const string PluginName = "MoreUI"; private static Plugin Instance; private const float MinimumRefreshIntervalSeconds = 0.1f; private const float RunLevelInactiveGraceSeconds = 4f; private const int PlayerHeadTopColorSlot = 5; private const float PlayerColorCacheRefreshSeconds = 0.2f; private const float PlayerPositionCacheSeconds = 0.15f; private const string TeammateIcon = "\ud83e\udd16"; private const string CartIcon = ""; private const float CartCacheInterval = 0.15f; private const float CartFarFontShrinkPercent = 30f; private const float TrackedObjectCleanupIntervalSeconds = 0.5f; private static readonly GUIContent ReusableGuiContent = new GUIContent(); private static readonly CultureInfo MoneyCulture = CultureInfo.GetCultureInfo("en-US"); private static readonly HashSet<int> BoundsVisitedBuffer = new HashSet<int>(); private static readonly List<Renderer> BoundsRendererBuffer = new List<Renderer>(); private static readonly List<Collider> BoundsColliderBuffer = new List<Collider>(); private static readonly Dictionary<int, Renderer[]> CachedChildRenderers = new Dictionary<int, Renderer[]>(); private static readonly Dictionary<int, Collider[]> CachedChildColliders = new Dictionary<int, Collider[]>(); private static readonly Dictionary<int, bool> PlayerAliveFrameCache = new Dictionary<int, bool>(); private static readonly HashSet<int> TrackedEnemyKeyBuffer = new HashSet<int>(); private static int playerAliveFrameCacheFrame = -1; private static readonly Dictionary<string, int> EnemyBreakdownRankTable = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { ["Apex Predator"] = 10, ["Bang"] = 11, ["Gnome"] = 12, ["Peeper"] = 13, ["Shadow Child"] = 14, ["Spewer"] = 15, ["Tick"] = 16, ["Bella"] = 17, ["Birthday Boy"] = 18, ["Elsa"] = 19, ["Animal"] = 20, ["Bowtie"] = 21, ["Head Grabber"] = 22, ["Heart Hugger"] = 23, ["Mentalist"] = 24, ["Oogly"] = 25, ["Rugrat"] = 26, ["Upscream"] = 27, ["Head"] = 30, ["Hidden"] = 31, ["Hunter"] = 32, ["Loom"] = 33, ["Reaper"] = 34, ["Robe"] = 35, ["Slow Mouth"] = 36, ["Slow Walker"] = 37, ["Trudge"] = 38, ["Cleanup Crew"] = 39, ["Beamer"] = 40, ["Gambit"] = 41 }; private static int cachedWorldLabelCameraFrame = -1; private static Camera cachedWorldLabelCamera; private static int cachedRunLevelActiveFrame = -1; private static bool cachedRunLevelActive; private static int cachedLocalPlayerFrame = -1; private static PlayerAvatar cachedLocalPlayer; private static readonly HashSet<int> valuablesCurrentlyInDollarHaul = new HashSet<int>(); private static readonly List<ValuableObject> trackedValuables = new List<ValuableObject>(); private static readonly HashSet<object> trackedValuableSet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<PhysGrabCart> trackedCarts = new List<PhysGrabCart>(); private static readonly HashSet<object> trackedCartSet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<ItemVehicle> trackedVehicles = new List<ItemVehicle>(); private static readonly HashSet<object> trackedVehicleSet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<ItemVehicle> preservedTrackedVehiclesBuffer = new List<ItemVehicle>(); private static readonly List<Enemy> trackedEnemies = new List<Enemy>(); private static readonly HashSet<object> trackedEnemySet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<PhysGrabber> trackedGrabbers = new List<PhysGrabber>(); private static readonly HashSet<object> trackedGrabberSet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<ItemAttributes> trackedItems = new List<ItemAttributes>(); private static readonly List<ItemAttributes> trackedTokenBoxItems = new List<ItemAttributes>(); private static readonly List<ValuableDiscoverCustom> trackedCustomDiscoverables = new List<ValuableDiscoverCustom>(); private static readonly List<CosmeticShopMachine> trackedCosmeticShopMachines = new List<CosmeticShopMachine>(); private static readonly Dictionary<int, int> trackedTokenBoxObjectRefCounts = new Dictionary<int, int>(); private static readonly HashSet<object> EmptyReferenceSet = new HashSet<object>(ReferenceObjectComparer.Instance); private static readonly List<PhysGrabCart> preservedTrackedCartsBuffer = new List<PhysGrabCart>(); private static readonly List<ItemAttributes> preservedTrackedItemsBuffer = new List<ItemAttributes>(); private static readonly List<ValuableDiscoverCustom> preservedTrackedCustomDiscoverablesBuffer = new List<ValuableDiscoverCustom>(); private static readonly List<CosmeticShopMachine> preservedTrackedCosmeticShopMachinesBuffer = new List<CosmeticShopMachine>(); private static int trackedTokenBoxObjectCount; private static float nextTrackedValuableCleanupAt; private static float nextTrackedCartCleanupAt; private static float nextTrackedVehicleCleanupAt; private static float nextTrackedEnemyCleanupAt; private static float nextTrackedGrabberCleanupAt; private static float nextTrackedTokenItemCleanupAt; private static float nextTrackedCustomDiscoverableCleanupAt; private static float nextTrackedCosmeticShopMachineCleanupAt; private ConfigEntry<bool> modEnabled; private ConfigEntry<bool> overlayEnabled; private ConfigEntry<bool> sectionSpacing; private ConfigEntry<DisplayLanguage> displayLanguage; private ConfigEntry<bool> enemyNicknameEnabled; private ConfigEntry<DisplayMode> displayMode; private ConfigEntry<int> fontSize; private ConfigEntry<int> overlayTextOpacityPercent; private ConfigEntry<float> updateInterval; private ConfigEntry<int> overlayOffsetX; private ConfigEntry<int> overlayOffsetY; private ConfigEntry<bool> showEnemySection; private ConfigEntry<bool> showBreakdown; private ConfigEntry<bool> showTotalEnemyCount; private ConfigEntry<bool> showTokenBoxCount; private ConfigEntry<bool> showValueSection; private ConfigEntry<bool> showMapLostValue; private ConfigEntry<bool> showExplorationProgress; private ConfigEntry<bool> showMapTotalValue; private ConfigEntry<bool> showCurrentRunSubmittedFunds; private ConfigEntry<bool> showShopRemainingFunds; private ConfigEntry<bool> showLevelInfo; private ConfigEntry<bool> showTeammateInfoSection; private ConfigEntry<bool> showDeadTeammates; private ConfigEntry<bool> showAliveTeammates; private ConfigEntry<bool> showPlayerCounts; private ConfigEntry<bool> teammateOverlayEnabled; private ConfigEntry<bool> teammateAliveOverlayEnabled; private ConfigEntry<bool> teammateDeadOverlayEnabled; private ConfigEntry<bool> teammateAliveEdgeOverlayEnabled; private ConfigEntry<bool> teammateDeadEdgeOverlayEnabled; private ConfigEntry<bool> teammateDistanceEnabled; private ConfigEntry<int> teammateFontSize; private ConfigEntry<bool> cartSectionEnabled; private ConfigEntry<bool> cartOverlayEnabled; private ConfigEntry<bool> smallCartOverlayEnabled; private ConfigEntry<bool> cartDistanceEnabled; private ConfigEntry<int> cartFontSize; private ConfigEntry<bool> showLargeCartCount; private ConfigEntry<bool> showSmallCartCount; private ConfigEntry<bool> showKartCount; private ConfigEntry<bool> showCargoCount; private ConfigEntry<bool> vehicleSectionEnabled; private ConfigEntry<bool> vehicleOverlayEnabled; private ConfigEntry<bool> racingVehicleOverlayEnabled; private ConfigEntry<bool> vehicleDistanceEnabled; private ConfigEntry<int> vehicleFontSize; private GameObject overlayObject; private RectTransform overlayRect; private TextMeshProUGUI overlayLabel; private readonly List<TextMeshProUGUI> nativeOverlayLineLabels = new List<TextMeshProUGUI>(); private readonly List<RectTransform> nativeOverlayLineRects = new List<RectTransform>(); private readonly List<NativeOverlayLineState> nativeOverlayLineStates = new List<NativeOverlayLineState>(); private readonly List<string> nativeOverlayLineTextBuffer = new List<string>(); private TMP_FontAsset nativeOverlayStableFont; private Material nativeOverlayStableMaterial; private bool nativeOverlayStableFontResolved; private Harmony valuableHaulHarmony; private Harmony nativeNameHarmony; private string overlayText = string.Empty; private string lastNativeOverlayText; private int lastNativeOverlayFontSize = -1; private int lastNativeOverlayOffsetX = int.MinValue; private int lastNativeOverlayOffsetY = int.MinValue; private bool lastNativeOverlayShowBreakdown; private float lastNativeOverlayOpacity = -1f; private Transform lastNativeOverlayParent; private string lastPlainOverlaySource; private string lastPlainOverlayText = string.Empty; private string lastTextOverlaySource; private int lastTextOverlayFontSize = -1; private bool lastTextOverlayShowBreakdown; private int lastTextOverlayOffsetX = int.MinValue; private int lastTextOverlayOffsetY = int.MinValue; private int lastTextOverlayScreenWidth = -1; private int lastTextOverlayScreenHeight = -1; private Rect cachedTextOverlayRect; private Rect cachedTextOverlayShadowRect; private float cachedTextOverlayWidth; private string cachedTextOverlayPlainText = string.Empty; private readonly List<MoreUiCartDistance> cartDistanceCache = new List<MoreUiCartDistance>(); private readonly List<MoreUiCartDistance> cartDistancePool = new List<MoreUiCartDistance>(); private readonly List<MoreUiVehicleDistance> vehicleDistanceCache = new List<MoreUiVehicleDistance>(); private readonly List<MoreUiVehicleDistance> vehicleDistancePool = new List<MoreUiVehicleDistance>(); private readonly List<int> reusableSnapshotKeys = new List<int>(); private readonly Dictionary<int, int> largeCartLabelIndices = new Dictionary<int, int>(); private readonly Dictionary<int, int> smallCartLabelIndices = new Dictionary<int, int>(); private readonly Dictionary<int, bool> smallCartTypeCache = new Dictionary<int, bool>(); private readonly Dictionary<int, GUIStyle> centeredRichLabelStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<int, GUIStyle> centeredShadowLabelStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<int, GUIStyle> overlayRichStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<int, GUIStyle> overlayShadowStyleCache = new Dictionary<int, GUIStyle>(); private readonly Dictionary<LabelSizeCacheKey, Vector2> centeredLabelSizeCache = new Dictionary<LabelSizeCacheKey, Vector2>(); private readonly StringBuilder reusableOverlayTextBuilder = new StringBuilder(512); private readonly StringBuilder reusableItemSearchTextBuilder = new StringBuilder(256); private readonly StringBuilder reusableNativeOverlayTagStripBuilder = new StringBuilder(256); private readonly List<Enemy> activeEnemyBuffer = new List<Enemy>(); private readonly Dictionary<string, int> enemyBreakdownBuffer = new Dictionary<string, int>(); private readonly Dictionary<string, int> enemyBreakdownRankBuffer = new Dictionary<string, int>(); private readonly Dictionary<int, int> enemyBreakdownRankCache = new Dictionary<int, int>(); private readonly Dictionary<string, int> enemyBreakdownRawNameRankCache = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private readonly List<KeyValuePair<string, int>> orderedEnemyBreakdownBuffer = new List<KeyValuePair<string, int>>(); private readonly List<object> currentDollarHaulObjectsBuffer = new List<object>(); private readonly List<object> currentCartObjectsBuffer = new List<object>(); private readonly HashSet<object> haulReferenceSetBuffer = new HashSet<object>(ReferenceObjectComparer.Instance); private readonly HashSet<object> cartReferenceSetBuffer = new HashSet<object>(ReferenceObjectComparer.Instance); private readonly List<PhysGrabCart> activeCartBuffer = new List<PhysGrabCart>(); private readonly List<CartLabelCandidate> cartLabelCandidateBuffer = new List<CartLabelCandidate>(); private readonly List<MoreUiPlayerDistance> teammateDistanceBuffer = new List<MoreUiPlayerDistance>(); private readonly List<MoreUiPlayerDistance> teammateDistancePool = new List<MoreUiPlayerDistance>(); private readonly List<TeammateEdgeLabelDrawInfo> leftEdgeTeammateLabelBuffer = new List<TeammateEdgeLabelDrawInfo>(); private readonly List<TeammateEdgeLabelDrawInfo> rightEdgeTeammateLabelBuffer = new List<TeammateEdgeLabelDrawInfo>(); private readonly List<Rect> leftEdgeTeammateRectBuffer = new List<Rect>(); private readonly List<Rect> rightEdgeTeammateRectBuffer = new List<Rect>(); private readonly Component[] cartBoundsRootBuffer = (Component[])(object)new Component[2]; private readonly Dictionary<int, CartComponentCache> cartComponentCache = new Dictionary<int, CartComponentCache>(); private readonly Dictionary<int, string> itemSearchTextCache = new Dictionary<int, string>(); private readonly Dictionary<int, bool> itemTokenBoxCandidateCache = new Dictionary<int, bool>(); private List<PlayerAvatar> playerObjectsFrameCache; private readonly Dictionary<int, string> enemyDisplayNameCache = new Dictionary<int, string>(); private readonly Dictionary<int, string> playerNameCache = new Dictionary<int, string>(); private readonly Dictionary<int, PlayerColorCacheEntry> playerColorCache = new Dictionary<int, PlayerColorCacheEntry>(); private readonly Dictionary<int, LabelYOffsetCache> cartLabelYOffsetCache = new Dictionary<int, LabelYOffsetCache>(); private readonly Dictionary<int, PlayerPositionCache> playerPositionCache = new Dictionary<int, PlayerPositionCache>(); private DisplayLanguage cachedEnemyDisplayNameLanguage; private bool cachedEnemyNicknameEnabled; private bool hasCachedEnemyDisplayNameLanguage; private float refreshTimer; private float cartRefreshTimer; private int enemyObjectsFrameCacheFrame = -1; private int cartObjectsFrameCacheFrame = -1; private int grabberObjectsFrameCacheFrame = -1; private int valuableObjectsFrameCacheFrame = -1; private int playerObjectsFrameCacheFrame = -1; private int playerNameCacheFrame = -1; private int teammateDistanceCacheFrame = -1; private int playerCountsFrame = -1; private int cachedTotalPlayers; private int cachedAlivePlayers; private int cachedDeadPlayers; private bool cartDistanceCacheValid; private bool vehicleDistanceCacheValid; private float vehicleRefreshTimer; private int cartLabelIndexLevelNumber = -1; private int nextLargeCartLabelIndex = 1; private int nextSmallCartLabelIndex = 1; private int trackedLevelNumber = -1; private int valuableSnapshotGeneration; private float previousExtractedValue = -1f; private float accumulatedLostValue; private bool hasLoggedUpdateError; private bool runtimeWasActive; private bool levelTransitionLogIndicatesRun; private float lastConfirmedRunLevelTime = -999f; private int submittedFundsSnapshotLevelNumber = -1; private float submittedFundsBaselineTotalHaul = -1f; private float submittedFundsSnapshot; private int shopRemainingSnapshotLevelNumber = -1; private float shopRemainingFundsSnapshot = -1f; private readonly Dictionary<int, ValuableSnapshot> valuableSnapshots = new Dictionary<int, ValuableSnapshot>(); private static readonly FieldRef<PlayerAvatar, bool> PlayerDeadSetRef = CreateFieldRef<PlayerAvatar, bool>("deadSet"); private static readonly FieldRef<PlayerAvatar, bool> PlayerIsDisabledRef = CreateFieldRef<PlayerAvatar, bool>("isDisabled"); private static readonly FieldRef<PlayerAvatar, string> PlayerNameRef = CreateFieldRef<PlayerAvatar, string>("playerName"); private static readonly FieldRef<PlayerAvatar, bool> PlayerIsLocalRef = CreateFieldRef<PlayerAvatar, bool>("isLocal"); private static readonly FieldRef<PlayerCosmetics, int[]> PlayerCosmeticsColorsEquippedRef = CreateFieldRef<PlayerCosmetics, int[]>("colorsEquipped"); private static readonly FieldRef<PlayerAvatar, PlayerDeathHead> PlayerDeathHeadRef = CreateFieldRef<PlayerAvatar, PlayerDeathHead>("playerDeathHead"); private static readonly FieldRef<PlayerAvatar, Vector3> PlayerLastNavmeshPositionRef = CreateFieldRef<PlayerAvatar, Vector3>("LastNavmeshPosition"); private static readonly FieldRef<PlayerDeathHead, PhysGrabObject> DeathHeadPhysGrabObjectRef = CreateFieldRef<PlayerDeathHead, PhysGrabObject>("physGrabObject"); private static readonly FieldRef<PlayerDeathHead, Vector3> DeathHeadTriggeredPositionRef = CreateFieldRef<PlayerDeathHead, Vector3>("triggeredPosition"); private static readonly FieldRef<PlayerDeathHead, Transform> DeathHeadOverridePositionTransformRef = CreateFieldRef<PlayerDeathHead, Transform>("overridePositionTransform"); private static readonly FieldRef<SpectateCamera, PlayerAvatar> SpectateCameraPlayerRef = CreateFieldRef<SpectateCamera, PlayerAvatar>("player"); private static readonly FieldRef<SpectateCamera, PlayerAvatar> SpectateCameraPlayerOverrideRef = CreateFieldRef<SpectateCamera, PlayerAvatar>("playerOverride"); private static readonly FieldRef<SpectateCamera, Camera> SpectateCameraMainCameraRef = CreateFieldRef<SpectateCamera, Camera>("MainCamera"); private static readonly FieldRef<Enemy, EnemyParent> EnemyParentRef = CreateFieldRef<Enemy, EnemyParent>("EnemyParent"); private static readonly FieldRef<Enemy, EnemyHealth> EnemyHealthRef = CreateFieldRef<Enemy, EnemyHealth>("Health"); private static readonly FieldRef<EnemyHealth, bool> EnemyHealthDeadRef = CreateFieldRef<EnemyHealth, bool>("dead"); private static readonly FieldRef<EnemyParent, bool> EnemyParentSpawnedRef = CreateFieldRef<EnemyParent, bool>("Spawned"); private static readonly FieldRef<EnemyParent, Enemy> EnemyParentEnemyRef = CreateFieldRef<EnemyParent, Enemy>("Enemy"); private static readonly FieldRef<ValuableObject, float> ValuableOriginalValueRef = CreateFieldRef<ValuableObject, float>("dollarValueOriginal"); private static readonly FieldRef<ValuableObject, float> ValuableCurrentValueRef = CreateFieldRef<ValuableObject, float>("dollarValueCurrent"); private static readonly FieldRef<ValuableObject, bool> ValuableValueSetRef = CreateFieldRef<ValuableObject, bool>("dollarValueSet"); private static readonly FieldRef<ValuableObject, PhotonView> ValuablePhotonViewRef = CreateFieldRef<ValuableObject, PhotonView>("photonView"); private static readonly FieldRef<ValuableObject, PhysGrabObject> ValuablePhysGrabObjectRef = CreateFieldRef<ValuableObject, PhysGrabObject>("physGrabObject"); private static readonly FieldRef<PhysGrabCart, List<PhysGrabObject>> PhysGrabCartItemsInCartRef = CreateFieldRef<PhysGrabCart, List<PhysGrabObject>>("itemsInCart"); private static readonly FieldRef<PhysGrabCart, PhysGrabObject> PhysGrabCartPhysGrabObjectRef = CreateFieldRef<PhysGrabCart, PhysGrabObject>("physGrabObject"); private static readonly FieldRef<PhysGrabCart, bool> PhysGrabCartBeingPulledRef = CreateFieldRef<PhysGrabCart, bool>("cartBeingPulled"); private static readonly FieldRef<PhysGrabCart, State> PhysGrabCartCurrentStateRef = CreateFieldRef<PhysGrabCart, State>("currentState"); private static readonly FieldRef<PhysGrabCart, ItemEquippable> PhysGrabCartItemEquippableRef = CreateFieldRef<PhysGrabCart, ItemEquippable>("itemEquippable"); private static readonly FieldRef<PhysGrabInCart, List<CartObject>> PhysGrabInCartObjectsRef = CreateFieldRef<PhysGrabInCart, List<CartObject>>("inCartObjects"); private static readonly FieldRef<ItemEquippable, ItemState> ItemEquippableCurrentStateRef = CreateFieldRef<ItemEquippable, ItemState>("currentState"); private static readonly FieldRef<PhysGrabber, PhysGrabObject> PhysGrabberGrabbedPhysGrabObjectRef = CreateFieldRef<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject"); private static readonly FieldRef<PhysGrabber, bool> PhysGrabberIsPushingRef = CreateFieldRef<PhysGrabber, bool>("isPushing"); private static readonly FieldRef<PhysGrabber, bool> PhysGrabberIsPullingRef = CreateFieldRef<PhysGrabber, bool>("isPulling"); private static readonly FieldRef<PlayerAvatar, WorldSpaceUIPlayerName> PlayerWorldSpaceUIPlayerNameRef = CreateFieldRef<PlayerAvatar, WorldSpaceUIPlayerName>("worldSpaceUIPlayerName"); private static readonly FieldRef<WorldSpaceUIPlayerName, PlayerAvatar> WsUiPlayerAvatarRef = CreateFieldRef<WorldSpaceUIPlayerName, PlayerAvatar>("playerAvatar"); private static readonly FieldRef<WorldSpaceUIPlayerName, float> WsUiShowTimerRef = CreateFieldRef<WorldSpaceUIPlayerName, float>("showTimer"); private static readonly FieldRef<ItemAttributes, string> ItemAttribNameRef = CreateFieldRef<ItemAttributes, string>("itemName"); private static readonly FieldRef<ItemAttributes, string> ItemAttribPromptNameRef = CreateFieldRef<ItemAttributes, string>("promptName"); private static readonly FieldRef<ItemAttributes, string> ItemAttribAssetNameRef = CreateFieldRef<ItemAttributes, string>("itemAssetName"); private static readonly FieldRef<ItemAttributes, string> ItemAttribInstanceNameRef = CreateFieldRef<ItemAttributes, string>("instanceName"); private static readonly FieldRef<ItemAttributes, string> ItemAttribTagRef = CreateFieldRef<ItemAttributes, string>("itemTag"); private static readonly FieldRef<ItemAttributes, itemType> ItemAttribTypeRef = CreateFieldRef<ItemAttributes, itemType>("itemType"); private static readonly FieldRef<ItemVehicle, VehicleSeat[]> ItemVehicleSeatsRef = CreateFieldRef<ItemVehicle, VehicleSeat[]>("seats"); private static readonly FieldRef<ItemVehicle, bool> ItemVehicleIsRacingRef = CreateFieldRef<ItemVehicle, bool>("isRacingVehicle"); internal static readonly Dictionary<string, CfgI18N> _cfgByEnSection = new Dictionary<string, CfgI18N>(StringComparer.Ordinal); internal static readonly Dictionary<string, CfgI18N> _cfgByEnKey = new Dictionary<string, CfgI18N>(StringComparer.Ordinal); internal static readonly Dictionary<string, List<CfgI18N>> _cfgByKeyOnly = new Dictionary<string, List<CfgI18N>>(StringComparer.Ordinal); private static readonly List<CfgI18N> _cfgI18Ns = new List<CfgI18N>(64); private static readonly string[] _chineseModKeywords = new string[6] { "chinese", "简体", "繁體", "繁体", "汉化", "中文" }; private static readonly string[] _chineseEnvironmentPluginGuids = new string[1] { "gravydevsupreme.xunity.autotranslator" }; private static readonly List<LiveLabel> _liveLabels = new List<LiveLabel>(64); private static readonly List<LiveValue> _liveValues = new List<LiveValue>(8); private static readonly List<LiveSliderOptions> _liveSliderOptions = new List<LiveSliderOptions>(4); private static readonly List<LiveToggleButtons> _liveToggleButtons = new List<LiveToggleButtons>(16); private static readonly Dictionary<Type, FieldInfo> _labelTmpFieldCache = new Dictionary<Type, FieldInfo>(8); private static readonly Dictionary<Type, PropertyInfo> _sliderStringOptionsPropCache = new Dictionary<Type, PropertyInfo>(4); private static readonly Dictionary<Type, FieldInfo> _toggleLeftTmpCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<Type, FieldInfo> _toggleRightTmpCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<string, int> _pendingKeyMatchIndex = new Dictionary<string, int>(StringComparer.Ordinal); internal static string _currentRenderingConfigFilePath; internal static bool _createModEntriesPatchInstalled; private static readonly Dictionary<Type, FieldInfo> _inputStringSystemFieldCache = new Dictionary<Type, FieldInfo>(4); private static readonly Dictionary<Type, MethodInfo> _inputStringSystemSetValueCache = new Dictionary<Type, MethodInfo>(4); private static readonly Dictionary<string, string> _enumNameCNtoEN = new Dictionary<string, string>(StringComparer.Ordinal) { ["中文"] = "Chinese", ["文字显示"] = "Text Mode", ["原生UI显示"] = "Native UI" }; private static readonly Dictionary<string, string> _enumNameENtoCN = new Dictionary<string, string>(StringComparer.Ordinal) { ["English"] = "英语", ["Chinese"] = "中文" }; private const float NativeOverlayRightMargin = -2f; private const float NativeOverlayBottomMargin = -2f; private const float NativeOverlayCompactLineSpacing = -4f; private const float NativeOverlayCompactParagraphSpacing = -1f; private const float NativeOverlayBreakdownWidth = 430f; private const float NativeOverlaySummaryWidth = 320f; private float tokenBoxCountLastUpdate = -1f; private const float TokenBoxCountCacheSeconds = 1f; private static readonly Dictionary<int, int> vehicleLabelIndices = new Dictionary<int, int>(); private static int nextVehicleLabelIndex = 1; private static int vehicleLabelIndexLevelNumber = -1; private static readonly List<ItemVehicle> activeVehicleBuffer = new List<ItemVehicle>(); private DisplayLanguage CurrentLanguage { get { if (displayLanguage != null) { return displayLanguage.Value; } return DisplayLanguage.English; } } private bool UseEnemyNicknameNames { get { if (CurrentLanguage == DisplayLanguage.中文 && enemyNicknameEnabled != null) { return enemyNicknameEnabled.Value; } return false; } } private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown DetachFromManager(); Instance = this; MakePluginHostPersistent(); Application.logMessageReceived += new LogCallback(OnUnityLogMessageReceived); ResetConfigIfVersionChanged(); BindConfig(); Harmony val = new Harmony("zichen.moreui"); ApplyValuableHaulPatch(); ApplyNativeNamePatch(); TryHookREPOConfig(val); if (displayLanguage != null) { displayLanguage.SettingChanged += delegate { RefreshAllI18N(); }; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"moreui loaded."); } private void BindConfig() { DisplayLanguage defaultVal = DetectDefaultLanguage(); displayLanguage = BindI18N("A.Mod Info", "A.模组信息", "More UI Language", "语言", "Switch display language.", "切换显示语言。", defaultVal, null, 980, null, "Language"); BindReadOnlyI18N("A.Mod Info", "A.模组信息", "More UI Mod Name", "模组名称", "More UI", "更多的UI显示", 1000, null, "Mod Name"); BindReadOnlyI18N("A.Mod Info", "A.模组信息", "More UI Mod Version", "模组版本号", "1.3.4", "1.3.4", 990, null, "Mod Version"); modEnabled = BindI18N("B.Global", "B.全局设置", "Mod Enabled", "模组启用", "Disable to turn off all features (HUD, teammate/cart distance, monster stats, value tracking, all Harmony patches).", "关闭后整个模组所有UI显示功能都不生效,包括右下角显示、队友/敌人距离、购物车距离、怪物统计和价值统计。", defaultVal: true, null, 990); enemyNicknameEnabled = BindI18N("B.Global", "B.全局设置", "Enemy Nicknames", "敌人名字优化", "Default on. Only affects Chinese mode: replaces literal translations with friendlier nicknames. English mode always uses English.", "默认开启。仅在语言为中文时生效,会把直接翻译的敌人名称优化成更顺口、更好辨认的中文名字;语言为 English 时始终显示英文。", defaultVal: true, null, 970); teammateOverlayEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Enabled", "启用", "Always show teammate names, distance and death status. Disable to fall back to the game's proximity-based name display.", "开启后始终显示好友名字、距离和死亡状态。关闭后使用游戏自带的靠近检测显示逻辑。", defaultVal: true, null, 600); teammateDeadOverlayEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Show Dead Teammates", "死亡好友显示", "Show name and distance for dead teammates in the world.", "开启后,局内显示死亡好友的名字和距离。", defaultVal: true, null, 599); teammateDeadEdgeOverlayEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Dead Teammate Edge Hint", "死亡好友离屏边缘提示", "Show name and distance on left/right screen edges when a dead teammate is off-screen.", "开启后,死亡好友离开屏幕时会在左/右边缘显示名字和距离。", defaultVal: true, null, 598); teammateAliveOverlayEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Show Alive Teammates", "存活好友显示", "Show name and distance for alive teammates in the world.", "开启后,局内显示存活好友的名字和距离。", defaultVal: true, null, 597); teammateAliveEdgeOverlayEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Alive Teammate Edge Hint", "存活好友离屏边缘提示", "Show name and distance on left/right screen edges when an alive teammate is off-screen.", "开启后,存活好友离开屏幕时会在左/右边缘显示名字和距离。", defaultVal: false, null, 596); teammateDistanceEnabled = BindI18N("C.Teammate Display", "C.好友局内显示", "Show Distance Meters", "显示米数", "Append distance in meters after teammate world labels and edge hints. Off by default.", "开启后,好友局内标签和离屏边缘提示会显示距离米数。默认关闭。", defaultVal: false, null, 595); teammateFontSize = BindI18N("C.Teammate Display", "C.好友局内显示", "Font Size", "字体大小", "Font size of teammate names. The game's native default is around 20; this value overrides it.", "好友名字的字体大小。游戏原生默认约20,此值会覆盖原生大小。", 22, (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 60), 590); cartSectionEnabled = BindI18N("D1.Cart Display", "D1.购物车局内显示", "Enabled", "启用", "Disable to hide all cart world labels.", "关闭后购物车局内显示全部不显示。", defaultVal: true, null, 530); smallCartOverlayEnabled = BindI18N("D1.Cart Display", "D1.购物车局内显示", "Show Small Cart", "显示小购物车", "Show index and distance on small carts.", "在小购物车上显示编号和距离。", defaultVal: true, null, 520); cartOverlayEnabled = BindI18N("D1.Cart Display", "D1.购物车局内显示", "Show Large Cart", "显示大购物车", "Show index and distance on large carts.", "在大购物车上显示编号和距离。", defaultVal: true, null, 518); cartDistanceEnabled = BindI18N("D1.Cart Display", "D1.购物车局内显示", "Show Distance Meters", "显示米数", "Append distance in meters after cart labels. Off by default.", "开启后,在购物车局内标签后面追加距离米数。默认关闭。", defaultVal: false, null, 517); cartFontSize = BindI18N("D1.Cart Display", "D1.购物车局内显示", "Font Size", "字体大小", "Font size of cart labels. Used as the near-distance maximum; far-distance labels shrink by a percentage.", "购物车局内文字的字体大小。近距离显示不超过这个大小,远距离会按变小百分比缩小。", 20, (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 36), 515); vehicleSectionEnabled = BindI18N("D2.Vehicle Display", "D2.载具局内显示", "Enabled", "启用", "Disable to hide all vehicle world labels.", "关闭后载具局内显示全部不显示。", defaultVal: true, null, 510); racingVehicleOverlayEnabled = BindI18N("D2.Vehicle Display", "D2.载具局内显示", "Show Racing Vehicle", "显示赛车", "Show label and distance on racing vehicles.", "在赛车上显示标签和距离。", defaultVal: true, null, 508); vehicleOverlayEnabled = BindI18N("D2.Vehicle Display", "D2.载具局内显示", "Show Cargo Vehicle", "显示载货车", "Show label and distance on cargo vehicles.", "在载货车上显示标签和距离。", defaultVal: true, null, 506); vehicleDistanceEnabled = BindI18N("D2.Vehicle Display", "D2.载具局内显示", "Show Distance Meters", "显示米数", "Append distance in meters after vehicle labels. Off by default.", "开启后,在载具局内标签后面追加距离米数。默认关闭。", defaultVal: false, null, 504); vehicleFontSize = BindI18N("D2.Vehicle Display", "D2.载具局内显示", "Font Size", "字体大小", "Font size of vehicle labels.", "载具局内文字的字体大小。", 20, (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 36), 502); overlayEnabled = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Enabled", "启用", "Show extra info in the bottom-right corner.", "是否在右下角显示额外信息。", defaultVal: true, null, 960); sectionSpacing = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Section Spacing", "不同分区空行", "Default on. Inserts a blank line between different info sections.", "默认开启。开启后不同信息分区之间会插入一行空白。", defaultVal: true, null, 955); displayMode = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Display Mode", "显示模式", "Bottom-right uses text mode by default with 70% opacity. Can switch to native UI style.", "右下角默认使用文字显示,默认透明度为 70%,也可切换为更贴近游戏的原生UI显示。", DisplayMode.文字显示, null, 952, DrawDisplayMode); fontSize = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Font Size", "字体大小", "Display font size.", "显示文字的字体大小。", 22, (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 28), 950); overlayTextOpacityPercent = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Text Opacity %", "文字透明度/%", "Controls overall opacity of both text mode and native UI mode. Default 70.", "右下角默认以文字显示为主时,这里控制文字显示和原生UI显示的整体透明度,默认 70%。", 70, (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), 949); updateInterval = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Refresh Interval (s)", "刷新间隔/秒", "How many seconds between display refreshes.", "每隔多少秒刷新一次显示。", 3f, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), 940); overlayOffsetX = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Offset X (px)", "右下角X偏移/像素", "Horizontal offset of the bottom-right info. Positive moves left, negative moves right.", "右下角信息的水平偏移。正数向左移动,负数向右移动。", 0, (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), 930); overlayOffsetY = BindI18N("E1.Panel Basics", "E1.右下角基础设置", "Offset Y (px)", "右下角Y偏移/像素", "Vertical offset of the bottom-right info. Positive moves up, negative moves down.", "右下角信息的垂直偏移。正数向上移动,负数向下移动。", 0, (AcceptableValueBase)(object)new AcceptableValueRange<int>(-600, 600), 920); showEnemySection = BindI18N("E2.Monster Stats", "E2.右下角怪物统计", "Enabled", "启用", "Disable to hide the monster stats section.", "关闭后右下角怪物统计分区全部不显示。", defaultVal: true, null, 800); showBreakdown = BindI18N("E2.Monster Stats", "E2.右下角怪物统计", "Show Breakdown", "显示怪物明细", "Show count per monster type.", "显示每种怪物当前数量。", defaultVal: true, null, 790); showTotalEnemyCount = BindI18N("E2.Monster Stats", "E2.右下角怪物统计", "Show Total", "显示怪物总数", "Show total alive monster count.", "显示当前存活怪物总数。", defaultVal: true, null, 780); showValueSection = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Enabled", "启用", "Disable to hide the value stats section.", "关闭后右下角价值统计分区全部不显示。", defaultVal: true, null, 770); showTokenBoxCount = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Lottery Boxes", "显示装饰箱", "Show the number of lottery / decor boxes (token machines, coin chests, etc.) in the current level.", "显示当前关卡中装饰箱的数量(包括投币机、硬币宝箱、代币箱等)。", defaultVal: true, null, 769); showKartCount = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Kart Count", "显示赛车数量", "Show kart (racing vehicle) count for the current level in the bottom-right.", "在右下角显示当前关卡的赛车数量。", defaultVal: false, null, 768); showCargoCount = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Cargo Count", "显示载货车数量", "Show cargo vehicle count for the current level in the bottom-right.", "在右下角显示当前关卡的载货车数量。", defaultVal: false, null, 767); showSmallCartCount = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Small Cart Count", "显示小购物车数量", "Show small cart count for the current level in the bottom-right.", "在右下角显示当前关卡的小购物车数量。", defaultVal: false, null, 766); showLargeCartCount = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Large Cart Count", "显示大购物车数量", "Show large cart count for the current level in the bottom-right.", "在右下角显示当前关卡的大购物车数量。", defaultVal: false, null, 765); showExplorationProgress = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Extraction Progress", "显示收集进度", "Shows extraction progress as a percent of the map's initial total value. Items in extraction points or carts count as collected.", "单独显示收集进度。进度按地图初始总价值计算,已放到提取点或购物车的物资也算作已收集。", defaultVal: true, null, 760); showMapLostValue = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Run Lost Funds", "显示损坏宝物", "Show value lost from broken or destroyed valuables in this run.", "显示本局中已摔坏或丢失造成的宝物损失。", defaultVal: true, null, 750); showMapTotalValue = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Map Remaining", "显示地图库存", "Shows remaining map value. Items already in extraction points are excluded; carts and uncollected items still count.", "显示当前地图库存。已放到提取点的物品会被排除,购物车里和地图上未收集的物品仍会计入。", defaultVal: true, null, 740); showCurrentRunSubmittedFunds = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Submitted Funds", "显示提交资金", "Show funds successfully extracted and settled this run. Items only placed at the extraction point but not yet finalized do not count.", "显示本局已经成功带走并结算的提交资金。仅放进提取点但未提取成功时不会计入。", defaultVal: true, null, 730); showShopRemainingFunds = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Shop Stock", "显示商店库存", "Shows shop remaining funds. Snapshot taken once per run start; submissions in the current level do not increase this.", "显示商店库存。此值只在每局开始读取一次快照,当前关卡提交物品不会让它上涨。", defaultVal: true, null, 720); showLevelInfo = BindI18N("E3.Value Stats", "E3.右下角价值统计", "Show Level", "显示关卡", "Show current level number and name, below shop stock.", "显示当前关卡编号和名称,位于商店库存下面。", defaultVal: true, null, 710); showTeammateInfoSection = BindI18N("E4.Teammate Info", "E4.右下角好友信息", "Enabled", "启用", "Disable to hide the bottom-right teammate info section.", "关闭后右下角好友信息分区全部不显示。", defaultVal: true, null, 670); showDeadTeammates = BindI18N("E4.Teammate Info", "E4.右下角好友信息", "Show Dead Teammates Info", "显示死亡好友信息", "Show dead teammate icon, name and distance at the top of the section. Closer teammates appear higher.", "在右下角好友信息分区顶部显示死亡好友图标、名字和距离,距离越近越靠上。", defaultVal: true, null, 660); showAliveTeammates = BindI18N("E4.Teammate Info", "E4.右下角好友信息", "Show Alive Teammates Info", "显示存活好友信息", "Show name and distance of each alive teammate. Closer teammates appear higher.", "在右下角好友信息分区显示每个存活好友的名字和距离,距离越近越靠上。", defaultVal: true, null, 650); showPlayerCounts = BindI18N("E4.Teammate Info", "E4.右下角好友信息", "Show Player Counts", "显示玩家", "Show dead / alive / total player counts at the bottom of the teammate section.", "在右下角好友信息分区最底部显示死亡、存活和总玩家。", defaultVal: true, null, 640); } private void ResetConfigIfVersionChanged() { try { string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; if (File.Exists(configFilePath)) { string text = ReadConfigPluginVersion(configFilePath); if (!(text == "1.3.4")) { ResetConfigFileToDefaults(configFilePath); ((BaseUnityPlugin)this).Logger.LogWarning((object)(string.IsNullOrWhiteSpace(text) ? "Old config without Mod Version, reset to defaults." : ("Config version " + text + " -> 1.3.4, reset to defaults."))); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reset config by version: " + ex.Message)); } } private static string ReadConfigPluginVersion(string configPath) { if (!File.Exists(configPath)) { return null; } Match match = Regex.Match(File.ReadAllText(configPath), "(?m)^More UI Mod Version\\s*=\\s*(.+?)\\s*$"); if (!match.Success) { return null; } return match.Groups[1].Value.Trim(); } private void ResetConfigFileToDefaults(string configPath) { ((BaseUnityPlugin)this).Config.Clear(); if (File.Exists(configPath)) { File.Delete(configPath); } ((BaseUnityPlugin)this).Config.Reload(); } private void Update() { try { UpdateCore(); } catch (Exception ex) { ResetRuntimeDisplayState(); if (!hasLoggedUpdateError) { hasLoggedUpdateError = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)("moreui update skipped after an error: " + ex.GetType().Name + ": " + ex.Message)); } } } private void UpdateCore() { bool flag = IsRuntimeSessionActive(); if (!IsModEnabled() || !flag) { if (runtimeWasActive) { runtimeWasActive = false; ResetLossTracking(); ResetRuntimeDisplayState(); } return; } runtimeWasActive = true; refreshTimer += Time.deltaTime; UpdateCartDistanceCache(); UpdateVehicleDistanceCache(); bool flag2 = overlayEnabled.Value && displayMode.Value == DisplayMode.原生UI显示; if (refreshTimer >= ClampRefreshInterval((updateInterval == null) ? 1.5f : updateInterval.Value)) { refreshTimer = 0f; overlayText = (overlayEnabled.Value ? BuildOverlayText() : string.Empty); if (flag2) { UpdateNativeOverlay(); } } if (flag2 && !string.IsNullOrWhiteSpace(overlayText)) { SetNativeOverlayVisible(visible: true); } else { SetNativeOverlayVisible(visible: false); } } private static float ClampRefreshInterval(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 0.1f; } return Mathf.Max(0.1f, value); } private void MakePluginHostPersistent() { try { ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message)); } } private void OnUnityLogMessageReceived(string condition, string stackTrace, LogType type) { if (!string.IsNullOrEmpty(condition)) { int num = condition.IndexOf("Changed level to:", StringComparison.OrdinalIgnoreCase); int length = "Changed level to:".Length; if (num < 0) { num = condition.IndexOf("updated level to:", StringComparison.OrdinalIgnoreCase); length = "updated level to:".Length; } if (num >= 0) { string name = condition.Substring(num + length).Trim(); levelTransitionLogIndicatesRun = LooksLikePlayableSessionName(name); } } } private void DetachFromManager() { ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown Application.logMessageReceived -= new LogCallback(OnUnityLogMessageReceived); if (Instance == this) { Instance = null; } ZichenMapValueService.Reset(); if (valuableHaulHarmony != null) { valuableHaulHarmony.UnpatchSelf(); valuableHaulHarmony = null; } if (nativeNameHarmony != null) { nativeNameHarmony.UnpatchSelf(); nativeNameHarmony = null; } valuablesCurrentlyInDollarHaul.Clear(); if ((Object)(object)overlayObject != (Object)null) { Object.Destroy((Object)(object)overlayObject); overlayObject = null; overlayRect = null; overlayLabel = null; lastNativeOverlayParent = null; } } private static void DrawDisplayMode(ConfigEntryBase entry) { if (entry is ConfigEntry<DisplayMode> val) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(entry.Definition.Key, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); DisplayMode value = val.Value; if (GUILayout.Button((!UseChinese()) ? ((value == DisplayMode.原生UI显示) ? "Native UI" : "Text") : ((value == DisplayMode.原生UI显示) ? "原生UI显示" : "文字显示"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(140f) })) { val.Value = ((value == DisplayMode.文字显示) ? DisplayMode.原生UI显示 : DisplayMode.文字显示); } GUILayout.EndHorizontal(); } } private bool IsModEnabled() { if (modEnabled != null) { return modEnabled.Value; } return true; } private bool IsRuntimeSessionActive() { if (IsRunLevelActive()) { lastConfirmedRunLevelTime = Time.unscaledTime; return true; } if (runtimeWasActive && Time.unscaledTime - lastConfirmedRunLevelTime <= 4f) { return true; } return false; } private void ResetRuntimeDisplayState() { overlayText = string.Empty; lastTextOverlaySource = null; lastTextOverlayFontSize = -1; lastTextOverlayScreenWidth = -1; lastTextOverlayScreenHeight = -1; cachedTextOverlayPlainText = string.Empty; enemyDisplayNameCache.Clear(); enemyBreakdownRankCache.Clear(); enemyBreakdownRawNameRankCache.Clear(); playerNameCache.Clear(); playerColorCache.Clear(); cartLabelYOffsetCache.Clear(); cartComponentCache.Clear(); itemSearchTextCache.Clear(); itemTokenBoxCandidateCache.Clear(); playerPositionCache.Clear(); playerObjectsFrameCache = null; cachedLocalPlayer = null; cachedLocalPlayerFrame = -1; playerCountsFrame = -1; cachedTotalPlayers = 0; cachedAlivePlayers = 0; cachedDeadPlayers = 0; ResetTrackedObjectCleanupSchedule(); enemyObjectsFrameCacheFrame = -1; cartObjectsFrameCacheFrame = -1; grabberObjectsFrameCacheFrame = -1; valuableObjectsFrameCacheFrame = -1; playerObjectsFrameCacheFrame = -1; ClearCartLabelIndices(); ClearCartDistanceCache(); ClearVehicleDistanceCache(); SetNativeOverlayVisible(visible: false); } private static bool IsRunLevelSafe() { try { return IsRunLevelActive(); } catch { return false; } } private static int GetCurrentMapValueLevelNumber() { try { return SemiFunc.RunGetLevelsCompleted() + 1; } catch { return 0; } } private static bool IsRunLevelActive() { int frameCount = Time.frameCount; if (cachedRunLevelActiveFrame == frameCount) { return cachedRunLevelActive; } cachedRunLevelActiveFrame = frameCount; cachedRunLevelActive = IsRunLevelActiveUncached(); return cachedRunLevelActive; } private static bool IsRunLevelActiveUncached() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) try { if (SemiFunc.RunIsShop()) { return true; } } catch { } try { if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null) { string name = ((Object)RunManager.instance.levelCurrent).name; string narrativeName = RunManager.instance.levelCurrent.NarrativeName; if (IsNonPlayableLevelName(name) || IsNonPlayableLevelName(narrativeName)) { return false; } } } catch { } try { Scene activeScene = SceneManager.GetActiveScene(); if (IsNonPlayableLevelName(((Scene)(ref activeScene)).name)) { return false; } } catch { } try { if (IsGameDirectorSessionStateActive()) { return true; } } catch { } try { if (SemiFunc.RunIsLevel()) { return true; } } catch { } Plugin instance = Instance; if ((Object)(object)instance != (Object)null && instance.levelTransitionLogIndicatesRun) { return true; } try { if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null) { string name2 = ((Object)RunManager.instance.levelCurrent).name; string narrativeName2 = RunManager.instance.levelCurrent.NarrativeName; return LooksLikePlayableSessionName(name2) || LooksLikePlayableSessionName(narrativeName2); } } catch { } return false; } private static bool IsGameDirectorSessionStateActive() { if ((Object)(object)GameDirector.instance == (Object)null) { return false; } switch (((object)(gameState)(ref GameDirector.instance.currentState)).ToString()) { case "Main": case "Outro": case "End": case "EndWait": case "Death": return true; default: return false; } } private static bool LooksLikePlayableSessionName(string name) { if (string.IsNullOrWhiteSpace(name) || IsNonPlayableLevelName(name)) { return false; } if (name.IndexOf("Level", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Rest", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("Truck", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsNonPlayableLevelName(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } if (name.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("Splash", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsStaticModEnabled() { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null)) { return instance.IsModEnabled(); } return true; } private bool IsCartFeatureEnabled() { if (cartSectionEnabled != null && cartSectionEnabled.Value) { if (cartOverlayEnabled == null || !cartOverlayEnabled.Value) { if (smallCartOverlayEnabled != null) { return smallCartOverlayEnabled.Value; } return false; } return true; } return false; } private bool IsVehicleFeatureEnabled() { if (vehicleSectionEnabled != null && vehicleSectionEnabled.Value) { if (vehicleOverlayEnabled == null || !vehicleOverlayEnabled.Value) { if (racingVehicleOverlayEnabled != null) { return racingVehicleOverlayEnabled.Value; } return false; } return true; } return false; } internal static void NotifyTrackedObjectDestroyed(ValuableObject valuable, PhysGrabCart cart, Enemy enemy, ValuableDiscoverCustom customDiscoverable, CosmeticShopMachine machine, ItemVehicle vehicle = null) { UnregisterTrackedValuable(valuable); UnregisterTrackedCart(cart); UnregisterTrackedEnemy(enemy); UnregisterTrackedCustomDiscoverable(customDiscoverable); UnregisterTrackedCosmeticShopMachine(machine); if ((Object)(object)vehicle != (Object)null) { UnregisterTrackedVehicle(vehicle); } } private static FieldRef<TInstance, TField> CreateFieldRef<TInstance, TField>(string fieldName) where TInstance : class { try { return AccessTools.FieldRefAccess<TInstance, TField>(fieldName); } catch { return null; } } internal static bool GetPlayerDeadSetFast(PlayerAvatar player) { if ((Object)(object)player != (Object)null && PlayerDeadSetRef != null) { return PlayerDeadSetRef.Invoke(player); } return false; } internal static bool GetPlayerIsDisabledFast(PlayerAvatar player) { if ((Object)(object)player != (Object)null && PlayerIsDisabledRef != null) { return PlayerIsDisabledRef.Invoke(player); } return false; } internal static bool GetPlayerIsLocalFast(PlayerAvatar player) { if ((Object)(object)player != (Object)null && PlayerIsLocalRef != null) { return PlayerIsLocalRef.Invoke(player); } return false; } internal static string GetPlayerInternalNameFast(PlayerAvatar player) { if (!((Object)(object)player == (Object)null) && PlayerNameRef != null) { return PlayerNameRef.Invoke(player); } return null; } internal static int[] GetPlayerCosmeticsColorsFast(PlayerCosmetics cosmetics) { if (!((Object)(object)cosmetics == (Object)null) && PlayerCosmeticsColorsEquippedRef != null) { return PlayerCosmeticsColorsEquippedRef.Invoke(cosmetics); } return null; } internal static PlayerDeathHead GetPlayerDeathHeadFast(PlayerAvatar player) { if (!((Object)(object)player == (Object)null) && PlayerDeathHeadRef != null) { return PlayerDeathHeadRef.Invoke(player); } return null; } internal static bool TryGetPlayerLastNavmeshPositionFast(PlayerAvatar player, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; if ((Object)(object)player == (Object)null || PlayerLastNavmeshPositionRef == null) { return false; } position = PlayerLastNavmeshPositionRef.Invoke(player); return ((Vector3)(ref position)).sqrMagnitude > 0.001f; } internal static PhysGrabObject GetDeathHeadPhysGrabObjectFast(PlayerDeathHead deathHead) { if (!((Object)(object)deathHead == (Object)null) && DeathHeadPhysGrabObjectRef != null) { return DeathHeadPhysGrabObjectRef.Invoke(deathHead); } return null; } internal static Transform GetDeathHeadOverridePositionTransformFast(PlayerDeathHead deathHead) { if (!((Object)(object)deathHead == (Object)null) && DeathHeadOverridePositionTransformRef != null) { return DeathHeadOverridePositionTransformRef.Invoke(deathHead); } return null; } internal static bool TryGetDeathHeadTriggeredPositionFast(PlayerDeathHead deathHead, out Vector3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; if ((Object)(object)deathHead == (Object)null || DeathHeadTriggeredPositionRef == null) { return false; } position = DeathHeadTriggeredPositionRef.Invoke(deathHead); return ((Vector3)(ref position)).sqrMagnitude > 0.001f; } internal static PlayerAvatar GetSpectateCameraPlayerFast(SpectateCamera spectateCamera) { if (!((Object)(object)spectateCamera == (Object)null) && SpectateCameraPlayerRef != null) { return SpectateCameraPlayerRef.Invoke(spectateCamera); } return null; } internal static PlayerAvatar GetSpectateCameraPlayerOverrideFast(SpectateCamera spectateCamera) { if (!((Object)(object)spectateCamera == (Object)null) && SpectateCameraPlayerOverrideRef != null) { return SpectateCameraPlayerOverrideRef.Invoke(spectateCamera); } return null; } internal static Camera GetSpectateCameraMainCameraFast(SpectateCamera spectateCamera) { if (!((Object)(object)spectateCamera == (Object)null) && SpectateCameraMainCameraRef != null) { return SpectateCameraMainCameraRef.Invoke(spectateCamera); } return null; } internal static EnemyParent GetEnemyParentFast(Enemy enemy) { if (!((Object)(object)enemy == (Object)null) && EnemyParentRef != null) { return EnemyParentRef.Invoke(enemy); } return null; } internal static EnemyHealth GetEnemyHealthFast(Enemy enemy) { if (!((Object)(object)enemy == (Object)null) && EnemyHealthRef != null) { return EnemyHealthRef.Invoke(enemy); } return null; } internal static bool GetEnemyHealthDeadFast(EnemyHealth health) { if ((Object)(object)health != (Object)null && EnemyHealthDeadRef != null) { return EnemyHealthDeadRef.Invoke(health); } return false; } internal static bool GetEnemyParentSpawnedFast(EnemyParent parent) { if (!((Object)(object)parent == (Object)null) && EnemyParentSpawnedRef != null) { return EnemyParentSpawnedRef.Invoke(parent); } return true; } internal static Enemy GetEnemyParentEnemyFast(EnemyParent parent) { if (!((Object)(object)parent == (Object)null) && EnemyParentEnemyRef != null) { return EnemyParentEnemyRef.Invoke(parent); } return null; } internal static float GetValuableOriginalValueFast(ValuableObject valuable) { if (!((Object)(object)valuable == (Object)null) && ValuableOriginalValueRef != null) { return Mathf.Max(0f, ValuableOriginalValueRef.Invoke(valuable)); } return 0f; } internal static float GetValuableCurrentValueFast(ValuableObject valuable) { if (!((Object)(object)valuable == (Object)null) && ValuableCurrentValueRef != null) { return Mathf.Max(0f, ValuableCurrentValueRef.Invoke(valuable)); } return 0f; } internal static bool IsValuableValueSetFast(ValuableObject valuable) { if ((Object)(object)valuable != (Object)null) { if (ValuableValueSetRef != null) { return ValuableValueSetRef.Invoke(valuable); } return true; } return false; } internal static PhotonView GetValuablePhotonViewFast(ValuableObject valuable) { if (!((Object)(object)valuable == (Object)null) && ValuablePhotonViewRef != null) { return ValuablePhotonViewRef.Invoke(valuable); } return null; } internal static PhysGrabObject GetValuablePhysGrabObjectFast(ValuableObject valuable) { if (!((Object)(object)valuable == (Object)null) && ValuablePhysGrabObjectRef != null) { return ValuablePhysGrabObjectRef.Invoke(valuable); } return null; } internal static List<PhysGrabObject> GetCartItemsInCartFast(PhysGrabCart cart) { if (!((Object)(object)cart == (Object)null) && PhysGrabCartItemsInCartRef != null) { return PhysGrabCartItemsInCartRef.Invoke(cart); } return null; } internal static PhysGrabObject GetCartPhysGrabObjectFast(PhysGrabCart cart) { if (!((Object)(object)cart == (Object)null) && PhysGrabCartPhysGrabObjectRef != null) { return PhysGrabCartPhysGrabObjectRef.Invoke(cart); } return null; } internal static bool GetCartBeingPulledFast(PhysGrabCart cart) { if ((Object)(object)cart != (Object)null && PhysGrabCartBeingPulledRef != null) { return PhysGrabCartBeingPulledRef.Invoke(cart); } return false; } internal static State? GetCartStateFast(PhysGrabCart cart) { if ((Object)(object)cart == (Object)null || PhysGrabCartCurrentStateRef == null) { return null; } return PhysGrabCartCurrentStateRef.Invoke(cart); } internal static ItemEquippable GetCartItemEquippableFast(PhysGrabCart cart) { if (!((Object)(object)cart == (Object)null) && PhysGrabCartItemEquippableRef != null) { return PhysGrabCartItemEquippableRef.Invoke(cart); } return null; } internal static List<CartObject> GetPhysGrabInCartObjectsFast(PhysGrabInCart inCart) { if (!((Object)(object)inCart == (Object)null) && PhysGrabInCartObjectsRef != null) { return PhysGrabInCartObjectsRef.Invoke(inCart); } return null; } internal static ItemState? GetItemEquippableStateFast(ItemEquippable itemEquippable) { if ((Object)(object)itemEquippable == (Object)null || ItemEquippableCurrentStateRef == null) { return null; } return ItemEquippableCurrentStateRef.Invoke(itemEquippable); } internal static PhysGrabObject GetGrabberHeldObjectFast(PhysGrabber grabber) { if (!((Object)(object)grabber == (Object)null) && PhysGrabberGrabbedPhysGrabObjectRef != null) { return PhysGrabberGrabbedPhysGrabObjectRef.Invoke(grabber); } return null; } internal static bool GetGrabberIsPushingFast(PhysGrabber grabber) { if ((Object)(object)grabber != (Object)null && PhysGrabberIsPushingRef != null) { return PhysGrabberIsPushingRef.Invoke(grabber); } return false; } internal static bool GetGrabberIsPullingFast(PhysGrabber grabber) { if ((Object)(object)grabber != (Object)null && PhysGrabberIsPullingRef != null) { return PhysGrabberIsPullingRef.Invoke(grabber); } return false; } internal static WorldSpaceUIPlayerName GetPlayerWorldSpaceUiFast(PlayerAvatar player) { if (!((Object)(object)player == (Object)null) && PlayerWorldSpaceUIPlayerNameRef != null) { return PlayerWorldSpaceUIPlayerNameRef.Invoke(player); } return null; } internal static PlayerAvatar GetWorldSpaceUiPlayerAvatarFast(WorldSpaceUIPlayerName nameUi) { if (!((Object)(object)nameUi == (Object)null) && WsUiPlayerAvatarRef != null) { return WsUiPlayerAvatarRef.Invoke(nameUi); } return null; } internal static void SetWorldSpaceUiShowTimerFast(WorldSpaceUIPlayerName nameUi, float value) { if (!((Object)(object)nameUi == (Object)null) && WsUiShowTimerRef != null) { WsUiShowTimerRef.Invoke(nameUi) = value; } } internal static string GetItemAttribNameFast(ItemAttributes item) { if (!((Object)(object)item == (Object)null) && ItemAttribNameRef != null) { return ItemAttribNameRef.Invoke(item); } return null; } internal static string GetItemAttribPromptNameFast(ItemAttributes item) { if (!((Object)(object)item == (Object)null) && ItemAttribPromptNameRef != null) { return ItemAttribPromptNameRef.Invoke(item); } return null; } internal static string GetItemAttribAssetNameFast(ItemAttributes item) { if (!((Object)(object)item == (Object)null) && ItemAttribAssetNameRef != null) { return ItemAttribAssetNameRef.Invoke(item); } return null; } internal static string GetItemAttribInstanceNameFast(ItemAttributes item) { if (!((Object)(object)item == (Object)null) && ItemAttribInstanceNameRef != null) { return ItemAttribInstanceNameRef.Invoke(item); } return null; } internal static string GetItemAttribTagFast(ItemAttributes item) { if (!((Object)(object)item == (Object)null) && ItemAttribTagRef != null) { return ItemAttribTagRef.Invoke(item); } return null; } internal static string GetItemAttribTypeNameFast(ItemAttributes item) { if ((Object)(object)item == (Object)null || ItemAttribTypeRef == null) { return null; } return ((object)(itemType)(ref ItemAttribTypeRef.Invoke(item))).ToString(); } internal static VehicleSeat[] GetVehicleSeatsFast(ItemVehicle vehicle) { if (!((Object)(object)vehicle == (Object)null) && ItemVehicleSeatsRef != null) { return ItemVehicleSeatsRef.Invoke(vehicle); } return null; } internal static bool GetVehicleIsRacingFast(ItemVehicle vehicle) { if ((Object)(object)vehicle == (Object)null || ItemVehicleIsRacingRef == null) { return false; } return ItemVehicleIsRacingRef.Invoke(vehicle); } internal static bool GetVehicleHasRider(ItemVehicle vehicle) { if ((Object)(object)vehicle == (Object)null) { return false; } VehicleSeat[] vehicleSeatsFast = GetVehicleSeatsFast(vehicle); if (vehicleSeatsFast == null) { return false; } for (int i = 0; i < vehicleSeatsFast.Length; i++) { if (vehicleSeatsFast[i] != null && (Object)(object)vehicleSeatsFast[i].seatedPlayer != (Object)null) { return true; } } return false; } private void ApplyValuableHaulPatch() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { valuableHaulHarmony = new Harmony("zichen.moreui.valuablehaul"); PatchValuableHaulMethod("AddToDollarHaulList", "ValuableDollarHaulAddPostfix"); PatchValuableHaulMethod("AddToDollarHaulListRPC", "ValuableDollarHaulAddPostfix"); PatchValuableHaulMethod("RemoveFromDollarHaulList", "ValuableDollarHaulRemovePostfix"); PatchValuableHaulMethod("RemoveFromDollarHaulListRPC", "ValuableDollarHaulRemovePostfix"); PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetLogic", "ValuableDollarValueSetLogicPostfix"); PatchValuableTrackingMethod(typeof(ValuableObject), "DollarValueSetRPC", "ValuableDollarValueSetRpcPostfix"); PatchValuableTrackingMethod(typeof(PhysGrabObjectImpactDetector), "BreakRPC", "ValuableBreakPostfix"); PatchValuableTrackingMethod(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC", "ValuableDestroyPhysGrabObjectPostfix"); PatchValuableTrackingMethod(typeof(RoundDirector), "ExtractionCompleted", "RoundDirectorExtractionCompletedPostfix"); PatchValuableTrackingMethod(typeof(LevelGenerator), "StartRoomGeneration", "LevelGeneratorStartRoomGenerationPrefix", prefix: true); PatchValuableTrackingMethod(typeof(LevelGenerator), "GenerateDone", "LevelGeneratorGenerateDonePostfix"); PatchValuableTrackingMethod(typeof(ValuableObject), "Start", "ValuableObjectStartPostfix"); PatchValuableTrackingMethod(typeof(PhysGrabCart), "Start", "PhysGrabCartStartPostfix"); PatchValuableTrackingMethod(typeof(ItemVehicle), "Start", "ItemVehicleStartPostfix"); PatchValuableTrackingMethod(typeof(PhysGrabber), "Start", "PhysGrabberStartPostfix"); PatchValuableTrackingMethod(typeof(PhysGrabber), "OnDestroy", "PhysGrabberOnDestroyPrefix", prefix: true); PatchValuableTrackingMethod(typeof(EnemyParent), "Awake", "EnemyParentAwakePostfix"); PatchValuableTrackingMethod(typeof(ItemAttributes), "Start", "ItemAttributesStartPostfix"); PatchValuableTrackingMethod(typeof(ItemAttributes), "OnDestroy", "ItemAttributesOnDestroyPrefix", prefix: true); PatchValuableTrackingMethod(typeof(ValuableDiscoverCustom), "Awake", "ValuableDiscoverCustomAwakePostfix"); PatchValuableTrackingMethod(typeof(CosmeticShopMachine), "Awake", "CosmeticShopMachineAwakePostfix"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Valuable haul tracking patched."); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to patch valuable haul tracking: {arg}"); } } private void PatchValuableHaulMethod(string originalName, string postfixName) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ValuableObject), originalName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), postfixName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable haul method patch target: " + originalName)); } else { valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private void PatchValuableTrackingMethod(Type originalType, string originalName, string patchName, bool prefix = false) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(originalType, originalName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), patchName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find valuable tracking patch target: " + originalType?.Name + "." + originalName)); return; } HarmonyMethod val = new HarmonyMethod(methodInfo2); if (prefix) { valuableHaulHarmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { valuableHaulHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void ValuableDollarHaulAddPostfix(ValuableObject __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { valuablesCurrentlyInDollarHaul.Add(GetValuableKey(__instance)); } } private static void ValuableDollarHaulRemovePostfix(ValuableObject __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { valuablesCurrentlyInDollarHaul.Remove(GetValuableKey(__instance)); } } private static void ValuableDollarValueSetLogicPostfix(ValuableObject __instance) { if (IsStaticModEnabled() && IsRunLevelSafe()) { ZichenMapValueService.RegisterValueSet(__instance, GetCurrentMapValueLevelNumber()); } } private static void ValuableDollarValueSetRpcPostfix(ValuableObject __instance, float value) { if (IsStaticModEnabled() && IsRunLevelSafe()) { ZichenMapValueService.RegisterValueSet(__instance, value, GetCurrentMapValueLevelNumber()); } } private static void ValuableBreakPostfix(float valueLost, PhysGrabObjectImpactDetector __instance, bool _loseValue) { if (_loseValue && IsStaticModEnabled() && IsRunLevelSafe()) { ZichenMapValueService.RegisterBreak(((Object)(object)__instance == (Object)null) ? null : ((Component)__instance).GetComponent<ValuableObject>(), valueLost, GetCurrentMapValueLevelNumber()); } } private static void ValuableDestroyPhysGrabObjectPostfix(PhysGrabObject __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled() && IsRunLevelSafe()) { ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>(); ZichenMapValueService.RegisterDestroy(component, GetCurrentMapValueLevelNumber()); UnregisterTrackedValuable(component); } } private static void RoundDirectorExtractionCompletedPostfix() { if (IsStaticModEnabled() && IsRunLevelSafe()) { ZichenMapValueService.SyncFromLiveValuables(GetValuableObjectsCachedForFrameStatic(), GetCurrentMapValueLevelNumber()); } } private static void LevelGeneratorStartRoomGenerationPrefix() { if (IsStaticModEnabled()) { if ((Object)(object)Instance != (Object)null) { Instance.ResetLossTracking(); Instance.ClearCartLabelIndices(); Instance.ClearCartDistanceCache(); Instance.ClearVehicleDistanceCache(); Instance.enemyDisplayNameCache.Clear(); Instance.enemyBreakdownRankCache.Clear(); Instance.enemyBreakdownRawNameRankCache.Clear(); Instance.playerNameCache.Clear(); Instance.playerColorCache.Clear(); ResetTrackedObjectCleanupSchedule(); cachedLocalPlayer = null; cachedLocalPlayerFrame = -1; trackedValuables.Clear(); trackedValuableSet.Clear(); trackedCarts.Clear(); trackedCartSet.Clear(); trackedVehicles.Clear(); trackedVehicleSet.Clear(); trackedEnemies.Clear(); trackedEnemySet.Clear(); trackedGrabbers.Clear(); trackedGrabberSet.Clear(); ClearTrackedTokenSources(); } else { valuablesCurrentlyInDollarHaul.Clear(); ZichenMapValueService.Reset(); ResetTrackedObjectCleanupSchedule(); cachedLocalPlayer = null; cachedLocalPlayerFrame = -1; trackedValuables.Clear(); trackedValuableSet.Clear(); trackedCarts.Clear(); trackedCartSet.Clear(); trackedVehicles.Clear(); trackedVehicleSet.Clear(); trackedEnemies.Clear(); trackedEnemySet.Clear(); trackedGrabbers.Clear(); trackedGrabberSet.Clear(); ClearTrackedTokenSources(); } } } private static void LevelGeneratorGenerateDonePostfix() { if (IsStaticModEnabled()) { SyncTrackedObjectsFromScene(); ZichenMapValueService.SyncFromLiveValuables(GetValuableObjectsCachedForFrameStatic(), GetCurrentMapValueLevelNumber()); } } private static void SyncTrackedObjectsFromScene() { CaptureTrackedObjects(trackedCarts, preservedTrackedCartsBuffer); CaptureTrackedObjects(trackedVehicles, preservedTrackedVehiclesBuffer); CaptureTrackedObjects(trackedItems, preservedTrackedItemsBuffer); CaptureTrackedObjects(trackedCustomDiscoverables, preservedTrackedCustomDiscoverablesBuffer); CaptureTrackedObjects(trackedCosmeticShopMachines, preservedTrackedCosmeticShopMachinesBuffer); try { trackedValuables.Clear(); trackedValuableSet.Clear(); List<ValuableObject> list = (((Object)(object)ValuableDirector.instance == (Object)null) ? null : ValuableDirector.instance.valuableList); if (list != null) { foreach (ValuableObject item in list) { RegisterTrackedValuable(item); } } trackedCarts.Clear(); trackedCartSet.Clear(); trackedVehicles.Clear(); trackedVehicleSet.Clear(); trackedEnemies.Clear(); trackedEnemySet.Clear(); List<EnemyParent> list2 = (((Object)(object)EnemyDirector.instance == (Object)null) ? null : EnemyDirector.instance.enemiesSpawned); if (list2 != null) { foreach (EnemyParent item2 in list2) { RegisterTrackedEnemyFromParent(item2); } } trackedGrabbers.Clear(); trackedGrabberSet.Clear(); List<PlayerAvatar> list3 = (((Object)(object)GameDirector.instance == (Object)null) ? null : GameDirector.instance.PlayerList); if (list3 != null) { foreach (PlayerAvatar item3 in list3) { RegisterTrackedGrabber(((Object)(object)item3 == (Object)null) ? null : item3.physGrabber); } } ClearTrackedTokenSources(); List<ItemAttributes> list4 = (((Object)(object)ItemManager.instance == (Object)null) ? null : ItemManager.instance.spawnedItems); if (list4 != null) { foreach (ItemAttributes item4 in list4) { RegisterTrackedItem(item4); RegisterTrackedCart(((Object)(object)item4 == (Object)null) ? null : ((Component)item4).GetComponent<PhysGrabCart>()); RegisterTrackedCustomDiscoverable(((Object)(object)item4 == (Object)null) ? null : ((Component)item4).GetComponent<ValuableDiscoverCustom>()); } } foreach (ItemAttributes item5 in preservedTrackedItemsBuffer) { RegisterTrackedItem(item5); RegisterTrackedCart(((Object)(object)item5 == (Object)null) ? null : ((Component)item5).GetComponent<PhysGrabCart>()); RegisterTrackedCustomDiscoverable(((Object)(object)item5 == (Object)null) ? null : ((Component)item5).GetComponent<ValuableDiscoverCustom>()); } foreach (PhysGrabCart item6 in preservedTrackedCartsBuffer) { RegisterTrackedCart(item6); } foreach (ItemVehicle item7 in preservedTrackedVehiclesBuffer) { RegisterTrackedVehicle(item7); } List<CosmeticWorldObject> list5 = (((Object)(object)RoundDirector.instance == (Object)null) ? null : RoundDirector.instance.cosmeticWorldObjects); if (list5 != null) { foreach (CosmeticWorldObject item8 in list5) { RegisterTrackedCustomDiscoverable(((Object)(object)item8 == (Object)null) ? null : ((Component)item8).GetComponent<ValuableDiscoverCustom>()); } } foreach (ValuableDiscoverCustom item9 in preservedTrackedCustomDiscoverablesBuffer) { RegisterTrackedCustomDiscoverable(item9); } RegisterTrackedCosmeticShopMachine(CosmeticShopMachine.instance); foreach (CosmeticShopMachine item10 in preservedTrackedCosmeticShopMachinesBuffer) { RegisterTrackedCosmeticShopMachine(item10); } } finally { ClearPreservedTrackedObjectBuffers(); } } private static void CaptureTrackedObjects<T>(List<T> source, List<T> destination) { destination.Clear(); if (source != null && source.Count != 0) { destination.AddRange(source); } } private static void ClearPreservedTrackedObjectBuffers() { preservedTrackedCartsBuffer.Clear(); preservedTrackedVehiclesBuffer.Clear(); preservedTrackedItemsBuffer.Clear(); preservedTrackedCustomDiscoverablesBuffer.Clear(); preservedTrackedCosmeticShopMachinesBuffer.Clear(); } private static void ValuableObjectStartPostfix(ValuableObject __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedValuable(__instance); } } private static void PhysGrabCartStartPostfix(PhysGrabCart __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedCart(__instance); } } private static void ItemVehicleStartPostfix(ItemVehicle __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedVehicle(__instance); } } private static void EnemyParentAwakePostfix(EnemyParent __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedEnemyFromParent(__instance); } } private static void PhysGrabberStartPostfix(PhysGrabber __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedGrabber(__instance); } } private static void PhysGrabberOnDestroyPrefix(PhysGrabber __instance) { UnregisterTrackedGrabber(__instance); } private static void ItemAttributesStartPostfix(ItemAttributes __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedItem(__instance); } } private static void ItemAttributesOnDestroyPrefix(ItemAttributes __instance) { UnregisterTrackedItem(__instance); } private static void ValuableDiscoverCustomAwakePostfix(ValuableDiscoverCustom __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedCustomDiscoverable(__instance); } } private static void CosmeticShopMachineAwakePostfix(CosmeticShopMachine __instance) { if (!((Object)(object)__instance == (Object)null) && IsStaticModEnabled()) { RegisterTrackedCosmeticShopMachine(__instance); } } private static void RegisterTrackedValuable(ValuableObject valuable) { if ((Object)(object)valuable != (Object)null && trackedValuableSet.Add(valuable)) { trackedValuables.Add(valuable); TrackNotifierForValuable(valuable); } } private static void UnregisterTrackedValuable(ValuableObject valuable) { if (!((Object)(object)valuable == (Object)null)) { trackedValuableSet.Remove(valuable); trackedValuables.Remove(valuable); valuablesCurrentlyInDollarHaul.Remove(GetValuableKey(valuable)); } } private static void RegisterTrackedCart(PhysGrabCart cart) { if ((Object)(object)cart != (Object)null && trackedCartSet.Add(cart)) { trackedCarts.Add(cart); TrackNotifierForCart(cart); Instance?.ClearCartDistanceCache(); } } private static void UnregisterTrackedCart(PhysGrabCart cart) { if (!((Object)(object)cart == (Object)null)) { trackedCartSet.Remove(cart); if (trackedCarts.Remove(cart)) { Instance?.ClearCartDistanceCache(); } } } private static void RegisterTrackedVehicle(ItemVehicle vehicle) { if ((Object)(object)vehicle != (Object)null && trackedVehicleSet.Add(vehicle)) { trackedVehicles.Add(vehicle); TrackNotifierForVehicle(vehicle); Instance?.ClearVehicleDistanceCache(); } } private static void UnregisterTrackedVehicle(ItemVehicle vehicle) { if (!((Object)(object)vehicle == (Object)null)) { trackedVehicleSet.Remove(vehicle); if (trackedVehicles.Remove(vehicle)) { Instance?.ClearVehicleDistanceCache(); } } } private static void RegisterTrackedEnemy(Enemy enemy) { if ((Object)(object)enemy != (Object)null && trackedEnemySet.Add(enemy)) { trackedEnemies.Add(enemy); TrackNotifierForEnemy(enemy); } } private static void RegisterTrackedEnemyFromParent(EnemyParent enemyParent) { if (!((Object)(object)enemyParent == (Object)null)) { Enemy val = GetEnemyParentEnemyFast(enemyParent); if ((Object)(object)val == (Object)null) { val = ((Component)enemyParent).GetComponentInChildren<Enemy>(true); } RegisterTrackedEnemy(val); } } private static void UnregisterTrackedEnemy(Enemy enemy) { if (!((Object)(object)enemy == (Object)null) && (trackedEnemySet.Remove(enemy) || trackedEnemies.Contains(enemy)) && trackedEnemies.Remove(enemy)) { Plugin instance = Instance; if (!((Object)(object)instance == (Object)null)) { int instanceID = ((Object)enemy).GetInstanceID(); instance.enemyDisplayNameCache.Remove(instanceID); instance.enemyBreakdownRankCache.Remove(instanceID); } } } private static void RegisterTrackedGrabber(PhysGrabber grabber) { if ((Object)(object)grabber != (Object)null && trackedGrabberSet.Add(grabber)) { trackedGrabbers.Add(grabber); } } private static void UnregisterTrackedGrabber(PhysGrabber grabber) { if (!((Object)(object)grabber == (Object)null)) { trackedGrabberSet.Remove(grabber); trackedGrabbers.Remove(grabber); } } private static void RegisterTrackedItem(ItemAttributes item) { if ((Object)(object)item != (Object)null && !trackedItems.Contains(item)) { trackedItems.Add(item); if ((Object)(object)Instance != (Object)null && Instance.IsTokenBoxItemCached(item) && !trackedTokenBoxItems.Contains(item)) { trackedTokenBoxItems.Add(item); RegisterTrackedTokenBoxSource((Component)(object)item); } InvalidateTokenBoxCache(); } } private static void UnregisterTrackedItem(ItemAttributes item) { if (!((Object)(object)item == (Object)null)) { trackedItems.Remove(item); if (trackedTokenBoxItems.Remove(item)) { UnregisterTrackedTokenBoxSource((Component)(object)item); } UnregisterTrackedValuable(((Component)item).GetComponent<ValuableObject>()); UnregisterTrackedCart(((Component)item).GetComponent<PhysGrabCart>()); UnregisterTrackedCustomDiscoverable(((Component)item).GetComponent<ValuableDiscoverCustom>()); Plugin instance = Instance; if ((Object)(object)instance != (Object)null) { instance.itemSearchTextCache.Remove(((Object)item).GetInstanceID()); instance.itemTokenBoxCandidateCache.Remove(((Object)item).GetInstanceID()); } InvalidateTokenBoxCache(); } } private static void RegisterTrackedCustomDiscoverable(ValuableDiscoverCustom customDiscoverable) { if ((Object)(object)customDiscoverable != (Object)null && !trackedCustomDiscoverables.Contains(customDiscoverable)) { trackedCustomDiscoverables.Add(customDiscoverable); TrackNotifierForCustomDiscoverable(customDiscoverable); RegisterTrackedTokenBoxSource((Component)(object)customDiscoverable); InvalidateTokenBoxCache(); } } private static void UnregisterTrackedCustomDiscoverable(ValuableDiscoverCustom customDiscoverable) { if ((Object)(object)customDiscoverable != (Object)null && trackedCustomDiscoverables.Remove(customDiscoverable)) { UnregisterTrackedTokenBoxSource((Component)(object)customDiscoverable); InvalidateTokenBoxCache(); } } private static void RegisterTrackedCosmeticShopMachine(CosmeticShopMachine machine) { if ((Object)(object)machine != (Object)null && !trackedCosmeticShopMachines.Contains(machine)) { trackedCosmeticShopMachines.Add(machine); TrackNotifierForCosmeticShopMachine(machine); RegisterTrackedTokenBoxSource((Component)(object)machine); InvalidateTokenBoxCache(); } } private static void UnregisterTrackedCosmeticShopMachine(CosmeticShopMachine machine) { if ((Object)(object)machine != (Object)null && trackedCosmeticShopMachines.Remove(machine)) { UnregisterTrackedTokenBoxSource((Component)(object)machine); InvalidateTokenBoxCache(); } } private static void ClearTrackedTokenSources() { trackedItems.Clear(); trackedTokenBoxItems.Clear(); trackedCustomDiscoverables.Clear(); trackedCosmeticShopMachines.Clear(); trackedTokenBoxObjectRefCounts.Clear(); trackedTokenBoxObjectCount = 0; Plugin instance = Instance; if ((Object)(object)instance != (Object)null) { instance.itemSearchTextCache.Clear(); instance.itemTokenBoxCandidateCache.Clear(); instance.tokenBoxCountLastUpdate = -1f; } InvalidateTokenBoxCache(); } private static void InvalidateTokenBoxCache() { } private static void RegisterTrackedTokenBoxSource(Component component) { if (TryGetTrackedTokenBoxObjectId(component, requireLiveScene: true, out var objectId)) { trackedTokenBoxObjectRefCounts.TryGetValue(objectId, out var value); trackedTokenBoxObjectRefCounts[objectId] = value + 1; if (value == 0) { trackedTokenBoxObjectCount++; } } } private static void UnregisterTrackedTokenBoxSource(Component component) { if (TryGetTrackedTokenBoxObjectId(component, requireLiveScene: false, out var objectId) && trackedTokenBoxObjectRefCounts.TryGetValue(objectId, out var value)) { if (value <= 1) { trackedTokenBoxObjectRefCounts.Remove(objectId); trackedTokenBoxObjectCount = Math.Max(0, trackedTokenBoxObjectCount - 1); } else { trackedTokenBoxObjectRefCounts[objectId] = value - 1; } } } private static bool TryGetTrackedTokenBoxObjectId(Component component, bool requireLiveScene, out int objectId) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) objectId = 0; if ((Object)(object)component == (Object)null || (Object)(object)component.gameObject == (Object)null) { return false; } GameObject gameObject = component.gameObject; Scene scene; if (requireLiveScene) { scene = gameObject.scene; if (!((Scene)(ref scene)).IsValid() || !gameObject.activeInHierarchy) { return false; } } else { scene = gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return false; } } objectId = ((Object)gameObject).GetInstanceID(); return objectId != 0; } private static void RebuildTrackedTokenBoxCount() { trackedTokenBoxObjectRefCounts.Clear(); trackedTokenBoxObjectCount = 0; foreach (CosmeticShopMachine trackedCosmeticShopMachine in trackedCosmeticShopMachines) { TryRegisterTrackedTokenBoxSourceForRebuild((Component)(object)trackedCosmeticShopMachine); } foreach (ValuableDiscoverCustom trackedCustomDiscoverable in trackedCustomDiscoverables) { TryRegisterTrackedTokenBoxSourceForRebuild((Component)(object)trackedCustomDiscoverable); } foreach (ItemAttributes trackedTokenBoxItem in trackedTokenBoxItems) { TryRegisterTrackedTokenBoxSourceForRebuild((Component)(object)trackedTokenBoxItem); } } private static void TryRegisterTrackedTokenBoxSourceForRebuild(Component component) { if (TryGetTrackedTokenBoxObjectId(component, requireLiveScene: true, out var objectId)) { trackedTokenBoxObjectRefCounts.TryGetValue(objectId, out var value); trackedTokenBoxObjectRefCounts[objectId] = value + 1; if (value == 0) { trackedTokenBoxObjectCount++; } } } private static void TrackNotifierForValuable(ValuableObject valuable) { GetOrAddTrackedObjectNotifier((Component)(object)valuable)?.TrackValuable(valuable); } private static void TrackNotifierForCart(PhysGrabCart cart) { GetOrAddTrackedObjectNotifier((Component)(object)cart)?.TrackCart(cart); } private static void TrackNotifierForVehicle(ItemVehicle vehicle) { GetOrAddTrackedObjectNotifier((Component)(object)vehicle)?.TrackVehicle(vehicle); } private static void TrackNotifierForEnemy(Enemy enemy) { GetOrAddTrackedObjectNotifier((Component)(object)enemy)?.TrackEnemy(enemy); } private static void TrackNotifierForCustomDiscoverable(ValuableDiscoverCustom customDiscoverable) { GetOrAddTrackedObjectNotifier((Component)(object)customDiscoverable)?.TrackCustomDiscoverable(customDiscoverable); } private static void TrackNotifierForCosmeticShopMachine(CosmeticShopMachine machine) { GetOrAddTrackedObjectNotifier((Component)(object)machine)?.TrackCosmeticShopMachine(machine); } private static MoreUiTrackedObjectNotifier GetOrAddTrackedObjectNotifier(Component component) { if ((Object)(object)component == (Object)null || (Object)(object)component.gameObject == (Object)null) { return null; } MoreUiTrackedObjectNotifier component2 = component.GetComponent<MoreUiTrackedObjectNotifier>(); if ((Object)(object)component2 != (Object)null) { return component2; } try { return component.gameObject.AddComponent<MoreUiTrackedObjectNotifier>(); } catch { return null; } } private void ApplyNativeNamePatch() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { nativeNameHarmony = new Harmony("zichen.moreui.nativename"); PatchNativeNameMethod(typeof(PlayerNameChecker), "Update", "PlayerNameCheckerUpdatePrefix", prefix: true); PatchNativeNameMethod(typeof(WorldSpaceUIPlayerName), "Update", "WorldSpaceUIPlayerNameUpdatePrefix", prefix: true); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Native teammate name display suppression patched."); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to patch native name display: {arg}"); } } private void PatchNativeNameMethod(Type originalType, string originalName, string patchName, bool prefix) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(originalType, originalName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Plugin), patchName, (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find native name patch target: " + originalType?.Name + "." + originalName)); } else if (prefix) { nativeNameHarmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { nativeNameHarmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool PlayerNameCheckerUpdatePrefix() { return !ShouldSuppressOfficialTeammateNames(); } private static bool WorldSpaceUIPlayerNameUpdatePrefix(WorldSpaceUIPlayerName __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!ShouldSuppressOfficialTeammateNames()) { return true; } TextMeshProUGUI text = __instance.text; if ((Object)(object)text == (Object)null) { return false; } Color color = ((Graphic)text).color; color.a = 0f; ((Graphic)text).color = color; ((TMP_Text)text).richText = false; SetWorldSpaceUiShowTimerFast(__instance, 0f); return false; } private static bool ShouldSuppressOfficialTeammateNames() { if (!IsStaticModEnabled() || !IsRunLevelSafe()) { return false; } Plugin instance = Instance; if ((Object)(object)instance != (Object)null && instance.teammateOverlayEnabled != null) { return instance.teammateOverlayEnabled.Value; } return false; } public static bool UseChinese() { Plugin instance = Instance; if ((Object)(object)instance == (Object)null || instance.displayLanguage == null) { return false; } return instance.displayLanguage.Value == DisplayLanguage.中文; } private static DisplayLanguage DetectDefaultLanguage() { try { foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { string text = pluginInfo.Key ?? string.Empty; string text2 = ((pluginInfo.Value == null || pluginInfo.Value.Metadata == null) ? string.Empty : (pluginInfo.Value.Metadata.Name ?? string.Empty)); for (int i = 0; i < _chineseModKeywords.Length; i++) { string value = _chineseModKeywords[i]; if ((!string.IsNullOrEmpty(text) && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) || (!string.IsNullOrEmpty(text2) && text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)) { return DisplayLanguage.中文; } } for (int j = 0; j < _chineseEnvironmentPluginGuids.Length; j++) { if (string.Equals(text, _chineseEnvironmentPluginGuids[j], StringComparison.OrdinalIgnoreCase)) { return DisplayLanguage.中文; } } } } catch { } return DisplayLanguage.English; } private ConfigEntry<T> BindI18N<T>(string sectEN, string sectCN, string keyEN, string keyCN, string descEN, string descCN, T defaultVal, AcceptableValueBase acceptableValues = null, int? order = null, Action<ConfigEntryBase> customDrawer = null, string displayEN = null) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes(); if (order.HasValue) { configurationManagerAttributes.Order = order.Value; } if (customDrawer != null) { configurationManagerAttributes.CustomDrawer = customDrawer; } CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, descEN, descCN, configurationManagerAttributes, readOnly: false); cfgI18N.DisplayEN = displayEN; ApplyI18N(cfgI18N); return (ConfigEntry<T>)(object)(cfgI18N.Entry = (ConfigEntryBase)(object)((BaseUnityPlugin)this).Config.Bind<T>(sectEN, keyEN, defaultVal, new ConfigDescription(descEN, acceptableValues, new object[1] { configurationManagerAttributes }))); } private void BindReadOnlyI18N(string sectEN, string sectCN, string keyEN, string keyCN, string valueEN, string valueCN, int? order = null, Action<ConfigEntryBase> customDrawer = null, string displayEN = null) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { ReadOnly = true }; if (order.HasValue) { configurationManagerAttributes.Order = order.Value; } if (customDrawer != null) { configurationManagerAttributes.CustomDrawer = customDrawer; } CfgI18N cfgI18N = NewI18N(sectEN, sectCN, keyEN, keyCN, string.Empty, string.Empty, configurationManagerAttributes, readOnly: true); cfgI18N.ValueEN = valueEN; cfgI18N.ValueCN = valueCN; cfgI18N.DisplayEN = displayEN; ApplyI18N(cfgI18N); cfgI18N.ReadOnlyEntry = ((BaseUnityPlugin)this).Config.Bind<string>(sectEN, keyEN, UseChinese() ? valueCN : valueEN, new ConfigDescription(string.Empty, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); cfgI18N.Entry = (ConfigEntryBase)(object)cfgI18N.ReadOnlyEntry; string text = (UseChinese() ? valueCN : valueEN); if (cfgI18N.ReadOnlyEntry.Value != text) { cfgI18N.ReadOnlyEntry.Value = text; } } private static CfgI18N NewI18N(string sectEN, string sectCN, string keyEN, string keyCN, string descEN, string descCN, ConfigurationManagerAttributes attrs, bool readOnly) { CfgI18N cfgI18N = new CfgI18N { SectionEN = sectEN, SectionCN = sectCN, KeyEN = keyEN, KeyCN = keyCN, DescEN = descEN, DescCN = descCN, Attrs = attrs }; ApplyI18N(cfgI18N); _cfgI18Ns.Add(cfgI18N); _cfgByEnSection[sectEN] = cfgI18N; _cfgByEnKey[sectEN + "\0" + keyEN] = cfgI18N; if (!_cfgByKeyOnly.TryGetValue(keyEN, out var value)) { value = new List<CfgI18N>(2); _cfgByKeyOnly[keyEN] = value; } value.Add(cfgI18N); string text = FixNamingForLookup(keyEN); if (!string.Equals(text, keyEN, StringComparison.Ordinal)) { if (!_cfgByKeyOnly.TryGetValue(text, out var value2)) { value2 = new List<CfgI18N>(2); _cfgByKeyOnly[text] = value2; } if (!value2.Contains(cfgI18N)) { value2.Add(cfgI18N); } } return cfgI18N; } private static void ApplyI18N(CfgI18N i18n) { if (i18n == null || i18n.Attrs == null) { return; } bool flag = UseChinese(); i18n.Attrs.Category = (flag ? i18n.SectionCN : i18n.SectionEN); i18n.Attrs.DispName = (flag ? i18n.KeyCN : (i18n.DisplayEN ?? i18n.KeyEN)); i18n.Attrs.Description = (flag ? i18n.DescCN : i18n.DescEN); if (i18n.ReadOnlyEntry != null) { string text = (flag ? i18n.ValueCN : i18n.ValueEN); if (i18n.ReadOnlyEntry.Value != text) { i18n.ReadOnlyEntry.Value = text; } } } private static void RefreshAllI18N() { for (int i = 0; i < _cfgI18Ns.Count; i++) { ApplyI18N(_cfgI18Ns[i]); } RefreshLiveLabels(); } private static string FixNamingForLookup(string input) { if (string.IsNullOrEmpty(input)) { return input; } input = Regex.Replace(input, "([a-z])([A-Z])", "$1 $2"); input = Regex.Replace(input, "([A-Z])([A-Z][a-z])", "$1 $2"); input = Regex.Replace(input, "\\s+", " "); input = Regex.Replace(input, "([A-Z]\\.)\\s([A-Z]\\.)", "$1$2"); return input.Trim(); } internal static void TryHookREPOConfig(Harmony h) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_018a: Expected O, but got Unknown try { Type type = AccessTools.TypeByName("MenuLib.MenuAPI"); if (type == null) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)"MenuLib not detected, skip REPOConfig bilingual hook."); } return; } Harmo