From c7714b8e3d4c604c3e4160f0c85e3a8332087be2 Mon Sep 17 00:00:00 2001 From: Starrah Date: Tue, 3 Feb 2026 01:57:49 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20PracticeMode=E5=9C=A81.55=E4=BB=A5?= =?UTF-8?q?=E4=B8=8A=EF=BC=8C=E9=83=A8=E5=88=86=E7=89=B9=E6=80=A7=E4=B8=8D?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 具体而言: 1. 1.55以上,MovieController._moviePlayers的定义发生改变,从对象变为List。 2. 先前的gameCtrl只是一个对象,但实际上对于1、2P会分别有两个GameCtrl对象。 3. 給SBGA擦屁股,GameCtrl.ResetOptionSpeed里都不对是否开启2P做一下校验的,1P运行时直接一个NPE抛出来了。 --- .../UX/PracticeMode/Libs/PractiseModeUI.cs | 2 +- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 36 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs b/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs index 8bd17b29..a4f23d97 100644 --- a/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs +++ b/AquaMai.Mods/UX/PracticeMode/Libs/PractiseModeUI.cs @@ -131,7 +131,7 @@ public void Update() else if (InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.E4)) { PracticeMode.keepNoteSpeed = !PracticeMode.keepNoteSpeed; - PracticeMode.gameCtrl?.ResetOptionSpeed(); + PracticeMode.GameCtrlResetOptionSpeed(); } else if ( InputManager.GetTouchPanelAreaDown(InputManager.TouchPanelArea.A1) || diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index 762377b0..1a4a82c3 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -12,7 +12,6 @@ using Monitor; using Monitor.Game; using Process; -using UnityEngine; using AquaMai.Config.Attributes; using AquaMai.Config.Types; using AquaMai.Core.Attributes; @@ -40,8 +39,8 @@ public class PracticeMode public static double repeatEnd = -1; public static float speed = 1; private static CriAtomExPlayer player; - private static MovieMaterialMai2 movie; - public static GameCtrl gameCtrl; + private static List movie; + private static GameCtrl[] gameCtrl = new GameCtrl[2]; public static bool keepNoteSpeed = false; public static void SetRepeatEnd(double time) @@ -67,14 +66,29 @@ public static void ClearRepeat() repeatEnd = -1; } + public static void GameCtrlResetOptionSpeed() + { + foreach (var g in gameCtrl) + { + try + { + g?.ResetOptionSpeed(); + } + catch (NullReferenceException) {} // 忽略即可,因为SBGA的代码在ResetOptionSpeed内部没有做null检查,单刷的时候对2P那侧这个函数必定会抛NPE + } + } + public static void SetSpeed() { player.SetPitch((float)(1200 * Math.Log(speed, 2))); // player.SetDspTimeStretchRatio(1 / speed); player.UpdateAll(); - - movie.player.SetSpeed(speed); - gameCtrl?.ResetOptionSpeed(); + + foreach (var m in movie) + { + m.player?.SetSpeed(speed); + } + GameCtrlResetOptionSpeed(); } private static IEnumerator SetSpeedCoroutineInner() @@ -195,7 +209,7 @@ public static void GameProcessPostRelease() [HarmonyPostfix] public static void GameCtrlPostInitialize(GameCtrl __instance) { - gameCtrl = __instance; + gameCtrl[__instance.MonitorIndex] =__instance; } # if DEBUG @@ -304,8 +318,12 @@ public static void SoundCtrlPostInitialize(SoundCtrl.InitParam param, Dictionary [HarmonyPatch(typeof(MovieController), "Awake")] [HarmonyPostfix] - public static void MovieControllerPostAwake(MovieMaterialMai2 ____moviePlayers) + public static void MovieControllerPostAwake(object ____moviePlayers) { - movie = ____moviePlayers; + // 1.55以上,_moviePlayers是List;1.50以下,___moviePlayers是MovieMaterialMai2。 + // 所以这里用object承接,再根据object的类型做具体处理 + if (____moviePlayers is List mList) movie = mList; + else if (____moviePlayers is MovieMaterialMai2 m) movie = new([m]); + else MelonLogger.Error("[PracticeMode] MovieControllerPostAwake: [BUG] 收到的____moviePlayers参数不正确"); } } \ No newline at end of file From 4962efff56748573172e7b67978ada92db06454f Mon Sep 17 00:00:00 2001 From: Starrah Date: Tue, 3 Feb 2026 16:05:45 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=8C=89gemini=E8=AF=B4=E7=9A=84=E5=81=9A?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B0=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index 1a4a82c3..a88dd98a 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -12,6 +12,7 @@ using Monitor; using Monitor.Game; using Process; +using UnityEngine; using AquaMai.Config.Attributes; using AquaMai.Config.Types; using AquaMai.Core.Attributes; @@ -84,10 +85,7 @@ public static void SetSpeed() // player.SetDspTimeStretchRatio(1 / speed); player.UpdateAll(); - foreach (var m in movie) - { - m.player?.SetSpeed(speed); - } + movie?.ForEach(m => m.player?.SetSpeed(speed)); GameCtrlResetOptionSpeed(); } @@ -326,4 +324,4 @@ public static void MovieControllerPostAwake(object ____moviePlayers) else if (____moviePlayers is MovieMaterialMai2 m) movie = new([m]); else MelonLogger.Error("[PracticeMode] MovieControllerPostAwake: [BUG] 收到的____moviePlayers参数不正确"); } -} \ No newline at end of file +}