Decompiled source of PlayerVolumeSaver v1.2.0

PlayerVolumeSaver.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerVolumeSaver")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("PlayerVolumeSaver")]
[assembly: AssemblyTitle("PlayerVolumeSaver")]
[assembly: AssemblyVersion("1.2.0.0")]
[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 PlayerVolumeSaver
{
	[BepInPlugin("purtzel_hd.playervolumesaver", "PlayerVolumeSaver", "1.2.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0051: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			VolumeStore.Load();
			try
			{
				Harmony val = new Harmony("purtzel_hd.playervolumesaver");
				Type type = AccessTools.TypeByName("GameManager");
				val.Patch((MethodBase)AccessTools.Method(type, "PlayerMicrophoneSettingGet", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "GetPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				val.Patch((MethodBase)AccessTools.Method(type, "PlayerMicrophoneSettingSet", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "SetPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Patching failed: {arg}");
			}
			GameObject val2 = new GameObject("PlayerVolumeSaver");
			Object.DontDestroyOnLoad((Object)val2);
			((Object)val2).hideFlags = (HideFlags)61;
			val2.AddComponent<VolumeApplier>();
			Log.LogInfo((object)$"PlayerVolumeSaver loaded, {VolumeStore.Volumes.Count} player(s) saved.");
		}
	}
	internal static class VolumeStore
	{
		public static readonly Dictionary<string, float> Volumes = new Dictionary<string, float>();

		public static bool Dirty;

		public static float DirtyTime;

		private const float DefaultGain = 0.5f;

		private static string FilePath => Path.Combine(Paths.ConfigPath, "purtzel_hd.playervolumesaver.txt");

		private static string OldFilePath => Path.Combine(Paths.ConfigPath, "PlayerVolumeSaver_Lautstaerken.txt");

		public static void Load()
		{
			Volumes.Clear();
			try
			{
				if (!File.Exists(FilePath) && File.Exists(OldFilePath))
				{
					File.Move(OldFilePath, FilePath);
					Plugin.Log.LogInfo((object)"Moved saved volumes to purtzel_hd.playervolumesaver.txt");
				}
				if (!File.Exists(FilePath))
				{
					return;
				}
				string[] array = File.ReadAllLines(FilePath, Encoding.UTF8);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length == 0 || text.StartsWith("#"))
					{
						continue;
					}
					string[] array2 = text.Split('\t');
					if (array2.Length < 2)
					{
						continue;
					}
					string key = array2[0].Trim();
					if (!float.TryParse(array2[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
					{
						continue;
					}
					if (IsDefault(result))
					{
						Dirty = true;
						DirtyTime = 0f;
						continue;
					}
					Volumes[key] = result;
					if (array2.Length > 2)
					{
						Dirty = true;
						DirtyTime = 0f;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Loading failed: {arg}");
			}
		}

		private static bool IsDefault(float gain)
		{
			return Mathf.Abs(gain - 0.5f) < 0.001f;
		}

		public static void Set(string id, float gain)
		{
			if (string.IsNullOrEmpty(id))
			{
				return;
			}
			float value;
			if (IsDefault(gain))
			{
				if (Volumes.Remove(id))
				{
					Dirty = true;
					DirtyTime = Time.realtimeSinceStartup;
					Plugin.Log.LogInfo((object)("Volume for " + id + " is back to 100 %, entry removed."));
				}
			}
			else if (!Volumes.TryGetValue(id, out value) || !Mathf.Approximately(value, gain))
			{
				Volumes[id] = gain;
				Dirty = true;
				DirtyTime = Time.realtimeSinceStartup;
			}
		}

		public static void Save()
		{
			if (!Dirty)
			{
				return;
			}
			Dirty = false;
			try
			{
				List<string> list = new List<string> { "# PlayerVolumeSaver - SteamID<TAB>Volume (0.5 = 100 %)" };
				foreach (KeyValuePair<string, float> item in Volumes.OrderBy((KeyValuePair<string, float> k) => k.Key))
				{
					list.Add(item.Key + "\t" + item.Value.ToString(CultureInfo.InvariantCulture));
				}
				File.WriteAllLines(FilePath, list, Encoding.UTF8);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Saving failed: {arg}");
			}
		}
	}
	internal static class Patches
	{
		public static bool GetPrefix(string __0, ref float __result)
		{
			if (string.IsNullOrEmpty(__0))
			{
				return true;
			}
			if (!VolumeStore.Volumes.TryGetValue(__0, out var value))
			{
				return true;
			}
			__result = value;
			return false;
		}

		public static void SetPostfix(string __0, float __1)
		{
			VolumeStore.Set(__0, __1);
		}
	}
	internal class VolumeApplier : MonoBehaviour
	{
		private const BindingFlags All = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private Type _vcType;

		private FieldInfo _fGain;

		private FieldInfo _fPhoton;

		private FieldInfo _fAvatar;

		private FieldInfo _fSteamId;

		private bool _ready;

		private float _next;

		private readonly HashSet<int> _done = new HashSet<int>();

		private void Init()
		{
			_ready = true;
			_vcType = AccessTools.TypeByName("PlayerVoiceChat");
			if (_vcType == null)
			{
				Plugin.Log.LogError((object)"PlayerVoiceChat not found.");
				return;
			}
			_fGain = _vcType.GetField("voiceGain", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_fPhoton = _vcType.GetField("photonView", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_fAvatar = _vcType.GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			_fSteamId = AccessTools.TypeByName("PlayerAvatar")?.GetField("steamID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}

		private void Update()
		{
			if (VolumeStore.Dirty && Time.realtimeSinceStartup - VolumeStore.DirtyTime > 2f)
			{
				VolumeStore.Save();
			}
			if (Time.realtimeSinceStartup < _next)
			{
				return;
			}
			_next = Time.realtimeSinceStartup + 1f;
			try
			{
				if (!_ready)
				{
					Init();
				}
				if (_vcType == null || _fGain == null)
				{
					return;
				}
				Object[] array = Object.FindObjectsByType(_vcType, (FindObjectsSortMode)0);
				foreach (Object obj in array)
				{
					Component val = (Component)(object)((obj is Component) ? obj : null);
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					int instanceID = ((Object)val).GetInstanceID();
					if (_done.Contains(instanceID))
					{
						continue;
					}
					object? obj2 = _fPhoton?.GetValue(val);
					PhotonView val2 = (PhotonView)((obj2 is PhotonView) ? obj2 : null);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					if (val2.IsMine)
					{
						_done.Add(instanceID);
						continue;
					}
					object? obj3 = _fAvatar?.GetValue(val);
					Object val3 = (Object)((obj3 is Object) ? obj3 : null);
					if (val3 == (Object)null)
					{
						continue;
					}
					string text = _fSteamId?.GetValue(val3) as string;
					if (!string.IsNullOrEmpty(text))
					{
						if (VolumeStore.Volumes.TryGetValue(text, out var value))
						{
							_fGain.SetValue(val, value);
							Plugin.Log.LogInfo((object)("Volume for " + text + " set to " + value.ToString(CultureInfo.InvariantCulture)));
						}
						_done.Add(instanceID);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		private void OnApplicationQuit()
		{
			VolumeStore.Save();
		}

		private void OnDestroy()
		{
			VolumeStore.Save();
		}
	}
}