Decompiled source of LTOWLethalCompanyBoomboxMod v1.2.0

LTOWLethalCompanyBoomboxMod.dll

Decompiled 4 days ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[CreateAssetMenu(menuName = "LCLethalCompanyBoomboxMod/AllAssets", order = 0)]
internal class AllAssets : ScriptableObject
{
	[Header("Prefabs")]
	public GameObject boomboxPrefab;

	public GameObject musicLoaderPrefab;

	[Space(3f)]
	[Header("DEBUG")]
	public bool debugRemoveOtherLoot;
}
public class BoomboxItem : NetworkBehaviour, IHeldObjectUsable
{
	private static ManualLogSource Logger;

	[Space(3f)]
	[Header("Music")]
	public bool playingMusic;

	public AudioSource audioSource;

	public List<AudioClip> clipsMusic = new List<AudioClip>();

	public AudioClip[] clipsStop;

	public AudioClip discoSong;

	private Random musicRandomizer;

	private static int boxesSpawned;

	[Space(3f)]
	[Header("Custom")]
	public PickUppable pickUpScript;

	public GroundDetectable detectableScript;

	public float cooldown;

	private float cooldownLeft;

	public float noiseInterval;

	private float noiseIntervalLeft;

	public string useString;

	[Space(3f)]
	[Header("Battery")]
	public bool useBattery;

	private bool batteryEmpty;

	public int batteryLifetime;

	public float batteryTimer;

	private float lastPitchShiftPercentage;

	public void Start()
	{
		SetBoxesSpawned(boxesSpawned + 1);
		SetRandomizer();
		if (((NetworkBehaviour)this).IsServer)
		{
			bool value = Configs.boomboxWormAudible.Value;
			float serverInterval = Configs.boomboxNoiseInterval.Value;
			bool value2 = Configs.boomboxBattery.Value;
			int value3 = Configs.batteryTimer.Value;
			int value4 = Configs.boomboxFuel.Value;
			int value5 = Configs.boomboxChomps.Value;
			SetValuesLocal(value, serverInterval, value2, value3, value4, value5);
			SyncHostValues_ClientRPC(value, serverInterval, value2, value3, value4, value5);
		}
	}

	private void Update()
	{
		if (cooldownLeft >= 0f)
		{
			cooldownLeft -= Time.deltaTime;
		}
		if (!playingMusic)
		{
			return;
		}
		if (noiseIntervalLeft > 0f)
		{
			noiseIntervalLeft -= Time.deltaTime;
		}
		else
		{
			PingGroundDetectable();
			noiseIntervalLeft = noiseInterval;
		}
		if (!useBattery)
		{
			return;
		}
		if (batteryTimer <= 0f)
		{
			if (((NetworkBehaviour)this).IsServer)
			{
				OnUse(sync: true, isEmptyBatteryUse: true);
			}
			return;
		}
		float num = batteryTimer / (float)batteryLifetime;
		if (num < 0.05f)
		{
			audioSource.pitch = 1f - (0.05f - num) * 4f;
			if (Mathf.Abs(lastPitchShiftPercentage - audioSource.pitch) > 0.01f)
			{
				TogglePitchOnDummies(audioSource.pitch);
				lastPitchShiftPercentage = audioSource.pitch;
			}
		}
		batteryTimer -= Time.deltaTime;
	}

	public void OnUse(bool sync = false, bool isEmptyBatteryUse = false)
	{
		if (!useBattery || !batteryEmpty)
		{
			ToggleMusic(fromLocalOwner: true, isEmptyBatteryUse);
			if (sync)
			{
				UseNonLocal_ServerRPC(Plugin.GetLocalPlayerNetworkId(), isEmptyBatteryUse);
			}
		}
	}

	private void ToggleMusic(bool fromLocalOwner = true, bool setBatteryEmpty = false)
	{
		if (!(cooldownLeft > 0f))
		{
			cooldownLeft = cooldown;
			if (!fromLocalOwner)
			{
				cooldownLeft /= 2f;
			}
			Logger.LogDebug((object)$"#{((NetworkBehaviour)this).NetworkObjectId} ToggleMusic(): set {playingMusic} to {!playingMusic}");
			if (playingMusic)
			{
				audioSource.Stop();
				audioSource.PlayOneShot(clipsStop[Random.Range(0, clipsStop.Length)]);
				playingMusic = false;
			}
			else
			{
				audioSource.clip = clipsMusic[musicRandomizer.Next(0, clipsMusic.Count)];
				audioSource.Play();
				playingMusic = true;
				Logger.LogDebug((object)$"playing: {audioSource.clip}");
			}
			ToggleMusicOnPlayerDummies(toggleHeld: true, setBatteryEmpty);
			if (setBatteryEmpty)
			{
				batteryEmpty = true;
				batteryTimer = 0f;
				Logger.LogDebug((object)$"batteryEmpty? {batteryEmpty} // batteryTimer? {batteryTimer}");
			}
			if (useBattery && Plugin.visibleTimersCompatible && Configs.batteryVisibleTimer.Value)
			{
				ToggleVisibleTimer();
				ToggleVisibleTimerOnDummies();
			}
		}
	}

	private void SetRandomizer()
	{
		int num = 5202551;
		if (Object.op_Implicit((Object)(object)MapLayoutPrefabLoader.Singleton))
		{
			num = MapLayoutPrefabLoader.Singleton.mapLayoutIndexChosenByServer + boxesSpawned;
		}
		Logger.LogDebug((object)$"starting with randomSeed {num} (boxesSpawned: {boxesSpawned})");
		musicRandomizer = new Random(num);
	}

	public void SetVolume(float overrideTo = -1f)
	{
		if (Object.op_Implicit((Object)(object)audioSource))
		{
			float num = (float)Configs.boomboxVolume.Value / 100f;
			if (overrideTo != -1f)
			{
				num = overrideTo;
			}
			audioSource.volume = Mathf.Clamp(num, 0f, 1f);
			Logger.LogDebug((object)$"instantiated with volume {audioSource.volume}");
		}
	}

	private void SetNoiseInterval(float setTo)
	{
		noiseInterval = setTo;
		Logger.LogDebug((object)$"set noiseInterval to {noiseInterval}");
	}

	private void SetBattery(bool setUseTo, int setLifetimeTo)
	{
		useBattery = setUseTo;
		batteryLifetime = setLifetimeTo;
		batteryTimer = batteryLifetime;
		Logger.LogDebug((object)$"battery has been set to: useBattery = {useBattery} && batteryLifetime = {batteryLifetime} && batteryTimer = {batteryTimer}");
	}

	private void SetFuelValue(int setTo)
	{
		pickUpScript.fuelValue = setTo;
		pickUpScript.cannotBurnInFurnace = pickUpScript.fuelValue <= 0;
		Logger.LogDebug((object)$"set pickUpScript.fuelValue to {pickUpScript.fuelValue} and pickUpScript.cannotBurnInFurnace to {pickUpScript.cannotBurnInFurnace}");
	}

	private void SetNumberOfChompsToEat(int setTo)
	{
		pickUpScript.numberOfChompsToEat = setTo;
		Logger.LogDebug((object)$"set pickUpScript.numberOfChompsToEat to {pickUpScript.numberOfChompsToEat}");
	}

	public void SetSecretSong()
	{
		if (Configs.secretDiscoSong.Value)
		{
			clipsMusic.Add(discoSong);
		}
	}

