Decompiled source of InFalsusJudgementCounter v1.0.1
BepInEx/plugins/InFalsusJudgementCounter.dll
Decompiled 14 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; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppInterop.Runtime.Runtime.VersionSpecific.MethodInfo; using Il2CppInterop.Runtime.Startup; using Il2CppSystem; using Microsoft.CodeAnalysis; using UnityEngine; using _E; using _K; using _b; using ifapp.Game; using ifapp.Game.Input; using ifapp.Game.Scenes; using ifapp.Game.Scenes.Game; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(/*Could not decode attribute arguments.*/)] [assembly: AssemblyTitle("In Falsus Judgement Counter")] [assembly: AssemblyCompany("SkyFrozen")] [assembly: AssemblyCopyright("Copyright © SkyFrozen")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: SecurityPermission((SecurityAction)8, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : System.Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(/*Could not decode attribute arguments.*/)] internal sealed class RefSafetyRulesAttribute : System.Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace InFalsusJudgementCounter { public sealed class CounterBehaviour : MonoBehaviour { private static CounterBehaviour _instance; private readonly CounterCapture _capture = new CounterCapture(); private readonly CounterView _view = new CounterView(); private readonly CounterSettingsView _settingsView = new CounterSettingsView(); private readonly CounterLifetime _life = new CounterLifetime(); private readonly Stopwatch _clock = Stopwatch.StartNew(); private ReferenceBackground _reference; private ResultsScene _results; private SongSelectScene _selection; private CounterShortcuts _shortcuts; private readonly CounterInputGate _inputGate = new CounterInputGate(); private readonly Func<int, bool> _readKeys = Down; private int _polledFrame = -1; private string _notice = ""; private bool _manualHidden; private bool _officialCapture; private bool _savePending; private double _hideUntil; private double _nextError; private double _nextCaptureAttempt; private double _saveAt; private double _noticeUntil; public CounterBehaviour(System.IntPtr pointer) : base(pointer) { } public void Awake() { _instance = this; _shortcuts = new CounterShortcuts(_readKeys, Plugin.SaveBindings); _shortcuts.Load(Plugin.PanelKey.Value, Plugin.VisibilityKey.Value); _settingsView.Shortcuts = _shortcuts; _reference = new ReferenceBackground(Path.Combine(Paths.ConfigPath, "InFalsusJudgementCounter", "custom-preview.png"), Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "InFalsusJudgementCounter-preview.png")); _reference.Load(); } [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int key); [HideFromIl2Cpp] private static bool Down(int key) { return (GetAsyncKeyState(key) & 0x8000) != 0; } [HideFromIl2Cpp] private void NewRun(GameScene scene) { _selection = null; _inputGate.Reset(); _life.Begin(((Il2CppObjectBase)scene).Pointer.ToInt64()); _capture.Reset(); _results = null; _settingsView.Close(); } [HideFromIl2Cpp] private void Clear() { _life.Clear(); _capture.Reset(); _results = null; _settingsView.Close(); } [HideFromIl2Cpp] private void ObserveGame(GameScene scene) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown if (scene != null && ((Behaviour)scene).isActiveAndEnabled && _life.ObserveGame(((Il2CppObjectBase)scene).Pointer.ToInt64(), (int)scene._lN)) { _capture.Reset(); _results = null; _settingsView.Close(); } } [HideFromIl2Cpp] public static void SceneEntered(GameScene __instance) { _instance?.NewRun(__instance); } [HideFromIl2Cpp] public static void SceneLeaving(GameScene __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 CounterBehaviour instance = _instance; if (!((Object)(object)instance == (Object)null)) { instance._settingsView.Close(); instance._life.LeaveGame(((Il2CppObjectBase)__instance).Pointer.ToInt64(), (int)__instance._lN >= 4); if (!instance._life.Visible) { instance._capture.Reset(); } } } [HideFromIl2Cpp] public static void ResultsObserved(ResultsScene __instance) { CounterBehaviour instance = _instance; if (!((Object)(object)instance == (Object)null) && __instance != null && ((Behaviour)__instance).isActiveAndEnabled) { instance._life.ObserveResults(((Il2CppObjectBase)__instance).Pointer.ToInt64()); if (instance._life.InResults && instance._life.ResultsOwner == ((Il2CppObjectBase)__instance).Pointer.ToInt64()) { instance._results = __instance; } } } [HideFromIl2Cpp] public static void ResultsLeaving(ResultsScene __instance) { CounterBehaviour instance = _instance; if ((Object)(object)instance != (Object)null && instance._life.CloseResults(((Il2CppObjectBase)__instance).Pointer.ToInt64())) { instance.Clear(); } } [HideFromIl2Cpp] public static void SelectionObserved(SongSelectScene __instance) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 CounterBehaviour instance = _instance; if ((Object)(object)instance == (Object)null || __instance == null || !((Behaviour)__instance).isActiveAndEnabled) { return; } GameScene xn = GameScene._xn; if ((Object)(object)xn == (Object)null || !((Behaviour)xn).isActiveAndEnabled || (int)xn._lN >= 4) { if (instance._life.Visible) { instance.Clear(); } SongSelectScene selection = instance._selection; System.IntPtr? intPtr = ((selection != null) ? new System.IntPtr?(((Il2CppObjectBase)selection).Pointer) : ((System.IntPtr?)null)); System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer; if (!intPtr.HasValue || (intPtr.HasValue && intPtr.GetValueOrDefault() != pointer)) { instance._settingsView.Close(); instance._inputGate.Reset(); } instance._selection = __instance; } } [HideFromIl2Cpp] public static void SelectionLeaving(SongSelectScene __instance) { CounterBehaviour instance = _instance; if (!((Object)(object)instance == (Object)null)) { SongSelectScene selection = instance._selection; System.IntPtr? intPtr = ((selection != null) ? new System.IntPtr?(((Il2CppObjectBase)selection).Pointer) : ((System.IntPtr?)null)); System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer; if (intPtr.HasValue && (!intPtr.HasValue || !(intPtr.GetValueOrDefault() != pointer))) { instance._selection = null; instance._settingsView.Close(); instance._inputGate.Reset(); } } } [HideFromIl2Cpp] public static void ScreenshotBegin() { if ((Object)(object)_instance != (Object)null) { _instance._officialCapture = true; } } [HideFromIl2Cpp] public static void ScreenshotStep(bool __result) { if (!__result) { ScreenshotEnd(); } } [HideFromIl2Cpp] public static void ScreenshotEnd() { if ((Object)(object)_instance != (Object)null) { _instance._officialCapture = false; } } [HideFromIl2Cpp] public static void ScreenshotFailed(System.Exception __exception) { if (__exception != null) { ScreenshotEnd(); } } [HideFromIl2Cpp] private void Report(System.Exception ex) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) TimeSpan elapsed = _clock.Elapsed; if (!(((TimeSpan)(ref elapsed)).TotalSeconds < _nextError)) { elapsed = _clock.Elapsed; _nextError = ((TimeSpan)(ref elapsed)).TotalSeconds + 5.0; Plugin.Logger.LogWarning((object)("Counter observation skipped: " + (object)ex)); } } [HideFromIl2Cpp] public static void JudgementsObserved(_VD __instance) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) CounterBehaviour instance = _instance; if ((Object)(object)instance == (Object)null || __instance == null) { return; } TimeSpan elapsed = instance._clock.Elapsed; if (((TimeSpan)(ref elapsed)).TotalSeconds < instance._nextCaptureAttempt) { return; } try { GameScene xn = GameScene._xn; if ((Object)(object)xn == (Object)null || !((Behaviour)xn).isActiveAndEnabled || (int)xn._lN != 3) { return; } _VD dN = GameScene._DN; System.IntPtr? intPtr = ((dN != null) ? new System.IntPtr?(((Il2CppObjectBase)dN).Pointer) : ((System.IntPtr?)null)); System.IntPtr pointer = ((Il2CppObjectBase)__instance).Pointer; if (intPtr.HasValue && (!intPtr.HasValue || !(intPtr.GetValueOrDefault() != pointer))) { instance.ObserveGame(xn); if (instance._life.Current == CounterLifetime.Page.Playing) { CounterCapture capture = instance._capture; LogicalNotePlayer qe = LogicalNotePlayer._Qe; elapsed = instance._clock.Elapsed; capture.Observe(qe, ((TimeSpan)(ref elapsed)).TotalSeconds); } } } catch (System.Exception ex) { elapsed = instance._clock.Elapsed; instance._nextCaptureAttempt = ((TimeSpan)(ref elapsed)).TotalSeconds + 1.0; instance.Report(ex); } } [HideFromIl2Cpp] private void ObserveScreenshotKeys() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (Plugin.HideOnScreenshot.Value && Application.isFocused && (Down(123) || Down(44))) { TimeSpan elapsed = _clock.Elapsed; _hideUntil = ((TimeSpan)(ref elapsed)).TotalSeconds + 1.5; } } [HideFromIl2Cpp] private bool CanEdit(GameScene scene) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 SongSelectScene selection = _selection; if (selection == null || !((Behaviour)selection).isActiveAndEnabled || (scene != null && ((Behaviour)scene).isActiveAndEnabled && (int)scene._lN < 4)) { if (_life.InResults) { ResultsScene results = _results; if (results != null && ((Behaviour)results).isActiveAndEnabled) { goto IL_0077; } } if (scene != null && ((Behaviour)scene).isActiveAndEnabled && (int)scene._lN == 3) { GamePauseLayer pauseLayer = scene.pauseLayer; if (pauseLayer == null) { return false; } return ((Behaviour)pauseLayer).isActiveAndEnabled; } return false; } goto IL_0077; IL_0077: return true; } [HideFromIl2Cpp] private bool AnyInputHeld() { for (int i = 1; i < 256; i++) { if (_readKeys.Invoke(i)) { return true; } } return false; } [HideFromIl2Cpp] private void PrepareUiInput() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) int frameCount = Time.frameCount; if (_polledFrame == frameCount || _shortcuts == null) { return; } _polledFrame = frameCount; bool flag = CanEdit(GameScene._xn); bool isFocused = Application.isFocused; int num = _shortcuts.Poll(isFocused, flag, _settingsView.Open); if (_shortcuts.CloseRequested) { _settingsView.Close(); } if (num == 1) { _manualHidden = !_manualHidden; _settingsView.Close(); } TimeSpan elapsed; if (num == 0) { if (_settingsView.Open) { _settingsView.Close(); } else if (flag && Plugin.InputBlockReady) { _settingsView.Open = true; } else { _notice = (Plugin.InputBlockReady ? "请在选歌、暂停或结算时打开设置" : "输入隔离初始化失败,请检查模组日志"); elapsed = _clock.Elapsed; _noticeUntil = ((TimeSpan)(ref elapsed)).TotalSeconds + 2.5; } } if (_settingsView.Open && (!flag || !isFocused)) { _settingsView.Close(); } bool held = (_settingsView.Open || _inputGate.Blocked) && isFocused && AnyInputHeld(); CounterInputGate inputGate = _inputGate; bool open = _settingsView.Open; elapsed = _clock.Elapsed; inputGate.Observe(open, isFocused, flag, held, ((TimeSpan)(ref elapsed)).TotalSeconds, frameCount); } [HideFromIl2Cpp] public static void BeforeNativeInput() { CounterBehaviour instance = _instance; if ((Object)(object)instance == (Object)null) { return; } try { instance.PrepareUiInput(); } catch (System.Exception ex) { instance._settingsView.Close(); instance._inputGate.Reset(); instance.Report(ex); } } [HideFromIl2Cpp] public static void InputBarrierFailed(System.Exception error) { Plugin.InputBlockReady = false; CounterBehaviour instance = _instance; if ((Object)(object)instance != (Object)null) { instance._settingsView.Close(); instance._inputGate.Reset(); } Plugin.Logger.LogWarning((object)("Input barrier disabled: " + error.Message)); } [HideFromIl2Cpp] public static bool AllowNativeDispatch() { CounterBehaviour instance = _instance; if ((Object)(object)instance == (Object)null) { return true; } try { BeforeNativeInput(); if (!Application.isFocused || !instance.CanEdit(GameScene._xn)) { instance._inputGate.Reset(); } return !instance._inputGate.Blocked; } catch (System.Exception ex) { instance._settingsView.Close(); instance._inputGate.Reset(); instance.Report(ex); return true; } } public void Update() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) try { GameScene xn = GameScene._xn; ObserveGame(xn); if (_life.InResults) { ResultsScene results = _results; if (results == null || !((Behaviour)results).isActiveAndEnabled) { Clear(); } } PrepareUiInput(); ObserveScreenshotKeys(); if (!_savePending) { return; } TimeSpan elapsed = _clock.Elapsed; if (((TimeSpan)(ref elapsed)).TotalSeconds >= _saveAt) { _savePending = false; try { Plugin.Save(); return; } catch (System.Exception ex) { Plugin.Logger.LogWarning((object)("Counter settings save failed: " + ex.Message)); return; } } } catch (System.Exception ex2) { Report(ex2); } } public void OnGUI() { //IL_003e: 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_0078: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) try { GUI.depth = (_settingsView.Open ? (-31000) : (-9000)); TimeSpan elapsed; if (!_life.Visible && !_settingsView.Open) { elapsed = _clock.Elapsed; if (((TimeSpan)(ref elapsed)).TotalSeconds >= _noticeUntil) { return; } } ObserveScreenshotKeys(); if (Plugin.HideOnScreenshot.Value) { if (_officialCapture) { return; } elapsed = _clock.Elapsed; if (((TimeSpan)(ref elapsed)).TotalSeconds < _hideUntil) { return; } } GameScene xn = GameScene._xn; if (_life.InResults) { ResultsScene results = _results; if (results == null || !((Behaviour)results).isActiveAndEnabled) { Clear(); return; } } if (_settingsView.Open) { if (!CanEdit(xn)) { _settingsView.Close(); return; } CounterOptions options = Plugin.Options; bool released; CounterOptions counterOptions = _settingsView.Draw(options, _capture.Counts, _reference, out released); if (counterOptions != options) { Plugin.Apply(counterOptions); _savePending = true; elapsed = _clock.Elapsed; _saveAt = ((TimeSpan)(ref elapsed)).TotalSeconds + 0.5; } if (released && _savePending) { _saveAt = 0.0; } return; } elapsed = _clock.Elapsed; if (((TimeSpan)(ref elapsed)).TotalSeconds < _noticeUntil) { _view.DrawPlan(new CounterInk[1] { new CounterInk((float)Screen.width * 0.3f, (float)Screen.height * 0.22f, (float)Screen.width * 0.65f, 32f, 3588878847u, _notice, 20) }); } if (!_life.Visible || !Plugin.Enabled.Value || _manualHidden) { return; } if (!_life.InResults && Plugin.HideWhenPaused.Value && xn != null) { GamePauseLayer pauseLayer = xn.pauseLayer; if (((pauseLayer != null) ? new bool?(((Behaviour)pauseLayer).isActiveAndEnabled) : ((bool?)null)) == true) { return; } } CounterView view = _view; JudgementCounts counts = _capture.Counts; bool ready = _capture.Ready; float value = Plugin.Scale.Value; float value2 = Plugin.PositionX.Value; float value3 = Plugin.PositionY.Value; bool value4 = Plugin.Horizontal.Value; bool value5 = Plugin.BreakOnRight.Value; float value6 = Plugin.WidthScale.Value; float value7 = Plugin.HeightScale.Value; view.Draw(counts, ready, value, value2, value3, value4, null, value5, value6, value7); } catch (System.Exception ex) { Report(ex); } } public void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); if (_savePending) { try { Plugin.Save(); } catch { } } _inputGate.Reset(); _reference?.Dispose(); _settingsView.Dispose(); _view.Dispose(); Clear(); if ((Object)(object)_instance == (Object)(object)this) { _instance = null; } } } public static class CounterBindingPanel { public static CounterPanel Create(CounterShortcuts keys, int width, int height) { CounterRect b = CounterPanel.Create(CounterOptions.Default, width, height).Bounds; float s = b.W / 368f; CounterPanel p = new CounterPanel { Bounds = b }; Box(0f, 0f, 368f, 430f, 118562303u); Box(0f, 0f, 368f, 2f, 2464017407u); Text(16f, 12f, 220f, 30f, "快捷键设置", 22); Button(104, 256f, 12f, 96f, "返回"); Text(16f, 58f, 336f, 22f, "Ctrl / Alt / Shift 组合键均可使用", 13, 2293614847u); Text(16f, 94f, 336f, 24f, "打开 / 关闭设置面板", 16); Button(101, 16f, 124f, 336f, keys.Label(0), keys.Capturing == 0); Text(16f, 178f, 336f, 24f, "隐藏 / 恢复局内统计", 16); Button(102, 16f, 208f, 336f, keys.Label(1), keys.Capturing == 1); Text(16f, 262f, 336f, 22f, keys.Message, 12, 2464017407u); Text(16f, 294f, 336f, 20f, "Esc 取消录入 / 返回;整组松开后保存。", 12, 2293614847u); if (keys.Capturing >= 0) { Button(105, 16f, 332f, 336f, "取消本次修改"); } else { Button(103, 16f, 332f, 336f, "恢复默认 F4 / Shift+F4"); } Text(16f, 388f, 336f, 20f, "编辑时游戏输入已隔离,不会误选歌曲。", 12, 2293614847u); return p; [CompilerGenerated] void Box(float x, float y, float w, float h, uint color) { CounterRect counterRect = R(x, y, w, h); p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, color)); } [CompilerGenerated] void Button(int id, float x, float y, float w, string text, bool active = false) { CounterRect rect = R(x, y, w, 34f); p.Controls.Add(new CounterControl(id, rect)); Box(x, y, w, 34f, active ? 592138239u : 355221503u); Box(x, y + 33f, w, 1f, 2464017407u); Text(x + 9f, y + 4f, w - 18f, 26f, text, 15); } [CompilerGenerated] CounterRect R(float x, float y, float w, float h) { return new CounterRect(b.X + x * s, b.Y + y * s, w * s, h * s); } [CompilerGenerated] void Text(float x, float y, float w, float h, string text, int size = 14, uint color = 3588878847u) { CounterRect counterRect = R(x, y, w, h); p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, color, text, Math.Max(8, (int)Math.Round((double)((float)size * s))))); } } } public sealed class CounterCapture { private const int MaximumRecords = 120000; [field: CompilerGenerated] public JudgementCounts Counts { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] public bool Ready { [CompilerGenerated] get; [CompilerGenerated] private set; } public void Reset() { Counts = default(JudgementCounts); Ready = false; } public void Observe(LogicalNotePlayer player, double now) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } _T ve = player._ve; Memory<_cH> val = ((ve != null) ? ve._cd : null); Object val2 = val?._object; if (val2 == null) { Ready = false; return; } System.IntPtr pointer = ((Il2CppObjectBase)val2).Pointer; System.IntPtr intPtr = IL2CPP.il2cpp_object_get_class(pointer); if (IL2CPP.il2cpp_class_get_element_class(intPtr) != Il2CppClassPointerStore<_cH>.NativeClassPtr || IL2CPP.il2cpp_array_element_size(intPtr) != 40 || System.Runtime.CompilerServices.Unsafe.SizeOf<JudgementRecord>() != 40 || RuntimeHelpers.IsReferenceOrContainsReferences<_cH>()) { throw new InvalidOperationException("Unsupported native judgement layout; counter disabled for this read."); } Il2CppStructArray<_cH> val3 = new Il2CppStructArray<_cH>(pointer); try { int index = val._index; int dd = ve._Dd; int num = val._length & 0x7FFFFFFF; if (index < 0 || dd < 0 || dd > 120000 || dd > num || index > ((Il2CppArrayBase<_cH>)(object)val3).Length - dd) { throw new InvalidOperationException("Invalid judgement buffer range."); } System.Span<_cH> span = Il2CppStructArray<_cH>.op_Implicit(val3); if (span.IsEmpty) { Counts = default(JudgementCounts); Ready = true; } else { Counts = JudgementCounts.Read(MemoryMarshal.CreateReadOnlySpan<JudgementRecord>(ref System.Runtime.CompilerServices.Unsafe.As<_cH, JudgementRecord>(ref MemoryMarshal.GetReference<_cH>(span)), span.Length).Slice(index, dd)); Ready = true; } } finally { GC.KeepAlive((object)val3); GC.KeepAlive((object)val2); GC.KeepAlive((object)player); } } } public sealed class CounterInputGate { private bool _draining; private int _neutral = -1; private double _after; [field: CompilerGenerated] public bool Blocked { [CompilerGenerated] get; [CompilerGenerated] private set; } public void Reset() { Blocked = (_draining = false); _neutral = -1; _after = 0.0; } public void Observe(bool open, bool focused, bool editable, bool held, double now, int frame) { if (!focused || !editable) { Reset(); return; } if (open) { Blocked = (_draining = true); _neutral = -1; _after = now + 0.08; return; } if (!_draining) { Blocked = false; return; } Blocked = true; if (held) { _neutral = -1; _after = now + 0.08; return; } if (_neutral < 0) { _neutral = frame; } if (frame > _neutral && now >= _after) { Reset(); } } } public readonly record struct CounterInk(float X, float Y, float W, float H, uint Color, string Text = "", int Size = 16, bool Right = false) { [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterInk"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("X = "); builder.Append(((object)X/*cast due to .constrained prefix*/).ToString()); builder.Append(", Y = "); builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString()); builder.Append(", W = "); builder.Append(((object)W/*cast due to .constrained prefix*/).ToString()); builder.Append(", H = "); builder.Append(((object)H/*cast due to .constrained prefix*/).ToString()); builder.Append(", Color = "); builder.Append(((object)Color/*cast due to .constrained prefix*/).ToString()); builder.Append(", Text = "); builder.Append((object)Text); builder.Append(", Size = "); builder.Append(((object)Size/*cast due to .constrained prefix*/).ToString()); builder.Append(", Right = "); builder.Append(((object)Right/*cast due to .constrained prefix*/).ToString()); return true; } } public static class CounterLayout { public const float Width = 216f; public const float Height = 296f; public const uint Perfect = 4088463359u; public const uint Small = 3130716927u; public const uint Near = 2531125247u; public const uint Miss = 4101801983u; public static CounterRect Bounds(int screenWidth, int screenHeight, CounterOptions options) { CounterOptions counterOptions = options.Normalize(); float num = (counterOptions.Horizontal ? 568f : 216f); float num2 = (counterOptions.Horizontal ? 120f : 296f); num *= counterOptions.WidthScale; num2 *= counterOptions.HeightScale; float num3 = Math.Min(counterOptions.Scale * Math.Clamp((float)screenHeight / 1080f, 0.5f, 2f), Math.Min((float)screenWidth / num, (float)screenHeight / num2)); return new CounterRect(((float)screenWidth - num * num3) * counterOptions.X, ((float)screenHeight - num2 * num3) * counterOptions.Y, num * num3, num2 * num3); } public static List<CounterInk> Create(JudgementCounts n, int screenWidth, int screenHeight, float scale, float anchorX, float anchorY, bool ready, bool horizontal = false, bool breakOnRight = false, float widthScale = 1f, float heightScale = 1f) { CounterOptions counterOptions = new CounterOptions(Enabled: true, horizontal, anchorX, anchorY, scale, HideWhenPaused: false, HideOnScreenshot: true); counterOptions.WidthScale = widthScale; counterOptions.HeightScale = heightScale; CounterOptions counterOptions2 = counterOptions.Normalize(); CounterRect counterRect = Bounds(screenWidth, screenHeight, counterOptions2 with { WidthScale = 1f, HeightScale = 1f }); CounterRect counterRect2 = Bounds(screenWidth, screenHeight, counterOptions2); List<CounterInk> val = CreateBase(n, screenWidth, screenHeight, counterOptions2.Scale, counterOptions2.X, counterOptions2.Y, ready, horizontal, breakOnRight); float num = counterRect2.W / counterRect.W; float num2 = counterRect2.H / counterRect.H; for (int i = 0; i < val.Count; i++) { CounterInk counterInk = val[i]; val[i] = counterInk with { X = counterRect2.X + (counterInk.X - counterRect.X) * num, Y = counterRect2.Y + (counterInk.Y - counterRect.Y) * num2, W = counterInk.W * num, H = counterInk.H * num2, Size = Math.Max(1, (int)Math.Round((double)((float)counterInk.Size * Math.Min(num, num2)))) }; } return val; } private static List<CounterInk> CreateBase(JudgementCounts n, int screenWidth, int screenHeight, float scale, float anchorX, float anchorY, bool ready, bool horizontal = false, bool breakOnRight = false) { if (horizontal) { return Horizontal(n, screenWidth, screenHeight, new CounterOptions(Enabled: true, Horizontal: true, anchorX, anchorY, scale, HideWhenPaused: true, HideOnScreenshot: true), ready, breakOnRight); } scale = (float.IsFinite(scale) ? Math.Clamp(scale, 0.6f, 2f) : 1f); float num = Math.Min((float)screenWidth / 216f, (float)screenHeight / 296f); float s = Math.Min(scale * Math.Clamp((float)screenHeight / 1080f, 0.5f, 2f), num); float x = ((float)screenWidth - 216f * s) * (float.IsFinite(anchorX) ? Math.Clamp(anchorX, 0f, 1f) : 0.02f); float y = ((float)screenHeight - 296f * s) * (float.IsFinite(anchorY) ? Math.Clamp(anchorY, 0f, 1f) : 0.35f); List<CounterInk> p = new List<CounterInk>(38); Box(0f, 0f, 216f, 296f, 118562280u); Box(0f, 0f, 216f, 1f, 1147762892u); Box(0f, 295f, 216f, 1f, 1147762892u); Box(0f, 0f, 3f, 296f, 1147762824u); Box(0f, 0f, 62f, 2f, 2296244991u); Text(12f, 8f, 188f, 18f, "JUDGEMENT", 3588878847u, 13); Text(16f, 30f, 184f, 18f, "EARLY / FAST", 2293614847u, 11); Row(50f, "NEAR", n.EarlyNear, 2531125247u); Row(85f, "EXACT", n.EarlyExact, 3130716927u); Row(122f, "EXACT", n.Exact, 4088463359u, centre: true); Row(159f, "EXACT", n.LateExact, 3130716927u); Row(194f, "NEAR", n.LateNear, 2531125247u); Text(16f, 230f, 184f, 18f, "LATE / SLOW", 2293614847u, 11); Box(10f, 251f, 196f, 1f, 1147762858u); Row(257f, "BREAK", n.Break, 4101801983u); return p; [CompilerGenerated] void Box(float a, float b, float w, float h, uint c) { p.Add(new CounterInk(x + a * s, y + b * s, w * s, h * s, c)); } [CompilerGenerated] void Row(float top, string name, int value, uint color, bool centre = false) { Box(10f, top, 196f, 32f, centre ? 942427865u : 287387306u); Box(10f, top, 2f, 32f, color); Text(20f, top + 4f, 86f, 24f, name, color, centre ? 20 : 17); Text(110f, top + 3f, 84f, 26f, ready ? value.ToString() : "--", color, centre ? 23 : 20, right: true); } [CompilerGenerated] void Text(float a, float b, float w, float h, string text, uint c, int size = 16, bool right = false) { p.Add(new CounterInk(x + a * s, y + b * s, w * s, h * s, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s))), right)); } } private static List<CounterInk> Horizontal(JudgementCounts n, int width, int height, CounterOptions o, bool ready, bool breakOnRight) { CounterRect b = Bounds(width, height, o); float s = b.W / 568f; List<CounterInk> p = new List<CounterInk>(40); Box(0f, 0f, 568f, 120f, 118562280u); Box(0f, 0f, 568f, 1f, 1147762892u); Box(0f, 0f, 62f, 2f, 2296244991u); Box(0f, 119f, 568f, 1f, 1147762892u); Text(12f, 5f, 280f, 18f, "JUDGEMENT", 3588878847u, 12); uint[] array = new uint[6]; RuntimeHelpers.InitializeArray((System.Array)array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); uint[] array2 = array; string[] array3 = new string[6] { "BREAK", "NEAR", "EXACT", "EXACT", "EXACT", "NEAR" }; int[] array4 = new int[6] { n.Break, n.EarlyNear, n.EarlyExact, n.Exact, n.LateExact, n.LateNear }; for (int i = 0; i < 6; i++) { int num = (breakOnRight ? ((i + 1) % 6) : i); float num2 = 10 + i * 92; Box(num2, 28f, 86f, 82f, (num == 3) ? 942427865u : 287387306u); Box(num2, 28f, 2f, 82f, array2[num]); Text(num2 + 8f, 48f, 72f, 22f, array3[num], array2[num], (num == 3) ? 18 : 16); Text(num2 + 8f, 73f, 70f, 30f, Count(array4[num]), array2[num], (num == 3) ? 22 : 20, right: true); } Text(breakOnRight ? 18 : 110, 30f, 164f, 16f, "FAST", 2293614847u, 10); Text(breakOnRight ? 294 : 386, 30f, 164f, 16f, "LATE", 2293614847u, 10); return p; [CompilerGenerated] void Box(float x, float y, float w, float h, uint c) { p.Add(new CounterInk(b.X + x * s, b.Y + y * s, w * s, h * s, c)); } [CompilerGenerated] string Count(int v) { if (!ready) { return "--"; } return v.ToString(); } [CompilerGenerated] void Text(float x, float y, float w, float h, string text, uint c, int size = 16, bool right = false) { p.Add(new CounterInk(b.X + x * s, b.Y + y * s, w * s, h * s, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s))), right)); } } } public sealed class CounterLifetime { public enum Page { Hidden, Playing, AwaitingResults, Results } private int _state = -1; private long _closedGameOwner; [field: CompilerGenerated] public Page Current { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] public long GameOwner { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] public long ResultsOwner { [CompilerGenerated] get; [CompilerGenerated] private set; } public bool Visible => Current != Page.Hidden; public bool InResults => Current == Page.Results; public void Begin(long owner) { Current = Page.Playing; GameOwner = owner; ResultsOwner = 0L; _state = -1; } public bool ObserveGame(long owner, int state) { if (Current == Page.Hidden && owner == _closedGameOwner && state >= 3) { return false; } int num; if (owner == GameOwner && Current != Page.Hidden) { if (state >= 0 && state < 3) { num = ((_state >= 3) ? 1 : 0); if (num != 0) { goto IL_0045; } } else { num = 0; } goto IL_004c; } num = 1; goto IL_0045; IL_0045: Begin(owner); goto IL_004c; IL_004c: _state = state; if (state >= 4 && Current == Page.Playing) { Current = Page.AwaitingResults; } return (byte)num != 0; } public void LeaveGame(long owner, bool completed) { if (owner == GameOwner && Current != Page.Results) { if (completed) { Current = Page.AwaitingResults; } else { Clear(); } } } public void ObserveResults(long owner) { if ((Current == Page.AwaitingResults || Current == Page.Results) && (ResultsOwner == 0L || ResultsOwner == owner)) { ResultsOwner = owner; Current = Page.Results; } } public bool CloseResults(long owner) { if (!InResults || owner != ResultsOwner) { return false; } Clear(); return true; } public void Clear() { if (GameOwner != 0L) { _closedGameOwner = GameOwner; } Current = Page.Hidden; long gameOwner = (ResultsOwner = 0L); GameOwner = gameOwner; _state = -1; } } public readonly record struct CounterOptions { public bool Enabled { [CompilerGenerated] get; [CompilerGenerated] init; } public bool Horizontal { [CompilerGenerated] get; [CompilerGenerated] init; } public float X { [CompilerGenerated] get; [CompilerGenerated] init; } public float Y { [CompilerGenerated] get; [CompilerGenerated] init; } public float Scale { [CompilerGenerated] get; [CompilerGenerated] init; } public bool HideWhenPaused { [CompilerGenerated] get; [CompilerGenerated] init; } public bool HideOnScreenshot { [CompilerGenerated] get; [CompilerGenerated] init; } public bool BreakOnRight { [CompilerGenerated] get; [CompilerGenerated] init; } public float WidthScale { [CompilerGenerated] get; [CompilerGenerated] init; } public float HeightScale { [CompilerGenerated] get; [CompilerGenerated] init; } public static CounterOptions Default => new CounterOptions(Enabled: true, Horizontal: false, 0.02f, 0.35f, 1f, HideWhenPaused: false, HideOnScreenshot: true); public CounterOptions(bool Enabled, bool Horizontal, float X, float Y, float Scale, bool HideWhenPaused, bool HideOnScreenshot) { BreakOnRight = false; this.Enabled = Enabled; this.Horizontal = Horizontal; this.X = X; this.Y = Y; this.Scale = Scale; this.HideWhenPaused = HideWhenPaused; this.HideOnScreenshot = HideOnScreenshot; WidthScale = 1f; HeightScale = 1f; } public CounterOptions Normalize() { return this with { X = Finite(X, 0f, 1f, 0.02f), Y = Finite(Y, 0f, 1f, 0.35f), Scale = Finite(Scale, 0.6f, 2f, 1f), WidthScale = Finite(WidthScale, 0.4f, 2.5f, 1f), HeightScale = Finite(HeightScale, 0.4f, 2.5f, 1f) }; } private static float Finite(float n, float min, float max, float fallback) { if (!float.IsFinite(n)) { return fallback; } return Math.Clamp(n, min, max); } [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterOptions"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Enabled = "); builder.Append(((object)Enabled/*cast due to .constrained prefix*/).ToString()); builder.Append(", Horizontal = "); builder.Append(((object)Horizontal/*cast due to .constrained prefix*/).ToString()); builder.Append(", X = "); builder.Append(((object)X/*cast due to .constrained prefix*/).ToString()); builder.Append(", Y = "); builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString()); builder.Append(", Scale = "); builder.Append(((object)Scale/*cast due to .constrained prefix*/).ToString()); builder.Append(", HideWhenPaused = "); builder.Append(((object)HideWhenPaused/*cast due to .constrained prefix*/).ToString()); builder.Append(", HideOnScreenshot = "); builder.Append(((object)HideOnScreenshot/*cast due to .constrained prefix*/).ToString()); builder.Append(", BreakOnRight = "); builder.Append(((object)BreakOnRight/*cast due to .constrained prefix*/).ToString()); builder.Append(", WidthScale = "); builder.Append(((object)WidthScale/*cast due to .constrained prefix*/).ToString()); builder.Append(", HeightScale = "); builder.Append(((object)HeightScale/*cast due to .constrained prefix*/).ToString()); return true; } [CompilerGenerated] public void Deconstruct(out bool Enabled, out bool Horizontal, out float X, out float Y, out float Scale, out bool HideWhenPaused, out bool HideOnScreenshot) { Enabled = this.Enabled; Horizontal = this.Horizontal; X = this.X; Y = this.Y; Scale = this.Scale; HideWhenPaused = this.HideWhenPaused; HideOnScreenshot = this.HideOnScreenshot; } } public readonly record struct CounterRect(float X, float Y, float W, float H) { public bool Contains(float x, float y) { if (x >= X && x < X + W && y >= Y) { return y < Y + H; } return false; } [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterRect"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("X = "); builder.Append(((object)X/*cast due to .constrained prefix*/).ToString()); builder.Append(", Y = "); builder.Append(((object)Y/*cast due to .constrained prefix*/).ToString()); builder.Append(", W = "); builder.Append(((object)W/*cast due to .constrained prefix*/).ToString()); builder.Append(", H = "); builder.Append(((object)H/*cast due to .constrained prefix*/).ToString()); return true; } } public readonly record struct CounterControl(int Id, CounterRect Rect, bool Slider = false) { [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterControl"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Id = "); builder.Append(((object)Id/*cast due to .constrained prefix*/).ToString()); builder.Append(", Rect = "); builder.Append(((object)Rect/*cast due to .constrained prefix*/).ToString()); builder.Append(", Slider = "); builder.Append(((object)Slider/*cast due to .constrained prefix*/).ToString()); return true; } } public sealed class CounterPanel { public readonly List<CounterInk> Ink = new List<CounterInk>(); public readonly List<CounterControl> Controls = new List<CounterControl>(); public CounterRect Bounds; public static CounterPanel Create(CounterOptions options, int width, int height) { CounterOptions counterOptions = options.Normalize(); float s = Math.Min(Math.Clamp((float)height / 1080f, 0.55f, 1.6f), Math.Min((float)width / 408f, (float)height / 470f)); float left = (float)width - 388f * s; float top = Math.Max(16f * s, Math.Min((float)height * 0.12f, (float)height - 446f * s)); CounterPanel p = new CounterPanel { Bounds = new CounterRect(left, top, 368f * s, 430f * s) }; Box(0f, 0f, 368f, 430f, 118562303u); Box(0f, 0f, 368f, 2f, 2464017407u); Text(16f, 12f, 224f, 30f, "判定统计设置", 3588878847u, 22); Button(17, 246f, 12f, 106f, "按键设置"); Text(16f, 45f, 336f, 20f, "拖动定位 · 拖右下角改变长宽", 2293614847u, 13); Button(1, 16f, 76f, 104f, counterOptions.Enabled ? "显示:开" : "显示:关", counterOptions.Enabled); Button(2, 128f, 76f, 108f, "竖版", !counterOptions.Horizontal); Button(3, 244f, 76f, 108f, "横版", counterOptions.Horizontal); Slider(4, 16f, 118f, 160f, "水平", counterOptions.X, 0f, 1f, (counterOptions.X * 100f).ToString("0.0") + "%"); Slider(5, 192f, 118f, 160f, "垂直", counterOptions.Y, 0f, 1f, (counterOptions.Y * 100f).ToString("0.0") + "%"); Slider(14, 16f, 172f, 160f, "宽度", counterOptions.WidthScale, 0.4f, 2.5f, counterOptions.WidthScale.ToString("0.00") + "×"); Slider(15, 192f, 172f, 160f, "高度", counterOptions.HeightScale, 0.4f, 2.5f, counterOptions.HeightScale.ToString("0.00") + "×"); Slider(6, 16f, 226f, 336f, "整体缩放", counterOptions.Scale, 0.6f, 2f, counterOptions.Scale.ToString("0.00") + "×"); Button(7, 16f, 286f, 160f, counterOptions.HideWhenPaused ? "暂停隐藏:开" : "暂停隐藏:关", counterOptions.HideWhenPaused); Button(8, 192f, 286f, 160f, counterOptions.HideOnScreenshot ? "截图隐藏:开" : "截图隐藏:关", counterOptions.HideOnScreenshot); Button(9, 16f, 324f, 160f, "恢复位置与尺寸"); Button(10, 192f, 324f, 160f, "完成并关闭"); Button(13, 16f, 362f, 160f, counterOptions.BreakOnRight ? "横版 Break:最右" : "横版 Break:最左", counterOptions.BreakOnRight); Button(12, 192f, 362f, 160f, "重新加载底图"); Text(16f, 405f, 336f, 18f, "选歌 / 暂停 / 结算均可设置", 2293614847u, 12); return p; [CompilerGenerated] void Box(float x, float y, float w, float h, uint c) { CounterRect counterRect = R(x, y, w, h); p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, c)); } [CompilerGenerated] void Button(int id, float x, float y, float w, string text, bool active = false) { CounterRect rect = R(x, y, w, 30f); p.Controls.Add(new CounterControl(id, rect)); Box(x, y, w, 30f, active ? 592138239u : 355221503u); Box(x, y + 29f, w, 1f, active ? 1625932543u : 1400145151u); Text(x + 8f, y + 3f, w - 16f, 24f, text, active ? 1961740543u : 3588878847u, 14); } [CompilerGenerated] CounterRect R(float x, float y, float w, float h) { return new CounterRect(left + x * s, top + y * s, w * s, h * s); } [CompilerGenerated] void Slider(int id, float x, float y, float w, string label, float value, float min, float max, string display) { Text(x, y, w, 22f, label + " " + display, 3084708607u, 14); CounterRect rect = R(x, y + 24f, w, 20f); p.Controls.Add(new CounterControl(id, rect, Slider: true)); float num = Math.Clamp((value - min) / (max - min), 0f, 1f); Box(x, y + 32f, w, 3f, 742939135u); Box(x, y + 32f, w * num, 3f, 2464017407u); Box(x + w * num - 3f, y + 25f, 6f, 17f, 3824484351u); } [CompilerGenerated] void Text(float x, float y, float w, float h, string text, uint c = 3588878847u, int size = 16) { CounterRect counterRect = R(x, y, w, h); p.Ink.Add(new CounterInk(counterRect.X, counterRect.Y, counterRect.W, counterRect.H, c, text, Math.Max(8, (int)Math.Round((double)((float)size * s))))); } } } public sealed class CounterEditor { public bool RefreshRequested; public bool ShortcutsRequested; private float _grabX; private float _grabY; private float _resizeX; private float _resizeY; private float _resizeW; private float _resizeH; private float _startWidth; private float _startHeight; private float _resizeLeft; private float _resizeTop; [field: CompilerGenerated] public int Captured { [CompilerGenerated] get; [CompilerGenerated] private set; } public void Cancel() { Captured = 0; } public CounterOptions Handle(CounterPanel panel, CounterRect overlay, CounterOptions options, int width, int height, float x, float y, bool down, bool drag, bool up, out bool close, CounterViewport? preview = null) { //IL_0062: 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) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) close = false; CounterOptions counterOptions = options.Normalize(); float num = preview?.OutputX(x) ?? x; float num2 = preview?.OutputY(y) ?? y; if (down && Captured == 0) { Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator(); try { while (enumerator.MoveNext()) { CounterControl current = enumerator.Current; if (current.Rect.Contains(x, y)) { Captured = current.Id; break; } } } finally { ((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } if (Captured == 0 && !panel.Bounds.Contains(x, y) && (!preview.HasValue || preview.GetValueOrDefault().Rect.Contains(x, y)) && overlay.Contains(num, num2)) { float num3 = 16f / (preview?.Zoom ?? 1f); if (num >= overlay.X + overlay.W - num3 && num2 >= overlay.Y + overlay.H - num3) { Captured = 16; _resizeX = num; _resizeY = num2; _resizeW = overlay.W; _resizeH = overlay.H; _startWidth = counterOptions.WidthScale; _startHeight = counterOptions.HeightScale; _resizeLeft = overlay.X; _resizeTop = overlay.Y; } else { Captured = 11; _grabX = num - overlay.X; _grabY = num2 - overlay.Y; } } } if (((Captured >= 4 && Captured <= 6) || Captured == 14 || Captured == 15) && (down || drag || up)) { Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator(); try { while (enumerator.MoveNext()) { CounterControl current2 = enumerator.Current; if (current2.Id == Captured) { float num4 = Math.Clamp((x - current2.Rect.X) / current2.Rect.W, 0f, 1f); counterOptions = ((Captured == 4) ? counterOptions with { X = num4 } : ((Captured == 5) ? counterOptions with { Y = num4 } : ((Captured == 14) ? counterOptions with { WidthScale = 0.4f + num4 * 2.1f } : ((Captured == 15) ? counterOptions with { HeightScale = 0.4f + num4 * 2.1f } : counterOptions with { Scale = 0.6f + num4 * 1.4f })))); break; } } } finally { ((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } if (Captured == 11 && (down || drag || up)) { counterOptions = counterOptions with { X = (((float)width > overlay.W) ? Math.Clamp((num - _grabX) / ((float)width - overlay.W), 0f, 1f) : 0f), Y = (((float)height > overlay.H) ? Math.Clamp((num2 - _grabY) / ((float)height - overlay.H), 0f, 1f) : 0f) }; } if (Captured == 16 && (down || drag || up)) { CounterOptions counterOptions2 = counterOptions with { WidthScale = _startWidth * (1f + (num - _resizeX) / _resizeW), HeightScale = _startHeight * (1f + (num2 - _resizeY) / _resizeH) }; CounterOptions counterOptions3 = counterOptions2.Normalize(); CounterRect counterRect = CounterLayout.Bounds(width, height, counterOptions3); counterOptions = counterOptions3 with { X = (((float)width > counterRect.W) ? Math.Clamp(_resizeLeft / ((float)width - counterRect.W), 0f, 1f) : 0f), Y = (((float)height > counterRect.H) ? Math.Clamp(_resizeTop / ((float)height - counterRect.H), 0f, 1f) : 0f) }; } if (up) { Enumerator<CounterControl> enumerator = panel.Controls.GetEnumerator(); try { while (enumerator.MoveNext()) { CounterControl current3 = enumerator.Current; if (current3.Id == Captured && current3.Rect.Contains(x, y)) { switch (Captured) { case 1: counterOptions = counterOptions with { Enabled = !counterOptions.Enabled }; break; case 2: counterOptions = counterOptions with { Horizontal = false }; break; case 3: counterOptions = counterOptions with { Horizontal = true }; break; case 7: counterOptions = counterOptions with { HideWhenPaused = !counterOptions.HideWhenPaused }; break; case 8: counterOptions = counterOptions with { HideOnScreenshot = !counterOptions.HideOnScreenshot }; break; case 9: counterOptions = counterOptions with { X = 0.02f, Y = 0.35f, Scale = 1f, WidthScale = 1f, HeightScale = 1f }; break; case 10: close = true; break; case 12: RefreshRequested = true; break; case 13: counterOptions = counterOptions with { BreakOnRight = !counterOptions.BreakOnRight }; break; case 17: ShortcutsRequested = true; break; case 4: case 5: case 6: case 11: case 14: case 15: case 16: break; } break; } } } finally { ((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } Cancel(); } return counterOptions; } } public sealed class CounterSettingsView { private readonly CounterView _painter = new CounterView { Depth = -31000 }; private readonly CounterView _previewPainter = new CounterView { Depth = -31000 }; private readonly CounterEditor _editor = new CounterEditor(); private CounterPanel _panel; private CounterOptions _previous; private int _width; private int _height; private int _control; private int _bindingPressed; public CounterShortcuts Shortcuts; public bool Open; public void Close() { Open = false; _editor.Cancel(); _bindingPressed = 0; Shortcuts?.CloseEditor(); if (_control != 0 && GUIUtility.hotControl == _control) { GUIUtility.hotControl = 0; } _control = 0; } public CounterOptions Draw(CounterOptions o, JudgementCounts counts, ReferenceBackground background, out bool released) { //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Invalid comparison between Unknown and I4 //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Invalid comparison between Unknown and I4 //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Invalid comparison between Unknown and I4 //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Invalid comparison between Unknown and I4 //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Invalid comparison between Unknown and I4 //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Invalid comparison between Unknown and I4 //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Invalid comparison between Unknown and I4 released = false; if (_panel == null || _previous != o || _width != Screen.width || _height != Screen.height) { _previous = o; _width = Screen.width; _height = Screen.height; _panel = CounterPanel.Create(o, _width, _height); } CounterViewport counterViewport = CounterViewport.Create(_width, _height, _panel.Bounds); _painter.DrawPlan(new CounterInk[1] { new CounterInk(0f, 0f, _width, _height, 101587199u) }); background.Draw(counterViewport, -31000); _previewPainter.Draw(counts, ready: true, o.Scale, o.X, o.Y, o.Horizontal, counterViewport, o.BreakOnRight, o.WidthScale, o.HeightScale); CounterRect counterRect = CounterLayout.Bounds(_width, _height, o); _painter.DrawPlan(new CounterInk[2] { new CounterInk(counterRect.X + counterRect.W - 14f / counterViewport.Zoom, counterRect.Y + counterRect.H - 3f / counterViewport.Zoom, 14f / counterViewport.Zoom, 3f / counterViewport.Zoom, 2464017407u), new CounterInk(counterRect.X + counterRect.W - 3f / counterViewport.Zoom, counterRect.Y + counterRect.H - 14f / counterViewport.Zoom, 3f / counterViewport.Zoom, 14f / counterViewport.Zoom, 2464017407u) }, counterViewport); _painter.DrawPlan(new CounterInk[1] { new CounterInk(18f, 30f, _panel.Bounds.X - 30f, 24f, 3084708607u, "游戏截图定位预览 · 拖动统计框即可调整", Math.Max(10, (int)((float)_height / 1080f * 16f))) }); CounterShortcuts shortcuts = Shortcuts; if (shortcuts != null && shortcuts.EditorOpen) { DrawBindings(); return o; } Event current = Event.current; int controlID = GUIUtility.GetControlID(704118, (FocusType)2); if (current != null) { bool flag = (int)current.type == 0 && current.button == 0; bool flag2 = (int)current.type == 1 && current.button == 0; bool drag = (int)current.type == 3; bool flag3 = _editor.Captured != 0; o = _editor.Handle(_panel, CounterLayout.Bounds(_width, _height, o), o, _width, _height, current.mousePosition.x, current.mousePosition.y, flag, drag, flag2, out var close, counterViewport); if (flag && _editor.Captured != 0) { _control = controlID; GUIUtility.hotControl = controlID; } if (flag2 && flag3) { if (GUIUtility.hotControl == _control) { GUIUtility.hotControl = 0; } _control = 0; released = true; } if (((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6 || (int)current.type == 4 || (int)current.type == 5) && (flag3 || _editor.Captured != 0 || Open)) { current.Use(); } if (close) { released = true; Close(); } if (_editor.RefreshRequested) { _editor.RefreshRequested = false; background.Reload(); } if (_editor.ShortcutsRequested) { _editor.ShortcutsRequested = false; _editor.Cancel(); Shortcuts?.OpenEditor(); } } _painter.DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)_panel.Ink); return o; } private void DrawBindings() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_0062: 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) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Invalid comparison between Unknown and I4 //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Invalid comparison between Unknown and I4 //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Invalid comparison between Unknown and I4 //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Invalid comparison between Unknown and I4 //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Invalid comparison between Unknown and I4 CounterPanel counterPanel = CounterBindingPanel.Create(Shortcuts, _width, _height); Event current = Event.current; int controlID = GUIUtility.GetControlID(704119, (FocusType)2); if (current != null) { bool num = (int)current.type == 0 && current.button == 0; bool flag = (int)current.type == 1 && current.button == 0; if (num) { Enumerator<CounterControl> enumerator = counterPanel.Controls.GetEnumerator(); try { while (enumerator.MoveNext()) { CounterControl current2 = enumerator.Current; if (current2.Rect.Contains(current.mousePosition.x, current.mousePosition.y)) { _bindingPressed = current2.Id; _control = controlID; GUIUtility.hotControl = controlID; break; } } } finally { ((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } if (flag) { Enumerator<CounterControl> enumerator = counterPanel.Controls.GetEnumerator(); try { while (enumerator.MoveNext()) { CounterControl current3 = enumerator.Current; if (current3.Id != _bindingPressed || !current3.Rect.Contains(current.mousePosition.x, current.mousePosition.y)) { continue; } if (current3.Id == 104) { Shortcuts.CloseEditor(); } else if (current3.Id == 105) { Shortcuts.Cancel(); } else if (Shortcuts.Capturing < 0) { if (current3.Id == 101 || current3.Id == 102) { Shortcuts.Begin(current3.Id - 101); } if (current3.Id == 103) { Shortcuts.Reset(); } } break; } } finally { ((System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } _bindingPressed = 0; if (_control != 0 && GUIUtility.hotControl == _control) { GUIUtility.hotControl = 0; } _control = 0; } if ((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 3 || (int)current.type == 6 || (int)current.type == 4 || (int)current.type == 5) { current.Use(); } } _painter.DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)counterPanel.Ink); } public void Dispose() { Close(); _painter.Dispose(); _previewPainter.Dispose(); _panel = null; } } [Flags] public enum CounterModifiers : byte { None = 0, Ctrl = 1, Alt = 2, Shift = 4 } public readonly record struct CounterChord(int Key, CounterModifiers Modifiers = CounterModifiers.None) { public string Text => (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Ctrl) ? "Ctrl+" : "") + (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Alt) ? "Alt+" : "") + (((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Shift) ? "Shift+" : "") + Name(Key); public bool Allowed { get { if (Name(Key).Length > 0 && Key != 123 && ((uint)Modifiers & 0xFFFFFFF8u) == 0 && (!((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Alt) || (Key != 115 && Key != 9 && Key != 27 && Key != 32)) && (!((System.Enum)Modifiers).HasFlag((System.Enum)CounterModifiers.Ctrl) || Key != 27)) { if (Key == 46) { return (Modifiers & (CounterModifiers.Ctrl | CounterModifiers.Alt)) != (CounterModifiers.Ctrl | CounterModifiers.Alt); } return true; } return false; } } public static bool Modifier(int key) { switch (key) { case 16: case 17: case 18: case 91: case 92: case 160: case 161: case 162: case 163: case 164: case 165: return true; default: return false; } } public static string Name(int key) { switch (key) { case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: return ((char)key).ToString(); case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: return ((char)key).ToString(); case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135: return "F" + (key - 111).ToString((IFormatProvider)(object)CultureInfo.InvariantCulture); case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: return "Num" + (key - 96).ToString((IFormatProvider)(object)CultureInfo.InvariantCulture); case 8: return "Backspace"; case 9: return "Tab"; case 13: return "Enter"; case 32: return "Space"; case 33: return "PageUp"; case 34: return "PageDown"; case 35: return "End"; case 36: return "Home"; case 37: return "Left"; case 38: return "Up"; case 39: return "Right"; case 40: return "Down"; case 45: return "Insert"; case 46: return "Delete"; case 106: return "NumMultiply"; case 107: return "NumAdd"; case 109: return "NumSubtract"; case 110: return "NumDecimal"; case 111: return "NumDivide"; case 186: return "Semicolon"; case 187: return "Equals"; case 188: return "Comma"; case 189: return "Minus"; case 190: return "Period"; case 191: return "Slash"; case 192: return "Backquote"; case 219: return "LeftBracket"; case 220: return "Backslash"; case 221: return "RightBracket"; case 222: return "Quote"; default: return ""; } } public static bool TryParse(string text, out CounterChord result) { int num = 0; CounterModifiers counterModifiers = CounterModifiers.None; result = default(CounterChord); if (string.IsNullOrWhiteSpace(text)) { return false; } string[] array = text.Split('+', (StringSplitOptions)0); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); CounterModifiers counterModifiers2 = ((text2.Equals("Ctrl", (StringComparison)5) || text2.Equals("Control", (StringComparison)5)) ? CounterModifiers.Ctrl : (text2.Equals("Alt", (StringComparison)5) ? CounterModifiers.Alt : (text2.Equals("Shift", (StringComparison)5) ? CounterModifiers.Shift : CounterModifiers.None))); if (counterModifiers2 != CounterModifiers.None) { if ((counterModifiers & counterModifiers2) != CounterModifiers.None) { return false; } counterModifiers |= counterModifiers2; continue; } if (num != 0 || text2.Length == 0) { return false; } for (int j = 8; j < 256; j++) { if (text2.Equals(Name(j), (StringComparison)5)) { num = j; break; } } if (num == 0) { return false; } } result = new CounterChord(num, counterModifiers); return result.Allowed; } [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterChord"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Key = "); builder.Append(((object)Key/*cast due to .constrained prefix*/).ToString()); builder.Append(", Modifiers = "); builder.Append(((object)Modifiers/*cast due to .constrained prefix*/).ToString()); builder.Append(", Text = "); builder.Append((object)Text); builder.Append(", Allowed = "); builder.Append(((object)Allowed/*cast due to .constrained prefix*/).ToString()); return true; } } public sealed class CounterShortcuts { private readonly Func<int, bool> _read; private readonly Func<CounterChord[], bool> _save; private readonly CounterChord[] _bindings = new CounterChord[2] { new CounterChord(115), new CounterChord(115, CounterModifiers.Shift) }; private readonly bool[] _keys = new bool[256]; private readonly bool[] _last = new bool[256]; private bool _release = true; private bool _focused; private int _phase; private CounterChord _candidate; [field: CompilerGenerated] public bool EditorOpen { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] public int Capturing { [CompilerGenerated] get; [CompilerGenerated] private set; } = -1; [field: CompilerGenerated] public bool CloseRequested { [CompilerGenerated] get; [CompilerGenerated] private set; } [field: CompilerGenerated] public string Message { [CompilerGenerated] get; [CompilerGenerated] private set; } = "支持 Ctrl / Alt / Shift + 一个主键。"; private CounterModifiers Mods => (CounterModifiers)((_keys[17] ? 1 : 0) | (_keys[18] ? 2 : 0) | (_keys[16] ? 4 : 0)); public static CounterChord Default(int i) { return new CounterChord(115, (i == 1) ? CounterModifiers.Shift : CounterModifiers.None); } public CounterChord Binding(int i) { return _bindings[i]; } public string Label(int i) { if (i != Capturing) { return _bindings[i].Text; } if (_phase != 2) { return "等待按键…"; } return _candidate.Text; } public CounterShortcuts(Func<int, bool> read = null, Func<CounterChord[], bool> save = null) { _read = read; _save = save; } public void Load(string panel, string visibility) { _bindings[0] = (CounterChord.TryParse(panel, out var result) ? result : Default(0)); _bindings[1] = (CounterChord.TryParse(visibility, out var result2) ? result2 : Default(1)); if (_bindings[0] == _bindings[1]) { _bindings[0] = Default(0); _bindings[1] = Default(1); } _release = true; } public void OpenEditor() { EditorOpen = true; Cancel(); Message = "点击对应按键修改;请避免与其他模组重合。"; } public void CloseEditor() { EditorOpen = false; Cancel(); } public void Cancel() { Capturing = -1; _phase = 0; _candidate = default(CounterChord); _release = true; } public void Begin(int i) { if (EditorOpen && i >= 0 && i <= 1) { Capturing = i; _phase = 0; _release = true; Message = "先松开旧按键,再按新组合,全部松开后保存。"; } } private bool Save(CounterChord[] bindings) { try { return _save?.Invoke(bindings) ?? true; } catch { return false; } } public bool Reset() { if (Capturing >= 0) { return false; } CounterChord[] array = new CounterChord[2] { Default(0), Default(1) }; if (!Save(array)) { Message = "保存失败,原绑定保留。"; return false; } System.Array.Copy((System.Array)array, (System.Array)_bindings, 2); Cancel(); Message = "已恢复 F4 / Shift+F4。"; return true; } public int Poll(bool focused, bool editable, bool panelOpen) { CloseRequested = false; if (!focused) { Cancel(); _focused = false; return -1; } if (_read == null) { return -1; } bool flag = EditorOpen || _release; System.Array.Clear((System.Array)_keys, 0, 256); bool flag2 = false; for (int i = 8; i < 256; i++) { if (flag || i == 16 || i == 17 || i == 18 || i == 27 || i == 91 || i == 92 || i == _bindings[0].Key || i == _bindings[1].Key) { _keys[i] = _read.Invoke(i); flag2 |= _keys[i]; } } try { if (!_focused) { _focused = true; _release = true; } if (EditorOpen && !editable) { CloseEditor(); return -1; } if (_keys[27] && !_last[27]) { if (Capturing >= 0) { Cancel(); Message = "已取消,原绑定保留。"; } else if (EditorOpen) { CloseEditor(); } else if (panelOpen) { CloseRequested = true; _release = true; } return -1; } if (EditorOpen) { if (Capturing >= 0) { Capture(flag2); } else if (!flag2) { _release = false; } return -1; } if (_release) { if (!flag2) { _release = false; } return -1; } if (_keys[91] || _keys[92]) { return -1; } for (int j = 0; j < 2; j++) { if (_keys[_bindings[j].Key] && !_last[_bindings[j].Key] && Mods == _bindings[j].Modifiers) { return j; } } return -1; } finally { System.Array.Copy((System.Array)_keys, (System.Array)_last, 256); } } private void Capture(bool any) { if (_phase == 0) { if (!any) { _phase = 1; } return; } int key = 0; int num = 0; for (int i = 8; i < 256; i++) { if (_keys[i] && !_last[i] && !CounterChord.Modifier(i)) { key = i; num++; } } if (_phase == 2) { if (num > 0) { _phase = 0; Message = "一次只按一个主键,松键后重试。"; } else if (!any) { CounterChord[] array = (CounterChord[])((System.Array)_bindings).Clone(); array[Capturing] = _candidate; bool flag = Save(array); if (flag) { System.Array.Copy((System.Array)array, (System.Array)_bindings, 2); } Cancel(); Message = (flag ? "绑定已保存。" : "保存失败,原绑定保留。"); } } else if (num != 0) { CounterChord counterChord = new CounterChord(key, Mods); if (num != 1 || _keys[91] || _keys[92] || !counterChord.Allowed) { _phase = 0; Message = "该组合保留或不可用,松键后重试。"; } else if (counterChord == _bindings[1 - Capturing]) { _phase = 0; Message = "与另一功能重复,松键后重试。"; } else { _candidate = counterChord; _phase = 2; Message = "已识别,松开全部按键后保存。"; } } } } public sealed class CounterView { private GUIStyle _style; private readonly SafeGuiTexture _texturePainter = new SafeGuiTexture(); private Font _font; private List<CounterInk> _plan; private JudgementCounts _previous; public int Depth = -9000; private int _width; private int _height; private float _scale; private float _x; private float _y; private float _widthScale; private float _heightScale; private bool _ready; private bool _horizontal; private bool _breakOnRight; public void Draw(JudgementCounts counts, bool ready, float scale, float x, float y, bool horizontal = false, CounterViewport? preview = null, bool breakOnRight = false, float widthScale = 1f, float heightScale = 1f) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 Event current = Event.current; if (current != null && (int)current.type == 7 && Screen.width >= 1 && Screen.height >= 1) { if (_plan == null || counts != _previous || ready != _ready || _width != Screen.width || _height != Screen.height || _scale != scale || _x != x || _y != y || _horizontal != horizontal || _breakOnRight != breakOnRight || _widthScale != widthScale || _heightScale != heightScale) { _previous = counts; _ready = ready; _width = Screen.width; _height = Screen.height; _scale = scale; _x = x; _y = y; _horizontal = horizontal; _breakOnRight = breakOnRight; _widthScale = widthScale; _heightScale = heightScale; _plan = CounterLayout.Create(counts, _width, _height, scale, x, y, ready, horizontal, breakOnRight, widthScale, heightScale); } DrawPlan((System.Collections.Generic.IReadOnlyList<CounterInk>)_plan, preview); } } public void DrawPlan(System.Collections.Generic.IReadOnlyList<CounterInk> plan, CounterViewport? preview = null) { //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_009e: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) Event current = Event.current; if (current == null || (int)current.type != 7) { return; } if (_style == null) { _font = new Font(); Font.Internal_CreateDynamicFont(_font, new Il2CppStringArray(new string[3] { "Bahnschrift", "Microsoft YaHei UI", "Arial" }), 20); _style = new GUIStyle { font = _font, fontStyle = (FontStyle)0, wordWrap = false, clipping = (TextClipping)1 }; _style.normal.textColor = Color.white; } Color color = GUI.color; int depth = GUI.depth; try { GUI.depth = Depth; System.Collections.Generic.IEnumerator<CounterInk> enumerator = ((System.Collections.Generic.IEnumerable<CounterInk>)plan).GetEnumerator(); try { Rect val = default(Rect); while (((System.Collections.IEnumerator)enumerator).MoveNext()) { CounterInk current2 = enumerator.Current; GUI.color = new Color((float)(current2.Color >> 24) / 255f, (float)((current2.Color >> 16) & 0xFF) / 255f, (float)((current2.Color >> 8) & 0xFF) / 255f, (float)(current2.Color & 0xFF) / 255f); ((Rect)(ref val))..ctor(current2.X, current2.Y, current2.W, current2.H); float num = preview?.Zoom ?? 1f; if (preview.HasValue) { CounterViewport value = preview.Value; ((Rect)(ref val))..ctor(value.Rect.X + current2.X * num, value.Rect.Y + current2.Y * num, current2.W * num, current2.H * num); } if (current2.Text.Length == 0) { _texturePainter.Draw(val, Texture2D.whiteTexture); continue; } _style.fontSize = Math.Max(1, (int)Math.Round((double)((float)current2.Size * num))); _style.alignment = (TextAnchor)(current2.Right ? 5 : 3); GUI.Label(val, current2.Text, _style); } } finally { ((System.IDisposable)enumerator)?.Dispose(); } } finally { GUI.color = color; GUI.depth = depth; } } public void Dispose() { _texturePainter.Release(); if ((Object)(object)_font != (Object)null) { Object.Destroy((Object)(object)_font); } _font = null; _style = null; _plan = null; } } public readonly record struct CounterViewport(CounterRect Rect, float Zoom) { public static CounterViewport Create(int width, int height, CounterRect panel) { float num = Math.Max(1f, panel.X - 36f); float num2 = Math.Max(1, height - 110); float num3 = Math.Min(num / (float)width, num2 / (float)height); return new CounterViewport(new CounterRect(18f + (num - (float)width * num3) * 0.5f, 66f + (num2 - (float)height * num3) * 0.5f, (float)width * num3, (float)height * num3), num3); } public float OutputX(float x) { return (x - Rect.X) / Zoom; } public float OutputY(float y) { return (y - Rect.Y) / Zoom; } [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("CounterViewport"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Rect = "); builder.Append(((object)Rect/*cast due to .constrained prefix*/).ToString()); builder.Append(", Zoom = "); builder.Append(((object)Zoom/*cast due to .constrained prefix*/).ToString()); return true; } } [StructLayout((LayoutKind)2, Size = 40)] public struct JudgementRecord { [FieldOffset(0)] public long Id; [FieldOffset(16)] public double AbsoluteMs; [FieldOffset(32)] public byte Result; [FieldOffset(33)] public byte Finalized; } public readonly record struct JudgementCounts(int Exact, int EarlyExact, int LateExact, int EarlyNear, int LateNear, int Break) { public int SmallExact => EarlyExact + LateExact; public int Near => EarlyNear + LateNear; public int Total => Exact + SmallExact + Near + Break; public static JudgementCounts Read(System.ReadOnlySpan<JudgementRecord> records) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; System.ReadOnlySpan<JudgementRecord> readOnlySpan = records; for (int i = 0; i < readOnlySpan.Length; i++) { ref JudgementRecord reference = readOnlySpan[i]; if (reference.Finalized != 0) { switch (reference.Result) { case 1: num6++; break; case 2: num4++; break; case 3: num5++; break; case 4: num2++; break; case 5: num3++; break; case 6: num++; break; } } } return new JudgementCounts(num, num2, num3, num4, num5, num6); } [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("JudgementCounts"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Exact = "); builder.Append(((object)Exact/*cast due to .constrained prefix*/).ToString()); builder.Append(", EarlyExact = "); builder.Append(((object)EarlyExact/*cast due to .constrained prefix*/).ToString()); builder.Append(", LateExact = "); builder.Append(((object)LateExact/*cast due to .constrained prefix*/).ToString()); builder.Append(", EarlyNear = "); builder.Append(((object)EarlyNear/*cast due to .constrained prefix*/).ToString()); builder.Append(", LateNear = "); builder.Append(((object)LateNear/*cast due to .constrained prefix*/).ToString()); builder.Append(", Break = "); builder.Append(((object)Break/*cast due to .constrained prefix*/).ToString()); builder.Append(", SmallExact = "); builder.Append(((object)SmallExact/*cast due to .constrained prefix*/).ToString()); builder.Append(", Near = "); builder.Append(((object)Near/*cast due to .constrained prefix*/).ToString()); builder.Append(", Total = "); builder.Append(((object)Total/*cast due to .constrained prefix*/).ToString()); return true; } } public readonly record struct RgbaImage(int Width, int Height, byte[] Pixels) { [CompilerGenerated] public override string ToString() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown StringBuilder val = new StringBuilder(); val.Append("RgbaImage"); val.Append(" { "); if (PrintMembers(val)) { val.Append(' '); } val.Append('}'); return ((object)val).ToString(); } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Width = "); builder.Append(((object)Width/*cast due to .constrained prefix*/).ToString()); builder.Append(", Height = "); builder.Append(((object)Height/*cast due to .constrained prefix*/).ToString()); builder.Append(", Pixels = "); builder.Append((object)Pixels); return true; } } public static class LocalImageCodec { private struct Startup { public uint Version; public System.IntPtr Callback; public int Thread; public int Codecs; } private struct Area { public int X; public int Y; public int Width; public int Height; } private struct BitmapData { public uint Width; public uint Height; public int Stride; public int Format; public System.IntPtr Pixels; public System.IntPtr Reserved; } private static System.IntPtr _token; private static readonly object Gate = new object(); private const int Argb32 = 2498570; [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdiplusStartup(out System.IntPtr token, ref Startup input, System.IntPtr output); [DllImport("gdiplus.dll", CharSet = (CharSet)3, ExactSpelling = true)] private static extern int GdipCreateBitmapFromFile(string path, out System.IntPtr image); [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdipGetImageWidth(System.IntPtr image, out uint width); [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdipGetImageHeight(System.IntPtr image, out uint height); [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdipBitmapLockBits(System.IntPtr image, ref Area area, uint flags, int format, ref BitmapData data); [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdipBitmapUnlockBits(System.IntPtr image, ref BitmapData data); [DllImport("gdiplus.dll", ExactSpelling = true)] private static extern int GdipDisposeImage(System.IntPtr image); private static void Check(int status) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (status != 0) { throw new IOException("PNG codec status " + status); } } public static RgbaImage Load(string path) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) lock (Gate) { if (_token == System.IntPtr.Zero) { Startup input = new Startup { Version = 1u }; Check(GdiplusStartup(out _token, ref input, System.IntPtr.Zero)); } Check(GdipCreateBitmapFromFile(path, out var image)); try { Check(GdipGetImageWidth(image, out var width)); Check(GdipGetImageHeight(image, out var height)); if (width == 0 || height == 0 || width > 8192 || height > 8192 || (long)width * (long)height > 16000000) { throw new IOException("Invalid reference screenshot dimensions"); } int num = (int)width; int num2 = (int)height; Area area = new Area { Width = num, Height = num2 }; BitmapData data = default(BitmapData); Check(GdipBitmapLockBits(image, ref area, 1u, 2498570, ref data)); try { byte[] array = new byte[checked(num * num2 * 4)]; byte[] array2 = new byte[num * 4]; for (int i = 0; i < num2; i++) { Marshal.Copy(System.IntPtr.Add(data.Pixels, i * data.Stride), array2, 0, array2.Length); int num3 = (num2 - 1 - i) * num * 4; for (int j = 0; j < array2.Length; j += 4) { array[num3 + j] = array2[j + 2]; array[num3 + j + 1] = array2[j + 1]; array[num3 + j + 2] = array2[j]; array[num3 + j + 3] = array2[j + 3]; } } return new RgbaImage(num, num2, array); } finally { GdipBitmapUnlockBits(image, ref data); } } finally { GdipDisposeImage(image); } } } public static RgbaImage Fit(RgbaImage image, int maxWidth) { if (image.Width <= maxWidth) { return image; } int num = Math.Max(1, (int)Math.Round((double)image.Height * (double)maxWidth / (double)image.Width)); byte[] array = new byte[checked(maxWidth * num * 4)]; for (int i = 0; i < num; i++) { for (int j = 0; j < maxWidth; j++) { int num2 = ((int)((long)i * (long)image.Height / num) * image.Width + (int)((long)j * (long)image.Width / maxWidth)) * 4; int num3 = (i * maxWidth + j) * 4; array[num3] = image.Pixels[num2]; array[num3 + 1] = image.Pixels[num2 + 1]; array[num3 + 2] = image.Pixels[num2 + 2]; array[num3 + 3] = image.Pixels[num2 + 3]; } } return new RgbaImage(maxWidth, num, array); } public static byte[] Encode(RgbaImage image) { //IL_0035: 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_0041: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (image.Width <= 0 || image.Height <= 0 || image.Pixels.Length != checked(image.Width * image.Height * 4)) { throw new ArgumentException("Invalid RGBA frame"); } MemoryStream val = new MemoryStream(); try { ((Stream)val).Write((System.ReadOnlySpan<byte>)new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }); byte[] array = new byte[13]; BinaryPrimitives.WriteInt32BigEndian(System.Span<byte>.op_Implicit(array), image.Width); BinaryPrimitives.WriteInt32BigEndian(MemoryExtensions.AsSpan<byte>(array, 4), image.Height); array[8] = 8; array[9] = 6; Chunk((Stream)(object)val, "IHDR", array); MemoryStream val2 = new MemoryStream(); try { ZLibStream val3 = new ZLibStream((Stream)(object)val2, (CompressionLevel)1, true); try { for (int num = image.Height - 1; num >= 0; num--) { ((Stream)val3).WriteByte((byte)0); ((Stream)val3).Write(image.Pixels, num * image.Width * 4, image.Width * 4); } } finally { ((System.IDisposable)val3)?.Dispose(); } Chunk((Stream)(object)val, "IDAT", val2.ToArray()); Chunk((Stream)(object)val, "IEND", System.Array.Empty<byte>()); return val.ToArray(); } finally { ((System.IDisposable)val2)?.Dispose(); } } finally { ((System.IDisposable)val)?.Dispose(); } } private static void Chunk(Stream stream, string name, byte[] data) { System.Span<byte> span = stackalloc byte[4]; BinaryPrimitives.WriteInt32BigEndian(span, data.Length); stream.Write(System.Span<byte>.op_Implicit(span)); byte[] bytes = Encoding.ASCII.GetBytes(name); stream.Write(System.ReadOnlySpan<byte>.op_Implicit(bytes)); stream.Write(System.ReadOnlySpan<byte>.op_Implicit(data)); uint num = 4294967295u; byte[] array = bytes; foreach (byte value in array) { num = ByteCrc(num, value); } array = data; foreach (byte value2 in array) { num = ByteCrc(num, value2); } BinaryPrimitives.WriteUInt32BigEndian(span, ~num); stream.Write(System.Span<byte>.op_Implicit(span)); } private static uint ByteCrc(uint crc, byte value) { crc ^= value; for (int i = 0; i < 8; i++) { crc = (crc >> 1) ^ (uint)(((crc & 1) != 0) ? (-306674912) : 0); } return crc; } } internal static class NativeInputBarrier { private static IDetour _detour; private static NativeInputDispatch _dispatch; internal unsafe static void Install() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (_detour != null) { throw new InvalidOperationException("Input barrier already prepared"); } if ((int)RuntimeInformation.ProcessArchitecture != 1) { throw new PlatformNotSupportedException("Requires Windows x64 input ABI"); } MethodInfo method = typeof(InputManager).GetMethod("ProcessEventOnInputReceiver"); if (method == (MethodInfo)null || ((MethodBase)method).IsStatic || ((MethodBase)method).GetParameters().Length != 6) { throw new MissingMethodException("Unexpected native input signature"); } Patches patchInfo = Harmony.GetPatchInfo((MethodBase)(object)method); if (patchInfo != null && patchInfo.Owners.Count > 0) { throw new InvalidOperationException("Input dispatch already patched by another owner"); } System.IntPtr intPtr = IL2CPP.il2cpp_class_get_method_from_name(Il2CppClassPointerStore<InputManager>.NativeClassPtr, "ProcessEventOnInputReceiver", 6); if (intPtr == System.IntPtr.Zero) { throw new MissingMethodException("Native input dispatch missing"); } INativeMethodInfoStruct val = UnityVersionHandler.Wrap((Il2CppMethodInfo*)(void*)intPtr); if (val.ParametersCount != 6 || val.MethodPointer == System.IntPtr.Zero) { throw new MissingMethodException("Unexpected native dispatch metadata"); } _dispatch = new NativeInputDispatch(CounterBehaviour.AllowNativeDispatch, CounterBehaviour.InputBarrierFailed); try { _detour = Il2CppInteropRuntime.Instance.DetourProvider.Create<NativeDispatchCall>(val.MethodPointer, _dispatch.Callback); _dispatch.Attach(_detour.GenerateTrampoline<NativeDispatchCall>()); _detour.Apply(); _dispatch.Enable(); } catch { _dispatch.Disable(); throw; } } } [UnmanagedFunctionPointer(/*Could not decode attribute arguments.*/)] public delegate void NativeDispatchCall(System.IntPtr owner, System.IntPtr pair, System.IntPtr inputEvent, System.IntPtr consumed, System.IntPtr modifiers, System.IntPtr mouse, System.IntPtr delta, System.IntPtr method); public sealed class NativeInputDispatch { private readonly Func<bool> _allowed; private readonly Action<System.Exception> _fault; private NativeDispatchCall _original; private bool _enabled; private bool _failed; public readonly NativeDispatchCall Callback; public NativeInputDispatch(Func<bool> allowed, Action<System.Exception> fault = null) { _allowed = allowed; _fault = fault; Callback = Invoke; } public void Attach(NativeDispatchCall original) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) _original = original ?? throw new ArgumentNullException("original"); } public void Enable() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (_original == null) { throw new InvalidOperationException("Original dispatch is not ready"); } _enabled = true; } public void Disable() { _enabled = false; } private void Invoke(System.IntPtr owner, System.IntPtr pair, System.IntPtr inputEvent, System.IntPtr consumed, System.IntPtr modifiers, System.IntPtr mouse, System.IntPtr delta, System.IntPtr method) { NativeDispatchCall original = _original; if (original == null) { return; } bool flag = true; if (_enabled && !_failed) { try { flag = _allowed?.Invoke() ?? true; } catch (System.Exception ex) { _failed = true; try { _fault?.Invoke(ex); } catch { } } } if (!flag) { if (consumed != System.IntPtr.Zero) { Marshal.WriteByte(consumed, (byte)1); } } else { original(owner, pair, inputEvent, consumed, modifiers, mouse, delta, method); } } } [BepInPlugin("skyfrozen.infalsus.judgementcounter", "In Falsus Judgement Counter", "1.0.1")] public sealed class Plugin : BasePlugin { internal static ManualLogSource Logger; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> Horizontal; internal static ConfigEntry<bool> BreakOnRight; internal static ConfigEntry<bool> HideOnScreenshot; internal static ConfigEntry<bool> HideWhenPaused; internal static ConfigEntry<float> Scale; internal static ConfigEntry<float> PositionX; internal static ConfigEntry<float> PositionY; internal static ConfigEntry<float> WidthScale; internal static ConfigEntry<float> HeightScale; internal static ConfigEntry<string> PanelKey; internal static ConfigEntry<string> VisibilityKey; internal static bool InputBlockReady; private static ConfigFile _settings; internal static CounterOptions Options { get { CounterOptions result = new CounterOptions(Enabled.Value, Horizontal.Value, PositionX.Value, PositionY.Value, Scale.Value, HideWhenPaused.Value, HideOnScreenshot.Value); result.BreakOnRight = BreakOnRight.Value; result.WidthScale = WidthScale.Value; result.HeightScale = HeightScale.Value; return result; } } internal static void Apply(CounterOptions value) { CounterOptions counterOptions = value.Normalize(); Enabled.Value = counterOptions.Enabled; Horizontal.Value = counterOptions.Horizontal; BreakOnRight.Value = counterOptions.BreakOnRight; PositionX.Value = counterOptions.X; PositionY.Value = counterOptions.Y; Scale.Value = counterOptions.Scale; WidthScale.Value = counterOptions.WidthScale; HeightScale.Value = counterOptions.HeightScale; HideWhenPaused.Value = counterOptions.HideWhenPaused; HideOnScreenshot.Value = counterOptions.HideOnScreenshot; } internal static void Save() { _settings.Save(); } internal static bool SaveBindings(CounterChord[] bindings) { string value = PanelKey.Value; string value2 = VisibilityKey.Value; try { PanelKey.Value = bindings[0].Text; VisibilityKey.Value = bindings[1].Text; _settings.Save(); return true; } catch (System.Exception ex) { PanelKey.Value = value; VisibilityKey.Value = value2; Logger.LogWarning((object)("Shortcut save failed: " + ex.Message)); return false; } } public override void Load() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Expected O, but got Unknown //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Expected O, but got Unknown //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Expected O, but got Unknown //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Expected O, but got Unknown //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Expected O, but got Unknown //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Expected O, but got Unknown //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missin