mirror of https://github.com/hykilpikonna/AquaDX
143 lines
4.9 KiB
C#
143 lines
4.9 KiB
C#
![]() |
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}");
|
||
|
}
|
||
|
}
|
||
![]() |
}
|