	public void RequestStatus(DummyBoombox dummyScript)
	{
		if (!Object.op_Implicit((Object)(object)dummyScript) || !Object.op_Implicit((Object)(object)dummyScript.audioSource))
		{
			Logger.LogDebug((object)$"RequestStatus sent to #{((NetworkBehaviour)this).NetworkObjectId} with no dummy");
		}
		else if (playingMusic)
		{
			dummyScript.audioSource.clip = audioSource.clip;
			dummyScript.audioSource.time = audioSource.time;
			dummyScript.audioSource.pitch = audioSource.pitch;
			dummyScript.audioSource.Play();
		}
		else
		{
			dummyScript.audioSource.clip = null;
			dummyScript.audioSource.time = 0f;
			dummyScript.audioSource.pitch = 1f;
			dummyScript.audioSource.Stop();
		}
	}

	private void ToggleMusicOnPlayerDummies(bool toggleHeld = true, bool toggleEquipped = false)
	{
		if (!Object.op_Implicit((Object)(object)pickUpScript) || pickUpScript.playerObjectIDWhoisHoldingUs == 1000000 || !Object.op_Implicit((Object)(object)NetworkManager.Singleton))
		{
			return;
		}
		PlayerGrabber component = ((Component)NetworkManager.Singleton.SpawnManager.SpawnedObjects[pickUpScript.playerObjectIDWhoisHoldingUs]).gameObject.GetComponent<PlayerGrabber>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return;
		}
		GameObject heldDummyObject = component.GetHeldDummyObject();
		if (Object.op_Implicit((Object)(object)heldDummyObject) && toggleHeld)
		{
			DummyBoombox component2 = heldDummyObject.GetComponent<DummyBoombox>();
			if (Object.op_Implicit((Object)(object)component2) && (Object)(object)component2.mainScript == (Object)(object)this)
			{
				component2.ToggleMusicOnDummy(playingMusic);
			}
		}
		GameObject spawnedEquipmentOnOurBodyDummy = component.GetSpawnedEquipmentOnOurBodyDummy();
		if (Object.op_Implicit((Object)(object)spawnedEquipmentOnOurBodyDummy) && toggleEquipped)
		{
			DummyBoombox component3 = spawnedEquipmentOnOurBodyDummy.GetComponent<DummyBoombox>();
			if (Object.op_Implicit((Object)(object)component3) && (Object)(object)component3.mainScript == (Object)(object)this)
			{
				component3.ToggleMusicOnDummy(playingMusic);
			}
		}
	}

	private void TogglePitchOnDummies(float mainPitch, bool toggleHeld = true, bool toggleEquipped = true)
	{
		if (!Object.op_Implicit((Object)(object)pickUpScript) || pickUpScript.playerObjectIDWhoisHoldingUs == 1000000 || !Object.op_Implicit((Object)(object)NetworkManager.Singleton))
		{
			return;
		}
		PlayerGrabber component = ((Component)NetworkManager.Singleton.SpawnManager.SpawnedObjects[pickUpScript.playerObjectIDWhoisHoldingUs]).gameObject.GetComponent<PlayerGrabber>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return;
		}
		GameObject heldDummyObject = component.GetHeldDummyObject();
		if (Object.op_Implicit((Object)(object)heldDummyObject) && toggleHeld)
		{
			DummyBoombox component2 = heldDummyObject.GetComponent<DummyBoombox>();
			if (Object.op_Implicit((Object)(object)component2) && (Object)(object)component2.mainScript == (Object)(object)this)
			{
				component2.audioSource.pitch = mainPitch;
			}
		}
		GameObject spawnedEquipmentOnOurBodyDummy = component.GetSpawnedEquipmentOnOurBodyDummy();
		if (Object.op_Implicit((Object)(object)spawnedEquipmentOnOurBodyDummy) && toggleEquipped)
		{
			DummyBoombox component3 = spawnedEquipmentOnOurBodyDummy.GetComponent<DummyBoombox>();
			if (Object.op_Implicit((Object)(object)component3) && (Object)(object)component3.mainScript == (Object)(object)this)
			{
				component3.audioSource.pitch = mainPitch;
			}
		}
	}

	private void PingGroundDetectable()
	{
		if (!Object.op_Implicit((Object)(object)detectableScript) || !Object.op_Implicit((Object)(object)pickUpScript))
		{
			Logger.LogWarning((object)$"no detectableScript ({!Object.op_Implicit((Object)(object)detectableScript)}) or pickUpScript ({!Object.op_Implicit((Object)(object)pickUpScript)}) on #{((NetworkBehaviour)this).NetworkObjectId}");
		}
		else if (detectableScript.isTouchingGround)
		{
			if (Object.op_Implicit((Object)(object)pickUpScript) && !pickUpScript.isInteractable)
			{
				Logger.LogDebug((object)"skipping PingGroundDetectable due to likely not being on ground");
				return;
			}
			((MonoBehaviour)this).StartCoroutine(WakeUpRigidBodyTemporarily());
			detectableScript.ResetVisability(0f, true, false);
		}
	}

	private IEnumerator WakeUpRigidBodyTemporarily()
	{
		if (pickUpScript.rb.IsSleeping())
		{
			float startingThreshold = pickUpScript.rb.sleepThreshold;
			bool startingKinematic = pickUpScript.rb.isKinematic;
			pickUpScript.rb.sleepThreshold = -1f;
			pickUpScript.rb.isKinematic = false;
			pickUpScript.rb.WakeUp();
			yield return (object)new WaitForSeconds(0.2f);
			pickUpScript.rb.sleepThreshold = startingThreshold;
			pickUpScript.rb.isKinematic = startingKinematic;
			Logger.LogDebug((object)$"pinging groundDetectable on #{((NetworkBehaviour)this).NetworkObjectId} // reset to sleepThreshold: {pickUpScript.rb.sleepThreshold} & isKinematic: {pickUpScript.rb.isKinematic}");
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void UseNonLocal_ServerRPC(int ownerNetworkId, bool isEmptyBatteryUse)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3079773884u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, ownerNetworkId);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isEmptyBatteryUse, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3079773884u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				UseNonLocal_ClientRPC(ownerNetworkId, isEmptyBatteryUse);
			}
		}
	}

	[ClientRpc]
	private void UseNonLocal_ClientRPC(int ownerNetworkId, bool isEmptyBatteryUse)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1376193008u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, ownerNetworkId);
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isEmptyBatteryUse, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1376193008u, val, (RpcDelivery)0);
		}
		if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (Plugin.GetLocalPlayerNetworkId() != ownerNetworkId)
			{
				ToggleMusic(fromLocalOwner: false, isEmptyBatteryUse);
			}
		}
	}

	[ClientRpc]
	private void SyncHostValues_ClientRPC(bool serverWormAudible, float serverInterval, bool serverUseBattery, int serverBatteryLifetime, int serverFuelValue, int serverWormChomps)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: 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_0139: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(73812417u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref serverWormAudible, default(ForPrimitives));
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref serverInterval, default(ForPrimitives));
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref serverUseBattery, default(ForPrimitives));
			BytePacker.WriteValueBitPacked(val2, serverBatteryLifetime);
			BytePacker.WriteValueBitPacked(val2, serverFuelValue);
			BytePacker.WriteValueBitPacked(val2, serverWormChomps);
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 73812417u, val, (RpcDelivery)0);
		}
		if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			base.__rpc_exec_stage = (__RpcExecStage)0;
			if (!((NetworkBehaviour)this).IsServer)
			{
				SetValuesLocal(serverWormAudible, serverInterval, serverUseBattery, serverBatteryLifetime, serverFuelValue, serverWormChomps);
			}
		}
	}

	private void SetValuesLocal(bool serverWormAudible, float serverInterval, bool serverUseBattery, int serverBatteryLifetime, int serverFuelValue, int serverWormChomps)
	{
		SetNoiseInterval(serverInterval);
		SetBattery(serverUseBattery, serverBatteryLifetime);
		SetFuelValue(serverFuelValue);
		SetNumberOfChompsToEat(serverWormChomps);
		if (!serverWormAudible && Object.op_Implicit((Object)(object)GameManager.Singleton) && Object.op_Implicit((Object)(object)GameManager.Singleton.localWormScript))
		{
			Logger.LogDebug((object)$"spawned with serverWormAudible {serverWormAudible} and localWormScript {GameManager.Singleton.localWormScript}");
			SetVolume(0f);
		}
	}

	void IHeldObjectUsable.OnUse(ulong _clientIDWhoUsedIt, bool serverside)
	{
		Logger.LogDebug((object)"OnUse()");
		OnUse(sync: true);
	}

	void IHeldObjectUsable.UseCancelled_Client(ulong _clientIDWhoUsedIt)
	{
	}

	void IHeldObjectUsable.Use_LocalOnly()
	{
		Logger.LogDebug((object)"Use_LocalOnly()");
		OnUse(sync: true);
	}

	public void OnPickUpValidated(GameObject fromDummy)
	{
		Logger.LogDebug((object)$"{((Object)this).name} #{((NetworkBehaviour)this).NetworkObjectId}: OnPickUpValidated()");
		if (!batteryEmpty && Object.op_Implicit((Object)(object)HudManager.Singleton) && Plugin.ObjectHeldByLocalPlayer(fromDummy))
		{
			HudManager.Singleton.DisplayNewHeldItemHint(useString, -1f);
		}
	}

	public void AddVisibleTimer(Transform toTransform)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if (useBattery)
		{
			GameObject val = new GameObject("BoomboxTimer");
			val.transform.SetParent(toTransform, false);
			val.AddComponent<VisibleBatteryTimer>();
		}
	}

	private void ToggleVisibleTimer()
	{
		if (!useBattery || !Object.op_Implicit((Object)(object)TimersManager.Singleton))
		{
			return;
		}
		VisibleTimerBase val = null;
		foreach (VisibleTimerBase allTimer in TimersManager.Singleton.allTimers)
		{
			if (Object.op_Implicit((Object)(object)allTimer) && (Object)(object)allTimer.followObject == (Object)(object)((Component)audioSource).gameObject)
			{
				val = allTimer;
				break;
			}
		}
		if (Object.op_Implicit((Object)(object)val))
		{
			val.SetVisibility(playingMusic);
		}
	}

	private void ToggleVisibleTimerOnDummies(bool toggleHeld = true, bool toggleEquipped = true)
	{
		if (!useBattery || !Object.op_Implicit((Object)(object)pickUpScript) || pickUpScript.playerObjectIDWhoisHoldingUs == 1000000 || !Object.op_Implicit((Object)(object)NetworkManager.Singleton) || !Object.op_Implicit((Object)(object)TimersManager.Singleton))
		{
			return;
		}
		PlayerGrabber component = ((Component)NetworkManager.Singleton.SpawnManager.SpawnedObjects[pickUpScript.playerObjectIDWhoisHoldingUs]).gameObject.GetComponent<PlayerGrabber>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return;
		}
		GameObject heldDummyObject = component.GetHeldDummyObject();
		if (Object.op_Implicit((Object)(object)heldDummyObject) && toggleHeld)
		{
			DummyBoombox component2 = heldDummyObject.GetComponent<DummyBoombox>();
			BasicTimer val = null;
			if (Object.op_Implicit((Object)(object)component2) && (Object)(object)component2.mainScript == (Object)(object)this)
			{
				foreach (VisibleTimerBase allTimer in TimersManager.Singleton.allTimers)
				{
					if (Object.op_Implicit((Object)(object)allTimer) && (Object)(object)allTimer.followObject == (Object)(object)((Component)component2).gameObject && allTimer is BasicTimer)
					{
						val = (BasicTimer)(object)((allTimer is BasicTimer) ? allTimer : null);
						break;
					}
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					((VisibleTimerBase)val).SetVisibility(playingMusic);
				}
			}
		}
		GameObject spawnedEquipmentOnOurBodyDummy = component.GetSpawnedEquipmentOnOurBodyDummy();
		if (!(Object.op_Implicit((Object)(object)spawnedEquipmentOnOurBodyDummy) && toggleEquipped))
		{
			return;
		}
		DummyBoombox component3 = spawnedEquipmentOnOurBodyDummy.GetComponent<DummyBoombox>();
		BasicTimer val2 = null;
		if (!Object.op_Implicit((Object)(object)component3) || !((Object)(object)component3.mainScript == (Object)(object)this))
		{
			return;
		}
		foreach (VisibleTimerBase allTimer2 in TimersManager.Singleton.allTimers)
		{
			if (Object.op_Implicit((Object)(object)allTimer2) && (Object)(object)allTimer2.followObject == (Object)(object)((Component)component3).gameObject && allTimer2 is BasicTimer)
			{
				val2 = (BasicTimer)(object)((allTimer2 is BasicTimer) ? allTimer2 : null);
				break;
			}
		}
		if (Object.op_Implicit((Object)(object)val2))
		{
			((VisibleTimerBase)val2).SetVisibility(playingMusic);
		}
	}

	public static void SetBoxesSpawned(int setTo)
	{
		Logger.LogDebug((object)$"setting boxesSpawned from {boxesSpawned} to {setTo}");
		boxesSpawned = setTo;
	}

	protected override void __initializeVariables()
	{
		((NetworkBehaviour)this).__initializeVariables();
	}

	protected override void __initializeRpcs()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		((NetworkBehaviour)this).__registerRpc(3079773884u, new RpcReceiveHandler(__rpc_handler_3079773884), "UseNonLocal_ServerRPC");
		((NetworkBehaviour)this).__registerRpc(1376193008u, new RpcReceiveHandler(__rpc_handler_1376193008), "UseNonLocal_ClientRPC");
		((NetworkBehaviour)this).__registerRpc(73812417u, new RpcReceiveHandler(__rpc_handler_73812417), "SyncHostValues_ClientRPC");
		((NetworkBehaviour)this).__initializeRpcs();
	}

	private static void __rpc_handler_3079773884(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0051: 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)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int ownerNetworkId = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref ownerNetworkId);
			bool isEmptyBatteryUse = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isEmptyBatteryUse, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((BoomboxItem)(object)target).UseNonLocal_ServerRPC(ownerNetworkId, isEmptyBatteryUse);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_1376193008(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0051: 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)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			int ownerNetworkId = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref ownerNetworkId);
			bool isEmptyBatteryUse = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isEmptyBatteryUse, default(ForPrimitives));
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((BoomboxItem)(object)target).UseNonLocal_ClientRPC(ownerNetworkId, isEmptyBatteryUse);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	private static void __rpc_handler_73812417(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: 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_0050: 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_006b: 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_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = target.NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			bool serverWormAudible = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref serverWormAudible, default(ForPrimitives));
			float serverInterval = default(float);
			((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref serverInterval, default(ForPrimitives));
			bool serverUseBattery = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref serverUseBattery, default(ForPrimitives));
			int serverBatteryLifetime = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref serverBatteryLifetime);
			int serverFuelValue = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref serverFuelValue);
			int serverWormChomps = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref serverWormChomps);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((BoomboxItem)(object)target).SyncHostValues_ClientRPC(serverWormAudible, serverInterval, serverUseBattery, serverBatteryLifetime, serverFuelValue, serverWormChomps);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}
	}

	protected internal override string __getTypeName()
	{
		return "BoomboxItem";
	}
}
internal class Configs
{
	private static ManualLogSource Logger;

