Decompiled source of MelaniesVoice v1.7.1
com.github.zehsteam.MelaniesVoice.dll
Decompiled 5 days 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