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);
}
}