	public static ConfigEntry<int> boomboxVolume;

	public static ConfigEntry<bool> boomboxWormAudible;

	public static ConfigEntry<int> boomboxNoiseInterval;

	public static ConfigEntry<int> boomboxFuel;

	public static ConfigEntry<int> boomboxChomps;

	public static ConfigEntry<bool> boomboxBattery;

	public static ConfigEntry<int> batteryTimer;

	public static ConfigEntry<bool> loadCustomMusic;

	public static ConfigEntry<bool> addOrOverwrite;

	public static ConfigEntry<string> musicFolderPath;

	public static ConfigEntry<bool> secretDiscoSong;

	public static ConfigEntry<bool> batteryVisibleTimer;

	public Configs(ConfigFile cfg)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		boomboxVolume = cfg.Bind<int>("Customization", "Boombox Volume", 75, new ConfigDescription("Set the volume of the Boombox's music.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		boomboxWormAudible = cfg.Bind<bool>("Customization", "Worm Hears Boombox", false, "Set whether or not worm-players can hear the boombox.\nLobby host's values are used.");
		boomboxNoiseInterval = cfg.Bind<int>("Customization", "Boombox Ping Interval", 4, new ConfigDescription("Set per how many seconds a boombox on the sand will ping the worm's attention.\nLobby host's values are used.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
		boomboxFuel = cfg.Bind<int>("Customization", "Boombox Train Fuel", 7, new ConfigDescription("Set how much fuel a boombox thrown into the train furnace is worth.\nLobby host's values are used.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 30), Array.Empty<object>()));
		boomboxChomps = cfg.Bind<int>("Customization", "Boombox Worm Chomps", 5, new ConfigDescription("Set how many times a boombox needs to chomped by a worm before emptying its mouth again.\nLobby host's values are used.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
		boomboxBattery = cfg.Bind<bool>("Extra", "Boombox Has Battery", true, "Set whether or not the boombox has a battery with a limited lifetime that depletes while the music is playing, so that it cannot be used indefinitely.\nLobby host's values are used.");
		batteryTimer = cfg.Bind<int>("Extra", "Battery Lifetime", 170, new ConfigDescription("If [Boombox Has Battery] is set to true, set for how long in seconds the boombox can play music before running out of battery.\nLobby host's values are used.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(30, 2400), Array.Empty<object>()));
		loadCustomMusic = cfg.Bind<bool>("Extra", "Load Custom Music", true, "If true, allows you to place songs from your computer in this mod's plugin folder and load them into the game.\nNote: Only files of type MP3, Wave, and OGG are supported.");
		addOrOverwrite = cfg.Bind<bool>("Extra", "Add Or Overwrite", true, "If [Load Custom Music] is set to true, set whether your custom music is added to the boombox's playlist (true), or tries to be the only music on the boombox (false).");
		musicFolderPath = cfg.Bind<string>("Extra", "Custom Music Folder", MusicLoader.GetFolderPath(toLoadMusic: false), "If [Load Custom Music] is set to true, load music from this folder on your computer, as opposed to this mod's auto-generated Custom Music folder.\nFor example: C:\\Users\\[UserName]\\Music");
		secretDiscoSong = cfg.Bind<bool>("Secret", "Boombox6QuestionMark", false, "Add the secret sixth Boombox song.");
		batteryVisibleTimer = cfg.Bind<bool>("Secret", "LTOWVisibleTimersMod", true, "Display the battery's time left.");
	}

	public static void DisplayConfigs()
	{
		Logger.LogInfo((object)$"Config [Boombox Volume] is set to a value of {boomboxVolume.Value}");
		if (boomboxWormAudible.Value)
		{
			Logger.LogInfo((object)"Config [Worm Hears Boombox] is set to TRUE. Worm players will be able to hear the boombox, even if they cannot see it.");
		}
		else
		{
			Logger.LogInfo((object)"Config [Worm Hears Boombox] is set to FALSE. Worm players will not be able to hear the boombox's music.");
		}
		Logger.LogInfo((object)$"Config [Boombox Ping Interval] is set to a value of {boomboxNoiseInterval.Value}");
		Logger.LogInfo((object)$"Config [Boombox Train Value] is set to a value of {boomboxFuel.Value}");
		Logger.LogInfo((object)$"Config [Boombox Worm Chomps] is set to a value of {boomboxChomps.Value}");
		if (boomboxBattery.Value)
		{
			Logger.LogInfo((object)"Config [Boombox Has Battery] is set to TRUE. The boombox will only be able to play music and ping the worm for a limited amount of time before running out of battery.");
			Logger.LogInfo((object)$"Config [Battery Lifetime] is set to a value of {batteryTimer.Value}");
		}
		else
		{
			Logger.LogInfo((object)"Config [Boombox Has Battery] is set to FALSE. The boombox can play its music and ping the worm indefinitely.");
		}
		if (loadCustomMusic.Value)
		{
			Logger.LogInfo((object)"Config [Load Custom Music] is set to TRUE. The boombox will load music you drop into this mod's plugin folder.");
			if (addOrOverwrite.Value)
			{
				Logger.LogInfo((object)"Config [Add Or Overwrite] is set to TRUE. Your custom music will be added to the boombox's playlist.");
			}
			else
			{
				Logger.LogInfo((object)"Config [Add Or Overwrite] is set to FALSE. Your custom music will try to be the only music on the boombox.");
			}
			if (Plugin.PathValid(musicFolderPath.Value))
			{
				Logger.LogInfo((object)("Config [Custom Music Folder] is set to: \"" + musicFolderPath.Value + "\""));
			}
			else
			{
				Logger.LogWarning((object)("Config [Custom Music Folder] is set to an invalid value of \"" + musicFolderPath.Value + "\". Resetting and using auto-generated folder."));
				musicFolderPath.Value = MusicLoader.GetFolderPath(toLoadMusic: false);
			}
		}
		else
		{
			Logger.LogInfo((object)"Config [Load Custom Music] is set to FALSE. The boombox will only load Lethal Company's built-in music.");
		}
		if (secretDiscoSong.Value)
		{
			Logger.LogDebug((object)"Config [Boombox6QuestionMark] is set to TRUE. Loading secrets...");
		}
		if (batteryVisibleTimer.Value && Plugin.visibleTimersCompatible)
		{
			Logger.LogDebug((object)"Config [LTOWVisibleTimersMod] is set to TRUE. Now where's the battery slot on this thing?");
		}
	}
}
public class DummyBoombox : MonoBehaviour
{
	private static ManualLogSource Logger;

	public BoomboxItem mainScript;

	public AudioSource audioSource;

	private void Start()
	{
		ManualLogSource logger = Logger;
		string name = ((Object)this).name;
		Transform parent = ((Component)this).transform.parent;
		logger.LogDebug((object)$"Start() on {name} under parent {((parent != null) ? parent.parent : null)}");
		if (ValidDummy())
		{
			mainScript.RequestStatus(this);
			if (mainScript.useBattery && Plugin.visibleTimersCompatible && Configs.batteryVisibleTimer.Value)
			{
				mainScript.AddVisibleTimer(((Component)this).transform);
			}
		}
	}

	public void ToggleMusicOnDummy(bool newMusicPlaying)
	{
		if (ValidDummy())
		{
			if (!newMusicPlaying)
			{
				audioSource.Stop();
				audioSource.PlayOneShot(mainScript.clipsStop[Random.Range(0, mainScript.clipsStop.Length)]);
			}
			else
			{
				audioSource.clip = mainScript.audioSource.clip;
				audioSource.time = 0f;
				audioSource.Play();
			}
		}
	}

	private bool ValidDummy()
	{
		if (!Object.op_Implicit((Object)(object)mainScript))
		{
			Logger.LogError((object)"dummy spawned without mainScript");
			return false;
		}
		if (!Object.op_Implicit((Object)(object)audioSource))
		{
			Logger.LogError((object)"dummy spawned without audioSource");
			return false;
		}
		return true;
	}

	public void OnPickUpValidated()
	{
		mainScript.OnPickUpValidated(((Component)this).gameObject);
	}
}
internal class HarmonyPatches : MonoBehaviour
{
	[HarmonyPatch(typeof(NetworkManager))]
	public class LCBoomboxPatch_NetworkManager
	{
		[HarmonyPostfix]
		[HarmonyPatch("SetSingleton")]
		public static void SetSingletonPostfix()
		{
			if (!Object.op_Implicit((Object)(object)NetworkManager.Singleton))
			{
				Logger.LogError((object)"NetworkManager.Singleton null, cannot add network prefabs");
				return;
			}
			Logger.LogDebug((object)$"SetSingleton(), on {((Component)NetworkManager.Singleton).gameObject}");
			GameObject boomboxPrefab = Plugin.allAssets.boomboxPrefab;
			if (Object.op_Implicit((Object)(object)boomboxPrefab) && Object.op_Implicit((Object)(object)boomboxPrefab.GetComponent<NetworkObject>()))
			{
				NetworkManager.Singleton.AddNetworkPrefab(boomboxPrefab);
				Logger.LogDebug((object)$"registered network prefab {boomboxPrefab}");
			}
		}
	}

	[HarmonyPatch(typeof(LocTableHelpers))]
	public class LCBoomboxPatch_LocTableHelpers
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetStringFromTable")]
		public static void GetStringFromTablePostfix(string _locTableKey, ref string __result)
		{
			if (_locTableKey == "LCBoombox")
			{
				__result = "Boombox";
			}
		}
	}

	[HarmonyPatch(typeof(LootManager))]
	public class LCBoomboxPatch_LootManager
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void AwakePostfix(LootManager __instance)
		{
			bool value = Configs.loadCustomMusic.Value;
			if (value)
			{
				((Component)__instance).gameObject.AddComponent<MusicLoader>();
			}
			bool debugRemoveOtherLoot = Plugin.allAssets.debugRemoveOtherLoot;
			Logger.LogDebug((object)$"debugRemoveOtherLoot = {debugRemoveOtherLoot}");
			if (debugRemoveOtherLoot)
			{
				Logger.LogWarning((object)$"CLEARING {__instance.standardEquipmentPrefabs.Count} OTHER STANDARD EQUIPMENT PREFABS!");
				__instance.standardEquipmentPrefabs.Clear();
			}
			GameObject boomboxPrefab = Plugin.allAssets.boomboxPrefab;
			if (Object.op_Implicit((Object)(object)boomboxPrefab))
			{
				__instance.standardEquipmentPrefabs.Add(boomboxPrefab);
				Logger.LogDebug((object)$"added {boomboxPrefab} to LootManager at {__instance.standardEquipmentPrefabs.Count - 1}");
				BoomboxItem component = boomboxPrefab.GetComponent<BoomboxItem>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.SetVolume();
					component.SetSecretSong();
					if (value)
					{
						MusicLoader.StartAddingCustomMusic(component);
					}
				}
			}
			BoomboxItem.SetBoxesSpawned(0);
		}
	}

	[HarmonyPatch(typeof(CheatsManager))]
	public class LCBoomboxPatch_CheatsManager
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		public static void AwakePrefix(CheatsManager __instance)
		{
			Logger.LogDebug((object)"CheatsManager.AwakePrefix()");
			if (Object.op_Implicit((Object)(object)__instance) && __instance.spawnablePrefabList != null)
			{
				Logger.LogDebug((object)$"adding {Plugin.allAssets.boomboxPrefab} to {__instance}");
				__instance.spawnablePrefabList.Add(Plugin.allAssets.boomboxPrefab);
			}
		}
	}

	private static ManualLogSource Logger;
}
public class MusicLoader : MonoBehaviour
{
	private static ManualLogSource Logger;

	public static MusicLoader Singleton;

	public static bool addedCustomMusic;

	private GameObject spawnedHudPopUp;

	private Image loadingImage;

	public static void OnPluginAwake()
	{
		SetAddedCustomMusic(setTo: false);
		Directory.CreateDirectory(GetFolderPath(toLoadMusic: false));
	}

	private void Awake()
	{
		Singleton = this;
	}

	public static void StartAddingCustomMusic(BoomboxItem boombox)
	{
		if (!addedCustomMusic && Configs.loadCustomMusic.Value && Object.op_Implicit((Object)(object)boombox) && Object.op_Implicit((Object)(object)Singleton))
		{
			Logger.LogDebug((object)("trying to add custom music to " + ((Object)boombox).name));
			Singleton.AddCustomMusicOnSingleton(boombox);
		}
	}

	private void AddCustomMusicOnSingleton(BoomboxItem boombox)
	{
		SpawnHudPopUp();
		((MonoBehaviour)this).StartCoroutine(AddCustomMusic(boombox));
	}

	private IEnumerator AddCustomMusic(BoomboxItem boombox)
	{
		SetHudPopUpVisibility(setTo: true);
		ShowMusicLoadingStatus(enableDots: true);
		SetHudPopUpFillAmount(0, 1);
		string finishedLoadingText = string.Empty;
		List<AudioClip> customMusicList = new List<AudioClip>();
		string[] allSongPaths = Directory.GetFiles(GetFolderPath(toLoadMusic: true));
		if (allSongPaths.Length == 0)
		{
			Logger.LogInfo((object)$"[Load Custom Music] is set to {Configs.loadCustomMusic.Value} but {allSongPaths.Length} files were found!");
			if (string.IsNullOrEmpty(finishedLoadingText))
			{
				SetHudPopUpFillAmount(1, 1);
				finishedLoadingText = "Custom Music folder empty";
			}
		}
		else
		{
			Logger.LogDebug((object)$"found {allSongPaths.Length} files to search");
			for (int i = 0; i < allSongPaths.Length; i++)
			{
				SetHudPopUpFillAmount(i + 1, allSongPaths.Length);
				yield return null;
				string filePath = allSongPaths[i];
				if (string.IsNullOrEmpty(filePath))
				{
					continue;
				}
				AudioType audioClipAudioType = GetAudioClipAudioType(filePath);
				if ((int)audioClipAudioType == 0)
				{
					Logger.LogWarning((object)("LoadAudioClip(" + filePath + ")\nerror 1: AudioType.UNKNOWN"));
					continue;
				}
				UnityWebRequest webRequest = UnityWebRequestMultimedia.GetAudioClip(filePath, audioClipAudioType);
				webRequest.SendWebRequest();
				while (!webRequest.isDone)
				{
					yield return null;
				}
				if (webRequest.error != null)
				{
					Logger.LogDebug((object)"");
					Logger.LogError((object)("LoadAudioClip(" + filePath + ")\nerror 2: webRequest.error\n" + webRequest.error));
				}
				else if ((int)webRequest.result == 1)
				{
					AudioClip loadedClip = DownloadHandlerAudioClip.GetContent(webRequest);
					while ((int)loadedClip.loadState == 0)
					{
						yield return null;
					}
					while ((int)loadedClip.loadState == 1)
					{
						yield return null;
					}
					if (Object.op_Implicit((Object)(object)loadedClip) && (int)loadedClip.loadState == 2)
					{
						AudioClip val = loadedClip;
						((Object)val).name = Path.GetFileName(filePath);
						Logger.LogDebug((object)$"LoadAudioClip({filePath})\nreturning AudioClip '{val}'");
						if (Object.op_Implicit((Object)(object)loadedClip))
						{
							customMusicList.Add(val);
						}
					}
					else
					{
						Logger.LogWarning((object)"error 3");
					}
				}
				else
				{
					Logger.LogError((object)("LoadAudioClip(" + filePath + ")\nerror 3"));
				}
			}
			Logger.LogDebug((object)$"adding {customMusicList.Count} songs");
		}
		if (customMusicList == null || customMusicList.Count == 0)
		{
			Logger.LogWarning((object)$"no boombox music was given to AddCustomMusicToBoombox (null? {customMusicList == null})");
			if (string.IsNullOrEmpty(finishedLoadingText))
			{
				finishedLoadingText = "Failed loading custom music!!";
			}
		}
		else
		{
			if (Configs.addOrOverwrite.Value)
			{
				boombox.clipsMusic.AddRange(customMusicList);
			}
			else
			{
				boombox.clipsMusic = customMusicList;
			}
			Logger.LogDebug((object)"successfully added music!");
			string arg = ((customMusicList.Count > 1) ? "songs" : "song");
			finishedLoadingText = $"Loaded {customMusicList.Count} custom {arg}!";
		}
		ShowMusicLoadingStatus(enableDots: false, finishedLoadingText);
		SetAddedCustomMusic(setTo: true);
		yield return (object)new WaitForSeconds(5f);
		SetHudPopUpVisibility(setTo: false);
	}

	private AudioType GetAudioClipAudioType(string filePath)
	{
		return (AudioType)(Path.GetExtension(filePath).ToLower() switch
		{
			".wav" => 20, 
			".ogg" => 14, 
			".mp3" => 13, 
			_ => 0, 
		});
	}

	private void SpawnHudPopUp()
	{
		if (!Object.op_Implicit((Object)(object)spawnedHudPopUp) && Object.op_Implicit((Object)(object)HudManager.Singleton) && Object.op_Implicit((Object)(object)HudManager.Singleton.needAtLeastOneWormPlayer_Text))
		{
			spawnedHudPopUp = Object.Instantiate<GameObject>(Plugin.allAssets.musicLoaderPrefab, HudManager.Singleton.needAtLeastOneWormPlayer_Text.transform.parent, false);
			Transform val = spawnedHudPopUp.transform.Find("LoadingImage");
			if (Object.op_Implicit((Object)(object)val))
			{
				loadingImage = ((Component)val).gameObject.GetComponent<Image>();
			}
			TextMeshProUGUI component = spawnedHudPopUp.GetComponent<TextMeshProUGUI>();
			TextMeshProUGUI component2 = HudManager.Singleton.needAtLeastOneWormPlayer_Text.GetComponent<TextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2))
			{
				((TMP_Text)component).font = ((TMP_Text)component2).font;
			}
		}
	}

	private void SetHudPopUpVisibility(bool setTo)
	{
		spawnedHudPopUp.SetActive(setTo);
	}

	private void SetHudPopUpFillAmount(int current, int max)
	{
		loadingImage.fillAmount = (float)current / (float)max;
	}

	private void ShowMusicLoadingStatus(bool enableDots, string textToPrint = null)
	{
		JoiningGameDotDotDot component = spawnedHudPopUp.GetComponent<JoiningGameDotDotDot>();
		if (Object.op_Implicit((Object)(object)component))
		{
			((Behaviour)component).enabled = enableDots;
		}
		TextMeshProUGUI component2 = spawnedHudPopUp.GetComponent<TextMeshProUGUI>();
		if (Object.op_Implicit((Object)(object)component2) && !string.IsNullOrEmpty(textToPrint))
		{
			((TMP_Text)component2).text = textToPrint;
		}
	}

	public static void SetAddedCustomMusic(bool setTo)
	{
		addedCustomMusic = setTo;
	}

	public static string GetFolderPath(bool toLoadMusic)
	{
		if (toLoadMusic && Plugin.PathValid(Configs.musicFolderPath.Value))
		{
			return Configs.musicFolderPath.Value;
		}
		return Path.Combine(Plugin.GetSaveDataFolder(), "Custom Music");
	}
}
[BepInPlugin("local.SimonTendo.LTOWLethalCompanyBoomboxMod", "LTOWLethalCompanyBoomboxMod", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Logger;

	public static AllAssets allAssets;

	public static bool visibleTimersCompatible;

	public static Configs MyConfig { get; internal set; }

	private void Awake()
	{
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		Logger = ((BaseUnityPlugin)this).Logger;
		Logger.LogInfo((object)"Plugin LTOWLethalCompanyBoomboxMod is loaded!");
		AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(GetAssemblyLocation(), "lcboomboxbundle"));
		if (!Object.op_Implicit((Object)(object)val))
		{
			Logger.LogError((object)"Failed to load AssetBundle");
			return;
		}
		allAssets = val.LoadAsset<AllAssets>("Assets/LTOWLethalCompanyBoomboxMod/ScriptableObjects/AllAssets.asset");
		if (!Object.op_Implicit((Object)(object)allAssets))
		{
			Logger.LogError((object)"Failed to load AllAssets!");
			return;
		}
		Logger.LogDebug((object)"Successfully loaded AssetBundle and AllAssets");
		SendLoggers();
		ReplaceAllMaterialShaders(val);
		MusicLoader.OnPluginAwake();
		visibleTimersCompatible = CheckForPlugin("LTOWVisibleTimersMod");
		MyConfig = new Configs(((BaseUnityPlugin)this).Config);
		new Harmony("LTOWLethalCompanyBoomboxMod").PatchAll();
		UnityNetcodePatcher();
		Configs.DisplayConfigs();
	}

	private static void SendLoggers()
	{
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		foreach (Type type in types)
		{
			FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType == typeof(ManualLogSource))
				{
					fieldInfo.SetValue(type, Logger);
				}
			}
		}
	}

	public static int GetLocalPlayerNetworkId()
	{
		if (!Object.op_Implicit((Object)(object)GameManager.Singleton) || !Object.op_Implicit((Object)(object)GameManager.Singleton.localPlayerObject))
		{
			Logger.LogError((object)$"GetLocalPlayerNetworkId failed first check | singleton? {!Object.op_Implicit((Object)(object)GameManager.Singleton)}");
			return -1;
		}
		NetworkObject component = GameManager.Singleton.localPlayerObject.GetComponent<NetworkObject>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			Logger.LogError((object)("GetLocalPlayerNetworkId failed second check for " + ((Object)GameManager.Singleton.localPlayerObject).name));
			return -1;
		}
		return (int)component.NetworkObjectId;
	}

