mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-02-13 13:37:59 +08:00
[+] Configurable mod key map manager
This commit is contained in:
@@ -32,21 +32,6 @@ public class Config
|
||||
""")]
|
||||
public bool LoadAssetBundleWithoutManifest { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
Press key "7" for 1 second to skip to next step or restart current song
|
||||
Hold the bottom four buttons (3456) for official quick retry (non-utage only)
|
||||
""",
|
||||
zh: """
|
||||
长按 Service 键或者键盘上的 “7” 键(ADX 默认固件下箭头键中间的圆形按键)可以:
|
||||
- 跳过登录过程中的界面直接进入选歌界面
|
||||
- 在选歌界面直接结束游戏
|
||||
在游玩界面,按一下 “7” 或者 Service 键重开当前的歌,按 1P 的“选择”键立即结束当前乐曲
|
||||
打完最后一个音符之后也可以
|
||||
按住下方四个按钮(3456)使用官方快速重开(仅对非宴谱有效)
|
||||
""")]
|
||||
public bool QuickSkip { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
Random BGM, put Mai2Cue.{acb,awb} of old version of the game in `LocalAssets\Mai2Cue` and rename them
|
||||
@@ -90,22 +75,6 @@ public class Config
|
||||
""")]
|
||||
public bool LoadLocalBga { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: "Prevent accidental touch of the Test button, requires 1 second long press to take effect",
|
||||
zh: "防止你不小心按到 Test 键,Test 键需要长按 1 秒才能生效")]
|
||||
public bool TestProof { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
In the song selection screen, press the Service button or the "7" key (the round button in the middle of the arrow keys in the default ADX firmware) to toggle the display of self-made charts.
|
||||
A directory is considered to contain self-made charts if it does not have DataConfig.xml or OfficialChartsMark.txt in the Axxx directory.
|
||||
""",
|
||||
zh: """
|
||||
选歌界面按下 Service 键或者键盘上的 “7” 键(ADX 默认固件下箭头键中间的圆形按键)切换自制谱的显示和隐藏
|
||||
是否是自制谱的判断方式是 Axxx 目录里没有 DataConfig.xml 或 OfficialChartsMark.txt 就认为这个目录里是自制谱
|
||||
""")]
|
||||
public bool HideSelfMadeCharts { get; set; }
|
||||
|
||||
[ConfigComment(
|
||||
en: """
|
||||
Place font.ttf in the LocalAssets directory to replace the game's global font
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AquaMai.Helpers;
|
||||
using HarmonyLib;
|
||||
using MAI2.Util;
|
||||
using Manager;
|
||||
using MelonLoader;
|
||||
using Process;
|
||||
using UnityEngine;
|
||||
using Util;
|
||||
|
||||
namespace AquaMai.UX;
|
||||
|
||||
public class HideSelfMadeCharts
|
||||
{
|
||||
private static Safe.ReadonlySortedDictionary<int, Manager.MaiStudio.MusicData> _musics;
|
||||
private static Safe.ReadonlySortedDictionary<int, Manager.MaiStudio.MusicData> _musicsNoneSelfMade;
|
||||
|
||||
private static bool isShowSelfMadeCharts = true;
|
||||
private static bool isForceDisable;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(DataManager), "GetMusics")]
|
||||
public static void GetMusics(ref Safe.ReadonlySortedDictionary<int, Manager.MaiStudio.MusicData> __result, List<string> ____targetDirs)
|
||||
{
|
||||
if (_musics is null)
|
||||
{
|
||||
// init musics for the first time
|
||||
if (__result.Count == 0) return;
|
||||
_musics = __result;
|
||||
var nonSelfMadeList = new SortedDictionary<int, Manager.MaiStudio.MusicData>();
|
||||
var officialDirs = ____targetDirs.Where(it => File.Exists(Path.Combine(it, "DataConfig.xml")) || File.Exists(Path.Combine(it, "OfficialChartsMark.txt")));
|
||||
foreach (var music in __result)
|
||||
{
|
||||
if (officialDirs.Any(it => MusicDirHelper.LookupPath(music.Value).StartsWith(it)))
|
||||
{
|
||||
nonSelfMadeList.Add(music.Key, music.Value);
|
||||
}
|
||||
}
|
||||
|
||||
_musicsNoneSelfMade = new Safe.ReadonlySortedDictionary<int, Manager.MaiStudio.MusicData>(nonSelfMadeList);
|
||||
MelonLogger.Msg($"[HideSelfMadeCharts] All music count: {__result.Count}, Official music count: {_musicsNoneSelfMade.Count}");
|
||||
}
|
||||
|
||||
var stackTrace = new StackTrace(); // get call stack
|
||||
var stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
if (stackFrames.All(it => it.GetMethod().DeclaringType.Name != "MusicSelectProcess")) return;
|
||||
if (isShowSelfMadeCharts && !isForceDisable) return;
|
||||
__result = _musicsNoneSelfMade;
|
||||
}
|
||||
|
||||
private static int _keyPressFrames;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(MusicSelectProcess), "OnUpdate")]
|
||||
public static void MusicSelectProcessOnUpdate(ref MusicSelectProcess __instance)
|
||||
{
|
||||
if (isForceDisable) return;
|
||||
if (Input.GetKey(KeyCode.Alpha7) || InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService))
|
||||
{
|
||||
_keyPressFrames++;
|
||||
}
|
||||
else if (_keyPressFrames is > 0 and < 30 && !Input.GetKey(KeyCode.Alpha7) && !InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService))
|
||||
{
|
||||
_keyPressFrames = 0;
|
||||
isShowSelfMadeCharts = !isShowSelfMadeCharts;
|
||||
MelonLogger.Msg($"[HideSelfMadeCharts] isShowSelfMadeCharts: {isShowSelfMadeCharts}");
|
||||
SharedInstances.ProcessDataContainer.processManager.AddProcess(new FadeProcess(SharedInstances.ProcessDataContainer, __instance, new MusicSelectProcess(SharedInstances.ProcessDataContainer)));
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
MessageHelper.ShowMessage($"{(isShowSelfMadeCharts ? "Show" : "Hide")} Self-Made Charts");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_keyPressFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(MusicSelectProcess), "OnStart")]
|
||||
public static void MusicSelectProcessOnStart(ref MusicSelectProcess __instance)
|
||||
{
|
||||
if (File.Exists(Path.Combine(Environment.CurrentDirectory, "LocalAssets", "SelfMadeChartsDenyUsers.txt")))
|
||||
{
|
||||
var userIds = File.ReadAllLines(Path.Combine(Environment.CurrentDirectory, "LocalAssets", "SelfMadeChartsDenyUsers.txt"));
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var user = Singleton<UserDataManager>.Instance.GetUserData(i);
|
||||
if (!user.IsEntry) continue;
|
||||
if (!userIds.Contains(user.Detail.UserID.ToString())) continue;
|
||||
isForceDisable = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (File.Exists(Path.Combine(Environment.CurrentDirectory, "LocalAssets", "SelfMadeChartsWhiteListUsers.txt")))
|
||||
{
|
||||
var userIds = File.ReadAllLines(Path.Combine(Environment.CurrentDirectory, "LocalAssets", "SelfMadeChartsWhiteListUsers.txt"));
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var user = Singleton<UserDataManager>.Instance.GetUserData(i);
|
||||
if (!user.IsEntry) continue;
|
||||
if (userIds.Contains(user.Detail.UserID.ToString())) continue;
|
||||
isForceDisable = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
isForceDisable = false;
|
||||
}
|
||||
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(EntryProcess), "OnStart")]
|
||||
public static void EntryProcessOnStart(ref EntryProcess __instance)
|
||||
{
|
||||
// reset status on login
|
||||
isShowSelfMadeCharts = true;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using AquaMai.Attributes;
|
||||
using AquaMai.Helpers;
|
||||
using HarmonyLib;
|
||||
using Mai2.Mai2Cue;
|
||||
using MAI2.Util;
|
||||
using Main;
|
||||
using Manager;
|
||||
using MelonLoader;
|
||||
using Monitor;
|
||||
using Process;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AquaMai.UX;
|
||||
|
||||
public class QuickSkip
|
||||
{
|
||||
private static int _keyPressFrames;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameMainObject), "Update")]
|
||||
public static void OnGameMainObjectUpdate()
|
||||
{
|
||||
// The button between [1p] and [2p] button on ADX
|
||||
if (Input.GetKey(KeyCode.Alpha7) || InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService)) _keyPressFrames++;
|
||||
|
||||
if (_keyPressFrames > 0 && !Input.GetKey(KeyCode.Alpha7) && !InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService))
|
||||
{
|
||||
_keyPressFrames = 0;
|
||||
MelonLogger.Msg(SharedInstances.ProcessDataContainer.processManager.Dump());
|
||||
return;
|
||||
}
|
||||
|
||||
if (_keyPressFrames != 60) return;
|
||||
MelonLogger.Msg("[QuickSkip] Activated");
|
||||
|
||||
var traverse = Traverse.Create(SharedInstances.ProcessDataContainer.processManager);
|
||||
var processList = traverse.Field("_processList").GetValue<LinkedList<ProcessManager.ProcessControle>>();
|
||||
|
||||
ProcessBase processToRelease = null;
|
||||
|
||||
foreach (ProcessManager.ProcessControle process in processList)
|
||||
{
|
||||
switch (process.Process.ToString())
|
||||
{
|
||||
// After login
|
||||
case "Process.ModeSelect.ModeSelectProcess":
|
||||
case "Process.LoginBonus.LoginBonusProcess":
|
||||
case "Process.RegionalSelectProcess":
|
||||
case "Process.CharacterSelectProcess":
|
||||
case "Process.TicketSelect.TicketSelectProcess":
|
||||
processToRelease = process.Process;
|
||||
break;
|
||||
|
||||
case "Process.MusicSelectProcess":
|
||||
// Skip to save
|
||||
SoundManager.PreviewEnd();
|
||||
SoundManager.PlayBGM(Cue.BGM_COLLECTION, 2);
|
||||
SharedInstances.ProcessDataContainer.processManager.AddProcess(new FadeProcess(SharedInstances.ProcessDataContainer, process.Process, new UnlockMusicProcess(SharedInstances.ProcessDataContainer)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (processToRelease != null)
|
||||
{
|
||||
GameManager.SetMaxTrack();
|
||||
SharedInstances.ProcessDataContainer.processManager.AddProcess(new FadeProcess(SharedInstances.ProcessDataContainer, processToRelease, new MusicSelectProcess(SharedInstances.ProcessDataContainer)));
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GameProcess), "OnUpdate")]
|
||||
public static void PostGameProcessUpdate(GameProcess __instance, Message[] ____message, ProcessDataContainer ___container)
|
||||
{
|
||||
if (InputManager.GetButtonDown(0, InputManager.ButtonSetting.Select))
|
||||
{
|
||||
var traverse = Traverse.Create(__instance);
|
||||
___container.processManager.SendMessage(____message[0]);
|
||||
Singleton<GamePlayManager>.Instance.SetSyncResult(0);
|
||||
traverse.Method("SetRelease").GetValue();
|
||||
}
|
||||
|
||||
if (Input.GetKey(KeyCode.Alpha7) || InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService) && GameInfo.GameVersion >= 23000)
|
||||
{
|
||||
// This is original typo in Assembly-CSharp
|
||||
Singleton<GamePlayManager>.Instance.SetQuickRetryFrag(flag: true);
|
||||
}
|
||||
}
|
||||
|
||||
[GameVersion(23000)]
|
||||
public class FestivalAndLaterQuickRetryPatch
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(QuickRetry), "IsQuickRetryEnable")]
|
||||
public static bool OnQuickRetryIsQuickRetryEnable(ref bool __result)
|
||||
{
|
||||
var isUtageProperty = Traverse.Create(typeof(GameManager)).Property("IsUtage");
|
||||
__result = !isUtageProperty.PropertyExists() || !isUtageProperty.GetValue<bool>();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fix for the game not resetting Fast and Late counts when quick retrying
|
||||
// For game version < 1.35.0
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(GamePlayManager), "SetQuickRetryFrag")]
|
||||
public static void PostGamePlayManagerSetQuickRetryFrag(GamePlayManager __instance, bool flag)
|
||||
{
|
||||
// Since 1.35.0, `GameScoreList.Initialize()` resets the Fast and Late counts
|
||||
if (flag && !Traverse.Create(typeof(GameScoreList)).Methods().Contains("Initialize"))
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
var gameScoreList = __instance.GetGameScore(i);
|
||||
var traverse = Traverse.Create(gameScoreList);
|
||||
traverse.Property("Fast").SetValue((uint)0);
|
||||
traverse.Property("Late").SetValue((uint)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using Manager;
|
||||
|
||||
namespace AquaMai.UX;
|
||||
|
||||
public class TestProof
|
||||
{
|
||||
private static int _keyPressFrames;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(InputManager), "GetSystemInputDown")]
|
||||
public static bool GetSystemInputDown(ref bool __result, InputManager.SystemButtonSetting button, bool[] ___SystemButtonDown)
|
||||
{
|
||||
__result = ___SystemButtonDown[(int)button];
|
||||
if (button != InputManager.SystemButtonSetting.ButtonTest)
|
||||
return false;
|
||||
if (!InputManager.GetSystemInputPush(button))
|
||||
{
|
||||
_keyPressFrames = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
var stackTrace = new StackTrace(); // get call stack
|
||||
var stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
|
||||
if (stackFrames.Any(it => it.GetMethod().Name == "DMD<Main.GameMainObject::Update>"))
|
||||
{
|
||||
__result = false;
|
||||
if (InputManager.GetSystemInputPush(button))
|
||||
{
|
||||
_keyPressFrames++;
|
||||
}
|
||||
|
||||
if (_keyPressFrames == 60)
|
||||
{
|
||||
__result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user