forked from Cookies_Github_mirror/AquaDX
[RF] AquaMai configuration refactor (#82)
更新了配置文件格式,原有的配置文件将被自动无缝迁移,详情请见新的配置文件中的注释(例外:`SlideJudgeTweak` 不再默认启用) 旧配置文件将被重命名备份,如果更新到此版本遇到 Bug 请联系我们 Updated configuration file schema. The old config file will be migrated automatically and seamlessly. See the comments in the new configuration file for details. (Except for `SlideJudgeTweak` is no longer enabled by default) Your old configuration file will be renamed as a backup. If you encounter any bug with this version, please contact us.
This commit is contained in:
142
AquaMai/AquaMai.Mods/GameSystem/CustomCameraId.cs
Normal file
142
AquaMai/AquaMai.Mods/GameSystem/CustomCameraId.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using Manager;
|
||||
using MelonLoader;
|
||||
using UnityEngine;
|
||||
using AquaMai.Config.Attributes;
|
||||
|
||||
namespace AquaMai.Mods.GameSystem;
|
||||
|
||||
[ConfigSection(
|
||||
en: """
|
||||
Use custom CameraId rather than the default ones.
|
||||
If enabled, you can customize the game to use the specified camera.
|
||||
""",
|
||||
zh: """
|
||||
使用自定义的摄像头 ID 而不是默认的
|
||||
启用后可以指定游戏使用的摄像头
|
||||
""")]
|
||||
public class CustomCameraId
|
||||
{
|
||||
[ConfigEntry(
|
||||
en: "Print the camera list to the log when starting, can be used as a basis for modification.",
|
||||
zh: "启动时打印摄像头列表到日志中,可以作为修改的依据")]
|
||||
public static bool printCameraList;
|
||||
|
||||
[ConfigEntry(
|
||||
en: "DX Pass 1P.",
|
||||
zh: "DX Pass 1P")]
|
||||
public static int leftQrCamera;
|
||||
|
||||
[ConfigEntry(
|
||||
en: "DX Pass 2P.",
|
||||
zh: "DX Pass 2P")]
|
||||
public static int rightQrCamera;
|
||||
|
||||
[ConfigEntry(
|
||||
en: "Player Camera.",
|
||||
zh: "玩家摄像头")]
|
||||
public static int photoCamera;
|
||||
|
||||
[ConfigEntry(
|
||||
en: "WeChat QRCode Camera.",
|
||||
zh: "二维码扫描摄像头")]
|
||||
public static int chimeCamera;
|
||||
|
||||
private static readonly Dictionary<string, string> cameraTypeMap = new()
|
||||
{
|
||||
["LeftQrCamera"] = "QRLeft",
|
||||
["RightQrCamera"] = "QRRight",
|
||||
["PhotoCamera"] = "Photo",
|
||||
["ChimeCamera"] = "Chime",
|
||||
};
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CameraManager), "CameraInitialize")]
|
||||
public static bool CameraInitialize(CameraManager __instance, ref IEnumerator __result)
|
||||
{
|
||||
__result = CameraInitialize(__instance);
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IEnumerator CameraInitialize(CameraManager __instance)
|
||||
{
|
||||
var textureCache = new WebCamTexture[WebCamTexture.devices.Length];
|
||||
SortedDictionary<CameraManager.CameraTypeEnum, WebCamTexture> webCamTextures = [];
|
||||
foreach (var (configEntry, cameraTypeName) in cameraTypeMap)
|
||||
{
|
||||
int deviceId = Traverse.Create(typeof(CustomCameraId)).Field(configEntry).GetValue<int>();
|
||||
if (deviceId < 0 || deviceId >= WebCamTexture.devices.Length)
|
||||
{
|
||||
MelonLogger.Warning($"[CustomCameraId] Ignoring custom camera {configEntry}: camera ID {deviceId} out of range");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Enum.TryParse<CameraManager.CameraTypeEnum>(cameraTypeName, out var cameraType))
|
||||
{
|
||||
MelonLogger.Warning($"[CustomCameraId] Ignoring custom camera {configEntry}: camera type {cameraTypeName} not present");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (textureCache[deviceId] != null)
|
||||
{
|
||||
webCamTextures[cameraType] = textureCache[deviceId];
|
||||
}
|
||||
else
|
||||
{
|
||||
var webCamTexture = new WebCamTexture(WebCamTexture.devices[deviceId].name);
|
||||
webCamTextures[cameraType] = webCamTexture;
|
||||
textureCache[deviceId] = webCamTexture;
|
||||
}
|
||||
}
|
||||
|
||||
int textureCount = webCamTextures.Count;
|
||||
__instance.isAvailableCamera = new bool[textureCount];
|
||||
__instance.cameraProcMode = new CameraManager.CameraProcEnum[textureCount];
|
||||
|
||||
int textureIndex = 0;
|
||||
foreach (var (cameraType, webCamTexture) in webCamTextures)
|
||||
{
|
||||
__instance.isAvailableCamera[textureIndex] = true;
|
||||
__instance.cameraProcMode[textureIndex] = CameraManager.CameraProcEnum.Good;
|
||||
CameraManager.DeviceId[(int)cameraType] = textureIndex;
|
||||
textureIndex++;
|
||||
}
|
||||
Traverse.Create(__instance).Field("_webcamtex").SetValue(webCamTextures.Values.ToArray());
|
||||
|
||||
CameraManager.IsReady = true;
|
||||
yield break;
|
||||
}
|
||||
|
||||
public static void OnBeforePatch()
|
||||
{
|
||||
if (!printCameraList)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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 += "==================================================";
|
||||
|
||||
foreach (var line in cameraList.Split('\n'))
|
||||
{
|
||||
MelonLogger.Msg($"[CustomCameraId] {line}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user