	public static void ReplaceAllMaterialShaders(AssetBundle inAssetBundle, bool printDebug = false)
	{
		Material[] array = inAssetBundle.LoadAllAssets<Material>();
		foreach (Material val in array)
		{
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.shader) || !((Object)val.shader).name.StartsWith("Shader Graphs/"))
			{
				continue;
			}
			string name = ((Object)val.shader).name;
			if (printDebug)
			{
				Logger.LogDebug((object)("trying to replace " + name));
			}
			Shader val2 = Shader.Find(name);
			if (!Object.op_Implicit((Object)(object)val2))
			{
				if (printDebug)
				{
					Logger.LogError((object)("Failed to find Shader with name " + name));
				}
				else
				{
					Logger.LogDebug((object)("Failed to find Shader with name " + name));
				}
			}
			else if (printDebug)
			{
				Logger.LogDebug((object)$"foundShader: {val2}");
			}
			val.shader = val2;
		}
	}

	private static void UnityNetcodePatcher()
	{
		Type[] types = Assembly.GetExecutingAssembly().GetTypes();
		for (int i = 0; i < types.Length; i++)
		{
			MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
				{
					methodInfo.Invoke(null, null);
				}
			}
		}
	}

	private static bool CheckForPlugin(string pluginName, bool printDebug = true)
	{
		foreach (PluginInfo value in Chainloader.PluginInfos.Values)
		{
			if (value.Metadata.Name == pluginName)
			{
				if (printDebug)
				{
					Logger.LogDebug((object)("Successfully found " + pluginName));
				}
				return true;
			}
		}
		if (printDebug)
		{
			Logger.LogDebug((object)("Failed to find " + pluginName));
		}
		return false;
	}

	public static bool ObjectHeldByLocalPlayer(GameObject checkForObject, bool heldOrEquipped = true)
	{
		if (Object.op_Implicit((Object)(object)GameManager.Singleton) && Object.op_Implicit((Object)(object)GameManager.Singleton.localPlayerObject))
		{
			PlayerGrabber component = GameManager.Singleton.localPlayerObject.GetComponent<PlayerGrabber>();
			if (Object.op_Implicit((Object)(object)component))
			{
				GameObject val = (heldOrEquipped ? component.GetHeldDummyObject() : component.GetSpawnedEquipmentOnOurBodyDummy());
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)val == (Object)(object)checkForObject)
				{
					return true;
				}
			}
		}
		return false;
	}

	public static string GetSaveDataFolder()
	{
		string text = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "AppData", "LocalLow", "Get(Color) Games", "Last Train Out Of WormTown");
		if (!Directory.Exists(text))
		{
			Logger.LogDebug((object)"couldn't find vanillaSaveFolder, returning assembly folder");
			return GetAssemblyLocation();
		}
		string text2 = Path.Combine(text, "SimonTendo");
		if (!Directory.Exists(text2))
		{
			Logger.LogDebug((object)"No GENERAL SaveFolder existed yet, trying to create new one");
			Directory.CreateDirectory(text2);
		}
		string text3 = Path.Combine(text2, "LTOWLethalCompanyBoomboxMod");
		if (!Directory.Exists(text3))
		{
			Logger.LogDebug((object)"No BOOMBOX SaveFolder existed yet, trying to create new one");
			Directory.CreateDirectory(text3);
		}
		Logger.LogDebug((object)"Successfully found SaveData folder");
		return text3;
	}

	public static string GetAssemblyLocation()
	{
		return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
	}

	public static bool PathValid(string path)
	{
		if (string.IsNullOrEmpty(path))
		{
			if (Application.isEditor)
			{
				Logger.LogDebug((object)"PathValid(): A");
			}
			return false;
		}
		if (!Directory.Exists(path))
		{
			if (Application.isEditor)
			{
				Logger.LogDebug((object)"PathValid(): B");
			}
			return false;
		}
		return true;
	}
}
internal class RuntimeColliderTransform : MonoBehaviour
{
	private static ManualLogSource Logger;

