Decompiled source of SkillSelection v1.0.1
SkillSelection.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers.Binary; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.Json; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using FastText; using FastText.Data; using Il2CppInterop.Common; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using Str; using UnityEngine; using UnityEngine.SceneManagement; using _K; using _m; using ifapp.Game; using ifapp.Game.Common; using ifapp.Game.Data; using ifapp.Game.Data.Crafting; using ifapp.Game.Input; using ifapp.Game.Scenes; using ifapp.Game.Scenes.Recipe; using ifapp.Game.UI.Common; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SkillSelection")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("在制卡界面按实际携带的技能筛选粒子。")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("SkillSelection")] [assembly: AssemblyTitle("SkillSelection")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace InFalsusMod { [BepInPlugin("menglei.infalsus.skillselection", "In Falsus Skill Selection", "1.0.1")] [BepInProcess("infalsus.exe")] public sealed class Plugin : BasePlugin { private SkillFilterNativeHooks? filterHooks; internal static ManualLogSource Logger { get; private set; } public override void Load() { Logger = ((BasePlugin)this).Log; WindowsConsoleEncoding.EnsureUtf8(((BasePlugin)this).Log); try { filterHooks = new SkillFilterNativeHooks(); ((BasePlugin)this).AddComponent<SkillFilterPanel>(); } catch { filterHooks?.Dispose(); filterHooks = null; throw; } ((BasePlugin)this).Log.LogInfo((object)"加载完成。"); } } internal static class PngRgba { private static readonly byte[] Signature = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; private const int BytesPerPixel = 4; internal static DecodedImage Decode(Stream stream) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Span<byte> span = memoryStream.GetBuffer().AsSpan(0, (int)memoryStream.Length); if (span.Length < Signature.Length || !span.Slice(0, Signature.Length).SequenceEqual(Signature)) { throw new InvalidDataException("特性筛选入口图案不是 PNG。"); } int num = 0; int num2 = 0; using MemoryStream memoryStream2 = new MemoryStream(); int num3 = Signature.Length; while (true) { if (num3 + 12 > span.Length) { throw new InvalidDataException("特性筛选入口图案数据不完整。"); } int num4 = checked((int)BinaryPrimitives.ReadUInt32BigEndian(span.Slice(num3))); Span<byte> span2 = span.Slice(num3 + 4, 4); if (num3 + 12 + num4 > span.Length) { throw new InvalidDataException("特性筛选入口图案数据不完整。"); } Span<byte> span3 = span.Slice(num3 + 8, num4); checked { if (span2.SequenceEqual("IHDR"u8)) { num = (int)BinaryPrimitives.ReadUInt32BigEndian(span3); num2 = (int)BinaryPrimitives.ReadUInt32BigEndian(span3.Slice(4)); if (num <= 0 || num2 <= 0 || span3[8] != 8 || span3[9] != 6 || span3[10] != 0 || span3[11] != 0 || span3[12] != 0) { throw new InvalidDataException("特性筛选入口图案必须是 8 位 RGBA 非隔行 PNG。"); } } else if (span2.SequenceEqual("IDAT"u8)) { memoryStream2.Write(span3); } else if (span2.SequenceEqual("IEND"u8)) { break; } } num3 += 12 + num4; } if (num == 0) { throw new InvalidDataException("特性筛选入口图案缺少 IHDR。"); } int num5; byte[] array; checked { num5 = num * 4; array = new byte[(num5 + 1) * num2]; memoryStream2.Position = 0L; } using (ZLibStream zLibStream = new ZLibStream(memoryStream2, CompressionMode.Decompress)) { int num6; for (int i = 0; i < array.Length; i += num6) { if ((num6 = zLibStream.Read(array, i, array.Length - i)) == 0) { throw new InvalidDataException("特性筛选入口图案像素数据不完整。"); } } } byte[] array2 = new byte[checked(num5 * num2)]; byte[] array3 = new byte[num5]; byte[] array4 = new byte[num5]; for (int j = 0; j < num2; j++) { int num7 = j * (num5 + 1); byte filter = array[num7]; array.AsSpan(num7 + 1, num5).CopyTo(array4); Unfilter(filter, array4, array3); array4.CopyTo(array2.AsSpan((num2 - 1 - j) * num5, num5)); byte[] array5 = array4; array4 = array3; array3 = array5; } return new DecodedImage(num, num2, array2); } private static void Unfilter(byte filter, byte[] line, byte[] previous) { for (int i = 0; i < line.Length; i++) { int num = ((i >= 4) ? line[i - 4] : 0); int num2 = previous[i]; int upLeft = ((i >= 4) ? previous[i - 4] : 0); int num3 = filter switch { 0 => 0, 1 => num, 2 => num2, 3 => (num + num2) / 2, 4 => Paeth(num, num2, upLeft), _ => throw new InvalidDataException("特性筛选入口图案使用了未知的 PNG 过滤类型。"), }; line[i] = (byte)(line[i] + num3); } } private static int Paeth(int left, int up, int upLeft) { int num = left + up - upLeft; int num2 = Math.Abs(num - left); int num3 = Math.Abs(num - up); int num4 = Math.Abs(num - upLeft); if (num2 > num3 || num2 > num4) { if (num3 > num4) { return upLeft; } return up; } return left; } } internal readonly record struct DecodedImage(int Width, int Height, byte[] BottomUpPixels); internal static class SkillFilter { internal static readonly HashSet<string> Families = new HashSet<string>(StringComparer.Ordinal); internal static readonly HashSet<int> Tiers = new HashSet<int>(); internal static bool MatchAll; private static readonly Dictionary<int, TraitInfo> Traits = TraitCatalog.Entries.ToDictionary((TraitInfo info) => info.Id); private static bool TierLimited { get { int count = Tiers.Count; if (count > 0) { return count < 3; } return false; } } internal static bool Active { get { if (Families.Count <= 0) { return TierLimited; } return true; } } internal static bool AppliesSelection(_bH mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 if ((int)mode == 0 || (int)mode == 2) { return true; } return false; } internal static UnorderedListVal<IotaInstance> View(UnorderedListVal<IotaInstance> source) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return source; } UnorderedListVal<IotaInstance> val = new UnorderedListVal<IotaInstance>(source.Length); for (int i = 0; i < source.Length; i++) { IotaInstance val2 = source.RawBuffer[i]; if (Matches(val2)) { val.Add(val2); } } return val; } internal static bool Matches(IotaInstance item) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (Families.Count == 0) { if (!TierLimited) { return true; } for (int i = 0; i < ParticleData.TraitCount(item); i++) { if (Traits.TryGetValue(ParticleData.GetTrait(item, i), out TraitInfo value) && Tiers.Contains(value.Tier)) { return true; } } return false; } foreach (string family in Families) { bool flag = false; for (int j = 0; j < ParticleData.TraitCount(item); j++) { if (Traits.TryGetValue(ParticleData.GetTrait(item, j), out TraitInfo value2) && value2.Family == family && (!TierLimited || Tiers.Contains(value2.Tier))) { flag = true; break; } } if (flag && !MatchAll) { return true; } if (!flag && MatchAll) { return false; } } return MatchAll; } } internal static class SkillFilterCatalog { internal static readonly SkillFilterGroup[] Groups = new SkillFilterGroup[4] { new SkillFilterGroup("DamageTraits", new int[7] { 2, 5, 8, 11, 12, 13, 63 }), new SkillFilterGroup("HealingTraits", new int[6] { 22, 25, 28, 31, 32, 33 }), new SkillFilterGroup("BuffTraits", new int[8] { 36, 39, 37, 38, 40, 43, 46, 49 }), new SkillFilterGroup("DebuffTraits", new int[5] { 16, 18, 19, 20, 21 }) }; internal static readonly TraitInfo[] Families = LoadFamilies(); private static TraitInfo[] LoadFamilies() { Dictionary<int, TraitInfo> entries = TraitCatalog.Entries.ToDictionary((TraitInfo info) => info.Id); TraitInfo[] array = (from id in Groups.SelectMany((SkillFilterGroup @group) => @group.TraitIds) select entries[id]).ToArray(); HashSet<string> hashSet = TraitCatalog.Entries.Select((TraitInfo info) => info.Family).ToHashSet<string>(StringComparer.Ordinal); if (array.Select((TraitInfo info) => info.Family).Distinct<string>(StringComparer.Ordinal).Count() != array.Length || !hashSet.SetEquals(array.Select((TraitInfo info) => info.Family))) { throw new InvalidOperationException("特性展示分组与游戏技能目录不一致。"); } return array; } } internal sealed record SkillFilterGroup(string TitleKey, int[] TraitIds); internal sealed class SkillFilterEntryVisuals : IDisposable { private Texture2D? texture; private Material? material; internal SkillFilterEntryVisuals(UIButton button, UIButton lastColor, UIButton previousColor) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) try { Transform val = ((Component)button).transform.Find("TraitsOnly") ?? throw new InvalidOperationException("原版特性入口缺少有特性图文层。"); Transform obj = val.Find("btn-traitswitch-traitsonly"); Constrained2D val2 = ((obj != null) ? ((Component)obj).GetComponent<Constrained2D>() : null) ?? throw new InvalidOperationException("原版特性入口缺少图案布局。"); Constrained2D val3 = ((Component)((Component)lastColor).transform.GetChild(0)).GetComponent<Constrained2D>() ?? throw new InvalidOperationException("原版颜色按钮缺少图案布局。"); for (int i = 0; i < ((Component)button).transform.childCount; i++) { Transform child = ((Component)button).transform.GetChild(i); ((Component)child).gameObject.SetActive((Object)(object)child == (Object)(object)val); } using Stream stream = typeof(SkillFilterEntryVisuals).Assembly.GetManifestResourceStream("InFalsusMod.Assets.trait-filter-button.png") ?? throw new InvalidOperationException("缺少特性筛选入口图案资源。"); DecodedImage decodedImage = PngRgba.Decode(stream); texture = new Texture2D(decodedImage.Width, decodedImage.Height, (TextureFormat)4, false) { name = "SkillSelection.Entry", hideFlags = (HideFlags)61, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; texture.LoadRawTextureData(new Il2CppStructArray<byte>(decodedImage.BottomUpPixels)); texture.Apply(false, true); Material renderableTargetMaterial = val2.constrained2DTransform.renderableTargetMaterial; if ((Object)(object)renderableTargetMaterial == (Object)null) { throw new InvalidOperationException("原版特性入口缺少图案材质。"); } material = new Material(renderableTargetMaterial) { name = "SkillSelection.Entry", hideFlags = (HideFlags)61, mainTexture = (Texture)(object)texture }; val2._irA(material, false); ((Component)button).transform.SetParent(((Component)lastColor).transform.parent, false); Constrained2DTransform constrained2DTransform = lastColor.constrained2D.constrained2DTransform; Constrained2DTransform constrained2DTransform2 = previousColor.constrained2D.constrained2DTransform; Constrained2DTransform constrained2DTransform3 = button.constrained2D.constrained2DTransform; float num = constrained2DTransform.offset.x - constrained2DTransform2.offset.x; float num2 = val2.constrained2DTransform.sizeInPixels.x - val3.constrained2DTransform.sizeInPixels.x; constrained2DTransform3.anchor = constrained2DTransform.anchor; constrained2DTransform3.parentAlignment = constrained2DTransform.parentAlignment; constrained2DTransform3.offset = constrained2DTransform.offset + new Vector2(num + num2 / 2f, 0f); button.constrained2D.constrained2DTransform = constrained2DTransform3; button.constrained2D._rQA(); button.constrained2D._PQA((byte)63); } catch { Dispose(); throw; } } public void Dispose() { if ((Object)(object)material != (Object)null) { Object.Destroy((Object)(object)material); } material = null; if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } texture = null; } } internal sealed class SkillFilterNativeHooks : IDisposable { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void RefreshCall(IntPtr instance, IntPtr method); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void InstancesCall(IntPtr instance, IntPtr details, byte force, IntPtr method); private static readonly IntPtr InstancesMethodInfo = MethodInfoPointer("_ju"); private INativeDetour? refreshHook; private INativeDetour? instancesHook; private readonly RefreshCall originalRefresh; private readonly InstancesCall originalInstances; internal SkillFilterNativeHooks() { if (!OperatingSystem.IsWindows() || IntPtr.Size != 8) { throw new PlatformNotSupportedException("制卡筛选原生入口仅适用于 Windows x64。"); } try { refreshHook = INativeDetour.Create<RefreshCall>(Marshal.ReadIntPtr(MethodInfoPointer("_ku")), (RefreshCall)Refresh); originalRefresh = ((IDetour)refreshHook).GenerateTrampoline<RefreshCall>(); instancesHook = INativeDetour.Create<InstancesCall>(Marshal.ReadIntPtr(InstancesMethodInfo), (InstancesCall)Instances); originalInstances = ((IDetour)instancesHook).GenerateTrampoline<InstancesCall>(); ((IDetour)refreshHook).Apply(); ((IDetour)instancesHook).Apply(); } catch { Dispose(); throw; } } private static IntPtr MethodInfoPointer(string name) { if (!(Il2CppInteropUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod((MethodBase)(typeof(CraftingLayer).GetMethod(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public) ?? throw new MissingMethodException(typeof(CraftingLayer).FullName, name)))?.GetValue(null) is IntPtr intPtr) || intPtr == IntPtr.Zero) { throw new InvalidOperationException("无法读取制卡入口 " + name + " 的 MethodInfo。"); } if (Marshal.ReadIntPtr(intPtr) == IntPtr.Zero) { throw new InvalidOperationException("制卡入口 " + name + " 为空。"); } return intPtr; } private void Refresh(IntPtr instance, IntPtr method) { WithFilteredInventory(instance, delegate { originalRefresh(instance, method); }); } private void Instances(IntPtr instance, IntPtr details, byte force, IntPtr method) { WithFilteredInventory(instance, delegate { originalInstances(instance, details, force, method); }); } private static void WithFilteredInventory(IntPtr instance, Action refresh) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //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) CraftingLayer val = null; UnorderedListVal<IotaInstance> val2 = null; UnorderedListVal<IotaInstance> obj = null; bool flag = false; try { if (SkillFilter.Active && instance != IntPtr.Zero) { val = new CraftingLayer(instance); if (SkillFilter.AppliesSelection(val._gZ.TraitFilter)) { val2 = val._dZ; obj = (val._dZ = SkillFilter.View(val2)); flag = true; } } } catch (Exception exception) { SkillFilterPanel.ReportFilterFailure(exception); } try { refresh(); } finally { if (flag) { val._dZ = val2; } GC.KeepAlive(obj); GC.KeepAlive(val2); } } internal unsafe static void RefreshInstances(CraftingLayer owner, IotaDetails details) { byte b = 1; IntPtr* ptr = stackalloc IntPtr[2]; *ptr = IL2CPP.il2cpp_object_unbox(((Il2CppObjectBase)details).Pointer); ptr[1] = (IntPtr)(&b); IntPtr zero = IntPtr.Zero; IL2CPP.il2cpp_runtime_invoke(InstancesMethodInfo, ((Il2CppObjectBase)owner).Pointer, (void**)ptr, ref zero); GC.KeepAlive(details); GC.KeepAlive(owner); Il2CppException.RaiseExceptionIfNecessary(zero); } public void Dispose() { ((IDisposable)instancesHook)?.Dispose(); instancesHook = null; ((IDisposable)refreshHook)?.Dispose(); refreshHook = null; } } public sealed class SkillFilterPanel : MonoBehaviour { private readonly record struct BuiltInElementState(GameObject Target, bool Active); private readonly record struct BuiltInLayoutState(Constrained2D Target, Constrained2DTransform Layout); private readonly record struct Heading(FastText Label, string Key); private const float SidebarWidth = 918f; private static readonly object failureSync = new object(); private static string? pendingFilterFailure; private CraftingLayer? owner; private RecipeScene? recipeScene; private UIButton? entryButton; private UIButton? entryTextTemplate; private SkillFilterEntryVisuals? entryVisuals; private bool entryInputEnabled; private bool entryAttempted; private bool shellFailed; private bool entryTextDirty = true; private RecipeFilterLayer? filterLayer; private _wd? originalFilterChanged; private readonly List<BuiltInElementState> builtInElementStates = new List<BuiltInElementState>(); private readonly List<BuiltInLayoutState> builtInLayoutStates = new List<BuiltInLayoutState>(); private readonly List<Heading> headings = new List<Heading>(); private TraitIcon? traitIconTemplate; private GameData? gameData; private int openRequestedFrame = -1; private bool open; private bool closing; private bool refresh; private float nextDiscovery; private Localization entryLanguage; private Localization controlsLanguage; private bool controlsDirty = true; private readonly TraitInfo[] familyTraits = SkillFilterCatalog.Families; private SkillFilterTooltip? tooltip; private int hoveredTrait = -1; private UIButton? resetButton; private readonly List<UIButton> tierButtons = new List<UIButton>(); private readonly List<UIButton> traitButtons = new List<UIButton>(); private readonly List<TraitIcon> traitIcons = new List<TraitIcon>(); private readonly List<FastText> traitNames = new List<FastText>(); private UIButton? matchAnyButton; private UIButton? matchAllButton; private string? pendingErrorKey; private NativeModalSession? errorSession; public SkillFilterPanel(IntPtr pointer) : base(pointer) { } public void Update() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) DiscoverOwner(); if ((Object)(object)owner == (Object)null) { return; } ObserveFilterLayer(); ObserveErrorModal(); ConsumeFilterFailure(); OpenRequestedPanel(); UpdateEntry(); if (open) { HideBuiltInFilterContent(); if (!closing && (controlsDirty || controlsLanguage != ModText.Language)) { TryRefreshControls(); } } UpdateTooltip(); RefreshCraftingList(); TryShowError(); } internal static void ReportFilterFailure(Exception exception) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown SkillFilter.Families.Clear(); lock (failureSync) { pendingFilterFailure = "FilterFailed"; } ManualLogSource logger = Plugin.Logger; bool flag; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("技能筛选视图准备失败,已恢复不筛选:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(exception); } logger.LogError(val); } private void DiscoverOwner() { if ((Object)(object)owner != (Object)null && ((Behaviour)owner).isActiveAndEnabled) { return; } CleanupOwner(); if (Time.realtimeSinceStartup < nextDiscovery) { return; } nextDiscovery = Time.realtimeSinceStartup + 0.5f; foreach (CraftingLayer item in Object.FindObjectsOfType<CraftingLayer>()) { if (((Behaviour)item).isActiveAndEnabled) { owner = item; break; } } } private void ObserveFilterLayer() { if (open && (!((Object)(object)filterLayer != (Object)null) || !filterLayer._bx())) { open = false; closing = false; ReleaseFilterLayer(); controlsDirty = true; } } private void ObserveErrorModal() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (errorSession == null || errorSession.IsOpen) { return; } if (errorSession.Failure != null) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("原版技能筛选错误窗口状态读取失败,按已关闭清理:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(errorSession.Failure); } logger.LogWarning(val); } errorSession = null; } private void ConsumeFilterFailure() { string text; lock (failureSync) { text = pendingFilterFailure; pendingFilterFailure = null; } if (text != null) { pendingErrorKey = text; controlsDirty = true; refresh = true; ClosePanel(); } } private bool CanOpen() { if ((Object)(object)owner != (Object)null && ((Behaviour)owner).isActiveAndEnabled && !((InputReceiver)owner).DisableInputEvents && (Object)(object)InputManager.Instance != (Object)null) { return InputManager.Instance.IsHeadOfStack((InputReceiver)(object)owner); } return false; } private void UpdateEntry() { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null) { return; } UIButton iotaTraitFilterButton = owner.iotaTraitFilterButton; Il2CppReferenceArray<UIButton> colorFilterButtons = owner.colorFilterButtons; if ((Object)(object)iotaTraitFilterButton == (Object)null || (Object)(object)iotaTraitFilterButton.constrained2D == (Object)null || colorFilterButtons == null || ((Il2CppArrayBase<UIButton>)(object)colorFilterButtons).Length < 2) { return; } if (!entryAttempted) { entryAttempted = true; try { UIButton lastColor = ((Il2CppArrayBase<UIButton>)(object)colorFilterButtons)[((Il2CppArrayBase<UIButton>)(object)colorFilterButtons).Length - 1]; entryTextTemplate = iotaTraitFilterButton; entryButton = NativeButtons.Create(entryTextTemplate, (InputReceiver)(object)owner, "SkillSelection.Button", ModText.Get("TraitsButton"), Toggle); entryVisuals = new SkillFilterEntryVisuals(entryButton, lastColor, ((Il2CppArrayBase<UIButton>)(object)colorFilterButtons)[((Il2CppArrayBase<UIButton>)(object)colorFilterButtons).Length - 2]); entryTextDirty = true; Plugin.Logger.LogDebug((object)"已建立技能选择入口。"); } catch (Exception ex) { if ((Object)(object)entryButton != (Object)null) { Object.Destroy((Object)(object)((Component)entryButton).gameObject); } entryButton = null; entryTextTemplate = null; entryVisuals?.Dispose(); entryVisuals = null; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("技能选择入口创建失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } if ((Object)(object)entryButton == (Object)null || (Object)(object)entryTextTemplate == (Object)null) { return; } bool isActiveAndEnabled = ((Behaviour)owner).isActiveAndEnabled; if (((Component)entryButton).gameObject.activeSelf != isActiveAndEnabled) { ((Component)entryButton).gameObject.SetActive(isActiveAndEnabled); entryTextDirty = isActiveAndEnabled; entryInputEnabled = false; } if (isActiveAndEnabled) { if (entryTextDirty || entryLanguage != ModText.Language) { SkillFilterVisuals.UpdateButtonText(entryButton, entryTextTemplate, ModText.Get("TraitsButton")); SkillFilterVisuals.AlignEntryLabel(entryButton); entryLanguage = ModText.Language; entryTextDirty = false; } bool flag2 = CanOpen() && openRequestedFrame < 0 && !shellFailed && errorSession == null && pendingErrorKey == null; NativeButtons.SetState(entryButton, flag2); if (flag2 && !entryInputEnabled) { UIManager._ftA()._ktA(entryButton); UIManager._ftA()._mtA(entryButton, (InputReceiver)(object)owner); InputManager.Instance.RequestLastMouseMoveReplay(); } entryInputEnabled = flag2; } } private void Toggle(UIButton button) { if (!((Object)(object)button != (Object)(object)entryButton)) { if (open) { ClosePanel(); } else if (openRequestedFrame < 0 && CanOpen() && !shellFailed && errorSession == null && pendingErrorKey == null) { openRequestedFrame = Time.frameCount; } } } private void OpenRequestedPanel() { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (openRequestedFrame < 0 || Time.frameCount <= openRequestedFrame) { return; } openRequestedFrame = -1; if (open || !CanOpen() || shellFailed || errorSession != null || pendingErrorKey != null) { return; } try { EnsureFilterLayer(); filterLayer._ZW((_Wd)0, SkillFilterVisuals.CenterOffset(filterLayer), (InputReceiver)null); filterLayer.self._sQA(SkillFilterVisuals.CenterOffset(filterLayer)); if (!filterLayer._bx()) { throw new InvalidOperationException("原版配方筛选浮窗未进入可见状态。"); } open = true; closing = false; HideBuiltInFilterContent(); CreateFilterControls(); controlsDirty = true; RefreshControls(); Plugin.Logger.LogDebug((object)"已打开技能选择浮窗。"); } catch (Exception ex) { if ((Object)(object)filterLayer != (Object)null) { ForceCloseFilterLayer(filterLayer, ex); } ReleaseFilterLayer(); open = false; closing = false; shellFailed = true; pendingErrorKey = "FilterRefreshFailed"; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("原版技能筛选浮窗准备或打开失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } private void EnsureFilterLayer() { if ((Object)(object)filterLayer != (Object)null) { return; } if ((Object)(object)owner == (Object)null || (Object)(object)entryButton == (Object)null) { throw new InvalidOperationException("制卡筛选入口尚未就绪。"); } RecipeFilterLayer val = (filterLayer = FindAvailableFilterLayer() ?? throw new InvalidOperationException("当前制卡场景没有空闲且完整绑定的 RecipeFilterLayer。")); originalFilterChanged = val.OnFilterChanged; try { val.OnFilterChanged = null; Constrained2D[] array = (Constrained2D[])(object)new Constrained2D[5] { val.self, val.contentContainer, val.backing, val.cornerBrackets, ((Component)((Component)val.buttons.ResetAllButton).transform.parent).GetComponent<Constrained2D>() }; foreach (Constrained2D val2 in array) { builtInLayoutStates.Add(new BuiltInLayoutState(val2, val2.constrained2DTransform)); } RecipeScene? obj = recipeScene; object obj2; if (obj == null) { obj2 = null; } else { DataAccess dataAccess = obj.dataAccess; obj2 = ((dataAccess != null) ? dataAccess._lLA() : null); } if (obj2 == null) { throw new InvalidOperationException("当前游戏技能定义尚未就绪。"); } gameData = (GameData?)obj2; TraitCatalog.Validate(gameData); traitIconTemplate = FindTraitIconTemplate() ?? throw new InvalidOperationException("场景中没有完整的原版技能图标模板。"); HideBuiltInFilterContent(); } catch { ReleaseFilterLayer(); throw; } } private RecipeFilterLayer? FindAvailableFilterLayer() { //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null) { return null; } bool flag = default(bool); foreach (RecipeScene item in Resources.FindObjectsOfTypeAll<RecipeScene>()) { if ((Object)(object)item == (Object)null) { continue; } Scene scene = ((Component)item).gameObject.scene; if (!((Scene)(ref scene)).IsValid() || (Object)(object)item.craftingLayer == (Object)null || ((Il2CppObjectBase)item.craftingLayer).Pointer != ((Il2CppObjectBase)owner).Pointer) { continue; } RecipeFilterLayer recipeFilterLayer = item.recipeFilterLayer; RecipeFilterLayerButtons val = ((recipeFilterLayer != null) ? recipeFilterLayer.buttons : null); if ((Object)(object)recipeFilterLayer == (Object)null || (Object)(object)recipeFilterLayer.self == (Object)null || (Object)(object)recipeFilterLayer.contentContainer == (Object)null || (Object)(object)recipeFilterLayer.backing == (Object)null || (Object)(object)recipeFilterLayer.cornerBrackets == (Object)null || (Object)(object)recipeFilterLayer.closeButton == (Object)null || (Object)(object)recipeFilterLayer.openAnimator == (Object)null || (Object)(object)recipeFilterLayer.closeAnimator == (Object)null || val == null || (Object)(object)val.ResetAllButton == (Object)null || val.ColorTypeButtons == null || ((Il2CppArrayBase<UIButton>)(object)val.ColorTypeButtons).Length == 0 || val.TierButtons == null || ((Il2CppArrayBase<UIButton>)(object)val.TierButtons).Length < 3 || val.TraitButtons == null || ((Il2CppArrayBase<UIButton>)(object)val.TraitButtons).Length < 2 || val.MasteryProgressButtons == null || ((Il2CppArrayBase<UIButton>)(object)val.MasteryProgressButtons).Length == 0 || ((Object)(object)((Component)recipeFilterLayer).transform.parent != (Object)null && !((Component)((Component)recipeFilterLayer).transform.parent).gameObject.activeInHierarchy)) { continue; } try { if (!recipeFilterLayer._bx()) { recipeScene = item; return recipeFilterLayer; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("跳过状态不可读的原版配方筛选浮窗:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } logger.LogDebug(val2); } } return null; } private static TraitIcon? FindTraitIconTemplate() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Invalid comparison between Unknown and I4 //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) TraitIcon val = null; float num = -1f; bool flag = false; foreach (TraitIcon item in Resources.FindObjectsOfTypeAll<TraitIcon>()) { if ((Object)(object)item == (Object)null) { continue; } Scene scene = ((Component)item).gameObject.scene; if (((Scene)(ref scene)).IsValid() && !((Object)(object)item.self == (Object)null) && !((Object)(object)item.frame == (Object)null) && !((Object)(object)item.icon == (Object)null) && !((Object)(object)item.traitIconAssets == (Object)null)) { bool flag2 = (int)item.style == 0; Vector2 sizeInPixels = item.self.constrained2DTransform.sizeInPixels; float num2 = Math.Abs(sizeInPixels.x * sizeInPixels.y); if ((!((Object)(object)val != (Object)null) || !(!flag2 || flag) || !(num2 <= num)) && (!flag || flag2)) { val = item; num = num2; flag = flag2; } } } return val; } private void HideBuiltInFilterContent() { RecipeFilterLayer? obj = filterLayer; RecipeFilterLayerButtons val = ((obj != null) ? obj.buttons : null); if ((Object)(object)obj == (Object)null || val == null) { return; } if (builtInElementStates.Count == 0) { Transform parent = ((Component)val.ResetAllButton).transform.parent; Transform obj2 = parent.Find("TitleText"); RememberBuiltInElement((obj2 != null) ? ((Component)obj2).gameObject : null); Transform obj3 = parent.Find("TitleTextShadow"); RememberBuiltInElement((obj3 != null) ? ((Component)obj3).gameObject : null); RememberBuiltInElement(((Component)val.ResetAllButton).gameObject); RememberBuiltInElement(((Component)((Component)((Il2CppArrayBase<UIButton>)(object)val.TierButtons)[0]).transform.parent).gameObject); RememberBuiltInElement(((Component)((Component)((Il2CppArrayBase<UIButton>)(object)val.ColorTypeButtons)[0]).transform.parent).gameObject); RememberBuiltInElement(((Component)((Component)((Il2CppArrayBase<UIButton>)(object)val.TraitButtons)[0]).transform.parent).gameObject); RememberBuiltInElement(((Component)((Component)((Il2CppArrayBase<UIButton>)(object)val.MasteryProgressButtons)[0]).transform.parent).gameObject); } foreach (BuiltInElementState builtInElementState in builtInElementStates) { if ((Object)(object)builtInElementState.Target != (Object)null && builtInElementState.Target.activeSelf) { builtInElementState.Target.SetActive(false); } } } private void RememberBuiltInElement(GameObject? target) { if (!((Object)(object)target == (Object)null) && !builtInElementStates.Any((BuiltInElementState state) => ((Il2CppObjectBase)state.Target).Pointer == ((Il2CppObjectBase)target).Pointer)) { builtInElementStates.Add(new BuiltInElementState(target, target.activeSelf)); } } private void CreateFilterControls() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) RecipeFilterLayerButtons val = (filterLayer ?? throw new InvalidOperationException("原版筛选浮窗尚未建立。")).buttons ?? throw new InvalidOperationException("原版筛选浮窗缺少按钮定义。"); Il2CppReferenceArray<UIButton> val2 = val.TierButtons; Il2CppReferenceArray<UIButton> val3 = val.TraitButtons; Transform parent = ((Component)val.ResetAllButton).transform.parent; Transform obj = ((Component)((Il2CppArrayBase<UIButton>)(object)val3)[0]).transform.parent.Find("TitleText"); FastText template = ((obj != null) ? ((Component)obj).GetComponent<FastText>() : null) ?? throw new InvalidOperationException("原版特性分区缺少名称字体模板。"); AddHeading(parent, parent, "TraitsButton", new Vector2(36f, -57f)); resetButton = CreateIconControl(val.ResetAllButton, "Reset", delegate { ResetSelection(); }); SkillFilterVisuals.Place(resetButton, parent, new Vector2(459f, -165f)); AddHeading(((Component)((Il2CppArrayBase<UIButton>)(object)val2)[0]).transform.parent, parent, "TierTitle", new Vector2(130f, -255f)); for (int num = 0; num < 3; num++) { int tier = num + 1; UIButton val4 = CreateIconControl(((Il2CppArrayBase<UIButton>)(object)val2)[num], $"Tier{tier}", delegate { ToggleTier(tier); }); tierButtons.Add(val4); SkillFilterVisuals.Place(val4, parent, new Vector2(459f + (float)(num - 1) * 250f, -375f)); } int num2 = 0; for (int num3 = 0; num3 < SkillFilterCatalog.Groups.Length; num3++) { SkillFilterGroup skillFilterGroup = SkillFilterCatalog.Groups[num3]; float num4 = -110f - (float)num3 * 200f; FastText obj2 = AddHeading(((Component)((Il2CppArrayBase<UIButton>)(object)val3)[0]).transform.parent, parent, skillFilterGroup.TitleKey, new Vector2(1160f, num4 - 14f)); obj2.SetFontSize(3.2f, (UpdateType)1); obj2.SetAlignment((AlignmentOptions)5, (UpdateType)1); int num5 = 0; while (num5 < skillFilterGroup.TraitIds.Length) { int capturedIndex = num2; UIButton val5 = CreateIconControl(((Il2CppArrayBase<UIButton>)(object)val2)[0], $"Trait{num2 + 1:00}", delegate { ToggleTrait(capturedIndex); }); traitButtons.Add(val5); val5._eSA(_fI.op_Implicit((Action<UIButton, bool>)delegate(UIButton _, bool isHovered) { SetHoveredTrait(capturedIndex, isHovered); })); SkillFilterVisuals.ResizeTraitButton(val5); SkillFilterVisuals.Place(val5, parent, new Vector2(1330f + (float)num5 * 290f, num4), activate: false); traitIcons.Add(CreateTraitIcon(traitIconTemplate, val5, num2)); traitNames.Add(SkillFilterVisuals.CreateTraitName(template, val5, num2, ModText.TraitName(familyTraits[num2].Family))); ((Component)val5).gameObject.SetActive(true); num5++; num2++; } } matchAnyButton = CreateTextControl(((Il2CppArrayBase<UIButton>)(object)val3)[0], "MatchAny", "MatchAnyCompact", delegate { SetMatchMode(matchAll: false); }); SkillFilterVisuals.Place(matchAnyButton, parent, new Vector2(459f, -590f)); matchAllButton = CreateTextControl(((Il2CppArrayBase<UIButton>)(object)val3)[1], "MatchAll", "MatchAllCompact", delegate { SetMatchMode(matchAll: true); }); SkillFilterVisuals.Place(matchAllButton, parent, new Vector2(459f, -710f)); CraftingLayer? obj3 = owner; TraitIconHoverContainer template2 = ((obj3 != null) ? obj3.traitIconHoverContainer : null) ?? throw new InvalidOperationException("当前制卡界面缺少原版特性说明组件。"); tooltip = new SkillFilterTooltip(template2, parent, recipeScene.dataAccess); } private FastText AddHeading(Transform source, Transform parent, string key, Vector2 offset) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) Transform obj = source.Find("TitleText"); FastText val = SkillFilterVisuals.CreateLabel(((obj != null) ? ((Component)obj).GetComponent<FastText>() : null) ?? throw new InvalidOperationException("原版筛选分区缺少标题文字。"), parent, key, ModText.Get(key), offset); headings.Add(new Heading(val, key)); return val; } [HideFromIl2Cpp] private UIButton CreateTextControl(UIButton template, string name, string textKey, Action<UIButton> clicked) { return NativeButtons.Create(template, (InputReceiver)(object)filterLayer, "SkillSelection." + name, ModText.Get(textKey), clicked); } [HideFromIl2Cpp] private UIButton CreateIconControl(UIButton template, string name, Action<UIButton> clicked) { UIManager val = UIManager._ftA(); RecipeFilterLayer val2 = filterLayer; if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)template.constrained2D == (Object)null) { throw new InvalidOperationException("原生图标按钮输入或布局尚未就绪。"); } GameObject val3 = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent, false); ((Object)val3).name = "InFalsus.SkillSelection." + name; val3.SetActive(false); try { UIButton component = val3.GetComponent<UIButton>(); if ((Object)(object)component == (Object)null || (Object)(object)component.constrained2D == (Object)null || (Object)(object)component.ButtonCollider == (Object)null) { throw new InvalidOperationException("原生图标按钮缺少布局或碰撞体。"); } component._Gjb = null; component._hjb = null; component._Hjb = null; component._ijb = null; component._Ijb = null; component.UserComponent = null; component._DSA(_EI.op_Implicit(clicked)); component._dSA((_dI)1); val._mtA(component, (InputReceiver)(object)val2); return component; } catch { Object.Destroy((Object)(object)val3); throw; } } private static TraitIcon CreateTraitIcon(TraitIcon template, UIButton host, int slot) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)host).transform, false); ((Object)val).name = $"InFalsus.SkillSelection.TraitIcon{slot + 1:00}"; val.SetActive(false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; try { SkillFilterVisuals.PrepareDisplayClone(val, ((Component)host).gameObject.layer); TraitIcon val2 = val.GetComponent<TraitIcon>() ?? val.GetComponentInChildren<TraitIcon>(true) ?? throw new InvalidOperationException("原版技能图标模板层级已改变。"); if ((Object)(object)val2.self == (Object)null || (Object)(object)val2.frame == (Object)null || (Object)(object)val2.icon == (Object)null) { throw new InvalidOperationException("原版技能图标缺少布局组件。"); } val2.style = (_BI)2; SkillFilterVisuals.CenterTraitIcon(val2); val.SetActive(true); val2.self._rQA(); val2.self._PQA((byte)63); return val2; } catch { Object.Destroy((Object)(object)val); throw; } } private void TryRefreshControls() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown try { RefreshControls(); } catch (Exception ex) { pendingErrorKey = "FilterRefreshFailed"; ClosePanel(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(13, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("技能筛选原版控件刷新失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } private void RefreshControls() { //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) RecipeFilterLayer? obj = filterLayer; RecipeFilterLayerButtons val = ((obj != null) ? obj.buttons : null); if (val == null || (Object)(object)gameData == (Object)null || (Object)(object)resetButton == (Object)null || (Object)(object)matchAnyButton == (Object)null || (Object)(object)matchAllButton == (Object)null || tierButtons.Count != 3 || traitButtons.Count != familyTraits.Length || traitIcons.Count != familyTraits.Length || traitNames.Count != familyTraits.Length) { throw new InvalidOperationException("技能筛选控件或图标未完整建立。"); } NativeButtons.SetState(resetButton, enabled: true); foreach (Heading heading in headings) { SkillFilterVisuals.SetText(heading.Label, ModText.Get(heading.Key)); } foreach (FastText componentsInChild in ((Component)resetButton).GetComponentsInChildren<FastText>(true)) { SkillFilterVisuals.RefreshTextMesh(componentsInChild); } for (int i = 0; i < tierButtons.Count; i++) { NativeButtons.SetState(tierButtons[i], enabled: true, SkillFilter.Tiers.Contains(i + 1)); } UpdateTextControl(matchAnyButton, ((Il2CppArrayBase<UIButton>)(object)val.TraitButtons)[0], ModText.Get("MatchAnyCompact"), enabled: true, !SkillFilter.MatchAll); UpdateTextControl(matchAllButton, ((Il2CppArrayBase<UIButton>)(object)val.TraitButtons)[1], ModText.Get("MatchAllCompact"), enabled: true, SkillFilter.MatchAll); for (int j = 0; j < familyTraits.Length; j++) { TraitInfo traitInfo = familyTraits[j]; if (traitInfo.Id <= 0 || traitInfo.Id >= ((Il2CppArrayBase<TraitSpecification>)(object)gameData.traits).Length) { throw new InvalidOperationException($"技能图标编号 {traitInfo.Id} 已失效。"); } TraitSpecification val2 = ((Il2CppArrayBase<TraitSpecification>)(object)gameData.traits)[traitInfo.Id]; traitIcons[j]._qsA(ref val2, false, false, true); SkillFilterVisuals.CenterTraitIcon(traitIcons[j]); NativeButtons.SetState(traitButtons[j], enabled: true, SkillFilter.Families.Contains(traitInfo.Family)); SkillFilterVisuals.SetText(traitNames[j], ModText.TraitName(traitInfo.Family)); } controlsLanguage = ModText.Language; controlsDirty = false; } private static void UpdateTextControl(UIButton button, UIButton template, string text, bool enabled, bool selected) { SkillFilterVisuals.UpdateButtonText(button, template, text, centered: true); NativeButtons.SetState(button, enabled, selected); } private void SetMatchMode(bool matchAll) { if (SkillFilter.MatchAll != matchAll) { SkillFilter.MatchAll = matchAll; FilterChanged(); } } private void ToggleTier(int tier) { if (!SkillFilter.Tiers.Remove(tier)) { SkillFilter.Tiers.Add(tier); } FilterChanged(); } private void ResetSelection() { if (SkillFilter.Families.Count != 0 || SkillFilter.Tiers.Count != 0 || SkillFilter.MatchAll) { SkillFilter.Families.Clear(); SkillFilter.Tiers.Clear(); SkillFilter.MatchAll = false; FilterChanged(); } } private void ToggleTrait(int index) { if (index >= 0 && index < familyTraits.Length) { string family = familyTraits[index].Family; if (!SkillFilter.Families.Remove(family)) { SkillFilter.Families.Add(family); } FilterChanged(); } } private void FilterChanged() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown controlsDirty = true; refresh = true; string text = ((SkillFilter.Tiers.Count == 0) ? "全部" : string.Join(",", SkillFilter.Tiers.OrderBy((int tier) => tier))); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(19, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("特性筛选:已选"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(SkillFilter.Families.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("项,等级="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(",匹配全部="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(SkillFilter.MatchAll); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("。"); } logger.LogDebug(val); } private void SetHoveredTrait(int index, bool isHovered) { if (isHovered) { hoveredTrait = index; } else if (hoveredTrait == index) { hoveredTrait = -1; } } private void UpdateTooltip() { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (tooltip == null) { return; } try { if (!open || closing || (Object)(object)filterLayer == (Object)null || ((InputReceiver)filterLayer).DisableInputEvents || (Object)(object)InputManager.Instance == (Object)null || !InputManager.Instance.IsHeadOfStack((InputReceiver)(object)filterLayer)) { hoveredTrait = -1; } if (hoveredTrait < 0 || hoveredTrait >= traitButtons.Count) { tooltip.Hide(); } else { tooltip.Show(familyTraits[hoveredTrait], traitButtons[hoveredTrait].constrained2D.constrained2DTransform.offset, filterLayer.backing.constrained2DTransform.sizeInPixels); } } catch (Exception ex) { pendingErrorKey = "FilterRefreshFailed"; ClosePanel(); ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("特性悬浮说明刷新失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } private void RefreshCraftingList() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!refresh || (Object)(object)owner == (Object)null) { return; } refresh = false; try { BottomInsetIotaScrollContainer bottomInsetIotaScrollContainer = owner.bottomInsetIotaScrollContainer; IotaDetails val = ((bottomInsetIotaScrollContainer != null) ? bottomInsetIotaScrollContainer._EC() : null); owner._ku(); if (val != null) { ushort value = val.Id.Value; if (value >= 1 && value <= 40) { SkillFilterNativeHooks.RefreshInstances(owner, val); } } } catch (Exception ex) { pendingErrorKey = "FilterRefreshFailed"; ClosePanel(); Plugin.Logger.LogError((object)ex); } } private void TryShowError() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if (pendingErrorKey == null || errorSession != null || open) { return; } try { if (NativeModal.TryShowMessage(ModText.Get("TraitsTitle"), ModText.Get(pendingErrorKey), out NativeModalSession session)) { errorSession = session; pendingErrorKey = null; } } catch (Exception ex) { pendingErrorKey = null; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(15, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("原版技能筛选错误窗口创建失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } private void ClosePanel() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown hoveredTrait = -1; tooltip?.Hide(); if (!open || closing) { return; } if ((Object)(object)filterLayer == (Object)null) { open = false; return; } try { filterLayer._Ax(); closing = true; } catch (Exception ex) { ForceCloseFilterLayer(filterLayer, ex, invokeClose: false); ReleaseFilterLayer(); open = false; closing = false; ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(13, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("原版技能筛选浮窗关闭失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogError(val); } } private static void ForceCloseFilterLayer(RecipeFilterLayer layer, Exception? failure, bool invokeClose = true) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown bool flag = default(bool); if (invokeClose) { try { if ((Object)(object)layer._qcA != (Object)null) { layer._Ax(); } } catch (Exception ex) { if (failure != null) { failure.Data["FilterLayerClose"] = ex.ToString(); } else { ManualLogSource logger = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(12, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("清理技能筛选输入层失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } logger.LogWarning(val); } } } try { InputManager instance = InputManager.Instance; if ((Object)(object)instance != (Object)null && instance.IsHeadOfStack((InputReceiver)(object)layer)) { instance.ReleaseInputControl((InputReceiver)(object)layer); } layer._qcA = null; } catch (Exception ex2) { if (failure != null) { failure.Data["FilterLayerInputRelease"] = ex2.ToString(); } else { ManualLogSource logger2 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(14, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("释放技能筛选输入所有权失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2); } logger2.LogWarning(val); } } try { if ((Object)(object)layer.contentContainer != (Object)null && ((Component)layer.contentContainer).gameObject.activeSelf) { ((Component)layer.contentContainer).gameObject.SetActive(false); } } catch (Exception ex3) { if (failure != null) { failure.Data["FilterLayerHide"] = ex3.ToString(); return; } ManualLogSource logger3 = Plugin.Logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(13, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("隐藏技能筛选原版浮窗失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex3); } logger3.LogWarning(val); } } private void ReleaseFilterLayer() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown tooltip?.Dispose(); tooltip = null; hoveredTrait = -1; RecipeFilterLayer val = filterLayer; if ((Object)(object)val != (Object)null) { try { val.OnFilterChanged = originalFilterChanged; } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(13, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("恢复原版配方筛选回调失败:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } logger.LogDebug(val2); } } originalFilterChanged = null; foreach (BuiltInLayoutState builtInLayoutState in builtInLayoutStates) { if ((Object)(object)builtInLayoutState.Target != (Object)null) { builtInLayoutState.Target.constrained2DTransform = builtInLayoutState.Layout; builtInLayoutState.Target._PQA((byte)63); } } builtInLayoutStates.Clear(); foreach (Heading heading in headings) { if ((Object)(object)heading.Label != (Object)null) { Object.Destroy((Object)(object)((Component)heading.Label).gameObject); } } headings.Clear(); foreach (BuiltInElementState builtInElementState in builtInElementStates) { if ((Object)(object)builtInElementState.Target != (Object)null && builtInElementState.Target.activeSelf != builtInElementState.Active) { builtInElementState.Target.SetActive(builtInElementState.Active); } } builtInElementStates.Clear(); DestroyControl(resetButton); foreach (UIButton tierButton in tierButtons) { DestroyControl(tierButton); } foreach (UIButton traitButton in traitButtons) { DestroyControl(traitButton); } DestroyControl(matchAnyButton); DestroyControl(matchAllButton); filterLayer = null; gameData = null; traitIconTemplate = null; ClearControlReferences(); } private static void DestroyControl(UIButton? button) { if ((Object)(object)button != (Object)null) { Object.Destroy((Object)(object)((Component)button).gameObject); } } private void CleanupOwner() { if ((Object)(object)filterLayer != (Object)null) { ForceCloseFilterLayer(filterLayer, null, !closing); } ReleaseFilterLayer(); openRequestedFrame = -1; open = false; closing = false; if ((Object)(object)entryButton != (Object)null) { Object.Destroy((Object)(object)((Component)entryButton).gameObject); } entryButton = null; entryTextTemplate = null; entryVisuals?.Dispose(); entryVisuals = null; entryInputEnabled = false; entryAttempted = false; entryTextDirty = true; shellFailed = false; owner = null; recipeScene = null; refresh = false; controlsDirty = true; SkillFilter.Families.Clear(); SkillFilter.Tiers.Clear(); SkillFilter.MatchAll = false; } private void ClearControlReferences() { resetButton = null; tierButtons.Clear(); traitButtons.Clear(); traitIcons.Clear(); traitNames.Clear(); matchAnyButton = null; matchAllButton = null; } public void OnDestroy() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown NativeModalSession nativeModalSession = errorSession; nativeModalSession?.Close(); if (nativeModalSession?.Failure != null) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("组件卸载时关闭原版技能筛选错误窗口失败:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(nativeModalSession.Failure); } logger.LogWarning(val); } errorSession = null; pendingErrorKey = null; CleanupOwner(); } } internal sealed class SkillFilterTooltip : IDisposable { private readonly TraitIconHoverContainer view; private readonly DataAccess data; private readonly FastText title; private readonly FastText description; private string? shownFamily; private Localization language; internal SkillFilterTooltip(TraitIconHoverContainer template, Transform parent, DataAccess data) { //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) this.data = data; GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = "InFalsus.SkillSelection.Tooltip"; val.SetActive(false); try { view = val.GetComponent<TraitIconHoverContainer>() ?? throw new InvalidOperationException("原版特性说明副本缺少组件。"); if ((Object)(object)view.self == (Object)null || (Object)(object)view.icon == (Object)null || (Object)(object)view.traitDescriptionContainer == (Object)null || (Object)(object)view.traitDescriptionBacking == (Object)null || (Object)(object)view.titleText == (Object)null || (Object)(object)view.descriptionText == (Object)null) { throw new InvalidOperationException("原版特性说明资源未完整绑定。"); } SkillFilterVisuals.PrepareDisplayClone(val, ((Component)parent).gameObject.layer); title = ((Component)view.titleText).GetComponent<FastText>() ?? throw new InvalidOperationException("原版特性说明缺少标题文字。"); description = ((Component)view.descriptionText).GetComponent<FastText>() ?? throw new InvalidOperationException("原版特性说明缺少效果文字。"); Transform parent2 = ((Component)view.icon).transform.parent; for (int i = 0; i < parent2.childCount; i++) { Transform child = parent2.GetChild(i); ((Component)child).gameObject.SetActive(((Il2CppObjectBase)child).Pointer == ((Il2CppObjectBase)((Component)view.icon).transform).Pointer || ((Il2CppObjectBase)child).Pointer == ((Il2CppObjectBase)((Component)view.traitDescriptionContainer).transform).Pointer); } Constrained2DTransform constrained2DTransform = view.self.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = Vector2.zero; constrained2DTransform.renderableScale = Vector2.one; constrained2DTransform.zPosition = -0.5f; view.self.constrained2DTransform = constrained2DTransform; view.traitDescriptionContainer._sQA(Vector2.zero); view.icon.style = (_BI)2; Constrained2DTransform constrained2DTransform2 = view.traitDescriptionBacking.constrained2DTransform; constrained2DTransform2.anchor = new Vector2(0f, 1f); constrained2DTransform2.offset = new Vector2(144f, 0f); constrained2DTransform2.renderableScale = Vector2.one; view.traitDescriptionBacking.constrained2DTransform = constrained2DTransform2; ConfigureText(title, view.titleText, 3.6f, new Vector2(180f, -32f)); ConfigureText(description, view.descriptionText, 3.25f, new Vector2(180f, -90f)); } catch { Object.Destroy((Object)(object)val); throw; } } private static void ConfigureText(FastText label, Constrained2D constrained, float fontSize, Vector2 offset) { //IL_0012: 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_0043: 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_004d: Unknown result type (might be due to invalid IL or missing references) Constrained2DTransform constrained2DTransform = constrained.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = offset; constrained.constrained2DTransform = constrained2DTransform; label.SetFontSize(fontSize, (UpdateType)1); label.SetAlignment((AlignmentOptions)0, (UpdateType)1); label.presention = (FastTextPresentation)((label.presention | 0x40) & -33); label.SetMaxAutoLineBreakPixelWidth(900, (UpdateType)1); } internal void Show(TraitInfo family, Vector2 anchor, Vector2 availableSize) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: 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_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) if (shownFamily == family.Family && language == ModText.Language) { return; } DynamicStringMapping val = data._QLA() ?? throw new InvalidOperationException("游戏特性说明本地化映射尚未就绪。"); List<string> list = new List<string>(); foreach (TraitInfo item in from info in TraitCatalog.Entries where info.Family == family.Family orderby info.Tier select info) { string text = val.Get((DynamicStringTypeFlags)512, ModText.Language, new TraitId { Value = (short)item.Id }).CreateString(); if (string.IsNullOrWhiteSpace(text)) { throw new InvalidOperationException($"技能 {item.Id} 缺少当前语言的效果说明。"); } list.Add(new string('I', item.Tier) + " " + text); } ((Component)view).gameObject.SetActive(true); view.self._rQA(); TraitSpecification val2 = ((Il2CppArrayBase<TraitSpecification>)(object)data._lLA().traits)[family.Id]; view.icon._qsA(ref val2, false, false, true); SkillFilterVisuals.CenterTraitIcon(view.icon, 160f); view.icon.self._sQA(new Vector2(50f, -100f)); SkillFilterVisuals.SetText(title, ModText.TraitName(family.Family)); SkillFilterVisuals.SetText(description, string.Join("\n\n", list)); view.titleText._PQA((byte)63); view.descriptionText._PQA((byte)63); view._eR(); Constrained2DTransform constrained2DTransform = view.traitDescriptionBacking.constrained2DTransform; Vector2 val3 = Vector2.Scale(constrained2DTransform.sizeInPixels, Vector2.Scale(constrained2DTransform.renderableScale, constrained2DTransform.typeSpecificExtraScale)); float num = 144f + val3.x; float num2 = Math.Max(180f, val3.y); float num3 = anchor.x + 120f; if (num3 + num > availableSize.x - 24f) { num3 = anchor.x - 100f - num; } num3 = Mathf.Clamp(num3, 54f, availableSize.x - 24f - num); float num4 = Mathf.Clamp(anchor.y + 110f, num2 + 24f - availableSize.y, -24f); view.self._sQA(new Vector2(num3, num4)); view.self._PQA((byte)63); shownFamily = family.Family; language = ModText.Language; } internal void Hide() { shownFamily = null; if ((Object)(object)view != (Object)null && ((Component)view).gameObject.activeSelf) { ((Component)view).gameObject.SetActive(false); } } public void Dispose() { if ((Object)(object)view != (Object)null) { ((Component)view).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)view).gameObject); } } } internal static class SkillFilterVisuals { internal static Vector2 CenterOffset(RecipeFilterLayer layer) { //IL_000d: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Constrained2DTransform constrained2DTransform = layer.backing.constrained2DTransform; return -(constrained2DTransform.offset + Vector2.Scale(new Vector2(0.5f, 0.5f) - constrained2DTransform.anchor, constrained2DTransform.sizeInPixels)); } internal static void Place(UIButton button, Transform parent, Vector2 offset, bool activate = true) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) ((Component)button).transform.SetParent(parent, false); Constrained2DTransform constrained2DTransform = button.constrained2D.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = offset; constrained2DTransform.zPosition = -0.05f; button.constrained2D.constrained2DTransform = constrained2DTransform; ((Component)button).gameObject.SetActive(activate); button.constrained2D._rQA(); button.constrained2D._PQA((byte)63); } internal static void UpdateButtonText(UIButton button, UIButton template, string text, bool centered = false) { //IL_004b: 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) NativeButtons.UpdateText(button, template, text); foreach (FastText componentsInChild in ((Component)button).GetComponentsInChildren<FastText>(true)) { Constrained2D obj = ((Component)componentsInChild).GetComponent<Constrained2D>() ?? throw new InvalidOperationException("原版按钮文字缺少布局组件。"); Constrained2DTransform constrained2DTransform = obj.constrained2DTransform; if (centered) { constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = new Vector2(0f, -8f); componentsInChild.SetAlignment((AlignmentOptions)4, (UpdateType)1); } constrained2DTransform.fastText = componentsInChild; constrained2DTransform.meshRenderer = ((Component)componentsInChild).GetComponent<MeshRenderer>(); obj.constrained2DTransform = constrained2DTransform; RefreshTextMesh(componentsInChild); obj._PQA((byte)63); } } internal static void AlignEntryLabel(UIButton button) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Transform obj = ((Component)button).transform.Find("AllPresent"); object obj2; if (obj == null) { obj2 = null; } else { FastText componentInChildren = ((Component)obj).GetComponentInChildren<FastText>(true); obj2 = ((componentInChildren != null) ? ((Component)componentInChildren).GetComponent<Constrained2D>() : null); } if (obj2 == null) { throw new InvalidOperationException("原版特性入口缺少“全部”文字布局。"); } Constrained2D val = (Constrained2D)obj2; Transform obj3 = ((Component)button).transform.Find("TraitsOnly") ?? throw new InvalidOperationException("原版特性入口缺少有特性图文层。"); Constrained2DTransform constrained2DTransform = val.constrained2DTransform; foreach (FastText componentsInChild in ((Component)obj3).GetComponentsInChildren<FastText>(true)) { Constrained2D obj4 = ((Component)componentsInChild).GetComponent<Constrained2D>() ?? throw new InvalidOperationException("原版按钮文字缺少布局组件。"); Constrained2DTransform constrained2DTransform2 = obj4.constrained2DTransform; constrained2DTransform2.anchor = constrained2DTransform.anchor; constrained2DTransform2.parentAlignment = constrained2DTransform.parentAlignment; constrained2DTransform2.offset = constrained2DTransform.offset; obj4.constrained2DTransform = constrained2DTransform2; obj4._PQA((byte)63); } } internal static FastText CreateLabel(FastText template, Transform parent, string name, string text, Vector2 offset) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false); ((Object)val).name = "InFalsus.SkillSelection." + name; try { FastText component = val.GetComponent<FastText>(); Constrained2D component2 = val.GetComponent<Constrained2D>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { throw new InvalidOperationException("原版分区标题缺少文字或布局。"); } Constrained2DTransform constrained2DTransform = component2.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = offset; constrained2DTransform.zPosition = -0.08f; constrained2DTransform.fastText = component; constrained2DTransform.meshRenderer = val.GetComponent<MeshRenderer>(); component2.constrained2DTransform = constrained2DTransform; val.SetActive(true); SetText(component, text); component2._rQA(); component2._PQA((byte)63); return component; } catch { Object.Destroy((Object)(object)val); throw; } } internal static FastText CreateTraitName(FastText template, UIButton host, int index, string text) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) FastText obj = CreateLabel(template, ((Component)host).transform, $"TraitName{index + 1:00}", text, new Vector2(0f, -72f)); Constrained2D component = ((Component)obj).GetComponent<Constrained2D>(); Constrained2DTransform constrained2DTransform = component.constrained2DTransform; constrained2DTransform.color = Color.white; component.constrained2DTransform = constrained2DTransform; obj.SetFontSize(3f, (UpdateType)1); obj.SetAlignment((AlignmentOptions)1, (UpdateType)1); obj.SetTextColor(Color.white, (UpdateType)1); obj.presention = (FastTextPresentation)((obj.presention | 0x40) & -33); obj.SetMaxAutoLineBreakPixelWidth(280, (UpdateType)1); RefreshTextMesh(obj); component._PQA((byte)63); return obj; } internal static void SetText(FastText label, string text) { label.SetTextNonLocalized(text, (UpdateType)1); RefreshTextMesh(label); } internal static void RefreshTextMesh(FastText label) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) label.targetLocalization = ModText.Language; label.meshRenderer = ((Component)label).GetComponent<MeshRenderer>(); label.meshFilter = ((Component)label).GetComponent<MeshFilter>(); label.dirtyFlags = (DirtyFlags)(label.dirtyFlags | 0xC); label.EnsureDirtyFlagsProcessed(); } internal static void PrepareDisplayClone(GameObject root, int layer) { foreach (Transform componentsInChild in root.GetComponentsInChildren<Transform>(true)) { ((Component)componentsInChild).gameObject.layer = layer; } foreach (UIButton componentsInChild2 in root.GetComponentsInChildren<UIButton>(true)) { componentsInChild2._Gjb = null; componentsInChild2._hjb = null; componentsInChild2._Hjb = null; componentsInChild2._ijb = null; componentsInChild2._Ijb = null; componentsInChild2.UserComponent = null; ((Behaviour)componentsInChild2).enabled = false; } foreach (Collider componentsInChild3 in root.GetComponentsInChildren<Collider>(true)) { componentsInChild3.enabled = false; } foreach (FastText componentsInChild4 in root.GetComponentsInChildren<FastText>(true)) { Constrained2D component = ((Component)componentsInChild4).GetComponent<Constrained2D>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("原版特性说明文字缺少布局组件。"); } Constrained2DTransform constrained2DTransform = component.constrained2DTransform; constrained2DTransform.fastText = componentsInChild4; constrained2DTransform.meshRenderer = ((Component)componentsInChild4).GetComponent<MeshRenderer>(); component.constrained2DTransform = constrained2DTransform; RefreshTextMesh(componentsInChild4); } } internal static void ResizeTraitButton(UIButton button) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < ((Component)button).transform.childCount; i++) { Transform child = ((Component)button).transform.GetChild(i); if (((Object)child).name.StartsWith("icon-tier-", StringComparison.Ordinal)) { ((Component)child).gameObject.SetActive(false); continue; } Constrained2D component = ((Component)child).GetComponent<Constrained2D>(); if (!((Object)(object)component == (Object)null)) { Constrained2DTransform constrained2DTransform = component.constrained2DTransform; constrained2DTransform.sizeInPixels = new Vector2(128f, 128f); component.constrained2DTransform = constrained2DTransform; component._PQA((byte)63); } } BoxCollider obj = ((Il2CppObjectBase)button.ButtonCollider).TryCast<BoxCollider>() ?? throw new InvalidOperationException("原版特性筛选按钮的碰撞体类型已改变。"); Vector3 size = obj.size; obj.size = new Vector3(size.x * 128f / 180f, size.y * 128f / 180f, size.z); } internal static void CenterTraitIcon(TraitIcon icon, float frameSize = 120f) { //IL_0017: 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_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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) Constrained2DTransform constrained2DTransform = icon.self.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform.offset = Vector2.zero; constrained2DTransform.zPosition = -0.05f; constrained2DTransform.renderableScale = Vector2.one; constrained2DTransform.color = Color.white; icon.self.constrained2DTransform = constrained2DTransform; icon.self._PQA((byte)63); (Constrained2D, float, float)[] array = new(Constrained2D, float, float)[2] { (icon.frame, frameSize, 0f), (icon.icon, frameSize * 2f / 3f, -0.01f) }; for (int i = 0; i < array.Length; i++) { (Constrained2D, float, float) tuple = array[i]; Constrained2D item = tuple.Item1; float item2 = tuple.Item2; float item3 = tuple.Item3; Constrained2DTransform constrained2DTransform2 = item.constrained2DTransform; constrained2DTransform2.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform2.parentAlignment = (Constrained2DAlignment)0; constrained2DTransform2.offset = Vector2.zero; constrained2DTransform2.zPosition = item3; constrained2DTransform2.sizeInPixels = new Vector2(item2, item2); constrained2DTransform2.renderableScale = Vector2.one; constrained2DTransform2.color = Color.white; constrained2DTransform2.spriteBlendEffect = (_Ti)0; item.constrained2DTransform = constrained2DTransform2; item._PQA((byte)63); } } } internal static class ModText { private static readonly Dictionary<string, string[]> messages = Load(); private static readonly Dictionary<string, string> errorKeys = messages.Where<KeyValuePair<string, string[]>>((KeyValuePair<string, string[]> pair) => pair.Key.StartsWith("Error", StringComparison.Ordinal)).ToDictionary((KeyValuePair<string, string[]> pair) => pair.Value[0], (KeyValuePair<string, string[]> pair) => pair.Key); private static int frame = -1; private static Localization language = (Localization)1; private static Localization traitLanguage; private static readonly Dictionary<string, string> traitNames = new Dictionary<string, string>(); internal static Localization Language { get { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (frame != Time.frameCount) { frame = Time.frameCount; language = Strings.GetCurrentLocalization(); if ((int)language == 0) { language = Strings.GetLocalizationForSystemLanguage(); } } return language; } } private static Dictionary<string, string[]> Load() { using Stream utf8Json = Assembly.GetExecutingAssembly().GetManifestResourceStream("InFalsusMod.Data.ui-text.json") ?? throw new InvalidOperationException("Missing mod localization resource."); Dictionary<string, string[]>? obj = JsonSerializer.Deserialize<Dictionary<string, string[]>>(utf8Json) ?? throw new InvalidOperationException("Empty mod localization resource."); if (obj.Values.Any((string[] values) => values.Length != 5 || values.Any(string.IsNullOrWhiteSpace))) { throw new InvalidOperationException("Incomplete mod localization resource."); } return obj; } internal unsafe static string Get(string key, params object[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown Localization val = Language; object obj = (val - 2) switch { 3 => (0, "zh-CN"), 2 => (1, "zh-TW"), 0 => (3, "ja-JP"), 1 => (4, "ko-KR"), _ => (2, "en-US"), }; int item = ((ValueTuple<int, string>*)(&obj))->Item1; string item2 = ((ValueTuple<int, string>*)(&obj))->Item2; string text = messages[key][item]; if (args.Length != 0) { return string.Format(CultureInfo.GetCultureInfo(item2), text, args); } return text; } internal static string Error(Exception exception) { if (errorKeys.TryGetValue(exception.Message, out string value)) { return Get(value); } if (exception is InvalidOperationException && new string[6] { "粒子", "游戏粒子", "技能", "回想", "融合", "强化" }.Any((string prefix) => exception.Message.StartsWith(prefix, StringComparison.Ordinal))) { return Get("ErrorRules"); } return Get("ErrorUnknown"); } internal static string TraitName(string family) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) Localization val = Language; if (traitLanguage != val) { traitNames.Clear(); traitLanguage = val; } if (traitNames.TryGetValue(family, out string value)) { return value; } TraitInfo traitInfo = (from entry in TraitCatalog.Entries where entry.Family == family orderby entry.Tier select entry).First(); _NH cEb = _NH._CEb; object obj; if (cEb == null) { obj = null; } else { DataAccess obj2 = cEb._VNA(); obj = ((obj2 != null) ? obj2._QLA() : null); } DynamicStringMapping val2 = (DynamicStringMapping)obj; if ((Object)(object)val2 == (Object)null) { return Get("TraitId", traitInfo.Id); } value = val2.Get((DynamicStringTypeFlags)8, val, new TraitId { Value = (short)traitInfo.Id }).CreateString(); if (string.IsNullOrWhiteSpace(value)) { return Get("TraitId", traitInfo.Id); } string[] array = new string[3] { " III", " II", " I" }; foreach (string text in array) { if (value.EndsWith(text, StringComparison.Ordinal)) { string text2 = value; int length = text.Length; value = text2.Substring(0, text2.Length - length); break; } } traitNames.Add(family, value); return value; } } internal static class NativeButtons { internal static void UpdateText(UIButton button, UIButton template, string text) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) Il2CppArrayBase<FastText> componentsInChildren = ((Component)button).GetComponentsInChildren<FastText>(true); Il2CppArrayBase<FastText> componentsInChildren2 = ((Component)template).GetComponentsInChildren<FastText>(true); if (componentsInChildren.Length != componentsInChildren2.Length) { throw new InvalidOperationException("原版按钮文字层级已改变。"); } for (int i = 0; i < componentsInChildren.Length; i++) { FastText obj = componentsInChildren[i]; FastText val = componentsInChildren2[i]; obj.style = val.style; obj.SetFontFamilyAsset(val.FontFamilyAsset); obj.SetFontSize(val.FontSize, (UpdateType)1); obj.SetTextNonLocalized(text, (UpdateType)0); obj.targetLocalization = val.targetLocalization; obj.dirtyFlags = (DirtyFlags)(obj.dirtyFlags | 0xC); obj.EnsureDirtyFlagsProcessed(); } } internal static UIButton Create(UIButton template, InputReceiver owner, string name, string text, Action<UIButton> clicked) { UIManager val = UIManager._ftA(); if ((Object)(object)val == (Object)null || (Object)(object)template.constrained2D == (Object)null) { throw new InvalidOperationException("原生按钮输入或布局尚未就绪。"); } GameObject val2 = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)template).transform.parent, false); ((Object)val2).name = "InFalsus." + name; val2.SetActive(false); try { UIButton component = val2.GetComponent<UIButton>(); Il2CppArrayBase<FastText> componentsInChildren = val2.GetComponentsInChildren<FastText>(true); if ((Object)(object)component == (Object)null || (Object)(object)component.constrained2D == (Object)null || (Object)(object)component.ButtonCollider == (Object)null || componentsInChildren.Length == 0) { throw new InvalidOperationException("原生按钮缺少布局、碰撞体或文字组件。"); } component._Gjb = null; component._hjb = null; component._Hjb = null; component._ijb = null; component._Ijb = null; component.UserComponent = null; component._DSA(_EI.op_Implicit(clicked)); component._dSA((_dI)1); UpdateText(component, template, text); val._mtA(component, owner); return component; } catch { Object.Destroy((Object)(object)val2); throw; } } internal static void Place(UIButton button, Transform parent, Vector2 offset, Vector2 size) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) ((Component)button).transform.SetParent(parent, false); Constrained2DTransform constrained2DTransform = button.constrained2D.constrained2DTransform; constrained2DTransform.anchor = new Vector2(0.5f, 0.5f); constrained2DTransform.offset = offset; constrained2DTransform.sizeInPixels = size; constrained2DTransform.parentAlignment = (Constrained2DAlignment)0; button.constrained2D.constrained2DTransform = constrained2DTransform; foreach (FastText componentsInChild in ((Component)button).GetComponentsInChildren<FastText>(true)) { componentsInChild.presention = (FastTextPresentation)((componentsInChild.presention | 0x40) & -33); componentsInChild.SetMaxAutoLineBreakPixelWidth((int)Math.Max(24f, size.x - 24f), (UpdateType)1); componentsInChild.dirtyFlags = (DirtyFlags)(componentsInChild.dirtyFlags | 8); componentsInChild.EnsureDirtyFlagsProcessed(); } ((Component)button).gameObject.SetActive(true); button.constrained2D._rQA(); button.constrained2D._PQA((byte)63); } internal static void SetState(UIButton button, bool enabled, bool selected = false) { button._dSA((_dI)(enabled ? ((!selected) ? 1 : 2) : 0)); } } internal static class NativeModal { internal static bool TryShowMessage(string title, string body, out NativeModalSession? session, Action? closed = null) { session = null; UiModal available = GetAvailable(); if ((Object)(object)available == (Object)null) { return false; } Action<UiModal> val = Convert(delegate(UiModal current) { current._VtA(); closed?.Invoke(); }); try { available._TtA(Direct(title), Direct(body), (_yi)0, (Key)383, val, true); } catch (Exception ex) { try { if (available._StA()) { available._VtA(); } } catch (Exception ex2) { ex.Data["ModalCleanup"] = ex2.ToString(); } throw; } session = new NativeModalSession(available, val, null); return true; } internal static bool TryShowConfirmation(string title, string body, Action cancelled, Action confirmed, out NativeModalSession? session) { session = null; UiModal available = GetAvailable(); if ((Object)(object)available == (Object)null) { return false; } Action<UiModal> val = Convert(delegate(UiModal current) { current._VtA(); cancelled(); }); Action<UiModal> val2 = Convert(delegate(UiModal current) { current._VtA(); confirmed(); }); try { available._vtA(Direct(title), Direct(body), (_yi)0, (_yi)0, (Key)117, (Key)986, val, val2, true); } catch (Exception ex) { try { if (available._StA()) { available._VtA(); } } catch (Exception ex2) { ex.Data["ModalCleanup"] = ex2.ToString(); } throw; } session = new NativeModalSession(available, val, val2); return true; } private static UiModal? GetAvailable() { UiModal val = UiModal._BJb; if ((Object)(object)val == (Object)null) { CoreScene obj = CoreScene._Xl ?? CoreScene._YI(); val = ((obj != null) ? obj.UiModal : null); }