Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ProximityVoiceChat v1.0.2
ProximityVoiceChat.dll
Decompiled 9 hours 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Concentus.Celt; using Concentus.Celt.Structs; using Concentus.Common; using Concentus.Common.CPlusPlus; using Concentus.Enums; using Concentus.Silk; using Concentus.Silk.Enums; using Concentus.Silk.Structs; using Concentus.Structs; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ProximityVoiceChat.UI; using ProximityVoiceChat.Voice; using ProximityVoiceChat.Voice.Audio; using ServerSync; using Splatform; using Steamworks; using TMPro; using UIManager; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.U2D; using UnityEngine.UI; using UserManagement; using Valheim.SettingsGui; using Valheim.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ProximityVoiceChat")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Azumatt")] [assembly: AssemblyProduct("ProximityVoiceChat")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { public ExtensionMarkerAttribute(string name) { } } } namespace ProximityVoiceChat { [BepInPlugin("Azumatt.ProximityVoiceChat", "ProximityVoiceChat", "1.0.2")] public class ProximityVoiceChatPlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } public enum Bone { X, Y, Z } private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; } internal const string ModName = "ProximityVoiceChat"; internal const string ModVersion = "1.0.2"; internal const string Author = "Azumatt"; private const string ModGUID = "Azumatt.ProximityVoiceChat"; private static readonly string ConfigFileName = "Azumatt.ProximityVoiceChat.cfg"; private static readonly string ConfigFileFullPath = Paths.ConfigPath + Path.DirectorySeparatorChar + ConfigFileName; private readonly Harmony _harmony = new Harmony("Azumatt.ProximityVoiceChat"); private static GameObject _runtimeObject = null; internal static ProximityVoiceChatPlugin? Instance; public static readonly ManualLogSource Log = Logger.CreateLogSource("ProximityVoiceChat"); private static readonly ConfigSync ConfigSync = new ConfigSync("Azumatt.ProximityVoiceChat") { DisplayName = "ProximityVoiceChat", CurrentVersion = "1.0.2", MinimumRequiredVersion = "1.0.2", IsLocked = false }; private static ConfigEntry<Toggle> _serverConfigLocked = null; internal static ConfigEntry<float> MaxRange = null; internal static ConfigEntry<float> RangeHysteresis = null; internal static ConfigEntry<float> FullVolumeRange = null; internal static ConfigEntry<Toggle> EnableVoice = null; internal static ConfigEntry<string> InputDevice = null; internal static ConfigEntry<Toggle> MuteSelf = null; internal static ConfigEntry<KeyboardShortcut> MuteSelfKey = null; internal static ConfigEntry<Toggle> UseVoiceActivation = null; internal static ConfigEntry<KeyboardShortcut> PushToTalkKey = null; internal static ConfigEntry<float> ActivationThreshold = null; internal static ConfigEntry<float> MicGain = null; internal static ConfigEntry<Toggle> AutoGain = null; internal static ConfigEntry<float> AutoGainTarget = null; internal static ConfigEntry<int> Bitrate = null; internal static ConfigEntry<int> ExpectedPacketLoss = null; internal static ConfigEntry<Toggle> UseDtx = null; internal static ConfigEntry<Toggle> AdaptiveFec = null; internal static ConfigEntry<float> VoiceVolume = null; internal static ConfigEntry<Toggle> Deafen = null; internal static ConfigEntry<KeyboardShortcut> DeafenKey = null; internal static ConfigEntry<float> MonitorVolume = null; internal static ConfigEntry<int> JitterTargetMs = null; internal static ConfigEntry<int> JitterMaxMs = null; internal static ConfigEntry<Toggle> AdaptiveJitter = null; internal static ConfigEntry<Toggle> DuckMusic = null; internal static ConfigEntry<float> DuckMusicAmount = null; internal static ConfigEntry<Toggle> Occlusion = null; internal static ConfigEntry<float> OccludedCutoff = null; internal static ConfigEntry<float> OccludedVolume = null; internal static ConfigEntry<Toggle> UnderwaterMuffle = null; internal static ConfigEntry<float> UnderwaterCutoff = null; internal static ConfigEntry<Toggle> VoiceReverb = null; internal static ConfigEntry<float> ReverbMix = null; internal static ConfigEntry<Toggle> ShowSpeakingIndicator = null; internal static ConfigEntry<float> SpeakingIndicatorHeight = null; internal static ConfigEntry<Toggle> PeerIndicators = null; internal static ConfigEntry<float> PeerIndicatorHeight = null; internal static ConfigEntry<float> PeerIndicatorScale = null; internal static ConfigEntry<Toggle> PeerIndicatorThroughWalls = null; internal static ConfigEntry<Toggle> JawMovement = null; internal static ConfigEntry<float> JawMaxAngle = null; internal static ConfigEntry<float> JawSensitivity = null; internal static ConfigEntry<Bone> JawAxis = null; internal static ConfigEntry<Toggle> HotkeyMessages = null; internal static ConfigEntry<Toggle> TestTone = null; internal static ConfigEntry<Toggle> LoopbackTest = null; internal static ConfigEntry<string> PerPlayerSettings = null; public void Awake() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Expected O, but got Unknown //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Expected O, but got Unknown //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected O, but got Unknown //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Expected O, but got Unknown //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Expected O, but got Unknown //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Expected O, but got Unknown //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Expected O, but got Unknown //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Expected O, but got Unknown //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Expected O, but got Unknown //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Expected O, but got Unknown //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_060f: Expected O, but got Unknown //IL_0659: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Expected O, but got Unknown //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Expected O, but got Unknown //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Expected O, but got Unknown //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0763: Expected O, but got Unknown //IL_0791: Unknown result type (might be due to invalid IL or missing references) //IL_079c: Expected O, but got Unknown //IL_0841: Unknown result type (might be due to invalid IL or missing references) //IL_084c: Expected O, but got Unknown //IL_088b: Unknown result type (might be due to invalid IL or missing references) //IL_0895: Expected O, but got Unknown Instance = this; Localizer.Load(); bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; _serverConfigLocked = config("1 - General", "Lock Configuration", Toggle.On, "If on, only server admins can change the synced settings."); ConfigSync.AddLockingConfigEntry<Toggle>(_serverConfigLocked); MaxRange = config("2 - Proximity", "Max Range", 45f, new ConfigDescription("Max distance you can hear other players", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>())); RangeHysteresis = config("2 - Proximity", "Range Buffer", 8f, new ConfigDescription("Extra distance before a player disconnects from voice. Helps prevent audio cutting in and out near max range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>())); FullVolumeRange = config("2 - Proximity", "Full Volume Range", 4f, new ConfigDescription("Players within this distance are heard at full volume. Beyond it, volume fades with distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); EnableVoice = config("3 - Microphone", "Enable Voice", Toggle.On, "Turn microphone capture off entirely.", synchronizedSetting: false); InputDevice = config("3 - Microphone", "Input Device", "", "Microphone to use. Leave blank to use your system default.", synchronizedSetting: false); MuteSelf = config("3 - Microphone", "Mute Self", Toggle.Off, "Stops sending your voice without turning off the microphone.", synchronizedSetting: false); MuteSelfKey = config<KeyboardShortcut>("3 - Microphone", "Mute Self Key", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), new ConfigDescription("Toggles your microphone mute. Unbound by default to avoid conflicts with other mods.", (AcceptableValueBase)(object)new AcceptableShortcuts(), Array.Empty<object>()), synchronizedSetting: false); UseVoiceActivation = config("3 - Microphone", "Use Voice Activation", Toggle.Off, "Automatically transmits when you speak. Turn this off to use push-to-talk.", synchronizedSetting: false); PushToTalkKey = config<KeyboardShortcut>("3 - Microphone", "Push To Talk", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), new ConfigDescription("Hold this key to talk when Voice Activation is off.", (AcceptableValueBase)(object)new AcceptableShortcuts(), Array.Empty<object>()), synchronizedSetting: false); ActivationThreshold = config("3 - Microphone", "Activation Threshold", 0.02f, new ConfigDescription("How loud you need to speak before voice activation starts transmitting. Lower values are more sensitive.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.3f), Array.Empty<object>()), synchronizedSetting: false); MicGain = config("3 - Microphone", "Microphone Gain", 1f, new ConfigDescription("Boosts or lowers your microphone volume before it is sent. Checked before encoding", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 8f), Array.Empty<object>()), synchronizedSetting: false); AutoGain = config("3 - Microphone", "Auto Gain", Toggle.On, "Chases a steady speaking level so you do not have to hunt for a gain number. Microphone Gain still multiplies on top.", synchronizedSetting: false); AutoGainTarget = config("3 - Microphone", "Auto Gain Target", 0.12f, new ConfigDescription("Target speaking volume used by Automatic Gain. Higher values make your voice louder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.4f), Array.Empty<object>()), synchronizedSetting: false); Bitrate = config("4 - Codec", "Bitrate", 24000, new ConfigDescription("Opus target bitrate in bits per second. Voice quality and bandwidth usage. Higher is better but uses more bandwidth.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(6000, 64000), Array.Empty<object>())); ExpectedPacketLoss = config("4 - Codec", "Expected Packet Loss", 5, new ConfigDescription("How much packet loss Opus should expect. Higher values use more error correction.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 40), Array.Empty<object>())); UseDtx = config("4 - Codec", "Use DTX", Toggle.Off, "Stops sending audio while you are silent. Saves bandwidth, but very quiet words may get cut off."); AdaptiveFec = config("4 - Codec", "Adaptive FEC", Toggle.On, "Adds more error correction when other players report lost audio packets.", synchronizedSetting: false); VoiceVolume = config("5 - Playback", "Voice Volume", 1f, new ConfigDescription("Overall volume of voice chat.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()), synchronizedSetting: false); Deafen = config("5 - Playback", "Deafen", Toggle.Off, "Stops all incoming voice and stops you transmitting.", synchronizedSetting: false); DeafenKey = config<KeyboardShortcut>("5 - Playback", "Deafen Key", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), new ConfigDescription("Toggles Deafen. Unbound by default to avoid conflicts with other mods.", (AcceptableValueBase)(object)new AcceptableShortcuts(), Array.Empty<object>()), synchronizedSetting: false); MonitorVolume = config("5 - Playback", "Monitor Volume", 0.7f, new ConfigDescription("How loudly you hear yourself while Hear Myself While I Talk is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()), synchronizedSetting: false); JitterTargetMs = config("5 - Playback", "Jitter Buffer Target", 60, new ConfigDescription("Audio buffered to smooth out network hiccups. Lower means less delay; higher is more stable.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(20, 300), Array.Empty<object>()), synchronizedSetting: false); JitterMaxMs = config("5 - Playback", "Jitter Buffer Max", 200, new ConfigDescription("Maximum buffer size allowed when Automatic Voice Buffer is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(40, 600), Array.Empty<object>()), synchronizedSetting: false); AdaptiveJitter = config("5 - Playback", "Adaptive Jitter", Toggle.On, "Automatically adjusts each player's audio buffer based on their connection.", synchronizedSetting: false); DuckMusic = config("5 - Playback", "Duck Music", Toggle.On, "Lowers Valheim's music while a nearby player is speaking.", synchronizedSetting: false); DuckMusicAmount = config("5 - Playback", "Duck Music Amount", 0.35f, new ConfigDescription("Music volume while someone is speaking. 0 is silent, 1 is unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()), synchronizedSetting: false); Occlusion = config("5 - Playback", "Occlusion", Toggle.On, "Makes voices quieter and muffled when something solid is between you.", synchronizedSetting: false); OccludedCutoff = config("5 - Playback", "Occluded Cutoff", 900f, new ConfigDescription("How muffled voices sound through walls. Lower values sound more muffled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(200f, 8000f), Array.Empty<object>()), synchronizedSetting: false); OccludedVolume = config("5 - Playback", "Occluded Volume", 0.7f, new ConfigDescription("Volume of voices heard through walls. 1 is full volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()), synchronizedSetting: false); UnderwaterMuffle = config("5 - Playback", "Underwater Muffle", Toggle.On, "Muffles voice chat while you are swimming.", synchronizedSetting: false); UnderwaterCutoff = config("5 - Playback", "Underwater Cutoff", 500f, new ConfigDescription("How muffled voices sound underwater. Lower values sound more muffled.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(150f, 4000f), Array.Empty<object>()), synchronizedSetting: false); VoiceReverb = config("5 - Playback", "Voice Reverb", Toggle.Off, "Let the game's reverb zones colour voices, so caves and halls sound like caves and halls.", synchronizedSetting: false); ReverbMix = config("5 - Playback", "Reverb Mix", 0.3f, new ConfigDescription("How much of the game's reverb a voice picks up. A full send drowns speech in echo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()), synchronizedSetting: false); ShowSpeakingIndicator = config("6 - UI", "Speaking Indicator", Toggle.On, "Shows a speaker icon above your character while you are transmitting.", synchronizedSetting: false); SpeakingIndicatorHeight = config("6 - UI", "Speaking Indicator Height", 0.5f, new ConfigDescription("How high the speaker icon sits above your head.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()), synchronizedSetting: false); PeerIndicators = config("6 - UI", "Peer Speaking Indicators", Toggle.Off, "Shows a speaker icon above other players while they are talking.", synchronizedSetting: false); PeerIndicatorHeight = config("6 - UI", "Peer Indicator Height", 0.9f, new ConfigDescription("How high speaker icons sit above other players.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()), synchronizedSetting: false); PeerIndicatorScale = config("6 - UI", "Peer Indicator Scale", 1f, new ConfigDescription("Size of the speaker icons shown above other players.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>()), synchronizedSetting: false); PeerIndicatorThroughWalls = config("6 - UI", "Peer Indicator Through Walls", Toggle.Off, "Keeps speaking indicators visible even when a wall is between you.", synchronizedSetting: false); JawMovement = config("6 - UI", "Jaw Movement", Toggle.On, "Moves player jaws while they are speaking. Yours and others.", synchronizedSetting: false); JawMaxAngle = config("6 - UI", "Jaw Max Angle", 14f, new ConfigDescription("Maximum amount the jaw opens while speaking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>()), synchronizedSetting: false); JawSensitivity = config("6 - UI", "Jaw Sensitivity", 12f, new ConfigDescription("How strongly voice volume moves the jaw. Raise this if mouths barely move.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()), synchronizedSetting: false); JawAxis = config("6 - UI", "Jaw Axis", Bone.X, "Change this if the head twists instead of the mouth opening. Default is good for Valheim model, but might not be for VRMs", synchronizedSetting: false); HotkeyMessages = config("6 - UI", "Hotkey Messages", Toggle.On, "Shows a short message when you mute or deafen yourself with a hotkey.", synchronizedSetting: false); TestTone = config("6 - UI", "Test Tone", Toggle.Off, "Sends a test tone instead of microphone audio. Useful for testing without a working microphone.", synchronizedSetting: false); LoopbackTest = config("6 - UI", "Loopback Test", Toggle.Off, "Plays your outgoing voice back to you so you can hear what other players hear.", synchronizedSetting: false); PerPlayerSettings = config("6 - UI", "Per Player Settings", "", new ConfigDescription("Saved data. Don't write here manually, unless you know what you're doing. Written by the player list. steamid:volume:muted, semicolon separated.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } }), synchronizedSetting: false); TestTone.Value = Toggle.Off; LoopbackTest.Value = Toggle.Off; PeerPreferences.Load(PerPlayerSettings.Value); _harmony.PatchAll(Assembly.GetExecutingAssembly()); _runtimeObject = new GameObject("ProximityVoiceChat_Runtime"); Object.DontDestroyOnLoad((Object)(object)_runtimeObject); ((Object)_runtimeObject).hideFlags = (HideFlags)61; _runtimeObject.AddComponent<VoiceRuntime>(); _runtimeObject.AddComponent<SpeakingIndicator>(); _runtimeObject.AddComponent<JawAnimator>(); _runtimeObject.AddComponent<VoiceHotkeys>(); UIRoot.Init(Log, _harmony); SetupWatcher(); ((BaseUnityPlugin)this).Config.Save(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } } private void OnDestroy() { if ((Object)(object)_runtimeObject != (Object)null) { Object.Destroy((Object)(object)_runtimeObject); } if (PeerPreferences.TryFlush(out string serialized)) { PerPlayerSettings.Value = serialized; } ((BaseUnityPlugin)this).Config.Save(); } internal static void SaveConfig() { if (PeerPreferences.TryFlush(out string serialized)) { PerPlayerSettings.Value = serialized; } ProximityVoiceChatPlugin? instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Config.Save(); } } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { Log.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { Log.LogError((object)("There was an issue loading your " + ConfigFileName)); Log.LogError((object)"Please check your config entries for spelling and format!"); } } private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]"), description.AcceptableValues, description.Tags); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val); ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synchronizedSetting; return val2; } private ConfigEntry<T> config<T>(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } } public static class KeyboardExtensions { [SpecialName] public sealed class <G>$8D1D3E80A18AA9715780B6CB7003B2F1 { [SpecialName] public static class <M>$895AB635D4D087636CF1C26BA650BA11 { } [ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyDown() { throw null; } [ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyHeld() { throw null; } } public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } return false; } } public static class ToggleExtensions { [SpecialName] public sealed class <G>$BDF3EF541E575CBEE3FDDD5BBDE7E281 { [SpecialName] public static class <M>$E3FDBDD135D264042C5DDA2535FB9962 { } [ExtensionMarker("<M>$E3FDBDD135D264042C5DDA2535FB9962")] public bool IsOn() { throw null; } [ExtensionMarker("<M>$E3FDBDD135D264042C5DDA2535FB9962")] public bool IsOff() { throw null; } } public static bool IsOn(this ProximityVoiceChatPlugin.Toggle toggle) { return toggle == ProximityVoiceChatPlugin.Toggle.On; } public static bool IsOff(this ProximityVoiceChatPlugin.Toggle toggle) { return toggle == ProximityVoiceChatPlugin.Toggle.Off; } } } namespace ProximityVoiceChat.UI { internal static class SettingsTabInjector { internal const string TabLabel = "Voice"; internal static void Inject(Settings? settings) { //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown //IL_0298: Expected O, but got Unknown if ((Object)(object)settings == (Object)null) { return; } TabHandler val = (((Object)(object)settings.m_tabHandler != (Object)null) ? settings.m_tabHandler : ((Component)settings).GetComponentInChildren<TabHandler>()); if ((Object)(object)val == (Object)null) { ProximityVoiceChatPlugin.Log.LogWarning((object)"Voice tab: no TabHandler in the settings prefab"); return; } if (val.m_tabs.Count == 0) { ProximityVoiceChatPlugin.Log.LogWarning((object)"Voice tab: settings prefab has no tabs"); return; } foreach (Tab tab in val.m_tabs) { if ((Object)(object)tab.m_button != (Object)null && ((Object)tab.m_button).name == "Voice") { return; } } Button val2 = null; RectTransform val3 = null; foreach (Tab tab2 in val.m_tabs) { if ((Object)(object)tab2.m_button != (Object)null) { val2 = tab2.m_button; } if ((Object)(object)tab2.m_page != (Object)null && (Object)(object)val3 == (Object)null) { val3 = tab2.m_page; } } if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { ProximityVoiceChatPlugin.Log.LogWarning((object)$"Voice tab: no usable template, button {(Object)(object)val2 != (Object)null}, page {(Object)(object)val3 != (Object)null}"); return; } Button val4 = Object.Instantiate<Button>(val2, ((Component)val2).transform.parent); ((Object)val4).name = "Voice"; ((Component)val4).transform.SetAsLastSibling(); ((UnityEventBase)val4.onClick).RemoveAllListeners(); SetLabel(((Component)val4).gameObject, "Voice"); Transform val5 = ((Component)val4).transform.Find("KeyHint"); if ((Object)(object)val5 != (Object)null) { ((Component)val5).gameObject.SetActive(false); } GameObject val6 = new GameObject("VoicePage", new Type[1] { typeof(RectTransform) }); val6.transform.SetParent(((Transform)val3).parent, false); RectTransform val7 = (RectTransform)val6.transform; val7.anchorMin = val3.anchorMin; val7.anchorMax = val3.anchorMax; val7.pivot = val3.pivot; val7.offsetMin = val3.offsetMin; val7.offsetMax = val3.offsetMax; ((Transform)val7).localScale = Vector3.one; val6.AddComponent<VoiceSettingsTab>(); val6.SetActive(false); val.m_tabs.Add(new Tab { m_button = val4, m_page = val7, m_default = false, m_onClick = new UnityEvent() }); ProximityVoiceChatPlugin.Log.LogInfo((object)$"Added the Voice tab to the settings menu, {val.m_tabs.Count} tabs now"); } private static void SetLabel(GameObject button, string text) { TMP_Text[] componentsInChildren = button.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = text; } Text[] componentsInChildren2 = button.GetComponentsInChildren<Text>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].text = text; } Localize[] componentsInChildren3 = button.GetComponentsInChildren<Localize>(true); for (int j = 0; j < componentsInChildren3.Length; j++) { Object.Destroy((Object)(object)componentsInChildren3[j]); } } } [HarmonyPatch(typeof(Settings), "SetAvailableTabs")] internal static class Settings_SetAvailableTabs_Patch { private static void Prefix(Settings __instance) { try { SettingsTabInjector.Inject(__instance); } catch (Exception arg) { ProximityVoiceChatPlugin.Log.LogError((object)$"Could not add the Voice settings tab: {arg}"); } } } [HarmonyPatch(typeof(SessionPlayerListEntry), "SetValues")] internal static class SessionPlayerListEntry_SetValues_Patch { private static void Postfix(SessionPlayerListEntry __instance) { VoiceEntryUI voiceEntryUI = ((Component)__instance).gameObject.GetComponent<VoiceEntryUI>(); if ((Object)(object)voiceEntryUI == (Object)null) { voiceEntryUI = ((Component)__instance).gameObject.AddComponent<VoiceEntryUI>(); } voiceEntryUI.Bind(__instance, __instance.IsOwnPlayer); } } internal sealed class SliderRow { internal Slider Slider; internal Text Value; internal string Format = "0.00"; internal void Set(float value) { Slider.SetValueWithoutNotify(value); Value.text = value.ToString(Format); } } internal sealed class KeyRow { internal Button Button; internal Text Label; internal ConfigEntry<KeyboardShortcut> Entry; internal void Refresh() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) Label.text = (KeyBinder.IsListening(Entry) ? UIBuild.Localize("$pvc_key_press") : KeyBinder.Describe(Entry.Value)); } } internal sealed class CycleRow<T> where T : struct, Enum { internal Button Button; internal Text Label; internal ConfigEntry<T> Entry; internal void Step() { T[] array = (T[])Enum.GetValues(typeof(T)); int num = Array.IndexOf(array, Entry.Value); Entry.Value = array[(num + 1 + array.Length) % array.Length]; Refresh(); } internal void Refresh() { Label.text = Entry.Value.ToString(); } } internal static class UIBuild { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__42_0; public static UnityAction <>9__42_1; internal void <DevicePicker>b__42_0() { StepDevice(-1); } internal void <DevicePicker>b__42_1() { StepDevice(1); } } internal const float RowHeight = 26f; internal const float LabelWidth = 210f; internal const float ValueWidth = 56f; private const float RowSpacing = 10f; private const float HeadingHeight = 28f; private const float NoteHeight = 20f; private const float ControlHeight = 24f; private const float ToggleHeight = 22f; private const float SliderHeight = 18f; private const float SliderWidth = 200f; private const float ButtonWidth = 160f; internal const float TallRowHeight = 28f; private const float ArrowWidth = 28f; private const float ArrowCell = 32f; private const float MeterRowHeight = 20f; private const float MeterLabelWidth = 70f; private const float MeterTrackWidth = 200f; private const float MeterTrackHeight = 12f; private const int BodyFontSize = 16; private const int TitleFontSize = 18; private const int NoteFontSize = 15; private const int SmallFontSize = 14; internal const float MeterFloorDb = -60f; private const float MeterSilence = 0.0001f; private const float AmplitudeToDb = 20f; internal static string Localize(string key) { if (Localization.instance == null) { return key; } return Localization.instance.Localize(key); } internal static string Localize(string key, params object[] args) { return string.Format(Localize(key), args); } internal static GameObject Row(Transform parent, float height) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown GameObject val = new GameObject("Row", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f; ((LayoutGroup)obj).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; LayoutElement obj2 = val.AddComponent<LayoutElement>(); obj2.minHeight = height; obj2.preferredHeight = height; return val; } internal static LayoutElement Element(Component component) { LayoutElement component2 = component.gameObject.GetComponent<LayoutElement>(); if (!((Object)(object)component2 != (Object)null)) { return component.gameObject.AddComponent<LayoutElement>(); } return component2; } internal static T Fixed<T>(T component, float width, float height = 0f) where T : Component { LayoutElement val = Element((Component)(object)component); val.minWidth = width; val.preferredWidth = width; if (height > 0f) { val.minHeight = height; val.preferredHeight = height; } return component; } internal static T Flex<T>(T component) where T : Component { Element((Component)(object)component).flexibleWidth = 1f; return component; } internal static Text Label(Transform parent, string text) { return UIFactory.Text("Label", parent, text, TextRole.Body, 16, (TextAnchor)3); } internal static Text Heading(Transform parent, string text) { Text obj = UIFactory.Text("Heading", parent, text, TextRole.Title, 18, (TextAnchor)3); Element((Component)(object)obj).preferredHeight = 28f; return obj; } internal static Text Note(Transform parent, string text) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Text obj = UIFactory.Text("Note", parent, text, TextRole.Body, 15, (TextAnchor)3); ((Graphic)obj).color = GameColors.Beige; Element((Component)(object)obj).preferredHeight = 20f; return obj; } internal static float MeterScale(float amplitude) { if (amplitude <= 0.0001f) { return 0f; } return Mathf.Clamp01((20f * Mathf.Log10(amplitude) - -60f) / 60f); } internal static RectTransform Meter(Transform parent, string label) { //IL_0046: 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_00ab: Expected O, but got Unknown //IL_00c3: 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) //IL_00c9: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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) //IL_00fe: 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_0109: 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_0124: Expected O, but got Unknown GameObject val = Row(parent, 20f); UIBuild.Fixed<Text>(UIFactory.Text("Label", val.transform, label, TextRole.Body, 14, (TextAnchor)3), 70f, 0f); GameObject val2 = UIFactory.Panel("Track", val.transform, new Vector2(200f, 12f), window: false); UIBuild.Flex<Transform>(val2.transform); Element((Component)(object)val2.transform).preferredHeight = 12f; GameObject val3 = new GameObject("Fill", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = Vector2.zero; val4.anchorMax = new Vector2(0f, 1f); val4.pivot = new Vector2(0f, 0.5f); val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; ((Graphic)val3.GetComponent<Image>()).color = GameColors.Beige; return val4; } internal static SliderRow SliderControl(Transform parent, string label, float min, float max, float value, UnityAction<float> onChanged, string format = "0.00") { //IL_0060: Unknown result type (might be due to invalid IL or missing references) GameObject val = Row(parent, 26f); UIBuild.Fixed<Text>(Label(val.transform, label), 210f, 0f); SliderRow control = new SliderRow { Format = format }; control.Slider = UIFactory.Slider(label, val.transform, new Vector2(200f, 18f), min, max, value, delegate(float v) { onChanged.Invoke(v); control.Value.text = v.ToString(control.Format); }); UIBuild.Flex<Slider>(control.Slider); Element((Component)(object)control.Slider).preferredHeight = 18f; control.Value = UIBuild.Fixed<Text>(UIFactory.Text("Value", val.transform, value.ToString(format), TextRole.Body, 16, (TextAnchor)5), 56f, 0f); return control; } internal static SliderRow SliderFor(Transform parent, string label, ConfigEntry<float> entry, string format = "0.00") { AcceptableValueRange<float> val = (AcceptableValueRange<float>)(object)((ConfigEntryBase)entry).Description.AcceptableValues; return SliderControl(parent, label, val.MinValue, val.MaxValue, entry.Value, delegate(float v) { if (!Mathf.Approximately(entry.Value, v)) { entry.Value = v; } }, format); } internal static Toggle ToggleFor(Transform parent, string label, ConfigEntry<ProximityVoiceChatPlugin.Toggle> entry) { return RawToggle(parent, label, entry.Value.IsOn(), delegate(bool on) { entry.Value = (on ? ProximityVoiceChatPlugin.Toggle.On : ProximityVoiceChatPlugin.Toggle.Off); }); } internal static Toggle RawToggle(Transform parent, string label, bool value, UnityAction<bool> onChanged) { GameObject val = Row(parent, 26f); Toggle obj = UIFactory.Toggle(label, val.transform, label, value, onChanged); UIBuild.Flex<Toggle>(obj); Element((Component)(object)obj).preferredHeight = 22f; return obj; } internal static KeyRow KeyBinding(Transform parent, string label, ConfigEntry<KeyboardShortcut> entry) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown GameObject val = Row(parent, 26f); UIBuild.Fixed<Text>(Label(val.transform, label), 210f, 0f); KeyRow obj = new KeyRow { Entry = entry, Button = UIBuild.Flex<Button>(UIFactory.Button("Bind", val.transform, KeyBinder.Describe(entry.Value), new Vector2(160f, 24f), (UnityAction)delegate { KeyBinder.Begin(entry); })) }; Element((Component)(object)obj.Button).preferredHeight = 24f; obj.Label = ((Component)obj.Button).GetComponentInChildren<Text>(); return obj; } internal static CycleRow<T> Cycle<T>(Transform parent, string label, ConfigEntry<T> entry) where T : struct, Enum { //IL_005f: 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) //IL_0076: Expected O, but got Unknown GameObject val = Row(parent, 26f); UIBuild.Fixed<Text>(Label(val.transform, label), 210f, 0f); CycleRow<T> cycleRow = new CycleRow<T> { Entry = entry }; cycleRow.Button = UIBuild.Flex<Button>(UIFactory.Button("Cycle", val.transform, entry.Value.ToString(), new Vector2(160f, 24f), new UnityAction(cycleRow.Step))); Element((Component)(object)cycleRow.Button).preferredHeight = 24f; cycleRow.Label = ((Component)cycleRow.Button).GetComponentInChildren<Text>(); return cycleRow; } internal static Text DevicePicker(Transform parent, string label) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown GameObject val = Row(parent, 28f); UIBuild.Fixed<Text>(Label(val.transform, label), 210f, 0f); Transform transform = val.transform; Vector2 size = new Vector2(28f, 24f); object obj = <>c.<>9__42_0; if (obj == null) { UnityAction val2 = delegate { StepDevice(-1); }; <>c.<>9__42_0 = val2; obj = (object)val2; } UIBuild.Fixed<Button>(UIFactory.Button("Prev", transform, "<", size, (UnityAction)obj), 32f, 24f); Text result = UIBuild.Flex<Text>(UIFactory.Text("Device", val.transform, "", TextRole.Body, 16, (TextAnchor)4)); Transform transform2 = val.transform; Vector2 size2 = new Vector2(28f, 24f); object obj2 = <>c.<>9__42_1; if (obj2 == null) { UnityAction val3 = delegate { StepDevice(1); }; <>c.<>9__42_1 = val3; obj2 = (object)val3; } UIBuild.Fixed<Button>(UIFactory.Button("Next", transform2, ">", size2, (UnityAction)obj2), 32f, 24f); return result; } internal static void StepDevice(int direction) { string[] devices = MicrophoneCapture.Devices; if (devices.Length != 0) { int num = Array.IndexOf(devices, ProximityVoiceChatPlugin.InputDevice.Value); if (num < 0) { num = 0; } num = (num + direction + devices.Length) % devices.Length; ProximityVoiceChatPlugin.InputDevice.Value = devices[num]; } } internal static string CurrentDeviceName() { string value = ProximityVoiceChatPlugin.InputDevice.Value; if (!string.IsNullOrEmpty(value)) { return value; } string[] devices = MicrophoneCapture.Devices; if (devices.Length == 0) { return Localize("$pvc_device_none"); } return devices[0]; } } internal sealed class VoiceSettingsTab : MonoBehaviour, ISettingsTab { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction<bool> <>9__45_0; public static UnityAction <>9__45_1; internal void <Build>b__45_0(bool on) { ProximityVoiceChatPlugin.LoopbackTest.Value = (on ? ProximityVoiceChatPlugin.Toggle.On : ProximityVoiceChatPlugin.Toggle.Off); } internal void <Build>b__45_1() { VoiceRuntime.Instance?.Capture?.ProbeRaw(); } } private Text? _device; private Text? _status; private RectTransform? _inFill; private RectTransform? _rmsFill; private RectTransform? _outFill; private Text? _numbers; private Text? _stats; private SliderRow? _gain; private SliderRow? _gate; private SliderRow? _incoming; private SliderRow? _monitor; private Toggle? _enableVoice; private Toggle? _activation; private Toggle? _muteSelf; private Toggle? _deafen; private Toggle? _monitorOn; private Toggle? _autoGain; private Toggle? _duckMusic; private Toggle? _adaptiveJitter; private Toggle? _testTone; private Toggle? _speakingIndicator; private Toggle? _peerIndicators; private Toggle? _peerThroughWalls; private Toggle? _jawMovement; private Toggle? _occlusion; private Toggle? _underwater; private Toggle? _reverb; private SliderRow? _selfHeight; private SliderRow? _peerHeight; private SliderRow? _peerScale; private SliderRow? _jawAngle; private SliderRow? _jawSensitivity; private CycleRow<ProximityVoiceChatPlugin.Bone>? _jawAxis; private readonly List<KeyRow> _keyRows = new List<KeyRow>(); private const float TextInterval = 0.15f; private const int ClipWarningFrames = 50; private const int ContentPadding = 24; private const float ContentSpacing = 6f; private const float ProbeButtonWidth = 220f; private const float ProbeButtonHeight = 26f; private float _textTimer; public event Action<string, int>? SharedSettingChanged; public void Initialize() { try { Build(); } catch (Exception arg) { ProximityVoiceChatPlugin.Log.LogError((object)$"Voice settings tab failed to build: {arg}"); } } private void Build() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0077: Expected O, but got Unknown //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Expected O, but got Unknown RectTransform content; RectTransform val = (RectTransform)((Component)UIFactory.ScrollView("VoiceScroll", ((Component)this).transform, new Vector2(100f, 100f), out content)).transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = Vector2.zero; val.offsetMax = Vector2.zero; Transform parent = (Transform)(object)content; VerticalLayoutGroup component = ((Component)content).GetComponent<VerticalLayoutGroup>(); if (component != null) { ((LayoutGroup)component).padding = new RectOffset(24, 24, 24, 24); ((HorizontalOrVerticalLayoutGroup)component).spacing = 6f; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; } UIBuild.Heading(parent, UIBuild.Localize("$pvc_heading_microphone")); _enableVoice = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_enable_voice"), ProximityVoiceChatPlugin.EnableVoice); _status = UIBuild.Note(parent, ""); _device = UIBuild.DevicePicker(parent, UIBuild.Localize("$pvc_input_device")); _inFill = UIBuild.Meter(parent, UIBuild.Localize("$pvc_meter_input")); _rmsFill = UIBuild.Meter(parent, UIBuild.Localize("$pvc_meter_sent")); _outFill = UIBuild.Meter(parent, UIBuild.Localize("$pvc_meter_heard")); _numbers = UIBuild.Note(parent, ""); _gain = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_mic_gain"), ProximityVoiceChatPlugin.MicGain); _gate = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_gate_threshold"), ProximityVoiceChatPlugin.ActivationThreshold, "0.000"); _activation = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_voice_activation"), ProximityVoiceChatPlugin.UseVoiceActivation); _autoGain = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_auto_gain"), ProximityVoiceChatPlugin.AutoGain); _muteSelf = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_mute_self"), ProximityVoiceChatPlugin.MuteSelf); UIBuild.Heading(parent, UIBuild.Localize("$pvc_heading_listening")); _incoming = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_incoming_volume"), ProximityVoiceChatPlugin.VoiceVolume); _deafen = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_deafen"), ProximityVoiceChatPlugin.Deafen); _duckMusic = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_duck_music"), ProximityVoiceChatPlugin.DuckMusic); _adaptiveJitter = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_adaptive_jitter"), ProximityVoiceChatPlugin.AdaptiveJitter); _occlusion = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_occlusion"), ProximityVoiceChatPlugin.Occlusion); _underwater = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_underwater"), ProximityVoiceChatPlugin.UnderwaterMuffle); _reverb = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_reverb"), ProximityVoiceChatPlugin.VoiceReverb); UIBuild.Heading(parent, UIBuild.Localize("$pvc_heading_keys")); _keyRows.Add(UIBuild.KeyBinding(parent, UIBuild.Localize("$pvc_key_ptt"), ProximityVoiceChatPlugin.PushToTalkKey)); _keyRows.Add(UIBuild.KeyBinding(parent, UIBuild.Localize("$pvc_key_mute"), ProximityVoiceChatPlugin.MuteSelfKey)); _keyRows.Add(UIBuild.KeyBinding(parent, UIBuild.Localize("$pvc_key_deafen"), ProximityVoiceChatPlugin.DeafenKey)); UIBuild.Note(parent, UIBuild.Localize("$pvc_note_binding")); UIBuild.Heading(parent, UIBuild.Localize("$pvc_heading_interface")); _speakingIndicator = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_speaking_indicator"), ProximityVoiceChatPlugin.ShowSpeakingIndicator); _selfHeight = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_indicator_height"), ProximityVoiceChatPlugin.SpeakingIndicatorHeight); _peerIndicators = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_peer_indicators"), ProximityVoiceChatPlugin.PeerIndicators); _peerHeight = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_peer_indicator_height"), ProximityVoiceChatPlugin.PeerIndicatorHeight); _peerScale = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_peer_indicator_scale"), ProximityVoiceChatPlugin.PeerIndicatorScale); _peerThroughWalls = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_peer_through_walls"), ProximityVoiceChatPlugin.PeerIndicatorThroughWalls); _jawMovement = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_jaw_movement"), ProximityVoiceChatPlugin.JawMovement); _jawAngle = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_jaw_angle"), ProximityVoiceChatPlugin.JawMaxAngle, "0"); _jawSensitivity = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_jaw_sensitivity"), ProximityVoiceChatPlugin.JawSensitivity, "0"); _jawAxis = UIBuild.Cycle<ProximityVoiceChatPlugin.Bone>(parent, UIBuild.Localize("$pvc_jaw_axis"), ProximityVoiceChatPlugin.JawAxis); UIBuild.Heading(parent, UIBuild.Localize("$pvc_heading_test")); _monitor = UIBuild.SliderFor(parent, UIBuild.Localize("$pvc_monitor_volume"), ProximityVoiceChatPlugin.MonitorVolume); _monitorOn = UIBuild.RawToggle(parent, UIBuild.Localize("$pvc_hear_myself"), ProximityVoiceChatPlugin.LoopbackTest.Value.IsOn(), delegate(bool on) { ProximityVoiceChatPlugin.LoopbackTest.Value = (on ? ProximityVoiceChatPlugin.Toggle.On : ProximityVoiceChatPlugin.Toggle.Off); }); _testTone = UIBuild.ToggleFor(parent, UIBuild.Localize("$pvc_test_tone"), ProximityVoiceChatPlugin.TestTone); GameObject val2 = UIBuild.Row(parent, 28f); Transform transform = val2.transform; string label = UIBuild.Localize("$pvc_probe_button"); Vector2 size = new Vector2(220f, 26f); object obj = <>c.<>9__45_1; if (obj == null) { UnityAction val3 = delegate { VoiceRuntime.Instance?.Capture?.ProbeRaw(); }; <>c.<>9__45_1 = val3; obj = (object)val3; } UIBuild.Flex<Button>(UIFactory.Button("Probe", transform, label, size, (UnityAction)obj)); _stats = UIBuild.Note(parent, ""); UIBuild.Note(parent, UIBuild.Localize("$pvc_note_perplayer")); UIBuild.Note(parent, UIBuild.Localize("$pvc_note_menu_mic")); } public void OnTabOpen(Button backButton, Button okButton) { } private void OnEnable() { VoiceRuntime.LocalTestRequested = true; } private void OnDisable() { VoiceRuntime.LocalTestRequested = false; KeyBinder.Cancel(); } public void OnOkAsync(OkActionCompletedHandler okActionCompletedCallback) { ProximityVoiceChatPlugin.SaveConfig(); if (okActionCompletedCallback != null) { okActionCompletedCallback.Invoke(); } } private void Update() { KeyBinder.Tick(); for (int i = 0; i < _keyRows.Count; i++) { _keyRows[i].Refresh(); } VoiceRuntime instance = VoiceRuntime.Instance; MicrophoneCapture microphoneCapture = instance?.Capture; VoiceEncoder voiceEncoder = instance?.Encoder; float num = 0f; if (instance?.Playback != null && instance.Playback.Streams.TryGetValue(1uL, out PeerVoiceStream value)) { num = value.OutputRms; } SetFill(_inFill, microphoneCapture?.PeakLevel ?? 0f); SetFill(_rmsFill, voiceEncoder?.LastRms ?? 0f); SetFill(_outFill, num); _textTimer += Time.unscaledDeltaTime; if (_textTimer >= 0.15f) { _textTimer = 0f; RefreshText(microphoneCapture, voiceEncoder, instance, num); } _gain?.Set(ProximityVoiceChatPlugin.MicGain.Value); _gate?.Set(ProximityVoiceChatPlugin.ActivationThreshold.Value); _incoming?.Set(ProximityVoiceChatPlugin.VoiceVolume.Value); _monitor?.Set(ProximityVoiceChatPlugin.MonitorVolume.Value); _selfHeight?.Set(ProximityVoiceChatPlugin.SpeakingIndicatorHeight.Value); _peerHeight?.Set(ProximityVoiceChatPlugin.PeerIndicatorHeight.Value); _peerScale?.Set(ProximityVoiceChatPlugin.PeerIndicatorScale.Value); _jawAngle?.Set(ProximityVoiceChatPlugin.JawMaxAngle.Value); _jawSensitivity?.Set(ProximityVoiceChatPlugin.JawSensitivity.Value); _jawAxis?.Refresh(); SetToggle(_enableVoice, ProximityVoiceChatPlugin.EnableVoice); SetToggle(_activation, ProximityVoiceChatPlugin.UseVoiceActivation); SetToggle(_muteSelf, ProximityVoiceChatPlugin.MuteSelf); SetToggle(_deafen, ProximityVoiceChatPlugin.Deafen); SetToggle(_monitorOn, ProximityVoiceChatPlugin.LoopbackTest); SetToggle(_autoGain, ProximityVoiceChatPlugin.AutoGain); SetToggle(_duckMusic, ProximityVoiceChatPlugin.DuckMusic); SetToggle(_adaptiveJitter, ProximityVoiceChatPlugin.AdaptiveJitter); SetToggle(_testTone, ProximityVoiceChatPlugin.TestTone); SetToggle(_speakingIndicator, ProximityVoiceChatPlugin.ShowSpeakingIndicator); SetToggle(_peerIndicators, ProximityVoiceChatPlugin.PeerIndicators); SetToggle(_peerThroughWalls, ProximityVoiceChatPlugin.PeerIndicatorThroughWalls); SetToggle(_jawMovement, ProximityVoiceChatPlugin.JawMovement); SetToggle(_occlusion, ProximityVoiceChatPlugin.Occlusion); SetToggle(_underwater, ProximityVoiceChatPlugin.UnderwaterMuffle); SetToggle(_reverb, ProximityVoiceChatPlugin.VoiceReverb); } private void RefreshText(MicrophoneCapture? capture, VoiceEncoder? encoder, VoiceRuntime? runtime, float heard) { if ((Object)(object)_device != (Object)null) { _device.text = UIBuild.CurrentDeviceName(); } if ((Object)(object)_status != (Object)null) { _status.text = ((capture == null) ? UIBuild.Localize("$pvc_no_microphone") : UIBuild.Localize("$pvc_status_device", capture.Device ?? "", capture.DeviceRate, capture.Channels)); } if ((Object)(object)_stats != (Object)null) { SteamVoiceTransport steamVoiceTransport = runtime?.Transport; _stats.text = ((steamVoiceTransport == null) ? UIBuild.Localize("$pvc_not_connected") : UIBuild.Localize("$pvc_stats", steamVoiceTransport.PacketsSent, steamVoiceTransport.PacketsReceived, steamVoiceTransport.PacketsDropped)); } if (!((Object)(object)_numbers == (Object)null)) { string text = ((encoder != null && encoder.FramesSinceClip < 50) ? (" <color=#ff8080>" + UIBuild.Localize("$pvc_too_loud") + "</color>") : ""); _numbers.text = UIBuild.Localize("$pvc_numbers", (capture?.PeakLevel ?? 0f).ToString("0.000"), (encoder?.LastRms ?? 0f).ToString("0.000"), heard.ToString("0.000"), (-60f).ToString("0")) + text; } } private static void SetFill(RectTransform? fill, float value) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fill != (Object)null) { fill.anchorMax = new Vector2(UIBuild.MeterScale(value), 1f); } } private static void SetToggle(Toggle? toggle, ConfigEntry<ProximityVoiceChatPlugin.Toggle> entry) { if ((Object)(object)toggle != (Object)null) { toggle.SetIsOnWithoutNotify(entry.Value.IsOn()); } } } internal sealed class VoiceEntryUI : MonoBehaviour { private static readonly Color Speaking = new Color(0.45f, 1f, 0.45f, 1f); private static readonly Color Silent = new Color(1f, 1f, 1f, 0.55f); private static readonly Color Blocked = new Color(1f, 0.45f, 0.45f, 1f); private const float FallbackSpacing = -60f; private const float IconSize = 48f; private const float Gap = 12f; private const float RefreshInterval = 0.1f; private const float ExtraHeight = 40f; private const float LabelWidth = 64f; private const float SliderWidth = 296f; private const float SliderHeight = 14f; private const float ValueWidth = 46f; private const float TextHeight = 20f; private const int FontSize = 14; private const float DefaultNameLeft = 76f; private const float DefaultNameBottom = -28f; private static bool _warned; private Image? _icon; private Slider? _volume; private Text? _volumeText; private ulong _steamId; private bool _own; private bool _suppress; private float _timer; internal void Bind(SessionPlayerListEntry entry, bool isOwnPlayer) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown _own = isOwnPlayer; if (PeerPreferences.TryGetSteamId(entry.User, out _steamId)) { VoiceSprites.Resolve(); GrowRow((RectTransform)((Component)entry).transform); BuildMute(entry); BuildVolume(entry); Refresh(); } } private void BuildMute(SessionPlayerListEntry entry) { //IL_0107: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown if ((Object)(object)_icon != (Object)null) { return; } Transform val = ((Component)entry).transform.Find("PVC_MuteImage"); if ((Object)(object)val != (Object)null) { _icon = ((Component)val).GetComponent<Image>(); Wire((val.childCount > 0) ? ((Component)val.GetChild(0)).GetComponent<Button>() : null); return; } Transform val2 = ((Component)entry).transform.Find("MuteImage"); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(true); _icon = ((Component)val2).GetComponent<Image>(); Transform obj = val2.Find("Mute"); Wire((obj != null) ? ((Component)obj).GetComponent<Button>() : null); return; } Transform obj2 = ((Component)entry).transform.Find("BlockImage"); RectTransform val3 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); Transform obj3 = ((Component)entry).transform.Find("KickImage"); RectTransform val4 = (RectTransform)(object)((obj3 is RectTransform) ? obj3 : null); if ((Object)(object)val3 == (Object)null) { if (!_warned) { _warned = true; ProximityVoiceChatPlugin.Log.LogWarning((object)"No BlockImage on the player list row, so there is nothing to clone a mute button from. Player list voice controls are off."); } return; } float num = (((Object)(object)val4 != (Object)null) ? (val3.anchoredPosition.x - val4.anchoredPosition.x) : (-60f)); GameObject val5 = Object.Instantiate<GameObject>(((Component)val3).gameObject, ((Component)entry).transform); ((Object)val5).name = "PVC_MuteImage"; val5.SetActive(true); Pin((RectTransform)val5.transform, val3.anchoredPosition.x + num, 48f, 48f); _icon = val5.GetComponent<Image>(); Transform val6 = ((val5.transform.childCount > 0) ? val5.transform.GetChild(0) : null); if ((Object)(object)val6 != (Object)null) { ((Object)val6).name = "PVC_Mute"; Wire(((Component)val6).GetComponent<Button>()); } } private void Wire(Button? button) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown if (!((Object)(object)button == (Object)null)) { for (int i = 0; i < ((UnityEventBase)button.onClick).GetPersistentEventCount(); i++) { ((UnityEventBase)button.onClick).SetPersistentListenerState(i, (UnityEventCallState)0); } ((UnityEventBase)button.onClick).RemoveAllListeners(); ((UnityEvent)button.onClick).AddListener(new UnityAction(OnClick)); } } private void BuildVolume(SessionPlayerListEntry entry) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00da: 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_0130: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) if (_own || (Object)(object)_volume != (Object)null) { return; } Slider val = ((IEnumerable<Slider>)((Component)entry).GetComponentsInChildren<Slider>(true)).FirstOrDefault((Func<Slider, bool>)((Slider x) => ((Object)x).name == "PVC_Volume")); if ((Object)(object)val != (Object)null) { _volume = val; Transform obj = ((Component)val).transform.parent.Find("PVC_VolumeValue"); _volumeText = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null); ((UnityEventBase)_volume.onValueChanged).RemoveAllListeners(); ((UnityEvent<float>)(object)_volume.onValueChanged).AddListener((UnityAction<float>)OnVolumeChanged); return; } RectTransform val2 = (RectTransform)((Component)entry).transform; Transform obj2 = ((Component)entry).transform.Find("Background"); RectTransform val3 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if (!((Object)(object)val3 == (Object)null)) { float y = (NameBottomEdge(val2) - val2.sizeDelta.y * 0.5f) * 0.5f; float num = NameLeftEdge(val2); Text obj3 = UIFactory.Text("PVC_VolumeLabel", (Transform)(object)val3, UIBuild.Localize("$pvc_volume_label"), TextRole.Body, 14, (TextAnchor)3); PinLeft((RectTransform)((Component)obj3).transform, num, y, 64f, 20f); ((Graphic)obj3).color = GameColors.Muted; _volume = UIFactory.Slider("PVC_Volume", (Transform)(object)val3, new Vector2(296f, 14f), 0f, 2f, PeerPreferences.GetVolume(_steamId), OnVolumeChanged); PinLeft((RectTransform)((Component)_volume).transform, num + 64f + 12f, y, 296f, 14f); _volumeText = UIFactory.Text("PVC_VolumeValue", (Transform)(object)val3, "", TextRole.Body, 14, (TextAnchor)3); PinLeft((RectTransform)((Component)_volumeText).transform, num + 64f + 12f + 296f + 12f, y, 46f, 20f); ((Graphic)_volumeText).color = GameColors.Beige; } } private static void GrowRow(RectTransform row) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)((Transform)row).Find("PVC_Tall") != (Object)null)) { GameObject val = new GameObject("PVC_Tall", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)row, false); val.SetActive(false); row.sizeDelta = new Vector2(row.sizeDelta.x, row.sizeDelta.y + 40f); LayoutRebuilder.MarkLayoutForRebuild(row); } } private static float NameLeftEdge(RectTransform row) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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) //IL_0055: Unknown result type (might be due to invalid IL or missing references) RectTransform[] componentsInChildren = ((Component)row).GetComponentsInChildren<RectTransform>(true); foreach (RectTransform val in componentsInChildren) { if (((Object)val).name == "CharacterName" && Mathf.Approximately(val.anchorMin.x, 0f)) { float x = val.anchoredPosition.x; float x2 = val.pivot.x; Rect rect = val.rect; return x - x2 * ((Rect)(ref rect)).width; } } return 76f; } private static float NameBottomEdge(RectTransform row) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) float num = float.PositiveInfinity; RectTransform[] componentsInChildren = ((Component)row).GetComponentsInChildren<RectTransform>(true); foreach (RectTransform val in componentsInChildren) { if (!(((Object)val).name != "CharacterName") || !(((Object)val).name != "Gamertag")) { float num2 = num; float y = val.anchoredPosition.y; float num3 = 1f - val.pivot.y; Rect rect = val.rect; num = Mathf.Min(num2, y - num3 * ((Rect)(ref rect)).height); } } if (!float.IsPositiveInfinity(num)) { return num; } return -28f; } private static void Pin(RectTransform rect, float x, float width, float height) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) rect.anchorMin = new Vector2(1f, 0.5f); rect.anchorMax = new Vector2(1f, 0.5f); rect.pivot = new Vector2(0.5f, 0.5f); ((Transform)rect).localScale = Vector3.one; rect.sizeDelta = new Vector2(width, height); rect.anchoredPosition = new Vector2(x, 0f); } private static void PinLeft(RectTransform rect, float x, float y, float width, float height) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0f, 0.5f); rect.anchorMax = new Vector2(0f, 0.5f); rect.pivot = new Vector2(0f, 0.5f); ((Transform)rect).localScale = Vector3.one; rect.sizeDelta = new Vector2(width, height); rect.anchoredPosition = new Vector2(x, y); } private void OnVolumeChanged(float value) { if (!_suppress) { PeerPreferences.SetVolume(_steamId, value); ProximityVoiceChatPlugin.SaveConfig(); } } private void OnClick() { if (_own) { ProximityVoiceChatPlugin.MuteSelf.Value = ((!ProximityVoiceChatPlugin.MuteSelf.Value.IsOn()) ? ProximityVoiceChatPlugin.Toggle.On : ProximityVoiceChatPlugin.Toggle.Off); } else { PeerPreferences.ToggleMuted(_steamId); VoiceRuntime.Instance?.Playback?.Remove(_steamId); ProximityVoiceChatPlugin.SaveConfig(); } Refresh(); } private void Update() { if (!((Object)(object)_icon == (Object)null)) { _timer += Time.unscaledDeltaTime; if (!(_timer < 0.1f)) { _timer = 0f; Refresh(); } } } private void Refresh() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) if (!((Object)(object)_icon == (Object)null)) { bool flag = (_own ? ProximityVoiceChatPlugin.MuteSelf.Value.IsOn() : PeerPreferences.IsSilenced(_steamId)); if ((Object)(object)VoiceSprites.Speaker != (Object)null && (Object)(object)VoiceSprites.Muted != (Object)null) { _icon.sprite = (flag ? VoiceSprites.Muted : VoiceSprites.Speaker); } ((Graphic)_icon).color = (flag ? Blocked : (IsTalking() ? Speaking : Silent)); RefreshVolume(flag); } } private void RefreshVolume(bool muted) { if (!((Object)(object)_volume == (Object)null) && !((Object)(object)_volumeText == (Object)null)) { float volume = PeerPreferences.GetVolume(_steamId); _suppress = true; _volume.SetValueWithoutNotify(volume); _suppress = false; ((Selectable)_volume).interactable = !PeerPreferences.IsBlockedByGame(_steamId); _volumeText.text = (muted ? UIBuild.Localize("$pvc_mute") : volume.ToString("0.00")); } } private bool IsTalking() { VoiceRuntime instance = VoiceRuntime.Instance; if ((Object)(object)instance == (Object)null) { return false; } if (_own) { return instance.Encoder?.IsTransmitting ?? false; } if (instance.Playback != null && instance.Playback.Streams.TryGetValue(_steamId, out PeerVoiceStream value)) { return value.Speaking; } return false; } } internal static class VoiceSprites { private const int Size = 128; private const int Samples = 3; private const int MaxAlpha = 255; private const float PixelsPerUnit = 100f; private const int QuietWaves = 1; private const int TalkingWaves = 3; private const float Middle = 0.5f; private const float ConeMouth = 0.5f; private const float BodyLeft = 0.16f; private const float BodyRight = 0.3f; private const float BodyHalfHeight = 0.11f; private const float ConeFlare = 0.2f; private const float SlashHalfWidth = 0.035f; private const float SlashGap = 0.075f; private const float WaveArcDegrees = 52f; private const float WaveInner = 0.1f; private const float WaveSpacing = 0.1f; private const float WaveThickness = 0.045f; private static readonly Vector2 SlashStart = new Vector2(0.17f, 0.2f); private static readonly Vector2 SlashEnd = new Vector2(0.83f, 0.8f); private static bool _built; internal static Sprite? Speaker { get; private set; } internal static Sprite? SpeakerTalking { get; private set; } internal static Sprite? Muted { get; private set; } internal static void Resolve() { if (!_built) { _built = true; Speaker = Build(1, slash: false); SpeakerTalking = Build(3, slash: false); Muted = Build(0, slash: true); } } private static Sprite Build(int waves, bool slash) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) //IL_0028: Expected O, but got Unknown //IL_013b: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1, hideFlags = (HideFlags)61 }; Color32[] array = (Color32[])(object)new Color32[16384]; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num = 0f; for (int k = 0; k < 3; k++) { for (int l = 0; l < 3; l++) { float u = ((float)j + ((float)l + 0.5f) / 3f) / 128f; float v = ((float)i + ((float)k + 0.5f) / 3f) / 128f; if (Inside(u, v, waves, slash)) { num += 1f; } } } num /= 9f; byte b = (byte)Mathf.Clamp(Mathf.RoundToInt(num * 255f), 0, 255); array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b); } } val.SetPixels32(array); val.Apply(false, false); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).hideFlags = (HideFlags)61; return obj; } private static bool Inside(float u, float v, int waves, bool slash) { if (slash) { float num = DistanceToSlash(u, v); if (num <= 0.035f) { return true; } if (num <= 0.075f) { return false; } } float num2 = Mathf.Abs(v - 0.5f); if (u >= 0.16f && u <= 0.3f && num2 <= 0.11f) { return true; } if (u > 0.3f && u <= 0.5f && num2 <= 0.11f + (u - 0.3f) / 0.19999999f * 0.2f) { return true; } if (waves <= 0) { return false; } float num3 = u - 0.5f; float num4 = v - 0.5f; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); if (num3 <= 0f) { return false; } if (Mathf.Abs(Mathf.Atan2(num4, num3)) * 57.29578f > 52f) { return false; } for (int i = 0; i < waves; i++) { float num6 = 0.1f + (float)i * 0.1f; if (num5 >= num6 && num5 <= num6 + 0.045f) { return true; } } return false; } private static float DistanceToSlash(float u, float v) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) Vector2 val = new Vector2(u, v); Vector2 val2 = SlashEnd - SlashStart; float num = Mathf.Clamp01(Vector2.Dot(val - SlashStart, val2) / Vector2.Dot(val2, val2)); return Vector2.Distance(val, SlashStart + val2 * num); } } internal sealed class SpeakingIndicator : MonoBehaviour { private sealed class Marker { internal GameObject Root; internal Image Icon; internal RectTransform Rect; internal float Shown; } private const float FadeRate = 6f; private const float IconSize = 34f; private const float PeerHeadHeight = 1.5f; private const float FadeBandFraction = 0.25f; private const float BounceBase = 0.9f; private const float BounceDepth = 0.25f; private const float Invisible = 0.001f; private static readonly List<RosterEntry> NoPeers = new List<RosterEntry>(); private readonly List<Marker> _peers = new List<Marker>(); private Marker? _self; private Hud? _hud; private void OnDestroy() { Teardown(); } private void LateUpdate() { bool flag = ProximityVoiceChatPlugin.ShowSpeakingIndicator.Value.IsOn(); bool flag2 = ProximityVoiceChatPlugin.PeerIndicators.Value.IsOn(); if (!flag && !flag2) { Teardown(); return; } Player localPlayer = Player.m_localPlayer; Hud instance = Hud.instance; Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)localPlayer == (Object)null || !Object.op_Implicit((Object)(object)localPlayer) || (Object)(object)instance == (Object)null || !Object.op_Implicit((Object)(object)instance) || (Object)(object)mainCamera == (Object)null || Hud.IsUserHidden()) { HideAll(); return; } if ((Object)(object)_hud != (Object)(object)instance) { Teardown(); _hud = instance; } if (flag) { DrawSelf(instance, mainCamera, localPlayer); } else { Fade(_self); } DrawPeers(instance, mainCamera, flag2); } private void DrawSelf(Hud hud, Camera camera, Player player) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) if (_self == null) { _self = Build(hud, "PVC_Speaking"); } VoiceEncoder voiceEncoder = VoiceRuntime.Instance?.Encoder; bool flag = ProximityVoiceChatPlugin.MuteSelf.Value.IsOn() || ProximityVoiceChatPlugin.Deafen.Value.IsOn(); bool flag2 = !flag && voiceEncoder != null && voiceEncoder.IsSpeaking && VoiceRuntime.GateOpen(); float level = ((!flag && voiceEncoder != null) ? UIBuild.MeterScale(voiceEncoder.LastRms) : 0f); _self.Icon.sprite = (flag ? VoiceSprites.Muted : VoiceSprites.SpeakerTalking); Vector3 world = ((Character)player).GetHeadPoint() + Vector3.up * ProximityVoiceChatPlugin.SpeakingIndicatorHeight.Value; Place(_self, camera, world, flag2 || flag, flag ? GameColors.Danger : GameColors.Beige, level, 1f, 1f); } private void DrawPeers(Hud hud, Camera camera, bool wantPeers) { //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) VoiceRuntime instance = VoiceRuntime.Instance; IReadOnlyList<RosterEntry> readOnlyList; if (!((Object)(object)instance != (Object)null && wantPeers)) { IReadOnlyList<RosterEntry> noPeers = NoPeers; readOnlyList = noPeers; } else { readOnlyList = instance.Roster.Entries; } IReadOnlyList<RosterEntry> readOnlyList2 = readOnlyList; float value = ProximityVoiceChatPlugin.PeerIndicatorScale.Value; bool flag = ProximityVoiceChatPlugin.PeerIndicatorThroughWalls.Value.IsOn(); float value2 = ProximityVoiceChatPlugin.MaxRange.Value; while (_peers.Count < readOnlyList2.Count) { _peers.Add(Build(hud, "PVC_PeerSpeaking")); } for (int i = 0; i < _peers.Count; i++) { Marker marker = _peers[i]; if (i >= readOnlyList2.Count) { Fade(marker); continue; } RosterEntry rosterEntry = readOnlyList2[i]; instance.Links.TryGetValue(rosterEntry.SteamId, out PeerLink value3); bool flag2 = PeerPreferences.IsSilenced(rosterEntry.SteamId); PeerVoiceStream peerVoiceStream = null; if (instance.Playback != null && instance.Playback.Streams.TryGetValue(rosterEntry.SteamId, out PeerVoiceStream value4)) { peerVoiceStream = value4; } bool num = ((!flag2) ? (peerVoiceStream?.Speaking ?? false) : (value3?.Transmitting ?? false)); bool flag3 = !flag && (peerVoiceStream?.Occluded ?? false); bool wanted = num && !flag3 && rosterEntry.HasPosition && (value3?.InRange ?? false); marker.Icon.sprite = (flag2 ? VoiceSprites.Muted : VoiceSprites.SpeakerTalking); float level = ((!flag2 && peerVoiceStream != null) ? UIBuild.MeterScale(peerVoiceStream.OutputRms) : 0f); float num2 = value3?.Distance ?? value2; float fade = Mathf.Clamp01((value2 - num2) / Mathf.Max(1f, value2 * 0.25f)); Vector3 world = HeadOf(rosterEntry) + Vector3.up * ProximityVoiceChatPlugin.PeerIndicatorHeight.Value; Place(marker, camera, world, wanted, flag2 ? GameColors.Danger : GameColors.Beige, level, value, fade); } } private static Vector3 HeadOf(RosterEntry entry) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) if (!((Object)(object)entry.Player != (Object)null) || !Object.op_Implicit((Object)(object)entry.Player)) { return entry.LastKnownPosition + Vector3.up * 1.5f; } return ((Character)entry.Player).GetHeadPoint(); } private static void Place(Marker marker, Camera camera, Vector3 world, bool wanted, Color color, float level, float scale, float fade) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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) marker.Shown = Mathf.MoveTowards(marker.Shown, wanted ? 1f : 0f, 6f * Time.unscaledDeltaTime); float num = marker.Shown * fade; if (num <= 0.001f) { Hide(marker); return; } Vector3 val = Utils.WorldToScreenPointScaled(camera, world); if (val.z <= 0f) { Hide(marker); return; } marker.Root.SetActive(true); ((Transform)marker.Rect).position = val; ((Transform)marker.Rect).localScale = Vector3.one * scale * (0.9f + 0.25f * level) * marker.Shown; color.a = num; ((Graphic)marker.Icon).color = color; } private static Marker Build(Hud hud, string name) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) VoiceSprites.Resolve(); GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(((Component)hud).transform, false); RectTransform val2 = (RectTransform)val.transform; val2.sizeDelta = new Vector2(34f, 34f); Image component = val.GetComponent<Image>(); component.sprite = VoiceSprites.SpeakerTalking; ((Graphic)component).raycastTarget = false; component.preserveAspect = true; val.SetActive(false); return new Marker { Root = val, Icon = component, Rect = val2 }; } private static void Fade(Marker? marker) { if (marker != null) { marker.Shown = Mathf.MoveTowards(marker.Shown, 0f, 6f * Time.unscaledDeltaTime); if (marker.Shown <= 0.001f) { Hide(marker); } } } private static void Hide(Marker marker) { if ((Object)(object)marker.Root != (Object)null && marker.Root.activeSelf) { marker.Root.SetActive(false); } } private void HideAll() { if (_self != null) { Hide(_self); } for (int i = 0; i < _peers.Count; i++) { Hide(_peers[i]); } } private void Teardown() { if (_self != null) { Object.Destroy((Object)(object)_self.Root); _self = null; } for (int i = 0; i < _peers.Count; i++) { Object.Destroy((Object)(object)_peers[i].Root); } _peers.Clear(); _hud = null; } } internal static class KeyBinder { private static readonly KeyCode[] Modifiers; private static KeyCode[]? _candidates; private static int _startedFrame; private static readonly List<KeyCode> Held; internal static ConfigEntry<KeyboardShortcut>? Target; internal static bool Listening => Target != null; internal static bool IsListening(ConfigEntry<KeyboardShortcut> entry) { return Target == entry; } internal static void Begin(ConfigEntry<KeyboardShortcut> entry) { Target = entry; _startedFrame = Time.frameCount; } internal static void Cancel() { Target = null; } internal static void Tick() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between I4 and Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<KeyboardShortcut> target = Target; if (target == null || !Input.anyKeyDown || Time.frameCount == _startedFrame) { return; } if (Input.GetKeyDown((KeyCode)27)) { Target = null; return; } if (Input.GetKeyDown((KeyCode)8) || Input.GetKeyDown((KeyCode)127)) { target.Value = new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()); Target = null; return; } if (_candidates == null) { _candidates = BuildCandidates(); } for (int i = 0; i < _candidates.Length; i++) { KeyCode val = _candidates[i]; if (!Input.GetKeyDown(val)) { continue; } Held.Clear(); for (int j = 0; j < Modifiers.Length; j++) { if ((int)Modifiers[j] != (int)val && Input.GetKey(Modifiers[j])) { Held.Add(Modifiers[j]); } } target.Value = new KeyboardShortcut(val, Held.ToArray()); Target = null; break; } } internal static string Describe(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return UIBuild.Localize("$pvc_key_unbound"); } string text = ""; foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { text = text + ((object)modifier/*cast due to .constrained prefix*/).ToString() + " + "; } return text + ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString(); } private static KeyCode[] BuildCandidates() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) List<KeyCode> list = new List<KeyCode>(); foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if ((int)value != 0 && (int)value != 323 && !((object)value/*cast due to .constrained prefix*/).ToString().StartsWith("Joystick", StringComparison.Ordinal)) { list.Add(value); } } return list.ToArray(); } static KeyBinder() { KeyCode[] array = new KeyCode[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); Modifiers = (KeyCode[])(object)array; Held = new List<KeyCode>(); } } } namespace ProximityVoiceChat.Voice { internal static class MusicDucking { [HarmonyPatch(typeof(MusicMan), "UpdateMusic")] private static class MusicMan_UpdateMusic_Patch { private static void Postfix(MusicMan __instance) { if (!(_duck >= 0.999f) && !((Object)(object)__instance.m_musicSource == (Object)null)) { AudioSource musicSource = __instance.m_musicSource; musicSource.volume *= _duck; } } } private const float FadeRate = 3f; private static float _duck = 1f; internal static void Tick(float deltaTime, bool someoneSpeaking) { float num = 1f; if (someoneSpeaking && ProximityVoiceChatPlugin.DuckMusic.Value.IsOn()) { num = Mathf.Clamp01(ProximityVoiceChatPlugin.DuckMusicAmount.Value); } _duck = Mathf.MoveTowards(_duck, num, 3f * deltaTime); } internal static void Reset() { _duck = 1f; } } internal sealed class JawAnimator : MonoBehaviour { private sealed class Mouth { internal Transform? Jaw; internal Quaternion Rest; internal float Open; internal float Seed; internal bool Missing; } private const string JawBone = "Jaw"; private const float AttackPerSecond = 14f; private const float ReleasePerSecond = 7f; private const float Floor = 0.012f; private const float Closed = 0.0005f; private const float WobbleBase = 0.85f; private const float WobbleDepth = 0.15f; private const float WobbleHz = 9f; private const float SeedRange = 10f; private readonly Dictionary<Player, Mouth> _mouths = new Dictionary<Player, Mouth>(); private readonly List<Player> _stale = new List<Player>(); private void LateUpdate() { if (ProximityVoiceChatPlugin.JawMovement.Value == ProximityVoiceChatPlugin.Toggle.Off || (Object)(object)ZNet.instance == (Object)null) { if (_mouths.Count > 0) { ReleaseAll(); } return; } VoiceRuntime instance = VoiceRuntime.Instance; if ((Object)(object)instance == (Object)null) { return; } float deltaTime = Time.deltaTime; VoiceEncoder encoder = instance.Encoder; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && Object.op_Implicit((Object)(object)localPlayer)) { float level = ((encoder != null && encoder.IsSpeaking && VoiceRuntime.GateOpen()) ? encoder.LastRms : 0f); if (ProximityVoiceChatPlugin.LoopbackTest.Value.IsOn() && instance.Playback != null && instance.Playback.Streams.TryGetValue(1uL, out PeerVoiceStream value)) { level = (value.Speaking ? value.OutputRms : 0f); } Drive(localPlayer, level, deltaTime); } if (instance.Playback != null) { IReadOnlyList<RosterEntry> entries = instance.Roster.Entries; for (int i = 0; i < entries.Count; i++) { RosterEntry rosterEntry = entries[i]; if (!((Object)(object)rosterEntry.Player == (Object)null) && Object.op_Implicit((Object)(object)rosterEntry.Player)) { PeerVoiceStream value2; float level2 = ((instance.Playback.Streams.TryGetValue(rosterEntry.SteamId, out value2)