	public BoxCollider colliderToResize;

	[Space]
	public Vector3 runtimeCenter;

	public Vector3 runtimeSize;

	private void Start()
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)colliderToResize))
		{
			colliderToResize = ((Component)this).GetComponent<BoxCollider>();
		}
		if (!Object.op_Implicit((Object)(object)colliderToResize))
		{
			Logger.LogWarning((object)("RuntimeColliderTransform put on GameObject " + ((Object)this).name + " without any BoxCollider"));
			return;
		}
		colliderToResize.center = runtimeCenter;
		colliderToResize.size = runtimeSize;
	}
}
public class VisibleBatteryTimer : MonoBehaviour
{
	public MonoBehaviour timerScriptContainer;

	private BoomboxItem mainScript;

	private void Awake()
	{
		mainScript = ((Component)this).GetComponentInParent<DummyBoombox>().mainScript;
		timerScriptContainer = (MonoBehaviour)(object)((Component)this).gameObject.AddComponent<BasicTimer>();
		MonoBehaviour obj = timerScriptContainer;
		MonoBehaviour obj2 = ((obj is BasicTimer) ? obj : null);
		((VisibleTimerBase)obj2).startVisible = mainScript.playingMusic;
		((VisibleTimerBase)obj2).SetTimerType((TimerType)2);
	}

