using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using MenuLib.Structs; using Microsoft.CodeAnalysis; using MoreHead; using Newtonsoft.Json; using Photon.Pun; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("YMC_MHZ")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyDescription("一个简单好玩的装饰模组,提供unitypackage,供玩家自行导入模型。")] [assembly: AssemblyFileVersion("1.4.5.0")] [assembly: AssemblyInformationalVersion("1.4.5+fb1e87f19f865b08e90354213ff2b4919d362595")] [assembly: AssemblyProduct("MoreHead")] [assembly: AssemblyTitle("MoreHead")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.4.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [BepInPlugin("Mhz.REPOMoreHead", "MoreHead", "1.4.5")] public class Morehead : BaseUnityPlugin { private const string PluginGuid = "Mhz.REPOMoreHead"; private const string PluginName = "MoreHead"; private const string PluginVersion = "1.4.5"; public static ManualLogSource? Logger; public static Morehead? Instance { get; private set; } public static string GetPluginVersion() { return "1.4.5"; } private void Awake() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; try { Harmony val = new Harmony("Mhz.REPOMoreHead"); val.PatchAll(typeof(PlayerAvatarVisualsPatch)); val.PatchAll(typeof(PlayerUpdatePatch)); val.PatchAll(typeof(PlayerAvatarAwakePatch)); val.PatchAll(typeof(GameDirectorUpdatePatch)); val.PatchAll(typeof(PlayerRevivePatch)); val.PatchAll(typeof(MenuManagerStartPatch)); val.PatchAll(typeof(MenuButtonHoveringPatch)); val.PatchAll(typeof(MenuButtonHoverEndPatch)); val.PatchAll(typeof(MenuPageStateSetPatch)); val.PatchAll(typeof(MenuScrollBox_Update_Patch)); val.PatchAll(typeof(REPOInputStringSystem_HandleInput_Patch)); string text = "\r\n\r\n ███▄ ▄███▓ ▒█████ ██▀███ ▓█████ ██░ ██ ▓█████ ▄▄▄ ▓█████▄ \r\n▓██▒▀█▀ ██▒▒██▒ ██▒▓██ ▒ ██▒▓█ ▀ ▓██░ ██▒▓█ ▀▒████▄ ▒██▀ ██▌\r\n▓██ ▓██░▒██░ ██▒▓██ ░▄█ ▒▒███ ▒██▀███░▒███ ▒██ ▀█▄ ░██ █▌\r\n▒██ ▒██ ▒██ ██░▒███▀█▄ ▒▓█ ▄ ░▓█ ░██ ▒▓█ ▄░██▄▄▄▄██ ░▓█▄ ▌\r\n▒██▒ ░██▒░ ████▓▒░░██▓ ▒██▒░▒████▒░▓█▒░██▓░▒████▒▓█ ▓██▒░▒████▓ v1.4.5\r\n░ ▒░ ░ ░░ ▒░▒░▒░ ░ ▒▓ ░▒▓░░░ ▒░ ░ ▒ ░░▒░▒░░ ▒░ ░▒▒ ▓▒█░ ▒▒▓ ▒ \r\n░ ░ ░ ░ ▒ ▒░ ░▒ ░ ▒░ ░ ░ ░ ▒ ░▒░ ░ ░ ░ ░ ▒ ▒▒ ░ ░ ▒ ▒ \r\n░ ░ ░ ░ ░ ▒ ░░ ░ ░ ░ ░░ ░ ░ ░ ▒ ░ ░ ░ \r\n ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ \r\n"; ManualLogSource? logger = Logger; if (logger != null) { logger.LogMessage((object)text); } DecorationBlacklistManager.Initialize(); HeadDecorationManager.Initialize(); ConfigManager.Initialize(); } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("Harmony补丁应用失败: " + ex.Message)); } } } private void OnApplicationQuit() { ConfigManager.SaveConfig(); } public static bool GetDecorationState(string? name) { return HeadDecorationManager.GetDecorationState(name); } } [HarmonyPatch(typeof(MenuManager))] [HarmonyPatch("Start")] internal class MenuManagerStartPatch { [HarmonyPostfix] private static void Postfix() { try { if ((Object)(object)MenuManager.instance != (Object)null && MenuManager.instance.menuPages != null && MenuManager.instance.menuPages.Count > 0) { MoreHeadUI.Initialize(); MoreHeadUI.InitializeShortcutListener(); return; } ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"MenuManager未准备好,无法初始化UI"); } } catch (Exception arg) { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogError((object)$"在MenuManager.Start补丁中初始化UI时出错: {arg}"); } } } } [HarmonyPatch(typeof(PlayerAvatar))] [HarmonyPatch("Update")] internal class PlayerUpdatePatch { private static void Postfix(PlayerAvatar __instance) { if (__instance.photonView.IsMine && GameManager.Multiplayer() && PhotonNetwork.LocalPlayer != null) { } } public static void UpdatePlayerDecorations(PlayerAvatar playerAvatar) { try { if ((Object)(object)playerAvatar?.playerAvatarVisuals == (Object)null) { return; } Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)playerAvatar.playerAvatarVisuals).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"找不到任何装饰物父级节点"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { if (decorationParentNodes.TryGetValue(decoration.ParentTag ?? string.Empty, out var value)) { Transform val = value.Find("HeadDecorations"); if ((Object)(object)val != (Object)null) { DecorationUtils.UpdateDecoration(val, decoration.Name ?? string.Empty, decoration.IsVisible); } } else { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)("找不到装饰物 " + decoration.DisplayName + " 的父级节点: " + decoration.ParentTag)); } } } } catch (Exception ex) { ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("更新玩家装饰物时出错: " + ex.Message)); } } } public static void UpdateMenuPlayerDecorations() { try { PlayerAvatarVisuals val = FindMenuPlayerVisuals(); if ((Object)(object)val == (Object)null) { return; } Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)val).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"找不到任何菜单角色装饰物父级节点"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { if (decorationParentNodes.TryGetValue(decoration.ParentTag ?? string.Empty, out var value)) { Transform val2 = value.Find("HeadDecorations"); if ((Object)(object)val2 != (Object)null) { Transform val3 = val2.Find(decoration.Name); if ((Object)(object)val3 == (Object)null) { AddMenuDecoration(val2, decoration.Name); } else { DecorationUtils.UpdateDecoration(val2, decoration.Name ?? string.Empty, decoration.IsVisible); } } } else { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)("找不到菜单角色装饰物 " + decoration.DisplayName + " 的父级节点: " + decoration.ParentTag)); } } } } catch (Exception ex) { ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("更新菜单角色装饰物状态失败: " + ex.Message)); } } } private static PlayerAvatarVisuals? FindMenuPlayerVisuals() { if ((Object)(object)PlayerAvatarMenu.instance == (Object)null) { return null; } return ((Component)PlayerAvatarMenu.instance).GetComponentInChildren(); } public static void AddMenuDecoration(Transform parent, string? decorationName) { string decorationName2 = decorationName; try { Transform val = parent.Find(decorationName2); if ((Object)(object)val != (Object)null) { bool decorationState = Morehead.GetDecorationState(decorationName2); ((Component)val).gameObject.SetActive(decorationState); return; } DecorationInfo decorationInfo = HeadDecorationManager.Decorations.Find((DecorationInfo d) => d.Name != null && d.Name.Equals(decorationName2, StringComparison.OrdinalIgnoreCase)); if (decorationInfo != null && (Object)(object)decorationInfo.Prefab != (Object)null) { GameObject val2 = Object.Instantiate(decorationInfo.Prefab, parent); ((Object)val2).name = decorationName2; val2.SetActive(decorationInfo.IsVisible); return; } ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)("AddMenuDecoration: 找不到装饰物 " + decorationName2 + " 或其预制体为空")); } } catch (Exception ex) { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogError((object)("为菜单角色添加装饰物时出错: " + ex.Message)); } } } } [HarmonyPatch(typeof(PlayerAvatar))] [HarmonyPatch("Awake")] internal class PlayerAvatarAwakePatch { private static void Postfix(PlayerAvatar __instance) { ((Component)__instance).gameObject.AddComponent(); } } public class HeadDecorationSync : MonoBehaviourPun { public void SyncAllDecorations() { try { SyncAllDecorationsCompressed(); HeadDecorationManager.ClearChangedDecorations(); } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("同步所有装饰物状态失败: " + ex.Message)); } } } private void SyncAllDecorationsCompressed() { try { List decorations = HeadDecorationManager.Decorations; int count = decorations.Count; if (count == 0) { return; } int num = (count + 7) / 8; byte[] array = new byte[num]; Dictionary dictionary = new Dictionary(); List list = new List(); for (int i = 0; i < count; i++) { DecorationInfo decorationInfo = decorations[i]; string text = decorationInfo.ParentTag ?? string.Empty; if (!dictionary.ContainsKey(text)) { dictionary[text] = list.Count; list.Add(text); } if (decorationInfo.IsVisible) { int num2 = i / 8; int num3 = i % 8; array[num2] |= (byte)(1 << num3); } } string[] array2 = new string[count]; byte[] array3 = new byte[count]; for (int j = 0; j < count; j++) { DecorationInfo decorationInfo2 = decorations[j]; array2[j] = decorationInfo2.Name ?? string.Empty; array3[j] = (byte)dictionary[decorationInfo2.ParentTag ?? string.Empty]; } ((MonoBehaviourPun)this).photonView.RPC("UpdateAllDecorationsCompressed", (RpcTarget)1, new object[4] { array, array2, list.ToArray(), array3 }); } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("压缩同步所有装饰物状态失败: " + ex.Message)); } } } public void SyncChangedDecorations() { try { List changedDecorations = HeadDecorationManager.GetChangedDecorations(); if (changedDecorations.Count == 0) { return; } string[] array = new string[changedDecorations.Count]; bool[] array2 = new bool[changedDecorations.Count]; string[] array3 = new string[changedDecorations.Count]; int num = 0; foreach (string child in changedDecorations) { DecorationInfo decorationInfo = HeadDecorationManager.Decorations.Find((DecorationInfo d) => d.Name == child); if (decorationInfo != null) { array[num] = decorationInfo.Name; array2[num] = decorationInfo.IsVisible; array3[num] = decorationInfo.ParentTag; num++; } } ((MonoBehaviourPun)this).photonView.RPC("UpdateChangedDecorations", (RpcTarget)1, new object[3] { array, array2, array3 }); HeadDecorationManager.ClearChangedDecorations(); } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("同步变化装饰物状态失败: " + ex.Message)); } } } [PunRPC] private void UpdateAllDecorations(string[] names, bool[] states, string[] parentTags) { try { PlayerAvatar component = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.playerAvatarVisuals == (Object)null) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"找不到PlayerAvatar或PlayerAvatarVisuals组件"); } return; } Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)component.playerAvatarVisuals).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)"找不到任何装饰物父级节点"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); for (int i = 0; i < names.Length; i++) { string decorationName = names[i]; bool showDecoration = states[i]; string key = parentTags[i]; if (decorationParentNodes.TryGetValue(key, out var value)) { Transform val = value.Find("HeadDecorations"); if ((Object)(object)val != (Object)null) { DecorationUtils.UpdateDecoration(val, decorationName, showDecoration); } } } } catch (Exception ex) { ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("RPC更新所有装饰物状态失败: " + ex.Message)); } } } [PunRPC] private void UpdateAllDecorationsCompressed(byte[] stateBitmap, string[] names, string[] parentTags, byte[] tagIndices) { try { PlayerAvatar component = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.playerAvatarVisuals == (Object)null) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"找不到PlayerAvatar或PlayerAvatarVisuals组件"); } return; } Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)component.playerAvatarVisuals).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)"找不到任何装饰物父级节点"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); for (int i = 0; i < names.Length; i++) { int num = i / 8; int num2 = i % 8; bool showDecoration = false; if (num < stateBitmap.Length) { showDecoration = (stateBitmap[num] & (1 << num2)) != 0; } string key = string.Empty; if (i < tagIndices.Length && tagIndices[i] < parentTags.Length) { key = parentTags[tagIndices[i]]; } string decorationName = names[i]; if (decorationParentNodes.TryGetValue(key, out var value)) { Transform val = value.Find("HeadDecorations"); if ((Object)(object)val != (Object)null) { DecorationUtils.UpdateDecoration(val, decorationName, showDecoration); } } } } catch (Exception ex) { ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("RPC更新压缩装饰物状态失败: " + ex.Message)); } } } [PunRPC] private void UpdateChangedDecorations(string[] names, bool[] states, string[] parentTags) { try { PlayerAvatar component = ((Component)this).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.playerAvatarVisuals == (Object)null) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"找不到PlayerAvatar或PlayerAvatarVisuals组件"); } return; } Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)component.playerAvatarVisuals).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)"找不到任何装饰物父级节点"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); for (int i = 0; i < names.Length; i++) { string decorationName = names[i]; bool showDecoration = states[i]; string key = parentTags[i]; if (decorationParentNodes.TryGetValue(key, out var value)) { Transform val = value.Find("HeadDecorations"); if ((Object)(object)val != (Object)null) { DecorationUtils.UpdateDecoration(val, decorationName, showDecoration); } } } } catch (Exception ex) { ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("RPC更新变化装饰物状态失败: " + ex.Message)); } } } } [HarmonyPatch(typeof(PlayerAvatarVisuals))] [HarmonyPatch("Start")] internal class PlayerAvatarVisualsPatch { private static void Postfix(PlayerAvatarVisuals __instance) { try { Dictionary decorationParentNodes = DecorationUtils.GetDecorationParentNodes(((Component)__instance).transform); if (decorationParentNodes.Count == 0) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)$"找不到任何装饰物父级节点 (isMenuAvatar: {__instance.isMenuAvatar})"); } return; } DecorationUtils.EnsureDecorationContainers(decorationParentNodes); if (__instance.isMenuAvatar) { foreach (KeyValuePair item in decorationParentNodes) { string key = item.Key; Transform value = item.Value; Transform val = value.Find("HeadDecorations"); if ((Object)(object)val != (Object)null) { foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { if (decoration.ParentTag == key) { PlayerUpdatePatch.AddMenuDecoration(val, decoration.Name); } } } } return; } foreach (DecorationInfo decoration2 in HeadDecorationManager.Decorations) { if (decorationParentNodes.TryGetValue(decoration2.ParentTag ?? string.Empty, out var value2)) { Transform val2 = value2.Find("HeadDecorations"); if ((Object)(object)val2 != (Object)null) { AddNewDecoration(val2, decoration2, __instance); } } else { ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)("初始化时找不到装饰物 " + decoration2.DisplayName + " 的父级节点: " + decoration2.ParentTag)); } } } if (!GameManager.Multiplayer() || !((Object)(object)__instance.playerAvatar != (Object)null) || !((Object)(object)__instance.playerAvatar.photonView != (Object)null) || !__instance.playerAvatar.photonView.IsMine) { return; } try { HeadDecorationSync component = ((Component)__instance.playerAvatar).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncAllDecorations(); return; } ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogWarning((object)"找不到HeadDecorationSync组件,无法同步初始状态"); } } catch (Exception ex) { ManualLogSource? logger4 = Morehead.Logger; if (logger4 != null) { logger4.LogError((object)("同步初始装饰物状态失败: " + ex.Message)); } } } catch (Exception ex2) { ManualLogSource? logger5 = Morehead.Logger; if (logger5 != null) { logger5.LogError((object)$"添加装饰物失败: {ex2.Message} (isMenuAvatar: {__instance.isMenuAvatar})"); } } } private static void AddNewDecoration(Transform parent, DecorationInfo decoration, PlayerAvatarVisuals __instance) { Transform val = parent.Find(decoration.Name); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(decoration.IsVisible); return; } if ((Object)(object)decoration.Prefab != (Object)null) { try { GameObject val2 = Object.Instantiate(decoration.Prefab, parent); ((Object)val2).name = decoration.Name; val2.SetActive(decoration.IsVisible); return; } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("实例化预制体时出错: " + ex.Message)); } return; } } ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogWarning((object)("AddNewDecoration: 装饰物 " + decoration.DisplayName + " 的预制体为空")); } } } [HarmonyPatch(typeof(GameDirector))] [HarmonyPatch("Update")] internal class GameDirectorUpdatePatch { private static gameState previousState; private static void Postfix(GameDirector __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) try { if ((int)previousState != 2 && (int)__instance.currentState == 2) { SyncAllPlayersDecorations(); } previousState = __instance.currentState; } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("监听游戏状态变化时出错: " + ex.Message)); } } } private static void SyncAllPlayersDecorations() { try { PlayerAvatar val = FindLocalPlayer(); if ((Object)(object)val != (Object)null) { PlayerUpdatePatch.UpdatePlayerDecorations(val); HeadDecorationSync component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncAllDecorations(); } } } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("同步所有玩家装饰物状态时出错: " + ex.Message)); } } } private static PlayerAvatar? FindLocalPlayer() { try { PlayerAvatar[] array = Object.FindObjectsOfType(); PlayerAvatar[] array2 = array; foreach (PlayerAvatar val in array2) { if ((Object)(object)val?.photonView != (Object)null && val.photonView.IsMine) { return val; } } } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("查找本地玩家时出错: " + ex.Message)); } } return null; } } [HarmonyPatch(typeof(PlayerAvatar))] [HarmonyPatch("ReviveRPC")] internal class PlayerRevivePatch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerAvatar playerAvatar; private Exception 5__1; private HeadDecorationSync 5__2; private Exception 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; case 2: <>1__state = -1; try { PlayerUpdatePatch.UpdatePlayerDecorations(playerAvatar); } catch (Exception ex) { 5__1 = ex; ManualLogSource? logger3 = Morehead.Logger; if (logger3 != null) { logger3.LogError((object)("更新玩家装饰物状态失败: " + 5__1.Message)); } } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; case 3: <>1__state = -1; try { 5__2 = ((Component)playerAvatar).GetComponent(); if ((Object)(object)5__2 != (Object)null) { 5__2.SyncAllDecorations(); } else { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogWarning((object)"玩家复活后找不到HeadDecorationSync组件"); } } 5__2 = null; } catch (Exception ex) { 5__3 = ex; ManualLogSource? logger2 = Morehead.Logger; if (logger2 != null) { logger2.LogError((object)("同步装饰物状态失败: " + 5__3.Message)); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static void Postfix(PlayerAvatar __instance) { try { if (__instance.photonView.IsMine) { ((MonoBehaviour)__instance).StartCoroutine(DelayedSync(__instance)); } } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("玩家复活时同步装饰物状态失败: " + ex.Message)); } } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator DelayedSync(PlayerAvatar playerAvatar) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { playerAvatar = playerAvatar }; } } public class DecorationButtonMarker : MonoBehaviour { public DecorationInfo? Decoration { get; set; } public bool HasHandledHover { get; set; } } [HarmonyPatch(typeof(MenuButton))] [HarmonyPatch("OnHovering")] internal class MenuButtonHoveringPatch { [HarmonyPostfix] private static void Postfix(MenuButton __instance) { try { if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null || !((Component)__instance).gameObject.activeInHierarchy) { return; } DecorationButtonMarker decorationButtonMarker = null; try { foreach (DecorationButtonMarker value2 in MoreHeadUI.buttonMarkers.Values) { if ((Object)(object)value2 != (Object)null && (Object)(object)((Component)value2).gameObject != (Object)null && (Object)(object)((Component)value2).gameObject == (Object)(object)((Component)__instance).gameObject) { decorationButtonMarker = value2; break; } } } catch (Exception) { return; } if ((Object)(object)decorationButtonMarker == (Object)null || decorationButtonMarker.Decoration == null || decorationButtonMarker.HasHandledHover) { return; } DecorationInfo decoration = decorationButtonMarker.Decoration; if (string.IsNullOrEmpty(decoration.ModName)) { return; } if (MoreHeadUI.decorationButtons.TryGetValue(decoration.Name ?? string.Empty, out REPOButton value)) { if ((Object)(object)value == (Object)null || (Object)(object)value.labelTMP == (Object)null) { return; } if (!((TMP_Text)value.labelTMP).text.Contains(decoration.ModName)) { ((TMP_Text)value.labelTMP).text = ((TMP_Text)value.labelTMP).text + " - " + decoration.ModName + ""; } } decorationButtonMarker.HasHandledHover = true; } catch (Exception ex2) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("MenuButton.OnHovering补丁出错: " + ex2.Message + "\n" + ex2.StackTrace)); } } } } [HarmonyPatch(typeof(MenuButton))] [HarmonyPatch("OnHoverEnd")] internal class MenuButtonHoverEndPatch { [HarmonyPostfix] private static void Postfix(MenuButton __instance) { try { if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null || !((Component)__instance).gameObject.activeInHierarchy) { return; } DecorationButtonMarker decorationButtonMarker = null; try { foreach (DecorationButtonMarker value3 in MoreHeadUI.buttonMarkers.Values) { if ((Object)(object)value3 != (Object)null && (Object)(object)((Component)value3).gameObject != (Object)null && (Object)(object)((Component)value3).gameObject == (Object)(object)((Component)__instance).gameObject) { decorationButtonMarker = value3; break; } } } catch (Exception) { return; } if ((Object)(object)decorationButtonMarker == (Object)null || decorationButtonMarker.Decoration == null) { return; } DecorationInfo decoration = decorationButtonMarker.Decoration; if (string.IsNullOrEmpty(decoration.ModName)) { return; } if (MoreHeadUI.decorationButtons.TryGetValue(decoration.Name ?? string.Empty, out REPOButton value)) { if ((Object)(object)value == (Object)null || (Object)(object)value.labelTMP == (Object)null) { return; } string text = ((TMP_Text)value.labelTMP).text; string value2 = " - " + decoration.ModName + ""; int num = text.IndexOf(value2); if (num != -1) { ((TMP_Text)value.labelTMP).text = text.Substring(0, num).TrimEnd(); } } decorationButtonMarker.HasHandledHover = false; } catch (Exception ex2) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("MenuButton.OnHoverEnd补丁出错: " + ex2.Message + "\n" + ex2.StackTrace)); } } } } [HarmonyPatch(typeof(MenuPage))] [HarmonyPatch("PageStateSet")] internal class MenuPageStateSetPatch { [HarmonyPostfix] private static void Postfix(MenuPage __instance, PageState pageState) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 try { if (((int)pageState == 2 || (int)pageState == 3) && (Object)(object)MoreHeadUI.decorationsPage != (Object)null && (Object)(object)__instance == (Object)(object)MoreHeadUI.decorationsPage.menuPage) { MoreHeadUI.SafeDestroyAvatar(); } } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("MenuPage.PageStateSet补丁出错: " + ex.Message + "\n" + ex.StackTrace)); } } } } [HarmonyPatch(typeof(MenuScrollBox))] [HarmonyPatch("Update")] internal class MenuScrollBox_Update_Patch { private static readonly FieldRef GetParentPage = AccessTools.FieldRefAccess("parentPage"); private static readonly FieldRef GetPageScrollBoxes = AccessTools.FieldRefAccess("scrollBoxes"); private static readonly FieldRef GetMenuElementHover = AccessTools.FieldRefAccess("menuElementHover"); private static readonly FieldRef refScrollBoxActive = AccessTools.FieldRefAccess("scrollBoxActive"); private static readonly FieldRef GetScrollBar = AccessTools.FieldRefAccess("scrollBar"); private static readonly FieldRef GetScrollHandle = AccessTools.FieldRefAccess("scrollHandle"); private static readonly FieldRef refScrollHandleTargetPosition = AccessTools.FieldRefAccess("scrollHandleTargetPosition"); private static readonly FieldRef GetScrollBarBackground = AccessTools.FieldRefAccess("scrollBarBackground"); private static readonly FieldRef refScrollAmount = AccessTools.FieldRefAccess("scrollAmount"); private static readonly FieldRef GetScroller = AccessTools.FieldRefAccess("scroller"); private static readonly FieldRef GetScrollerStartPosition = AccessTools.FieldRefAccess("scrollerStartPosition"); private static readonly FieldRef GetScrollerEndPosition = AccessTools.FieldRefAccess("scrollerEndPosition"); private static readonly FieldRef GetMenuSelectableElement = AccessTools.FieldRefAccess("menuSelectableElement"); private static readonly FieldRef GetIsHovering = AccessTools.FieldRefAccess("isHovering"); private static readonly FieldRef GetMenuID = AccessTools.FieldRefAccess("menuID"); [HarmonyPrefix] private static bool Prefix(MenuScrollBox __instance) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MoreHeadUI.decorationsPage == (Object)null || (Object)(object)GetParentPage.Invoke(__instance) != (Object)(object)MoreHeadUI.decorationsPage.menuPage) { return true; } MenuPage val = GetParentPage.Invoke(__instance); GameObject val2 = GetScrollBar.Invoke(__instance); RectTransform val3 = GetScrollHandle.Invoke(__instance); RectTransform val4 = GetScrollBarBackground.Invoke(__instance); RectTransform val5 = GetScroller.Invoke(__instance); if (GetPageScrollBoxes.Invoke(val) > 1) { refScrollBoxActive.Invoke(__instance) = GetIsHovering.Invoke(GetMenuElementHover.Invoke(__instance)); } if (!val2.activeSelf) { ((Transform)val3).localPosition = new Vector3(((Transform)val3).localPosition.x, refScrollHandleTargetPosition.Invoke(__instance), ((Transform)val3).localPosition.z); return false; } Rect rect; if (!refScrollBoxActive.Invoke(__instance)) { ((Transform)val3).localPosition = new Vector3(((Transform)val3).localPosition.x, Mathf.Lerp(((Transform)val3).localPosition.y, refScrollHandleTargetPosition.Invoke(__instance), Time.deltaTime * 20f), ((Transform)val3).localPosition.z); ref float reference = ref refScrollAmount.Invoke(__instance); float num = ((Transform)val3).localPosition.y + val3.sizeDelta.y / 2f; rect = val4.rect; reference = Mathf.Clamp01(num / ((Rect)(ref rect)).height); ((Transform)val5).localPosition = new Vector3(((Transform)val5).localPosition.x, Mathf.Lerp(GetScrollerStartPosition.Invoke(__instance), GetScrollerEndPosition.Invoke(__instance), refScrollAmount.Invoke(__instance)), ((Transform)val5).localPosition.z); return false; } if (Input.GetMouseButton(0) && SemiFunc.UIMouseHover(val, val4, GetMenuID.Invoke(GetMenuSelectableElement.Invoke(__instance)), 0f, 0f, (MenuScrollBox)null, (ScrollRect)null)) { float y = SemiFunc.UIMouseGetLocalPositionWithinRectTransform(val4).y; float num2 = y; float num3 = val3.sizeDelta.y / 2f; rect = val4.rect; y = Mathf.Clamp(num2, num3, ((Rect)(ref rect)).height - val3.sizeDelta.y / 2f); refScrollHandleTargetPosition.Invoke(__instance) = y; } float num4 = SemiFunc.InputMovementY() / 20f; float num5 = SemiFunc.InputScrollY(); if (!Mathf.Approximately(num4, 0f) || !Mathf.Approximately(num5, 0f)) { float num6 = Mathf.Abs(GetScrollerEndPosition.Invoke(__instance) - GetScrollerStartPosition.Invoke(__instance)); if (num6 > 0f) { float num7 = 100f; float num9; if (Mathf.Approximately(num5, 0f)) { float num8 = num4 * num7 / num6; rect = val4.rect; num9 = num8 * ((Rect)(ref rect)).height; } else { float num10 = (num4 + Mathf.Sign(num5)) * num7 / num6; rect = val4.rect; num9 = num10 * ((Rect)(ref rect)).height; } float num11 = num9; refScrollHandleTargetPosition.Invoke(__instance) += num11; } ref float reference2 = ref refScrollHandleTargetPosition.Invoke(__instance); float num12 = refScrollHandleTargetPosition.Invoke(__instance); float num13 = val3.sizeDelta.y / 2f; rect = val4.rect; reference2 = Mathf.Clamp(num12, num13, ((Rect)(ref rect)).height - val3.sizeDelta.y / 2f); } ((Transform)val3).localPosition = new Vector3(((Transform)val3).localPosition.x, Mathf.Lerp(((Transform)val3).localPosition.y, refScrollHandleTargetPosition.Invoke(__instance), Time.deltaTime * 20f), ((Transform)val3).localPosition.z); ref float reference3 = ref refScrollAmount.Invoke(__instance); float num14 = ((Transform)val3).localPosition.y + val3.sizeDelta.y / 2f; rect = val4.rect; reference3 = Mathf.Clamp01(num14 / ((Rect)(ref rect)).height); ((Transform)val5).localPosition = new Vector3(((Transform)val5).localPosition.x, Mathf.Lerp(GetScrollerStartPosition.Invoke(__instance), GetScrollerEndPosition.Invoke(__instance), refScrollAmount.Invoke(__instance)), ((Transform)val5).localPosition.z); return false; } } [HarmonyPatch(typeof(REPOInputStringSystem))] [HarmonyPatch("HandleInput")] internal class REPOInputStringSystem_HandleInput_Patch { [CompilerGenerated] private sealed class d__0 : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable instructions; public IEnumerable <>3__instructions; private MethodInfo 5__1; private IEnumerator <>s__2; private CodeInstruction 5__3; CodeInstruction IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } 5__1 = null; <>s__2 = null; 5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = typeof(Input).GetProperty("inputString")?.GetGetMethod(); if (5__1 == null) { return false; } <>s__2 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; if (5__3.opcode == OpCodes.Call && (MethodInfo)5__3.operand == 5__1) { <>2__current = new CodeInstruction(OpCodes.Call, (object)typeof(REPOInputStringSystem_HandleInput_Patch).GetMethod("ProcessMultipleBackspaces", BindingFlags.Static | BindingFlags.NonPublic)); <>1__state = 2; return true; } goto IL_013a; case 2: { <>1__state = -3; goto IL_013a; } IL_013a: 5__3 = null; break; } if (<>s__2.MoveNext()) { 5__3 = <>s__2.Current; <>2__current = 5__3; <>1__state = 1; return true; } <>m__Finally1(); <>s__2 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>s__2 != null) { <>s__2.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__0 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__0(0); } d__.instructions = <>3__instructions; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [IteratorStateMachine(typeof(d__0))] private static IEnumerable Transpiler(IEnumerable instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__0(-2) { <>3__instructions = instructions }; } private static string ProcessMultipleBackspaces(string input) { if (string.IsNullOrEmpty(input)) { return input; } if (input.Length > 1 && input.Contains("\b")) { return "\b"; } return input; } } namespace MoreHead { public static class ConfigManager { private class ConfigData { public Dictionary> OutfitStates { get; set; } = new Dictionary>(); public int CurrentOutfitIndex { get; set; } = 1; } private const string MOD_DATA_FOLDER = "REPOModData"; private const string MOD_FOLDER = "MoreHead"; private const string CONFIG_FILENAME = "MoreHeadConfig.json"; private const string OUTFIT_CONFIG_FILENAME = "MoreHeadOutfits.json"; private static Dictionary _decorationStates = new Dictionary(); private static Dictionary> _outfitStates = new Dictionary>(); private static ManualLogSource? Logger => Morehead.Logger; public static int CurrentOutfitIndex { get; private set; } = 1; private static string NewConfigFilePath => Path.Combine(Application.persistentDataPath, "REPOModData", "MoreHead", "MoreHeadConfig.json"); private static string OutfitConfigFilePath => Path.Combine(Application.persistentDataPath, "REPOModData", "MoreHead", "MoreHeadOutfits.json"); private static string BepInExConfigFilePath => Path.Combine(Paths.ConfigPath, "MoreHeadConfig.json"); private static string OldConfigFilePath { get { Morehead? instance = Morehead.Instance; return Path.Combine(Path.GetDirectoryName((instance != null) ? ((BaseUnityPlugin)instance).Info.Location : null) ?? string.Empty, "MoreHeadConfig.txt"); } } public static void Initialize() { try { EnsureModDataDirectoryExists(); InitializeOutfitStates(); LoadConfig(); ApplyOutfit(CurrentOutfitIndex); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("初始化配置管理器时出错: " + ex.Message)); } } } private static void InitializeOutfitStates() { for (int i = 1; i <= 5; i++) { if (!_outfitStates.ContainsKey(i)) { _outfitStates[i] = new Dictionary(); } } } private static void EnsureModDataDirectoryExists() { try { string text = Path.Combine(Application.persistentDataPath, "REPOModData"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)("已创建MOD数据总文件夹: " + text)); } } string text2 = Path.Combine(text, "MoreHead"); if (!Directory.Exists(text2)) { Directory.CreateDirectory(text2); ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)("已创建MOD特定文件夹: " + text2)); } } } catch (Exception ex) { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogError((object)("创建MOD数据目录时出错: " + ex.Message)); } } } private static void LoadConfig() { try { _decorationStates.Clear(); LoadOutfitConfig(); if (File.Exists(NewConfigFilePath) && LoadJsonConfig(NewConfigFilePath)) { if (_outfitStates[1].Count == 0) { _outfitStates[1] = new Dictionary(_decorationStates); SaveOutfitConfig(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"已将单套配置迁移到第1套装备方案"); } } return; } if (File.Exists(BepInExConfigFilePath) && LoadJsonConfig(BepInExConfigFilePath)) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)("已从BepInEx配置目录加载配置: " + BepInExConfigFilePath)); } SaveConfigWithoutUpdate(); ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogInfo((object)("已将配置从BepInEx目录迁移到Unity存档位置: " + NewConfigFilePath)); } if (_outfitStates[1].Count == 0) { _outfitStates[1] = new Dictionary(_decorationStates); SaveOutfitConfig(); ManualLogSource? logger4 = Logger; if (logger4 != null) { logger4.LogInfo((object)"已将单套配置迁移到第1套装备方案"); } } try { File.Delete(BepInExConfigFilePath); ManualLogSource? logger5 = Logger; if (logger5 != null) { logger5.LogInfo((object)("已删除BepInEx配置文件: " + BepInExConfigFilePath)); } return; } catch (Exception ex) { ManualLogSource? logger6 = Logger; if (logger6 != null) { logger6.LogWarning((object)("删除BepInEx配置文件失败: " + ex.Message)); } return; } } if (!File.Exists(OldConfigFilePath)) { return; } try { string[] array = File.ReadAllLines(OldConfigFilePath); string[] array2 = array; foreach (string text in array2) { if (!string.IsNullOrWhiteSpace(text)) { string[] array3 = text.Split('='); if (array3.Length == 2) { string key = array3[0].Trim(); bool value = array3[1].Trim().Equals("1", StringComparison.OrdinalIgnoreCase); _decorationStates[key] = value; } } } if (_decorationStates.Count <= 0) { return; } ManualLogSource? logger7 = Logger; if (logger7 != null) { logger7.LogInfo((object)$"已从旧文本格式加载配置,包含 {_decorationStates.Count} 个装饰物状态"); } SaveConfigWithoutUpdate(); ManualLogSource? logger8 = Logger; if (logger8 != null) { logger8.LogInfo((object)("已将旧文本格式配置迁移到新的JSON格式: " + NewConfigFilePath)); } if (_outfitStates[1].Count == 0) { _outfitStates[1] = new Dictionary(_decorationStates); SaveOutfitConfig(); ManualLogSource? logger9 = Logger; if (logger9 != null) { logger9.LogInfo((object)"已将单套配置迁移到第1套装备方案"); } } try { File.Delete(OldConfigFilePath); ManualLogSource? logger10 = Logger; if (logger10 != null) { logger10.LogInfo((object)("已删除旧文本配置文件: " + OldConfigFilePath)); } } catch (Exception ex2) { ManualLogSource? logger11 = Logger; if (logger11 != null) { logger11.LogWarning((object)("删除旧文本配置文件失败: " + ex2.Message)); } } } catch (Exception ex3) { ManualLogSource? logger12 = Logger; if (logger12 != null) { logger12.LogError((object)("从旧文本格式加载配置时出错: " + ex3.Message)); } } } catch (Exception ex4) { ManualLogSource? logger13 = Logger; if (logger13 != null) { logger13.LogError((object)("加载配置时出错: " + ex4.Message)); } _decorationStates.Clear(); } } private static void LoadOutfitConfig() { try { InitializeOutfitStates(); if (File.Exists(OutfitConfigFilePath)) { string text = File.ReadAllText(OutfitConfigFilePath); ConfigData configData = JsonConvert.DeserializeObject(text); if (configData != null) { _outfitStates.Clear(); foreach (KeyValuePair> outfitState in configData.OutfitStates) { _outfitStates[outfitState.Key] = new Dictionary(); foreach (KeyValuePair item in outfitState.Value) { _outfitStates[outfitState.Key][item.Key] = item.Value; } } CurrentOutfitIndex = configData.CurrentOutfitIndex; if (CurrentOutfitIndex < 1 || CurrentOutfitIndex > 5) { CurrentOutfitIndex = 1; } return; } } InitializeOutfitStates(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("加载多套装备方案配置时出错: " + ex.Message)); } InitializeOutfitStates(); } } private static bool LoadJsonConfig(string filePath) { //IL_0095: Expected O, but got Unknown try { string text = File.ReadAllText(filePath); Dictionary dictionary = JsonConvert.DeserializeObject>(text); if (dictionary != null) { foreach (KeyValuePair item in dictionary) { _decorationStates[item.Key] = item.Value; } ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)$"已从JSON加载配置,包含 {_decorationStates.Count} 个装饰物状态"); } return true; } } catch (JsonException val) { JsonException val2 = val; ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("解析JSON配置文件时出错: " + ((Exception)(object)val2).Message)); } } catch (Exception ex) { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogError((object)("加载JSON配置文件时出错: " + ex.Message)); } } return false; } public static void SaveConfig() { try { UpdateConfigData(); SaveToFile(); SaveCurrentOutfit(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("保存配置时出错: " + ex.Message)); } } } private static void SaveConfigWithoutUpdate() { try { SaveToFile(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("保存配置时出错: " + ex.Message)); } } } private static void SaveToFile() { try { EnsureModDataDirectoryExists(); string contents = JsonConvert.SerializeObject((object)_decorationStates, (Formatting)1); File.WriteAllText(NewConfigFilePath, contents); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("写入配置文件时出错: " + ex.Message)); } } } private static void SaveOutfitConfig() { try { EnsureModDataDirectoryExists(); ConfigData configData = new ConfigData { OutfitStates = new Dictionary>(), CurrentOutfitIndex = CurrentOutfitIndex }; foreach (KeyValuePair> outfitState in _outfitStates) { configData.OutfitStates[outfitState.Key] = new Dictionary(); foreach (KeyValuePair item in outfitState.Value) { if (item.Key != null) { configData.OutfitStates[outfitState.Key][item.Key] = item.Value; } } } string contents = JsonConvert.SerializeObject((object)configData, (Formatting)1); File.WriteAllText(OutfitConfigFilePath, contents); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("写入多套装备方案配置文件时出错: " + ex.Message)); } } } private static void UpdateConfigData() { _decorationStates.Clear(); foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { _decorationStates[decoration.Name] = decoration.IsVisible; } } public static void ApplySavedStates() { try { int num = 0; foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { if (_decorationStates.TryGetValue(decoration.Name, out var value)) { decoration.IsVisible = value; num++; } } if (num > 0) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)$"已应用 {num} 个已保存的装饰物状态"); } } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("应用已保存的装饰物状态时出错: " + ex.Message)); } } } public static void SwitchOutfit(int outfitIndex) { if (outfitIndex < 1 || outfitIndex > 5) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)$"无效的装备方案索引: {outfitIndex},索引应在1-5之间"); } return; } try { SaveCurrentOutfitState(); CurrentOutfitIndex = outfitIndex; ApplyOutfit(outfitIndex); SaveAllConfigs(); } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("切换装备方案时出错: " + ex.Message)); } } } private static void SaveCurrentOutfitState() { try { if (CurrentOutfitIndex < 1 || CurrentOutfitIndex > 5) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)$"无效的当前装备方案索引: {CurrentOutfitIndex},重置为1"); } CurrentOutfitIndex = 1; } Dictionary dictionary = new Dictionary(); foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { dictionary[decoration.Name] = decoration.IsVisible; } _outfitStates[CurrentOutfitIndex] = dictionary; } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("保存当前装备状态到方案时出错: " + ex.Message)); } } } private static void SaveAllConfigs() { try { UpdateConfigData(); SaveToFile(); SaveOutfitConfig(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("保存所有配置时出错: " + ex.Message)); } } } private static void ApplyOutfit(int outfitIndex) { try { if (outfitIndex < 1 || outfitIndex > 5) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)$"无效的装备方案索引: {outfitIndex},使用默认方案1"); } outfitIndex = 1; } if (!_outfitStates.TryGetValue(outfitIndex, out Dictionary value)) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogWarning((object)$"找不到装备方案 {outfitIndex},使用空方案"); } value = new Dictionary(); } foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { bool flag = false; if (value.TryGetValue(decoration.Name ?? string.Empty, out var value2)) { flag = value2; } if (decoration.IsVisible != flag) { HeadDecorationManager.SetDecorationState(decoration.Name ?? string.Empty, flag); } } CurrentOutfitIndex = outfitIndex; } catch (Exception ex) { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogError((object)$"应用装备方案 {outfitIndex} 时出错: {ex.Message}"); } } } public static void SaveCurrentOutfit() { try { SaveCurrentOutfitState(); SaveOutfitConfig(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("保存当前装备状态到方案时出错: " + ex.Message)); } } } public static int GetCurrentOutfitIndex() { return CurrentOutfitIndex; } } public static class DecorationUtils { private const string HEAD_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side/Player Spring Impulse - Head Bot/_____________________________________/ANIM HEAD TOP/code_head_top"; private const string NECK_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side"; private const string BODY_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/ANIM BODY TOP SCALE"; private const string HIP_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT"; private const string LEFT_ARM_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM L/code_arm_l"; private const string RIGHT_ARM_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM R/code_arm_r_parent/code_arm_r/ANIM ARM R SCALE"; private const string LEFT_LEG_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG L BOT/_____________________________________/ANIM LEG L TOP"; private const string RIGHT_LEG_NODE_PATH = "[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG R BOT/_____________________________________/ANIM LEG R TOP"; public static Dictionary GetDecorationParentNodes(Transform rootTransform) { //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); Transform val = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side/Player Spring Impulse - Head Bot/_____________________________________/ANIM HEAD TOP/code_head_top"); if ((Object)(object)val != (Object)null) { dictionary["head"] = val; } Transform val2 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side"); if ((Object)(object)val2 != (Object)null) { dictionary["neck"] = val2; } Transform val3 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/ANIM BODY TOP SCALE"); if ((Object)(object)val3 != (Object)null) { dictionary["body"] = val3; } Transform val4 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT"); if ((Object)(object)val4 != (Object)null) { dictionary["hip"] = val4; } Transform val5 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM L/code_arm_l"); if ((Object)(object)val5 != (Object)null) { dictionary["leftarm"] = val5; } Transform val6 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM R/code_arm_r_parent/code_arm_r/ANIM ARM R SCALE"); if ((Object)(object)val6 != (Object)null) { dictionary["rightarm"] = val6; } Transform val7 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG L BOT/_____________________________________/ANIM LEG L TOP"); if ((Object)(object)val7 != (Object)null) { dictionary["leftleg"] = val7; } Transform val8 = rootTransform.Find("[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG R BOT/_____________________________________/ANIM LEG R TOP"); if ((Object)(object)val8 != (Object)null) { dictionary["rightleg"] = val8; } if ((Object)(object)rootTransform != (Object)null) { bool flag = false; PlayerAvatar componentInChildren = ((Component)rootTransform.parent).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { flag = !SemiFunc.IsMultiplayer() || ((Object)(object)componentInChildren.photonView != (Object)null && componentInChildren.photonView.IsMine); } Transform val9 = rootTransform.Find("WorldDecorationFollower"); if ((Object)(object)val9 != (Object)null) { if (flag) { ((Component)val9).gameObject.SetActive(false); } else { ((Component)val9).gameObject.SetActive(true); } dictionary["world"] = val9; } else { GameObject val10 = new GameObject("WorldDecorationFollower"); val10.transform.SetParent(rootTransform, false); val10.transform.localPosition = Vector3.zero; val10.transform.localRotation = Quaternion.identity; val10.transform.localScale = Vector3.one; val10.AddComponent(); if (flag) { val10.SetActive(false); } else { val10.SetActive(true); } dictionary["world"] = val10.transform; } } return dictionary; } public static void EnsureDecorationContainers(Dictionary parentNodes) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair parentNode in parentNodes) { Transform value = parentNode.Value; Transform val = value.Find("HeadDecorations"); if ((Object)(object)val == (Object)null) { val = new GameObject("HeadDecorations").transform; val.SetParent(value, false); val.localPosition = Vector3.zero; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; } } } public static void UpdateDecoration(Transform parent, string decorationName, bool showDecoration) { Transform val = parent.Find(decorationName); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf != showDecoration) { ((Component)val).gameObject.SetActive(showDecoration); } } } public class WorldSpaceFollower : MonoBehaviour { private Transform? _rootTransform; private Vector3 _initialOffset; private void Start() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) _rootTransform = ((Component)this).transform.parent; if ((Object)(object)_rootTransform != (Object)null) { _initialOffset = ((Component)this).transform.position - _rootTransform.position; ((Component)this).transform.rotation = Quaternion.identity; ((Component)this).transform.localScale = Vector3.one; } } private void LateUpdate() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rootTransform != (Object)null) { ((Component)this).transform.position = _rootTransform.position + _initialOffset; ((Component)this).transform.rotation = Quaternion.Euler(0f, _rootTransform.eulerAngles.y, 0f); ((Component)this).transform.localScale = Vector3.one; } } } public static class DecorationBlacklistManager { private static HashSet _blacklistedDecorations = new HashSet(); private static readonly string BlacklistFilePath = Path.Combine(Paths.ConfigPath, "MoreHeadBlacklist.json"); private static ManualLogSource? Logger => Morehead.Logger; public static void Initialize() { try { LoadBlacklist(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)$"黑名单管理器初始化完成,已加载 {_blacklistedDecorations.Count} 个黑名单项"); } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("初始化黑名单管理器时出错: " + ex.Message)); } } } public static void LoadBlacklist() { try { if (!File.Exists(BlacklistFilePath)) { SaveBlacklist(); return; } string text = File.ReadAllText(BlacklistFilePath); BlacklistData blacklistData = JsonConvert.DeserializeObject(text); if (blacklistData != null) { _blacklistedDecorations = new HashSet(blacklistData.DecorationNames); } else { _blacklistedDecorations.Clear(); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("加载黑名单时出错: " + ex.Message)); } _blacklistedDecorations.Clear(); } } public static void SaveBlacklist() { try { BlacklistData blacklistData = new BlacklistData { DecorationNames = _blacklistedDecorations.ToList() }; string contents = JsonConvert.SerializeObject((object)blacklistData, (Formatting)1); File.WriteAllText(BlacklistFilePath, contents); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("保存黑名单时出错: " + ex.Message)); } } } public static void AddToBlacklist(string decorationName) { if (!string.IsNullOrEmpty(decorationName) && _blacklistedDecorations.Add(decorationName)) { SaveBlacklist(); } } public static void RemoveFromBlacklist(string decorationName) { if (!string.IsNullOrEmpty(decorationName) && _blacklistedDecorations.Remove(decorationName)) { SaveBlacklist(); } } public static bool IsBlacklisted(string decorationName) { return !string.IsNullOrEmpty(decorationName) && _blacklistedDecorations.Contains(decorationName); } public static List GetBlacklistedDecorations() { return _blacklistedDecorations.ToList(); } public static void ClearBlacklist() { _blacklistedDecorations.Clear(); SaveBlacklist(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"已清空黑名单"); } } } [Serializable] public class BlacklistData { public List DecorationNames { get; set; } = new List(); } public class DecorationInfo { public string? Name { get; set; } public string? DisplayName { get; set; } public bool IsVisible { get; set; } public GameObject? Prefab { get; set; } public string? ParentTag { get; set; } public string? BundlePath { get; set; } public string? ModName { get; set; } } public static class HeadDecorationManager { private static ConfigEntry? _enableVerboseLogging; private static HashSet changedDecorations = new HashSet(); private static Dictionary parentPathMap = new Dictionary { { "head", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side/_____________________________________/ANIM HEAD TOP/code_head_top" }, { "neck", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM HEAD BOT/code_head_bot_up/code_head_bot_side" }, { "body", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/ANIM BODY TOP SCALE" }, { "hip", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT" }, { "leftarm", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM L/code_arm_l" }, { "rightarm", "[RIG]/code_lean/code_tilt/ANIM BOT/_____________________________________/ANIM BODY BOT/_____________________________________/ANIM BODY TOP/code_body_top_up/code_body_top_side/_____________________________________/ANIM ARM R/code_arm_r_parent/code_arm_r/ANIM ARM R SCALE" }, { "leftleg", "[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG L BOT/_____________________________________/ANIM LEG L TOP" }, { "rightleg", "[RIG]/code_lean/code_tilt/ANIM BOT/code_leg_twist/_____________________________________/ANIM LEG R BOT/_____________________________________/ANIM LEG R TOP" }, { "world", "" } }; private static Dictionary> externalDecorations = new Dictionary>(); private static ManualLogSource? Logger => Morehead.Logger; public static List Decorations { get; private set; } = new List(); public static void Initialize() { try { Morehead? instance = Morehead.Instance; _enableVerboseLogging = ((instance != null) ? ((BaseUnityPlugin)instance).Config.Bind("Logging", "EnableVerboseLogging", false, "启用模型加载日志(默认关闭) Enable model loading logs (default: off)") : null); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"正在初始化装饰物管理器..."); } Decorations.Clear(); LoadAllDecorations(); ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)$"装饰物管理器初始化完成,共加载了 {Decorations.Count} 个装饰物"); } } catch (Exception ex) { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogError((object)("初始化装饰物管理器时出错: " + ex.Message)); } } } private static void LoadAllDecorations() { try { Morehead? instance = Morehead.Instance; string directoryName = Path.GetDirectoryName((instance != null) ? ((BaseUnityPlugin)instance).Info.Location : null); if (string.IsNullOrEmpty(directoryName)) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)"无法获取MOD所在目录"); } return; } string text = Path.Combine(directoryName, "Decorations"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)("已创建装饰物目录: " + text)); } } List list = new List(); string[] files = Directory.GetFiles(text, "*.hhh"); list.AddRange(files); try { string pluginPath = Paths.PluginPath; if (!string.IsNullOrEmpty(pluginPath) && Directory.Exists(pluginPath)) { string[] files2 = Directory.GetFiles(pluginPath, "*.hhh", SearchOption.AllDirectories); list.AddRange(files2); } else { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogWarning((object)"无法找到BepInEx/plugins目录,将只加载本地装饰物"); } } } catch (Exception ex) { ManualLogSource? logger4 = Logger; if (logger4 != null) { logger4.LogError((object)("搜索plugins目录时出错: " + ex.Message)); } } list = list.Distinct().ToList(); if (list.Count == 0) { ManualLogSource? logger5 = Logger; if (logger5 != null) { logger5.LogWarning((object)"未找到任何装饰物包文件,请确保.hhh文件已放置"); } } foreach (string item in list) { LoadDecorationBundle(item); } } catch (Exception ex2) { ManualLogSource? logger6 = Logger; if (logger6 != null) { logger6.LogError((object)("加载装饰物时出错: " + ex2.Message)); } } } private static void LoadDecorationBundle(string bundlePath) { AssetBundle val = null; try { if (!File.Exists(bundlePath)) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("文件不存在: " + bundlePath)); } return; } FileInfo fileInfo = new FileInfo(bundlePath); if (fileInfo.Length < 1024) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogWarning((object)$"文件过小,可能不是有效的AssetBundle: {bundlePath}, 大小: {fileInfo.Length} 字节"); } return; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(bundlePath); string parentTag = "head"; string text = fileNameWithoutExtension; if (fileNameWithoutExtension.Contains("_")) { string[] array = fileNameWithoutExtension.Split('_'); if (array.Length >= 2) { string text2 = array[^1].ToLower(); if (parentPathMap.ContainsKey(text2)) { parentTag = text2; text = string.Join("_", array, 0, array.Length - 1); } } } string text3 = EnsureUniqueName(text); if (text3 != text) { ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogWarning((object)("检测到重名,将基础名称从 " + text + " 修改为 " + text3)); } text = text3; } try { val = AssetBundle.LoadFromFile(bundlePath); if ((Object)(object)val == (Object)null) { ManualLogSource? logger4 = Logger; if (logger4 != null) { logger4.LogError((object)("无法加载AssetBundle,文件可能已损坏或不是有效的AssetBundle: " + bundlePath)); } return; } } catch (Exception ex) { ManualLogSource? logger5 = Logger; if (logger5 != null) { logger5.LogError((object)("加载AssetBundle时出错,文件可能不是有效的AssetBundle: " + bundlePath + ", 错误: " + ex.Message)); } return; } try { string[] allAssetNames; try { allAssetNames = val.GetAllAssetNames(); } catch (Exception ex2) { ManualLogSource? logger6 = Logger; if (logger6 != null) { logger6.LogError((object)("获取AssetBundle资源名称时出错: " + bundlePath + ", 错误: " + ex2.Message)); } val.Unload(true); return; } if (allAssetNames.Length == 0) { ManualLogSource? logger7 = Logger; if (logger7 != null) { logger7.LogWarning((object)("AssetBundle不包含任何资源: " + bundlePath)); } val.Unload(true); return; } bool flag = false; GameObject val2 = null; string[] array2 = allAssetNames; foreach (string text4 in array2) { try { val2 = val.LoadAsset(text4); if ((Object)(object)val2 != (Object)null) { flag = true; break; } } catch (Exception ex3) { ManualLogSource? logger8 = Logger; if (logger8 != null) { logger8.LogWarning((object)("加载资源 " + text4 + " 时出错: " + ex3.Message)); } } } if (!flag || (Object)(object)val2 == (Object)null) { ManualLogSource? logger9 = Logger; if (logger9 != null) { logger9.LogWarning((object)("AssetBundle不包含有效的GameObject资源: " + bundlePath)); } val.Unload(true); return; } string text5 = ((Object)val2).name; string text6 = EnsureUniqueDisplayName(text5); if (text6 != text5) { ManualLogSource? logger10 = Logger; if (logger10 != null) { logger10.LogWarning((object)("检测到显示名称重复,将显示名称从 " + text5 + " 修改为 " + text6)); } text5 = text6; } DecorationInfo decorationInfo = new DecorationInfo { Name = text, DisplayName = text5, IsVisible = false, Prefab = val2, ParentTag = parentTag, BundlePath = bundlePath, ModName = GetModNameFromPath(bundlePath) }; if (DecorationBlacklistManager.IsBlacklisted(text5)) { ConfigEntry? enableVerboseLogging = _enableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { ManualLogSource? logger11 = Logger; if (logger11 != null) { logger11.LogWarning((object)("跳过黑名单中的装饰物: " + text5)); } } val.Unload(true); return; } Decorations.Add(decorationInfo); ConfigEntry? enableVerboseLogging2 = _enableVerboseLogging; if (enableVerboseLogging2 != null && enableVerboseLogging2.Value) { ManualLogSource? logger12 = Logger; if (logger12 != null) { logger12.LogInfo((object)("成功加载装饰物: " + decorationInfo.DisplayName + ", 标签: " + decorationInfo.ParentTag)); } } val.Unload(false); } catch (Exception ex4) { ManualLogSource? logger13 = Logger; if (logger13 != null) { logger13.LogError((object)("处理AssetBundle时出错: " + ex4.Message)); } if ((Object)(object)val != (Object)null) { val.Unload(true); } } } catch (Exception ex5) { ManualLogSource? logger14 = Logger; if (logger14 != null) { logger14.LogError((object)("加载装饰物包时出错: " + ex5.Message + ", 路径: " + bundlePath)); } if ((Object)(object)val != (Object)null) { val.Unload(true); } } } private static string EnsureUniqueName(string baseName) { string name = baseName; int num = 1; while (Decorations.Any((DecorationInfo d) => d.Name != null && d.Name.Equals(name, StringComparison.OrdinalIgnoreCase))) { name = $"{baseName}({num})"; num++; } return name; } private static string EnsureUniqueDisplayName(string baseDisplayName) { string displayName = baseDisplayName; int num = 1; while (Decorations.Any((DecorationInfo d) => d.DisplayName != null && d.DisplayName.Equals(displayName, StringComparison.OrdinalIgnoreCase))) { displayName = $"{baseDisplayName}({num})"; num++; } return displayName; } private static string? GetParentTagFromPrefab(GameObject prefab) { string text = ((Object)prefab).name.ToLower(); foreach (string key in parentPathMap.Keys) { if (key != null && text.Contains(key)) { return key; } } return null; } public static bool GetDecorationState(string? name) { string name2 = name; if (string.IsNullOrEmpty(name2)) { return false; } return Decorations.FirstOrDefault((DecorationInfo d) => d.Name == name2)?.IsVisible ?? false; } public static void SetDecorationState(string name, bool isVisible) { string name2 = name; if (!string.IsNullOrEmpty(name2)) { DecorationInfo decorationInfo = Decorations.FirstOrDefault((DecorationInfo d) => d.Name == name2); if (decorationInfo != null && decorationInfo.IsVisible != isVisible) { decorationInfo.IsVisible = isVisible; changedDecorations.Add(name2); } } } public static bool ToggleDecorationState(string? name) { string name2 = name; if (string.IsNullOrEmpty(name2)) { return false; } DecorationInfo decorationInfo = Decorations.FirstOrDefault((DecorationInfo d) => d.Name == name2); if (decorationInfo != null) { decorationInfo.IsVisible = !decorationInfo.IsVisible; changedDecorations.Add(name2); return decorationInfo.IsVisible; } return false; } public static string GetParentPath(string parentTag) { if (parentPathMap.TryGetValue(parentTag.ToLower(), out string value)) { return value; } return parentPathMap["head"]; } public static List GetChangedDecorations() { return changedDecorations.ToList(); } public static void ClearChangedDecorations() { changedDecorations.Clear(); } public static void DisableAllDecorations() { try { foreach (DecorationInfo decoration in Decorations) { if (decoration.IsVisible) { decoration.IsVisible = false; changedDecorations.Add(decoration.Name ?? string.Empty); } } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("禁用所有装饰物时出错: " + ex.Message)); } } } public static bool LoadExternalAssetBundle(byte[] bundleData, string resourceName) { try { string text = Path.Combine(Path.GetTempPath(), resourceName); File.WriteAllBytes(text, bundleData); LoadDecorationBundle(text); try { File.Delete(text); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("清理临时文件失败: " + ex.Message)); } } return true; } catch (Exception ex2) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("加载外部AB包失败: " + ex2.Message)); } return false; } } public static void LoadExternalAssetBundlesFromAssembly(Assembly assembly) { try { int num = 0; string name2 = assembly.GetName().Name; string location = assembly.Location; string fileName = Path.GetFileName(location); if (!externalDecorations.ContainsKey(name2)) { externalDecorations[name2] = new List(); } else { externalDecorations[name2].Clear(); } int count = Decorations.Count; string[] manifestResourceNames = assembly.GetManifestResourceNames(); IEnumerable enumerable = manifestResourceNames.Where((string name) => name.EndsWith(".hhh", StringComparison.OrdinalIgnoreCase)); if (!enumerable.Any()) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("在DLL " + name2 + " 中未找到.hhh资源")); } return; } ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)$"在DLL {name2} 中找到 {enumerable.Count()} 个.hhh资源"); } foreach (string item in enumerable) { try { string text = item.Substring(0, item.Length - 4); string text2 = ((!text.Contains(".")) ? text : text.Split('.').Last()); ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogInfo((object)("处理资源: " + item + ", 提取文件名: " + text2)); } byte[] array; using (Stream stream = assembly.GetManifestResourceStream(item)) { if (stream == null) { continue; } array = new byte[stream.Length]; stream.Read(array, 0, array.Length); goto IL_01bc; } IL_01bc: if (LoadExternalAssetBundle(array, text2 + ".hhh")) { num++; } } catch (Exception ex) { ManualLogSource? logger4 = Logger; if (logger4 != null) { logger4.LogError((object)("加载资源 " + item + " 失败: " + ex.Message)); } } } if (num > 0) { for (int i = count; i < Decorations.Count; i++) { DecorationInfo decorationInfo = Decorations[i]; decorationInfo.ModName = fileName; externalDecorations[name2].Add(decorationInfo); } ManualLogSource? logger5 = Logger; if (logger5 != null) { logger5.LogInfo((object)$"成功从DLL {name2} 加载了 {num} 个资源,已保存到外部装饰物记录中"); } ConfigManager.ApplySavedStates(); } } catch (Exception ex2) { ManualLogSource? logger6 = Logger; if (logger6 != null) { logger6.LogError((object)("从DLL加载资源失败: " + ex2.Message)); } } } public static List GetDecorationsFromAssembly(Assembly assembly) { string name = assembly.GetName().Name; if (externalDecorations.TryGetValue(name, out List value)) { return value; } return new List(); } public static List GetDecorationGameObjectsFromAssembly(Assembly assembly) { List list = new List(); foreach (DecorationInfo item in GetDecorationsFromAssembly(assembly)) { if ((Object)(object)item.Prefab != (Object)null) { list.Add(item.Prefab); } } return list; } public static DecorationInfo GetDecorationByName(Assembly assembly, string decorationName) { string decorationName2 = decorationName; List decorationsFromAssembly = GetDecorationsFromAssembly(assembly); return decorationsFromAssembly.FirstOrDefault((DecorationInfo d) => (d.Name != null && d.Name.Equals(decorationName2, StringComparison.OrdinalIgnoreCase)) || (d.DisplayName != null && d.DisplayName.Equals(decorationName2, StringComparison.OrdinalIgnoreCase))); } public static List FindDecorationsByPartialName(Assembly assembly, string partialName) { string partialName2 = partialName; if (string.IsNullOrEmpty(partialName2)) { return new List(); } List decorationsFromAssembly = GetDecorationsFromAssembly(assembly); return decorationsFromAssembly.Where((DecorationInfo d) => (d.Name != null && d.Name.IndexOf(partialName2, StringComparison.OrdinalIgnoreCase) >= 0) || (d.DisplayName != null && d.DisplayName.IndexOf(partialName2, StringComparison.OrdinalIgnoreCase) >= 0)).ToList(); } public static void RecreateUI() { try { MoreHeadUI.RecreateUI(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("重新创建UI时出错: " + ex.Message)); } } } private static string? GetModNameFromPath(string? bundlePath) { try { if (string.IsNullOrEmpty(bundlePath)) { return null; } string pluginPath = Paths.PluginPath; if (string.IsNullOrEmpty(pluginPath) || !Directory.Exists(pluginPath)) { return null; } if (!bundlePath.StartsWith(pluginPath, StringComparison.OrdinalIgnoreCase)) { return null; } string directoryName = Path.GetDirectoryName(bundlePath); if (string.IsNullOrEmpty(directoryName)) { return null; } string text = directoryName; while (!string.IsNullOrEmpty(text)) { DirectoryInfo? parent = Directory.GetParent(text); if (parent == null || parent.FullName.Equals(pluginPath, StringComparison.OrdinalIgnoreCase)) { break; } text = Directory.GetParent(text)?.FullName ?? string.Empty; } if (string.IsNullOrEmpty(text)) { return null; } string fileName = Path.GetFileName(text); string[] array = fileName.Split('-'); if (array.Length <= 1) { return fileName; } string text2 = array[^1]; bool flag = IsLikelyVersionNumber(text2); if (flag && array.Length > 2) { return array[^2]; } if (flag) { return array[0]; } return text2; } catch (Exception ex) { ManualLogSource? logger = Morehead.Logger; if (logger != null) { logger.LogError((object)("获取模组名称时出错: " + ex.Message)); } return null; } } private static bool IsLikelyVersionNumber(string text) { if (text.Length == 0 || !char.IsDigit(text[0])) { return false; } bool flag = false; bool flag2 = false; foreach (char c in text) { if (char.IsDigit(c)) { flag = true; } else if (c == '.' || c == '_' || c == '-') { flag2 = true; } } return flag && flag2; } } public static class MoreHeadUI { private class ShortcutKeyListener : MonoBehaviour { public static ShortcutKeyListener? Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) for (int i = 1; i <= 5; i++) { KeyCode val = (KeyCode)(282 + (i - 1)); if (Input.GetKeyDown(val)) { SwitchOutfitWithShortcut(i); } } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static BuilderDelegate <>9__26_0; public static BuilderDelegate <>9__26_1; public static Func <>9__27_0; public static Action <>9__31_1; public static BuilderDelegate <>9__31_0; public static BuilderDelegate <>9__46_0; public static Func <>9__50_0; public static Func <>9__50_1; public static Func <>9__51_0; public static Func <>9__51_1; public static Func <>9__51_2; public static BuilderDelegate <>9__53_0; public static BuilderDelegate <>9__53_1; internal void b__26_0(Transform parent) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(escButtonPosX?.Value ?? 0f, escButtonPosY?.Value ?? 0f); MenuAPI.CreateREPOButton("MOREHEAD", (Action)OnMenuButtonClick, parent, val); } internal void b__26_1(Transform parent) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(lobbyButtonPosX?.Value ?? 0f, lobbyButtonPosY?.Value ?? 0f); MenuAPI.CreateREPOButton("MOREHEAD", (Action)OnMenuButtonClick, parent, val); } internal bool b__27_0(DecorationInfo decoration) { return LIMB_TAGS.Contains(decoration.ParentTag?.ToUpper()); } internal void b__31_0(Transform parent) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) string text = null; try { if (SteamClient.IsValid) { text = SteamUtils.SteamUILanguage; } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("获取Steam语言时出错(将使用默认英文): " + ex.Message)); } } string text2 = "v" + Morehead.GetPluginVersion() + ""; string text3 = ((text != null && text.ToLower().StartsWith("schinese")) ? ("马赛克了和尤里的猫共同制作。 " + text2) : ((text == null || !text.ToLower().StartsWith("tchinese")) ? ("Masaicker and Yuriscat co-developed. " + text2) : ("馬賽克了和尤里的貓共同製作。 " + text2))); MenuAPI.CreateREPOButton(text3, (Action)delegate { }, parent, new Vector2(300f, 329f)); } internal void b__31_1() { } internal void b__46_0(Transform parent) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) avatarPreview = MenuAPI.CreateREPOAvatarPreview(parent, new Vector2(420f, 10f), false, (Color?)null); } internal string b__50_0(DecorationInfo decoration) { return $"{decoration.Name}{'\u001f'}{decoration.DisplayName}{'\u001f'}{decoration.ParentTag}{'\u001f'}{IsBuiltInDecoration(decoration)}{'\u001f'}{decoration.IsVisible}"; } internal string b__50_1(string value) { return value; } internal bool b__51_0(DecorationInfo decoration) { return decoration.IsVisible; } internal int b__51_1(DecorationInfo decoration) { return (!IsBuiltInDecoration(decoration)) ? 1 : 0; } internal string b__51_2(DecorationInfo decoration) { return decoration.DisplayName; } internal void b__53_0(Transform parent) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("CLOSE", (Action)OnCloseButtonClick, parent, new Vector2(301f, 0f)); } internal void b__53_1(Transform parent) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("CLEAR ALL", (Action)OnDisableAllButtonClick, parent, new Vector2(401f, 0f)); } } [CompilerGenerated] private sealed class d__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private Exception 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { if ((Object)(object)decorationsPage != (Object)null && decorationOrderStateKey != GetDecorationOrderStateKey()) { RecreateUI(); } if ((Object)(object)decorationsPage == (Object)null) { decorationsPage = MenuAPI.CreateREPOPopupPage(PAGE_TITLE, true, true, 0f, (Vector2?)new Vector2(-299f, 10f)); SetupPopupPage(decorationsPage); CreateAllDecorationButtons(decorationsPage); CreateTagFilterButtons(decorationsPage); CreateSearchInputField(decorationsPage); AddAuthorCredit(decorationsPage); AddActionButtons(decorationsPage); } decorationsPage.OpenPage(false); MonoBehaviour obj = Object.FindObjectOfType(); if (obj != null) { obj.StartCoroutine(DelayedShowTagDecorations(currentTagFilter)); } UpdateAvatarPreview(); UpdateButtonStates(); } catch (Exception ex) { 5__1 = ex; ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("延迟打开设置页面时出错: " + 5__1.Message)); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__55 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string tag; private Exception 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__55(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { ShowTagDecorations(tag); } catch (Exception ex) { 5__1 = ex; ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("延迟显示标签装饰物时出错: " + 5__1.Message)); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static ConfigEntry? _blacklistModeKey; public static REPOPopupPage? decorationsPage; public static Dictionary decorationButtons = new Dictionary(); public static Dictionary buttonMarkers = new Dictionary(); private static Dictionary> tagScrollViewElements = new Dictionary>(); private static string currentTagFilter = "ALL"; private static Dictionary tagFilterButtons = new Dictionary(); private static string currentSearchQuery = ""; private static REPOInputField? searchInputField; private static string decorationOrderStateKey = ""; private static Dictionary> decorationDataCache = new Dictionary>(); private static Dictionary> buttonTextCache = new Dictionary>(); private static REPOAvatarPreview? avatarPreview; private static ConfigEntry? lobbyButtonPosX; private static ConfigEntry? lobbyButtonPosY; private static ConfigEntry? escButtonPosX; private static ConfigEntry? escButtonPosY; private const string BUTTON_NAME = "MOREHEAD"; private const char DecorationOrderStateSeparator = '\u001f'; private static readonly string PAGE_TITLE = "Rotate robot: A/D"; private static readonly string[] ALL_TAGS = new string[7] { "ALL", "HEAD", "NECK", "BODY", "HIP", "LIMBS", "WORLD" }; private static readonly string[] FULL_TAGS = new string[10] { "ALL", "HEAD", "NECK", "BODY", "HIP", "LEFTARM", "RIGHTARM", "LEFTLEG", "RIGHTLEG", "WORLD" }; private static readonly string[] LIMB_TAGS = new string[4] { "LEFTARM", "RIGHTARM", "LEFTLEG", "RIGHTLEG" }; private static Dictionary outfitButtons = new Dictionary(); private static ManualLogSource? Logger => Morehead.Logger; public static void Initialize() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown try { Morehead? instance = Morehead.Instance; _blacklistModeKey = ((instance != null) ? ((BaseUnityPlugin)instance).Config.Bind("Blacklist", "BlacklistMode", "", "黑名单模式:设置为 \"ENABLE_BLACKLIST\"(不含引号)以启用。\n启用后可通过 Shift + 点击装饰物按钮 添加/移除 黑名单项目。\n使用 Shift + CLEAR ALL 可一次性清空所有黑名单条目。\n⚠\ufe0f 所有黑名单相关操作需重启游戏后才会生效。\n\nBlacklist mode: set to \"ENABLE_BLACKLIST\" to enable.\nWhen enabled, use Shift + click on decoration buttons to add/remove items from the blacklist.\nUse Shift + CLEAR ALL to clear the entire blacklist at once.\n⚠\ufe0f All blacklist changes take effect after restarting the game.") : null); Morehead? instance2 = Morehead.Instance; escButtonPosX = ((instance2 != null) ? ((BaseUnityPlugin)instance2).Config.Bind("UI", "EscButtonPosX", 0f, new ConfigDescription("ESC menu button X position", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 618f), Array.Empty())) : null); Morehead? instance3 = Morehead.Instance; escButtonPosY = ((instance3 != null) ? ((BaseUnityPlugin)instance3).Config.Bind("UI", "EscButtonPosY", 0f, new ConfigDescription("ESC menu button Y position", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 360f), Array.Empty())) : null); Morehead? instance4 = Morehead.Instance; lobbyButtonPosX = ((instance4 != null) ? ((BaseUnityPlugin)instance4).Config.Bind("UI", "LobbyButtonPosX", 0f, new ConfigDescription("Lobby button X position", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 618f), Array.Empty())) : null); Morehead? instance5 = Morehead.Instance; lobbyButtonPosY = ((instance5 != null) ? ((BaseUnityPlugin)instance5).Config.Bind("UI", "LobbyButtonPosY", 0f, new ConfigDescription("Lobby button Y position", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 360f), Array.Empty())) : null); object obj = <>c.<>9__26_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(escButtonPosX?.Value ?? 0f, escButtonPosY?.Value ?? 0f); MenuAPI.CreateREPOButton("MOREHEAD", (Action)OnMenuButtonClick, parent, val4); }; <>c.<>9__26_0 = val; obj = (object)val; } MenuAPI.AddElementToEscapeMenu((BuilderDelegate)obj); object obj2 = <>c.<>9__26_1; if (obj2 == null) { BuilderDelegate val2 = delegate(Transform parent) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(lobbyButtonPosX?.Value ?? 0f, lobbyButtonPosY?.Value ?? 0f); MenuAPI.CreateREPOButton("MOREHEAD", (Action)OnMenuButtonClick, parent, val3); }; <>c.<>9__26_1 = val2; obj2 = (object)val2; } MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj2); InitializeDataCache(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"MoreHead UI已初始化"); } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("初始化UI时出错: " + ex.Message)); } } } private static void InitializeDataCache() { try { decorationDataCache.Clear(); buttonTextCache.Clear(); string[] aLL_TAGS = ALL_TAGS; foreach (string tag in aLL_TAGS) { List list = ((!(tag == "LIMBS")) ? HeadDecorationManager.Decorations.Where((DecorationInfo decoration) => tag == "ALL" || decoration.ParentTag?.ToUpper() == tag).ToList() : HeadDecorationManager.Decorations.Where((DecorationInfo decoration) => LIMB_TAGS.Contains(decoration.ParentTag?.ToUpper())).ToList()); decorationDataCache[tag] = list; buttonTextCache[tag] = new Dictionary(); foreach (DecorationInfo item in list) { string buttonText = GetButtonText(item, item.IsVisible); buttonTextCache[tag][item.Name ?? string.Empty] = buttonText; } } ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"数据缓存初始化完成"); } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("初始化数据缓存时出错: " + ex.Message)); } } } private static void OnMenuButtonClick() { try { if ((Object)(object)MenuPageEsc.instance != (Object)null) { MenuPageEsc.instance.ButtonEventContinue(); } MonoBehaviour obj = Object.FindObjectOfType(); if (obj != null) { obj.StartCoroutine(DelayedOpenMoreHeadUI()); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("打开设置页面时出错: " + ex.Message)); } } } [IteratorStateMachine(typeof(d__29))] private static IEnumerator DelayedOpenMoreHeadUI() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0); } private static void SetupPopupPage(REPOPopupPage page) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)((Component)page).gameObject != (Object)null) { ((Object)((Component)page).gameObject).name = "MoreHead_Page"; } page.pageDimmerVisibility = true; page.maskPadding = new Padding(10f, 20f, 10f, 10f); ((Transform)((TMP_Text)page.headerTMP).rectTransform).position = new Vector3(170f, 344f, 0f); page.pageDimmerOpacity = 0.85f; page.scrollView.scrollSpeed = 4f; } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("设置弹出页面属性时出错: " + ex.Message)); } } } private static void AddAuthorCredit(REPOPopupPage page) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { object obj = <>c.<>9__31_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) string text = null; try { if (SteamClient.IsValid) { text = SteamUtils.SteamUILanguage; } } catch (Exception ex2) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogWarning((object)("获取Steam语言时出错(将使用默认英文): " + ex2.Message)); } } string text2 = "v" + Morehead.GetPluginVersion() + ""; string text3 = ((text != null && text.ToLower().StartsWith("schinese")) ? ("马赛克了和尤里的猫共同制作。 " + text2) : ((text == null || !text.ToLower().StartsWith("tchinese")) ? ("Masaicker and Yuriscat co-developed. " + text2) : ("馬賽克了和尤里的貓共同製作。 " + text2))); MenuAPI.CreateREPOButton(text3, (Action)delegate { }, parent, new Vector2(300f, 329f)); }; <>c.<>9__31_0 = val; obj = (object)val; } page.AddElement((BuilderDelegate)obj); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("添加作者标记时出错: " + ex.Message)); } } } private static bool IsBuiltInDecoration(DecorationInfo decoration) { string bundlePath = decoration.BundlePath; if (string.IsNullOrEmpty(bundlePath)) { return false; } Morehead? instance = Morehead.Instance; string directoryName = Path.GetDirectoryName((instance != null) ? ((BaseUnityPlugin)instance).Info.Location : null); if (string.IsNullOrEmpty(directoryName)) { return false; } string value = Path.Combine(directoryName, "Decorations"); return bundlePath.StartsWith(value); } private static void CreateTagFilterButtons(REPOPopupPage? page) { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown try { tagFilterButtons.Clear(); CreateOutfitButtons(page); for (int i = 0; i < ALL_TAGS.Length; i++) { string text = ALL_TAGS[i]; string text2 = text.ToLower(); int num = i; if (1 == 0) { } string text3 = text2 switch { "head" => "#00AAFF", "neck" => "#AA00FF", "body" => "#FFAA00", "hip" => "#FF00AA", "limbs" => "#AACCAA", "world" => "#00FFAA", _ => "#FFFFFF", }; if (1 == 0) { } string text4 = text3; string buttonText = ((text2 == currentTagFilter.ToLower()) ? ("" + text + "") : ("" + text + "")); string tagForCallback = ((text2 == "all") ? "ALL" : text); int xPosition = 50 + i * 35; if (page == null) { continue; } page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) REPOButton value = MenuAPI.CreateREPOButton(buttonText, (Action)delegate { OnTagFilterButtonClick(tagForCallback); }, parent, new Vector2((float)xPosition, 20f)); tagFilterButtons[tagForCallback] = value; }); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("创建标签筛选按钮时出错: " + ex.Message)); } } } private static void CreateSearchInputField(REPOPopupPage? page) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown try { string text = null; try { if (SteamClient.IsValid) { text = SteamUtils.SteamUILanguage; } } catch { } string labelText; string placeholderText; if (text != null && text.ToLower().StartsWith("schinese")) { labelText = "搜索"; placeholderText = "输入..."; } else if (text != null && text.ToLower().StartsWith("tchinese")) { labelText = "搜尋"; placeholderText = "輸入..."; } else { labelText = "SEARCH"; placeholderText = "Type to filter..."; } if (page != null) { page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) searchInputField = MenuAPI.CreateREPOInputField(labelText, (Action)OnSearchValueChanged, parent, new Vector2(50f, 295f), false, placeholderText, ""); }); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("创建搜索框时出错: " + ex.Message)); } } } private static void OnSearchValueChanged(string? searchQuery) { currentSearchQuery = searchQuery ?? ""; UpdateDecorationVisibility(); } private static void UpdateDecorationVisibility() { if ((Object)(object)decorationsPage == (Object)null || string.IsNullOrEmpty(currentTagFilter) || !tagScrollViewElements.TryGetValue(currentTagFilter, out List value) || !decorationDataCache.TryGetValue(currentTagFilter, out List value2)) { return; } foreach (KeyValuePair> tagScrollViewElement in tagScrollViewElements) { foreach (REPOScrollViewElement item in tagScrollViewElement.Value) { if (item != null) { item.visibility = false; } } } if (string.IsNullOrEmpty(currentSearchQuery)) { foreach (REPOScrollViewElement item2 in value) { if (item2 != null) { item2.visibility = true; } } } else { string value3 = currentSearchQuery.Replace(" ", "").ToLowerInvariant(); foreach (DecorationInfo item3 in value2) { if (decorationButtons.TryGetValue(item3.Name ?? string.Empty, out REPOButton value4) && (Object)(object)value4 != (Object)null && value.Contains(((REPOElement)value4).repoScrollViewElement)) { string text = item3.DisplayName?.Replace(" ", "").ToLowerInvariant() ?? ""; ((REPOElement)value4).repoScrollViewElement.visibility = text.Contains(value3); } } } decorationsPage.scrollView.SetScrollPosition(0f); decorationsPage.scrollView.UpdateElements(); } private static void OnTagFilterButtonClick(string tag) { try { if (tag == currentTagFilter) { REPOPopupPage? obj = decorationsPage; if (obj != null) { obj.scrollView.SetScrollPosition(0f); } } else { ShowTagDecorations(tag); UpdateTagButtonHighlights(); UpdateButtonStates(); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("切换标签筛选时出错: " + ex.Message)); } } } private static void UpdateButtonStates() { try { if (decorationButtons.Count == 0) { return; } if (decorationDataCache.TryGetValue(currentTagFilter, out List value)) { foreach (DecorationInfo item in value) { if (!decorationButtons.TryGetValue(item.Name ?? string.Empty, out REPOButton value2)) { continue; } if (buttonTextCache.TryGetValue(currentTagFilter, out Dictionary value3) && value3.TryGetValue(item.Name ?? string.Empty, out var value4)) { value4 = GetButtonText(item, item.IsVisible); value3[item.Name ?? string.Empty] = value4; } else { value4 = GetButtonText(item, item.IsVisible); if (buttonTextCache.TryGetValue(currentTagFilter, out value3)) { value3[item.Name ?? string.Empty] = value4; } } ((TMP_Text)value2.labelTMP).text = value4; } } UpdateTagButtonHighlights(); UpdateOutfitButtonHighlights(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("更新按钮状态时出错: " + ex.Message)); } } } private static void UpdateTagButtonHighlights() { try { string[] aLL_TAGS = ALL_TAGS; foreach (string text in aLL_TAGS) { string text2 = ((text == "ALL") ? "ALL" : text); if (tagFilterButtons.TryGetValue(text2, out REPOButton value)) { string text3 = text.ToLower(); if (1 == 0) { } string text4 = text3 switch { "head" => "#00AAFF", "neck" => "#AA00FF", "body" => "#FFAA00", "hip" => "#FF00AA", "limbs" => "#AACCAA", "world" => "#00FFAA", _ => "#FFFFFF", }; if (1 == 0) { } string text5 = text4; string text6 = ((text2 == currentTagFilter) ? ("" + text + "") : ("" + text + "")); ((TMP_Text)value.labelTMP).text = text6; } } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("更新标签按钮高亮状态时出错: " + ex.Message)); } } } private static void OnDecorationButtonClick(string? decorationName) { string decorationName2 = decorationName; try { DecorationInfo decorationInfo = HeadDecorationManager.Decorations.FirstOrDefault((DecorationInfo d) => d.Name != null && d.Name.Equals(decorationName2, StringComparison.OrdinalIgnoreCase)); if (decorationInfo == null) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("OnDecorationButtonClick: 找不到装饰物: " + decorationName2)); } return; } string text = _blacklistModeKey?.Value ?? string.Empty; bool flag = text == "ENABLE_BLACKLIST"; bool flag2 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (flag && flag2) { string decorationName3 = decorationInfo.DisplayName ?? string.Empty; if (DecorationBlacklistManager.IsBlacklisted(decorationName3)) { DecorationBlacklistManager.RemoveFromBlacklist(decorationName3); } else { DecorationBlacklistManager.AddToBlacklist(decorationName3); } UpdateButtonStates(); return; } bool isEnabled = HeadDecorationManager.ToggleDecorationState(decorationName2); string buttonText = GetButtonText(decorationInfo, isEnabled); string[] aLL_TAGS = ALL_TAGS; foreach (string text2 in aLL_TAGS) { bool flag3 = false; if (text2 == "ALL") { flag3 = true; } else if (text2 == "LIMBS" && LIMB_TAGS.Contains(decorationInfo.ParentTag?.ToUpper())) { flag3 = true; } else if (decorationInfo.ParentTag?.ToUpper() == text2) { flag3 = true; } if (flag3 && buttonTextCache.TryGetValue(text2, out Dictionary value)) { value[decorationName2 ?? string.Empty] = buttonText; } } if (decorationButtons.TryGetValue(decorationName2 ?? string.Empty, out REPOButton value2)) { ((TMP_Text)value2.labelTMP).text = buttonText; if (buttonMarkers.TryGetValue(decorationName2 ?? string.Empty, out DecorationButtonMarker value3) && value3?.Decoration != null && !string.IsNullOrEmpty(value3.Decoration.ModName) && !((TMP_Text)value2.labelTMP).text.Contains(value3.Decoration.ModName)) { ((TMP_Text)value2.labelTMP).text = ((TMP_Text)value2.labelTMP).text + " - " + value3.Decoration.ModName + ""; } } UpdateDecorations(); ConfigManager.SaveConfig(); } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("切换装饰物 " + decorationName2 + " 状态时出错: " + ex.Message)); } } } private static string GetButtonText(DecorationInfo decoration, bool isEnabled) { string text = decoration.DisplayName?.ToUpper() ?? "UNKNOWN"; string text2 = decoration.ParentTag ?? "unknown"; string text3 = text2.ToLower(); if (1 == 0) { } string text4 = text3 switch { "head" => "#00AAFF", "neck" => "#AA00FF", "body" => "#FFAA00", "hip" => "#FF00AA", "leftarm" => "#88CC88", "rightarm" => "#88CC88", "leftleg" => "#88BBEE", "rightleg" => "#88BBEE", "world" => "#00FFAA", _ => "#AAAAAA", }; if (1 == 0) { } string text5 = text4; string text6 = ""; if (LIMB_TAGS.Contains(text2.ToUpper())) { string text7 = text2.ToLower(); if (1 == 0) { } text4 = text7 switch { "leftarm" => "L-ARM", "rightarm" => "R-ARM", "leftleg" => "L-LEG", "rightleg" => "R-LEG", _ => text2, }; if (1 == 0) { } string text8 = text4; text6 = "(" + text8 + ") "; } else { text6 = "(" + text2 + ") "; } string text9 = _blacklistModeKey?.Value ?? string.Empty; if (text9 == "ENABLE_BLACKLIST" && DecorationBlacklistManager.IsBlacklisted(decoration.DisplayName ?? string.Empty)) { string text10 = "#888888"; text6 = "(" + text2 + ") "; return "" + (isEnabled ? "[+]" : "[-]") + " " + text6 + "" + text + ""; } return "" + (isEnabled ? "[+]" : "[-]") + " " + text6 + text + ""; } private static void OnCloseButtonClick() { try { REPOPopupPage? obj = decorationsPage; if (obj != null) { obj.ClosePage(true); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("关闭页面时出错: " + ex.Message)); } } } private static void UpdateDecorations() { try { PlayerAvatar val = FindLocalPlayer(); if ((Object)(object)val != (Object)null) { PlayerUpdatePatch.UpdatePlayerDecorations(val); HeadDecorationSync component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { component.SyncChangedDecorations(); } } PlayerUpdatePatch.UpdateMenuPlayerDecorations(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("更新装饰物状态时出错: " + ex.Message)); } } } private static PlayerAvatar? FindLocalPlayer() { try { PlayerAvatar[] array = Object.FindObjectsOfType(); PlayerAvatar[] array2 = array; foreach (PlayerAvatar val in array2) { if ((Object)(object)val?.photonView != (Object)null && val.photonView.IsMine) { return val; } } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("查找本地玩家时出错: " + ex.Message)); } } return null; } private static void UpdateAvatarPreview() { try { if (!((Object)(object)decorationsPage == (Object)null)) { if ((Object)(object)avatarPreview != (Object)null) { SafeDestroyAvatar(); } CreateAvatarPreview(decorationsPage); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("更新头像预览时出错: " + ex.Message)); } } } private static void CreateAvatarPreview(REPOPopupPage page) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { object obj = <>c.<>9__46_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) avatarPreview = MenuAPI.CreateREPOAvatarPreview(parent, new Vector2(420f, 10f), false, (Color?)null); }; <>c.<>9__46_0 = val; obj = (object)val; } page.AddElement((BuilderDelegate)obj); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("创建头像预览时出错: " + ex.Message)); } } } public static void SafeDestroyAvatar() { try { if ((Object)(object)avatarPreview != (Object)null) { if ((Object)(object)((Component)avatarPreview).transform != (Object)null && (Object)(object)((Component)avatarPreview).transform.parent != (Object)null) { ((Component)avatarPreview).transform.SetParent((Transform)null, false); } PlayerAvatarVisuals playerAvatarVisuals = avatarPreview.playerAvatarVisuals; if ((Object)(object)playerAvatarVisuals != (Object)null) { } if ((Object)(object)((Component)avatarPreview).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)avatarPreview).gameObject); } avatarPreview = null; } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)("安全销毁头像预览时出错,但这不影响功能: " + ex.Message)); } avatarPreview = null; } } private static void OnDisableAllButtonClick() { try { string text = _blacklistModeKey?.Value ?? string.Empty; bool flag = text == "ENABLE_BLACKLIST"; bool flag2 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (flag && flag2) { DecorationBlacklistManager.ClearBlacklist(); UpdateButtonStates(); return; } HeadDecorationManager.DisableAllDecorations(); string[] aLL_TAGS = ALL_TAGS; foreach (string text2 in aLL_TAGS) { if (!buttonTextCache.TryGetValue(text2, out Dictionary value)) { continue; } foreach (DecorationInfo decoration in HeadDecorationManager.Decorations) { bool flag3 = false; if (text2 == "ALL") { flag3 = true; } else if (text2 == "LIMBS" && LIMB_TAGS.Contains(decoration.ParentTag?.ToUpper())) { flag3 = true; } else if (decoration.ParentTag?.ToUpper() == text2) { flag3 = true; } if (flag3) { string buttonText = GetButtonText(decoration, isEnabled: false); value[decoration.Name ?? string.Empty] = buttonText; } } } foreach (DecorationInfo decoration2 in HeadDecorationManager.Decorations) { if (decorationButtons.TryGetValue(decoration2.Name ?? string.Empty, out REPOButton value2)) { ((TMP_Text)value2.labelTMP).text = GetButtonText(decoration2, isEnabled: false); } } UpdateDecorations(); ConfigManager.SaveConfig(); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("关闭所有装饰物时出错: " + ex.Message)); } } } public static void RecreateUI() { try { decorationDataCache.Clear(); buttonTextCache.Clear(); decorationButtons.Clear(); buttonMarkers.Clear(); tagScrollViewElements.Clear(); tagFilterButtons.Clear(); outfitButtons.Clear(); currentSearchQuery = ""; searchInputField = null; if ((Object)(object)decorationsPage != (Object)null && (Object)(object)((Component)decorationsPage).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)decorationsPage).gameObject); decorationsPage = null; } SafeDestroyAvatar(); InitializeDataCache(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"UI已重新初始化,缓存已重置"); } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("重新创建UI时出错: " + ex.Message)); } } } private static string GetDecorationOrderStateKey() { return string.Join('\u001f'.ToString(), from decoration in HeadDecorationManager.Decorations select $"{decoration.Name}{'\u001f'}{decoration.DisplayName}{'\u001f'}{decoration.ParentTag}{'\u001f'}{IsBuiltInDecoration(decoration)}{'\u001f'}{decoration.IsVisible}" into value orderby value select value); } private static void CreateAllDecorationButtons(REPOPopupPage page) { try { decorationButtons.Clear(); buttonMarkers.Clear(); tagScrollViewElements.Clear(); string[] aLL_TAGS = ALL_TAGS; foreach (string key in aLL_TAGS) { tagScrollViewElements[key] = new List(); } List list = (from decoration in HeadDecorationManager.Decorations orderby decoration.IsVisible descending, (!IsBuiltInDecoration(decoration)) ? 1 : 0, decoration.DisplayName select decoration).ToList(); foreach (DecorationInfo item in list) { CreateDecorationButton(page, item); } decorationOrderStateKey = GetDecorationOrderStateKey(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)$"创建了所有装饰物按钮,总共 {decorationButtons.Count} 个"); } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("创建装饰物按钮时出错: " + ex.Message)); } } } private static void CreateDecorationButton(REPOPopupPage page, DecorationInfo decoration) { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown DecorationInfo decoration2 = decoration; try { string decorationName = decoration2.Name; string parentTag = decoration2.ParentTag; if (string.IsNullOrEmpty(decorationName) || string.IsNullOrEmpty(parentTag)) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)"跳过创建按钮:装饰物名称或标签为空"); } return; } string buttonText = GetButtonText(decoration2, decoration2.IsVisible); string[] aLL_TAGS = ALL_TAGS; foreach (string text in aLL_TAGS) { bool flag = false; if (text == "ALL") { flag = true; } else if (text == "LIMBS" && LIMB_TAGS.Contains(parentTag.ToUpper())) { flag = true; } else if (parentTag.ToUpper() == text) { flag = true; } if (flag) { if (!buttonTextCache.TryGetValue(text, out Dictionary value)) { buttonTextCache[text] = new Dictionary(); value = buttonTextCache[text]; } value[decorationName] = buttonText; } } REPOButton repoButton = null; page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform scrollView) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) repoButton = MenuAPI.CreateREPOButton(buttonText, (Action)delegate { OnDecorationButtonClick(decorationName); }, scrollView, default(Vector2)); DecorationButtonMarker decorationButtonMarker = ((Component)repoButton).gameObject.AddComponent(); decorationButtonMarker.Decoration = decoration2; buttonMarkers[decorationName] = decorationButtonMarker; return ((REPOElement)repoButton).rectTransform; }, 0f, 0f); if ((Object)(object)repoButton != (Object)null) { decorationButtons[decorationName] = repoButton; ((REPOElement)repoButton).repoScrollViewElement.visibility = false; tagScrollViewElements["ALL"].Add(((REPOElement)repoButton).repoScrollViewElement); List value2; if (LIMB_TAGS.Contains(parentTag.ToUpper())) { tagScrollViewElements["LIMBS"].Add(((REPOElement)repoButton).repoScrollViewElement); } else if (tagScrollViewElements.TryGetValue(parentTag.ToUpper(), out value2)) { value2.Add(((REPOElement)repoButton).repoScrollViewElement); } } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("创建装饰物按钮时出错: " + ex.Message)); } } } private static void AddActionButtons(REPOPopupPage page) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown try { object obj = <>c.<>9__53_0; if (obj == null) { BuilderDelegate val = delegate(Transform parent) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("CLOSE", (Action)OnCloseButtonClick, parent, new Vector2(301f, 0f)); }; <>c.<>9__53_0 = val; obj = (object)val; } page.AddElement((BuilderDelegate)obj); object obj2 = <>c.<>9__53_1; if (obj2 == null) { BuilderDelegate val2 = delegate(Transform parent) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) MenuAPI.CreateREPOButton("CLEAR ALL", (Action)OnDisableAllButtonClick, parent, new Vector2(401f, 0f)); }; <>c.<>9__53_1 = val2; obj2 = (object)val2; } page.AddElement((BuilderDelegate)obj2); } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("创建操作按钮时出错: " + ex.Message)); } } } private static void ShowTagDecorations(string tag) { try { if (!((Object)(object)decorationsPage == (Object)null)) { currentTagFilter = tag; UpdateDecorationVisibility(); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("显示标签 " + tag + " 的装饰物时出错: " + ex.Message)); } } } [IteratorStateMachine(typeof(d__55))] private static IEnumerator DelayedShowTagDecorations(string tag) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__55(0) { tag = tag }; } private static void CreateOutfitButtons(REPOPopupPage? page) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown try { outfitButtons.Clear(); int currentOutfitIndex = ConfigManager.GetCurrentOutfitIndex(); for (int i = 1; i <= 5; i++) { int outfitIndex = i; string arg = $"[F{outfitIndex}]"; string buttonText = ((outfitIndex == currentOutfitIndex) ? $"{outfitIndex} {arg}" : $"{outfitIndex} {arg}"); int yPosition = 260 - (i - 1) * 25; if (page == null) { continue; } page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) REPOButton value = MenuAPI.CreateREPOButton(buttonText, (Action)delegate { OnOutfitButtonClick(outfitIndex); }, parent, new Vector2(640f, (float)yPosition)); outfitButtons[outfitIndex] = value; }); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("创建装备方案按钮时出错: " + ex.Message)); } } } private static void OnOutfitButtonClick(int outfitIndex) { try { int currentOutfitIndex = ConfigManager.GetCurrentOutfitIndex(); if (outfitIndex != currentOutfitIndex) { ConfigManager.SwitchOutfit(outfitIndex); UpdateOutfitButtonHighlights(); UpdateDecorations(); UpdateButtonStates(); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("切换装备方案时出错: " + ex.Message)); } } } private static void UpdateOutfitButtonHighlights() { try { int currentOutfitIndex = ConfigManager.GetCurrentOutfitIndex(); for (int i = 1; i <= 5; i++) { if (outfitButtons.TryGetValue(i, out REPOButton value)) { string arg = $"[F{i}]"; string text = ((i == currentOutfitIndex) ? $"{i} {arg}" : $"{i} {arg}"); ((TMP_Text)value.labelTMP).text = text; } } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("更新装备方案按钮高亮状态时出错: " + ex.Message)); } } } private static void SwitchOutfitWithShortcut(int outfitIndex) { try { int currentOutfitIndex = ConfigManager.GetCurrentOutfitIndex(); if (outfitIndex != currentOutfitIndex) { ConfigManager.SwitchOutfit(outfitIndex); if ((Object)(object)decorationsPage != (Object)null && ((Behaviour)decorationsPage.menuPage).isActiveAndEnabled) { UpdateOutfitButtonHighlights(); UpdateButtonStates(); } UpdateDecorations(); } } catch (Exception ex) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogError((object)("通过快捷键切换装备方案时出错: " + ex.Message)); } } } public static void InitializeShortcutListener() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown try { if ((Object)(object)ShortcutKeyListener.Instance == (Object)null) { GameObject val = new GameObject("MoreHeadShortcutListener"); val.AddComponent(); ManualLogSource? logger = Logger; if (logger != null) { logger.LogInfo((object)"已初始化装备方案快捷键监听器"); } } } catch (Exception ex) { ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogError((object)("初始化快捷键监听器时出错: " + ex.Message)); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }