From 81e0232712d35c81e0a715a3caa7f626ae1370aa Mon Sep 17 00:00:00 2001 From: Menci Date: Sun, 13 Oct 2024 21:35:13 +0800 Subject: [PATCH] [O] Support SDGA and other game version in one binary Merge pull request #61 * Merge targets * Merge branch 'v1-dev' into fork/Menci/merge-targets * [O] Move Shim to AquaMai.Helpers --------- Co-authored-by: Clansty --- AquaMai/AquaMai.sln | 3 -- AquaMai/Fix/RemoveEncryption.cs | 69 +++++++++++---------------------- AquaMai/Helpers/Shim.cs | 67 ++++++++++++++++++++++++++++++++ AquaMai/UX/ImmediateSave.cs | 21 +++------- 4 files changed, 94 insertions(+), 66 deletions(-) create mode 100644 AquaMai/Helpers/Shim.cs diff --git a/AquaMai/AquaMai.sln b/AquaMai/AquaMai.sln index 4e5cbf75..1804c25b 100644 --- a/AquaMai/AquaMai.sln +++ b/AquaMai/AquaMai.sln @@ -8,14 +8,11 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|Any CPU = Release|Any CPU - SDGA145|Any CPU = SDGA145|Any CPU Debug|Any CPU = Debug|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {788BC472-59F7-46F6-B760-65C18BA74389}.Release|Any CPU.ActiveCfg = Release|Any CPU {788BC472-59F7-46F6-B760-65C18BA74389}.Release|Any CPU.Build.0 = Release|Any CPU - {788BC472-59F7-46F6-B760-65C18BA74389}.SDGA145|Any CPU.ActiveCfg = SDGA145|Any CPU - {788BC472-59F7-46F6-B760-65C18BA74389}.SDGA145|Any CPU.Build.0 = SDGA145|Any CPU {788BC472-59F7-46F6-B760-65C18BA74389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {788BC472-59F7-46F6-B760-65C18BA74389}.Debug|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection diff --git a/AquaMai/Fix/RemoveEncryption.cs b/AquaMai/Fix/RemoveEncryption.cs index 52c7cb03..2a29d9f8 100644 --- a/AquaMai/Fix/RemoveEncryption.cs +++ b/AquaMai/Fix/RemoveEncryption.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Reflection; using HarmonyLib; -using MelonLoader; using Net.Packet; namespace AquaMai.Fix; @@ -11,65 +10,41 @@ public class RemoveEncryption { [HarmonyPrefix] [HarmonyPatch(typeof(Packet), "Obfuscator", typeof(string))] - private static bool PreObfuscator(string srcStr, ref string __result) + public static bool PreObfuscator(string srcStr, ref string __result) { __result = srcStr.Replace("MaimaiExp", "").Replace("MaimaiChn", ""); return false; } [HarmonyPatch] - public class Encrypt + public class EncryptDecrypt { public static IEnumerable TargetMethods() { -# if SDGA145 - return [AccessTools.Method("Net.CipherAES:Encrypt", [typeof(byte[])])]; -# else - return [AccessTools.TypeByName("Net.CipherAES").GetMethods().FirstOrDefault(it => it.Name == "Encrypt")]; -# endif + var methods = AccessTools.TypeByName("Net.CipherAES").GetMethods(); + return + [ + methods.FirstOrDefault(it => it.Name == "Encrypt" && it.IsPublic), + methods.FirstOrDefault(it => it.Name == "Decrypt" && it.IsPublic) + ]; } -# if SDGA145 - public static bool Prefix(byte[] data, ref byte[] __result) + public static bool Prefix(object[] __args, ref object __result) { - __result = data; + if (__args.Length == 1) + { + // public static byte[] Encrypt(byte[] data) + // public static byte[] Decrypt(byte[] encryptData) + __result = __args[0]; + } + else if (__args.Length == 2) + { + // public static bool Encrypt(byte[] data, out byte[] encryptData) + // public static bool Decrypt(byte[] encryptData, out byte[] plainData) + __args[1] = __args[0]; + __result = true; + } return false; } -# else - public static bool Prefix(byte[] data, out byte[] encryptData, ref bool __result) - { - encryptData = data; - __result = true; - return false; - } -# endif - } - - [HarmonyPatch] - public class Decrypt - { - public static IEnumerable TargetMethods() - { -# if SDGA145 - return [AccessTools.Method("Net.CipherAES:Decrypt", [typeof(byte[])])]; -# else - return [AccessTools.TypeByName("Net.CipherAES").GetMethods().FirstOrDefault(it => it.Name == "Decrypt")]; -# endif - } - -# if SDGA145 - public static bool Prefix(byte[] encryptData, ref byte[] __result) - { - __result = encryptData; - return false; - } -# else - public static bool Prefix(byte[] encryptData, out byte[] plainData, ref bool __result) - { - plainData = encryptData; - __result = true; - return false; - } -# endif } } diff --git a/AquaMai/Helpers/Shim.cs b/AquaMai/Helpers/Shim.cs new file mode 100644 index 00000000..d6a85b6b --- /dev/null +++ b/AquaMai/Helpers/Shim.cs @@ -0,0 +1,67 @@ +using System; +using System.Reflection; +using HarmonyLib; +using MAI2.Util; +using Manager; +using Net.Packet; +using Net.Packet.Mai2; + +namespace AquaMai.Helpers; + +public static class Shim +{ + public delegate string GetAccessTokenMethod(int index); + public static readonly GetAccessTokenMethod GetAccessToken = new Func(() => { + var tOperationManager = Traverse.Create(Singleton.Instance); + var tGetAccessToken = tOperationManager.Method("GetAccessToken", [typeof(int)]); + if (!tGetAccessToken.MethodExists()) + { + return (index) => throw new MissingMethodException("No matching OperationManager.GetAccessToken() method found"); + } + return (index) => tGetAccessToken.GetValue(index); + })(); + + public delegate PacketUploadUserPlaylog PacketUploadUserPlaylogCreator(int index, UserData src, int trackNo, Action onDone, Action onError = null); + public static readonly PacketUploadUserPlaylogCreator CreatePacketUploadUserPlaylog = new Func(() => { + var type = typeof(PacketUploadUserPlaylog); + if (type.GetConstructor([typeof(int), typeof(UserData), typeof(int), typeof(Action), typeof(Action)]) is ConstructorInfo ctor1) { + return (index, src, trackNo, onDone, onError) => { + var args = new object[] {index, src, trackNo, "", onDone, onError}; + return (PacketUploadUserPlaylog)ctor1.Invoke(args); + }; + } + else if (type.GetConstructor([typeof(int), typeof(UserData), typeof(int), typeof(string), typeof(Action), typeof(Action)]) is ConstructorInfo ctor2) { + return (index, src, trackNo, onDone, onError) => { + var accessToken = GetAccessToken(index); + var args = new object[] {index, src, trackNo, accessToken, onDone, onError}; + return (PacketUploadUserPlaylog)ctor2.Invoke(args); + }; + } + else + { + throw new MissingMethodException("No matching PacketUploadUserPlaylog constructor found"); + } + })(); + + public delegate PacketUpsertUserAll PacketUpsertUserAllCreator(int index, UserData src, Action onDone, Action onError = null); + public static readonly PacketUpsertUserAllCreator CreatePacketUpsertUserAll = new Func(() => { + var type = typeof(PacketUpsertUserAll); + if (type.GetConstructor([typeof(int), typeof(UserData), typeof(Action), typeof(Action)]) is ConstructorInfo ctor1) { + return (index, src, onDone, onError) => { + var args = new object[] {index, src, "", onDone, onError}; + return (PacketUpsertUserAll)ctor1.Invoke(args); + }; + } + else if (type.GetConstructor([typeof(int), typeof(UserData), typeof(string), typeof(Action), typeof(Action)]) is ConstructorInfo ctor2) { + return (index, src, onDone, onError) => { + var accessToken = GetAccessToken(index); + var args = new object[] {index, src, accessToken, onDone, onError}; + return (PacketUpsertUserAll)ctor2.Invoke(args); + }; + } + else + { + throw new MissingMethodException("No matching PacketUpsertUserAll constructor found"); + } + })(); +} diff --git a/AquaMai/UX/ImmediateSave.cs b/AquaMai/UX/ImmediateSave.cs index a978c15b..290614f9 100644 --- a/AquaMai/UX/ImmediateSave.cs +++ b/AquaMai/UX/ImmediateSave.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using AquaMai.Helpers; using AquaMai.Resources; +using AquaMai.Utils; +using CriAtomDebugDetail; using DB; using HarmonyLib; using MAI2.Util; @@ -63,12 +65,7 @@ public class ImmediateSave } SaveDataFix(userData); -# if SDGA145 - PacketHelper.StartPacket(new PacketUploadUserPlaylog(i, userData, (int)GameManager.MusicTrackNumber - 1, -# else - var accessToken = Singleton.Instance.GetAccessToken(i); - PacketHelper.StartPacket(new PacketUploadUserPlaylog(i, userData, (int)GameManager.MusicTrackNumber - 1, accessToken, -# endif + PacketHelper.StartPacket(Shim.CreatePacketUploadUserPlaylog(i, userData, (int)GameManager.MusicTrackNumber - 1, delegate { MelonLogger.Msg("Playlog saved"); @@ -82,11 +79,7 @@ public class ImmediateSave MessageHelper.ShowMessage("Playlog save error"); CheckSaveDone(); })); -# if SDGA145 - PacketHelper.StartPacket(new PacketUpsertUserAll(i, userData, delegate(int code) -# else - PacketHelper.StartPacket(new PacketUpsertUserAll(i, userData, accessToken, delegate(int code) -# endif + PacketHelper.StartPacket(Shim.CreatePacketUpsertUserAll(i, userData, delegate(int code) { if (code == 1) { @@ -222,11 +215,7 @@ public class ImmediateSave userData.Detail.LastPlayMode = 2; } -# if SDGA145 - userData.Detail.LastGameId = "SDGA"; -# else - userData.Detail.LastGameId = "SDEZ"; -# endif + userData.Detail.LastGameId = ConstParameter.GameIDStr; userData.Detail.LastRomVersion = Singleton.Instance.config.romVersionInfo.versionNo.versionString; userData.Detail.LastDataVersion = Singleton.Instance.config.dataVersionInfo.versionNo.versionString; }