using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RadioPlus")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+11ff202d8a61f880a82902b780d183bc232704c2")]
[assembly: AssemblyProduct("RadioPlus")]
[assembly: AssemblyTitle("RadioPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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;
}
}
}
namespace RadioPlus
{
[HarmonyPatch(typeof(AudioLoader), "LoadAudio")]
public static class LoadAudioPatch
{
private static readonly HashSet<string> Known = new HashSet<string>
{
".mp3", ".wav", ".ogg", ".flac", ".aiff", ".aif", ".m4a", ".opus", ".mod", ".it",
".s3m", ".xm"
};
private static readonly HashSet<string> Skip = new HashSet<string>
{
".meta", ".txt", ".ini", ".json", ".jpg", ".jpeg", ".png", ".gif", ".pdf", ".zip",
".rar", ".7z", ".exe", ".dll", ".lnk", ".db", ".url", ".cue", ".log", ".m3u",
".m3u8"
};
private static bool Prefix(AudioLoader __instance, string path, ref IEnumerator __result)
{
__result = Replacement(__instance, path);
return false;
}
private static IEnumerator Replacement(AudioLoader loader, string path)
{
string fileName = Path.GetFileName(path);
string ext = Path.GetExtension(path).ToLowerInvariant();
if (ext.Length == 0 || Skip.Contains(ext))
{
Plugin.Log.LogInfo((object)("Ignoring " + fileName));
yield break;
}
if (!Known.Contains(ext))
{
Plugin.Log.LogInfo((object)("Trying " + fileName + " (unrecognized extension)"));
}
UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file://" + path, GuessType(ext));
try
{
((DownloadHandlerAudioClip)req.downloadHandler).streamAudio = true;
yield return req.SendWebRequest();
if ((int)req.result != 1)
{
Plugin.Log.LogWarning((object)("Skipping " + fileName + ": " + req.error));
yield break;
}
AudioClip clip = DownloadHandlerAudioClip.GetContent(req);
if ((Object)(object)clip == (Object)null)
{
Plugin.Log.LogWarning((object)("Skipping " + fileName + ": no clip"));
yield break;
}
((Object)clip).name = fileName;
loader.tracks.Add(clip);
Plugin.Log.LogInfo((object)$"Loaded {fileName} — {clip.length:F2}s, {clip.samples} samples, {clip.frequency}Hz, {clip.channels}ch, state={clip.loadState}");
}
finally
{
((IDisposable)req)?.Dispose();
}
}
private static AudioType GuessType(string ext)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
return (AudioType)(ext switch
{
".mp3" => 13,
".ogg" => 14,
".wav" => 20,
_ => 0,
});
}
}
[BepInPlugin("com.figrindan.radioplus", "Radio Plus", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<bool> Shuffle;
internal static ConfigEntry<bool> UnlockCustom;
private void Awake()
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Shuffle = ((BaseUnityPlugin)this).Config.Bind<bool>("Radio", "Shuffle", true, "Shuffle the custom radio playlist.");
UnlockCustom = ((BaseUnityPlugin)this).Config.Bind<bool>("Radio", "UnlockCustomStation", true, "Give the custom radio station (88.1) full signal from the start, without activating the radio tower. Note, driving next to towers that haven't yet been activated will interrupt your listening :)");
new Harmony("com.figrindan.radioplus").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Radio Plus loaded");
}
}
[HarmonyPatch(typeof(RadioChannel), "GetRandomizedClone")]
public static class ShufflePatch
{
private static readonly Random rng = new Random();
private static void Postfix(AudioClip[] __result)
{
if (Plugin.Shuffle.Value && __result != null && __result.Length >= 2)
{
for (int num = __result.Length - 1; num > 0; num--)
{
int num2 = rng.Next(num + 1);
ref AudioClip reference = ref __result[num];
ref AudioClip reference2 = ref __result[num2];
AudioClip val = __result[num2];
AudioClip val2 = __result[num];
reference = val;
reference2 = val2;
}
}
}
}
[HarmonyPatch(typeof(sRadioSystem), "GetStartTimeAndClip")]
public static class StartTimePatch
{
private static readonly ConditionalWeakTable<AudioClip[], object> lengthCache = new ConditionalWeakTable<AudioClip[], object>();
private static bool Prefix(RadioChannel channel, ref AudioClip clip, ref float __result)
{
if ((Object)(object)channel == (Object)null || channel.queue == null || channel.queue.Length == 0)
{
clip = null;
__result = -1f;
return false;
}
AudioClip[] queue = channel.queue;
float num;
if (lengthCache.TryGetValue(queue, out var value))
{
num = (float)value;
}
else
{
num = 0f;
for (int i = 0; i < queue.Length; i++)
{
num += queue[i].length;
}
lengthCache.Add(queue, num);
}
if (num <= 0f)
{
clip = null;
__result = -1f;
return false;
}
float num2 = Time.unscaledTime % num;
for (int j = 0; j < queue.Length; j++)
{
if (num2 <= queue[j].length)
{
clip = queue[j];
__result = num2;
return false;
}
num2 -= queue[j].length;
}
clip = null;
__result = -1f;
return false;
}
}
[HarmonyPatch(typeof(RadioSignalManager), "CheckStation")]
public static class UnlockPatch
{
private static void Postfix(RadioSignalManager __instance, int index)
{
if (!Plugin.UnlockCustom.Value)
{
return;
}
object? value = AccessTools.Field(typeof(RadioSignalManager), "radio").GetValue(__instance);
sRadioSystem val = (sRadioSystem)((value is sRadioSystem) ? value : null);
if (!((Object)(object)val == (Object)null) && index < val.channels.Count)
{
RadioChannel val2 = val.channels[index];
if (val2.externalTracks != null && val2.externalTracks.Count != 0)
{
val2.signal = 1f;
}
}
}
}
}