Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MelaniesVoice v1.7.1
com.github.zehsteam.MelaniesVoice.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalConfig.Mods; using Microsoft.CodeAnalysis; using Mirage.Domain.Audio; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Unity.Netcode; using UnityEngine; using UnityEngine.Networking; using com.github.zehsteam.MelaniesVoice.Dependencies; using com.github.zehsteam.MelaniesVoice.Extensions; using com.github.zehsteam.MelaniesVoice.Helpers; using com.github.zehsteam.MelaniesVoice.Managers; using com.github.zehsteam.MelaniesVoice.MonoBehaviours; using com.github.zehsteam.MelaniesVoice.NetcodePatcher; using com.github.zehsteam.MelaniesVoice.Objects; using com.github.zehsteam.MelaniesVoice.Objects.Config; using com.github.zehsteam.MelaniesVoice.Objects.Voices; using com.github.zehsteam.MelaniesVoice.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("LethalConfig")] [assembly: IgnoresAccessChecksTo("Mirage")] [assembly: IgnoresAccessChecksTo("Mirage.Plugin")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.zehsteam.MelaniesVoice")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2025 Zehs")] [assembly: AssemblyDescription("[v73+] Allows players to talk through Text-To-Speech (TTS) by using the in-game chat.")] [assembly: AssemblyFileVersion("1.7.1.0")] [assembly: AssemblyInformationalVersion("1.7.1+8c4053cd6b7ff3035525326c94660163e55ec054")] [assembly: AssemblyProduct("MelaniesVoice")] [assembly: AssemblyTitle("com.github.zehsteam.MelaniesVoice")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.7.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.MelaniesVoice { internal static class Assets { public static AssetBundle AssetBundle { get; private set; } public static GameObject VoiceControllerPrefab { get; private set; } public static void Load() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = "melaniesvoice_assets"; string text2 = Path.Combine(directoryName, text); if (!File.Exists(text2)) { Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file."); } else { AssetBundle val = AssetBundle.LoadFromFile(text2); if ((Object)(object)val == (Object)null) { Logger.LogFatal("Failed to load assets. AssetBundle is null."); } else { OnAssetBundleLoaded(val); } } } private static void OnAssetBundleLoaded(AssetBundle assetBundle) { AssetBundle = assetBundle; VoiceControllerPrefab = LoadAsset<GameObject>("VoiceController", assetBundle); } private static T LoadAsset<T>(string name, AssetBundle assetBundle) where T : Object { if (string.IsNullOrWhiteSpace(name)) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace."); return default(T); } if ((Object)(object)assetBundle == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null."); return default(T); } T val = assetBundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name."); return default(T); } return val; } private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset<T>(name, assetBundle); return (Object)(object)asset != (Object)null; } } internal static class Utils { [CompilerGenerated] private sealed class <WaitForTask>d__4<T> : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Task<T> task; public Action<T> result; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForTask>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!task.IsCompleted) { <>2__current = null; <>1__state = 1; return true; } if (task.IsFaulted) { throw task.Exception; } result?.Invoke(task.Result); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static string GetPluginPersistentDataPath() { return Path.Combine(Application.persistentDataPath, "MelaniesVoice"); } public static ConfigFile CreateConfigFile(BaseUnityPlugin plugin, string path, string name = null, bool saveOnInit = false) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown BepInPlugin metadata = MetadataHelper.GetMetadata((object)plugin); if (name == null) { name = metadata.GUID; } name += ".cfg"; return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata); } public static ConfigFile CreateLocalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false) { return CreateConfigFile(plugin, Paths.ConfigPath, name, saveOnInit); } public static ConfigFile CreateGlobalConfigFile(BaseUnityPlugin plugin, string name = null, bool saveOnInit = false) { string pluginPersistentDataPath = GetPluginPersistentDataPath(); if (name == null) { name = "global"; } return CreateConfigFile(plugin, pluginPersistentDataPath, name, saveOnInit); } [IteratorStateMachine(typeof(<WaitForTask>d__4<>))] public static IEnumerator WaitForTask<T>(Task<T> task, Action<T> result) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForTask>d__4<T>(0) { task = task, result = result }; } public static string SanitizeFileName(string input) { char[] invalidChars = Path.GetInvalidFileNameChars(); return string.Concat(input.Where((char c) => !invalidChars.Contains(c))); } public static void DisplayMessage(string text, bool isError = false) { string text2 = "MelaniesVoice"; if (isError) { text2 += " - ERROR"; } HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip(text2, text, isError, false, "LC_Tip1"); } } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data, bool extended = false) { Log((LogLevel)32, data, extended); } public static void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } public static void LogMessage(object data, bool extended = false) { Log((LogLevel)8, data, extended); } public static void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } public static void LogError(object data, bool extended = false) { Log((LogLevel)2, data, extended); } public static void LogFatal(object data, bool extended = false) { Log((LogLevel)1, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (!extended || IsExtendedLoggingEnabled()) { ManualLogSource manualLogSource = ManualLogSource; if (manualLogSource != null) { manualLogSource.Log(logLevel, data); } } } public static bool IsExtendedLoggingEnabled() { if (ConfigManager.ExtendedLogging == null) { return false; } return ConfigManager.ExtendedLogging.Value; } } [BepInPlugin("com.github.zehsteam.MelaniesVoice", "MelaniesVoice", "1.7.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.MelaniesVoice"); public static Plugin Instance { get; private set; } public ConfigFile Config { get; private set; } private void Awake() { Instance = this; Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.MelaniesVoice")); Logger.LogInfo("MelaniesVoice has awoken!"); Config = Utils.CreateGlobalConfigFile((BaseUnityPlugin)(object)this); _harmony.PatchAll(typeof(GameNetworkManagerPatch)); _harmony.PatchAll(typeof(StartOfRoundPatch)); _harmony.PatchAll(typeof(HUDManagerPatch)); _harmony.PatchAll(typeof(PlayerControllerBPatch)); Assets.Load(); ConfigManager.Initialize(Config); NetcodePatcherAwake(); } private void NetcodePatcherAwake() { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); Type[] types = executingAssembly.GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { try { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { try { methodInfo.Invoke(null, null); } catch (TargetInvocationException ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message)); } } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message)); } } } } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.MelaniesVoice"; public const string PLUGIN_NAME = "MelaniesVoice"; public const string PLUGIN_VERSION = "1.7.1"; } } namespace com.github.zehsteam.MelaniesVoice.Patches { [HarmonyPatch(typeof(GameNetworkManager))] internal static class GameNetworkManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { AddNetworkPrefabs(); TTSVoice_TTSMonster.FetchVoices(); } private static void AddNetworkPrefabs() { AddNetworkPrefab(Assets.VoiceControllerPrefab); } private static void AddNetworkPrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { Logger.LogError("Failed to register network prefab. GameObject is null."); return; } NetworkManager.Singleton.AddNetworkPrefab(prefab); Logger.LogInfo("Registered \"" + ((Object)prefab).name + "\" network prefab."); } } [HarmonyPatch(typeof(HUDManager))] internal static class HUDManagerPatch { [HarmonyPatch("AddTextToChatOnServer")] [HarmonyPostfix] private static void AddTextToChatOnServerPatch(string chatMessage, int playerId) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (playerId == -1 || ConfigManager.TTS_DisableMyVoice.Value || chatMessage.StartsWithAny(ConfigManager.TTS_IgnorePefixesArray)) { return; } PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript(); if (!((Object)(object)localPlayerScript == (Object)null)) { VoiceController componentInChildren = ((Component)localPlayerScript).GetComponentInChildren<VoiceController>(); if (!((Object)(object)componentInChildren == (Object)null)) { componentInChildren.CreateVoiceMessage_ServerRpc(ConfigManager.TTS_Voice.Value, chatMessage); } } } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class PlayerControllerBPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(PlayerControllerB __instance) { if (NetworkUtils.IsServer) { GameObject val = Object.Instantiate<GameObject>(Assets.VoiceControllerPrefab, ((Component)__instance).transform); NetworkObject component = val.GetComponent<NetworkObject>(); component.DontDestroyWithOwner = true; component.SpawnWithOwnership(__instance.actualClientId, false); component.TrySetParent(((Component)__instance).transform, true); } } [HarmonyPatch("OnDestroy")] [HarmonyPrefix] private static void OnDestroyPatch(PlayerControllerB __instance) { if (NetworkUtils.IsServer) { VoiceController componentInChildren = ((Component)__instance).GetComponentInChildren<VoiceController>(); NetworkObject val = default(NetworkObject); if (!((Object)(object)componentInChildren == (Object)null) && ((Component)componentInChildren).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned) { val.Despawn(true); } } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPatch("OnClientConnect")] [HarmonyPostfix] private static void OnClientConnectPatch(ulong clientId) { PlayerControllerB playerScriptByClientId = PlayerUtils.GetPlayerScriptByClientId(clientId); if (!((Object)(object)playerScriptByClientId == (Object)null)) { VoiceController componentInChildren = ((Component)playerScriptByClientId).GetComponentInChildren<VoiceController>(); NetworkObject val = default(NetworkObject); if (!((Object)(object)componentInChildren == (Object)null) && ((Component)componentInChildren).TryGetComponent<NetworkObject>(ref val) && val.IsSpawned) { val.ChangeOwnership(playerScriptByClientId.actualClientId); } } } } } namespace com.github.zehsteam.MelaniesVoice.Objects { public class PlayerAudioGroup { public AudioSource VoiceAudio { get; private set; } public AudioSource DeadAudio { get; private set; } public bool IsPlaying => VoiceAudio.isPlaying; public float Volume { get { return VoiceAudio.volume; } set { VoiceAudio.volume = value; DeadAudio.volume = value; } } public float MaxDistance { get { return VoiceAudio.maxDistance; } set { VoiceAudio.maxDistance = value; DeadAudio.maxDistance = value; } } public AudioClip Clip { get { return VoiceAudio.clip; } set { VoiceAudio.clip = value; DeadAudio.clip = value; } } public bool Mute { get { if (VoiceAudio.mute) { return DeadAudio.mute; } return false; } set { VoiceAudio.mute = value; DeadAudio.mute = value; } } public PlayerAudioGroup(AudioSource voiceAudio, AudioSource deadAudio) { VoiceAudio = voiceAudio; DeadAudio = deadAudio; } public void Play() { AudioSource voiceAudio = VoiceAudio; if (voiceAudio != null) { voiceAudio.Play(); } AudioSource deadAudio = DeadAudio; if (deadAudio != null) { deadAudio.Play(); } } public void Pause() { AudioSource voiceAudio = VoiceAudio; if (voiceAudio != null) { voiceAudio.Pause(); } AudioSource deadAudio = DeadAudio; if (deadAudio != null) { deadAudio.Pause(); } } public void Stop() { AudioSource voiceAudio = VoiceAudio; if (voiceAudio != null) { voiceAudio.Stop(); } AudioSource deadAudio = DeadAudio; if (deadAudio != null) { deadAudio.Stop(); } } } public struct RequestHeader { public string Name { get; set; } public string Value { get; set; } public RequestHeader(string name, string value) { Name = name; Value = value; } } public class VoiceMessage { public int Channels = 1; public int SampleRate = 48000; private float _timer; public int Id { get; private set; } public string VoiceName { get; private set; } public string Message { get; private set; } public AudioClip AudioClip { get; set; } public List<ulong> ClientsReceivedAudioClip { get; private set; } = new List<ulong>(); public List<float> BufferedSamples { get; private set; } = new List<float>(); public bool IsClipBuilt { get; private set; } public bool HasBufferedAudio => BufferedSamples.Count > 0; public bool IsReady { get { if (!ClientsReceivedAudioClip.Contains(NetworkUtils.GetLocalClientId())) { return false; } return ClientsReceivedAudioClip.Count >= NetworkUtils.ConnectedPlayerCount; } } public bool IsTimedout => _timer >= ConfigManager.TTS_RequestTimeoutDuration.Value; public VoiceMessage(int id, string voiceName, string message) { Id = id; VoiceName = voiceName; Message = message; } public void Tick() { _timer += Time.deltaTime; } public void BuildClipIfNeeded() { if (!IsClipBuilt && BufferedSamples.Count != 0) { AudioClip = AudioClip.Create($"VoiceMessage_{Id}", BufferedSamples.Count / Channels, Channels, SampleRate, false); AudioClip.SetData(BufferedSamples.ToArray(), 0); IsClipBuilt = true; } } public override string ToString() { return $"(Id: {Id}, VoiceName: \"{VoiceName}\", Message: \"{Message}\")"; } } } namespace com.github.zehsteam.MelaniesVoice.Objects.Voices { public enum VoiceService { Unknown = -1, Streamlabs, LazyPy, TTSMonster } public abstract class TTSVoice { protected const int DEFAULT_VOLUME = 100; protected static string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 OPR/123.0.0.0"; public string Name { get; protected set; } public string VoiceId { get; protected set; } public int DefaultVolume { get; protected set; } = 100; public abstract VoiceService Service { get; } protected TTSVoice(string name, string voiceId, int defaultVolume = 100) { Name = name; VoiceId = voiceId; DefaultVolume = defaultVolume; } public virtual void RequestAudio(string text, Action<AudioClip> onClipReady) { CoroutineRunner.Start(RequestAudioCoroutine(text, onClipReady)); } public abstract IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady); protected async Task<JObject> FetchJsonAsync(string url, WWWForm form, List<RequestHeader> requestHeaders = null) { LogInfo("Sending POST request to \"" + url + "\"", extended: true); UnityWebRequest www = UnityWebRequest.Post(url, form); try { www.SetRequestHeader("User-Agent", UserAgent); if (requestHeaders != null) { foreach (RequestHeader requestHeader in requestHeaders) { www.SetRequestHeader(requestHeader.Name, requestHeader.Value); } } UnityWebRequestAsyncOperation operation = www.SendWebRequest(); while (!((AsyncOperation)operation).isDone) { await Task.Yield(); } if ((int)www.result == 4) { LogError("Failed to process data: " + www.error, extended: false, displayMessage: true); return null; } if ((int)www.result != 1) { LogError("Failed to fetch audio: " + www.error, extended: false, displayMessage: true); return null; } string text = www.downloadHandler.text; try { JObject val = JObject.Parse(text); LogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true); return val; } catch (Exception arg) { LogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}"); DisplayMessage("Failed to parse response. Check logs", isError: true); return null; } } finally { ((IDisposable)www)?.Dispose(); } } protected async Task<JObject> FetchJsonAsync(string url, JObject body, List<RequestHeader> requestHeaders = null) { LogInfo("Sending POST request to \"" + url + "\"", extended: true); string s = ((body != null) ? ((JToken)body).ToString((Formatting)0, Array.Empty<JsonConverter>()) : "{}"); byte[] bytes = Encoding.UTF8.GetBytes(s); UnityWebRequest www = new UnityWebRequest(url, "POST"); try { www.uploadHandler = (UploadHandler)new UploadHandlerRaw(bytes); www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer(); www.SetRequestHeader("Content-Type", "application/json"); www.SetRequestHeader("User-Agent", UserAgent); if (requestHeaders != null) { foreach (RequestHeader requestHeader in requestHeaders) { www.SetRequestHeader(requestHeader.Name, requestHeader.Value); } } UnityWebRequestAsyncOperation operation = www.SendWebRequest(); while (!((AsyncOperation)operation).isDone) { await Task.Yield(); } if ((int)www.result == 4) { LogError("Failed to process data: " + www.error, extended: false, displayMessage: true); return null; } if ((int)www.result != 1) { LogError("Failed to fetch audio: " + www.error, extended: false, displayMessage: true); LogError(www.downloadHandler.text, extended: true); return null; } string text = www.downloadHandler.text; try { JObject val = JObject.Parse(text); LogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true); return val; } catch (Exception arg) { LogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}"); DisplayMessage("Failed to parse response. Check logs", isError: true); return null; } } finally { ((IDisposable)www)?.Dispose(); } } protected async Task<AudioClip> DownloadAudioClipAsync(string url, AudioType audioType = 13) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) LogInfo("Sending GET request to \"" + url + "\"", extended: true); UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, audioType); try { www.SetRequestHeader("User-Agent", UserAgent); UnityWebRequestAsyncOperation operation = www.SendWebRequest(); while (!((AsyncOperation)operation).isDone) { await Task.Yield(); } if ((int)www.result != 1) { LogError("Failed to download audio: " + www.error, extended: false, displayMessage: true); return null; } try { AudioClip content = DownloadHandlerAudioClip.GetContent(www); ((Object)content).name = string.Format("{0}_{1}_{2}", "MelaniesVoice", Utils.SanitizeFileName(Name), Guid.NewGuid()); return content; } catch (Exception ex) { LogError("Failed to download audio: " + ex.Message, extended: false, displayMessage: true); return null; } } finally { ((IDisposable)www)?.Dispose(); } } protected void DisplayMessage(string text, bool isError = false) { Utils.DisplayMessage(text, isError); } public override string ToString() { return $"(Name: \"{Name}\", Service: {Service}, VoiceId: \"{VoiceId}\")"; } protected void Log(LogLevel logLevel, object data, bool extended = false, bool displayMessage = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 Logger.Log(logLevel, $"[{GetType().Name}] [{Name}] {data}", extended); if (displayMessage) { DisplayMessage(data.ToString(), (int)logLevel == 2); } } protected void LogInfo(object data, bool extended = false, bool displayMessage = false) { Log((LogLevel)16, data, extended, displayMessage); } protected void LogWarning(object data, bool extended = false, bool displayMessage = false) { Log((LogLevel)4, data, extended, displayMessage); } protected void LogError(object data, bool extended = false, bool displayMessage = false) { Log((LogLevel)2, data, extended, displayMessage); } } public class TTSVoice_LazyPy : TTSVoice { [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public JObject responseJson; public Action<AudioClip> onClipReady; internal void <RequestAudioCoroutine>b__0(JObject result) { responseJson = result; } internal void <RequestAudioCoroutine>b__1(AudioClip clip) { onClipReady?.Invoke(clip); } } [CompilerGenerated] private sealed class <RequestAudioCoroutine>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action<AudioClip> onClipReady; public TTSVoice_LazyPy <>4__this; public string text; private <>c__DisplayClass7_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RequestAudioCoroutine>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown int num = <>1__state; TTSVoice_LazyPy tTSVoice_LazyPy = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass7_0(); <>8__1.onClipReady = onClipReady; string url = "https://lazypy.ro/tts/request_tts.php"; WWWForm val = new WWWForm(); val.AddField("service", tTSVoice_LazyPy.RedirectService); val.AddField("voice", tTSVoice_LazyPy.VoiceId); val.AddField("text", this.text); Task<JObject> task2 = tTSVoice_LazyPy.FetchJsonAsync(url, val); <>8__1.responseJson = null; <>2__current = Utils.WaitForTask(task2, delegate(JObject result) { <>8__1.responseJson = result; }); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (<>8__1.responseJson == null) { tTSVoice_LazyPy.LogError("Failed to request audio. Response from server is invalid."); <>8__1.onClipReady?.Invoke(null); return false; } JToken obj = <>8__1.responseJson["success"]; if (obj == null || !obj.ToObject<bool>()) { string text = ((object)<>8__1.responseJson["error_msg"])?.ToString(); tTSVoice_LazyPy.LogError("Failed to fetch audio: " + text); tTSVoice_LazyPy.DisplayMessage(text, isError: true); <>8__1.onClipReady?.Invoke(null); return false; } string text2 = ((object)<>8__1.responseJson["audio_url"])?.ToString(); if (string.IsNullOrEmpty(text2)) { tTSVoice_LazyPy.LogError("Failed to fetch audio: 'audio_url' is missing.", extended: false, displayMessage: true); <>8__1.onClipReady?.Invoke(null); return false; } Task<AudioClip> task = tTSVoice_LazyPy.DownloadAudioClipAsync(text2, (AudioType)13); <>2__current = Utils.WaitForTask(task, delegate(AudioClip clip) { <>8__1.onClipReady?.Invoke(clip); }); <>1__state = 2; return true; } case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public override VoiceService Service => VoiceService.LazyPy; public string RedirectService { get; protected set; } public TTSVoice_LazyPy(string name, string redirectService, string voiceId, int defaultVolume = 100) : base(name, voiceId, defaultVolume) { RedirectService = redirectService; } [IteratorStateMachine(typeof(<RequestAudioCoroutine>d__7))] public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RequestAudioCoroutine>d__7(0) { <>4__this = this, text = text, onClipReady = onClipReady }; } } public class TTSVoice_Streamlabs : TTSVoice { [CompilerGenerated] private sealed class <>c__DisplayClass3_0 { public JObject responseJson; public Action<AudioClip> onClipReady; internal void <RequestAudioCoroutine>b__0(JObject result) { responseJson = result; } internal void <RequestAudioCoroutine>b__1(AudioClip clip) { onClipReady?.Invoke(clip); } } [CompilerGenerated] private sealed class <RequestAudioCoroutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action<AudioClip> onClipReady; public TTSVoice_Streamlabs <>4__this; public string text; private <>c__DisplayClass3_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RequestAudioCoroutine>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown int num = <>1__state; TTSVoice_Streamlabs tTSVoice_Streamlabs = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass3_0(); <>8__1.onClipReady = onClipReady; string url = "https://streamlabs.com/tts/polly/speak"; WWWForm val = new WWWForm(); val.AddField("voice", tTSVoice_Streamlabs.VoiceId); val.AddField("text", this.text); Task<JObject> task2 = tTSVoice_Streamlabs.FetchJsonAsync(url, val); <>8__1.responseJson = null; <>2__current = Utils.WaitForTask(task2, delegate(JObject result) { <>8__1.responseJson = result; }); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (<>8__1.responseJson == null) { tTSVoice_Streamlabs.LogError("Failed to request audio. Response from server is invalid."); <>8__1.onClipReady?.Invoke(null); return false; } JToken obj = <>8__1.responseJson["success"]; if (obj == null || !obj.ToObject<bool>()) { string text = ((object)<>8__1.responseJson["message"])?.ToString(); tTSVoice_Streamlabs.LogError("Failed to fetch audio: " + (object)<>8__1.responseJson["message"]); tTSVoice_Streamlabs.DisplayMessage(text, isError: true); <>8__1.onClipReady?.Invoke(null); return false; } string text2 = ((object)<>8__1.responseJson["speak_url"])?.ToString(); if (string.IsNullOrEmpty(text2)) { tTSVoice_Streamlabs.LogError("Failed to fetch audio: 'speak_url' is missing.", extended: false, displayMessage: true); <>8__1.onClipReady?.Invoke(null); return false; } Task<AudioClip> task = tTSVoice_Streamlabs.DownloadAudioClipAsync(text2, (AudioType)13); <>2__current = Utils.WaitForTask(task, delegate(AudioClip clip) { <>8__1.onClipReady?.Invoke(clip); }); <>1__state = 2; return true; } case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public override VoiceService Service => VoiceService.Streamlabs; public TTSVoice_Streamlabs(string name, string voiceId, int defaultVolume = 100) : base(name, voiceId, defaultVolume) { } [IteratorStateMachine(typeof(<RequestAudioCoroutine>d__3))] public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RequestAudioCoroutine>d__3(0) { <>4__this = this, text = text, onClipReady = onClipReady }; } } public class TTSVoice_TTSMonster : TTSVoice { [CompilerGenerated] private sealed class <>c__DisplayClass5_0 { public JObject responseJson; public Action<AudioClip> onClipReady; internal void <RequestAudioCoroutine>b__0(JObject result) { responseJson = result; } internal void <RequestAudioCoroutine>b__1(AudioClip clip) { onClipReady?.Invoke(clip); } } [CompilerGenerated] private sealed class <>c__DisplayClass8_0 { public JObject responseJson; internal void <FetchVoicesCoroutine>b__0(JObject result) { responseJson = result; } } [CompilerGenerated] private sealed class <FetchVoicesCoroutine>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private <>c__DisplayClass8_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FetchVoicesCoroutine>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass8_0(); string value = ConfigManager.TTSMonster_APIKey.Value; if (string.IsNullOrEmpty(value)) { StaticLogError("Failed to fetch voices. TTS.Monster API key required. Set in config file."); return false; } Task<JObject> task = FetchVoicesJsonAsync(value); <>8__1.responseJson = null; <>2__current = Utils.WaitForTask(task, delegate(JObject result) { <>8__1.responseJson = result; }); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (<>8__1.responseJson == null) { StaticLogError("Failed to fetch voices. Response from server is invalid."); return false; } List<TTSMonsterVoice> list = ParseVoicesJson(<>8__1.responseJson); if (list.Count == 0) { StaticLogError("Failed to fetch voices. No voices found from response data."); return false; } List<TTSVoice_TTSMonster> list2 = ConvertToTTSVoices(list); if (list2.Count == 0) { StaticLogError("Failed to fetch voices. Could not convert TTSMonsterVoice(s) to TTSVoice_TTSMonster(s)"); return false; } UpdateExistingVoicesData(list2); List<TTSVoice_TTSMonster> list3 = TextToSpeech.AddVoices(list2, logErrors: false); if (list3.Count > 0) { VoiceConfigManager.BindConfigs(list3); ConfigManager.UpdateTTSVoiceAcceptableValues(); } StaticLogInfo($"Found {list.Count} voices. Registered {list3.Count} new voices."); return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RequestAudioCoroutine>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Action<AudioClip> onClipReady; public TTSVoice_TTSMonster <>4__this; public string text; private <>c__DisplayClass5_0 <>8__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RequestAudioCoroutine>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown int num = <>1__state; TTSVoice_TTSMonster tTSVoice_TTSMonster = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; <>8__1 = new <>c__DisplayClass5_0(); <>8__1.onClipReady = onClipReady; string url = "https://api.console.tts.monster/generate"; string value = ConfigManager.TTSMonster_APIKey.Value; if (string.IsNullOrEmpty(value)) { tTSVoice_TTSMonster.LogError("TTS.Monster API key required. Set in config file.", extended: false, displayMessage: true); <>8__1.onClipReady?.Invoke(null); return false; } List<RequestHeader> requestHeaders = new List<RequestHeader>(1) { new RequestHeader("Authorization", value) }; JObject body = new JObject { ["voice_id"] = JToken.op_Implicit(tTSVoice_TTSMonster.VoiceId), ["message"] = JToken.op_Implicit(this.text) }; Task<JObject> task2 = tTSVoice_TTSMonster.FetchJsonAsync(url, body, requestHeaders); <>8__1.responseJson = null; <>2__current = Utils.WaitForTask(task2, delegate(JObject result) { <>8__1.responseJson = result; }); <>1__state = 1; return true; } case 1: { <>1__state = -1; if (<>8__1.responseJson == null) { tTSVoice_TTSMonster.LogError("Failed to request audio. Response from server is invalid."); <>8__1.onClipReady?.Invoke(null); return false; } JToken obj = <>8__1.responseJson["status"]; int num2 = ((obj != null) ? obj.ToObject<int>() : 0); if (num2 != 200) { string text = num2 switch { 401 => "Unauthorized: Invalid API key", 402 => "Character quota exceeded. Upgrade your account or turn on usage-based-billing", 429 => "Too many requests. Try again later", 500 => "Internal server error", _ => $"Unknown error. Code {num2}", }; tTSVoice_TTSMonster.LogError("Failed to fetch audio: " + text); tTSVoice_TTSMonster.DisplayMessage(text, isError: true); <>8__1.onClipReady?.Invoke(null); return false; } string text2 = ((object)<>8__1.responseJson["url"])?.ToString(); if (string.IsNullOrEmpty(text2)) { tTSVoice_TTSMonster.LogError("Failed to fetch audio: 'url' is missing.", extended: false, displayMessage: true); <>8__1.onClipReady?.Invoke(null); return false; } Task<AudioClip> task = tTSVoice_TTSMonster.DownloadAudioClipAsync(text2, (AudioType)20); <>2__current = Utils.WaitForTask(task, delegate(AudioClip clip) { <>8__1.onClipReady?.Invoke(clip); }); <>1__state = 2; return true; } case 2: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Dictionary<string, string> _voiceNameProxies; public override VoiceService Service => VoiceService.TTSMonster; static TTSVoice_TTSMonster() { _voiceNameProxies = new Dictionary<string, string>(); _voiceNameProxies.Add("Chef", "Gordon Ramsay"); _voiceNameProxies.Add("Circuit", "Linus Tech Tips"); _voiceNameProxies.Add("Dash", "Sonic"); _voiceNameProxies.Add("Diplomat", "Joe Biden"); _voiceNameProxies.Add("Elder", "Morgan Freeman"); _voiceNameProxies.Add("Frogman", "Kermit"); _voiceNameProxies.Add("Gravel", "MoistCr1TiKaL"); _voiceNameProxies.Add("Leader", "Obama"); _voiceNameProxies.Add("Micro", "Plankton"); _voiceNameProxies.Add("Oracle", "GLaDOS"); _voiceNameProxies.Add("Phantom", "Vega"); _voiceNameProxies.Add("Scout", "Bart Simpson"); _voiceNameProxies.Add("Spongey", "Sponge Bob"); _voiceNameProxies.Add("Star", "Patrick Star"); _voiceNameProxies.Add("Tentacle", "Squidward"); _voiceNameProxies.Add("Tycoon", "Donald Trump"); } public TTSVoice_TTSMonster(string name, string voiceId, int defaultVolume = 100) : base(name, voiceId, defaultVolume) { } [IteratorStateMachine(typeof(<RequestAudioCoroutine>d__5))] public override IEnumerator RequestAudioCoroutine(string text, Action<AudioClip> onClipReady) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RequestAudioCoroutine>d__5(0) { <>4__this = this, text = text, onClipReady = onClipReady }; } public static List<TTSVoice_TTSMonster> CreateDefaultVoices() { try { JObject val = PluginResourceHelper.ReadJObject("Data/TTSMonsterVoicesDefault.json"); if (val == null) { return new List<TTSVoice_TTSMonster>(); } return ConvertToTTSVoices(ParseVoicesJson(val)); } catch (Exception arg) { StaticLogError($"Failed to load default voices. {arg}"); return new List<TTSVoice_TTSMonster>(); } } public static void FetchVoices() { CoroutineRunner.Start(FetchVoicesCoroutine()); } [IteratorStateMachine(typeof(<FetchVoicesCoroutine>d__8))] public static IEnumerator FetchVoicesCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FetchVoicesCoroutine>d__8(0); } protected static async Task<JObject> FetchVoicesJsonAsync(string apiKey) { string text = "https://api.console.tts.monster/voices"; StaticLogInfo("Sending POST request to \"" + text + "\"", extended: true); UnityWebRequest www = UnityWebRequest.Post(text, new WWWForm()); try { www.SetRequestHeader("User-Agent", TTSVoice.UserAgent); www.SetRequestHeader("Authorization", apiKey); UnityWebRequestAsyncOperation operation = www.SendWebRequest(); while (!((AsyncOperation)operation).isDone) { await Task.Yield(); } if ((int)www.result == 4) { StaticLogError("Failed to process voices data: " + www.error); return null; } if ((int)www.result != 1) { StaticLogError("Failed to fetch voices: " + www.error); return null; } string text2 = www.downloadHandler.text; try { JObject val = JObject.Parse(text2); StaticLogInfo("Response data:\n" + JsonConvert.SerializeObject((object)val, (Formatting)1), extended: true); return val; } catch (Exception arg) { StaticLogError($"Failed to parse response as JSON:\n\nResponse:\n\"{text2}\"\n\nError:\n{arg}"); return null; } } finally { ((IDisposable)www)?.Dispose(); } } protected static void UpdateExistingVoicesData(List<TTSVoice_TTSMonster> voices) { List<TTSVoice_TTSMonster> list = (from x in TextToSpeech.GetVoicesByService(VoiceService.TTSMonster) select x as TTSVoice_TTSMonster into x where x != null select x).ToList(); foreach (TTSVoice_TTSMonster existingVoice in list) { TTSVoice_TTSMonster tTSVoice_TTSMonster = voices.FirstOrDefault((TTSVoice_TTSMonster x) => x.Name == existingVoice.Name); if (tTSVoice_TTSMonster != null && existingVoice.VoiceId != tTSVoice_TTSMonster.VoiceId) { existingVoice.VoiceId = tTSVoice_TTSMonster.VoiceId; StaticLogInfo("Updated already registerd voice \"" + existingVoice.Name + "\" VoiceId to \"" + tTSVoice_TTSMonster.VoiceId + "\"", extended: true); } } } protected static string GetProxyName(string name) { return _voiceNameProxies.GetValueOrDefault(name, name); } protected static List<TTSMonsterVoice> ParseVoicesJson(string text) { try { JObject data = JObject.Parse(text); return ParseVoicesJson(data); } catch (Exception arg) { StaticLogError($"Failed to parse text as JSON:\n\nResponse:\n\"{text}\"\n\nError:\n{arg}"); return new List<TTSMonsterVoice>(); } } protected static List<TTSMonsterVoice> ParseVoicesJson(JObject data) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown List<TTSMonsterVoice> list = new List<TTSMonsterVoice>(); string text = "TTSM - "; JToken obj = data["customVoices"]; JArray val = (JArray)(object)((obj is JArray) ? obj : null); JToken obj2 = data["voices"]; JArray val2 = (JArray)(object)((obj2 is JArray) ? obj2 : null); foreach (JObject item in val) { JObject val3 = item; string text2 = ((object)val3["name"])?.ToString(); string text3 = ((object)val3["voice_id"])?.ToString(); if (!string.IsNullOrEmpty(text2) && !string.IsNullOrEmpty(text3)) { list.Add(new TTSMonsterVoice(text + text2, text3, isCustom: true)); } } foreach (JObject item2 in val2) { JObject val4 = item2; string text4 = ((object)val4["name"])?.ToString(); string text5 = ((object)val4["voice_id"])?.ToString(); if (!string.IsNullOrEmpty(text4) && !string.IsNullOrEmpty(text5)) { list.Add(new TTSMonsterVoice(text + GetProxyName(text4), text5)); } } return list; } protected static List<TTSVoice_TTSMonster> ConvertToTTSVoices(List<TTSMonsterVoice> ttsMonsterVoices) { List<TTSVoice_TTSMonster> list = new List<TTSVoice_TTSMonster>(); foreach (TTSMonsterVoice ttsMonsterVoice in ttsMonsterVoices) { TTSVoice_TTSMonster tTSVoice_TTSMonster = ConvertToTTSVoice(ttsMonsterVoice); if (tTSVoice_TTSMonster != null) { list.Add(tTSVoice_TTSMonster); } } return list; } protected static TTSVoice_TTSMonster ConvertToTTSVoice(TTSMonsterVoice ttsMonsterVoice) { if (!ttsMonsterVoice.IsValid()) { return null; } return new TTSVoice_TTSMonster(ttsMonsterVoice.Name, ttsMonsterVoice.VoiceId); } public static void OpenLoginWebpage() { Application.OpenURL("https://console.tts.monster/login"); } protected static void StaticLog(LogLevel logLevel, object data, bool extended = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Logger.Log(logLevel, string.Format("[{0}] {1}", "TTSVoice_TTSMonster", data), extended); } protected static void StaticLogInfo(object data, bool extended = false) { StaticLog((LogLevel)16, data, extended); } protected static void StaticLogWarning(object data, bool extended = false) { StaticLog((LogLevel)4, data, extended); } protected static void StaticLogError(object data, bool extended = false) { StaticLog((LogLevel)2, data, extended); } } public struct TTSMonsterVoice { public string Name { get; set; } public string VoiceId { get; set; } public bool IsCustom { get; set; } public TTSMonsterVoice(string name, string voiceId, bool isCustom = false) { Name = name; VoiceId = voiceId; IsCustom = isCustom; } public bool IsValid() { if (!string.IsNullOrEmpty(Name)) { return !string.IsNullOrEmpty(VoiceId); } return false; } public override string ToString() { return $"(Name: \"{Name}\", IsCustom: {IsCustom}, VoiceId: \"{VoiceId}\")"; } } } namespace com.github.zehsteam.MelaniesVoice.Objects.Config { public class VoiceConfigEntry { public TTSVoice Voice { get; private set; } public ConfigEntry<int> Volume { get; private set; } public VoiceConfigEntry(TTSVoice voice, int defaultVolume) { Bind(voice, defaultVolume); } private void Bind(TTSVoice voice, int defaultVolume) { Voice = voice; string section = "Voice: " + Voice.Name; Volume = ConfigHelper.Bind(section, "Volume", defaultVolume, "The volume of the voice.", requiresRestart: false, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200)); } } } namespace com.github.zehsteam.MelaniesVoice.MonoBehaviours { internal class CoroutineRunner : MonoBehaviour { public static CoroutineRunner Instance { get; private set; } public static void Spawn() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance != (Object)null)) { new GameObject("MelaniesVoice CoroutineRunner", new Type[1] { typeof(CoroutineRunner) }); } } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Object)this).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)this); } public static Coroutine Start(IEnumerator routine) { if ((Object)(object)Instance == (Object)null) { Spawn(); } CoroutineRunner instance = Instance; return ((instance != null) ? ((MonoBehaviour)instance).StartCoroutine(routine) : null) ?? null; } public static void Stop(IEnumerator routine) { if (!((Object)(object)Instance == (Object)null)) { ((MonoBehaviour)Instance).StopCoroutine(routine); } } public static void Stop(Coroutine routine) { if (!((Object)(object)Instance == (Object)null)) { ((MonoBehaviour)Instance).StopCoroutine(routine); } } } public class VoiceController : NetworkBehaviour { [CompilerGenerated] private sealed class <StreamAudio_Local>d__35 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioClip clip; public VoiceMessage voiceMessage; public VoiceController <>4__this; private float[] <data>5__2; private int <pos>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <StreamAudio_Local>d__35(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <data>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; VoiceController voiceController = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if ((Object)(object)clip == (Object)null) { return false; } voiceMessage.AudioClip = clip; if (NetworkUtils.ConnectedPlayerCount == 1) { voiceController.ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id); return false; } <data>5__2 = new float[clip.samples * clip.channels]; clip.GetData(<data>5__2, 0); <pos>5__3 = 0; break; case 1: <>1__state = -1; break; } if (<pos>5__3 < <data>5__2.Length) { int num2 = Mathf.Min(voiceController._chunkSize, <data>5__2.Length - <pos>5__3); float[] array = new float[num2]; Array.Copy(<data>5__2, <pos>5__3, array, 0, num2); voiceController.StreamAudioChunk_ServerRpc(voiceMessage.Id, array, clip.channels, clip.frequency); <pos>5__3 += num2; <>2__current = null; <>1__state = 1; return true; } voiceController.StreamAudioComplete_ServerRpc(voiceMessage.Id); voiceController.ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly List<VoiceController> _instances = new List<VoiceController>(); [SerializeField] private AudioSource _voiceAudio; [SerializeField] private AudioSource _deadAudio; private List<VoiceMessage> _voiceMessageQueue = new List<VoiceMessage>(); private float _noiseRange = 30f; private float _noiseLoudness = 0.7f; private float _noiseTimer; private float _noiseCooldown = 0.2f; private readonly int _chunkSize = 480; public static IReadOnlyList<VoiceController> Instances => _instances; public PlayerAudioGroup PlayerAudioGroup { get; private set; } public PlayerControllerB PlayerScript { get; private set; } public bool IsLocal => PlayerUtils.IsLocalPlayer(PlayerScript); private void OnEnable() { if (!_instances.Contains(this)) { _instances.Add(this); } } private void OnDisable() { _instances.Remove(this); } private void Start() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB playerScript = default(PlayerControllerB); if ((Object)(object)((Component)this).transform.parent == (Object)null) { LogError("Failed to initialize. Transform parent is null."); if (NetworkUtils.IsServer) { ((Component)this).GetComponent<NetworkObject>().Despawn(true); } } else if (!((Component)((Component)this).transform.parent).TryGetComponent<PlayerControllerB>(ref playerScript)) { LogError("Failed to initialize. PlayerControllerB is null."); if (NetworkUtils.IsServer) { ((Component)this).GetComponent<NetworkObject>().Despawn(true); } } else { PlayerScript = playerScript; ((Component)this).transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); PlayerAudioGroup = new PlayerAudioGroup(_voiceAudio, _deadAudio); PlayerAudioGroup.Volume = 1f; ApplySettings(); LogInfo("Initialized.", extended: true); } } private void Update() { VoiceMessageTick(); NoiseTick(); } private void VoiceMessageTick() { if (!NetworkUtils.IsServer || PlayerAudioGroup == null || IsPlayingVoiceMessage() || _voiceMessageQueue.Count == 0) { return; } VoiceMessage voiceMessage = _voiceMessageQueue[0]; if (voiceMessage == null) { _voiceMessageQueue.RemoveAt(0); return; } if (voiceMessage.IsReady) { PlayVoiceMessage_ClientRpc(voiceMessage.Id); return; } voiceMessage.Tick(); if (voiceMessage.IsTimedout) { VoiceMessageTimedout_Server(voiceMessage.Id); } } private void NoiseTick() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (NetworkUtils.IsServer && PlayerAudioGroup != null && PlayerAudioGroup.IsPlaying && !((Object)(object)PlayerScript == (Object)null)) { if (_noiseTimer >= _noiseCooldown) { _noiseTimer = 0f; RoundManager.Instance.PlayAudibleNoise(((Component)PlayerScript).transform.position, _noiseRange, _noiseLoudness, 0, PlayerScript.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed, 75); } else { _noiseTimer += Time.deltaTime; } } } private void UpdateVoiceMute() { if ((Object)(object)PlayerScript == (Object)null || PlayerAudioGroup == null) { return; } if (IsLocal) { PlayerAudioGroup.Mute = !ConfigManager.TTS_HearMyself.Value; if (!PlayerAudioGroup.Mute) { PlayerAudioGroup.VoiceAudio.mute = PlayerScript.isPlayerDead; PlayerAudioGroup.DeadAudio.mute = !PlayerScript.isPlayerDead; } } else { PlayerAudioGroup.VoiceAudio.mute = PlayerScript.isPlayerDead; PlayerControllerB localPlayerScript = PlayerUtils.GetLocalPlayerScript(); if ((Object)(object)localPlayerScript == (Object)null || !localPlayerScript.isPlayerDead) { PlayerAudioGroup.DeadAudio.mute = true; } else { PlayerAudioGroup.DeadAudio.mute = !PlayerScript.isPlayerDead; } } } private bool IsPlayingVoiceMessage() { return PlayerAudioGroup.IsPlaying; } private VoiceMessage GetVoiceMessage(int id) { return _voiceMessageQueue.FirstOrDefault((VoiceMessage x) => x.Id == id); } [ServerRpc] public void CreateVoiceMessage_ServerRpc(string voiceName, string message, ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Invalid comparison between Unknown and I4 //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2160464779u, serverRpcParams, (RpcDelivery)0); bool flag = voiceName != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val)).WriteValueSafe(voiceName, false); } bool flag2 = message != null; ((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val)).WriteValueSafe(message, false); } ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2160464779u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId) && !((Object)(object)PlayerScript == (Object)null) && PlayerScript.actualClientId == senderClientId) { int id = Random.Range(0, 1000000); CreateVoiceMessage_ClientRpc(id, voiceName, message); } } } [ClientRpc] private void CreateVoiceMessage_ClientRpc(int id, string voiceName, string message) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1380029231u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); bool flag = voiceName != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(voiceName, false); } bool flag2 = message != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives)); if (flag2) { ((FastBufferWriter)(ref val2)).WriteValueSafe(message, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1380029231u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; int id2 = id; string voiceName2 = voiceName; VoiceMessage voiceMessage = new VoiceMessage(id2, voiceName2, message); _voiceMessageQueue.Add(voiceMessage); LogInfo($"Created VoiceMessage. {voiceMessage}", extended: true); if (!IsLocal) { return; } TextToSpeech.RequestAudio(voiceMessage.VoiceName, voiceMessage.Message, delegate(AudioClip clip) { if ((Object)(object)clip == (Object)null) { DeleteVoiceMessage_ServerRpc(id2); } else { ((Object)clip).name = string.Format("{0}_{1}_{2}", "MelaniesVoice", Utils.SanitizeFileName(voiceName2), id2); ((MonoBehaviour)this).StartCoroutine(StreamAudio_Local(voiceMessage, clip)); if (MirageProxy.Enabled) { MirageProxy.SaveAudioClip(clip); } } }); } [ServerRpc] private void DeleteVoiceMessage_ServerRpc(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4045068609u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4045068609u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; DeleteVoiceMessage_ClientRpc(id); DeleteVoiceMessage_Local(id); } } [ClientRpc] private void DeleteVoiceMessage_ClientRpc(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2880339731u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2880339731u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; if (!NetworkUtils.IsServer) { DeleteVoiceMessage_Local(id); } } } private void DeleteVoiceMessage_Local(int id) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage != null) { _voiceMessageQueue.Remove(voiceMessage); } } [IteratorStateMachine(typeof(<StreamAudio_Local>d__35))] private IEnumerator StreamAudio_Local(VoiceMessage voiceMessage, AudioClip clip) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <StreamAudio_Local>d__35(0) { <>4__this = this, voiceMessage = voiceMessage, clip = clip }; } [ServerRpc] private void StreamAudioChunk_ServerRpc(int id, float[] chunk, int channels, int sampleRate) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Invalid comparison between Unknown and I4 //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1252295788u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); bool flag = chunk != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(chunk, default(ForPrimitives)); } BytePacker.WriteValueBitPacked(val2, channels); BytePacker.WriteValueBitPacked(val2, sampleRate); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1252295788u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; StreamAudioChunk_ClientRpc(id, chunk, channels, sampleRate); } } [ClientRpc] private void StreamAudioChunk_ClientRpc(int id, float[] chunk, int channels, int sampleRate) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2319454299u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); bool flag = chunk != null; ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe<float>(chunk, default(ForPrimitives)); } BytePacker.WriteValueBitPacked(val2, channels); BytePacker.WriteValueBitPacked(val2, sampleRate); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2319454299u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (!IsLocal) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage != null) { voiceMessage.Channels = channels; voiceMessage.SampleRate = sampleRate; voiceMessage.BufferedSamples.AddRange(chunk); } } } [ServerRpc] private void StreamAudioComplete_ServerRpc(int id, ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(3290872701u, serverRpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, id); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 3290872701u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId)) { StreamAudioComplete_ClientRpc(id); } } } [ClientRpc] private void StreamAudioComplete_ClientRpc(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4122899824u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4122899824u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; if (!IsLocal) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage != null) { voiceMessage.BuildClipIfNeeded(); ReceivedVoiceMessageAudioClip_ServerRpc(voiceMessage.Id); } } } [ServerRpc(RequireOwnership = false)] private void ReceivedVoiceMessageAudioClip_ServerRpc(int id, ServerRpcParams serverRpcParams = default(ServerRpcParams)) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(2085373701u, serverRpcParams, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val, id); ((NetworkBehaviour)this).__endSendServerRpc(ref val, 2085373701u, serverRpcParams, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost)) { return; } base.__rpc_exec_stage = (__RpcExecStage)0; ulong senderClientId = serverRpcParams.Receive.SenderClientId; if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(senderClientId)) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage != null && !voiceMessage.ClientsReceivedAudioClip.Contains(senderClientId)) { voiceMessage.ClientsReceivedAudioClip.Add(senderClientId); } } } private void VoiceMessageTimedout_Server(int id) { if (NetworkUtils.IsServer) { VoiceMessageTimedout_ClientRpc(id); VoiceMessageTimedout_Local(id); } } [ClientRpc] private void VoiceMessageTimedout_ClientRpc(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3812723390u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3812723390u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; if (!NetworkUtils.IsServer) { VoiceMessageTimedout_Local(id); } } } private void VoiceMessageTimedout_Local(int id) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage != null) { if (IsLocal) { string text = "TTS audio for \"" + voiceMessage.VoiceName + "\" timed out"; LogError(text); Utils.DisplayMessage(text, isError: true); } _voiceMessageQueue.Remove(voiceMessage); } } [ClientRpc] private void PlayVoiceMessage_ClientRpc(int id) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(544932966u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, id); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 544932966u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; PlayVoiceMessage_Local(id); } } } private void PlayVoiceMessage_Local(int id) { VoiceMessage voiceMessage = GetVoiceMessage(id); if (voiceMessage == null) { LogWarning($"Failed to play VoiceMessage. Could not find VoiceMessage. (Id: {id})", extended: true); return; } if ((Object)(object)voiceMessage.AudioClip == (Object)null) { LogWarning($"Failed to play VoiceMessage. AudioClip is null. {voiceMessage}", extended: true); _voiceMessageQueue.Remove(voiceMessage); return; } LogInfo($"Playing VoiceMessage. {voiceMessage}", extended: true); float num = ConfigManager.TTS_MasterVolume.Value; VoiceService service = VoiceService.Unknown; if (TextToSpeech.TryGetVoiceByName(voiceMessage.VoiceName, out var result)) { service = result.Service; } float serviceMasterVolume = ConfigManager.GetServiceMasterVolume(service); float num2 = 100f; if (VoiceConfigManager.TryGetVoiceConfigEntry(voiceMessage.VoiceName, out var voiceConfigEntry)) { num2 = voiceConfigEntry.Volume.Value; } AudioClip clip = AudioUtils.CreateAdjustedClip(voiceMessage.AudioClip, num, serviceMasterVolume, num2); UpdateVoiceMute(); PlayerAudioGroup.Clip = clip; PlayerAudioGroup.Play(); _voiceMessageQueue.Remove(voiceMessage); } private void ApplySettings() { if (PlayerAudioGroup != null) { UpdateVoiceMute(); PlayerAudioGroup.MaxDistance = ConfigManager.TTS_MaxDistance.Value; } } public static void HandleConfigSettingsChanged() { foreach (VoiceController instance in _instances) { instance.ApplySettings(); } } private void Log(LogLevel logLevel, object data, bool extended = false) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) string arg = (((Object)(object)PlayerScript == (Object)null) ? ("[" + ((object)this).GetType().Name + "]") : ("[" + ((object)this).GetType().Name + " : " + PlayerScript.playerUsername + "]")); Logger.Log(logLevel, $"{arg} {data}", extended); } private void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } private void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } private void LogError(object data, bool extended = false) { Log((LogLevel)2, data, extended); } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(2160464779u, new RpcReceiveHandler(__rpc_handler_2160464779), "CreateVoiceMessage_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(1380029231u, new RpcReceiveHandler(__rpc_handler_1380029231), "CreateVoiceMessage_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(4045068609u, new RpcReceiveHandler(__rpc_handler_4045068609), "DeleteVoiceMessage_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(2880339731u, new RpcReceiveHandler(__rpc_handler_2880339731), "DeleteVoiceMessage_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(1252295788u, new RpcReceiveHandler(__rpc_handler_1252295788), "StreamAudioChunk_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(2319454299u, new RpcReceiveHandler(__rpc_handler_2319454299), "StreamAudioChunk_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(3290872701u, new RpcReceiveHandler(__rpc_handler_3290872701), "StreamAudioComplete_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(4122899824u, new RpcReceiveHandler(__rpc_handler_4122899824), "StreamAudioComplete_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(2085373701u, new RpcReceiveHandler(__rpc_handler_2085373701), "ReceivedVoiceMessageAudioClip_ServerRpc"); ((NetworkBehaviour)this).__registerRpc(3812723390u, new RpcReceiveHandler(__rpc_handler_3812723390), "VoiceMessageTimedout_ClientRpc"); ((NetworkBehaviour)this).__registerRpc(544932966u, new RpcReceiveHandler(__rpc_handler_544932966), "PlayVoiceMessage_ClientRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_2160464779(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); string voiceName = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref voiceName, false); } bool flag2 = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives)); string message = null; if (flag2) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false); } ServerRpcParams server = rpcParams.Server; target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).CreateVoiceMessage_ServerRpc(voiceName, message, server); target.__rpc_exec_stage = (__RpcExecStage)0; } private static void __rpc_handler_1380029231(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int id = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref id); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); string voiceName = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref voiceName, false); } bool flag2 = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag2, default(ForPrimitives)); string message = null; if (flag2) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref message, false); } target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).CreateVoiceMessage_ClientRpc(id, voiceName, message); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_4045068609(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 NetworkManager networkManager = target.NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } } else { int id = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref id); target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).DeleteVoiceMessage_ServerRpc(id); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2880339731(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int id = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref id); target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).DeleteVoiceMessage_ClientRpc(id); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1252295788(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId) { if ((int)networkManager.LogLevel <= 1) { Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!"); } return; } int id = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref id); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); float[] chunk = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref chunk, default(ForPrimitives)); } int channels = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref channels); int sampleRate = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref sampleRate); target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).StreamAudioChunk_ServerRpc(id, chunk, channels, sampleRate); target.__rpc_exec_stage = (__RpcExecStage)0; } private static void __rpc_handler_2319454299(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int id = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref id); bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives)); float[] chunk = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref chunk, default(ForPrimitives)); } int channels = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref channels); int sampleRate = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref sampleRate); target.__rpc_exec_stage = (__RpcExecStage)1; ((VoiceController)(object)target).StreamAudioChunk_ClientRpc(id, chunk, channels, sampleRate); target.__rpc_exec_stage = (__RpcExecStage)0; } } private sta