using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Antro.BetterVolume")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Antro.BetterVolume")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyProduct("Antro.BetterVolume")]
[assembly: AssemblyTitle("Antro.BetterVolume")]
[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 BetterVolume
{
[BepInPlugin("BetterVolume", "BetterVolume", "1.0.9")]
public class BetterVolumePlugin : BaseUnityPlugin
{
public static ManualLogSource Log;
static BetterVolumePlugin()
{
Console.WriteLine("[BetterVolume] Static Constructor: Assembly loaded into Mono context.");
}
private void Awake()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"BetterVolume Awake() started execution.");
try
{
Harmony val = new Harmony("BetterVolume");
MethodInfo methodInfo = AccessTools.PropertySetter(AccessTools.TypeByName("Dissonance.RemoteVoicePlayerState"), "Volume");
if (methodInfo != null)
{
MethodInfo methodInfo2 = AccessTools.Method(typeof(RemoteVoicePlayerStateVolumePatch), "Prefix", (Type[])null, (Type[])null);
val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Log.LogInfo((object)"Successfully patched RemoteVoicePlayerState.Volume.");
}
else
{
Log.LogError((object)"Could not find Dissonance.RemoteVoicePlayerState.Volume property setter!");
}
MethodInfo methodInfo3 = AccessTools.Method(AccessTools.TypeByName("IngamePlayerListElement"), "Start", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
MethodInfo methodInfo4 = AccessTools.Method(typeof(IngamePlayerListElementStartPatch), "Postfix", (Type[])null, (Type[])null);
val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Log.LogInfo((object)"Successfully patched IngamePlayerListElement.Start.");
}
else
{
Log.LogError((object)"Could not find IngamePlayerListElement.Start method!");
}
Log.LogInfo((object)"BetterVolume patches initialized successfully.");
}
catch (Exception ex)
{
Log.LogError((object)("Failed to initialize BetterVolume: " + ex.ToString()));
}
}
}
public static class RemoteVoicePlayerStateVolumePatch
{
public static bool Prefix(object __instance, float value)
{
try
{
float num = Mathf.Clamp(value, 0f, 100f);
PropertyInfo propertyInfo = AccessTools.Property(__instance.GetType(), "PlaybackInternal");
if (propertyInfo != null)
{
object value2 = propertyInfo.GetValue(__instance);
if (value2 != null)
{
PropertyInfo propertyInfo2 = AccessTools.Property(value2.GetType(), "PlaybackVolume");
if (propertyInfo2 != null)
{
propertyInfo2.SetValue(value2, num);
}
}
}
PropertyInfo propertyInfo3 = AccessTools.Property(__instance.GetType(), "IsLocallyMuted");
PropertyInfo propertyInfo4 = AccessTools.Property(__instance.GetType(), "Name");
string text = ((propertyInfo4 != null) ? (propertyInfo4.GetValue(__instance) as string) : "Unknown");
if (propertyInfo3 != null)
{
bool flag = (bool)propertyInfo3.GetValue(__instance);
if (num <= 0.001f)
{
if (!flag)
{
propertyInfo3.SetValue(__instance, true);
BetterVolumePlugin.Log.LogInfo((object)("Player " + text + " was forced to MUTED state because volume is 0."));
}
}
else if (flag)
{
propertyInfo3.SetValue(__instance, false);
BetterVolumePlugin.Log.LogInfo((object)("Player " + text + " was UNMUTED because volume is above 0."));
}
}
}
catch (Exception ex)
{
BetterVolumePlugin.Log.LogError((object)("Error in RemoteVoicePlayerStateVolumePatch: " + ex.ToString()));
}
return false;
}
}
public static class IngamePlayerListElementStartPatch
{
public static void Postfix(MonoBehaviour __instance)
{
try
{
BetterVolumePlugin.Log.LogInfo((object)"IngamePlayerListElement.Start Postfix triggered dynamically.");
Component component = ((Component)__instance).GetComponent("SliderUGUI");
if ((Object)(object)component == (Object)null)
{
BetterVolumePlugin.Log.LogWarning((object)"SliderUGUI component not found on IngamePlayerListElement.");
return;
}
AccessTools.Property(((object)component).GetType(), "MinValue")?.SetValue(component, 0f);
AccessTools.Property(((object)component).GetType(), "MaxValue")?.SetValue(component, 5f);
AccessTools.Field(((object)component).GetType(), "StepSize")?.SetValue(component, 0.05f);
AccessTools.Field(((object)component).GetType(), "ValueFormat")?.SetValue(component, "{0:0%}");
FieldInfo fieldInfo = AccessTools.Field(((object)component).GetType(), "Slider");
if (fieldInfo != null)
{
object value = fieldInfo.GetValue(component);
if (value != null)
{
AccessTools.Property(value.GetType(), "minValue")?.SetValue(value, 0f);
AccessTools.Property(value.GetType(), "maxValue")?.SetValue(value, 5f);
}
}
BetterVolumePlugin.Log.LogInfo((object)"SliderUGUI values modified successfully via reflection.");
CreateInputFieldForSlider(component);
}
catch (Exception ex)
{
BetterVolumePlugin.Log.LogError((object)("Error in IngamePlayerListElementStartPatch: " + ex.ToString()));
}
}
private static void CreateInputFieldForSlider(Component sliderComponent)
{
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Expected O, but got Unknown
//IL_028d: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_02df: Unknown result type (might be due to invalid IL or missing references)
//IL_031e: Unknown result type (might be due to invalid IL or missing references)
//IL_0325: Expected O, but got Unknown
//IL_0365: Unknown result type (might be due to invalid IL or missing references)
//IL_036c: Expected O, but got Unknown
//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0467: Unknown result type (might be due to invalid IL or missing references)
//IL_0495: Unknown result type (might be due to invalid IL or missing references)
//IL_049a: Unknown result type (might be due to invalid IL or missing references)
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
try
{
num = 1;
object? obj = AccessTools.Field(((object)sliderComponent).GetType(), "ValueTf")?.GetValue(sliderComponent);
TextMeshProUGUI val = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
object? obj2 = AccessTools.Field(((object)sliderComponent).GetType(), "TextTf")?.GetValue(sliderComponent);
TextMeshProUGUI val2 = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null);
if ((Object)(object)val == (Object)null)
{
BetterVolumePlugin.Log.LogWarning((object)"ValueTf was null on SliderUGUI. Searching in children...");
TextMeshProUGUI[] componentsInChildren = sliderComponent.GetComponentsInChildren<TextMeshProUGUI>(true);
TextMeshProUGUI[] array = componentsInChildren;
foreach (TextMeshProUGUI val3 in array)
{
if ((Object)(object)val3 != (Object)(object)val2 && (((Object)val3).name.ToLower().Contains("value") || ((Object)val3).name.ToLower().Contains("percent") || ((Object)val3).name.ToLower().Contains("val")))
{
val = val3;
break;
}
}
if ((Object)(object)val == (Object)null && componentsInChildren.Length > 1)
{
TextMeshProUGUI[] array2 = componentsInChildren;
foreach (TextMeshProUGUI val4 in array2)
{
if ((Object)(object)val4 != (Object)(object)val2)
{
val = val4;
break;
}
}
}
}
if ((Object)(object)val == (Object)null)
{
BetterVolumePlugin.Log.LogError((object)"Could not find any suitable TextMeshProUGUI for volume percentage.");
return;
}
BetterVolumePlugin.Log.LogInfo((object)("Found percentage text component: " + ((Object)((Component)val).gameObject).name));
num = 2;
Color savedOriginalColor = ((Graphic)val).color;
((Component)val).gameObject.SetActive(false);
num = 3;
GameObject val5 = new GameObject("VolumeInputField", new Type[1] { typeof(RectTransform) });
val5.transform.SetParent(((TMP_Text)val).transform.parent, false);
num = 4;
RectTransform component = val5.GetComponent<RectTransform>();
RectTransform rectTransform = ((TMP_Text)val).rectTransform;
if ((Object)(object)rectTransform != (Object)null)
{
component.anchorMin = rectTransform.anchorMin;
component.anchorMax = rectTransform.anchorMax;
component.anchoredPosition = rectTransform.anchoredPosition;
}
component.sizeDelta = new Vector2(60f, 30f);
num = 5;
Sprite roundedSprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/InputFieldBackground.psd") ?? Resources.GetBuiltinResource<Sprite>("UI/Skin/UISprite.psd");
Image bg = val5.AddComponent<Image>();
((Graphic)bg).color = new Color(0f, 0f, 0f, 0f);
bg.sprite = null;
((Graphic)bg).raycastTarget = true;
num = 6;
GameObject val6 = new GameObject("Text Area", new Type[1] { typeof(RectTransform) });
val6.transform.SetParent(val5.transform, false);
RectTransform component2 = val6.GetComponent<RectTransform>();
component2.anchorsToFillParent();
num = 7;
GameObject val7 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
val7.transform.SetParent(val6.transform, false);
RectTransform component3 = val7.GetComponent<RectTransform>();
component3.anchorsToFillParent();
num = 8;
TextMeshProUGUI textComponent = val7.AddComponent<TextMeshProUGUI>();
if ((Object)(object)((TMP_Text)val).font != (Object)null)
{
((TMP_Text)textComponent).font = ((TMP_Text)val).font;
}
((TMP_Text)textComponent).fontSize = ((TMP_Text)val).fontSize;
((Graphic)textComponent).color = savedOriginalColor;
((TMP_Text)textComponent).alignment = ((TMP_Text)val).alignment;
((Graphic)textComponent).raycastTarget = false;
num = 9;
TMP_InputField inputField = val5.AddComponent<TMP_InputField>();
inputField.textViewport = component2;
inputField.textComponent = (TMP_Text)(object)textComponent;
inputField.contentType = (ContentType)2;
inputField.characterLimit = 5;
((Selectable)inputField).interactable = true;
inputField.caretColor = Color.black;
inputField.customCaretColor = true;
inputField.caretWidth = 2;
num = 10;
Navigation navigation = ((Selectable)inputField).navigation;
((Navigation)(ref navigation)).mode = (Mode)0;
((Selectable)inputField).navigation = navigation;
val5.transform.SetAsLastSibling();
num = 11;
PropertyInfo valueProp = AccessTools.Property(((object)sliderComponent).GetType(), "Value");
float num2 = 1f;
if (valueProp != null && valueProp.GetValue(sliderComponent) is float num3)
{
num2 = num3;
}
inputField.text = Mathf.RoundToInt(num2 * 100f) + "%";
num = 12;
((UnityEvent<string>)(object)inputField.onSelect).AddListener((UnityAction<string>)delegate(string text)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
((Graphic)bg).color = Color.white;
bg.sprite = roundedSprite;
bg.type = (Type)1;
((Graphic)textComponent).color = Color.black;
if (text.EndsWith("%"))
{
inputField.text = text.Replace("%", "").Trim();
}
});
((UnityEvent<string>)(object)inputField.onEndEdit).AddListener((UnityAction<string>)delegate(string text)
{
//IL_001b: 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)
((Graphic)bg).color = new Color(0f, 0f, 0f, 0f);
bg.sprite = null;
((Graphic)textComponent).color = savedOriginalColor;
string s = text.Replace("%", "").Trim();
if (float.TryParse(s, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
{
float num4 = result / 100f;
float num5 = 0f;
PropertyInfo propertyInfo = AccessTools.Property(((object)sliderComponent).GetType(), "MinValue");
if (propertyInfo != null && propertyInfo.GetValue(sliderComponent) is float num6)
{
num5 = num6;
}
float num7 = Mathf.Max(5f, num4);
AccessTools.Property(((object)sliderComponent).GetType(), "MaxValue")?.SetValue(sliderComponent, num7);
FieldInfo fieldInfo2 = AccessTools.Field(((object)sliderComponent).GetType(), "Slider");
if (fieldInfo2 != null)
{
object value2 = fieldInfo2.GetValue(sliderComponent);
if (value2 != null)
{
AccessTools.Property(value2.GetType(), "maxValue")?.SetValue(value2, num7);
}
}
num4 = Mathf.Clamp(num4, num5, num7);
valueProp?.SetValue(sliderComponent, num4);
inputField.text = Mathf.RoundToInt(num4 * 100f) + "%";
}
else
{
float num8 = 1f;
if (valueProp != null && valueProp.GetValue(sliderComponent) is float num9)
{
num8 = num9;
}
inputField.text = Mathf.RoundToInt(num8 * 100f) + "%";
}
});
num = 13;
FieldInfo fieldInfo = AccessTools.Field(((object)sliderComponent).GetType(), "Slider");
if (fieldInfo != null)
{
object value = fieldInfo.GetValue(sliderComponent);
Slider unitySlider = (Slider)((value is Slider) ? value : null);
if (unitySlider != null)
{
((UnityEvent<float>)(object)unitySlider.onValueChanged).AddListener((UnityAction<float>)delegate(float num6)
{
if (!inputField.isFocused)
{
float num4 = 5f;
PropertyInfo propertyInfo = AccessTools.Property(((object)sliderComponent).GetType(), "MaxValue");
if (propertyInfo != null && propertyInfo.GetValue(sliderComponent) is float num5)
{
num4 = num5;
}
if (num6 <= 5f && num4 > 5f)
{
AccessTools.Property(((object)sliderComponent).GetType(), "MaxValue")?.SetValue(sliderComponent, 5f);
AccessTools.Property(((object)unitySlider).GetType(), "maxValue")?.SetValue(unitySlider, 5f);
}
inputField.text = Mathf.RoundToInt(num6 * 100f) + "%";
}
});
}
}
BetterVolumePlugin.Log.LogInfo((object)"Volume InputField successfully created and attached via reflection.");
}
catch (Exception ex)
{
BetterVolumePlugin.Log.LogError((object)($"Error in CreateInputFieldForSlider at step {num}: " + ex.ToString()));
}
}
}
public static class RectTransformExtensions
{
public static void anchorsToFillParent(this RectTransform t)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: 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)
t.anchorMin = Vector2.zero;
t.anchorMax = Vector2.one;
t.sizeDelta = Vector2.zero;
t.anchoredPosition = Vector2.zero;
}
}
}