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<float> 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<float>("General", "UnknownPlayerVolume", 1f, new ConfigDescription("VOIP multiplier for players without a matching entry. 0 = muted, 1 = normal, 15 = max.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
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<ModConfigurationUI>();
}
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<ModConfigurationUI>().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<float> data, int channels)
{
float volume = PlayerVolumeConfig.GetVolume(__instance);
ApplyGain(data, volume);
}
private static void ApplyGain(Il2CppStructArray<float> data, float volume)
{
if (data != null && !Mathf.Approximately(volume, 1f))
{
for (int i = 0; i < ((Il2CppArrayBase<float>)(object)data).Length; i++)
{
int num = i;
((Il2CppArrayBase<float>)(object)data)[num] = ((Il2CppArrayBase<float>)(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<T>
{
private readonly ConfigEntry<T> _entry;
private readonly Action _onChanged;
private readonly Func<T, T> _clamp;
public ConfigChangeListener(ConfigEntry<T> entry, Action onChanged, Func<T, T> 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<string> ConfigMenuKey { get; }
public ConfigEntry<float> 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<T> Bind<T>(string section, string key, T defaultValue, string description, Action onChanged = null, Func<T, T> clamp = null)
{
ConfigEntry<T> val = _config.Bind<T>(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<T>(ConfigEntry<T> entry, Action onChanged, Func<T, T> clamp)
{
EventInfo eventInfo = typeof(ConfigEntry<T>).GetEvent("SettingChanged");
if (eventInfo == null)
{
Plugin.Log.LogWarning((object)("Could not subscribe to SettingChanged for " + ((ConfigEntryBase)entry).Definition.Key));
return;
}
ConfigChangeListener<T> firstArgument = new ConfigChangeListener<T>(entry, onChanged, clamp);
MethodInfo method = typeof(ConfigChangeListener<T>).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<KeyCode>(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<Option> _options = new List<Option>();
private bool _visible;
private int _selectedIndex;
private int _scrollStartIndex;
private int _knownPlayerConfigVersion = -1;
private bool _prevCursorVisible;
private CursorLockMode _prevCursorLock;
private bool _waitingForBinding;
private Option _bindingTarget;
private Texture2D _whiteTex;
private GUIStyle _titleStyle;
private GUIStyle _rowStyle;
private GUIStyle _hintStyle;
private string titleText = "Big Voice | v 1.0.0";
private string hintText = "F11: Open/Close | Tab or Up/Down: Move | Enter/Click: Change | Scroll Wheel or Left/Right: Adjust Volume | +/-: Scale Menu";
private int RowHeight = 32;
private int PanelWidth = 460;
private int Pad = 12;
private int TitleFontSize = 22;
private int OptionFontSize = 16;
private int HintFontSize = 14;
private Player _player;
private Keyboard _keyboard;
private Mouse _mouse;
public ModConfigurationUI(IntPtr ptr)
: base(ptr)
{
}
private Color GetColor(Color c)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
//IL_0011: 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)SystemInfo.graphicsDeviceType == 21)
{
return ((Color)(ref c)).linear;
}
return c;
}
private void CalculatePanelWidth()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
float num = _titleStyle.CalcSize(new GUIContent(titleText)).x;
foreach (Option option in _options)
{
float x = _rowStyle.CalcSize(new GUIContent(option.Label + ": " + option.DisplayValue())).x;
if (x > num)
{
num = x;
}
}
int num2 = CalculateHintWidth();
num = Mathf.Max(num, (float)num2);
PanelWidth = Mathf.Clamp((int)num + Pad * 2, 460, Screen.width - Pad * 2);
}
private int CalculateHintWidth()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
float num = _hintStyle.CalcHeight(new GUIContent("Test"), 9999f) * 2f;
for (int i = 200; i < Screen.width - Pad * 2; i += 20)
{
if (_hintStyle.CalcHeight(new GUIContent(hintText), (float)i) <= num)
{
return i;
}
}
return Screen.width - Pad * 2;
}
private void Scale(int scale)
{
if (scale >= 0 || HintFontSize >= 2)
{
TitleFontSize += scale * 2;
OptionFontSize += scale * 2;
HintFontSize += scale * 2;
RowHeight = OptionFontSize + 16;
CalculatePanelWidth();
}
}
public void Init()
{
RebuildOptions();
_selectedIndex = 0;
UpdateHintText();
}
private void RebuildOptionsIfNeeded()
{
if (_knownPlayerConfigVersion != PlayerVolumeConfig.Version)
{
RebuildOptions();
}
}
private void RebuildOptions()
{
ConfigurationHandler configurationHandler = Plugin.Instance.ConfigurationHandler;
string selectedLabel = ((_options.Count > 0 && _selectedIndex >= 0 && _selectedIndex < _options.Count) ? _options[_selectedIndex].Label : null);
List<Option> list = new List<Option> { Option.Float("Default Player Volume", configurationHandler.ConfigUnknownPlayerVolume, 0f, 15f, 0.25f) };
foreach (PlayerVolumeOption playerOption in PlayerVolumeConfig.GetPlayerOptions())
{
list.Add(Option.Float(playerOption.DisplayName, playerOption.ConfigEntry, 0f, 15f, 0.25f));
}
list.Add(Option.InputAction("Menu Key", configurationHandler.ConfigMenuKey));
_options = list;
_knownPlayerConfigVersion = PlayerVolumeConfig.Version;
if (selectedLabel != null)
{
int num = _options.FindIndex((Option option) => option.Label == selectedLabel);
_selectedIndex = ((num >= 0) ? num : Mathf.Clamp(_selectedIndex, 0, _options.Count - 1));
}
else
{
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _options.Count - 1);
}
UpdateHintText();
}
private void UpdateHintText()
{
string text = Plugin.Instance.ConfigurationHandler.ConfigMenuKey.Value.Split("/")[^1].ToUpper();
hintText = text + ": Open/Close | Tab or Up/Down: Move | Enter/Click: Change | Scroll Wheel or Left/Right: Adjust Volume | +/-: Scale Menu";
}
private void EnsureStyles()
{
//IL_004b: 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_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
//IL_00a8: Expected O, but got Unknown
//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_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Expected O, but got Unknown
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//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 ((Object)(object)_whiteTex == (Object)null)
{
_whiteTex = new Texture2D(1, 1, (TextureFormat)4, false);
_whiteTex.SetPixel(0, 0, GetColor(Color.white));
_whiteTex.Apply();
}
_titleStyle = new GUIStyle(GUI.skin.label)
{
fontSize = TitleFontSize,
alignment = (TextAnchor)3,
fontStyle = (FontStyle)1
};
_rowStyle = new GUIStyle(GUI.skin.button)
{
alignment = (TextAnchor)3,
fontSize = OptionFontSize,
padding = new RectOffset(10, 10, 4, 4)
};
_hintStyle = new GUIStyle(GUI.skin.label)
{
fontSize = HintFontSize,
alignment = (TextAnchor)3,
wordWrap = true
};
}
private void Update()
{
//IL_0138: 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_0071: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
if (!ReInput.isReady)
{
return;
}
if (_player == null)
{
_player = ReInput.players.GetPlayer(0);
_keyboard = ReInput.controllers.Keyboard;
_mouse = ReInput.controllers.Mouse;
}
if (_waitingForBinding)
{
bool flag = default(bool);
foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
{
if (_keyboard.GetKeyDown(value))
{
string text = ((object)value/*cast due to .constrained prefix*/).ToString();
_bindingTarget.StringEntry.Value = text;
ManualLogSource log = Plugin.Log;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(12, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Rebound ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_bindingTarget.Label);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" to ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
}
log.LogInfo(val2);
_waitingForBinding = false;
UpdateHintText();
_bindingTarget = null;
break;
}
}
return;
}
if (_keyboard.GetKeyDown(Plugin.Instance.ConfigurationHandler.MenuKey))
{
_visible = !_visible;
if (_visible)
{
OnOpened();
}
else
{
OnClosed();
}
}
if (_visible && _options.Count != 0)
{
RebuildOptionsIfNeeded();
if (_keyboard.GetKeyDown((KeyCode)9))
{
bool flag2 = _keyboard.GetKey((KeyCode)304) || _keyboard.GetKey((KeyCode)303);
CycleSelection((!flag2) ? 1 : (-1));
}
if (_keyboard.GetKeyDown((KeyCode)61) || _keyboard.GetKeyDown((KeyCode)43))
{
Scale(1);
}
if (_keyboard.GetKeyDown((KeyCode)45))
{
Scale(-1);
}
if (_keyboard.GetKeyDown((KeyCode)273))
{
CycleSelection(-1);
}
if (_keyboard.GetKeyDown((KeyCode)274))
{
CycleSelection(1);
}
if (_keyboard.GetKeyDown((KeyCode)13) || _keyboard.GetKeyDown((KeyCode)271))
{
ToggleSelected();
}
if (_keyboard.GetKeyDown((KeyCode)276))
{
AdjustNumerical(-1);
}
if (_keyboard.GetKeyDown((KeyCode)275))
{
AdjustNumerical(1);
}
float axis = ((ControllerWithAxes)_mouse).GetAxis(2);
if (axis > 0f)
{
AdjustNumerical(1);
}
else if (axis < 0f)
{
AdjustNumerical(-1);
}
}
}
private void ToggleSelected()
{
Option option = _options[_selectedIndex];
if (option.IsDisabled())
{
return;
}
switch (option.Type)
{
case Option.OptionType.Bool:
option.BoolEntry.Value = !option.BoolEntry.Value;
break;
case Option.OptionType.Int:
{
int num2 = option.IntEntry.Value + option.Step;
if (num2 > option.MaxInt)
{
num2 = option.MinInt;
}
option.IntEntry.Value = num2;
break;
}
case Option.OptionType.Float:
{
float num = option.FloatEntry.Value + option.FloatStep;
if (num > option.MaxFloat)
{
num = option.MinFloat;
}
option.FloatEntry.Value = num;
break;
}
case Option.OptionType.InputAction:
_waitingForBinding = true;
_bindingTarget = option;
break;
case Option.OptionType.String:
break;
}
}
private void AdjustNumerical(int delta)
{
Option option = _options[_selectedIndex];
if (!option.IsDisabled())
{
if (option.Type == Option.OptionType.Bool)
{
option.BoolEntry.Value = delta > 0;
}
else if (option.Type == Option.OptionType.Int)
{
AdjustInt(option, delta);
}
else if (option.Type == Option.OptionType.Float)
{
AdjustFloat(option, delta);
}
}
}
private static void AdjustInt(Option option, int delta)
{
int value = option.IntEntry.Value;
int num = value;
int num2 = Mathf.Max(1, Mathf.CeilToInt((float)(option.MaxInt - option.MinInt) / (float)option.Step) + 1);
for (int i = 0; i < num2; i++)
{
int num3 = Mathf.Clamp(num + delta * option.Step, option.MinInt, option.MaxInt);
if (num3 == num)
{
break;
}
option.IntEntry.Value = num3;
if (option.IntEntry.Value != value)
{
break;
}
num = num3;
}
}
private static void AdjustFloat(Option option, int delta)
{
float value = option.FloatEntry.Value;
float num = value;
int num2 = Mathf.Max(1, Mathf.CeilToInt((option.MaxFloat - option.MinFloat) / option.FloatStep) + 1);
for (int i = 0; i < num2; i++)
{
float num3 = Mathf.Clamp(num + (float)delta * option.FloatStep, option.MinFloat, option.MaxFloat);
if (Mathf.Approximately(num3, num))
{
break;
}
option.FloatEntry.Value = num3;
if (!Mathf.Approximately(option.FloatEntry.Value, value))
{
break;
}
num = num3;
}
}
private void OnOpened()
{
//IL_0012: 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)
RebuildOptionsIfNeeded();
_prevCursorVisible = Cursor.visible;
_prevCursorLock = Cursor.lockState;
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
if (_options.Count > 0 && _options[_selectedIndex].IsDisabled())
{
CycleSelection(1);
}
}
private void OnClosed()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
Cursor.visible = _prevCursorVisible;
Cursor.lockState = _prevCursorLock;
}
private void CycleSelection(int delta)
{
if (_options.Count == 0)
{
return;
}
int selectedIndex = _selectedIndex;
do
{
_selectedIndex = (_selectedIndex + delta) % _options.Count;
if (_selectedIndex < 0)
{
_selectedIndex += _options.Count;
}
}
while (_options[_selectedIndex].IsDisabled() && _selectedIndex != selectedIndex);
}
private void EnsureSelectedVisible(int visibleRows)
{
if (visibleRows <= 0)
{
_scrollStartIndex = 0;
return;
}
if (_selectedIndex < _scrollStartIndex)
{
_scrollStartIndex = _selectedIndex;
}
else if (_selectedIndex >= _scrollStartIndex + visibleRows)
{
_scrollStartIndex = _selectedIndex - visibleRows + 1;
}
_scrollStartIndex = Mathf.Clamp(_scrollStartIndex, 0, Mathf.Max(0, _options.Count - visibleRows));
}
private void OnGUI()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
//IL_0253: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_026a: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
//IL_02de: Unknown result type (might be due to invalid IL or missing references)
if (!_visible)
{
return;
}
RebuildOptionsIfNeeded();
EnsureStyles();
CalculatePanelWidth();
float num = _titleStyle.CalcHeight(new GUIContent(titleText), (float)(PanelWidth - Pad * 2));
float num2 = _options.Count * (RowHeight + 4);
float num3 = _hintStyle.CalcHeight(new GUIContent("Test"), 9999f) * 2f;
int num4 = Mathf.Max(1, Mathf.Min(_options.Count, Mathf.FloorToInt(((float)(Screen.height - 80) - num - num3 - (float)(Pad * 3)) / (float)(RowHeight + 4))));
EnsureSelectedVisible(num4);
num2 = num4 * (RowHeight + 4);
int num5 = Pad + (int)num + 8 + (int)num2 + Pad + (int)num3;
Rect val = default(Rect);
((Rect)(ref val))..ctor(20f, 20f, (float)PanelWidth, (float)num5);
GUI.color = GetColor(new Color(0f, 0f, 0f, 0.75f));
GUI.DrawTexture(val, (Texture)(object)_whiteTex);
GUI.color = Color.white;
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(((Rect)(ref val)).x + (float)Pad, ((Rect)(ref val)).y + (float)Pad, ((Rect)(ref val)).width - (float)(Pad * 2), num);
GUI.Label(val2, titleText, _titleStyle);
float num6 = ((Rect)(ref val2)).yMax + 8f;
int num7 = Mathf.Min(_options.Count, _scrollStartIndex + num4);
Rect val3 = default(Rect);
for (int i = _scrollStartIndex; i < num7; i++)
{
((Rect)(ref val3))..ctor(((Rect)(ref val)).x + (float)Pad, num6, ((Rect)(ref val)).width - (float)(Pad * 2), (float)RowHeight);
Option option = _options[i];
if (((Rect)(ref val3)).Contains(Event.current.mousePosition) && !option.IsDisabled())
{
_selectedIndex = i;
}
if (i == _selectedIndex && !option.IsDisabled())
{
GUI.color = GetColor(new Color(1f, 1f, 1f, 0.24f));
GUI.DrawTexture(val3, (Texture)(object)_whiteTex);
GUI.color = Color.white;
}
GUI.enabled = !option.IsDisabled();
if (option.Label == "Menu Key" && _waitingForBinding)
{
GUI.color = GetColor(new Color(0f, 0f, 0f, 0.6f));
GUI.DrawTexture(val3, (Texture)(object)_whiteTex);
GUI.color = Color.white;
GUI.Button(val3, "Press any key...", _rowStyle);
}
else if (GUI.Button(val3, option.Label + ": " + option.DisplayValue(), _rowStyle) && !option.IsDisabled())
{
ToggleSelected();
}
GUI.enabled = true;
num6 += (float)(RowHeight + 4);
}
GUI.Label(new Rect(((Rect)(ref val)).x + (float)Pad, ((Rect)(ref val)).yMax - (float)Pad - num3, ((Rect)(ref val)).width - (float)(Pad * 2), num3), hintText, _hintStyle);
}
private void OnDestroy()
{
if ((Object)(object)_whiteTex != (Object)null)
{
Object.Destroy((Object)(object)_whiteTex);
_whiteTex = null;
}
}
}
public class Option
{
public enum OptionType
{
Bool,
Int,
String,
InputAction,
Float
}
public string Label { get; set; }
public OptionType Type { get; set; }
public ConfigEntry<bool> BoolEntry { get; set; }
public ConfigEntry<int> IntEntry { get; set; }
public ConfigEntry<string> StringEntry { get; set; }
public int MinInt { get; set; }
public int MaxInt { get; set; }
public int Step { get; set; }
public Func<bool> IsDisabled { get; set; } = () => false;
public Func<string> DisplayValue { get; set; } = () => "";
public ConfigEntry<float> FloatEntry { get; set; }
public float MinFloat { get; set; }
public float MaxFloat { get; set; }
public float FloatStep { get; set; }
private Option(string label, OptionType type)
{
Label = label;
Type = type;
}
public static Option Float(string label, ConfigEntry<float> entry, float min, float max, float step = 0.05f, Func<bool> isDisabled = null, Func<string> displayValue = null)
{
return new Option(label, OptionType.Float)
{
FloatEntry = entry,
MinFloat = min,
MaxFloat = max,
FloatStep = step,
IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
DisplayValue = (displayValue ?? ((Func<string>)(() => entry.Value.ToString("F2") + "x")))
};
}
public static Option Bool(string label, ConfigEntry<bool> entry, Func<bool> isDisabled = null)
{
return new Option(label, OptionType.Bool)
{
BoolEntry = entry,
IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
DisplayValue = () => (!entry.Value) ? "OFF" : "ON"
};
}
public static Option InputAction(string label, ConfigEntry<string> entry, Func<bool> isDisabled = null)
{
return new Option(label, OptionType.InputAction)
{
StringEntry = entry,
IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
DisplayValue = delegate
{
string[] array = entry.Value.Split("/");
return (array.Length <= 1) ? entry.Value : array[^1].ToUpper();
}
};
}
public static Option Int(string label, ConfigEntry<int> entry, int min, int max, int step = 1, Func<bool> isDisabled = null, Func<string> displayValue = null)
{
return new Option(label, OptionType.Int)
{
IntEntry = entry,
MinInt = min,
MaxInt = max,
Step = step,
IsDisabled = (isDisabled ?? ((Func<bool>)(() => false))),
DisplayValue = (displayValue ?? ((Func<string>)(() => entry.Value.ToString())))
};
}
}
internal sealed class PlayerRecord(string displayName, ConfigEntry<float> configEntry)
{
public string DisplayName { get; set; } = displayName;
public ConfigEntry<float> ConfigEntry { get; } = configEntry;
}
internal static class PlayerVolumeConfig
{
private const string PlayerVolumesSection = "Player Volumes";
public const float MinVolume = 0f;
public const float MaxVolume = 15f;
public const float VolumeStep = 0.25f;
private static readonly List<PlayerRecord> Records = new List<PlayerRecord>();
private static readonly Dictionary<string, PlayerRecord> RecordsById = new Dictionary<string, PlayerRecord>();
private static readonly Dictionary<int, PlayerRecord> RecordsBySampleProviderId = new Dictionary<int, PlayerRecord>();
public static int Version { get; private set; }
public static void Register(PlayerNetworking networking)
{
try
{
GetOrCreateRecord(networking);
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Failed to register player VOIP volume: " + ex));
}
}
public static void RegisterSampleProvider(SamplePlaybackComponent sampleProvider, PlayerNetworking networking)
{
if ((Object)(object)sampleProvider == (Object)null)
{
return;
}
try
{
PlayerRecord orCreateRecord = GetOrCreateRecord(networking);
if (orCreateRecord != null)
{
RecordsBySampleProviderId[((Object)sampleProvider).GetInstanceID()] = orCreateRecord;
}
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Failed to register VOIP sample provider: " + ex));
}
}
public static IReadOnlyList<PlayerVolumeOption> GetPlayerOptions()
{
return (from record in Records.OrderBy<PlayerRecord, string>((PlayerRecord record) => record.DisplayName, StringComparer.OrdinalIgnoreCase)
select new PlayerVolumeOption(record.DisplayName, record.ConfigEntry)).ToArray();
}
public static float GetVolume(SamplePlaybackComponent sampleProvider)
{
if ((Object)(object)sampleProvider != (Object)null && RecordsBySampleProviderId.TryGetValue(((Object)sampleProvider).GetInstanceID(), out var value))
{
return ClampVolume(value.ConfigEntry.Value);
}
return ClampVolume(Plugin.UnknownPlayerVolume.Value);
}
private static PlayerRecord GetOrCreateRecord(PlayerNetworking networking)
{
if ((Object)(object)networking == (Object)null || ((NetworkBehaviour)networking).isLocalPlayer)
{
return null;
}
string playerId = GetPlayerId(networking);
if (string.IsNullOrWhiteSpace(playerId))
{
return null;
}
string playerName = GetPlayerName(networking);
if (RecordsById.TryGetValue(playerId, out var value))
{
UpdateDisplayName(value, playerName);
return value;
}
value = new PlayerRecord(GetDisplayName(playerName, playerId), CreateEntry(playerId, GetDisplayName(playerName, playerId)));
RecordsById[playerId] = value;
Records.Add(value);
Version++;
return value;
}
private static void UpdateDisplayName(PlayerRecord record, string name)
{
if (!string.IsNullOrWhiteSpace(name) && !string.Equals(record.DisplayName, name, StringComparison.Ordinal))
{
record.DisplayName = name;
Version++;
}
}
private static ConfigEntry<float> CreateEntry(string id, string displayName)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
ConfigDefinition val = new ConfigDefinition("Player Volumes", id);
ConfigEntry<float> result = default(ConfigEntry<float>);
if (Plugin.PluginConfig.TryGetEntry<float>(val, ref result))
{
return result;
}
ConfigEntry<float> result2 = Plugin.PluginConfig.Bind<float>(val, ClampVolume(Plugin.UnknownPlayerVolume.Value), new ConfigDescription("VOIP volume multiplier for " + displayName + ". Player ID " + id, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
Plugin.PluginConfig.Save();
Plugin.Log.LogInfo((object)("Created VOIP volume config entry for " + displayName + " as [Player Volumes] " + id));
return result2;
}
private static string GetPlayerId(PlayerNetworking networking)
{
if (networking.NetworkuserPlatformId != 0L)
{
return networking.NetworkuserPlatformId.ToString(CultureInfo.InvariantCulture);
}
return "";
}
private static string GetPlayerName(PlayerNetworking networking)
{
return networking.NetworkmoderationName;
}
private static string GetDisplayName(string name, string id)
{
if (!string.IsNullOrWhiteSpace(name))
{
return name;
}
return id;
}
private static float ClampVolume(float value)
{
if (!float.IsNaN(value) && !float.IsInfinity(value))
{
return Math.Clamp(value, 0f, 15f);
}
return 1f;
}
}
public readonly struct PlayerVolumeOption
{
public string DisplayName { get; }
public ConfigEntry<float> ConfigEntry { get; }
public PlayerVolumeOption(string displayName, ConfigEntry<float> configEntry)
{
DisplayName = displayName;
ConfigEntry = configEntry;
}
}
}