Decompiled source of Agalar Boombox v1.3.0

plugins/Lethalmod2.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Lethalmod2")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Lethalmod2")]
[assembly: AssemblyTitle("Lethalmod2")]
[assembly: AssemblyVersion("1.0.0.0")]
public static class BoomboxStateManager
{
	private static Dictionary<BoomboxItem, float> playbackPositions = new Dictionary<BoomboxItem, float>();

	public static void SavePlaybackPosition(BoomboxItem boombox, float position)
	{
		if (!((Object)(object)boombox == (Object)null))
		{
			if (playbackPositions.ContainsKey(boombox))
			{
				playbackPositions[boombox] = position;
			}
			else
			{
				playbackPositions.Add(boombox, position);
			}
		}
	}

	public static float GetPlaybackPosition(BoomboxItem boombox)
	{
		if ((Object)(object)boombox == (Object)null)
		{
			return 0f;
		}
		float value;
		return playbackPositions.TryGetValue(boombox, out value) ? value : 0f;
	}
}
namespace BoomboxMod;

public class BoomboxComponent : MonoBehaviour
{
	[HarmonyPatch(typeof(BoomboxItem))]
	private class BoomboxPatch
	{
		[HarmonyPatch("ItemActivate")]
		[HarmonyPrefix]
		private static bool ItemActivatePatch(BoomboxItem __instance, bool used, bool buttonDown)
		{
			if (!buttonDown)
			{
				return true;
			}
			AudioSource boomboxAudio = __instance.boomboxAudio;
			if ((Object)(object)boomboxAudio == (Object)null)
			{
				logger.LogError((object)"BoomboxItem has no AudioSource!");
				return true;
			}
			if (boomboxAudio.isPlaying)
			{
				boomboxAudio.Pause();
				BoomboxMod.isPaused = true;
			}
			else if ((Object)(object)boomboxAudio.clip != (Object)null && BoomboxMod.isPaused)
			{
				boomboxAudio.UnPause();
				BoomboxMod.isPaused = false;
			}
			else
			{
				((MonoBehaviour)instance).StartCoroutine(PlayNextTrack(boomboxAudio));
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(PlayerControllerB), "DiscardHeldObject")]
	private class BoomboxDropPatch
	{
		[HarmonyPrefix]
		private static void Prefix(PlayerControllerB __instance)
		{
			GrabbableObject val = __instance.ItemSlots[__instance.currentItemSlot];
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			BoomboxItem val2 = (BoomboxItem)(object)((val is BoomboxItem) ? val : null);
			if (val2 != null)
			{
				AudioSource boomboxAudio = val2.boomboxAudio;
				if ((Object)(object)boomboxAudio != (Object)null && !boomboxAudio.isPlaying)
				{
					boomboxAudio.Stop();
					BoomboxMod.isPaused = true;
				}
			}
		}
	}

	private static BoomboxComponent instance;

	private static string[] musicFiles;

	private static int currentTrackIndex;

	private static bool isChangingTrack;

	private static Coroutine activeTrackRoutine;

	private static ManualLogSource logger;

	private InputAction nextTrackAction;

	private static string musicDirectory;

	private static AudioClip lastClip;

	private static bool wasSkipped;

	public void Initialize(ManualLogSource logSource)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Expected O, but got Unknown
		instance = this;
		logger = logSource;
		logger.LogInfo((object)"BoomboxComponent initialized.");
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		musicDirectory = Path.Combine(directoryName, "BoomboxMusic");
		if (!Directory.Exists(musicDirectory))
		{
			Directory.CreateDirectory(musicDirectory);
		}
		musicFiles = Directory.GetFiles(musicDirectory, "*.mp3");
		nextTrackAction = new InputAction("NextTrack", (InputActionType)0, "<Keyboard>/rightArrow", (string)null, (string)null, (string)null);
		nextTrackAction.performed += delegate
		{
			SkipTrack();
		};
		nextTrackAction.Enable();
		logger.LogInfo((object)"Input action for next track set up.");
	}

