using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BigRadio")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+36783b4aa600e8cf1c6e45b85fef1d23f6153c65")]
[assembly: AssemblyProduct("BigRadio")]
[assembly: AssemblyTitle("BigRadio")]
[assembly: AssemblyVersion("1.0.1.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 BigRadio
{
internal static class Core
{
private sealed class Pending
{
public string Key;
public string File;
public UnityWebRequest Request;
}
private const string StationSection = "Stations";
private const float PollInterval = 0.25f;
private static ConfigEntry<string> _musicFolderCfg;
private static ConfigEntry<string> _reloadKeyCfg;
private static ConfigEntry<bool> _verboseCfg;
private static ConfigEntry<bool> _shuffleCfg;
private static readonly Random Rng = new Random();
private static readonly Dictionary<string, ConfigEntry<string>> Stations = new Dictionary<string, ConfigEntry<string>>();
private static readonly Dictionary<IntPtr, string> GroupToKey = new Dictionary<IntPtr, string>();
private static readonly HashSet<string> UsedKeys = new HashSet<string>();
private static readonly Dictionary<string, AudioClip> Clips = new Dictionary<string, AudioClip>();
private static readonly List<string> AvailableFiles = new List<string>();
private static readonly Dictionary<IntPtr, AudioClip> Primary = new Dictionary<IntPtr, AudioClip>();
private static readonly HashSet<IntPtr> Muted = new HashSet<IntPtr>();
private static bool _inOwnPlay;
private static readonly List<Pending> PendingLoads = new List<Pending>();
private static readonly List<AudioClip> ToDestroy = new List<AudioClip>();
private static readonly Dictionary<string, List<MusicPlayer>> ByKey = new Dictionary<string, List<MusicPlayer>>();
private static int _reloadVk;
private static bool _keyWasDown;
private static float _nextPoll;
private static readonly HashSet<string> Reported = new HashSet<string>();
private static readonly Action TickAction = TickInner;
internal static string MusicFolder { get; private set; }
private static bool Verbose
{
get
{
if (_verboseCfg != null)
{
return _verboseCfg.Value;
}
return false;
}
}
[DllImport("user32.dll")]
private static extern short GetAsyncKeyState(int vKey);
internal static void Init()
{
ConfigFile cfg = Plugin.Cfg;
string text = Path.Combine(Paths.ConfigPath, "BigRadio");
_musicFolderCfg = cfg.Bind<string>("General", "Music Folder", text, "Folder that holds your music files. Put .ogg, .wav or .mp3 files here, then restart the game so they appear in the station lists below.");
_reloadKeyCfg = cfg.Bind<string>("General", "Reload Key", "F8", "Key that reloads this config while the game runs. F1-F24, or a single letter or digit.");
_shuffleCfg = cfg.Bind<bool>("General", "Shuffle On Reload", true, "Reload key reshuffles: every audio file in the music folder is dealt out to a random station, never the same file twice. Turn off to keep your hand-written station list.");
_verboseCfg = cfg.Bind<bool>("General", "Verbose Logging", false, "Log every radio playback change. Turn on when reporting a bug.");
ApplyGeneralSettings();
ScanFiles();
}
private static void ApplyGeneralSettings()
{
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
string text = (_musicFolderCfg.Value ?? "").Trim().Trim('"');
MusicFolder = ((text.Length == 0) ? Path.Combine(Paths.ConfigPath, "BigRadio") : text);
try
{
Directory.CreateDirectory(MusicFolder);
string path = Path.Combine(MusicFolder, "PUT_YOUR_MUSIC_HERE.txt");
if (!File.Exists(path))
{
File.WriteAllText(path, "Put your .ogg, .wav or .mp3 files in this folder.\r\nThen open ArtemisCorp.BigRadio.cfg (mod manager: Config editor) and write a file name\r\nnext to a station under [Stations], e.g. musicGroup_DanceFM = my song.ogg\r\nStations appear in the config after you have loaded into a walk once.\r\nPress F8 in-game to reload.\r\n");
}
}
catch (Exception ex)
{
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not create music folder '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(MusicFolder);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
l.LogWarning(val);
}
_reloadVk = ParseKey(_reloadKeyCfg.Value);
}
private static int ParseKey(string raw)
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Expected O, but got Unknown
string text = (raw ?? "").Trim().ToUpperInvariant();
if (text.Length >= 2 && text[0] == 'F' && int.TryParse(text.Substring(1), out var result) && result >= 1 && result <= 24)
{
return 112 + result - 1;
}
if (text.Length == 1 && char.IsLetterOrDigit(text[0]))
{
return text[0];
}
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ReloadKey '");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(raw);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' not recognised - using F8.");
}
l.LogWarning(val);
return 119;
}
internal static void OnManagerInitialized(FmRadioManager manager)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
Il2CppReferenceArray<MusicGroup> stationTrackGroups = manager.stationTrackGroups;
if (stationTrackGroups == null)
{
return;
}
List<string> list = new List<string>();
foreach (MusicGroup item in (Il2CppArrayBase<MusicGroup>)(object)stationTrackGroups)
{
if (!((Object)(object)item == (Object)null) && !GroupToKey.ContainsKey(((Il2CppObjectBase)item).Pointer))
{
string text = Register(item);
if (text != null)
{
list.Add(text);
}
}
}
if (list.Count > 0)
{
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" radio stations: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", list));
}
l.LogInfo(val);
}
}
private static void ScanFiles()
{
AvailableFiles.Clear();
AvailableFiles.Add("");
try
{
List<string> list = new List<string>();
foreach (string item in Directory.EnumerateFiles(MusicFolder))
{
switch (Path.GetExtension(item).ToLowerInvariant())
{
case ".ogg":
case ".wav":
case ".mp3":
list.Add(Path.GetFileName(item));
break;
}
}
list.Sort(StringComparer.OrdinalIgnoreCase);
AvailableFiles.AddRange(list);
}
catch (Exception e)
{
Report("scan music folder", e);
}
}
private static string Register(MusicGroup group)
{
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Expected O, but got Unknown
if ((Object)(object)group == (Object)null)
{
return null;
}
if (GroupToKey.TryGetValue(((Il2CppObjectBase)group).Pointer, out var value))
{
return value;
}
string text = Regex.Replace((((Object)group).name ?? "").Replace("musicGroup_", ""), "[^A-Za-z0-9 _-]", "").Trim();
if (text.Length == 0)
{
text = "unknown";
}
int num = -1;
try
{
num = FmRadioManager.GetIndex(group);
}
catch
{
}
string text2 = ((num >= 0) ? $"Station {num + 1} ({text})" : ("Station (" + text + ")"));
int num2 = 2;
while (UsedKeys.Contains(text2))
{
text2 = $"Station {num + 1} ({text}) {num2}";
num2++;
}
ConfigEntry<string> value2 = Plugin.Cfg.Bind<string>("Stations", text2, "", new ConfigDescription("Track for this station. Leave empty for the game's original music.", (AcceptableValueBase)(object)new AcceptableValueList<string>(AvailableFiles.ToArray()), Array.Empty<object>()));
UsedKeys.Add(text2);
Stations[text2] = value2;
GroupToKey[((Il2CppObjectBase)group).Pointer] = text2;
QueueLoad(text2);
return text2;
}
private static void QueueLoad(string key)
{
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Expected O, but got Unknown
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Expected O, but got Unknown
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_0216: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Expected O, but got Unknown
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
for (int num = PendingLoads.Count - 1; num >= 0; num--)
{
if (!(PendingLoads[num].Key != key))
{
try
{
PendingLoads[num].Request.Abort();
PendingLoads[num].Request.Dispose();
}
catch
{
}
PendingLoads.RemoveAt(num);
}
}
string text = (Stations[key].Value ?? "").Trim().Trim('"');
bool flag = default(bool);
if (text.Length == 0)
{
DropClip(key);
if (Verbose)
{
ManualLogSource l = Plugin.L;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] original music");
}
l.LogInfo(val);
}
return;
}
string text2 = (Path.IsPathRooted(text) ? text : Path.Combine(MusicFolder, text));
if (!File.Exists(text2))
{
DropClip(key);
ManualLogSource l2 = Plugin.L;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] file not found: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" - playing original music");
}
l2.LogWarning(val2);
return;
}
AudioType val3 = (AudioType)(Path.GetExtension(text2).ToLowerInvariant() switch
{
".ogg" => 14,
".wav" => 20,
".mp3" => 13,
_ => 0,
});
if ((int)val3 == 0)
{
DropClip(key);
ManualLogSource l3 = Plugin.L;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(73, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] unsupported format: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (use .ogg, .wav or .mp3) - playing original music");
}
l3.LogWarning(val2);
}
else
{
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(text2).AbsoluteUri, val3);
audioClip.SendWebRequest();
PendingLoads.Add(new Pending
{
Key = key,
File = text,
Request = audioClip
});
}
}
private static void DropClip(string key)
{
if (Clips.Remove(key, out var value))
{
ToDestroy.Add(value);
ClearOverrides();
}
}
private static void FinishLoads()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Expected O, but got Unknown
bool flag = default(bool);
for (int num = PendingLoads.Count - 1; num >= 0; num--)
{
Pending pending = PendingLoads[num];
if (pending.Request.isDone)
{
PendingLoads.RemoveAt(num);
try
{
if ((int)pending.Request.result != 1)
{
DropClip(pending.Key);
ManualLogSource l = Plugin.L;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(pending.Key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(pending.File);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed to load (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(pending.Request.error);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") - playing original music");
}
l.LogWarning(val);
}
else
{
AudioClip content = DownloadHandlerAudioClip.GetContent(pending.Request);
if ((Object)(object)content == (Object)null || content.length <= 0f)
{
DropClip(pending.Key);
ManualLogSource l2 = Plugin.L;
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(49, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(pending.Key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(pending.File);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" could not be decoded - playing original music");
}
l2.LogWarning(val);
}
else
{
((Object)content).name = "BigRadio_" + pending.Key;
((Object)content).hideFlags = (HideFlags)32;
if (Clips.TryGetValue(pending.Key, out var value))
{
ToDestroy.Add(value);
}
Clips[pending.Key] = content;
ClearOverrides();
ManualLogSource l3 = Plugin.L;
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(13, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(pending.Key);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(pending.File);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded (");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(FormatTime(content.length));
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
}
l3.LogInfo(val2);
}
}
}
finally
{
pending.Request.Dispose();
}
}
}
if (PendingLoads.Count != 0 || ToDestroy.Count <= 0)
{
return;
}
foreach (AudioClip item in ToDestroy)
{
if ((Object)(object)item != (Object)null)
{
Object.Destroy((Object)(object)item);
}
}
ToDestroy.Clear();
}
private static string FormatTime(float seconds)
{
TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
if (!(timeSpan.TotalHours >= 1.0))
{
return timeSpan.ToString("m\\:ss");
}
return timeSpan.ToString("h\\:mm\\:ss");
}
private static void ClearOverrides()
{
Primary.Clear();
Muted.Clear();
}
private static void Reload()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
Plugin.Cfg.Reload();
ApplyGeneralSettings();
if (_shuffleCfg != null && _shuffleCfg.Value)
{
Shuffle();
}
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Reloading ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Stations.Count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stations from config...");
}
l.LogInfo(val);
foreach (string item in new List<string>(Stations.Keys))
{
QueueLoad(item);
}
ClearOverrides();
}
private static void Shuffle()
{
if (Stations.Count == 0)
{
return;
}
List<string> list = new List<string>();
foreach (string availableFile in AvailableFiles)
{
if (availableFile.Length == 0)
{
continue;
}
try
{
if (File.Exists(Path.Combine(MusicFolder, availableFile)))
{
list.Add(availableFile);
}
}
catch
{
}
}
for (int num = list.Count - 1; num > 0; num--)
{
int num2 = Rng.Next(num + 1);
List<string> list2 = list;
int index = num;
int index2 = num2;
string value = list[num2];
string value2 = list[num];
list2[index] = value;
list[index2] = value2;
}
List<string> list3 = new List<string>(Stations.Keys);
for (int num3 = list3.Count - 1; num3 > 0; num3--)
{
int num4 = Rng.Next(num3 + 1);
List<string> list2 = list3;
int index2 = num3;
int index = num4;
string value2 = list3[num4];
string value = list3[num3];
list2[index2] = value2;
list3[index] = value;
}
int num5 = 0;
foreach (string item in list3)
{
string text = ((num5 < list.Count) ? list[num5] : "");
Stations[item].Value = text;
if (text.Length > 0)
{
num5++;
}
}
Plugin.L.LogInfo((object)((list.Count == 0) ? "Shuffle: no audio files in the music folder." : $"Shuffled {num5} track(s) across {list3.Count} stations."));
}
internal static void Tick()
{
Safe(TickAction, "Tick");
}
private static void TickInner()
{
int num;
if (_reloadVk != 0)
{
num = (((GetAsyncKeyState(_reloadVk) & 0x8000) != 0) ? 1 : 0);
if (num != 0 && !_keyWasDown && Application.isFocused)
{
Reload();
}
}
else
{
num = 0;
}
_keyWasDown = (byte)num != 0;
if (PendingLoads.Count > 0 || ToDestroy.Count > 0)
{
FinishLoads();
}
if (Clips.Count != 0 && !(Time.unscaledTime < _nextPoll))
{
_nextPoll = Time.unscaledTime + 0.25f;
Poll();
}
}
private static void Poll()
{
Il2CppReferenceArray<Object> val = Object.FindObjectsOfType(Il2CppType.Of<MusicPlayer>());
if (val == null)
{
return;
}
ByKey.Clear();
foreach (Object item in (Il2CppArrayBase<Object>)(object)val)
{
if (item == (Object)null)
{
continue;
}
MusicPlayer val2 = ((Il2CppObjectBase)item).TryCast<MusicPlayer>();
if ((Object)(object)val2 == (Object)null)
{
continue;
}
MusicGroup musicConfig = val2.MusicConfig;
string value = null;
if ((Object)(object)musicConfig != (Object)null)
{
GroupToKey.TryGetValue(((Il2CppObjectBase)musicConfig).Pointer, out value);
}
if (value == null || !Clips.ContainsKey(value))
{
Release(val2);
continue;
}
if (!ByKey.TryGetValue(value, out var value2))
{
value2 = new List<MusicPlayer>();
ByKey[value] = value2;
}
value2.Add(val2);
}
foreach (KeyValuePair<string, List<MusicPlayer>> item2 in ByKey)
{
HandleStation(item2.Key, item2.Value);
}
}
private static void HandleStation(string key, List<MusicPlayer> players)
{
if (!Clips.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
{
return;
}
Dictionary<IntPtr, List<MusicPlayer>> dictionary = new Dictionary<IntPtr, List<MusicPlayer>>();
foreach (MusicPlayer player in players)
{
IntPtr key2;
try
{
Transform val = (((Object)(object)((Component)player).transform != (Object)null) ? ((Component)player).transform.parent : null);
key2 = (((Object)(object)val != (Object)null) ? ((Il2CppObjectBase)val).Pointer : ((Il2CppObjectBase)player).Pointer);
}
catch
{
key2 = ((Il2CppObjectBase)player).Pointer;
}
if (!dictionary.TryGetValue(key2, out var value2))
{
value2 = (dictionary[key2] = new List<MusicPlayer>());
}
value2.Add(player);
}
foreach (List<MusicPlayer> value3 in dictionary.Values)
{
MusicPlayer val2 = null;
int num = int.MaxValue;
foreach (MusicPlayer item in value3)
{
int num2;
try
{
num2 = item.Index;
}
catch
{
num2 = 0;
}
if (num2 < num)
{
num = num2;
val2 = item;
}
}
if ((Object)(object)val2 == (Object)null)
{
continue;
}
foreach (MusicPlayer item2 in value3)
{
if (((Il2CppObjectBase)item2).Pointer == ((Il2CppObjectBase)val2).Pointer)
{
Takeover(item2, key, value);
}
else
{
Silence(item2, key);
}
}
}
}
private static void Takeover(MusicPlayer mp, string key, AudioClip clip)
{
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Expected O, but got Unknown
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected O, but got Unknown
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
AudioSourceController aSC;
try
{
aSC = mp.ASC;
}
catch
{
return;
}
if ((Object)(object)aSC == (Object)null)
{
return;
}
bool flag2 = default(bool);
if (Primary.TryGetValue(pointer, out var value))
{
if (!aSC.IsPlaying && !aSC.IsHibernating)
{
Primary.Remove(pointer);
return;
}
bool flag = ((Il2CppObjectBase)value).Pointer != ((Il2CppObjectBase)clip).Pointer;
if (!flag)
{
AudioClip clip2 = aSC.Clip;
flag = (Object)(object)clip2 == (Object)null || ((Il2CppObjectBase)clip2).Pointer != ((Il2CppObjectBase)clip).Pointer;
}
if (flag)
{
Primary[pointer] = clip;
PlayOurs(mp, clip);
if (Verbose)
{
ManualLogSource l = Plugin.L;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] restarted custom track");
}
l.LogInfo(val);
}
}
EnsureLoop(mp);
}
else if (aSC.IsPlaying)
{
Primary[pointer] = clip;
PlayOurs(mp, clip);
EnsureLoop(mp);
ManualLogSource l2 = Plugin.L;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] custom track now playing on this radio");
}
l2.LogInfo(val);
}
}
private static void Silence(MusicPlayer mp, string key)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
if (!Muted.Add(pointer))
{
return;
}
try
{
mp.Stop(0.25f);
}
catch (Exception e)
{
Report("stop stem", e);
}
if (Verbose)
{
ManualLogSource l = Plugin.L;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] silenced an extra stem");
}
l.LogInfo(val);
}
}
private static void Release(MusicPlayer mp)
{
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
bool num = Primary.Remove(pointer);
bool flag = Muted.Remove(pointer);
if (!num && !flag)
{
return;
}
try
{
AudioSourceController aSC = mp.ASC;
if ((Object)(object)aSC != (Object)null && !aSC.IsPlaying)
{
mp.Play((AudioClip)null);
}
}
catch (Exception e)
{
Report("restore original", e);
}
}
private static void PlayOurs(MusicPlayer mp, AudioClip clip)
{
if (_inOwnPlay)
{
return;
}
_inOwnPlay = true;
try
{
mp.Play(clip);
}
catch (Exception e)
{
Report("play custom clip", e);
}
finally
{
_inOwnPlay = false;
}
}
private static void EnsureLoop(MusicPlayer mp)
{
try
{
AudioSourceController aSC = mp.ASC;
if (!((Object)(object)aSC == (Object)null))
{
if (!aSC._loop)
{
aSC._loop = true;
}
AudioSource audioSource = aSC.AudioSource;
if ((Object)(object)audioSource != (Object)null && !audioSource.loop)
{
audioSource.loop = true;
}
}
}
catch (Exception e)
{
Report("loop", e);
}
}
internal static bool IsOverridden(MusicPlayer mp)
{
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
if (!Primary.ContainsKey(pointer))
{
return Muted.Contains(pointer);
}
return true;
}
internal static bool OnPlay(MusicPlayer mp, AudioClip clipOverride)
{
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
if (Muted.Contains(pointer))
{
return false;
}
if (!Primary.TryGetValue(pointer, out var value))
{
return true;
}
if ((Object)(object)value == (Object)null)
{
Primary.Remove(pointer);
return true;
}
if (_inOwnPlay)
{
return true;
}
if (clipOverride != null && ((Il2CppObjectBase)clipOverride).Pointer == ((Il2CppObjectBase)value).Pointer)
{
return true;
}
PlayOurs(mp, value);
EnsureLoop(mp);
return false;
}
internal static void OnManualUpdate(MusicPlayer mp)
{
if (Primary.ContainsKey(((Il2CppObjectBase)mp).Pointer))
{
EnsureLoop(mp);
}
}
internal static void Forget(MusicPlayer mp)
{
IntPtr pointer = ((Il2CppObjectBase)mp).Pointer;
Primary.Remove(pointer);
Muted.Remove(pointer);
}
internal static void Safe(Action action, string where)
{
try
{
action();
}
catch (Exception e)
{
Report(where, e);
}
}
internal static void Report(string where, Exception e)
{
string text = $"{where}: {e.GetType().Name}: {e.Message}";
if (Reported.Add(text))
{
Plugin.L.LogError((object)(text + Environment.NewLine + e.StackTrace));
}
}
}
[HarmonyPatch]
internal static class RadioManagerPatches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(FmRadioManager), "Initialize")]
private static void InitializePostfix(FmRadioManager __instance)
{
Core.Safe(delegate
{
Core.OnManagerInitialized(__instance);
}, "FmRadioManager.Initialize");
}
}
[HarmonyPatch]
internal static class MusicPlayerPatches
{
[HarmonyPrefix]
[HarmonyPatch(typeof(MusicPlayer), "Play")]
private static bool PlayPrefix(MusicPlayer __instance, AudioClip clipOverride)
{
try
{
return Core.OnPlay(__instance, clipOverride);
}
catch (Exception e)
{
Core.Report("MusicPlayer.Play", e);
return true;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MusicPlayer), "Sync")]
private static bool SyncPrefix(MusicPlayer __instance)
{
return !Core.IsOverridden(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MusicPlayer), "SetSyncPitch")]
private static bool SetSyncPitchPrefix(MusicPlayer __instance)
{
return !Core.IsOverridden(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MusicPlayer), "ManualUpdate")]
private static void ManualUpdatePostfix(MusicPlayer __instance)
{
Core.OnManualUpdate(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MusicPlayer), "OnDestroy")]
private static void OnDestroyPrefix(MusicPlayer __instance)
{
Core.Forget(__instance);
}
}
[BepInPlugin("ArtemisCorp.BigRadio", "BigRadio", "1.0.0")]
public class Plugin : BasePlugin
{
public const string Guid = "ArtemisCorp.BigRadio";
public const string Name = "BigRadio";
public const string Version = "1.0.0";
internal static ManualLogSource L;
internal static ConfigFile Cfg;
public override void Load()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Expected O, but got Unknown
L = ((BasePlugin)this).Log;
Cfg = ((BasePlugin)this).Config;
Core.Init();
Harmony val = new Harmony("ArtemisCorp.BigRadio");
Type[] array = new Type[2]
{
typeof(RadioManagerPatches),
typeof(MusicPlayerPatches)
};
bool flag = default(bool);
foreach (Type type in array)
{
try
{
val.PatchAll(type);
}
catch (Exception ex)
{
ManualLogSource l = L;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(20, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not patch ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(type.Name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
}
l.LogWarning(val2);
L.LogWarning((object)"BigRadio keeps running; some vanilla audio behaviour may not be suppressed.");
}
}
if (!ClassInjector.IsTypeRegisteredInIl2Cpp<RadioDriver>())
{
ClassInjector.RegisterTypeInIl2Cpp<RadioDriver>();
}
((BasePlugin)this).AddComponent<RadioDriver>();
ManualLogSource l2 = L;
BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(24, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("BigRadio");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("1.0.0");
((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" loaded. Music folder: ");
((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(Core.MusicFolder);
}
l2.LogInfo(val3);
}
}
public class RadioDriver : MonoBehaviour
{
public RadioDriver(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
Core.Tick();
}
}
}