using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BigVoice.Configuration; using Dissonance.Audio.Playback; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Microsoft.CodeAnalysis; using Mirror; using Rewired; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("BigVoice")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4e2352a9dc4752c0718672eb17293ce5cb0b7461")] [assembly: AssemblyProduct("Big Voice")] [assembly: AssemblyTitle("BigVoice")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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; } } } namespace BigVoice { [BepInPlugin("BigVoice", "Big Voice", "1.0.0")] public class Plugin : BasePlugin { internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigFile PluginConfig; internal static ConfigEntry UnknownPlayerVolume; private Harmony _harmony; private GameObject _configurationUiObject; public ConfigurationHandler ConfigurationHandler { get; private set; } public override void Load() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown Instance = this; Log = ((BasePlugin)this).Log; PluginConfig = ((BasePlugin)this).Config; UnknownPlayerVolume = ((BasePlugin)this).Config.Bind("General", "UnknownPlayerVolume", 1f, new ConfigDescription("VOIP multiplier for players without a matching entry. 0 = muted, 1 = normal, 15 = max.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 15f), Array.Empty())); ConfigurationHandler = new ConfigurationHandler(((BasePlugin)this).Config); _harmony = new Harmony("BigVoice"); HarmonyPatches(); CreateConfigurationUI(); Log.LogInfo((object)"Big Voice loaded"); } private void CreateConfigurationUI() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown try { ClassInjector.RegisterTypeInIl2Cpp(); } catch (Exception ex) { Log.LogDebug((object)("ModConfigurationUI type registration skipped or failed: " + ex.Message)); } _configurationUiObject = new GameObject("Big Voice Configuration UI"); Object.DontDestroyOnLoad((Object)(object)_configurationUiObject); ((Object)_configurationUiObject).hideFlags = (HideFlags)61; _configurationUiObject.AddComponent().Init(); } private void HarmonyPatches() { TryPatch(AccessTools.Method(typeof(PlayerNetworking), "OnStartClient", Type.EmptyTypes, (Type[])null), null, AccessTools.Method(typeof(PlayerNetworkingPatch), "RegisterPostfix", (Type[])null, (Type[])null), "PlayerNetworking.OnStartClient"); TryPatch(AccessTools.Method(typeof(PlayerNetworking), "Start", Type.EmptyTypes, (Type[])null), null, AccessTools.Method(typeof(PlayerNetworkingPatch), "RegisterPostfix", (Type[])null, (Type[])null), "PlayerNetworking.Start"); TryPatch(AccessTools.Method(typeof(PlayerVoicePlaybackControl), "Update", Type.EmptyTypes, (Type[])null), null, AccessTools.Method(typeof(PlayerVoicePlaybackControlPatch), "UpdatePostfix", (Type[])null, (Type[])null), "PlayerVoicePlaybackControl.Update"); TryPatch(AccessTools.Method(typeof(SamplePlaybackComponent), "ProcessSamples", (Type[])null, (Type[])null), null, AccessTools.Method(typeof(SamplePlaybackComponentPatch), "ProcessSamplesPostfix", (Type[])null, (Type[])null), "SamplePlaybackComponent.ProcessSamples"); } private void TryPatch(MethodInfo original, MethodInfo prefix, MethodInfo postfix, string patchName) { //IL_0032: 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) if (original == null) { Log.LogError((object)("Failed to find patch target: " + patchName)); return; } try { _harmony.Patch((MethodBase)original, (prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(prefix), (postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Patches patchInfo = Harmony.GetPatchInfo((MethodBase)original); int valueOrDefault = (patchInfo?.Prefixes?.Count).GetValueOrDefault(); int valueOrDefault2 = (patchInfo?.Postfixes?.Count).GetValueOrDefault(); Log.LogInfo((object)("Installed patch for " + patchName + " prefixes=" + valueOrDefault + " postfixes=" + valueOrDefault2)); } catch (Exception ex) { Log.LogError((object)("Failed to apply the patch for " + patchName + ": " + ex)); } } } internal static class PlayerNetworkingPatch { public static void RegisterPostfix(PlayerNetworking __instance) { PlayerVolumeConfig.Register(__instance); } } internal static class PlayerVoicePlaybackControlPatch { public static void UpdatePostfix(PlayerVoicePlaybackControl __instance) { PlayerCharacter val = ((__instance != null) ? __instance.playerCharacter : null); if ((Object)(object)((val != null) ? val.playerNetworking : null) != (Object)null) { PlayerVolumeConfig.Register(val.playerNetworking); if ((Object)(object)__instance.dissonanceSampleProvider != (Object)null) { PlayerVolumeConfig.RegisterSampleProvider(__instance.dissonanceSampleProvider, val.playerNetworking); } } } } internal static class SamplePlaybackComponentPatch { public static void ProcessSamplesPostfix(SamplePlaybackComponent __instance, ref Il2CppStructArray data, int channels) { float volume = PlayerVolumeConfig.GetVolume(__instance); ApplyGain(data, volume); } private static void ApplyGain(Il2CppStructArray data, float volume) { if (data != null && !Mathf.Approximately(volume, 1f)) { for (int i = 0; i < ((Il2CppArrayBase)(object)data).Length; i++) { int num = i; ((Il2CppArrayBase)(object)data)[num] = ((Il2CppArrayBase)(object)data)[num] * volume; } } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BigVoice"; public const string PLUGIN_NAME = "Big Voice"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace BigVoice.Configuration { public class ConfigurationHandler { private sealed class ConfigChangeListener { private readonly ConfigEntry _entry; private readonly Action _onChanged; private readonly Func _clamp; public ConfigChangeListener(ConfigEntry entry, Action onChanged, Func clamp) { _entry = entry; _onChanged = onChanged; _clamp = clamp; } public void OnSettingChanged(object sender, EventArgs args) { if (_clamp != null) { _entry.Value = _clamp(_entry.Value); } _onChanged(); } } private readonly ConfigFile _config; public KeyCode MenuKey { get; private set; } public ConfigEntry ConfigMenuKey { get; } public ConfigEntry ConfigUnknownPlayerVolume => Plugin.UnknownPlayerVolume; public ConfigurationHandler(ConfigFile configFile) { _config = configFile; Plugin.Log.LogInfo((object)"ConfigurationHandler initialising"); ConfigMenuKey = Bind("General", "Config Menu Key", "F10", "Keyboard key for opening the Big Voice configuration menu", SetupInputKey); SetupInputKey(); Plugin.Log.LogInfo((object)"ConfigurationHandler initialised"); } private ConfigEntry Bind(string section, string key, T defaultValue, string description, Action onChanged = null, Func clamp = null) { ConfigEntry val = _config.Bind(section, key, defaultValue, description); if (clamp != null) { val.Value = clamp(val.Value); } Plugin.Log.LogInfo((object)(key + " set to " + val.Value)); if (onChanged != null) { AddSettingChangedHandler(val, onChanged, clamp); } return val; } private static void AddSettingChangedHandler(ConfigEntry entry, Action onChanged, Func clamp) { EventInfo eventInfo = typeof(ConfigEntry).GetEvent("SettingChanged"); if (eventInfo == null) { Plugin.Log.LogWarning((object)("Could not subscribe to SettingChanged for " + ((ConfigEntryBase)entry).Definition.Key)); return; } ConfigChangeListener firstArgument = new ConfigChangeListener(entry, onChanged, clamp); MethodInfo method = typeof(ConfigChangeListener).GetMethod("OnSettingChanged", BindingFlags.Instance | BindingFlags.Public); Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, firstArgument, method); eventInfo.AddEventHandler(entry, handler); } private void SetupInputKey() { //IL_0015: 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_002b: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse(ConfigMenuKey.Value, out KeyCode result)) { MenuKey = result; Plugin.Log.LogInfo((object)("Menu key set to " + ((object)MenuKey/*cast due to .constrained prefix*/).ToString())); } else { MenuKey = (KeyCode)291; Plugin.Log.LogWarning((object)("Invalid menu key " + ConfigMenuKey.Value + ", using F10")); } } } public class ModConfigurationUI : MonoBehaviour { private const int MouseWheelAxis = 2; private List