From 2c0dac56ad10a68298ff12c09546bccfdf11cc3a Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 1 Feb 2026 18:17:47 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[O]=20DontRuinMyAccount=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=20(Fix=20#82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现在实现: 1. 判定表会被清空显示为全0(我认为这是最合理的,而不是转为全miss。不然就和开局直接trackskip的情况无法区分了。或者说“判定表全0”可以作为DontRuinMyAccount的标志) 2. 达成率、DX分、连击、同步、是否clear都是0/None 3. 自然的,isAchieveNewRecord和isDeluxscoreNewRecord就不可能为true,beforeRating/afterRating等肯定也保持不变。 --- AquaMai.Mods/UX/DontRuinMyAccount.cs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/AquaMai.Mods/UX/DontRuinMyAccount.cs b/AquaMai.Mods/UX/DontRuinMyAccount.cs index a8b3c986..48c69da7 100644 --- a/AquaMai.Mods/UX/DontRuinMyAccount.cs +++ b/AquaMai.Mods/UX/DontRuinMyAccount.cs @@ -107,13 +107,32 @@ public static void AfterResultProcessStart() ignoreScore = false; var musicid = GameManager.SelectMusicID[0]; var difficulty = GameManager.SelectDifficultyID[0]; + // current music playlog var score = Singleton.Instance.GetGameScore(0, (int)currentTrackNumber - 1); - // score.Achivement = 0; // Private setter, so reflection is essential - typeof(GameScoreList).GetProperty("Achivement", BindingFlags.Public | BindingFlags.Instance)?.GetSetMethod(true)?.Invoke(score, [0m]); - typeof(GameScoreList).GetProperty("ComboType", BindingFlags.Public | BindingFlags.Instance)?.GetSetMethod(true)?.Invoke(score, [PlayComboflagID.None]); - typeof(GameScoreList).GetProperty("NowComboType", BindingFlags.Public | BindingFlags.Instance)?.GetSetMethod(true)?.Invoke(score, [PlayComboflagID.None]); + var t = Traverse.Create(score); + // 设置各个成绩相关的字段,清零 + t.Property("Achivement").Value = 0m; + t.Property("ComboType").Value = PlayComboflagID.None; + t.Property("NowComboType").Value = PlayComboflagID.None; score.SyncType = PlaySyncflagID.None; + score.IsClear = false; + t.Property("DxScore").Value = 0u; + t.Property("MaxCombo").Value = 0u; + t.Property("MaxChain").Value = 0u; // 最大同步数 + // 把所有判定结果清零(直接把判定表清零,而不是转为miss) + t.Property("Fast").Value = 0u; + t.Property("Late").Value = 0u; + var judgeList = t.Field("_resultList").Value; + int rows = judgeList.GetLength(0), cols = judgeList.GetLength(1); + for (int r = 0; r < rows; r++) + { + for (int c = 0; c < cols; c++) + { + judgeList[r, c] = 0u; + } + } + // user's all scores var userData = Singleton.Instance.GetUserData(0); var userScoreDict = userData.ScoreDic[difficulty]; From 967dba358711409c9773078c2400b336d0cdeb2f Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 1 Feb 2026 18:57:49 +0800 Subject: [PATCH 2/5] =?UTF-8?q?refactor:=20DontRuinMyAccount=E4=B8=80?= =?UTF-8?q?=E7=82=B9=E5=B0=8F=E9=87=8D=E6=9E=84=EF=BC=8C=E5=8E=BB=E9=99=A4?= =?UTF-8?q?=E5=86=97=E4=BD=99=E4=BB=A3=E7=A0=81&=E6=8A=BD=E5=8F=96?= =?UTF-8?q?=E4=B8=80=E4=B8=AAtrigger=E5=87=BD=E6=95=B0=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/DontRuinMyAccount.cs | 33 ++++++++++------------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/AquaMai.Mods/UX/DontRuinMyAccount.cs b/AquaMai.Mods/UX/DontRuinMyAccount.cs index 48c69da7..45ae4a2a 100644 --- a/AquaMai.Mods/UX/DontRuinMyAccount.cs +++ b/AquaMai.Mods/UX/DontRuinMyAccount.cs @@ -1,5 +1,4 @@ using System; -using System.Reflection; using AquaMai.Config.Attributes; using AquaMai.Core.Attributes; using AquaMai.Core.Helpers; @@ -29,32 +28,22 @@ public class DontRuinMyAccount private static uint currentTrackNumber => GameManager.MusicTrackNumber; public static bool ignoreScore; private static UserScore oldScore; + + public static void trigger() + { + if (!(GameManager.IsInGame && !ignoreScore)) return; + // 对8号和10号门,永不启用防毁号(它们中用到了autoplay功能来模拟特殊谱面效果) + if (GameManager.IsKaleidxScopeMode && (Singleton.Instance.gateId == 8 || + Singleton.Instance.gateId == 10)) return; + ignoreScore = true; + MelonLogger.Msg("[DontRuinMyAccount] Triggered. Will ignore this score."); + } [HarmonyPatch(typeof(GameProcess), "OnUpdate")] [HarmonyPostfix] public static void OnUpdate() { - if (GameManager.IsInGame && GameManager.IsAutoPlay() && !ignoreScore) - { - if (GameManager.IsKaleidxScopeMode) - { - if (Singleton.Instance.gateId == 8 || - Singleton.Instance.gateId == 10) - { - ignoreScore = false; - } - else - { - ignoreScore = true; - MelonLogger.Msg("[DontRuinMyAccount] Autoplay triggered, will ignore this score."); - } - } - else - { - ignoreScore = true; - MelonLogger.Msg("[DontRuinMyAccount] Autoplay triggered, will ignore this score."); - } - } + if (GameManager.IsInGame && GameManager.IsAutoPlay()) trigger(); } [HarmonyPatch(typeof(GameProcess), "OnStart")] From bbf5d68c5e662a49ee60c6cb8a49d6f24d4e873f Mon Sep 17 00:00:00 2001 From: Starrah Date: Sun, 1 Feb 2026 19:21:54 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20DontRuinMyAccount=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20forPracticeMode(=E9=BB=98=E8=AE=A4=E4=B8=BAfalse)?= =?UTF-8?q?=EF=BC=8C=E4=BD=9C=E7=94=A8=E6=98=AF=E5=AF=B9PracticeMode/Debug?= =?UTF-8?q?Feature=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=B9=9F?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E9=98=B2=E6=AF=81=E5=8F=B7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Core/Resources/Locale.Designer.cs | 4 ++-- AquaMai.Core/Resources/Locale.resx | 2 +- AquaMai.Core/Resources/Locale.zh.resx | 2 +- AquaMai.Mods/Fix/DebugFeature.cs | 5 +++++ AquaMai.Mods/UX/DontRuinMyAccount.cs | 9 +++++++++ AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 1 + 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/AquaMai.Core/Resources/Locale.Designer.cs b/AquaMai.Core/Resources/Locale.Designer.cs index 97795c2f..0ab3bf5d 100644 --- a/AquaMai.Core/Resources/Locale.Designer.cs +++ b/AquaMai.Core/Resources/Locale.Designer.cs @@ -69,7 +69,7 @@ public static string AutoplayOn { } /// - /// Looks up a localized string similar to Autoplay was used, score will not be saved.. + /// Looks up a localized string similar to Autoplay/PracticeMode was used, score will not be saved.. /// public static string AutoplayWasUsed { get { @@ -227,7 +227,7 @@ public static string NextPlayShowTouchDisplay { /// Looks up a localized string similar to Did you double-click Sinmai.exe directly? That's not how it works. There should be something called "start.bat" or "启动.bat", and you need to use it to start. ///Check if your AMDaemon is still alive (look for a command line window called AMDaemon.exe running in the background). ///If the window has disappeared, then there might be some issues with your configuration. Please check your segatools.ini carefully. - ///Maybe the window is there, but it's constantly scrolling errors. If that's the case, then there might als [rest of string was truncated]";. + ///Maybe the window is there, but it's constantly scrolling errors. If that's the case, then there might [rest of string was truncated]";. /// public static string NoAmDaemonAlertMessage { get { diff --git a/AquaMai.Core/Resources/Locale.resx b/AquaMai.Core/Resources/Locale.resx index bbc60ebe..97c01eff 100644 --- a/AquaMai.Core/Resources/Locale.resx +++ b/AquaMai.Core/Resources/Locale.resx @@ -170,7 +170,7 @@ Press {2} to switch block or exit adjustment mode AutoPlay On - Autoplay was used, score will not be saved. + Autoplay/PracticeMode was used, score will not be saved. ==================================================================!!! diff --git a/AquaMai.Core/Resources/Locale.zh.resx b/AquaMai.Core/Resources/Locale.zh.resx index 93996943..0a2c4697 100644 --- a/AquaMai.Core/Resources/Locale.zh.resx +++ b/AquaMai.Core/Resources/Locale.zh.resx @@ -163,7 +163,7 @@ AutoPlay开启中 - Autoplay曾开启过,本曲成绩不会被上传。 + Autoplay或练习模式曾开启过,本曲成绩不会被上传。 =============================================!!! diff --git a/AquaMai.Mods/Fix/DebugFeature.cs b/AquaMai.Mods/Fix/DebugFeature.cs index 11dadff8..ae58c26a 100644 --- a/AquaMai.Mods/Fix/DebugFeature.cs +++ b/AquaMai.Mods/Fix/DebugFeature.cs @@ -2,6 +2,7 @@ using System.Reflection; using AquaMai.Config.Attributes; using AquaMai.Mods.GameSystem; +using AquaMai.Mods.UX; using HarmonyLib; using MAI2.Util; using Manager; @@ -118,6 +119,7 @@ public static bool Pause SoundManager.PauseMusic(value); GameMoviePause(value); NotesManager.Pause(value); + if (value) DontRuinMyAccount.triggerForPracticeMode(); } } @@ -132,6 +134,7 @@ public static void Seek(int msec) { _debugFeatureType.GetMethod("DebugTimeSkip", BindingFlags.Instance | BindingFlags.Public).Invoke(_debugFeatureOriginal, new object[] { msec }); } + DontRuinMyAccount.triggerForPracticeMode(); } public static double CurrentPlayMsec @@ -242,6 +245,7 @@ public static void Postfix(byte ____sequence) SoundManager.PauseMusic(isPause); GameMoviePause(isPause); NotesManager.Pause(isPause); + if (isPause) DontRuinMyAccount.triggerForPracticeMode(); } else if (DebugInput.GetKeyDown(KeyCode.LeftArrow) || DebugInput.GetKeyDown(KeyCode.RightArrow)) { @@ -261,6 +265,7 @@ public static void Postfix(byte ____sequence) : (num23 * 5)); Singleton.Instance.Initialize(); DebugTimeSkip(addMsec); + DontRuinMyAccount.triggerForPracticeMode(); } } } diff --git a/AquaMai.Mods/UX/DontRuinMyAccount.cs b/AquaMai.Mods/UX/DontRuinMyAccount.cs index 45ae4a2a..7d707dca 100644 --- a/AquaMai.Mods/UX/DontRuinMyAccount.cs +++ b/AquaMai.Mods/UX/DontRuinMyAccount.cs @@ -25,10 +25,19 @@ public class DontRuinMyAccount { [ConfigEntry(zh: "AutoPlay 激活后显示提示", en: "Show notice when AutoPlay is activated")] public static readonly bool showNotice = true; + [ConfigEntry(zh: "使用练习模式/DebugFeature相关功能也不保存成绩", en: "Also not save scores when using PracticeMode/DebugFeature")] + public static readonly bool forPracticeMode = false; + private static uint currentTrackNumber => GameManager.MusicTrackNumber; public static bool ignoreScore; private static UserScore oldScore; + // 当练习模式相关功能启动时,应当调用本函数 + public static void triggerForPracticeMode() + { + if (forPracticeMode) trigger(); + } + public static void trigger() { if (!(GameManager.IsInGame && !ignoreScore)) return; diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index 762377b0..0b67848c 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -75,6 +75,7 @@ public static void SetSpeed() movie.player.SetSpeed(speed); gameCtrl?.ResetOptionSpeed(); + DontRuinMyAccount.triggerForPracticeMode(); } private static IEnumerator SetSpeedCoroutineInner() From cbc12fc9c2778e02589bc0e76236bb1d712a063a Mon Sep 17 00:00:00 2001 From: Starrah Date: Mon, 2 Feb 2026 10:43:35 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E6=95=B0=E7=BB=84=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/DontRuinMyAccount.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/AquaMai.Mods/UX/DontRuinMyAccount.cs b/AquaMai.Mods/UX/DontRuinMyAccount.cs index 7d707dca..d48c9f0d 100644 --- a/AquaMai.Mods/UX/DontRuinMyAccount.cs +++ b/AquaMai.Mods/UX/DontRuinMyAccount.cs @@ -122,14 +122,7 @@ public static void AfterResultProcessStart() t.Property("Fast").Value = 0u; t.Property("Late").Value = 0u; var judgeList = t.Field("_resultList").Value; - int rows = judgeList.GetLength(0), cols = judgeList.GetLength(1); - for (int r = 0; r < rows; r++) - { - for (int c = 0; c < cols; c++) - { - judgeList[r, c] = 0u; - } - } + Array.Clear(judgeList, 0, judgeList.Length); // user's all scores var userData = Singleton.Instance.GetUserData(0); From 3034887aa8c492d4c69e2c0973d31597d910c188 Mon Sep 17 00:00:00 2001 From: Starrah Date: Tue, 3 Feb 2026 02:40:58 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=B0=86forPracticeMode=E7=9A=84=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=80=BC=E8=AE=BE=E7=BD=AE=E4=B8=BAtrue=20&=20?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E5=B0=8F=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AquaMai.Mods/UX/DontRuinMyAccount.cs | 26 +++++++++----------- AquaMai.Mods/UX/PracticeMode/PracticeMode.cs | 3 ++- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/AquaMai.Mods/UX/DontRuinMyAccount.cs b/AquaMai.Mods/UX/DontRuinMyAccount.cs index d48c9f0d..0f172249 100644 --- a/AquaMai.Mods/UX/DontRuinMyAccount.cs +++ b/AquaMai.Mods/UX/DontRuinMyAccount.cs @@ -26,8 +26,9 @@ public class DontRuinMyAccount [ConfigEntry(zh: "AutoPlay 激活后显示提示", en: "Show notice when AutoPlay is activated")] public static readonly bool showNotice = true; [ConfigEntry(zh: "使用练习模式/DebugFeature相关功能也不保存成绩", en: "Also not save scores when using PracticeMode/DebugFeature")] - public static readonly bool forPracticeMode = false; - + public static readonly bool forPracticeMode = true; + + private static bool Enabled = false; // 需要有一个flag来标记本模块是否被disable了,不然如果disable了本模块后,开练习模式时调用到triggerForPracticeMode还是触发了功能就不对了。 private static uint currentTrackNumber => GameManager.MusicTrackNumber; public static bool ignoreScore; private static UserScore oldScore; @@ -40,7 +41,7 @@ public static void triggerForPracticeMode() public static void trigger() { - if (!(GameManager.IsInGame && !ignoreScore)) return; + if (!(Enabled && !ignoreScore && GameManager.IsInGame)) return; // 对8号和10号门,永不启用防毁号(它们中用到了autoplay功能来模拟特殊谱面效果) if (GameManager.IsKaleidxScopeMode && (Singleton.Instance.gateId == 8 || Singleton.Instance.gateId == 10)) return; @@ -48,19 +49,16 @@ public static void trigger() MelonLogger.Msg("[DontRuinMyAccount] Triggered. Will ignore this score."); } - [HarmonyPatch(typeof(GameProcess), "OnUpdate")] - [HarmonyPostfix] - public static void OnUpdate() + public static void OnBeforePatch() { - if (GameManager.IsInGame && GameManager.IsAutoPlay()) trigger(); + Enabled = true; } - [HarmonyPatch(typeof(GameProcess), "OnStart")] + [HarmonyPatch(typeof(GameProcess), "OnUpdate")] [HarmonyPostfix] - [EnableIf(nameof(showNotice))] - public static void OnStart(GameMonitor[] ____monitors) + public static void OnUpdate() { - ____monitors[0].gameObject.AddComponent(); + if (GameManager.IsInGame && GameManager.IsAutoPlay()) trigger(); } [HarmonyPrefix] @@ -141,10 +139,10 @@ public static void AfterResultProcessStart() [HarmonyPostfix] [HarmonyPatch(typeof(GameProcess), nameof(GameProcess.OnStart))] - public static void OnGameStart() + public static void OnGameStart(GameMonitor[] ____monitors) { - // For compatibility with QuickRetry - ignoreScore = false; + ignoreScore = false; // For compatibility with QuickRetry + if (showNotice) ____monitors[0].gameObject.AddComponent(); } private class NoticeUI : MonoBehaviour diff --git a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs index 0b67848c..5ad2c821 100644 --- a/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs +++ b/AquaMai.Mods/UX/PracticeMode/PracticeMode.cs @@ -69,13 +69,14 @@ public static void ClearRepeat() public static void SetSpeed() { + DontRuinMyAccount.triggerForPracticeMode(); + player.SetPitch((float)(1200 * Math.Log(speed, 2))); // player.SetDspTimeStretchRatio(1 / speed); player.UpdateAll(); movie.player.SetSpeed(speed); gameCtrl?.ResetOptionSpeed(); - DontRuinMyAccount.triggerForPracticeMode(); } private static IEnumerator SetSpeedCoroutineInner()