From 0cab18b9b5f2a96d0c69e3a30854a55bb886772f Mon Sep 17 00:00:00 2001 From: WYH2004 <32890512+WYH2004-MC@users.noreply.github.com> Date: Thu, 17 Oct 2024 02:26:44 +0800 Subject: [PATCH] [+] CustomCameraId (#66) * [+] CustomCameraId * [F] Map CameraType to the correct Camera IDs using enum * [+] GameInfo Utils * [+] CustomCameraId Add ChimeCamera Support * [+] Decide whether to print a CameraList based on the Config --- AquaMai/AquaMai.toml | 10 +++ AquaMai/AquaMai.zh.toml | 10 +++ AquaMai/Config.cs | 11 ++++ AquaMai/CustomCameraId/Enable.cs | 104 +++++++++++++++++++++++++++++++ AquaMai/Utils/GameInfo.cs | 19 ++++++ 5 files changed, 154 insertions(+) create mode 100644 AquaMai/CustomCameraId/Enable.cs create mode 100644 AquaMai/Utils/GameInfo.cs diff --git a/AquaMai/AquaMai.toml b/AquaMai/AquaMai.toml index 2e3793dc..b9bbcff5 100644 --- a/AquaMai/AquaMai.toml +++ b/AquaMai/AquaMai.toml @@ -138,6 +138,16 @@ Windowed=false Width=0 Height=0 +[CustomCameraId] +# Enable custom CameraId +# If enabled, you can customize the game to use the specified camera +Enable=false +PrintCameraList=false +LeftQrCamera=0 +RightQrCamera=0 +PhotoCamera=0 +ChimeCamera=0 + [TouchSensitivity] # Enable custom sensitivity # When enabled, the settings in Test mode will not take effect diff --git a/AquaMai/AquaMai.zh.toml b/AquaMai/AquaMai.zh.toml index c5d93ee1..3ed10513 100644 --- a/AquaMai/AquaMai.zh.toml +++ b/AquaMai/AquaMai.zh.toml @@ -157,6 +157,16 @@ Windowed=false Width=0 Height=0 +[CustomCameraId] +# 是否启用自定义摄像头ID +# 启用后可以指定游戏使用的摄像头 +Enable=false +PrintCameraList=false +LeftQrCamera=0 +RightQrCamera=0 +PhotoCamera=0 +ChimeCamera=0 + [TouchSensitivity] # 是否启用自定义灵敏度 # 这里启用之后 Test 里的就不再起作用了 diff --git a/AquaMai/Config.cs b/AquaMai/Config.cs index 2f742a55..c9d0712e 100644 --- a/AquaMai/Config.cs +++ b/AquaMai/Config.cs @@ -12,6 +12,7 @@ namespace AquaMai public UtilsConfig Utils { get; set; } = new(); public TimeSavingConfig TimeSaving { get; set; } = new(); public WindowStateConfig WindowState { get; set; } = new(); + public CustomCameraIdConfig CustomCameraId { get; set; } = new(); public TouchSensitivityConfig TouchSensitivity { get; set; } = new(); public CustomKeyMapConfig CustomKeyMap { get; set; } = new(); @@ -96,6 +97,16 @@ namespace AquaMai public int Height { get; set; } } + public class CustomCameraIdConfig + { + public bool Enable { get; set; } + public bool PrintCameraList { get; set; } = false; + public int LeftQrCamera { get; set; } = 0; + public int RightQrCamera { get; set; } = 0; + public int PhotoCamera { get; set; } = 0; + public int ChimeCamera { get; set; } = 0; + } + public class TouchSensitivityConfig { public bool Enable { get; set; } diff --git a/AquaMai/CustomCameraId/Enable.cs b/AquaMai/CustomCameraId/Enable.cs new file mode 100644 index 00000000..cc63c6dd --- /dev/null +++ b/AquaMai/CustomCameraId/Enable.cs @@ -0,0 +1,104 @@ +using static Manager.CameraManager; +using System.Collections; +using AquaMai.Utils; +using HarmonyLib; +using Manager; +using MelonLoader; +using UnityEngine; + +namespace AquaMai.CustomCameraId; + +public class Enable +{ + [HarmonyPrefix] + [HarmonyPatch(typeof(CameraManager), "CameraInitialize")] + public static bool CameraInitialize(CameraManager __instance, ref IEnumerator __result) + { + __result = CameraInitialize(__instance); + return false; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(CameraManager), "Initialize")] + public static void SetCameraResolution(CameraManager __instance) + { + if(AquaMai.AppConfig.CustomCameraId.PrintCameraList) PrintCameraList(); + WebCamDevice gameDevice = WebCamTexture.devices[AquaMai.AppConfig.CustomCameraId.PhotoCamera]; + WebCamDevice qrDevice = WebCamTexture.devices[GameInfo.GetGameId() == "SDGB" ? AquaMai.AppConfig.CustomCameraId.ChimeCamera : AquaMai.AppConfig.CustomCameraId.LeftQrCamera]; + WebCamTexture gameTexture = new WebCamTexture(gameDevice.name); + WebCamTexture qrTexture = new WebCamTexture(qrDevice.name); + gameTexture.Play(); + qrTexture.Play(); + CameraParameter gameCameraParam = new CameraParameter(gameTexture.width, gameTexture.height, (int)gameTexture.requestedFPS); + CameraParameter qrCameraParam = new CameraParameter(qrTexture.width, qrTexture.height, (int)qrTexture.requestedFPS); + AccessTools.Field(typeof(CameraManager), "GameCameraParam").SetValue(__instance, gameCameraParam); + AccessTools.Field(typeof(CameraManager), "QrCameraParam").SetValue(__instance, qrCameraParam); + gameTexture.Stop(); + qrTexture.Stop(); + } + + private static IEnumerator CameraInitialize(CameraManager __instance) + { + var webcamtexField = AccessTools.Field(typeof(CameraManager), "_webcamtex"); + WebCamTexture[] webcamtex = new WebCamTexture[GameInfo.GetGameId() == "SDGB" ? 2 : 3]; + + int leftQrCameraId = ((AquaMai.AppConfig.CustomCameraId.LeftQrCamera < WebCamTexture.devices.Length) + ? AquaMai.AppConfig.CustomCameraId.LeftQrCamera + : 0); + int rightQrCameraId = ((AquaMai.AppConfig.CustomCameraId.RightQrCamera < WebCamTexture.devices.Length) + ? AquaMai.AppConfig.CustomCameraId.RightQrCamera + : 0); + int photoCameraId = ((AquaMai.AppConfig.CustomCameraId.PhotoCamera < WebCamTexture.devices.Length) + ? AquaMai.AppConfig.CustomCameraId.PhotoCamera + : 0); + int chimeQrCameraId= ((AquaMai.AppConfig.CustomCameraId.ChimeCamera < WebCamTexture.devices.Length) + ? AquaMai.AppConfig.CustomCameraId.ChimeCamera + : 0); + + if (GameInfo.GetGameId() == "SDGB") + { + webcamtex[chimeQrCameraId] = new WebCamTexture(WebCamTexture.devices[chimeQrCameraId].name, QrCameraParam.Width, QrCameraParam.Height, QrCameraParam.Fps); + DeviceId[0] = chimeQrCameraId; + DeviceId[1] = photoCameraId; + } + else + { + webcamtex[leftQrCameraId] = new WebCamTexture(WebCamTexture.devices[leftQrCameraId].name, QrCameraParam.Width, QrCameraParam.Height, QrCameraParam.Fps); + webcamtex[rightQrCameraId] = new WebCamTexture(WebCamTexture.devices[rightQrCameraId].name, QrCameraParam.Width, QrCameraParam.Height, QrCameraParam.Fps); + DeviceId[(int) CameraTypeEnum.QRLeft] = leftQrCameraId; + DeviceId[(int) CameraTypeEnum.QRRight] = rightQrCameraId; + DeviceId[(int) CameraTypeEnum.Photo] = photoCameraId; + } + webcamtex[photoCameraId] = new WebCamTexture(WebCamTexture.devices[photoCameraId].name, GameCameraParam.Width, GameCameraParam.Height, GameCameraParam.Fps); + webcamtexField.SetValue(__instance, webcamtex); + + for (int i = 0; i < webcamtex.Length; i++) + { + __instance.isAvailableCamera[i] = true; + __instance.cameraProcMode[i] = CameraManager.CameraProcEnum.Good; + } + + CameraManager.IsReady = true; + yield break; + } + + private static void PrintCameraList() + { + WebCamDevice[] devices = WebCamTexture.devices; + string cameraList = "Connected Web Cameras:\n"; + for (int i = 0; i < devices.Length; i++) + { + WebCamDevice webCamDevice = devices[i]; + WebCamTexture webCamTexture = new WebCamTexture(webCamDevice.name); + webCamTexture.Play(); + cameraList += "==================================================\n"; + cameraList += "Name: " + webCamDevice.name + "\n"; + cameraList += $"ID: {i}\n"; + cameraList += $"Resolution: {webCamTexture.width} * {webCamTexture.height}\n"; + cameraList += $"FPS: {webCamTexture.requestedFPS}\n"; + webCamTexture.Stop(); + } + cameraList += "=================================================="; + MelonLogger.Msg(cameraList); + } +} \ No newline at end of file diff --git a/AquaMai/Utils/GameInfo.cs b/AquaMai/Utils/GameInfo.cs new file mode 100644 index 00000000..05301b28 --- /dev/null +++ b/AquaMai/Utils/GameInfo.cs @@ -0,0 +1,19 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using MAI2System; + +namespace AquaMai.Utils; + +public class GameInfo +{ + public static uint GetGameVersion() + { + return (uint) typeof(ConstParameter).GetField("NowGameVersion", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).GetValue(null); + } + + public static string GetGameId() + { + return typeof(ConstParameter).GetField("GameIDStr", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy).GetValue(null) as string; + } +} \ No newline at end of file