using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using FMOD;
using FMODUnity;
using Mirror;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CustomBoombox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomBoombox")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cf8bd6d7-5d01-4cb9-82c0-f839260bd127")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("eva.customboombox.display", "Boombox Display", "2.4.1")]
public class BoomboxDisplay : BaseUnityPlugin
{
private CustomBoombox boomboxPlugin;
private BoomboxMusic musicPlugin;
private FieldInfo boomboxField;
private FieldInfo volumeField;
private FieldInfo pausedField;
private FieldInfo hasChannelField;
private GameObject currentBoombox;
private GameObject displayObject;
private GameObject equalizerObject;
private GameObject frameObject;
private Transform borderTransform;
private Transform backgroundTransform;
private TextMesh volumeText;
private readonly Transform[] bars = (Transform[])(object)new Transform[13];
private readonly float[] barHeights = new float[13];
private Material panelMaterial;
private Material borderMaterial;
private Material[] barMaterials;
private Vector3 displayPosition = new Vector3(0.01f, 0.32f, -0.58f);
private float displayScale = 0.7499999f;
private bool flipped = true;
private Vector3 equalizerPosition = new Vector3(-0.01f, -0.07f, -0.02f);
private float equalizerScale = 2.049999f;
private float barWidth = 0.011f;
private float barSpacing = 0.013f;
private float barHeightMultiplier = 2.2f;
private Vector3 framePosition = new Vector3(-0.02f, -0.01f, 0f);
private float frameWidth = 0.4450001f;
private float frameHeight = 0.1789595f;
private float frameThickness = 0.009499999f;
private const float BarMinHeight = 0.004f;
private const float BarMaxHeight = 0.022f;
private float animationTime = 0f;
private void Awake()
{
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.NonPublic;
boomboxField = typeof(CustomBoombox).GetField("activeBoombox", bindingAttr);
volumeField = typeof(BoomboxMusic).GetField("volume", bindingAttr);
pausedField = typeof(BoomboxMusic).GetField("isPaused", bindingAttr);
hasChannelField = typeof(BoomboxMusic).GetField("hasChannel", bindingAttr);
CreateMaterials();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Boombox Display 2.4.1 запущен!");
}
private void CreateMaterials()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Expected O, but got Unknown
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
Shader val = Shader.Find("Unlit/Color");
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Sprites/Default");
}
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"Не найден шейдер дисплея.");
return;
}
panelMaterial = new Material(val);
panelMaterial.color = new Color(0.075f, 0.035f, 0.15f, 1f);
borderMaterial = new Material(val);
borderMaterial.color = new Color(0.95f, 0.38f, 0.78f, 1f);
barMaterials = (Material[])(object)new Material[3];
barMaterials[0] = new Material(val);
barMaterials[0].color = new Color(1f, 0.94f, 1f, 1f);
barMaterials[1] = new Material(val);
barMaterials[1].color = new Color(0.94f, 0.38f, 0.78f, 1f);
barMaterials[2] = new Material(val);
barMaterials[2].color = new Color(0.55f, 0.35f, 0.95f, 1f);
}
private void Update()
{
FindBoombox();
if (!((Object)(object)currentBoombox == (Object)null))
{
if ((Object)(object)displayObject == (Object)null)
{
CreateDisplay();
}
UpdateVolumeText();
UpdateEqualizer();
}
}
private void FindBoombox()
{
if ((Object)(object)boomboxPlugin == (Object)null)
{
boomboxPlugin = Object.FindFirstObjectByType<CustomBoombox>();
}
if ((Object)(object)musicPlugin == (Object)null)
{
musicPlugin = Object.FindFirstObjectByType<BoomboxMusic>();
}
if ((Object)(object)boomboxPlugin == (Object)null || boomboxField == null)
{
return;
}
object? value = boomboxField.GetValue(boomboxPlugin);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if (!((Object)(object)val == (Object)(object)currentBoombox))
{
DestroyDisplay();
currentBoombox = val;
if ((Object)(object)currentBoombox != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Дисплей подключён к бумбоксу!");
}
}
}
private void CreateDisplay()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
//IL_006c: 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)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Expected O, but got Unknown
displayObject = new GameObject("Boombox Digital Display");
displayObject.transform.SetParent(currentBoombox.transform, false);
frameObject = new GameObject("Adjustable Display Frame");
frameObject.transform.SetParent(displayObject.transform, false);
GameObject val = CreateRectangle("Pink Border", frameObject.transform, Vector3.zero, frameWidth, frameHeight, borderMaterial);
borderTransform = val.transform;
GameObject val2 = CreateRectangle("Dark Screen", frameObject.transform, new Vector3(0f, 0f, -0.0005f), frameWidth - frameThickness * 2f, frameHeight - frameThickness * 2f, panelMaterial);
backgroundTransform = val2.transform;
CreateVolumeText();
equalizerObject = new GameObject("Adjustable Equalizer");
equalizerObject.transform.SetParent(displayObject.transform, false);
CreateEqualizer();
ApplyDisplayTransform();
ApplyEqualizerTransform();
ApplyFrameTransform();
}
private GameObject CreateRectangle(string objectName, Transform parent, Vector3 position, float width, float height, Material material)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
GameObject val = GameObject.CreatePrimitive((PrimitiveType)5);
((Object)val).name = objectName;
val.transform.SetParent(parent, false);
val.transform.localPosition = position;
val.transform.localRotation = Quaternion.identity;
val.transform.localScale = new Vector3(width, height, 1f);
Collider component = val.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
MeshRenderer component2 = val.GetComponent<MeshRenderer>();
if ((Object)(object)component2 != (Object)null)
{
((Renderer)component2).sharedMaterial = material;
((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)component2).receiveShadows = false;
}
return val;
}
private void CreateVolumeText()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Volume Text");
val.transform.SetParent(displayObject.transform, false);
val.transform.localPosition = new Vector3(0f, 0.012f, -0.0015f);
volumeText = val.AddComponent<TextMesh>();
volumeText.text = "VOL70%";
volumeText.anchor = (TextAnchor)4;
volumeText.alignment = (TextAlignment)1;
volumeText.fontSize = 64;
volumeText.characterSize = 0.01f;
volumeText.color = new Color(1f, 0.76f, 0.94f, 1f);
Font builtinResource = Resources.GetBuiltinResource<Font>("Arial.ttf");
if ((Object)(object)builtinResource != (Object)null)
{
volumeText.font = builtinResource;
MeshRenderer component = val.GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null)
{
((Renderer)component).sharedMaterial = builtinResource.material;
((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
}
}
}
private void CreateEqualizer()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)equalizerObject == (Object)null) && barMaterials != null)
{
for (int i = 0; i < bars.Length; i++)
{
GameObject val = CreateRectangle("Equalizer Bar " + i, equalizerObject.transform, Vector3.zero, barWidth, 0.004f, barMaterials[i % 3]);
bars[i] = val.transform;
barHeights[i] = 0.004f;
SetBarHeight(i, 0.004f);
}
}
}
private void SetBarHeight(int index, float height)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)bars[index] == (Object)null))
{
float num = ((float)index - (float)(bars.Length - 1) / 2f) * barSpacing;
float num2 = height * barHeightMultiplier;
float num3 = -0.011f;
bars[index].localPosition = new Vector3(num, num3 + num2 / 2f, 0f);
bars[index].localScale = new Vector3(barWidth, num2, 1f);
}
}
private void UpdateVolumeText()
{
if ((Object)(object)volumeText == (Object)null || (Object)(object)musicPlugin == (Object)null || volumeField == null || pausedField == null)
{
return;
}
try
{
float num = (float)volumeField.GetValue(musicPlugin);
if ((bool)pausedField.GetValue(musicPlugin))
{
volumeText.text = "PAUSE";
return;
}
int num2 = Mathf.RoundToInt(num * 100f);
volumeText.text = "VOL" + num2 + "%";
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Ошибка дисплея: " + ex.Message));
}
}
private bool IsMusicPlaying()
{
if ((Object)(object)musicPlugin == (Object)null || hasChannelField == null || pausedField == null)
{
return false;
}
try
{
bool flag = (bool)hasChannelField.GetValue(musicPlugin);
bool flag2 = (bool)pausedField.GetValue(musicPlugin);
return flag && !flag2;
}
catch
{
return false;
}
}
private void UpdateEqualizer()
{
bool flag = IsMusicPlaying();
if (flag)
{
animationTime += Time.deltaTime;
}
for (int i = 0; i < bars.Length; i++)
{
if (!((Object)(object)bars[i] == (Object)null))
{
float num4;
if (flag)
{
float num = Mathf.Sin(animationTime * 12f + (float)i * 1.37f);
float num2 = Mathf.Sin(animationTime * 7f - (float)i * 0.83f);
float num3 = Mathf.Abs(num * 0.65f + num2 * 0.35f);
num4 = Mathf.Lerp(0.004f, 0.022f, num3);
}
else
{
num4 = 0.004f;
}
barHeights[i] = Mathf.Lerp(barHeights[i], num4, Mathf.Clamp01(Time.deltaTime * 12f));
SetBarHeight(i, barHeights[i]);
}
}
}
private void ApplyDisplayTransform()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)displayObject == (Object)null))
{
displayObject.transform.localPosition = displayPosition;
displayObject.transform.localRotation = Quaternion.Euler(0f, flipped ? 0f : 180f, 0f);
displayObject.transform.localScale = Vector3.one * displayScale;
}
}
private void ApplyEqualizerTransform()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)equalizerObject == (Object)null)
{
return;
}
equalizerObject.transform.localPosition = equalizerPosition;
equalizerObject.transform.localRotation = Quaternion.identity;
equalizerObject.transform.localScale = Vector3.one * equalizerScale;
for (int i = 0; i < bars.Length; i++)
{
if ((Object)(object)bars[i] != (Object)null)
{
SetBarHeight(i, barHeights[i]);
}
}
}
private void ApplyFrameTransform()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)frameObject == (Object)null) && !((Object)(object)borderTransform == (Object)null) && !((Object)(object)backgroundTransform == (Object)null))
{
frameObject.transform.localPosition = framePosition;
borderTransform.localScale = new Vector3(frameWidth, frameHeight, 1f);
float num = Mathf.Max(0.001f, frameWidth - frameThickness * 2f);
float num2 = Mathf.Max(0.001f, frameHeight - frameThickness * 2f);
backgroundTransform.localScale = new Vector3(num, num2, 1f);
}
}
private void DestroyDisplay()
{
if ((Object)(object)displayObject != (Object)null)
{
Object.Destroy((Object)(object)displayObject);
}
displayObject = null;
equalizerObject = null;
frameObject = null;
borderTransform = null;
backgroundTransform = null;
volumeText = null;
for (int i = 0; i < bars.Length; i++)
{
bars[i] = null;
barHeights[i] = 0f;
}
}
private void OnDestroy()
{
DestroyDisplay();
if ((Object)(object)panelMaterial != (Object)null)
{
Object.Destroy((Object)(object)panelMaterial);
}
if ((Object)(object)borderMaterial != (Object)null)
{
Object.Destroy((Object)(object)borderMaterial);
}
if (barMaterials == null)
{
return;
}
Material[] array = barMaterials;
foreach (Material val in array)
{
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
}
}
}
[BepInPlugin("eva.customboombox.effects", "Boombox Effects", "2.7.0")]
public class BoomboxEffects : BaseUnityPlugin
{
private class SoundWave
{
public GameObject gameObject;
public LineRenderer line;
public float age;
public float strength;
public Color color;
public float sizeMultiplier;
public float forwardMultiplier;
public float widthMultiplier;
public float lifetimeMultiplier;
public float layerOffset;
}
private readonly Vector3 leftSpeaker = new Vector3(-0.25f, 0f, -0.12f);
private readonly Vector3 rightSpeaker = new Vector3(0.25f, 0f, -0.12f);
private const float WaveLifetime = 0.85f;
private const int RingSegments = 48;
private const float MinimumBeatInterval = 0.18f;
private const float BackgroundInterval = 1f;
private const float MainWaveRadius = 0.6687525f;
private const float LayerOffset = 0.16f;
private CustomBoombox boomboxPlugin;
private BoomboxMusic musicPlugin;
private FieldInfo boomboxField;
private FieldInfo channelField;
private FieldInfo hasChannelField;
private FieldInfo pausedField;
private GameObject currentBoombox;
private Material waveMaterial;
private readonly List<SoundWave> waves = new List<SoundWave>();
private DSP fft;
private Channel analyzedChannel;
private bool hasFFT = false;
private float averageBass = 0f;
private float previousBass = 0f;
private float lastBeatTime = -10f;
private float lastWaveTime = -10f;
private void Awake()
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Expected O, but got Unknown
boomboxField = typeof(CustomBoombox).GetField("activeBoombox", BindingFlags.Instance | BindingFlags.NonPublic);
Type typeFromHandle = typeof(BoomboxMusic);
channelField = typeFromHandle.GetField("channel", BindingFlags.Instance | BindingFlags.NonPublic);
hasChannelField = typeFromHandle.GetField("hasChannel", BindingFlags.Instance | BindingFlags.NonPublic);
pausedField = typeFromHandle.GetField("isPaused", BindingFlags.Instance | BindingFlags.NonPublic);
Shader val = Shader.Find("Sprites/Default");
if ((Object)(object)val == (Object)null)
{
val = Shader.Find("Unlit/Transparent");
}
if ((Object)(object)val != (Object)null)
{
waveMaterial = new Material(val);
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)"Не найден шейдер для звуковых волн.");
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Boombox Effects 2.7.0 запущен!");
}
private void Update()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
FindBoombox();
Channel channel;
bool flag = TryGetPlayingChannel(out channel);
if (flag && (Object)(object)currentBoombox != (Object)null && (Object)(object)waveMaterial != (Object)null)
{
EnsureFFT(channel);
AnalyzeBass();
}
else
{
averageBass = 0f;
previousBass = 0f;
if (!flag)
{
ReleaseFFT();
}
}
UpdateWaves();
}
private void FindBoombox()
{
if ((Object)(object)boomboxPlugin == (Object)null)
{
boomboxPlugin = Object.FindFirstObjectByType<CustomBoombox>();
}
if ((Object)(object)musicPlugin == (Object)null)
{
musicPlugin = Object.FindFirstObjectByType<BoomboxMusic>();
}
if ((Object)(object)boomboxPlugin == (Object)null || boomboxField == null)
{
return;
}
object? value = boomboxField.GetValue(boomboxPlugin);
GameObject val = (GameObject)((value is GameObject) ? value : null);
if (!((Object)(object)val == (Object)(object)currentBoombox))
{
ReleaseFFT();
ClearWaves();
currentBoombox = val;
averageBass = 0f;
previousBass = 0f;
if ((Object)(object)currentBoombox != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Эффекты подключены к бумбоксу!");
}
}
}
private bool TryGetPlayingChannel(out Channel channel)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Invalid comparison between Unknown and I4
channel = default(Channel);
if ((Object)(object)musicPlugin == (Object)null || channelField == null || hasChannelField == null || pausedField == null)
{
return false;
}
try
{
bool flag = (bool)hasChannelField.GetValue(musicPlugin);
bool flag2 = (bool)pausedField.GetValue(musicPlugin);
if (!flag || flag2)
{
return false;
}
channel = (Channel)channelField.GetValue(musicPlugin);
if (!((Channel)(ref channel)).hasHandle())
{
return false;
}
bool flag3 = default(bool);
RESULT val = ((Channel)(ref channel)).isPlaying(ref flag3);
return (int)val == 0 && flag3;
}
catch
{
return false;
}
}
private unsafe void EnsureFFT(Channel musicChannel)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Invalid comparison between Unknown and I4
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: 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_009b: Invalid comparison between Unknown and I4
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Invalid comparison between Unknown and I4
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
if (hasFFT && ((Channel)(ref analyzedChannel)).hasHandle() && analyzedChannel.handle == musicChannel.handle)
{
return;
}
ReleaseFFT();
System coreSystem = RuntimeManager.CoreSystem;
RESULT val = ((System)(ref coreSystem)).createDSPByType((DSP_TYPE)26, ref fft);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Не удалось создать FFT: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
return;
}
val = ((DSP)(ref fft)).setParameterInt(0, 2048);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Не удалось настроить FFT: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
}
val = ((Channel)(ref musicChannel)).addDSP(0, fft);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Не удалось подключить FFT: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
((DSP)(ref fft)).release();
((DSP)(ref fft)).clearHandle();
}
else
{
analyzedChannel = musicChannel;
hasFFT = true;
averageBass = 0f;
previousBass = 0f;
((BaseUnityPlugin)this).Logger.LogInfo((object)"FFT подключён. Анализируем бас!");
}
}
private void AnalyzeBass()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
if (!hasFFT || !((DSP)(ref fft)).hasHandle())
{
EmitBackgroundWave();
return;
}
IntPtr intPtr = default(IntPtr);
uint num = default(uint);
RESULT parameterData = ((DSP)(ref fft)).getParameterData(4, ref intPtr, ref num);
if ((int)parameterData != 0 || intPtr == IntPtr.Zero)
{
EmitBackgroundWave();
return;
}
DSP_PARAMETER_FFT val;
try
{
val = (DSP_PARAMETER_FFT)Marshal.PtrToStructure(intPtr, typeof(DSP_PARAMETER_FFT));
}
catch
{
EmitBackgroundWave();
return;
}
if (val.numchannels <= 0 || val.length <= 0 || ((DSP_PARAMETER_FFT)(ref val)).spectrum == null || ((DSP_PARAMETER_FFT)(ref val)).spectrum[0] == null)
{
EmitBackgroundWave();
return;
}
float[] array = ((DSP_PARAMETER_FFT)(ref val)).spectrum[0];
int num2 = 2;
int num3 = Mathf.Min(12, array.Length - 1);
if (num3 < num2)
{
EmitBackgroundWave();
return;
}
float num4 = 0f;
for (int i = num2; i <= num3; i++)
{
num4 += array[i];
}
num4 /= (float)(num3 - num2 + 1);
if (averageBass <= 0f)
{
averageBass = num4;
}
else
{
averageBass = Mathf.Lerp(averageBass, num4, Mathf.Clamp01(Time.deltaTime * 2f));
}
float num5 = Mathf.Max(averageBass * 1.45f, 0.0001f);
bool flag = num4 > num5;
bool flag2 = num4 > previousBass * 1.08f;
bool flag3 = Time.time - lastBeatTime >= 0.18f;
if (flag && flag2 && flag3)
{
float strength = Mathf.Clamp(num4 / Mathf.Max(averageBass, 0.0001f), 1f, 2f);
EmitWaves(strength);
lastBeatTime = Time.time;
lastWaveTime = Time.time;
}
else
{
EmitBackgroundWave();
}
previousBass = num4;
}
private void EmitBackgroundWave()
{
if (!(Time.time - lastWaveTime < 1f))
{
EmitWaves(0.65f);
lastWaveTime = Time.time;
}
}
private void EmitWaves(float strength)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
EmitSpeakerWaves(leftSpeaker, strength, isLeft: true);
EmitSpeakerWaves(rightSpeaker, strength, isLeft: false);
}
private void EmitSpeakerWaves(Vector3 position, float strength, bool isLeft)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
Color color = (isLeft ? new Color(1f, 0.35f, 0.85f, 0.85f) : new Color(0.7f, 0.35f, 1f, 0.85f));
CreateWave(position, color, strength, 1f, 1f, 1f, 1f, 0f);
CreateWave(position, new Color(0.22f, 0.12f, 0.75f, 0.85f), strength, 1.22f, 1.15f, 0.85f, 1.12f, -0.16f);
CreateWave(position, new Color(1f, 1f, 1f, 0.9f), strength, 0.68f, 0.85f, 0.75f, 0.8f, 0.16f);
}
private void CreateWave(Vector3 speakerPosition, Color color, float strength, float sizeMultiplier, float forwardMultiplier, float widthMultiplier, float lifetimeMultiplier, float layerOffset)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)currentBoombox == (Object)null))
{
GameObject val = new GameObject("Boombox Sound Wave");
val.transform.SetParent(currentBoombox.transform, false);
val.transform.localPosition = speakerPosition;
val.transform.localRotation = Quaternion.identity;
LineRenderer val2 = val.AddComponent<LineRenderer>();
val2.useWorldSpace = false;
val2.loop = true;
val2.positionCount = 48;
((Renderer)val2).sharedMaterial = waveMaterial;
((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
((Renderer)val2).receiveShadows = false;
SoundWave soundWave = new SoundWave
{
gameObject = val,
line = val2,
age = 0f,
strength = strength,
color = color,
sizeMultiplier = sizeMultiplier,
forwardMultiplier = forwardMultiplier,
widthMultiplier = widthMultiplier,
lifetimeMultiplier = lifetimeMultiplier,
layerOffset = layerOffset
};
waves.Add(soundWave);
DrawWave(soundWave);
}
}
private void UpdateWaves()
{
for (int num = waves.Count - 1; num >= 0; num--)
{
SoundWave soundWave = waves[num];
if ((Object)(object)soundWave.gameObject == (Object)null || (Object)(object)soundWave.line == (Object)null)
{
waves.RemoveAt(num);
}
else
{
soundWave.age += Time.deltaTime;
float num2 = 0.85f * soundWave.lifetimeMultiplier;
if (soundWave.age >= num2)
{
Object.Destroy((Object)(object)soundWave.gameObject);
waves.RemoveAt(num);
}
else
{
DrawWave(soundWave);
}
}
}
}
private void DrawWave(SoundWave wave)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
float num = 0.85f * wave.lifetimeMultiplier;
float num2 = Mathf.Clamp01(wave.age / num);
float num3 = Mathf.Lerp(0.08f * wave.sizeMultiplier, 0.6687525f * wave.strength * wave.sizeMultiplier, num2);
float num4 = Mathf.Lerp(0f, 0.35f * wave.forwardMultiplier, num2);
num4 += wave.layerOffset;
float num5 = (1f - num2) * (1f - num2);
Color color = wave.color;
color.a *= num5;
wave.line.startColor = color;
wave.line.endColor = color;
float num6 = Mathf.Lerp(0.035f * wave.widthMultiplier, 0.008f * wave.widthMultiplier, num2);
wave.line.startWidth = num6;
wave.line.endWidth = num6;
for (int i = 0; i < 48; i++)
{
float num7 = (float)i / 48f * (float)Math.PI * 2f;
float num8 = Mathf.Cos(num7) * num3;
float num9 = Mathf.Sin(num7) * num3;
wave.line.SetPosition(i, new Vector3(num8, num9, num4));
}
}
private void ReleaseFFT()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
if (hasFFT)
{
if (((Channel)(ref analyzedChannel)).hasHandle() && ((DSP)(ref fft)).hasHandle())
{
((Channel)(ref analyzedChannel)).removeDSP(fft);
}
if (((DSP)(ref fft)).hasHandle())
{
((DSP)(ref fft)).release();
((DSP)(ref fft)).clearHandle();
}
analyzedChannel = default(Channel);
hasFFT = false;
}
}
private void ClearWaves()
{
foreach (SoundWave wave in waves)
{
if ((Object)(object)wave.gameObject != (Object)null)
{
Object.Destroy((Object)(object)wave.gameObject);
}
}
waves.Clear();
}
private void OnDestroy()
{
ReleaseFFT();
ClearWaves();
if ((Object)(object)waveMaterial != (Object)null)
{
Object.Destroy((Object)(object)waveMaterial);
}
}
}
[BepInPlugin("eva.customboombox.hands", "Boombox Hands", "1.6.0")]
public class BoomboxHands : BaseUnityPlugin
{
private CustomBoombox boomboxPlugin;
private FieldInfo holdingField;
private Animator handsAnimator;
private Transform handsTransform;
private string holdingParam;
private string widthParam;
private string clutchParam;
private bool animationActive;
private bool previousHolding;
private bool originalHolding;
private float originalWidth;
private float originalClutch;
private Vector3 originalHandsPosition;
private bool warningShown;
private float nextSearchTime;
private const float HandWidth = 0.55f;
private const float HandClutch = 0.55f;
private const float HandsBackOffset = -0.035f;
private readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private void Awake()
{
holdingField = typeof(CustomBoombox).GetField("isHolding", BindingFlags.Instance | BindingFlags.NonPublic);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Boombox Hands 1.6.0 запущен!");
}
private void LateUpdate()
{
if (holdingField == null)
{
return;
}
try
{
if ((Object)(object)boomboxPlugin == (Object)null)
{
boomboxPlugin = Object.FindFirstObjectByType<CustomBoombox>();
}
if ((Object)(object)boomboxPlugin == (Object)null)
{
return;
}
bool flag = (bool)holdingField.GetValue(boomboxPlugin);
if (flag && !previousHolding)
{
warningShown = false;
nextSearchTime = 0f;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Бумбокс поднят. Настраиваем руки.");
}
if (flag)
{
if (!animationActive && Time.unscaledTime >= nextSearchTime)
{
nextSearchTime = Time.unscaledTime + 3f;
FindAndActivateHands();
}
if (animationActive)
{
ApplyHoldingPose();
}
}
else if (animationActive)
{
RestoreHands();
}
previousHolding = flag;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)ex);
if (animationActive)
{
RestoreHands();
}
((Behaviour)this).enabled = false;
}
}
private void FindAndActivateHands()
{
//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
PlayerInventory val = FindLocalInventory();
if ((Object)(object)val == (Object)null)
{
WarnOnce("Локальный инвентарь не найден.");
return;
}
FieldInfo field = typeof(PlayerInventory).GetField("playerHands", flags);
GameObject val2 = null;
if (field != null)
{
object? value = field.GetValue(val);
val2 = (GameObject)((value is GameObject) ? value : null);
}
if ((Object)(object)val2 == (Object)null)
{
WarnOnce("PlayerHands не найден.");
return;
}
Animator[] array = val2.GetComponentsInChildren<Animator>(true);
if (array.Length == 0)
{
Animator componentInParent = val2.GetComponentInParent<Animator>();
if ((Object)(object)componentInParent != (Object)null)
{
array = (Animator[])(object)new Animator[1] { componentInParent };
}
}
Animator[] array2 = array;
foreach (Animator val3 in array2)
{
if (!((Object)(object)val3 == (Object)null) && HasParameter(val3, "isHoldingItem", (AnimatorControllerParameterType)4) && HasParameter(val3, "handsWidth", (AnimatorControllerParameterType)1) && HasParameter(val3, "handsClutching", (AnimatorControllerParameterType)1))
{
handsAnimator = val3;
holdingParam = "isHoldingItem";
widthParam = "handsWidth";
clutchParam = "handsClutching";
originalHolding = handsAnimator.GetBool(holdingParam);
originalWidth = handsAnimator.GetFloat(widthParam);
originalClutch = handsAnimator.GetFloat(clutchParam);
handsTransform = val2.transform;
originalHandsPosition = handsTransform.localPosition;
animationActive = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Animator найден. Новая поза включена!");
ApplyHoldingPose();
return;
}
}
WarnOnce("Animator с параметрами удержания не найден.");
}
private bool HasParameter(Animator animator, string name, AnimatorControllerParameterType type)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
AnimatorControllerParameter[] parameters = animator.parameters;
foreach (AnimatorControllerParameter val in parameters)
{
if (val.name == name && val.type == type)
{
return true;
}
}
return false;
}
private PlayerInventory FindLocalInventory()
{
if ((Object)(object)NetworkClient.localPlayer != (Object)null)
{
PlayerInventory val = ((Component)NetworkClient.localPlayer).GetComponentInChildren<PlayerInventory>(true);
if ((Object)(object)val == (Object)null)
{
val = ((Component)NetworkClient.localPlayer).GetComponentInParent<PlayerInventory>();
}
if ((Object)(object)val != (Object)null)
{
return val;
}
}
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
return ((Component)main).GetComponentInParent<PlayerInventory>();
}
return null;
}
private void ApplyHoldingPose()
{
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)handsAnimator == (Object)null)
{
animationActive = false;
return;
}
handsAnimator.SetBool(holdingParam, true);
handsAnimator.SetFloat(widthParam, 0.55f);
handsAnimator.SetFloat(clutchParam, 0.55f);
if ((Object)(object)handsTransform != (Object)null)
{
handsTransform.localPosition = originalHandsPosition + new Vector3(0f, 0f, -0.035f);
}
}
private void RestoreHands()
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)handsAnimator != (Object)null)
{
handsAnimator.SetBool(holdingParam, originalHolding);
handsAnimator.SetFloat(widthParam, originalWidth);
handsAnimator.SetFloat(clutchParam, originalClutch);
}
if ((Object)(object)handsTransform != (Object)null)
{
handsTransform.localPosition = originalHandsPosition;
}
animationActive = false;
handsAnimator = null;
handsTransform = null;
holdingParam = null;
widthParam = null;
clutchParam = null;
warningShown = false;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Руки возвращены в обычное положение.");
}
private void WarnOnce(string message)
{
if (!warningShown)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)message);
warningShown = true;
}
}
private void OnDisable()
{
if (animationActive)
{
RestoreHands();
}
}
}
public class BoomboxItem : Item
{
protected override void OnPickedUp(PlayerInventory playerInventory)
{
((Item)this).OnPickedUp(playerInventory);
}
protected override void OnDropped(PlayerInventory playerInventory)
{
((Item)this).OnDropped(playerInventory);
}
}
[BepInPlugin("eva.customboombox.multiplayer", "Boombox Multiplayer", "1.3.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class BoomboxMultiplayer : BaseUnityPlugin
{
public struct State : NetworkMessage
{
public bool exists;
public Vector3 position;
public Quaternion rotation;
public bool playing;
public bool paused;
public int song;
public float volume;
public uint positionMs;
public uint holderNetId;
}
public struct Request : NetworkMessage
{
public byte action;
public uint playerNetId;
}
private CustomBoombox boombox;
private BoomboxMusic music;
private FieldInfo activeField;
private FieldInfo musicObjectField;
private FieldInfo songField;
private FieldInfo volumeField;
private FieldInfo pausedField;
private FieldInfo hasChannelField;
private FieldInfo channelField;
private MethodInfo spawnMethod;
private MethodInfo playMethod;
private MethodInfo toggleMethod;
private MethodInfo nextMethod;
private MethodInfo prevMethod;
private MethodInfo volumeMethod;
private GameObject hostObject;
private GameObject remoteObject;
private uint holderId;
private bool clientRegistered;
private bool serverRegistered;
private float nextState;
private int lastSong = -1;
private bool lastPlaying;
private bool lastPaused;
private Vector3 targetPosition;
private Quaternion targetRotation;
private bool haveTarget;
private bool applyingRemote;
private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private static void WriteState(NetworkWriter w, State s)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
NetworkWriterExtensions.WriteBool(w, s.exists);
NetworkWriterExtensions.WriteVector3(w, s.position);
NetworkWriterExtensions.WriteQuaternion(w, s.rotation);
NetworkWriterExtensions.WriteBool(w, s.playing);
NetworkWriterExtensions.WriteBool(w, s.paused);
NetworkWriterExtensions.WriteInt(w, s.song);
NetworkWriterExtensions.WriteFloat(w, s.volume);
NetworkWriterExtensions.WriteUInt(w, s.positionMs);
NetworkWriterExtensions.WriteUInt(w, s.holderNetId);
}
private static State ReadState(NetworkReader r)
{
//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_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)
return new State
{
exists = NetworkReaderExtensions.ReadBool(r),
position = NetworkReaderExtensions.ReadVector3(r),
rotation = NetworkReaderExtensions.ReadQuaternion(r),
playing = NetworkReaderExtensions.ReadBool(r),
paused = NetworkReaderExtensions.ReadBool(r),
song = NetworkReaderExtensions.ReadInt(r),
volume = NetworkReaderExtensions.ReadFloat(r),
positionMs = NetworkReaderExtensions.ReadUInt(r),
holderNetId = NetworkReaderExtensions.ReadUInt(r)
};
}
private static void WriteRequest(NetworkWriter w, Request s)
{
w.WriteByte(s.action);
NetworkWriterExtensions.WriteUInt(w, s.playerNetId);
}
private static Request ReadRequest(NetworkReader r)
{
return new Request
{
action = r.ReadByte(),
playerNetId = NetworkReaderExtensions.ReadUInt(r)
};
}
private void Awake()
{
Writer<State>.write = WriteState;
Reader<State>.read = ReadState;
Writer<Request>.write = WriteRequest;
Reader<Request>.read = ReadRequest;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[MULTIPLAYER] 1.3 loaded");
}
private bool Resolve()
{
if ((Object)(object)boombox == (Object)null)
{
boombox = Object.FindFirstObjectByType<CustomBoombox>();
}
if ((Object)(object)music == (Object)null)
{
music = Object.FindFirstObjectByType<BoomboxMusic>();
}
if ((Object)(object)boombox == (Object)null || (Object)(object)music == (Object)null)
{
return false;
}
if (activeField != null)
{
return true;
}
Type type = ((object)boombox).GetType();
Type type2 = ((object)music).GetType();
activeField = type.GetField("activeBoombox", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
spawnMethod = type.GetMethod("SpawnBoombox", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
musicObjectField = type2.GetField("currentBoombox", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
songField = type2.GetField("currentSong", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
volumeField = type2.GetField("volume", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
pausedField = type2.GetField("isPaused", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
hasChannelField = type2.GetField("hasChannel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
channelField = type2.GetField("channel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
playMethod = type2.GetMethod("PlayCurrentSong", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
toggleMethod = type2.GetMethod("ToggleMusic", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
nextMethod = type2.GetMethod("NextSong", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
prevMethod = type2.GetMethod("PreviousSong", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
volumeMethod = type2.GetMethod("ChangeVolume", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (activeField == null || spawnMethod == null || songField == null || musicObjectField == null || volumeField == null || pausedField == null || hasChannelField == null || channelField == null || playMethod == null || toggleMethod == null || nextMethod == null || prevMethod == null || volumeMethod == null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"[MULTIPLAYER] Missing field or method in CustomBoombox/BoomboxMusic");
((Behaviour)this).enabled = false;
return false;
}
return true;
}
private void Update()
{
if (!Resolve())
{
return;
}
if (NetworkClient.active && !clientRegistered)
{
NetworkClient.RegisterHandler<State>((Action<State>)OnState, false);
clientRegistered = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[MULTIPLAYER] Client handler registered");
}
if (!NetworkClient.active)
{
clientRegistered = false;
}
if (NetworkServer.active && !serverRegistered)
{
NetworkServer.RegisterHandler<Request>((Action<NetworkConnectionToClient, Request>)OnRequest, false);
serverRegistered = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"[MULTIPLAYER] Server handler registered");
}
if (!NetworkServer.active)
{
serverRegistered = false;
holderId = 0u;
hostObject = null;
}
if (NetworkServer.active)
{
ref GameObject reference = ref hostObject;
object? value = activeField.GetValue(boombox);
reference = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)hostObject != (Object)null && holderId != 0)
{
FollowHolder();
}
if (Time.unscaledTime >= nextState)
{
nextState = Time.unscaledTime + 0.15f;
NetworkServer.SendToAll<State>(CaptureState(), 0, false);
}
}
else if (NetworkClient.active && (Object)(object)remoteObject != (Object)null && Keyboard.current != null)
{
Keyboard current = Keyboard.current;
if (((ButtonControl)current.eKey).wasPressedThisFrame)
{
SendRequest(1);
}
if (((ButtonControl)current.pKey).wasPressedThisFrame)
{
SendRequest(2);
}
if (((ButtonControl)current.nKey).wasPressedThisFrame)
{
SendRequest(3);
}
if (((ButtonControl)current.bKey).wasPressedThisFrame)
{
SendRequest(4);
}
if (((ButtonControl)current.minusKey).wasPressedThisFrame || ((ButtonControl)current.numpadMinusKey).wasPressedThisFrame)
{
SendRequest(5);
}
if (((ButtonControl)current.equalsKey).wasPressedThisFrame || ((ButtonControl)current.numpadPlusKey).wasPressedThisFrame)
{
SendRequest(6);
}
}
}
private void LateUpdate()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active && (Object)(object)remoteObject != (Object)null && haveTarget)
{
remoteObject.transform.position = targetPosition;
remoteObject.transform.rotation = targetRotation;
}
}
private void SendRequest(byte action)
{
if (!((Object)(object)NetworkClient.localPlayer == (Object)null))
{
NetworkClient.Send<Request>(new Request
{
action = action,
playerNetId = NetworkClient.localPlayer.netId
}, 0);
}
}
private void OnRequest(NetworkConnectionToClient sender, Request req)
{
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || (Object)(object)hostObject == (Object)null || sender == null || (Object)(object)((NetworkConnection)sender).identity == (Object)null || ((NetworkConnection)sender).identity.netId != req.playerNetId)
{
return;
}
try
{
if (req.action == 1)
{
if (holderId == req.playerNetId)
{
holderId = 0u;
}
else if (holderId == 0 && Vector3.Distance(((Component)((NetworkConnection)sender).identity).transform.position, hostObject.transform.position) < 4f)
{
holderId = req.playerNetId;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("[MULTIPLAYER] Holder: " + holderId));
}
else if (req.action == 2)
{
toggleMethod.Invoke(music, null);
}
else if (req.action == 3)
{
nextMethod.Invoke(music, null);
}
else if (req.action == 4)
{
prevMethod.Invoke(music, null);
}
else if (req.action == 5)
{
volumeMethod.Invoke(music, new object[1] { -0.1f });
}
else if (req.action == 6)
{
volumeMethod.Invoke(music, new object[1] { 0.1f });
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[MULTIPLAYER] Request: " + ex));
}
}
private void FollowHolder()
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.spawned.TryGetValue(holderId, out var value) || (Object)(object)value == (Object)null)
{
holderId = 0u;
return;
}
Component componentInChildren = (Component)(object)((Component)value).GetComponentInChildren<PlayerInventory>();
if ((Object)(object)componentInChildren == (Object)null)
{
holderId = 0u;
return;
}
FieldInfo field = ((object)componentInChildren).GetType().GetField("handTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
Transform val = (Transform)((field == null) ? null : /*isinst with value type is only supported in some contexts*/);
if ((Object)(object)val == (Object)null)
{
holderId = 0u;
return;
}
hostObject.transform.position = val.position;
hostObject.transform.rotation = val.rotation;
}
private State CaptureState()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
State result = new State
{
exists = ((Object)(object)hostObject != (Object)null)
};
if (!result.exists)
{
return result;
}
result.position = hostObject.transform.position;
result.rotation = hostObject.transform.rotation;
result.song = (int)songField.GetValue(music);
result.volume = (float)volumeField.GetValue(music);
result.paused = (bool)pausedField.GetValue(music);
result.playing = (bool)hasChannelField.GetValue(music);
result.holderNetId = holderId;
if (result.playing)
{
try
{
Channel val = (Channel)channelField.GetValue(music);
if (((Channel)(ref val)).hasHandle())
{
((Channel)(ref val)).getPosition(ref result.positionMs, (TIMEUNIT)1);
}
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("[MULTIPLAYER] FMOD position: " + ex.Message));
}
}
return result;
}
private void OnState(State s)
{
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
if (NetworkServer.active || !Resolve())
{
return;
}
if (!s.exists)
{
if ((Object)(object)remoteObject != (Object)null)
{
Object.Destroy((Object)(object)remoteObject);
}
remoteObject = null;
activeField.SetValue(boombox, null);
haveTarget = false;
lastSong = -1;
lastPlaying = false;
return;
}
if ((Object)(object)remoteObject == (Object)null)
{
try
{
spawnMethod.Invoke(boombox, null);
ref GameObject reference = ref remoteObject;
object? value = activeField.GetValue(boombox);
reference = (GameObject)((value is GameObject) ? value : null);
if ((Object)(object)remoteObject == (Object)null)
{
return;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"[MULTIPLAYER] Host boombox created locally");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[MULTIPLAYER] Spawn: " + ex));
return;
}
}
if (musicObjectField.GetValue(music) != remoteObject)
{
musicObjectField.SetValue(music, remoteObject);
}
targetPosition = s.position;
targetRotation = s.rotation;
haveTarget = true;
ApplyMusic(s);
}
private void ApplyMusic(State s)
{
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
if (applyingRemote)
{
return;
}
applyingRemote = true;
try
{
volumeField.SetValue(music, s.volume);
bool flag = lastSong != s.song || lastPlaying != s.playing;
if (!s.playing)
{
if (lastPlaying)
{
((object)music).GetType().GetMethod("StopMusic", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Invoke(music, null);
}
songField.SetValue(music, s.song);
}
else if (flag)
{
songField.SetValue(music, s.song);
playMethod.Invoke(music, new object[2] { s.positionMs, s.paused });
((BaseUnityPlugin)this).Logger.LogInfo((object)("[MULTIPLAYER] Synced song " + s.song));
}
else if (lastPaused != s.paused)
{
Channel val = (Channel)channelField.GetValue(music);
if (((Channel)(ref val)).hasHandle())
{
((Channel)(ref val)).setPaused(s.paused);
}
pausedField.SetValue(music, s.paused);
}
if (s.playing)
{
Channel val2 = (Channel)channelField.GetValue(music);
if (((Channel)(ref val2)).hasHandle())
{
((Channel)(ref val2)).setVolume(s.volume);
}
}
lastSong = s.song;
lastPlaying = s.playing;
lastPaused = s.paused;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("[MULTIPLAYER] Music sync: " + ex));
}
finally
{
applyingRemote = false;
}
}
}
[BepInPlugin("eva.customboombox.music", "Boombox Music", "2.1.0")]
public class BoomboxMusic : BaseUnityPlugin
{
private CustomBoombox boomboxPlugin;
private FieldInfo boomboxField;
private GameObject currentBoombox;
private string musicFolder;
private string[] songs = new string[0];
private int currentSong = 0;
private float volume = 0.7f;
private Sound sound;
private Channel channel;
private bool hasSound = false;
private bool hasChannel = false;
private bool isPaused = false;
private bool wasPlaying = false;
private float nextEndCheck = 0f;
private bool changingScene = false;
private Coroutine sceneCoroutine;
private void Awake()
{
string directoryName = Path.GetDirectoryName(typeof(BoomboxMusic).Assembly.Location);
musicFolder = Path.Combine(directoryName, "Music");
Directory.CreateDirectory(musicFolder);
boomboxField = typeof(CustomBoombox).GetField("activeBoombox", BindingFlags.Instance | BindingFlags.NonPublic);
RefreshPlaylist();
SceneManager.activeSceneChanged += OnSceneChanged;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Boombox Music 2.1.0 запущен!");
}
private void Update()
{
if (!changingScene)
{
FindBoombox();
}
if (Keyboard.current != null && !changingScene)
{
if (((ButtonControl)Keyboard.current.pKey).wasPressedThisFrame)
{
ToggleMusic();
}
if (((ButtonControl)Keyboard.current.bKey).wasPressedThisFrame)
{
PreviousSong();
}
if (((ButtonControl)Keyboard.current.nKey).wasPressedThisFrame)
{
NextSong();
}
if (((ButtonControl)Keyboard.current.minusKey).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpadMinusKey).wasPressedThisFrame)
{
ChangeVolume(-0.1f);
}
if (((ButtonControl)Keyboard.current.equalsKey).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpadPlusKey).wasPressedThisFrame)
{
ChangeVolume(0.1f);
}
}
if (!changingScene)
{
UpdateSoundPosition();
CheckSongEnd();
}
}
private void RefreshPlaylist()
{
songs = Directory.GetFiles(musicFolder, "*.mp3").OrderBy<string, string>((string path) => Path.GetFileName(path), StringComparer.OrdinalIgnoreCase).ToArray();
if (currentSong >= songs.Length)
{
currentSong = 0;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Найдено MP3: " + songs.Length));
}
private GameObject GetPluginBoombox()
{
if ((Object)(object)boomboxPlugin == (Object)null)
{
boomboxPlugin = Object.FindFirstObjectByType<CustomBoombox>();
}
if ((Object)(object)boomboxPlugin == (Object)null || boomboxField == null)
{
return null;
}
object? value = boomboxField.GetValue(boomboxPlugin);
return (GameObject)((value is GameObject) ? value : null);
}
private void FindBoombox()
{
GameObject pluginBoombox = GetPluginBoombox();
if (!((Object)(object)pluginBoombox == (Object)(object)currentBoombox))
{
StopMusic();
currentBoombox = pluginBoombox;
if ((Object)(object)currentBoombox != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"FMOD подключён к бумбоксу!");
}
}
}
private void ToggleMusic()
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Invalid comparison between Unknown and I4
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Invalid comparison between Unknown and I4
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Invalid comparison between Unknown and I4
if ((Object)(object)currentBoombox == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Сначала создай бумбокс через F8.");
return;
}
if (songs.Length == 0)
{
RefreshPlaylist();
if (songs.Length == 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"В папке Music нет MP3.");
return;
}
}
if (hasChannel && ((Channel)(ref channel)).hasHandle())
{
if (isPaused)
{
RESULT val = ((Channel)(ref channel)).setPaused(false);
if ((int)val == 0)
{
isPaused = false;
wasPlaying = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Музыка продолжена.");
}
return;
}
bool flag = default(bool);
RESULT val2 = ((Channel)(ref channel)).isPlaying(ref flag);
if ((int)val2 == 0 && flag)
{
RESULT val3 = ((Channel)(ref channel)).setPaused(true);
if ((int)val3 == 0)
{
isPaused = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Пауза.");
}
return;
}
}
PlayCurrentSong(0u, startPaused: false);
}
private unsafe void PlayCurrentSong(uint startPositionMs, bool startPaused)
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Invalid comparison between Unknown and I4
//IL_00b0: 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)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Invalid comparison between Unknown and I4
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Invalid comparison between Unknown and I4
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Invalid comparison between Unknown and I4
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Invalid comparison between Unknown and I4
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)currentBoombox == (Object)null || songs.Length == 0)
{
return;
}
StopMusic();
string text = songs[currentSong];
((BaseUnityPlugin)this).Logger.LogInfo((object)("Открываем MP3: " + Path.GetFileName(text)));
try
{
System coreSystem = RuntimeManager.CoreSystem;
RESULT val = ((System)(ref coreSystem)).createSound(text, (MODE)2097297, ref sound);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Не удалось открыть MP3: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
return;
}
hasSound = true;
ChannelGroup val2 = default(ChannelGroup);
val = ((System)(ref coreSystem)).getMasterChannelGroup(ref val2);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Ошибка звуковой группы: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
StopMusic();
return;
}
val = ((System)(ref coreSystem)).playSound(sound, val2, true, ref channel);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Ошибка запуска MP3: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
StopMusic();
return;
}
hasChannel = true;
((Channel)(ref channel)).setVolume(volume);
((Channel)(ref channel)).set3DMinMaxDistance(2f, 25f);
val = ((Channel)(ref channel)).set3DDopplerLevel(0f);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Не удалось отключить Доплер: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
}
UpdateSoundPosition();
if (startPositionMs != 0)
{
uint num = default(uint);
val = ((Sound)(ref sound)).getLength(ref num, (TIMEUNIT)1);
if ((int)val == 0 && num != 0)
{
uint num2 = Math.Min(startPositionMs, num - 1);
((Channel)(ref channel)).setPosition(num2, (TIMEUNIT)1);
}
}
val = ((Channel)(ref channel)).setPaused(startPaused);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Не удалось настроить паузу: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
StopMusic();
return;
}
isPaused = startPaused;
wasPlaying = !startPaused;
nextEndCheck = Time.time + 2f;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Сейчас играет: " + Path.GetFileName(text)));
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Ошибка FMOD: " + ex));
StopMusic();
}
}
private void UpdateSoundPosition()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: 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)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Invalid comparison between Unknown and I4
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Invalid comparison between Unknown and I4
if (!((Object)(object)currentBoombox == (Object)null) && hasChannel && ((Channel)(ref channel)).hasHandle())
{
Vector3 position = currentBoombox.transform.position;
VECTOR val = new VECTOR
{
x = position.x,
y = position.y,
z = position.z
};
VECTOR val2 = new VECTOR
{
x = 0f,
y = 0f,
z = 0f
};
RESULT val3 = ((Channel)(ref channel)).set3DAttributes(ref val, ref val2);
if ((int)val3 > 0 && (int)val3 == 30)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"FMOD-канал стал недействительным.");
StopMusic();
}
}
}
private unsafe void CheckSongEnd()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Invalid comparison between Unknown and I4
if (hasChannel && ((Channel)(ref channel)).hasHandle() && !isPaused && wasPlaying && !(Time.time < nextEndCheck))
{
bool flag = default(bool);
RESULT val = ((Channel)(ref channel)).isPlaying(ref flag);
if ((int)val > 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("FMOD-канал недоступен: " + ((object)(*(RESULT*)(&val))/*cast due to .constrained prefix*/).ToString()));
StopMusic();
}
else if (!flag)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Песня закончилась.");
NextSong();
}
}
}
private void NextSong()
{
if (!((Object)(object)currentBoombox == (Object)null))
{
if (songs.Length == 0)
{
RefreshPlaylist();
}
if (songs.Length != 0)
{
currentSong = (currentSong + 1) % songs.Length;
PlayCurrentSong(0u, startPaused: false);
}
}
}
private void PreviousSong()
{
if (!((Object)(object)currentBoombox == (Object)null))
{
if (songs.Length == 0)
{
RefreshPlaylist();
}
if (songs.Length != 0)
{
currentSong = (currentSong - 1 + songs.Length) % songs.Length;
PlayCurrentSong(0u, startPaused: false);
}
}
}
private void ChangeVolume(float amount)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
volume = Mathf.Clamp01(volume + amount);
if (hasChannel && ((Channel)(ref channel)).hasHandle())
{
((Channel)(ref channel)).setVolume(volume);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Громкость: " + Mathf.RoundToInt(volume * 100f) + "%"));
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (sceneCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(sceneCoroutine);
}
sceneCoroutine = ((MonoBehaviour)this).StartCoroutine(RestoreAfterSceneChange());
}
private IEnumerator RestoreAfterSceneChange()
{
changingScene = true;
bool resumeMusic = false;
bool resumePaused = false;
uint savedPositionMs = 0u;
if (hasChannel && ((Channel)(ref channel)).hasHandle())
{
bool playing = default(bool);
RESULT status = ((Channel)(ref channel)).isPlaying(ref playing);
resumeMusic = isPaused || ((int)status == 0 && playing);
resumePaused = isPaused;
if (resumeMusic)
{
((Channel)(ref channel)).getPosition(ref savedPositionMs, (TIMEUNIT)1);
}
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Смена локации. Переподключаем звук.");
StopMusic();
yield return (object)new WaitForSecondsRealtime(0.5f);
currentBoombox = null;
boomboxPlugin = null;
float deadline = Time.realtimeSinceStartup + 5f;
while ((Object)(object)currentBoombox == (Object)null && Time.realtimeSinceStartup < deadline)
{
currentBoombox = GetPluginBoombox();
if ((Object)(object)currentBoombox == (Object)null)
{
yield return (object)new WaitForSecondsRealtime(0.2f);
}
}
changingScene = false;
sceneCoroutine = null;
if ((Object)(object)currentBoombox == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"В новой локации бумбокс не найден. Создай его через F8.");
yield break;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Бумбокс найден в новой локации.");
if (resumeMusic)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Восстанавливаем песню с позиции " + (float)savedPositionMs / 1000f + " секунд."));
PlayCurrentSong(savedPositionMs, resumePaused);
}
}
private void StopMusic()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
wasPlaying = false;
isPaused = false;
if (hasChannel)
{
if (((Channel)(ref channel)).hasHandle())
{
((Channel)(ref channel)).stop();
}
hasChannel = false;
((Channel)(ref channel)).clearHandle();
}
if (hasSound)
{
if (((Sound)(ref sound)).hasHandle())
{
((Sound)(ref sound)).release();
}
hasSound = false;
((Sound)(ref sound)).clearHandle();
}
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnSceneChanged;
if (sceneCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(sceneCoroutine);
}
StopMusic();
}
}
[BepInPlugin("eva.customboombox", "Custom Boombox", "1.5.0")]
public class CustomBoombox : BaseUnityPlugin
{
private GameObject boomboxPrefab;
private GameObject activeBoombox;
private AssetBundle bundle;
private Rigidbody boomboxRb;
private Collider[] boomboxColliders;
private bool isHolding = false;
private float pickupDistance = 3f;
private float holdingDistance = 0.95f;
private float holdingHeight = 0.35f;
private float holdingTilt = 0f;
private Transform handTransform;
private Vector3 initialHandLocalPosition;
private bool handPositionInitialized = false;
private readonly BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private void Awake()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom Boombox 1.5.0 запущен!");
try
{
string directoryName = Path.GetDirectoryName(typeof(CustomBoombox).Assembly.Location);
string text = Path.Combine(directoryName, "customboombox");
bundle = AssetBundle.LoadFromFile(text);
if ((Object)(object)bundle == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"Не удалось загрузить customboombox.");
return;
}
GameObject[] array = bundle.LoadAllAssets<GameObject>();
if (array.Length == 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)"В AssetBundle нет моделей.");
return;
}
boomboxPrefab = array[0];
((BaseUnityPlugin)this).Logger.LogInfo((object)("Модель загружена: " + ((Object)boomboxPrefab).name));
((BaseUnityPlugin)this).Logger.LogInfo((object)"F8 — создать бумбокс.");
((BaseUnityPlugin)this).Logger.LogInfo((object)"E — поднять или положить бумбокс.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)ex);
}
}
private void Update()
{
if (Keyboard.current != null)
{
if (((ButtonControl)Keyboard.current.f8Key).wasPressedThisFrame)
{
SpawnBoombox();
}
if (((ButtonControl)Keyboard.current.eKey).wasPressedThisFrame)
{
TogglePickup();
}
}
}
private void LateUpdate()
{
if (isHolding)
{
UpdateHeldPosition();
}
}
private void SpawnBoombox()
{
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)boomboxPrefab == (Object)null)
{
return;
}
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Камера не найдена.");
return;
}
if ((Object)(object)activeBoombox != (Object)null)
{
Object.Destroy((Object)(object)activeBoombox);
}
isHolding = false;
boomboxRb = null;
boomboxColliders = null;
handTransform = null;
handPositionInitialized = false;
Vector3 val = ((Component)main).transform.position + ((Component)main).transform.forward * 2f;
activeBoombox = Object.Instantiate<GameObject>(boomboxPrefab, val, Quaternion.identity);
((Object)activeBoombox).name = "CustomBoombox";
ApplyLitMaterials(activeBoombox);
boomboxRb = activeBoombox.GetComponent<Rigidbody>();
if ((Object)(object)boomboxRb == (Object)null)
{
boomboxRb = activeBoombox.AddComponent<Rigidbody>();
}
boomboxRb.mass = 1f;
boomboxRb.useGravity = true;
boomboxRb.isKinematic = false;
boomboxColliders = activeBoombox.GetComponentsInChildren<Collider>(true);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Бумбокс создан!");
}
private void TogglePickup()
{
if (!((Object)(object)activeBoombox == (Object)null))
{
if (isHolding)
{
DropBoombox();
}
else
{
TryPickupBoombox();
}
}
}
private void TryPickupBoombox()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
Camera main = Camera.main;
RaycastHit val = default(RaycastHit);
if ((Object)(object)main == (Object)null || !Physics.Raycast(((Component)main).transform.position, ((Component)main).transform.forward, ref val, pickupDistance, -5, (QueryTriggerInteraction)2))
{
return;
}
Transform transform = ((Component)((RaycastHit)(ref val)).collider).transform;
if ((Object)(object)transform != (Object)(object)activeBoombox.transform && !transform.IsChildOf(activeBoombox.transform))
{
return;
}
isHolding = true;
if ((Object)(object)boomboxRb != (Object)null)
{
boomboxRb.linearVelocity = Vector3.zero;
boomboxRb.angularVelocity = Vector3.zero;
boomboxRb.useGravity = false;
boomboxRb.isKinematic = true;
}
if (boomboxColliders != null)
{
Collider[] array = boomboxColliders;
foreach (Collider val2 in array)
{
if ((Object)(object)val2 != (Object)null)
{
val2.enabled = false;
}
}
}
FindHandTransform();
handPositionInitialized = false;
UpdateHeldPosition();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Бумбокс поднят!");
}
private void FindHandTransform()
{
handTransform = null;
PlayerInventory val = null;
if ((Object)(object)NetworkClient.localPlayer != (Object)null)
{
val = ((Component)NetworkClient.localPlayer).GetComponentInChildren<PlayerInventory>(true);
if ((Object)(object)val == (Object)null)
{
val = ((Component)NetworkClient.localPlayer).GetComponentInParent<PlayerInventory>();
}
}
if ((Object)(object)val == (Object)null)
{
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
val = ((Component)main).GetComponentInParent<PlayerInventory>();
}
}
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Инвентарь не найден. Используем прежнее движение бумбокса.");
return;
}
FieldInfo field = typeof(PlayerInventory).GetField("handTransform", flags);
if (field != null)
{
ref Transform reference = ref handTransform;
object? value = field.GetValue(val);
reference = (Transform)((value is Transform) ? value : null);
}
if ((Object)(object)handTransform != (Object)null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("HandTransform найден: " + ((Object)handTransform).name));
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"HandTransform не найден. Используем прежнее движение.");
}
}
private void UpdateHeldPosition()
{
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
if (!isHolding || (Object)(object)activeBoombox == (Object)null)
{
return;
}
Camera main = Camera.main;
if ((Object)(object)main == (Object)null)
{
return;
}
Transform transform = ((Component)main).transform;
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(0f, 0f - holdingHeight, holdingDistance);
if ((Object)(object)handTransform != (Object)null)
{
Vector3 val2 = transform.InverseTransformPoint(handTransform.position);
if (!handPositionInitialized)
{
initialHandLocalPosition = val2;
handPositionInitialized = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Движение HandTransform подключено!");
}
Vector3 val3 = val2 - initialHandLocalPosition;
val += val3;
}
activeBoombox.transform.position = transform.TransformPoint(val);
activeBoombox.transform.rotation = Quaternion.Euler(holdingTilt, transform.eulerAngles.y, 0f);
}
private void DropBoombox()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)activeBoombox == (Object)null)
{
return;
}
isHolding = false;
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
activeBoombox.transform.position = ((Component)main).transform.position + ((Component)main).transform.forward * 1.5f - ((Component)main).transform.up * 0.4f;
}
if ((Object)(object)boomboxRb != (Object)null)
{
boomboxRb.isKinematic = false;
boomboxRb.useGravity = true;
boomboxRb.linearVelocity = Vector3.zero;
boomboxRb.angularVelocity = Vector3.zero;
}
if (boomboxColliders != null)
{
Collider[] array = boomboxColliders;
foreach (Collider val in array)
{
if ((Object)(object)val != (Object)null)
{
val.enabled = true;
}
}
}
handTransform = null;
handPositionInitialized = false;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Бумбокс положен!");
}
private void ApplyLitMaterials(GameObject boombox)
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Expected O, but got Unknown
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
Shader val = Shader.Find("Universal Render Pipeline/Lit");
if ((Object)(object)val == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"URP/Lit не найден.");
return;
}
Renderer[] componentsInChildren = boombox.GetComponentsInChildren<Renderer>(true);
Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
Renderer[] array = componentsInChildren;
foreach (Renderer val2 in array)
{
Material[] sharedMaterials = val2.sharedMaterials;
for (int j = 0; j < sharedMaterials.Length; j++)
{
Material val3 = sharedMaterials[j];
if ((Object)(object)val3 == (Object)null)
{
continue;
}
if (!dictionary.TryGetValue(val3, out var value))
{
Color val4 = Color.white;
if (val3.HasProperty("_BaseColor"))
{
val4 = val3.GetColor("_BaseColor");
}
else if (val3.HasProperty("_Color"))
{
val4 = val3.GetColor("_Color");
}
value = new Material(val);
((Object)value).name = ((Object)val3).name + "_URP_Lit";
value.SetColor("_BaseColor", val4);
value.SetFloat("_Metallic", 0f);
value.SetFloat("_Smoothness", 0.35f);
dictionary.Add(val3, value);
}
sharedMaterials[j] = value;
}
val2.sharedMaterials = sharedMaterials;
}
((BaseUnityPlugin)this).Logger.LogInfo((object)("Материалы URP/Lit применены: " + dictionary.Count));
}
}