[+] toggle the display of self-made charts
Build AquaMai / build (SDEZ141) (push) Has been cancelled Details
Build AquaMai / build (SDGA145) (push) Has been cancelled Details

pull/52/head
Clansty 2024-09-05 02:31:07 +08:00
parent ca425cf949
commit e8307cdcd9
No known key found for this signature in database
GPG Key ID: 3A6BE8BAF2EDE134
11 changed files with 198 additions and 20 deletions

View File

@ -293,6 +293,9 @@
<Compile Include="Fix\ForceFreePlay.cs" />
<Compile Include="Fix\RemoveEncryption.cs" />
<Compile Include="Fix\SkipVersionCheck.cs" />
<Compile Include="Helpers\MessageHelper.cs" />
<Compile Include="Helpers\MusicDirHelper.cs" />
<Compile Include="Helpers\SharedInstances.cs" />
<Compile Include="Performance\ImproveLoadSpeed.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Main.cs" />
@ -300,6 +303,7 @@
<Compile Include="UX\CustomVersionString.cs" />
<Compile Include="UX\DemoMaster.cs" />
<Compile Include="UX\ExtendTimer.cs" />
<Compile Include="UX\HideSelfMadeCharts.cs" />
<Compile Include="UX\ImmediateSave.cs" />
<Compile Include="UX\LoadJacketPng.cs" />
<Compile Include="UX\LoadAssetBundleWithoutManifest.cs" />

View File

@ -51,6 +51,9 @@ TestProof=false
# Custom shop name in photo
# Also enable shop name display in SDGA
CustomPlaceName=""
# 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.
HideSelfMadeCharts=true
[Performance]
# Disable some useless delays to speed up the game boot process

View File

@ -57,6 +57,9 @@ TestProof=false
# 自定义拍照的店铺名称
# 同时在 SDGA 中会启用店铺名称的显示(但是不会在游戏里有设置)
CustomPlaceName=""
# 选歌界面按下 Service 键或者键盘上的 “7” 键ADX 默认固件下箭头键中间的圆形按键)切换自制谱的显示和隐藏
# 是否是自制谱的判断方式是 Axxx 目录里没有 DataConfig.xml 或 OfficialChartsMark.txt 就认为这个目录里是自制谱
HideSelfMadeCharts=true
# ===================================
# 一些性能优化

View File

@ -33,6 +33,7 @@ namespace AquaMai
public bool ImmediateSave { get; set; }
public bool LoadLocalBga { get; set; }
public bool TestProof { get; set; }
public bool HideSelfMadeCharts { get; set; }
public string CustomVersionString { get; set; }
public string CustomPlaceName { get; set; }
public string ExecOnIdle { get; set; }

View File

@ -0,0 +1,37 @@
using DB;
using HarmonyLib;
using Manager;
using MelonLoader;
using Process;
namespace AquaMai.Helpers;
public class MessageHelper
{
private static IGenericManager _genericManager = null;
[HarmonyPostfix]
[HarmonyPatch(typeof(ProcessManager), "SetMessageManager")]
private static void OnSetMessageManager(IGenericManager genericManager)
{
_genericManager = genericManager;
}
public static void ShowMessage(string message, WindowSizeID size = WindowSizeID.Middle)
{
if (_genericManager is null)
{
MelonLogger.Error($"[MessageHelper] Unable to show message: `{message}` GenericManager is null");
return;
}
_genericManager.Enqueue(0, WindowMessageID.CollectionAttentionEmptyFavorite, new WindowParam()
{
hideTitle = true,
replaceText = true,
text = message,
changeSize = true,
sizeID = size
});
}
}

View File

@ -0,0 +1,34 @@
using System.Collections.Generic;
using System.Diagnostics;
using HarmonyLib;
using Manager;
using MelonLoader;
namespace AquaMai.Helpers;
public class MusicDirHelper
{
private static Dictionary<int, string> _map = new();
[HarmonyPostfix]
[HarmonyPatch(typeof(Manager.MaiStudio.Serialize.MusicData), "AddPath")]
private static void AddPath(Manager.MaiStudio.Serialize.MusicData __instance, string parentPath)
{
_map[__instance.GetID()] = parentPath;
}
public static string LookupPath(int id)
{
return _map.GetValueOrDefault(id);
}
public static string LookupPath(Manager.MaiStudio.Serialize.MusicData musicData)
{
return LookupPath(musicData.GetID());
}
public static string LookupPath(Manager.MaiStudio.MusicData musicData)
{
return LookupPath(musicData.GetID());
}
}

View File

@ -0,0 +1,16 @@
using HarmonyLib;
using Process;
namespace AquaMai.Helpers;
public class SharedInstances
{
public static ProcessDataContainer ProcessDataContainer { get; private set; }
[HarmonyPrefix]
[HarmonyPatch(typeof(ProcessDataContainer), MethodType.Constructor)]
public static void OnCreateProcessDataContainer(ProcessDataContainer __instance)
{
ProcessDataContainer = __instance;
}
}