	private void Start()
	{
		//IL_0020: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		MonoBehaviour obj = timerScriptContainer;
		MonoBehaviour obj2 = ((obj is BasicTimer) ? obj : null);
		((VisibleTimerBase)obj2).SetImagesColor(new Vector4(1f, 1f, 0f, 1f), new Vector4(1f, 1f, 0f, 0.5f));
		((VisibleTimerBase)obj2).SetShowArrow(false);
		((VisibleTimerBase)obj2).SetSize(new Vector3(0.75f, 0.75f, 0.75f));
		((VisibleTimerBase)obj2).SetVerticalOffset(0.4f);
		((VisibleTimerBase)obj2).SetTimerMax((float)mainScript.batteryLifetime);
		((VisibleTimerBase)obj2).SetTimerCurrent(mainScript.batteryTimer);
		((VisibleTimerBase)obj2).SetTextDecimals(0);
		((VisibleTimerBase)obj2).SetGradientInterval(5f);
		((VisibleTimerBase)obj2).SetBackerOpacity(25);
		((VisibleTimerBase)obj2).SetCheckEveryXFrames(15);
		((VisibleTimerBase)obj2).SetMinuteNotation(true);
	}

	private void Update()
	{
		MonoBehaviour obj = timerScriptContainer;
		BasicTimer val = (BasicTimer)(object)((obj is BasicTimer) ? obj : null);
		if (((VisibleTimerBase)val).currentlyVisible)
		{
			((VisibleTimerBase)val).SetTimerCurrent(mainScript.batteryTimer);
		}
	}
}
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		MonoScriptData result = default(MonoScriptData);
		result.FilePathsData = new byte[608]
		{
			0, 0, 0, 1, 0, 0, 0, 56, 92, 65,
			115, 115, 101, 116, 115, 92, 76, 84, 79, 87,
			76, 101, 116, 104, 97, 108, 67, 111, 109, 112,
			97, 110, 121, 66, 111, 111, 109, 98, 111, 120,
			77, 111, 100, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 65, 108, 108, 65, 115, 115, 101, 116,
			115, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 58, 92, 65, 115, 115, 101, 116, 115, 92,
			76, 84, 79, 87, 76, 101, 116, 104, 97, 108,
			67, 111, 109, 112, 97, 110, 121, 66, 111, 111,
			109, 98, 111, 120, 77, 111, 100, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 66, 111, 111, 109,
			98, 111, 120, 73, 116, 101, 109, 46, 99, 115,
			0, 0, 0, 1, 0, 0, 0, 54, 92, 65,
			115, 115, 101, 116, 115, 92, 76, 84, 79, 87,
			76, 101, 116, 104, 97, 108, 67, 111, 109, 112,
			97, 110, 121, 66, 111, 111, 109, 98, 111, 120,
			77, 111, 100, 92, 83, 99, 114, 105, 112, 116,
			115, 92, 67, 111, 110, 102, 105, 103, 115, 46,
			99, 115, 0, 0, 0, 1, 0, 0, 0, 59,
			92, 65, 115, 115, 101, 116, 115, 92, 76, 84,
			79, 87, 76, 101, 116, 104, 97, 108, 67, 111,
			109, 112, 97, 110, 121, 66, 111, 111, 109, 98,
			111, 120, 77, 111, 100, 92, 83, 99, 114, 105,
			112, 116, 115, 92, 68, 117, 109, 109, 121, 66,
			111, 111, 109, 98, 111, 120, 46, 99, 115, 0,
			0, 0, 5, 0, 0, 0, 61, 92, 65, 115,
			115, 101, 116, 115, 92, 76, 84, 79, 87, 76,
			101, 116, 104, 97, 108, 67, 111, 109, 112, 97,
			110, 121, 66, 111, 111, 109, 98, 111, 120, 77,
			111, 100, 92, 83, 99, 114, 105, 112, 116, 115,
			92, 72, 97, 114, 109, 111, 110, 121, 80, 97,
			116, 99, 104, 101, 115, 46, 99, 115, 0, 0,
			0, 1, 0, 0, 0, 58, 92, 65, 115, 115,
			101, 116, 115, 92, 76, 84, 79, 87, 76, 101,
			116, 104, 97, 108, 67, 111, 109, 112, 97, 110,
			121, 66, 111, 111, 109, 98, 111, 120, 77, 111,
			100, 92, 83, 99, 114, 105, 112, 116, 115, 92,
			77, 117, 115, 105, 99, 76, 111, 97, 100, 101,
			114, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 53, 92, 65, 115, 115, 101, 116, 115, 92,
			76, 84, 79, 87, 76, 101, 116, 104, 97, 108,
			67, 111, 109, 112, 97, 110, 121, 66, 111, 111,
			109, 98, 111, 120, 77, 111, 100, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 80, 108, 117, 103,
			105, 110, 46, 99, 115, 0, 0, 0, 1, 0,
			0, 0, 71, 92, 65, 115, 115, 101, 116, 115,
			92, 76, 84, 79, 87, 76, 101, 116, 104, 97,
			108, 67, 111, 109, 112, 97, 110, 121, 66, 111,
			111, 109, 98, 111, 120, 77, 111, 100, 92, 83,
			99, 114, 105, 112, 116, 115, 92, 82, 117, 110,
			116, 105, 109, 101, 67, 111, 108, 108, 105, 100,
			101, 114, 84, 114, 97, 110, 115, 102, 111, 114,
			109, 46, 99, 115, 0, 0, 0, 1, 0, 0,
			0, 66, 92, 65, 115, 115, 101, 116, 115, 92,
			76, 84, 79, 87, 76, 101, 116, 104, 97, 108,
			67, 111, 109, 112, 97, 110, 121, 66, 111, 111,
			109, 98, 111, 120, 77, 111, 100, 92, 83, 99,
			114, 105, 112, 116, 115, 92, 86, 105, 115, 105,
			98, 108, 101, 66, 97, 116, 116, 101, 114, 121,
			84, 105, 109, 101, 114, 46, 99, 115
		};
		result.TypesData = new byte[360]
		{
			0, 0, 0, 0, 10, 124, 65, 108, 108, 65,
			115, 115, 101, 116, 115, 0, 0, 0, 0, 12,
			124, 66, 111, 111, 109, 98, 111, 120, 73, 116,
			101, 109, 0, 0, 0, 0, 8, 124, 67, 111,
			110, 102, 105, 103, 115, 0, 0, 0, 0, 13,
			124, 68, 117, 109, 109, 121, 66, 111, 111, 109,
			98, 111, 120, 0, 0, 0, 0, 15, 124, 72,
			97, 114, 109, 111, 110, 121, 80, 97, 116, 99,
			104, 101, 115, 0, 0, 0, 0, 44, 72, 97,
			114, 109, 111, 110, 121, 80, 97, 116, 99, 104,
			101, 115, 124, 76, 67, 66, 111, 111, 109, 98,
			111, 120, 80, 97, 116, 99, 104, 95, 78, 101,
			116, 119, 111, 114, 107, 77, 97, 110, 97, 103,
			101, 114, 0, 0, 0, 0, 45, 72, 97, 114,
			109, 111, 110, 121, 80, 97, 116, 99, 104, 101,
			115, 124, 76, 67, 66, 111, 111, 109, 98, 111,
			120, 80, 97, 116, 99, 104, 95, 76, 111, 99,
			84, 97, 98, 108, 101, 72, 101, 108, 112, 101,
			114, 115, 0, 0, 0, 0, 41, 72, 97, 114,
			109, 111, 110, 121, 80, 97, 116, 99, 104, 101,
			115, 124, 76, 67, 66, 111, 111, 109, 98, 111,
			120, 80, 97, 116, 99, 104, 95, 76, 111, 111,
			116, 77, 97, 110, 97, 103, 101, 114, 0, 0,
			0, 0, 43, 72, 97, 114, 109, 111, 110, 121,
			80, 97, 116, 99, 104, 101, 115, 124, 76, 67,
			66, 111, 111, 109, 98, 111, 120, 80, 97, 116,
			99, 104, 95, 67, 104, 101, 97, 116, 115, 77,
			97, 110, 97, 103, 101, 114, 0, 0, 0, 0,
			12, 124, 77, 117, 115, 105, 99, 76, 111, 97,
			100, 101, 114, 0, 0, 0, 0, 7, 124, 80,
			108, 117, 103, 105, 110, 0, 0, 0, 0, 25,
			124, 82, 117, 110, 116, 105, 109, 101, 67, 111,
			108, 108, 105, 100, 101, 114, 84, 114, 97, 110,
			115, 102, 111, 114, 109, 0, 0, 0, 0, 20,
			124, 86, 105, 115, 105, 98, 108, 101, 66, 97,
			116, 116, 101, 114, 121, 84, 105, 109, 101, 114
		};
		result.TotalFiles = 9;
		result.TotalTypes = 13;
		result.IsEditorOnly = false;
		return result;
	}
}
namespace __GEN;

internal class NetworkVariableSerializationHelper
{
	[RuntimeInitializeOnLoadMethod]
	internal static void InitializeSerialization()
	{
	}
}