Decompiled source of AC6SoundFix v1.0.0

plugins/AC6SoundFix.dll

Decompiled 19 hours ago
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace AC6SoundFix;

[BepInPlugin("evreborns.ac6soundfix", "AC6SoundFix", "1.0.0")]
public class AC6SoundFixPlugin : BaseUnityPlugin
{
	private class Loop
	{
		public GameObject go;

		public string play;

		public uint id;
	}

	private static ConfigEntry<string> loopPairs;

	private static readonly Dictionary<string, string> playToStop = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

	private static readonly HashSet<string> stopEvents = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	private static readonly List<Loop> loops = new List<Loop>();

	private static MethodInfo miStopPlayingID;

	private static ManualLogSource log;

	private static int stoppedCount;

	private void Awake()
	{
		log = ((BaseUnityPlugin)this).Logger;
		loopPairs = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LoopEvents", "Play_AC6BoostSoundsLoop=Stop_AC6BoostSoundsLoop", "Pasangan event loop Wwise: Play=Stop, pisahkan dengan koma.");
		string[] array = loopPairs.Value.Split(',');
		foreach (string text in array)
		{
			string[] array2 = text.Split('=');
			if (array2.Length == 2)
			{
				string text2 = array2[0].Trim();
				string text3 = array2[1].Trim();
				if (text2.Length != 0 && text3.Length != 0)
				{
					playToStop[text2] = text3;
					stopEvents.Add(text3);
				}
			}
		}
		SceneManager.activeSceneChanged += delegate
		{
			StopAll("pindah stage");
		};
	}

	private void Start()
	{
		try
		{
			Setup();
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Gagal setup: " + ex));
		}
	}

	private void Setup()
	{
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Expected O, but got Unknown
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected O, but got Unknown
		Type type = FindType("AkSoundEngine");
		if (type != null)
		{
			miStopPlayingID = type.GetMethod("StopPlayingID", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(uint) }, null);
		}
		if (miStopPlayingID == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"AkSoundEngine.StopPlayingID tidak ditemukan.");
			return;
		}
		Type type2 = FindType("RoR2.Util");
		if (type2 == null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"RoR2.Util tidak ditemukan.");
			return;
		}
		Harmony val = new Harmony("evreborns.ac6soundfix");
		HarmonyMethod val2 = new HarmonyMethod(typeof(AC6SoundFixPlugin).GetMethod("PlaySoundPrefix", BindingFlags.Static | BindingFlags.NonPublic));
		HarmonyMethod val3 = new HarmonyMethod(typeof(AC6SoundFixPlugin).GetMethod("PlaySoundPostfix", BindingFlags.Static | BindingFlags.NonPublic));
		int num = 0;
		MethodInfo[] methods = type2.GetMethods(BindingFlags.Static | BindingFlags.Public);
		foreach (MethodInfo methodInfo in methods)
		{
			if (!(methodInfo.Name != "PlaySound") && !(methodInfo.ReturnType != typeof(uint)) && !methodInfo.IsGenericMethod)
			{
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length >= 2 && !(parameters[0].ParameterType != typeof(string)) && !(parameters[1].ParameterType != typeof(GameObject)))
				{
					val.Patch((MethodBase)methodInfo, val2, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("AC6SoundFix aktif (" + num + " fungsi PlaySound dipantau, " + playToStop.Count + " loop)."));
	}

	private static Type FindType(string fullName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			Type type = null;
			try
			{
				type = assembly.GetType(fullName, throwOnError: false);
			}
			catch
			{
			}
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}

	private static void StopId(uint id)
	{
		if (id == 0 || miStopPlayingID == null)
		{
			return;
		}
		try
		{
			miStopPlayingID.Invoke(null, new object[1] { id });
			stoppedCount++;
		}
		catch
		{
		}
	}

	private static void StopAll(string reason)
	{
		int num = 0;
		for (int num2 = loops.Count - 1; num2 >= 0; num2--)
		{
			StopId(loops[num2].id);
			num++;
		}
		loops.Clear();
		if (num > 0 && log != null)
		{
			log.LogInfo((object)("Menghentikan " + num + " loop (" + reason + ")."));
		}
	}

	private static void PlaySoundPrefix(object[] __args)
	{
		try
		{
			if (!(__args[0] is string text))
			{
				return;
			}
			object obj = __args[1];
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if (playToStop.ContainsKey(text))
			{
				for (int num = loops.Count - 1; num >= 0; num--)
				{
					if ((Object)(object)loops[num].go == (Object)(object)val && string.Equals(loops[num].play, text, StringComparison.OrdinalIgnoreCase))
					{
						StopId(loops[num].id);
						loops.RemoveAt(num);
					}
				}
			}
			else
			{
				if (!stopEvents.Contains(text))
				{
					return;
				}
				for (int num2 = loops.Count - 1; num2 >= 0; num2--)
				{
					if ((Object)(object)loops[num2].go == (Object)(object)val && string.Equals(playToStop[loops[num2].play], text, StringComparison.OrdinalIgnoreCase))
					{
						StopId(loops[num2].id);
						loops.RemoveAt(num2);
					}
				}
			}
		}
		catch
		{
		}
	}

	private static void PlaySoundPostfix(object[] __args, uint __result)
	{
		try
		{
			if (__args[0] is string text && __result != 0 && playToStop.ContainsKey(text))
			{
				loops.Add(new Loop
				{
					go = (GameObject)/*isinst with value type is only supported in some contexts*/,
					play = text,
					id = __result
				});
			}
		}
		catch
		{
		}
	}

	private void Update()
	{
		for (int num = loops.Count - 1; num >= 0; num--)
		{
			GameObject go = loops[num].go;
			if ((Object)(object)go == (Object)null || !go.activeInHierarchy)
			{
				StopId(loops[num].id);
				loops.RemoveAt(num);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Loop yatim dihentikan (objek sudah hilang).");
			}
		}
	}
}