using System;
using System.Diagnostics;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using ZundamonizeNoMic.Plugins;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ZundamonizeNoMic")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZundamonizeNoMic")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a8246cf1-2bd5-4af9-b6aa-d48bacf30ae2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ZundamonizeNoMic
{
[BepInPlugin("Ryoryoman_ZundamonizeNoMic", "ZundamonizeNoMic", "1.0.0")]
public class ZundamonizeNoMicBase : BaseUnityPlugin
{
private const string modGUID = "Ryoryoman_ZundamonizeNoMic";
private const string modName = "ZundamonizeNoMic";
private const string modVersion = "1.0.0";
private readonly Harmony harmony = new Harmony("Ryoryoman_ZundamonizeNoMic");
public static ZundamonizeNoMicBase Instance;
public static ManualLogSource mls;
public ConfigEntry<int> speakerID;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
speakerID = ((BaseUnityPlugin)this).Config.Bind<int>("ZundamonizeNoMicConfig", "speakerID スピーカーID", 1, "スピーカーIDのリストは一部Websiteから見ることができます。そのほかのスピーカーIDは各自調べてください。");
mls = Logger.CreateLogSource("Ryoryoman_ZundamonizeNoMic");
mls.LogInfo((object)"ZundamonizeNoMic1.0.0loaded.");
harmony.PatchAll(typeof(ZundamonizeNoMicBase));
harmony.PatchAll(typeof(GetChatPatch));
}
}
}
namespace ZundamonizeNoMic.Plugins
{
[HarmonyPatch(typeof(HUDManager))]
internal class GetChatPatch
{
public class GetQuery
{
public static async Task<string> GetQueryPost(string text, int speakerID)
{
HttpClient httpClient = new HttpClient();
string jsonQuery;
try
{
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost:50021/audio_query?text=" + text + "&speaker=" + speakerID);
try
{
((HttpHeaders)request.Headers).TryAddWithoutValidation("accept", "application/json");
request.Content = (HttpContent)new StringContent("");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
jsonQuery = await (await httpClient.SendAsync(request)).Content.ReadAsStringAsync();
}
finally
{
((IDisposable)request)?.Dispose();
}
}
finally
{
((IDisposable)httpClient)?.Dispose();
}
return jsonQuery;
}
}
public class GetWav
{
public static async Task<byte[]> GetWavPost(string text, int speakerID)
{
HttpClient httpClient = new HttpClient();
byte[] result;
try
{
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost:50021/synthesis?speaker=" + speakerID + "&enable_interrogative_upspeak=true");
try
{
((HttpHeaders)request.Headers).TryAddWithoutValidation("accept", "audio/wav");
HttpRequestMessage val = request;
val.Content = (HttpContent)new StringContent(await GetQuery.GetQueryPost(text, speakerID));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
result = await (await httpClient.SendAsync(request)).Content.ReadAsByteArrayAsync();
}
finally
{
((IDisposable)request)?.Dispose();
}
}
finally
{
((IDisposable)httpClient)?.Dispose();
}
return result;
}
}
public static class WavUtility
{
public static AudioClip ToAudioClip(byte[] wavData)
{
int num = BitConverter.ToInt16(wavData, 22);
int num2 = BitConverter.ToInt32(wavData, 24);
int num3 = BitConverter.ToInt16(wavData, 34);
int num4 = FindDataChunk(wavData);
int num5 = BitConverter.ToInt32(wavData, num4 - 4);
float[] array = new float[num5 / (num3 / 8)];
for (int i = 0; i < array.Length; i++)
{
int num6 = num4 + i * (num3 / 8);
switch (num3)
{
case 16:
{
short num7 = BitConverter.ToInt16(wavData, num6);
array[i] = (float)num7 / 32768f;
break;
}
case 8:
array[i] = (float)(wavData[num6] - 128) / 128f;
break;
}
}
AudioClip val = AudioClip.Create("VoicevoxClip", array.Length / num, num, num2, false);
val.SetData(array, 0);
return val;
}
private static int FindDataChunk(byte[] wavData)
{
for (int i = 0; i < wavData.Length - 4; i++)
{
if (wavData[i] == 100 && wavData[i + 1] == 97 && wavData[i + 2] == 116 && wavData[i + 3] == 97)
{
return i + 8;
}
}
throw new Exception("WAV data chunk not found");
}
}
public class AddAudio
{
public static async Task AddAudioClip(string text, int speaker)
{
byte[] voiceData = await GetWav.GetWavPost(text, speaker);
AudioSource audioSource = audioObject.AddComponent<AudioSource>();
AudioClip clip = WavUtility.ToAudioClip(voiceData);
audioSource.clip = clip;
audioSource.Play();
}
}
private static string zundaText = "";
private static GameObject audioObject = new GameObject("CustomAudioPlayer");
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void Postfix()
{
Object.DontDestroyOnLoad((Object)(object)audioObject);
}
[HarmonyPatch("AddChatMessage")]
[HarmonyPostfix]
private static void GetChat(HUDManager __instance, string chatMessage, bool dontRepeat, int playerWhoSent)
{
int speakerID = ZundamonizeNoMicBase.Instance.speakerID.Value;
if ((dontRepeat && __instance.lastChatMessage == chatMessage) || (int)GameNetworkManager.Instance.localPlayerController.playerClientId == playerWhoSent)
{
return;
}
string zundaScript = "";
if (chatMessage.Length == 1)
{
zundaScript = "生存確認チャットなのだ";
}
else if (chatMessage.Length > 13 && !chatMessage.Contains(" "))
{
zundaScript = chatMessage.Replace(" ", "");
string text = "aiueoyn";
for (int i = 5; i < zundaScript.Length; i += 6)
{
char c = zundaScript[i];
while (text.Contains(c.ToString()) && i < zundaScript.Length)
{
i++;
c = zundaScript[i];
}
zundaScript = zundaScript.Insert(i, " ");
}
}
else
{
zundaScript = chatMessage;
}
ZundamonizeNoMicBase.mls.LogInfo((object)("scriptは" + zundaScript + "です"));
Task.Run(() => AddAudio.AddAudioClip(zundaScript, speakerID));
}
}
[HarmonyPatch(typeof(IngamePlayerSettings))]
internal class SetZundaVolume
{
[HarmonyPatch("SaveSettingsToPrefs")]
[HarmonyPostfix]
public static void SaveZundaVolumePatch()
{
}
[HarmonyPatch("LoadSettingsFromPrefs")]
[HarmonyPostfix]
public static void LoadZundaVolumePatch()
{
}
}
}