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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public class CarPatch
{
[CompilerGenerated]
private sealed class <AudioSourceListener>d__7 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioSource radio;
public VehicleController instance;
private AudioClip <clip>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AudioSourceListener>d__7(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<clip>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
if ((Object)(object)<clip>5__1 != (Object)(object)radio.clip)
{
if (CruiserTunesMod.GoodQuality.Value)
{
radio.volume = 1f;
instance.radioInterference.volume = 0f;
}
if ((Object)(object)CruiserTunesMod.instance != (Object)null)
{
((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(PlayNotification(instance));
}
}
<clip>5__1 = null;
break;
}
if ((Object)(object)radio != (Object)null && (Object)(object)instance != (Object)null)
{
<clip>5__1 = radio.clip;
instance.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
<>2__current = null;
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <EnsureClipReadyAndPlay>d__10 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioSource audio;
private float <timeout>5__1;
private float <start>5__2;
private float <max>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnsureClipReadyAndPlay>d__10(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<timeout>5__1 = 5f;
<start>5__2 = Time.time;
break;
case 1:
<>1__state = -1;
break;
}
if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
{
<>2__current = null;
<>1__state = 1;
return true;
}
if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
{
return false;
}
if (!audio.isPlaying)
{
audio.Play();
}
if (CruiserTunesMod.DoRandomTime != null && CruiserTunesMod.DoRandomTime.Value)
{
<max>5__3 = Mathf.Max(0.01f, audio.clip.length - 0.1f);
audio.time = Random.Range(0.01f, <max>5__3);
}
else
{
audio.time = 0f;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <PlayNotification>d__8 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public VehicleController instance;
private AudioClip <clip>5__1;
private PlayerControllerB <localPlayer>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayNotification>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<clip>5__1 = null;
<localPlayer>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (CruiserTunesMod.DoMessage.Value)
{
<clip>5__1 = instance.radioAudio.clip;
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 1;
return true;
}
break;
case 1:
<>1__state = -1;
if ((Object)(object)<clip>5__1 == (Object)(object)instance.radioAudio.clip)
{
<localPlayer>5__2 = StartOfRound.Instance.localPlayerController;
if ((Object)(object)<localPlayer>5__2 != (Object)null && (Object)(object)instance != (Object)null && Vector3.Distance(((Component)<localPlayer>5__2).transform.position, ((Component)instance).transform.position) < 10f)
{
HUDManager.Instance.DisplayTip("Now Playing:", ((Object)<clip>5__1).name.Replace("Radio_", "") + " - " + FormatLength(<clip>5__1.length), false, false, "LC_Tip1");
}
<localPlayer>5__2 = null;
}
<clip>5__1 = null;
break;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPatch(typeof(VehicleController), "Awake")]
[HarmonyPostfix]
public static void AwakePatch(VehicleController __instance)
{
if (CruiserTunesMod.HasSongs)
{
AudioClip[] source = ((!CruiserTunesMod.IncludeOriginal.Value) ? CruiserTunesMod.CustomSongs : __instance.radioClips.Concat(CruiserTunesMod.CustomSongs).ToArray());
source = source.OrderByDescending((AudioClip str) => GetAsciiSum(((Object)str).name)).ToArray();
__instance.radioClips = source;
__instance.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
if ((Object)(object)CruiserTunesMod.instance != (Object)null)
{
((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(AudioSourceListener(__instance.radioAudio, __instance));
}
}
static int GetAsciiSum(string str)
{
return str.Sum((char c) => c);
}
}
public static void UpdateLooping(object sender, EventArgs e)
{
Object val = Object.FindObjectOfType(typeof(VehicleController));
VehicleController val2 = (VehicleController)(object)((val is VehicleController) ? val : null);
if (val2 != null)
{
val2.radioAudio.loop = CruiserTunesMod.DoLoop.Value;
}
}
public static void ChangeVolume(object sender, EventArgs e)
{
Object val = Object.FindObjectOfType(typeof(VehicleController));
VehicleController val2 = (VehicleController)(object)((val is VehicleController) ? val : null);
if (val2 != null)
{
val2.radioAudio.volume = Mathf.Clamp(CruiserTunesMod.Volume.Value, 0f, 1.25f);
}
}
[HarmonyPatch(typeof(VehicleController), "ChangeRadioStation")]
[HarmonyPostfix]
public static void ChangeRadioStationPatch(VehicleController __instance)
{
float playbackTime = 0f;
if (CruiserTunesMod.DoRandomTime != null && CruiserTunesMod.DoRandomTime.Value && (Object)(object)__instance.radioAudio != (Object)null && (Object)(object)__instance.radioAudio.clip != (Object)null && __instance.radioAudio.clip.length > 0f)
{
float num = Math.Max(0.01f, __instance.radioAudio.clip.length - 0.1f);
playbackTime = Random.Range(0.01f, num);
}
if (CruiserTunesMod.SyncPlaybackTimeMessage != null)
{
FieldInfo field = ((object)__instance).GetType().GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
int station = ((field != null) ? ((int)field.GetValue(__instance)) : 0);
CruiserTunesMod.RadioSyncData radioSyncData = default(CruiserTunesMod.RadioSyncData);
radioSyncData.Station = station;
radioSyncData.PlaybackTime = playbackTime;
CruiserTunesMod.RadioSyncData radioSyncData2 = radioSyncData;
CruiserTunesMod.PendingSyncData = radioSyncData2;
CruiserTunesMod.SyncPlaybackTimeMessage.SendClients(radioSyncData2);
}
}
[HarmonyPatch(typeof(VehicleController), "SetRadioOnLocalClient")]
[HarmonyPrefix]
public static void SetOnClientPatch(VehicleController __instance)
{
Type type = ((object)__instance).GetType();
FieldInfo field = type.GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(__instance, (int)field.GetValue(__instance) % __instance.radioClips.Length);
}
[HarmonyPatch(typeof(VehicleController), "SetRadioValues")]
[HarmonyPrefix]
public static void SetRadioValuesPatch(VehicleController __instance)
{
if (CruiserTunesMod.GoodQuality.Value)
{
__instance.radioAudio.volume = 1f;
__instance.radioInterference.volume = 0f;
}
}
[HarmonyPatch(typeof(VehicleController), "SwitchRadio")]
[HarmonyPrefix]
public static void SwitchRadioPatch(VehicleController __instance)
{
}
[IteratorStateMachine(typeof(<AudioSourceListener>d__7))]
public static IEnumerator AudioSourceListener(AudioSource radio, VehicleController instance)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AudioSourceListener>d__7(0)
{
radio = radio,
instance = instance
};
}
[IteratorStateMachine(typeof(<PlayNotification>d__8))]
public static IEnumerator PlayNotification(VehicleController instance)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayNotification>d__8(0)
{
instance = instance
};
}
public static string FormatLength(float lengthInSeconds)
{
int num = Mathf.FloorToInt(lengthInSeconds / 3600f);
int num2 = Mathf.FloorToInt(lengthInSeconds % 3600f / 60f);
int num3 = Mathf.FloorToInt(lengthInSeconds % 60f);
return $"{num:00}:{num2:00}:{num3:00}";
}
[IteratorStateMachine(typeof(<EnsureClipReadyAndPlay>d__10))]
public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnsureClipReadyAndPlay>d__10(0)
{
audio = audio
};
}
public static void ChangeRadioStationWithoutServer(VehicleController instance)
{
Type type = ((object)instance).GetType();
FieldInfo field = type.GetField("radioSignalDecreaseThreshold", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo field2 = type.GetField("radioSignalQuality", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo field3 = type.GetField("currentRadioClip", BindingFlags.Instance | BindingFlags.NonPublic);
int num = ((int)field3.GetValue(instance) + 1) % instance.radioClips.Length;
field3.SetValue(instance, num);
instance.radioAudio.clip = instance.radioClips[num];
if ((Object)(object)CruiserTunesMod.instance != (Object)null)
{
((MonoBehaviour)CruiserTunesMod.instance).StartCoroutine(EnsureClipReadyAndPlay(instance.radioAudio));
}
else
{
if (CruiserTunesMod.DoRandomTime.Value && (Object)(object)instance.radioAudio.clip != (Object)null && instance.radioAudio.clip.length > 0f)
{
float num2 = Math.Max(0.01f, instance.radioAudio.clip.length - 0.1f);
instance.radioAudio.time = Random.Range(0.01f, num2);
}
else
{
instance.radioAudio.time = 0f;
}
instance.radioAudio.Play();
}
float num3 = 10f;
float num4 = (float)field2.GetValue(instance);
switch ((int)Mathf.Round(num4))
{
case 3:
num4 = 1f;
num3 = 10f;
break;
case 0:
num4 = 3f;
num3 = 90f;
break;
case 1:
num4 = 2f;
num3 = 70f;
break;
case 2:
num4 = 1f;
num3 = 30f;
break;
}
field2.SetValue(instance, num4);
field.SetValue(instance, num3);
ChangeRadioStationPatch(instance);
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Mellowdy.CruiserTunes", "CruiserTunes", "1.3.0")]
public class CruiserTunesMod : BaseUnityPlugin
{
[Serializable]
public struct RadioSyncData
{
public int Station;
public float PlaybackTime;
}
[CompilerGenerated]
private sealed class <EndOfPatch>d__23 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private bool <finishedLoading>5__1;
private bool[] <array>5__2;
private int <i>5__3;
private string <currentDirectory>5__4;
private string <path>5__5;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EndOfPatch>d__23(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<array>5__2 = null;
<currentDirectory>5__4 = null;
<path>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
goto IL_00ea;
}
<>1__state = -1;
mls.LogInfo((object)("Loading " + instance.loadingList.Length + " songs"));
<finishedLoading>5__1 = false;
goto IL_00f2;
IL_00ea:
<array>5__2 = null;
goto IL_00f2;
IL_00f2:
if (!<finishedLoading>5__1)
{
<finishedLoading>5__1 = true;
<array>5__2 = instance.loadingList;
<i>5__3 = 0;
while (<i>5__3 < <array>5__2.Length)
{
if (!<array>5__2[<i>5__3])
{
<finishedLoading>5__1 = false;
break;
}
<i>5__3++;
}
if (!<finishedLoading>5__1)
{
<>2__current = null;
<>1__state = 1;
return true;
}
goto IL_00ea;
}
instance.loadingList = null;
mls.LogInfo((object)("Finished loading songs, final song count at:" + instance.SongList.Count));
if (instance.SongList.Count == 0)
{
<currentDirectory>5__4 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
<path>5__5 = Path.Combine(<currentDirectory>5__4, instance.folderName).Replace("\\", "/");
mls.LogError((object)"No songs found in folder");
mls.LogError((object)("Make sure to add any .mp3 or .wav or .ogg files you want as songs to: '" + <path>5__5 + "'"));
<currentDirectory>5__4 = null;
<path>5__5 = null;
}
CustomSongs = instance.SongList.ToArray();
instance.SongList.Clear();
HasSongs = CustomSongs.Length != 0 || IncludeOriginal.Value;
mls.LogInfo((object)"CruiserTunes has been loaded with loleo's fix");
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <EnsureClipReadyAndPlay>d__31 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioSource audio;
private float <timeout>5__1;
private float <start>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnsureClipReadyAndPlay>d__31(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<timeout>5__1 = 5f;
<start>5__2 = Time.time;
break;
case 1:
<>1__state = -1;
break;
}
if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
{
<>2__current = null;
<>1__state = 1;
return true;
}
if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
{
return false;
}
if (!audio.isPlaying)
{
audio.Play();
}
audio.time = Mathf.Clamp(audio.time, 0.01f, audio.clip.length - 0.1f);
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <EnsureClipReadyAndPlayAt>d__30 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioSource audio;
public float timeToSet;
private float <timeout>5__1;
private float <start>5__2;
private float <clampedTime>5__3;
private float <guardEnd>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnsureClipReadyAndPlayAt>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<timeout>5__1 = 5f;
<start>5__2 = Time.time;
goto IL_0079;
case 1:
<>1__state = -1;
goto IL_0079;
case 2:
{
<>1__state = -1;
break;
}
IL_0079:
if (((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f || !audio.clip.isReadyToPlay) && !(Time.time - <start>5__2 > <timeout>5__1))
{
<>2__current = null;
<>1__state = 1;
return true;
}
if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null || audio.clip.length <= 0f)
{
return false;
}
<clampedTime>5__3 = Mathf.Clamp(timeToSet, 0.01f, audio.clip.length - 0.1f);
if (!audio.isPlaying)
{
audio.Play();
}
audio.time = <clampedTime>5__3;
<guardEnd>5__4 = Time.time + 0.5f;
break;
}
if (Time.time < <guardEnd>5__4)
{
if ((Object)(object)audio == (Object)null || (Object)(object)audio.clip == (Object)null)
{
return false;
}
if (Mathf.Abs(audio.time - <clampedTime>5__3) > 0.5f)
{
audio.time = <clampedTime>5__3;
}
<>2__current = null;
<>1__state = 2;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadAudioClip>d__24 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string filePath;
public int index;
public string fileType;
private float <loadingTime>5__1;
private float <maxLoading>5__2;
private string <fileName>5__3;
private AudioType <audioType>5__4;
private UnityWebRequest <loader>5__5;
private AudioClip <content>5__6;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadAudioClip>d__24(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<fileName>5__3 = null;
<loader>5__5 = null;
<content>5__6 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0071: 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_0083: Unknown result type (might be due to invalid IL or missing references)
bool result;
try
{
switch (<>1__state)
{
default:
result = false;
goto end_IL_0000;
case 0:
<>1__state = -1;
<loadingTime>5__1 = Time.time;
<maxLoading>5__2 = 5f;
<fileName>5__3 = Path.GetFileName(filePath);
mls.LogInfo((object)("Loading " + <fileName>5__3));
<audioType>5__4 = GetAudioType(fileType);
<loader>5__5 = UnityWebRequestMultimedia.GetAudioClip(filePath, <audioType>5__4);
<>1__state = -3;
<loader>5__5.SendWebRequest();
break;
case 1:
<>1__state = -3;
break;
}
if (!<loader>5__5.isDone)
{
if (<loadingTime>5__1 + <maxLoading>5__2 < Time.time)
{
mls.LogError((object)("Error loading clip from path: " + <fileName>5__3));
instance.loadingList[index] = true;
result = false;
goto IL_01c7;
}
<>2__current = null;
<>1__state = 1;
result = true;
}
else
{
instance.loadingList[index] = true;
if (<loader>5__5.error != null)
{
mls.LogError((object)("Error loading clip from path: " + <fileName>5__3 + "\n" + <loader>5__5.error));
result = false;
goto IL_01c7;
}
<content>5__6 = DownloadHandlerAudioClip.GetContent(<loader>5__5);
((Object)<content>5__6).name = <fileName>5__3;
instance.SongList.Add(<content>5__6);
<content>5__6 = null;
<>m__Finally1();
result = false;
}
goto end_IL_0000;
IL_01c7:
<>m__Finally1();
end_IL_0000:;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
return result;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<loader>5__5)?.Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <WaitForSyncThenPlay>d__29 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AudioSource audio;
public int expectedStation;
private float <timeout>5__1;
private float <start>5__2;
private float <timeToApply>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForSyncThenPlay>d__29(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<timeout>5__1 = 0.5f;
<start>5__2 = Time.time;
goto IL_0082;
case 1:
<>1__state = -1;
goto IL_0082;
case 2:
<>1__state = -1;
break;
case 3:
{
<>1__state = -1;
break;
}
IL_0082:
if ((!PendingSyncData.HasValue || PendingSyncData.Value.Station != expectedStation) && !(Time.time - <start>5__2 > <timeout>5__1))
{
<>2__current = null;
<>1__state = 1;
return true;
}
if (PendingSyncData.HasValue && PendingSyncData.Value.Station == expectedStation)
{
<timeToApply>5__3 = PendingSyncData.Value.PlaybackTime;
PendingSyncData = null;
<>2__current = EnsureClipReadyAndPlayAt(audio, <timeToApply>5__3);
<>1__state = 2;
return true;
}
PendingSyncData = null;
<>2__current = EnsureClipReadyAndPlay(audio);
<>1__state = 3;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const string modGUID = "Mellowdy.CruiserTunes";
private const string modName = "CruiserTunes";
private const string modVersion = "1.3.0";
private readonly Harmony harmony = new Harmony("Mellowdy.CruiserTunes");
public static ManualLogSource mls;
public static CruiserTunesMod instance;
public static ConfigEntry<bool> IncludeOriginal;
public static ConfigEntry<bool> DoMessage;
public static ConfigEntry<bool> DoLoop;
public static ConfigEntry<bool> DoRandomTime;
public static ConfigEntry<bool> GoodQuality;
public static ConfigEntry<float> Volume;
public static bool HasSongs;
public static AudioClip[] CustomSongs;
public static LNetworkMessage<RadioSyncData> SyncPlaybackTimeMessage;
public static RadioSyncData? PendingSyncData;
private const string supportedAudioFileTypes = ".mp3 or .wav or .ogg";
private string folderName = "CustomSongs";
private string altFolderName = "Custom Songs";
private List<AudioClip> SongList = new List<AudioClip>();
private bool[] loadingList;
private void Awake()
{
if ((Object)(object)instance == (Object)null)
{
instance = this;
}
mls = ((BaseUnityPlugin)this).Logger;
mls.LogInfo((object)"Loading...");
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
IncludeOriginal = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Include Original Songs", true, "The radio is able to play the orignal songs");
DoMessage = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Notify When New Song", true, "The radio notifies nearby players what song is now playing");
DoLoop = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Loop", false, "The radio loops songs upon completion");
DoLoop.SettingChanged += CarPatch.UpdateLooping;
DoRandomTime = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Random Start Time", false, "The randomly picks a point in the song to start playing when switching channels");
GoodQuality = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Always have good quality", true, "When switching between channels the quality will remain good");
Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Volume", 0.75f, "Volume of the radio (does not require restart)");
Volume.SettingChanged += CarPatch.ChangeVolume;
SyncPlaybackTimeMessage = LNetworkMessage<RadioSyncData>.Connect("CruiserTunes_SyncTime", (Action<RadioSyncData, ulong>)null, (Action<RadioSyncData>)OnSyncDataReceived, (Action<RadioSyncData, ulong>)null);
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string text = Path.Combine(directoryName, folderName);
List<string> list = new List<string>();
List<string> list2 = new List<string>();
string text2 = Path.Combine(Directory.GetParent(directoryName).FullName, folderName);
string text3 = Path.Combine(Directory.GetParent(directoryName).FullName, altFolderName);
if (Directory.Exists(text2))
{
list.Add(text2);
}
else if (Directory.Exists(text3))
{
list.Add(text3);
}
string text4 = Path.Combine(Directory.GetParent(directoryName).Parent.FullName, altFolderName);
if (Directory.Exists(text4))
{
list.Add(text4);
}
string[] directories = Directory.GetDirectories(Directory.GetParent(directoryName).FullName);
string[] array = directories;
foreach (string path in array)
{
string text5 = Path.Combine(path, folderName);
if (Directory.Exists(text5))
{
list.Add(text5);
}
}
if (list.Count == 0)
{
Directory.CreateDirectory(text);
mls.LogWarning((object)("Folder not found. One has been created at: '" + text + "'"));
return;
}
foreach (string item in list)
{
list2.AddRange(Directory.GetFiles(item));
}
list2 = RemoveDuplicateFiles(list2);
bool flag = false;
loadingList = new bool[list2.Count];
for (int j = 0; j < list2.Count; j++)
{
string text6 = list2[j];
loadingList[j] = false;
string fileName = Path.GetFileName(text6);
string text7 = Path.GetExtension(text6).ToLower();
if (text7 == ".mp3" || text7 == ".wav" || text7 == ".ogg")
{
((MonoBehaviour)this).StartCoroutine(LoadAudioClip(text6, j, text7));
continue;
}
loadingList[j] = true;
if (text7 != ".old")
{
mls.LogWarning((object)(fileName + " is of invalid extention. Must be a .mp3 or .wav or .ogg file or .old file"));
if (!flag)
{
mls.LogWarning((object)".old files ignore this message being printed.");
}
flag = true;
}
}
if (loadingList.Length == 0)
{
mls.LogError((object)"No songs found");
}
harmony.PatchAll(typeof(CruiserTunesMod));
harmony.PatchAll(typeof(CarPatch));
((MonoBehaviour)this).StartCoroutine(EndOfPatch());
}
[IteratorStateMachine(typeof(<EndOfPatch>d__23))]
private static IEnumerator EndOfPatch()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EndOfPatch>d__23(0);
}
[IteratorStateMachine(typeof(<LoadAudioClip>d__24))]
private static IEnumerator LoadAudioClip(string filePath, int index, string fileType)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadAudioClip>d__24(0)
{
filePath = filePath,
index = index,
fileType = fileType
};
}
public static AudioType GetAudioType(string fileType)
{
//IL_0047: 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)
if (1 == 0)
{
}
int num = fileType switch
{
".mp3" => 13,
".wav" => 20,
".ogg" => 14,
_ => 13,
};
if (1 == 0)
{
}
return (AudioType)num;
}
public static List<string> RemoveDuplicateFiles(List<string> filePaths)
{
HashSet<string> hashSet = new HashSet<string>();
List<string> list = new List<string>();
foreach (string filePath in filePaths)
{
string fileName = Path.GetFileName(filePath);
if (!hashSet.Contains(fileName))
{
hashSet.Add(fileName);
list.Add(filePath);
}
}
return list;
}
private static void OnSyncDataReceived(RadioSyncData data)
{
PendingSyncData = data;
VehicleController val = Object.FindObjectOfType<VehicleController>();
if ((Object)(object)val != (Object)null && (Object)(object)val.radioAudio != (Object)null && (Object)(object)val.radioAudio.clip != (Object)null && data.Station >= 0 && data.Station < val.radioClips.Length && (Object)(object)val.radioAudio.clip == (Object)(object)val.radioClips[data.Station] && data.PlaybackTime > 0f)
{
val.radioAudio.time = Mathf.Clamp(data.PlaybackTime, 0.01f, val.radioAudio.clip.length - 0.1f);
PendingSyncData = null;
}
}
[HarmonyPatch(typeof(VehicleController), "SetRadioStationClientRpc")]
[HarmonyPostfix]
public static void SetRadioStationPatch(ref int radioStation, VehicleController __instance)
{
if (radioStation < 0 || radioStation >= __instance.radioClips.Length)
{
return;
}
__instance.radioAudio.clip = __instance.radioClips[radioStation];
if (PendingSyncData.HasValue && PendingSyncData.Value.Station == radioStation)
{
float playbackTime = PendingSyncData.Value.PlaybackTime;
PendingSyncData = null;
if ((Object)(object)instance != (Object)null)
{
((MonoBehaviour)instance).StartCoroutine(EnsureClipReadyAndPlayAt(__instance.radioAudio, playbackTime));
return;
}
if (!__instance.radioAudio.isPlaying)
{
__instance.radioAudio.Play();
}
__instance.radioAudio.time = playbackTime;
}
else if ((Object)(object)instance != (Object)null)
{
((MonoBehaviour)instance).StartCoroutine(WaitForSyncThenPlay(__instance.radioAudio, radioStation));
}
else
{
__instance.radioAudio.Play();
}
}
[IteratorStateMachine(typeof(<WaitForSyncThenPlay>d__29))]
private static IEnumerator WaitForSyncThenPlay(AudioSource audio, int expectedStation)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForSyncThenPlay>d__29(0)
{
audio = audio,
expectedStation = expectedStation
};
}
[IteratorStateMachine(typeof(<EnsureClipReadyAndPlayAt>d__30))]
public static IEnumerator EnsureClipReadyAndPlayAt(AudioSource audio, float timeToSet)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnsureClipReadyAndPlayAt>d__30(0)
{
audio = audio,
timeToSet = timeToSet
};
}
[IteratorStateMachine(typeof(<EnsureClipReadyAndPlay>d__31))]
public static IEnumerator EnsureClipReadyAndPlay(AudioSource audio)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnsureClipReadyAndPlay>d__31(0)
{
audio = audio
};
}
}