	private void SkipTrack()
	{
		BoomboxItem[] array = Object.FindObjectsOfType<BoomboxItem>();
		if (array.Length == 0)
		{
			logger.LogWarning((object)"❌ No boombox found in the scene.");
			return;
		}
		PlayerControllerB[] array2 = Object.FindObjectsOfType<PlayerControllerB>();
		BoomboxItem[] array3 = array;
		foreach (BoomboxItem val in array3)
		{
			GrabbableObject componentInParent = ((Component)val).GetComponentInParent<GrabbableObject>();
			if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.playerHeldBy == (Object)null)
			{
				logger.LogWarning((object)("⚠ Boombox " + ((Object)val).name + " is not being held by any player."));
				continue;
			}
			PlayerControllerB[] array4 = array2;
			foreach (PlayerControllerB val2 in array4)
			{
				if (!((Object)(object)componentInParent.playerHeldBy == (Object)(object)val2))
				{
					continue;
				}
				AudioSource boomboxAudio = val.boomboxAudio;
				if ((Object)(object)boomboxAudio == (Object)null)
				{
					logger.LogError((object)"Boombox has no AudioSource!");
					return;
				}
				wasSkipped = true;
				if (activeTrackRoutine != null)
				{
					((MonoBehaviour)instance).StopCoroutine(activeTrackRoutine);
					activeTrackRoutine = null;
				}
				activeTrackRoutine = ((MonoBehaviour)instance).StartCoroutine(PlayNextTrack(boomboxAudio));
				return;
			}
		}
		logger.LogWarning((object)"❌ No player is currently holding a boombox. Skipping track is not allowed.");
	}

	private BoomboxItem FindActiveBoombox()
	{
		BoomboxItem[] array = Object.FindObjectsOfType<BoomboxItem>();
		BoomboxItem[] array2 = array;
		foreach (BoomboxItem val in array2)
		{
			if ((Object)(object)val != (Object)null && (Object)(object)val.boomboxAudio != (Object)null && ((Component)val.boomboxAudio).gameObject.activeInHierarchy)
			{
				return val;
			}
		}
		return null;
	}

	private static IEnumerator PlayNextTrack(AudioSource audioSource)
	{
		if (musicFiles.Length != 0 && !((Object)(object)audioSource == (Object)null))
		{
			if (audioSource.isPlaying)
			{
				audioSource.Stop();
			}
			isChangingTrack = true;
			if (activeTrackRoutine != null)
			{
				((MonoBehaviour)instance).StopCoroutine(activeTrackRoutine);
				activeTrackRoutine = null;
			}
			currentTrackIndex = (currentTrackIndex + 1) % musicFiles.Length;
			yield return PlayTrack(audioSource);
			isChangingTrack = false;
		}
	}

	private static IEnumerator PlayTrack(AudioSource audioSource)
	{
		if (activeTrackRoutine != null)
		{
			((MonoBehaviour)instance).StopCoroutine(activeTrackRoutine);
		}
		string filePath = "file://" + musicFiles[currentTrackIndex];
		UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(filePath, (AudioType)13);
		try
		{
			yield return www.SendWebRequest();
			if ((int)www.result != 1)
			{
				logger.LogError((object)("Load failed: " + www.error));
				yield break;
			}
			AudioClip clip = DownloadHandlerAudioClip.GetContent(www);
			if ((Object)(object)clip == (Object)null)
			{
				logger.LogError((object)"Loaded audio clip is null!");
				yield break;
			}
			audioSource.clip = clip;
			audioSource.Play();
			lastClip = clip;
			BoomboxMod.isPaused = false;
			activeTrackRoutine = null;
			yield return (object)new WaitWhile((Func<bool>)(() => audioSource.isPlaying));
			if (!BoomboxMod.isPaused && !wasSkipped)
			{
				audioSource.Stop();
				yield return ((MonoBehaviour)instance).StartCoroutine(PlayNextTrack(audioSource));
			}
			wasSkipped = false;
		}
		finally
		{
			((IDisposable)www)?.Dispose();
		}
	}
}
[BepInPlugin("com.yourname.boomboxmod", "Boombox Mod", "1.0.3")]
public class BoomboxMod : BaseUnityPlugin
{
	private const string ModGUID = "com.yourname.boomboxmod";

	private const string ModName = "Boombox Mod";

	private const string ModVersion = "1.0.3";

	public readonly Harmony harmony = new Harmony("com.yourname.boomboxmod");

	public static ManualLogSource mls;

	public static bool isPaused;

	private static BoomboxComponent boomboxComponent;

	private void Awake()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		mls = ((BaseUnityPlugin)this).Logger;
		mls.LogInfo((object)"Boombox Mod loaded. Patching and initializing.");
		harmony.PatchAll(Assembly.GetExecutingAssembly());
		mls.LogInfo((object)"BoomboxStateManager initialized.");
		BoomboxStateManager.GetPlaybackPosition(null);
		GameObject val = new GameObject("BoomboxManager");
		Object.DontDestroyOnLoad((Object)(object)val);
		((Object)val).hideFlags = (HideFlags)61;
		boomboxComponent = val.AddComponent<BoomboxComponent>();
		boomboxComponent.Initialize(mls);
	}
}