using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using JBLSpeaker.Valuables;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib;
using REPOLib.Modules;
using UnityEngine;
[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Brian Hepp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+06647606a89ba302cb63e404e399123082d3f024")]
[assembly: AssemblyProduct("JBLSpeaker")]
[assembly: AssemblyTitle("JBLSpeaker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace JBLSpeaker
{
[BepInPlugin("drb.jblspeaker", "JBLSpeaker", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugins : BaseUnityPlugin
{
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"JBLSpeaker Plugin Awake");
string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
string text = Path.Combine(directoryName, "jblspeaker.bundle");
((BaseUnityPlugin)this).Logger.LogInfo((object)("BundlePath = " + text.ToString()));
BundleLoader.LoadBundle(text, (Action<AssetBundle>)delegate(AssetBundle assetBundle)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"BundleLoader callback fired");
if ((Object)(object)assetBundle == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"AssetBundle is NULL");
}
else
{
GameObject val = assetBundle.LoadAsset<GameObject>("jblspeaker");
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"JBLSpeaker prefab NOT found in bundle");
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Prefab found: " + ((Object)val).name));
JBLSpeaker.Valuables.JBLSpeaker jBLSpeaker = default(JBLSpeaker.Valuables.JBLSpeaker);
if (!val.TryGetComponent<JBLSpeaker.Valuables.JBLSpeaker>(ref jBLSpeaker))
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"JBLSpeaker component NOT found on prefab — adding");
jBLSpeaker = val.AddComponent<JBLSpeaker.Valuables.JBLSpeaker>();
jBLSpeaker.tracks = new List<AudioSource>(val.GetComponentsInChildren<AudioSource>(true));
jBLSpeaker.particles = new List<ParticleSystem>(val.GetComponentsInChildren<ParticleSystem>(true));
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"JBLSpeaker component already exists on prefab");
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Registering JBLSpeaker valuable");
Valuables.RegisterValuable(val);
}
}
}, false);
}
}
}
namespace JBLSpeaker.Valuables
{
public class JBLSpeaker : MonoBehaviourPun
{
[Serializable]
public class TrackLyrics
{
public AudioSource track;
public List<AudioClip> lyrics;
}
private PhysGrabObject grab;
private bool wasGrabbed;
public List<AudioSource> tracks;
[Header("Audio")]
public List<ParticleSystem> particles;
private int musicIndex = -1;
[Header("Behavior")]
public float slamVelocityThreshold = 6f;
public int maxSkipsBeforeOff = 6;
private int skipCount;
private bool isActive;
[Header("Drop Audio")]
public float droppedVolume = 0.25f;
public float heldVolume = 0.8f;
private float[] audioSamples = new float[256];
private float headBobStrength = 0.03f;
[SerializeField]
private AudioSource voiceSource;
[SerializeField]
private AudioSource connectedSource;
[SerializeField]
private AudioSource skipSource;
[SerializeField]
private List<AudioSource> musicTracks;
[SerializeField]
private List<AudioClip> lyricClips;
[Header("Lyrics")]
public List<TrackLyrics> trackLyrics;
public float lyricInterval = 3f;
private float lyricTimer;
private AudioSource currentMusic;
[Header("Voice")]
[SerializeField]
private float voiceCooldown = 1.5f;
private float lastVoiceTime;
private void Awake()
{
grab = ((Component)this).GetComponent<PhysGrabObject>();
particles = new List<ParticleSystem>(((Component)this).GetComponentsInChildren<ParticleSystem>(true));
AudioSource[] componentsInChildren = ((Component)this).GetComponentsInChildren<AudioSource>(true);
AudioSource[] array = componentsInChildren;
foreach (AudioSource val in array)
{
if (((Object)((Component)val).gameObject).name == "ConnectedSource")
{
connectedSource = val;
}
else if (((Object)((Component)val).gameObject).name == "SkipSource")
{
skipSource = val;
}
else if (((Object)((Component)val).gameObject).name.StartsWith("Music"))
{
musicTracks.Add(val);
}
else if (((Object)((Component)val).gameObject).name == "VoiceSource")
{
voiceSource = val;
}
}
if (musicTracks.Count == 0)
{
Debug.LogError((object)"JBLSpeaker: musicTracks is empty!");
}
if (!Object.op_Implicit((Object)(object)skipSource))
{
Debug.LogError((object)"JBLSpeaker: SkipSource not assigned");
}
ShuffleMusic();
}
private void Update()
{
if (!Object.op_Implicit((Object)(object)grab))
{
return;
}
if (grab.grabbed && !wasGrabbed)
{
OnPickup();
}
if (!grab.grabbed && wasGrabbed)
{
OnDrop();
}
wasGrabbed = grab.grabbed;
if (grab.grabbedLocal && Input.GetKeyDown((KeyCode)101))
{
SkipTrack();
}
foreach (AudioSource musicTrack in musicTracks)
{
if (musicTrack.isPlaying)
{
ApplyHeadBob(musicTrack);
break;
}
}
if (grab.grabbed && Object.op_Implicit((Object)(object)currentMusic) && currentMusic.isPlaying)
{
lyricTimer += Time.deltaTime;
if (lyricTimer >= lyricInterval)
{
TrySpeakLyricForCurrentTrack();
lyricTimer = 0f;
}
}
}
private void OnPickup()
{
isActive = true;
skipCount = 0;
RestoreMusicVolume();
if (!IsAnyMusicPlaying() && Object.op_Implicit((Object)(object)connectedSource) && Object.op_Implicit((Object)(object)connectedSource.clip))
{
musicIndex = -1;
connectedSource.Play();
}
}
private void OnDrop()
{
SetMusicVolume(droppedVolume);
StopParticles();
}
private void ShuffleMusic()
{
for (int num = musicTracks.Count - 1; num > 0; num--)
{
int num2 = Random.Range(0, num + 1);
List<AudioSource> list = musicTracks;
int index = num;
List<AudioSource> list2 = musicTracks;
int index2 = num2;
AudioSource value = musicTracks[num2];
AudioSource value2 = musicTracks[num];
list[index] = value;
list2[index2] = value2;
}
}
private void SkipTrack()
{
if (!isActive)
{
return;
}
skipCount++;
if (skipCount >= maxSkipsBeforeOff)
{
PowerOff();
return;
}
PlaySkipThenMusic();
if (((MonoBehaviourPun)this).photonView.IsMine)
{
((MonoBehaviourPun)this).photonView.RPC("RPC_SkipTrack", (RpcTarget)1, Array.Empty<object>());
}
}
private void PlaySkipThenMusic()
{
if (!Object.op_Implicit((Object)(object)skipSource))
{
Debug.LogError((object)"JBLSpeaker: SkipSource not assigned");
return;
}
if (musicTracks == null || musicTracks.Count == 0)
{
Debug.LogError((object)"JBLSpeaker: No music tracks assigned");
return;
}
StopMusicOnly();
if (Object.op_Implicit((Object)(object)skipSource.clip))
{
skipSource.Play();
}
musicIndex++;
if (musicIndex >= musicTracks.Count)
{
ShuffleMusic();
musicIndex = 0;
}
float num = (Object.op_Implicit((Object)(object)skipSource.clip) ? skipSource.clip.length : 0f);
((MonoBehaviour)this).Invoke("PlayCurrentMusic", num);
}
private void PlayCurrentMusic()
{
if (!isActive || musicTracks.Count == 0)
{
return;
}
currentMusic = musicTracks[musicIndex];
currentMusic.volume = (grab.grabbed ? heldVolume : droppedVolume);
currentMusic.Play();
foreach (ParticleSystem particle in particles)
{
particle.Play();
}
}
private void PowerOff()
{
isActive = false;
StopMusicOnly();
StopParticles(clear: true);
}
private void StopMusicOnly()
{
foreach (AudioSource musicTrack in musicTracks)
{
musicTrack.Stop();
}
}
private void StopParticles(bool clear = false)
{
foreach (ParticleSystem particle in particles)
{
if (clear)
{
particle.Stop(true, (ParticleSystemStopBehavior)0);
}
else
{
particle.Stop(true, (ParticleSystemStopBehavior)1);
}
}
}
private void OnCollisionEnter(Collision collision)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)grab) && grab.grabbed)
{
Vector3 relativeVelocity = collision.relativeVelocity;
if (((Vector3)(ref relativeVelocity)).magnitude >= slamVelocityThreshold)
{
SkipTrack();
}
}
}
private void ApplyHeadBob(AudioSource src)
{
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)src) || !src.isPlaying)
{
return;
}
src.GetOutputData(audioSamples, 0);
float num = 0f;
for (int i = 0; i < audioSamples.Length; i++)
{
num += Mathf.Abs(audioSamples[i]);
}
float num2 = num / (float)audioSamples.Length;
float num3 = num2 * headBobStrength;
foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
{
if ((Object)(object)player == (Object)null)
{
continue;
}
float num4 = Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.position);
if (!(num4 > 8f))
{
if (player.isLocal)
{
CameraAim.Instance.AdditiveAimY(num3);
}
else
{
player.playerAvatarVisuals.HeadTiltOverride(num3);
}
}
}
}
private void TrySpeakLyricForCurrentTrack()
{
if ((Object)(object)currentMusic == (Object)null || trackLyrics == null)
{
return;
}
foreach (TrackLyrics trackLyric in trackLyrics)
{
if (trackLyric == null || (Object)(object)trackLyric.track == (Object)null || trackLyric.lyrics == null || !((Object)(object)trackLyric.track == (Object)(object)currentMusic) || trackLyric.lyrics.Count <= 0)
{
continue;
}
AudioClip clip = trackLyric.lyrics[Random.Range(0, trackLyric.lyrics.Count)];
Speak(clip);
break;
}
}
private bool IsAnyMusicPlaying()
{
foreach (AudioSource musicTrack in musicTracks)
{
if (Object.op_Implicit((Object)(object)musicTrack) && musicTrack.isPlaying)
{
return true;
}
}
return false;
}
private void SetMusicVolume(float volume)
{
foreach (AudioSource musicTrack in musicTracks)
{
if (Object.op_Implicit((Object)(object)musicTrack) && musicTrack.isPlaying)
{
musicTrack.volume = volume;
}
}
}
private void RestoreMusicVolume()
{
SetMusicVolume(heldVolume);
}
private void Speak(AudioClip clip)
{
if (Object.op_Implicit((Object)(object)clip) && Object.op_Implicit((Object)(object)voiceSource) && !voiceSource.isPlaying && !(Time.time - lastVoiceTime < voiceCooldown))
{
voiceSource.clip = clip;
voiceSource.Play();
lastVoiceTime = Time.time;
}
}
[PunRPC]
private void RPC_SkipTrack()
{
SkipTrack();
}
}
}