Decompiled source of ThankYou v1.0.3

ThankYou.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;

[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("ThankYou")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ThankYou")]
[assembly: AssemblyTitle("ThankYou")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 ThankYou
{
	public class CrouchSync : MonoBehaviourPun, IOnEventCallback
	{
		public void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		public void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		public void OnEvent(EventData photonEvent)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (photonEvent.Code == Plugin.ModEventCodes.CrouchSoundEvent)
			{
				object customData = photonEvent.CustomData;
				if (customData is Vector3)
				{
					Vector3 position = (Vector3)customData;
					Plugin.PlayCrouchSound(position);
				}
			}
		}
	}
	public class ModConfig
	{
		public readonly ConfigEntry<float> SFXVolume;

		public readonly ConfigEntry<float> SFXRange;

		public readonly ConfigEntry<float> MinRepeatGap;

		public ModConfig(ConfigFile cfg)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			cfg.SaveOnConfigSet = false;
			SFXVolume = cfg.Bind<float>("General", "Crouch Volume", 0.67f, new ConfigDescription("Volume of the crouch sound.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			SFXRange = cfg.Bind<float>("General", "Crouch Sound Range", 40f, new ConfigDescription("Maximum distance the crouch sound can be heard from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			MinRepeatGap = cfg.Bind<float>("General", "Min Repeat Gap", 0.33f, new ConfigDescription("Minimum seconds before the same character can trigger the sound again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear();
		}
	}
	[BepInPlugin("ThankYou", "ThankYou", "1.0.3")]
	public class Plugin : BaseUnityPlugin
	{
		internal static class ModEventCodes
		{
			internal static readonly byte CrouchSoundEvent = 77;
		}

		public const string Id = "ThankYou";

		internal static SFX_Instance ThankYou;

		internal static SFX_Instance YwSound;

		internal static CrouchSync syncInstance;

		private readonly Harmony harmony = new Harmony("ThankYou");

		private readonly Dictionary<int, bool> lastCrouchState = new Dictionary<int, bool>();

		private readonly Dictionary<int, float> lastPlayTime = new Dictionary<int, float>();

		private const int SFXLimit = 10;

		internal static ManualLogSource Log { get; private set; }

		internal static Plugin Instance { get; private set; }

		internal static ModConfig BoundConfig { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new ModConfig(((BaseUnityPlugin)this).Config);
			GetSyncInstance();
			LoadThankYou();
			Log.LogInfo((object)"ThankYou loaded.");
		}

		private void Update()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ThankYou == (Object)null || ThankYou.clips == null || ThankYou.clips.Length == 0)
			{
				return;
			}
			Object[] array;
			try
			{
				array = Object.FindObjectsByType(typeof(Character), (FindObjectsSortMode)0);
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to enumerate characters: {arg}");
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			Object[] array2 = array;
			foreach (Object obj in array2)
			{
				Character val = (Character)(object)((obj is Character) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				hashSet.Add(instanceID);
				if (!val.IsLocal)
				{
					continue;
				}
				bool isCrouching;
				Vector3 center;
				try
				{
					isCrouching = val.data.isCrouching;
					center = val.Center;
				}
				catch
				{
					continue;
				}
				if (!(lastCrouchState.TryGetValue(instanceID, out var value) && value) && isCrouching)
				{
					float time = Time.time;
					float value2;
					float num = (lastPlayTime.TryGetValue(instanceID, out value2) ? value2 : (-999f));
					if (time - num >= BoundConfig.MinRepeatGap.Value)
					{
						RaiseCrouchSoundEvent(center);
						lastPlayTime[instanceID] = time;
					}
				}
				lastCrouchState[instanceID] = isCrouching;
			}
			CleanupMissingCharacters(hashSet);
		}

		private void CleanupMissingCharacters(HashSet<int> seenIds)
		{
			List<int> list = null;
			foreach (int key in lastCrouchState.Keys)
			{
				if (!seenIds.Contains(key))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				lastCrouchState.Remove(item);
				lastPlayTime.Remove(item);
			}
		}

		internal static void PlayCrouchSound(Vector3 position)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			SFX_Instance val;
			if ((Object)(object)YwSound != (Object)null && Random.Range(0, 100) == 0)
			{
				val = YwSound;
			}
			else
			{
				if (!((Object)(object)ThankYou != (Object)null))
				{
					return;
				}
				val = ThankYou;
			}
			val.settings.volume = BoundConfig.SFXVolume.Value;
			val.settings.range = BoundConfig.SFXRange.Value;
			val.Play(position);
		}

		private void RaiseCrouchSoundEvent(Vector3 position)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (PhotonNetwork.OfflineMode)
			{
				PlayCrouchSound(position);
				return;
			}
			PhotonNetwork.RaiseEvent(ModEventCodes.CrouchSoundEvent, (object)position, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
		}

		internal static CrouchSync GetSyncInstance()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)syncInstance != (Object)null)
			{
				return syncInstance;
			}
			syncInstance = Object.FindFirstObjectByType<CrouchSync>();
			if ((Object)(object)syncInstance == (Object)null)
			{
				syncInstance = new GameObject("CrouchSync Listener Instance").AddComponent<CrouchSync>();
				Object.DontDestroyOnLoad((Object)(object)((Component)syncInstance).gameObject);
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"Created CrouchSync listener instance.");
				}
			}
			return syncInstance;
		}

		private void LoadThankYou()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00b3: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string[] files = Directory.GetFiles(directoryName, "*.wav");
			string text = files.FirstOrDefault((string f) => Path.GetFileNameWithoutExtension(f).Equals("yw", StringComparison.OrdinalIgnoreCase));
			if (text != null)
			{
				try
				{
					AudioClip val = LoadAudioClip(text);
					if ((Object)(object)val != (Object)null)
					{
						YwSound = ScriptableObject.CreateInstance<SFX_Instance>();
						YwSound.clips = (AudioClip[])(object)new AudioClip[1] { val };
						YwSound.settings = new SFX_Settings
						{
							volume = BoundConfig.SFXVolume.Value,
							range = BoundConfig.SFXRange.Value
						};
						Log.LogInfo((object)"Loaded yw sound.");
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Failed to load yw sound: " + ex.Message));
				}
			}
			List<string> list = files.Where((string f) => !Path.GetFileNameWithoutExtension(f).Equals("yw", StringComparison.OrdinalIgnoreCase)).Take(10).ToList();
			if (list.Count == 0)
			{
				Log.LogWarning((object)("No .wav files found in " + directoryName));
				return;
			}
			List<AudioClip> list2 = new List<AudioClip>();
			foreach (string item in list)
			{
				try
				{
					AudioClip val2 = LoadAudioClip(item);
					if ((Object)(object)val2 != (Object)null)
					{
						list2.Add(val2);
					}
				}
				catch (Exception ex2)
				{
					Log.LogError((object)("Failed to load sound file " + item + ": " + ex2.Message));
				}
			}
			if (list2.Count == 0)
			{
				Log.LogError((object)"No crouch audio clips were loaded.");
				return;
			}
			ThankYou = ScriptableObject.CreateInstance<SFX_Instance>();
			ThankYou.clips = list2.ToArray();
			ThankYou.settings = new SFX_Settings
			{
				volume = BoundConfig.SFXVolume.Value,
				range = BoundConfig.SFXRange.Value
			};
			Log.LogInfo((object)$"Created crouch SFX with {list2.Count} clip(s).");
		}

		private AudioClip LoadAudioClip(string filePath)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(filePath).AbsoluteUri, (AudioType)20);
			try
			{
				UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
				while (!((AsyncOperation)val).isDone)
				{
				}
				if ((int)audioClip.result == 2 || (int)audioClip.result == 3)
				{
					Log.LogError((object)("Error loading " + filePath + ": " + audioClip.error));
					return null;
				}
				return DownloadHandlerAudioClip.GetContent(audioClip);
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
		}
	}
}