View File

@ -1,5 +1,6 @@
using System;
using AquaMai.Fix;
using AquaMai.Helpers;
using AquaMai.UX;
using MelonLoader;
using Tomlet;
@ -46,7 +47,7 @@ namespace AquaMai
if (settingProp.PropertyType != typeof(bool)) continue;
// Check if the boolean value is true
if (!(bool) settingProp.GetValue(categoryValue)) continue;
if (!(bool)settingProp.GetValue(categoryValue)) continue;
// Get the Type from the config directive name
var directiveType = Type.GetType($"AquaMai.{categoryProp.Name}.{settingProp.Name}");
@ -72,17 +73,24 @@ namespace AquaMai
// Read AquaMai.toml to load settings
AppConfig = TomletMain.To<Config>(System.IO.File.ReadAllText("AquaMai.toml"));
// Apply patches based on the settings
ApplyPatches();
// Fixes that does not have side effects
// These don't need to be configurable
// Helpers
Patch(typeof(MessageHelper));
Patch(typeof(MusicDirHelper));
Patch(typeof(SharedInstances));
// Fixes
Patch(typeof(FixCharaCrash));
Patch(typeof(BasicFix));
Patch(typeof(DisableReboot));
// UX
Patch(typeof(CustomVersionString));
Patch(typeof(CustomPlaceName));
Patch(typeof(DisableReboot));
Patch(typeof(RunCommandOnEvents));
Patch(typeof(BasicFix));
// Apply patches based on the settings
ApplyPatches();
MelonLogger.Msg("Loaded!");
}

View File

@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AquaMai.Helpers;
using HarmonyLib;
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;
[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) return;
__result = _musicsNoneSelfMade;
}
private static int _keyPressFrames;
[HarmonyPostfix]
[HarmonyPatch(typeof(MusicSelectProcess), "OnUpdate")]
public static void MusicSelectProcessOnUpdate(ref MusicSelectProcess __instance)
{
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;
}
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Reflection;
@ -67,7 +66,7 @@ namespace AquaMai.UX
jacketPaths[match.Groups[1].Value] = laFile;
}
MelonLogger.Msg($"Loaded {jacketPaths.Count} custom jacket images.");
MelonLogger.Msg($"[LoadJacketPng] Loaded {jacketPaths.Count} custom jacket images.");
}
private static string GetJacketPath(string id)

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using AquaMai.Helpers;
using HarmonyLib;
using Mai2.Mai2Cue;
using MAI2.Util;
@ -12,16 +13,8 @@ namespace AquaMai.UX
{
public class QuickSkip
{
private static ProcessDataContainer _container;
private static int _keyPressFrames;
[HarmonyPrefix]
[HarmonyPatch(typeof(ProcessDataContainer), MethodType.Constructor)]
public static void OnCreateProcessDataContainer(ProcessDataContainer __instance)
{
_container = __instance;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameMainObject), "Update")]
public static void OnGameMainObjectUpdate()
@ -32,14 +25,14 @@ namespace AquaMai.UX
if (_keyPressFrames > 0 && !Input.GetKey(KeyCode.Alpha7) && !InputManager.GetSystemInputPush(InputManager.SystemButtonSetting.ButtonService))
{
_keyPressFrames = 0;
MelonLogger.Msg(_container.processManager.Dump());
MelonLogger.Msg(SharedInstances.ProcessDataContainer.processManager.Dump());
return;
}
if (_keyPressFrames != 60) return;
MelonLogger.Msg("[QuickSkip] Activated");
var traverse = Traverse.Create(_container.processManager);
var traverse = Traverse.Create(SharedInstances.ProcessDataContainer.processManager);
var processList = traverse.Field("_processList").GetValue<LinkedList<ProcessManager.ProcessControle>>();
ProcessBase processToRelease = null;
@ -61,7 +54,7 @@ namespace AquaMai.UX
// Skip to save
SoundManager.PreviewEnd();
SoundManager.PlayBGM(Cue.BGM_COLLECTION, 2);
_container.processManager.AddProcess(new FadeProcess(_container, process.Process, new UnlockMusicProcess(_container)));
SharedInstances.ProcessDataContainer.processManager.AddProcess(new FadeProcess(SharedInstances.ProcessDataContainer, process.Process, new UnlockMusicProcess(SharedInstances.ProcessDataContainer)));
break;
}
}
@ -69,7 +62,7 @@ namespace AquaMai.UX
if (processToRelease != null)
{
GameManager.SetMaxTrack();
_container.processManager.AddProcess(new FadeProcess(_container, processToRelease, new MusicSelectProcess(_container)));
SharedInstances.ProcessDataContainer.processManager.AddProcess(new FadeProcess(SharedInstances.ProcessDataContainer, processToRelease, new MusicSelectProcess(SharedInstances.ProcessDataContainer)));
}
}