using System;
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 EntityStates.SolusWing2;
using HG;
using HG.Reflection;
using IL.RoR2;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MusicSwapper.Extras;
using On.EntityStates.SolusWing2;
using On.RoR2;
using RoR2;
using RoR2.EntitlementManagement;
using RoR2.ExpansionManagement;
using RoR2.WwiseUtils;
using RoR2BepInExPack.GameAssetPathsBetter;
using SimpleJSON;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MusicSwapper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+73b5f1da4530a66881425ce8efeab5b108caf61d")]
[assembly: AssemblyProduct("MusicSwapper")]
[assembly: AssemblyTitle("MusicSwapper")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
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;
}
}
}
namespace MusicSwapper
{
public class ConsistentLanguageInstance : IDisposable
{
private List<KeyValuePair<string, string>> consistentTokenStringPairs;
public ConsistentLanguageInstance()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
Language.LoadAllTokensFromFolders += new hook_LoadAllTokensFromFolders(Language_LoadAllTokensFromFolders);
}
private void Language_LoadAllTokensFromFolders(orig_LoadAllTokensFromFolders orig, IEnumerable<string> folders, List<KeyValuePair<string, string>> output)
{
orig.Invoke(folders, output);
Language val = Language.FindLanguageByName("en");
if (val != null && folders == val.folders)
{
consistentTokenStringPairs = output;
}
}
public Dictionary<string, string> BuildConsistentLanguageDictionary()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
if (consistentTokenStringPairs == null)
{
MusicSwapperPlugin.Logger.LogWarning((object)"Failed to cache consistentTokenStringPairs - generating them from the language folders!");
if (Language.english == null)
{
return dictionary;
}
consistentTokenStringPairs = new List<KeyValuePair<string, string>>();
Language.LoadAllTokensFromFolders((IEnumerable<string>)Language.english.folders, consistentTokenStringPairs);
}
foreach (KeyValuePair<string, string> consistentTokenStringPair in consistentTokenStringPairs)
{
dictionary.TryAdd(consistentTokenStringPair.Key, consistentTokenStringPair.Value);
}
return dictionary;
}
public void Dispose()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
Language.LoadAllTokensFromFolders -= new hook_LoadAllTokensFromFolders(Language_LoadAllTokensFromFolders);
}
}
public static class Constants
{
public const string VALUE_DEFAULT = "default";
public const string VALUE_INHERIT = "inherit";
public const string TRACK_NAME_NONE = "None";
public const string MAIN_TRACK = "Main Track";
public const string BOSS_TRACK = "Teleporter Track";
}
public class HiddenAcceptableValueList<T> : AcceptableValueList<T> where T : IEquatable<T>
{
public virtual HashSet<T> HiddenAcceptableValues { get; }
public HiddenAcceptableValueList(T[] acceptableValues, HashSet<T> hiddenAcceptableValues)
{
HiddenAcceptableValues = hiddenAcceptableValues;
base..ctor(acceptableValues);
}
public override bool IsValid(object value)
{
if (value is T item && HiddenAcceptableValues.Contains(item))
{
return true;
}
return base.IsValid(value);
}
}
[BepInPlugin("groovesalad.MusicManager", "MusicManager", "1.1.0")]
public class MusicSwapperPlugin : BaseUnityPlugin
{
public const string GUID = "groovesalad.MusicManager";
public const string NAME = "MusicManager";
public const string VERSION = "1.1.0";
public static ManualLogSource Logger { get; private set; }
public static string RuntimeDirectory { get; private set; }
public static string ConfigDirectory { get; private set; }
public static string DefaultConfigDirectory { get; private set; }
public static ConfigFile TracksConfig { get; private set; }
public static ConfigFile ExtrasConfig { get; private set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
RuntimeDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
ConfigDirectory = Path.Combine(Paths.ConfigPath, "MusicManager");
DefaultConfigDirectory = Path.Combine(RuntimeDirectory, "defaultconfig");
TracksConfig = GetConfigFile("groovesalad.MusicManager.Tracks.cfg");
ExtrasConfig = GetConfigFile("groovesalad.MusicManager.Extras.cfg");
MusicSwapperSystem.Init();
TeleporterAudioAdjuster.Init();
SolutionalHauntMusic.Init();
ContinueTeleporterMusic.Init();
}
private ConfigFile GetConfigFile(string relativePath)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
string text = Path.Combine(ConfigDirectory, relativePath);
if (!File.Exists(text))
{
string text2 = Path.Combine(DefaultConfigDirectory, relativePath);
if (File.Exists(text2))
{
Logger.LogMessage((object)("Regenerating the config file " + relativePath + " from the default config file"));
Directory.CreateDirectory(Path.GetDirectoryName(text));
File.Copy(text2, text);
}
}
return new ConfigFile(text, true, ((BaseUnityPlugin)this).Info.Metadata);
}
}
public static class MusicSwapperSystem
{
private struct SceneMusicConfigurationResult
{
public struct TrackResult
{
public ConfigEntry<TrackTitle> configEntry;
public ConfigEntry<TrackTitle> postLoopConfigEntry;
}
public TrackResult mainTrack;
public TrackResult bossTrack;
}
private static TrackTitlesInstance trackTitles;
private static ConsistentLanguageInstance consistentLanguage;
public static void Init()
{
trackTitles = new TrackTitlesInstance("TrackTitles.json");
consistentLanguage = new ConsistentLanguageInstance();
RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnLoad));
}
private static void OnLoad()
{
DoConfiguration();
PostLoopMusicManager.Init();
trackTitles = null;
consistentLanguage.Dispose();
consistentLanguage = null;
}
private static void DoConfiguration()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: 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_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
ExpansionDef dlc1 = Addressables.LoadAssetAsync<ExpansionDef>((object)RoR2_DLC1_Common.DLC1_asset).WaitForCompletion();
HashSet<UnityObjectWrapperKey<SceneDef>> infiniteTowerStages = new HashSet<UnityObjectWrapperKey<SceneDef>>();
AsyncOperationHandle<SceneCollection> val2 = Addressables.LoadAssetAsync<SceneCollection>((object)RoR2_DLC1_GameModes_InfiniteTowerRun_SceneGroups.sgInfiniteTowerStageX_asset);
SceneCollection val3 = val2.WaitForCompletion();
if (Object.op_Implicit((Object)(object)val3))
{
Enumerator<SceneEntry> enumerator = val3.sceneEntries.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
SceneEntry current = enumerator.Current;
infiniteTowerStages.Add(UnityObjectWrapperKey<SceneDef>.op_Implicit(current.sceneDef));
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
}
else
{
MusicSwapperPlugin.Logger.LogError((object)"Failed to load sgInfiniteTowerStageX!");
}
SceneDef[] array = ((IEnumerable<SceneDef>)(object)SceneCatalog.allSceneDefs).Where(SceneValidForConfig).ToArray();
HashSet<UnityObjectWrapperKey<MusicTrackDef>> allMusicTracks = new HashSet<UnityObjectWrapperKey<MusicTrackDef>>();
HashSet<UnityObjectWrapperKey<MusicTrackDef>> alwaysAvailableMusicTracks = new HashSet<UnityObjectWrapperKey<MusicTrackDef>>();
Dictionary<UnityObjectWrapperKey<MusicTrackDef>, HashSet<UnityObjectWrapperKey<EntitlementDef>>> entitlementLockedMusicTracks = new Dictionary<UnityObjectWrapperKey<MusicTrackDef>, HashSet<UnityObjectWrapperKey<EntitlementDef>>>();
SceneDef[] array2 = array;
foreach (SceneDef val4 in array2)
{
EntitlementDef requiredEntitlement2 = GetRequiredEntitlementFromScene(val4);
if (SceneValidForMainTrack(val4))
{
RegisterMusicTrack(val4.mainTrack, requiredEntitlement2);
}
if (SceneValidForBossTrack(val4))
{
RegisterMusicTrack(val4.bossTrack, requiredEntitlement2);
}
}
MusicTrackDef val5 = Addressables.LoadAssetAsync<MusicTrackDef>((object)RoR2_Base_Common_MusicTrackDefs.muNone_asset).WaitForCompletion();
if (Object.op_Implicit((Object)(object)val5))
{
RegisterMusicTrack(val5, null);
}
else
{
MusicSwapperPlugin.Logger.LogError((object)"Failed to load muNone!");
}
trackTitles.SetAllTracks(allMusicTracks);
Dictionary<string, string> consistentLanguageDictionary2 = consistentLanguage.BuildConsistentLanguageDictionary();
HashSet<char> invalidConfigChars = new HashSet<char> { '=', '\n', '\t', '\\', '"', '\'', '[', ']' };
foreach (IGrouping<string, SceneDef> baseNameSceneGroup in from x in array
group x by x.baseSceneName)
{
SceneMusicConfigurationResult sceneMusicConfigurationResult = default(SceneMusicConfigurationResult);
MusicTrackDef val6 = null;
MusicTrackDef val7 = null;
List<SceneDef> list = baseNameSceneGroup.ToList();
if (list.Count > 1)
{
int num = list.FindIndex((SceneDef x) => x.cachedName == baseNameSceneGroup.Key);
if (num >= 0)
{
SceneDef val8 = list[num];
if (Object.op_Implicit((Object)(object)val8))
{
val6 = val8.mainTrack;
val7 = val8.bossTrack;
sceneMusicConfigurationResult = ConfigureSceneMusic(val8, default(SceneMusicConfigurationResult.TrackResult), default(SceneMusicConfigurationResult.TrackResult));
}
list.RemoveAt(num);
}
}
foreach (SceneDef item in list)
{
ConfigureSceneMusic(item, ((Object)(object)item.mainTrack == (Object)(object)val6) ? sceneMusicConfigurationResult.mainTrack : default(SceneMusicConfigurationResult.TrackResult), ((Object)(object)item.bossTrack == (Object)(object)val7) ? sceneMusicConfigurationResult.bossTrack : default(SceneMusicConfigurationResult.TrackResult));
}
}
val2.Release();
invalidConfigChars = null;
ConfigEntry<TrackTitle> ConfigureMusicTrack(ref MusicTrackDef musicTrack, SceneDef scene, string section, string key, string description, [CanBeNull] ConfigEntry<TrackTitle> parentConfigEntry)
{
if (!trackTitles.InternalNameToAlbumName.TryGetValue(musicTrack.cachedName, out var value2))
{
value2 = musicTrack.cachedName;
}
ConfigEntry<TrackTitle> val10 = CreateMusicTrackConfigEntry(section, key, description, string.Empty, value2, parentConfigEntry);
if (ShouldApplyMusicTrackConfig(val10, scene, parentConfigEntry, out var chosenMusicTrack3))
{
MusicSwapperPlugin.Logger.LogMessage((object)("Setting the " + scene.cachedName + " " + key + " to " + chosenMusicTrack3.cachedName + " (formerly " + musicTrack.cachedName + ")"));
musicTrack = chosenMusicTrack3;
}
return val10;
}
ConfigEntry<TrackTitle> ConfigureMusicTrackPostLoop(PostLoopMusicManager.IPostLoopTrackData postLoopTrackData, SceneDef scene, string section, string key, [CanBeNull] ConfigEntry<TrackTitle> parentConfigEntry)
{
ConfigEntry<TrackTitle> val9 = CreateMusicTrackConfigEntry(section, "Post-Loop " + key, "Choose a track to override the " + key + " after looping once.", "\nChoose \"default\" to disable this feature.", "default", parentConfigEntry);
if (ShouldApplyMusicTrackConfig(val9, scene, parentConfigEntry, out var chosenMusicTrack2))
{
MusicSwapperPlugin.Logger.LogMessage((object)("Setting the " + scene.cachedName + " " + ((ConfigEntryBase)val9).Definition.Key + " to " + chosenMusicTrack2.cachedName));
postLoopTrackData.RegisterTrack(scene, chosenMusicTrack2);
}
return val9;
}
SceneMusicConfigurationResult ConfigureSceneMusic(SceneDef scene, SceneMusicConfigurationResult.TrackResult mainTrackParent, SceneMusicConfigurationResult.TrackResult bossTrackParent)
{
SceneMusicConfigurationResult result = default(SceneMusicConfigurationResult);
string configSectionForScene = GetConfigSectionForScene(scene, consistentLanguageDictionary2);
bool flag = SceneValidForMainTrack(scene);
bool flag2 = SceneValidForBossTrack(scene);
if (flag)
{
result.mainTrack.configEntry = ConfigureMusicTrack(ref scene.mainTrack, scene, configSectionForScene, "Main Track", "Choose a track for the stage.", mainTrackParent.configEntry);
}
if (flag2)
{
result.bossTrack.configEntry = ConfigureMusicTrack(ref scene.bossTrack, scene, configSectionForScene, "Teleporter Track", "Choose a track for the Teleporter event.", bossTrackParent.configEntry);
}
if (flag)
{
result.mainTrack.postLoopConfigEntry = ConfigureMusicTrackPostLoop(PostLoopMusicManager.mainTrackData, scene, configSectionForScene, "Main Track", mainTrackParent.postLoopConfigEntry);
}
if (flag2)
{
result.bossTrack.postLoopConfigEntry = ConfigureMusicTrackPostLoop(PostLoopMusicManager.bossTrackData, scene, configSectionForScene, "Teleporter Track", bossTrackParent.postLoopConfigEntry);
}
return result;
}
static ConfigEntry<TrackTitle> CreateMusicTrackConfigEntry(string section, string key, string desc, string specialValuesDesc, string defaultValue, [CanBeNull] ConfigEntry<TrackTitle> parentConfigEntry)
{
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Expected O, but got Unknown
List<TrackTitle> list2 = trackTitles.PrimaryTrackTitles.ToList();
if (parentConfigEntry != null)
{
if (!list2.Contains(defaultValue))
{
list2.Insert(0, defaultValue);
}
defaultValue = "inherit";
specialValuesDesc = "\nChoose \"inherit\" to use the same " + key + " as " + ((ConfigEntryBase)parentConfigEntry).Definition.Section + "." + specialValuesDesc;
}
list2.Remove(defaultValue);
list2.Insert(0, defaultValue);
desc += " Some tracks require DLC.";
if (!string.IsNullOrEmpty(specialValuesDesc))
{
desc = desc + "\nSpecial Values:" + specialValuesDesc;
}
return MusicSwapperPlugin.TracksConfig.Bind<TrackTitle>(section, key, (TrackTitle)defaultValue, new ConfigDescription(desc, (AcceptableValueBase)(object)new HiddenAcceptableValueList<TrackTitle>(list2.ToArray(), trackTitles.AllTrackTitles), Array.Empty<object>()));
}
string GetConfigSafeString(string val)
{
val = val.Replace('\'', 'ꞌ');
for (int num2 = val.Length - 1; num2 >= 0; num2--)
{
if (invalidConfigChars.Contains(val[num2]))
{
val = val.Remove(num2, 1);
}
}
return val;
}
string GetConfigSectionForScene(SceneDef scene, Dictionary<string, string> consistentLanguageDictionary)
{
string value3;
string val11 = ((string.IsNullOrEmpty(scene.nameToken) || !consistentLanguageDictionary.TryGetValue(scene.nameToken, out value3) || string.IsNullOrWhiteSpace(value3)) ? scene.cachedName : (value3 + " (" + scene.cachedName + ")"));
return GetConfigSafeString(val11);
}
EntitlementDef GetRequiredEntitlementFromScene(SceneDef scene)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
EntitlementDef val12 = (Object.op_Implicit((Object)(object)scene.requiredExpansion) ? scene.requiredExpansion.requiredEntitlement : null);
if (!Object.op_Implicit((Object)(object)val12) && infiniteTowerStages.Contains(UnityObjectWrapperKey<SceneDef>.op_Implicit(scene)) && Object.op_Implicit((Object)(object)dlc1))
{
val12 = dlc1.requiredEntitlement;
}
return val12;
}
void RegisterMusicTrack(MusicTrackDef musicTrack, [CanBeNull] EntitlementDef requiredEntitlement)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: 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_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
allMusicTracks.Add(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack));
if (!alwaysAvailableMusicTracks.Contains(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack)))
{
HashSet<UnityObjectWrapperKey<EntitlementDef>> value4;
if (!Object.op_Implicit((Object)(object)requiredEntitlement) || ((BaseUserEntitlementTracker<LocalUser>)(object)EntitlementManager.localUserEntitlementTracker).AnyUserHasEntitlement(requiredEntitlement))
{
alwaysAvailableMusicTracks.Add(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack));
entitlementLockedMusicTracks.Remove(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack));
}
else if (entitlementLockedMusicTracks.TryGetValue(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack), out value4))
{
value4.Add(UnityObjectWrapperKey<EntitlementDef>.op_Implicit(requiredEntitlement));
}
else
{
entitlementLockedMusicTracks.Add(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(musicTrack), new HashSet<UnityObjectWrapperKey<EntitlementDef>> { UnityObjectWrapperKey<EntitlementDef>.op_Implicit(requiredEntitlement) });
}
}
}
bool SceneValidForBossTrack(SceneDef scene)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
return Object.op_Implicit((Object)(object)scene.bossTrack) && scene.hasAnyDestinations && !infiniteTowerStages.Contains(UnityObjectWrapperKey<SceneDef>.op_Implicit(scene));
}
static bool SceneValidForConfig(SceneDef scene)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Invalid comparison between Unknown and I4
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Invalid comparison between Unknown and I4
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Invalid comparison between Unknown and I4
if (scene.isOfflineScene)
{
return false;
}
SceneType sceneType = scene.sceneType;
if ((int)sceneType != 1 && (int)sceneType != 2 && (int)sceneType != 4 && (int)sceneType != 5)
{
return false;
}
return true;
}
static bool SceneValidForMainTrack(SceneDef scene)
{
return Object.op_Implicit((Object)(object)scene.mainTrack);
}
bool ShouldApplyMusicTrackConfig(ConfigEntry<TrackTitle> configEntry, SceneDef scene, [CanBeNull] ConfigEntry<TrackTitle> parentConfigEntry, out MusicTrackDef chosenMusicTrack)
{
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
chosenMusicTrack = null;
if (string.Equals(configEntry.Value, "inherit"))
{
if (parentConfigEntry != null)
{
return ShouldApplyMusicTrackConfig(parentConfigEntry, scene, null, out chosenMusicTrack);
}
return false;
}
if (string.Equals(configEntry.Value, (TrackTitle)((ConfigEntryBase)configEntry).DefaultValue))
{
return false;
}
if (string.Equals(configEntry.Value, "default"))
{
return false;
}
if (!trackTitles.TrackNameToMusicTrackDef.TryGetValue(configEntry.Value, out chosenMusicTrack))
{
return false;
}
if (entitlementLockedMusicTracks.TryGetValue(UnityObjectWrapperKey<MusicTrackDef>.op_Implicit(chosenMusicTrack), out var value))
{
EntitlementDef requiredEntitlementFromScene = GetRequiredEntitlementFromScene(scene);
if (!Object.op_Implicit((Object)(object)requiredEntitlementFromScene) || !value.Contains(UnityObjectWrapperKey<EntitlementDef>.op_Implicit(requiredEntitlementFromScene)))
{
MusicSwapperPlugin.Logger.LogWarning((object)("The " + scene.cachedName + " " + ((ConfigEntryBase)configEntry).Definition.Key + " cannot be set to " + chosenMusicTrack.cachedName + " because the track's entitlement requirements are not met"));
return false;
}
}
return true;
}
}
}
public static class PostLoopMusicManager
{
public interface IPostLoopTrackData
{
void RegisterTrack(SceneDef scene, MusicTrackDef postLoopTrack);
}
public class PostLoopTrackData : IPostLoopTrackData
{
private readonly string trackName;
public Dictionary<UnityObjectWrapperKey<SceneDef>, MusicTrackDef> tracks;
public MusicTrackDef mostRecentTrack;
public bool setHook;
public bool HasTracks => tracks != null && tracks.Count > 0;
public PostLoopTrackData(string trackName)
{
this.trackName = trackName;
base..ctor();
}
public void RegisterTrack(SceneDef scene, MusicTrackDef postLoopTrack)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
(tracks ?? (tracks = new Dictionary<UnityObjectWrapperKey<SceneDef>, MusicTrackDef>()))[UnityObjectWrapperKey<SceneDef>.op_Implicit(scene)] = postLoopTrack;
}
public void Init()
{
if (HasTracks)
{
SceneCatalog.onMostRecentSceneDefChanged += OnMostRecentSceneDefChanged;
}
}
private void OnMostRecentSceneDefChanged(SceneDef mostRecentSceneDef)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
mostRecentTrack = null;
if (Object.op_Implicit((Object)(object)Run.instance) && Run.instance.loopClearCount > 0 && tracks.TryGetValue(UnityObjectWrapperKey<SceneDef>.op_Implicit(mostRecentSceneDef), out mostRecentTrack) && !setHook)
{
MusicSwapperPlugin.Logger.LogMessage((object)("Setting a hook to override " + trackName + " post loop"));
setHook = true;
MusicController.PickCurrentTrack += new Manipulator(OverrideTrackPostLoop);
}
}
private void OverrideTrackPostLoop(ILContext il)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
ILCursor val = new ILCursor(il);
while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
{
(Instruction x) => ILPatternMatchingExt.MatchLdfld<SceneDef>(x, trackName)
}))
{
val.EmitDelegate<Func<MusicTrackDef, MusicTrackDef>>((Func<MusicTrackDef, MusicTrackDef>)((MusicTrackDef track) => Object.op_Implicit((Object)(object)mostRecentTrack) ? mostRecentTrack : track));
}
}
}
public static readonly PostLoopTrackData mainTrackData = new PostLoopTrackData("mainTrack");
public static readonly PostLoopTrackData bossTrackData = new PostLoopTrackData("bossTrack");
public static void Init()
{
mainTrackData.Init();
bossTrackData.Init();
}
}
public readonly struct TrackTitle : IEquatable<TrackTitle>
{
public string Value { get; }
public TrackTitle(string value)
{
Value = value;
}
static TrackTitle()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
TomlTypeConverter.AddConverter(typeof(TrackTitle), new TypeConverter
{
ConvertToString = (object obj, Type type) => obj.ToString(),
ConvertToObject = (string str, Type type) => new TrackTitle(str)
});
}
public override string ToString()
{
return Value;
}
public static implicit operator TrackTitle(string value)
{
return new TrackTitle(value);
}
public static implicit operator string(TrackTitle trackTitle)
{
return trackTitle.Value;
}
public override int GetHashCode()
{
return Value?.GetHashCode() ?? 0;
}
public bool Equals(string other)
{
return string.Equals(Value, other);
}
public bool Equals(TrackTitle other)
{
return Equals(other.Value);
}
public override bool Equals(object other)
{
if (1 == 0)
{
}
bool result = ((other is TrackTitle other2) ? Equals(other2) : (other is string other3 && Equals(other3)));
if (1 == 0)
{
}
return result;
}
}
public class TrackTitlesInstance
{
public Dictionary<string, string> InternalNameToAlbumName { get; private set; }
public List<TrackTitle> PrimaryTrackTitles { get; private set; }
public HashSet<TrackTitle> AllTrackTitles { get; private set; }
public Dictionary<string, MusicTrackDef> TrackNameToMusicTrackDef { get; private set; }
public TrackTitlesInstance(string fileName)
{
InternalNameToAlbumName = new Dictionary<string, string>();
string path = Path.Combine(MusicSwapperPlugin.RuntimeDirectory, fileName);
if (!File.Exists(path))
{
MusicSwapperPlugin.Logger.LogWarning((object)("Could not find " + fileName + "!"));
return;
}
JSONNode val = JSON.Parse(File.ReadAllText(path));
foreach (string key in val.Keys)
{
string value = val[key].Value;
InternalNameToAlbumName.Add(key, value);
}
MusicSwapperPlugin.Logger.LogMessage((object)$"Loaded {val.Count} track titles from {fileName}");
}
public void SetAllTracks(HashSet<UnityObjectWrapperKey<MusicTrackDef>> allTracks)
{
AllTrackTitles = new HashSet<TrackTitle>();
TrackNameToMusicTrackDef = new Dictionary<string, MusicTrackDef>();
List<string> list = new List<string>();
List<string> list2 = new List<string>();
foreach (MusicTrackDef item in allTracks.Select((UnityObjectWrapperKey<MusicTrackDef> x) => x.value))
{
string cachedName = item.cachedName;
if (InternalNameToAlbumName.TryGetValue(cachedName, out var value))
{
if (!list.Contains(value))
{
list.Add(value);
}
AllTrackTitles.Add(value);
TrackNameToMusicTrackDef.TryAdd(value, item);
}
else if (!list2.Contains(cachedName))
{
list2.Add(cachedName);
}
AllTrackTitles.Add(cachedName);
TrackNameToMusicTrackDef.TryAdd(cachedName, item);
}
list.Sort();
list2.Sort();
List<string> list3 = list;
List<string> list4 = list2;
List<TrackTitle> list5 = new List<TrackTitle>(list3.Count + list4.Count);
foreach (string item2 in list3)
{
list5.Add(item2);
}
foreach (string item3 in list4)
{
list5.Add(item3);
}
PrimaryTrackTitles = list5;
if (PrimaryTrackTitles.Remove("None"))
{
PrimaryTrackTitles.Add("None");
}
}
}
}
namespace MusicSwapper.Extras
{
public static class ContinueTeleporterMusic
{
[CompilerGenerated]
private static class <>O
{
public static hook_UpdateTeleporterParameters <0>__MusicController_UpdateTeleporterParameters;
}
public static void Init()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
ConfigEntry<bool> val = MusicSwapperPlugin.ExtrasConfig.Bind<bool>("Teleporter Music", "Continue After Charged", false, "After charging the Teleporter, continue playing the Teleporter track until you leave the stage.");
if (val.Value)
{
MusicSwapperPlugin.Logger.LogMessage((object)"ContinueTeleporterMusic extra is active");
object obj = <>O.<0>__MusicController_UpdateTeleporterParameters;
if (obj == null)
{
hook_UpdateTeleporterParameters val2 = MusicController_UpdateTeleporterParameters;
<>O.<0>__MusicController_UpdateTeleporterParameters = val2;
obj = (object)val2;
}
MusicController.UpdateTeleporterParameters += (hook_UpdateTeleporterParameters)obj;
}
}
private static void MusicController_UpdateTeleporterParameters(orig_UpdateTeleporterParameters orig, MusicController self, TeleporterInteraction teleporter, Transform cameraTransform, CharacterBody targetBody)
{
orig.Invoke(self, teleporter, cameraTransform, targetBody);
bool flag = (Object.op_Implicit((Object)(object)teleporter) && teleporter.isInFinalSequence) || (Object.op_Implicit((Object)(object)Run.instance) && Run.instance.inSceneTransition);
self.stBossStatus.valueId = (flag ? CommonWwiseIds.dead : CommonWwiseIds.alive);
}
}
public static class SolutionalHauntMusic
{
[CompilerGenerated]
private static class <>O
{
public static hook_OnEnter <0>__Mission5Death_OnEnter;
}
public static void Init()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
ConfigEntry<bool> val = MusicSwapperPlugin.ExtrasConfig.Bind<bool>("Solutional Haunt", "Restart Music After Fight", false, "After the Solus Wing fight, resume playing the main track of Solutional Haunt.");
if (val.Value)
{
MusicSwapperPlugin.Logger.LogMessage((object)"SolutionalHauntMusic extra is active");
object obj = <>O.<0>__Mission5Death_OnEnter;
if (obj == null)
{
hook_OnEnter val2 = Mission5Death_OnEnter;
<>O.<0>__Mission5Death_OnEnter = val2;
obj = (object)val2;
}
Mission5Death.OnEnter += (hook_OnEnter)obj;
}
}
private static void Mission5Death_OnEnter(orig_OnEnter orig, Mission5Death self)
{
orig.Invoke(self);
if (Object.op_Implicit((Object)(object)((SolusWing2BaseMissionState)self).solutionalHauntReferences) && Object.op_Implicit((Object)(object)((SolusWing2BaseMissionState)self).solutionalHauntReferences.PostFightMusic))
{
((SolusWing2BaseMissionState)self).solutionalHauntReferences.PostFightMusic.AddComponent<DestroyOnTimer>().duration = 10f;
}
}
}
public static class TeleporterAudioAdjuster
{
[CompilerGenerated]
private static class <>O
{
public static hook_UpdateTeleporterParameters <0>__MusicController_UpdateTeleporterParameters;
}
private static float proximityScalar;
public static void Init()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_007e: 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_0089: Expected O, but got Unknown
ConfigEntry<float> val = MusicSwapperPlugin.ExtrasConfig.Bind<float>("Teleporter Hum", "Volume Multiplier", 1f, new ConfigDescription("Reduce this value to dampen the volume of Teleporter hum (the Teleporter hum emits from the Teleporter and plays along with a stage's main track).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
if (val.Value != 1f)
{
MusicSwapperPlugin.Logger.LogMessage((object)"TeleporterAudioAdjuster extra is active");
proximityScalar = Mathf.Clamp01(val.Value);
object obj = <>O.<0>__MusicController_UpdateTeleporterParameters;
if (obj == null)
{
hook_UpdateTeleporterParameters val2 = MusicController_UpdateTeleporterParameters;
<>O.<0>__MusicController_UpdateTeleporterParameters = val2;
obj = (object)val2;
}
MusicController.UpdateTeleporterParameters += (hook_UpdateTeleporterParameters)obj;
}
}
private static void MusicController_UpdateTeleporterParameters(orig_UpdateTeleporterParameters orig, MusicController self, TeleporterInteraction teleporter, Transform cameraTransform, CharacterBody targetBody)
{
orig.Invoke(self, teleporter, cameraTransform, targetBody);
float value = self.rtpcTeleporterProximityValue.value;
self.rtpcTeleporterProximityValue.value = Util.Remap(value, 0f, 10000f, 10000f - 10000f * proximityScalar, 10000f);
}
}
}