using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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 GlobalEnums;
using Md.AudioManager;
using Md.GameManager;
using Md.QuitToMenu;
using Microsoft.CodeAnalysis;
using MonoDetour;
using MonoDetour.Cil;
using MonoDetour.DetourTypes;
using MonoDetour.HookGen;
using MonoDetour.Reflection.Unspeakable;
using MonoMod.Utils;
using MusicRando.Cache;
using MusicRando.MusicSelectionStrategies;
using Newtonsoft.Json;
using Silksong.AssetHelper.Core;
using Silksong.AssetHelper.ManagedAssets;
using Silksong.ModMenu.Plugin;
using UnityEngine;
using UnityEngine.ResourceManagement.ResourceLocations;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MusicRando")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.2.0")]
[assembly: AssemblyInformationalVersion("0.1.2+6beca92a7da41451cc7a5ba55100ed84813d1b59")]
[assembly: AssemblyProduct("MusicRando")]
[assembly: AssemblyTitle("MusicRando")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/flibber-hk/Silksong.MusicRando")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace Md.AudioManager
{
internal static class Start
{
public delegate void PrefixSignature(AudioManager self);
public delegate void PostfixSignature(AudioManager self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(AudioManager).GetMethod("Start", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("AudioManager", "Start");
}
}
internal static class ApplyMusicCue
{
public delegate void PrefixSignature(AudioManager self, ref MusicCue musicCue, ref float delayTime, ref float transitionTime, ref bool applySnapshot);
public delegate void PostfixSignature(AudioManager self, ref MusicCue musicCue, ref float delayTime, ref float transitionTime, ref bool applySnapshot);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(AudioManager).GetMethod("ApplyMusicCue", (BindingFlags)(-1), null, new Type[4]
{
typeof(MusicCue),
typeof(float),
typeof(float),
typeof(bool)
}, null) ?? throw new MissingMethodException("AudioManager", "ApplyMusicCue");
}
}
}
namespace Md.QuitToMenu
{
internal static class Start
{
public delegate void PrefixSignature(QuitToMenu self);
public delegate void PostfixSignature(QuitToMenu self, ref IEnumerator returnValue);
public delegate void PrefixMoveNextSignature(SpeakableEnumerator<object, QuitToMenu> self);
public delegate void PostfixMoveNextSignature(SpeakableEnumerator<object, QuitToMenu> self, ref bool continueEnumeration);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MonoDetourHook PrefixMoveNext(PrefixMoveNextSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>((MethodBase)StateMachineTarget(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook PostfixMoveNext(PostfixMoveNextSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>((MethodBase)StateMachineTarget(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHookMoveNext(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook((MethodBase)StateMachineTarget(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(QuitToMenu).GetMethod("Start", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("QuitToMenu", "Start");
}
public static MethodInfo StateMachineTarget()
{
return Extensions.GetStateMachineTarget((MethodInfo)Target());
}
}
}
namespace Md.GameManager
{
internal static class ContinueGame
{
public delegate void PrefixSignature(GameManager self);
public delegate void PostfixSignature(GameManager self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(GameManager).GetMethod("ContinueGame", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("GameManager", "ContinueGame");
}
}
internal static class StartNewGame
{
public delegate void PrefixSignature(GameManager self, ref bool permadeathMode, ref bool bossRushMode);
public delegate void PostfixSignature(GameManager self, ref bool permadeathMode, ref bool bossRushMode);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(GameManager).GetMethod("StartNewGame", (BindingFlags)(-1), null, new Type[2]
{
typeof(bool),
typeof(bool)
}, null) ?? throw new MissingMethodException("GameManager", "StartNewGame");
}
}
internal static class Start
{
public delegate void PrefixSignature(GameManager self);
public delegate void PostfixSignature(GameManager self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(GameManager).GetMethod("Start", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("GameManager", "Start");
}
}
internal static class PausedEvent
{
internal static class Invoke
{
public delegate void PrefixSignature(PausedEvent self, ref bool isPaused);
public delegate void PostfixSignature(PausedEvent self, ref bool isPaused);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(PausedEvent).GetMethod("Invoke", (BindingFlags)(-1), null, new Type[1] { typeof(bool) }, null) ?? throw new MissingMethodException("GameManager+PausedEvent", "Invoke");
}
}
}
internal static class GameStateEvent
{
internal static class Invoke
{
public delegate void PrefixSignature(GameStateEvent self, ref GameState gameState);
public delegate void PostfixSignature(GameStateEvent self, ref GameState gameState);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(GameStateEvent).GetMethod("Invoke", (BindingFlags)(-1), null, new Type[1] { typeof(GameState) }, null) ?? throw new MissingMethodException("GameManager+GameStateEvent", "Invoke");
}
}
}
internal static class BossLoad
{
internal static class Invoke
{
public delegate void PrefixSignature(BossLoad self);
public delegate void PostfixSignature(BossLoad self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(BossLoad).GetMethod("Invoke", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("GameManager+BossLoad", "Invoke");
}
}
}
internal static class EnterSceneEvent
{
internal static class Invoke
{
public delegate void PrefixSignature(EnterSceneEvent self);
public delegate void PostfixSignature(EnterSceneEvent self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(EnterSceneEvent).GetMethod("Invoke", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("GameManager+EnterSceneEvent", "Invoke");
}
}
}
internal static class SceneTransitionFinishEvent
{
internal static class Invoke
{
public delegate void PrefixSignature(SceneTransitionFinishEvent self);
public delegate void PostfixSignature(SceneTransitionFinishEvent self);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(SceneTransitionFinishEvent).GetMethod("Invoke", (BindingFlags)(-1), null, Array.Empty<Type>(), null) ?? throw new MissingMethodException("GameManager+SceneTransitionFinishEvent", "Invoke");
}
}
}
internal static class SceneTransitionBeganDelegate
{
internal static class Invoke
{
public delegate void PrefixSignature(SceneTransitionBeganDelegate self, ref SceneLoad sceneLoad);
public delegate void PostfixSignature(SceneTransitionBeganDelegate self, ref SceneLoad sceneLoad);
public static MonoDetourHook Prefix(PrefixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PrefixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook Postfix(PostfixSignature hook, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).Hook<PostfixDetour>(Target(), (Delegate)hook, config, applyByDefault);
}
public static MonoDetourHook ILHook(Manipulator manipulator, MonoDetourConfig? config = null, bool applyByDefault = true, MonoDetourManager? manager = null)
{
return (manager ?? DefaultMonoDetourManager.Instance).ILHook(Target(), manipulator, config, applyByDefault);
}
public static MethodBase Target()
{
return typeof(SceneTransitionBeganDelegate).GetMethod("Invoke", (BindingFlags)(-1), null, new Type[1] { typeof(SceneLoad) }, null) ?? throw new MissingMethodException("GameManager+SceneTransitionBeganDelegate", "Invoke");
}
}
}
}
namespace MonoDetour.HookGen
{
internal static class DefaultMonoDetourManager
{
internal static MonoDetourManager Instance { get; } = New();
internal static MonoDetourManager New()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
return new MonoDetourManager(typeof(DefaultMonoDetourManager).Assembly.GetName().Name);
}
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
internal class MonoDetourTargetsAttribute : Attribute, IMonoDetourTargets
{
public Type? TargetType { get; }
public bool IncludeNestedTypes { get; set; }
public string[]? Members { get; set; }
public string[]? MemberNamePrefixes { get; set; }
public string[]? MemberNameSuffixes { get; set; }
public bool GenerateControlFlowVariants { get; set; }
public MonoDetourTargetsAttribute(Type? targetType = null)
{
TargetType = targetType;
IncludeNestedTypes = true;
base..ctor();
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace MusicRando
{
internal static class ConfigSettings
{
public static ConfigEntry<RandomizationStrategyOption>? MusicRandomization;
public static void Init(ConfigFile config)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
MusicRandomization = config.Bind<RandomizationStrategyOption>("General", "MusicRandomization", RandomizationStrategyOption.OnChange, new ConfigDescription("When to randomize the music", (AcceptableValueBase)null, new object[1] { MenuElementGenerators.CreateRightDescGenerator(false) }));
}
}
public enum RandomizationStrategyOption
{
[Description("Randomize whenever the music changes")]
OnChange,
[Description("Randomize more often than usual")]
Chaos,
[Description("Select a song dependent on the vanilla song")]
Consistent,
[Description("Randomly decide when to randomize the music")]
RandoRando,
[Description("Do not randomize music")]
Disabled
}
public enum MusicAction
{
Ignore,
Replay,
Randomize
}
[MonoDetourTargets(typeof(GameManager))]
[MonoDetourTargets(typeof(QuitToMenu))]
internal static class GameEvents
{
private static readonly string Id = "MusicRando.GameEvents";
private static readonly MonoDetourManager mgr = new MonoDetourManager(Id);
public static bool IsInGame { get; private set; }
public static event Action? OnEnterGame;
public static event Action? OnQuitToMenu;
internal static void Hook()
{
ContinueGame.Postfix(AfterContinueGame, null, applyByDefault: true, mgr);
StartNewGame.Postfix(AfterStartNewGame, null, applyByDefault: true, mgr);
Md.QuitToMenu.Start.Postfix(AfterQuitGame, null, applyByDefault: true, mgr);
}
private static void AfterQuitGame(QuitToMenu self, ref IEnumerator returnValue)
{
AfterGameExit();
}
private static void AfterStartNewGame(GameManager self, ref bool permadeathMode, ref bool bossRushMode)
{
AfterGameEnter();
}
private static void AfterContinueGame(GameManager self)
{
AfterGameEnter();
}
private static void AfterGameEnter()
{
IsInGame = true;
Delegate[] array = GameEvents.OnEnterGame?.GetInvocationList() ?? Array.Empty<Action>();
for (int i = 0; i < array.Length; i++)
{
((Action)array[i])?.Invoke();
}
}
private static void AfterGameExit()
{
IsInGame = false;
Delegate[] array = GameEvents.OnQuitToMenu?.GetInvocationList() ?? Array.Empty<Action>();
for (int i = 0; i < array.Length; i++)
{
((Action)array[i])?.Invoke();
}
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MonoDetourTargets(typeof(AudioManager))]
[BepInPlugin("io.github.flibber-hk.musicrando", "MusicRando", "0.1.2")]
public class MusicRandoPlugin : BaseUnityPlugin
{
private ManagedResourceLocation<MusicCue>? _lastMusicCueLocation;
public const string Id = "io.github.flibber-hk.musicrando";
private static Dictionary<RandomizationStrategyOption, SelectionStrategy> Strategies { get; set; }
internal static ManualLogSource InstanceLogger { get; private set; }
public static string Name => "MusicRando";
public static string Version => "0.1.2";
private void Awake()
{
InstanceLogger = ((BaseUnityPlugin)this).Logger;
ConfigSettings.Init(((BaseUnityPlugin)this).Config);
GameEvents.Hook();
Strategies = new Dictionary<RandomizationStrategyOption, SelectionStrategy>
{
[RandomizationStrategyOption.OnChange] = new OnChangeSelectionStrategy(),
[RandomizationStrategyOption.Chaos] = new ChaosSelectionStrategy(),
[RandomizationStrategyOption.Consistent] = new ConsistentSelectionStrategy(),
[RandomizationStrategyOption.RandoRando] = new RandoRandoSelectionStrategy(),
[RandomizationStrategyOption.Disabled] = new DisabledSelectionStrategy()
};
ConfigEntry<RandomizationStrategyOption>? musicRandomization = ConfigSettings.MusicRandomization;
if (musicRandomization != null)
{
musicRandomization.SettingChanged += delegate
{
SelectionStrategy.Reset();
_lastMusicCueLocation = null;
if (Strategies.TryGetValue(ConfigSettings.MusicRandomization.Value, out SelectionStrategy value))
{
value.InitStrategy();
}
};
}
AddressablesData.InvokeAfterAddressablesLoaded((Action)FindAudioCues);
ApplyMusicCue.Prefix(OnApplyMusicCue);
GameEvents.OnQuitToMenu += OnQuitToMenu;
((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + Name + " (io.github.flibber-hk.musicrando) has loaded!"));
}
private void OnApplyMusicCue(AudioManager self, ref MusicCue musicCue, ref float delayTime, ref float transitionTime, ref bool applySnapshot)
{
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
RandomizationStrategyOption key = ConfigSettings.MusicRandomization?.Value ?? RandomizationStrategyOption.OnChange;
ManagedResourceLocation<MusicCue> location;
MusicAction musicAction = Strategies[key].Select(musicCue, out location);
if (location != null && !location.IsLoaded)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Failed to apply music cue: not loaded");
musicAction = MusicAction.Ignore;
}
if (musicAction == MusicAction.Replay)
{
if (_lastMusicCueLocation != null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Re-applying " + ((Object)_lastMusicCueLocation.Handle.Result).name + ", over " + ((Object)musicCue).name));
musicCue = _lastMusicCueLocation.Handle.Result;
return;
}
musicAction = MusicAction.Ignore;
}
if (musicAction != 0)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Applying " + ((Object)location.Handle.Result).name + " over " + ((Object)musicCue).name));
_lastMusicCueLocation = location;
musicCue = location.Handle.Result;
}
}
private void OnQuitToMenu()
{
SelectionStrategy.Reset();
_lastMusicCueLocation = null;
foreach (SelectionStrategy value in Strategies.Values)
{
value.InitStrategy();
}
}
private void FindAudioCues()
{
Stopwatch stopwatch = Stopwatch.StartNew();
List<string> cached = CacheManager.GetCached("musicrando.musiccues.json", Version, "0.1.0", GetMusicCuePrimaryKeys);
List<IResourceLocation> list = new List<IResourceLocation>();
IList<IResourceLocation> collection = default(IList<IResourceLocation>);
foreach (string item in cached)
{
if (AddressablesData.MainLocator.Locate((object)item, typeof(MusicCue), ref collection))
{
list.AddRange(collection);
}
}
SelectionStrategy.SetResourceLocations(list);
stopwatch.Stop();
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Prepared music cue locations in {stopwatch.ElapsedMilliseconds} ms");
}
private List<string> GetMusicCuePrimaryKeys()
{
List<string> list = new List<string>();
IList<IResourceLocation> list2 = default(IList<IResourceLocation>);
foreach (string item in AddressablesData.MainLocator.Keys.OfType<string>())
{
if (AddressablesData.MainLocator.Locate((object)item, typeof(MusicCue), ref list2))
{
list.Add(item);
}
}
return list;
}
}
internal static class RngExt
{
public static T Choose<T>(this Random rng, IList<T> things)
{
int index = rng.Next(things.Count);
return things[index];
}
public static T Choose<T>(this Random rng, IList<T> things, Func<T, bool> predicate)
{
List<T> things2 = things.Where(predicate).ToList();
return rng.Choose(things2);
}
}
}
namespace MusicRando.MusicSelectionStrategies
{
internal class ChaosSelectionStrategy : SelectionStrategy
{
protected override bool TrySelect(MusicCue origToPlay, out string? selected)
{
selected = SelectionStrategy.rng.Choose(SelectionStrategy.DifferentLocationKeys);
return true;
}
}
internal class ConsistentSelectionStrategy : SelectionStrategy
{
private readonly Dictionary<string, string> _previouslySelected = new Dictionary<string, string>();
private string? _lastOrigMusicCue;
public override void InitStrategy()
{
_previouslySelected.Clear();
_lastOrigMusicCue = null;
}
protected override bool TrySelect(MusicCue origToPlay, out string? selected)
{
if (_lastOrigMusicCue == ((Object)origToPlay).name)
{
selected = null;
return false;
}
if (_previouslySelected.TryGetValue(((Object)origToPlay).name, out selected))
{
return true;
}
selected = SelectionStrategy.rng.Choose(SelectionStrategy.DifferentLocationKeys);
_previouslySelected[((Object)origToPlay).name] = selected;
return true;
}
}
internal class DisabledSelectionStrategy : SelectionStrategy
{
protected override bool TrySelect(MusicCue origToPlay, out string? selected)
{
selected = null;
return false;
}
}
internal class OnChangeSelectionStrategy : SelectionStrategy
{
private string? _lastOrigMusicCue;
public override void InitStrategy()
{
_lastOrigMusicCue = null;
}
protected override bool TrySelect(MusicCue origToPlay, out string? selected)
{
if (((Object)origToPlay).name == _lastOrigMusicCue)
{
selected = null;
return false;
}
_lastOrigMusicCue = ((Object)origToPlay).name;
selected = SelectionStrategy.rng.Choose(SelectionStrategy.DifferentLocationKeys);
return true;
}
}
internal class RandoRandoSelectionStrategy : SelectionStrategy
{
protected override bool TrySelect(MusicCue origToPlay, out string? selected)
{
if (SelectionStrategy.rng.Next(8) != 5)
{
selected = null;
return false;
}
selected = SelectionStrategy.rng.Choose(SelectionStrategy.DifferentLocationKeys);
return true;
}
}
internal abstract class SelectionStrategy
{
protected static Random rng = new Random();
protected static Dictionary<string, ManagedResourceLocation<MusicCue>>? MusicResourceLocations;
protected static List<string> DifferentLocationKeys => MusicResourceLocations?.Keys.Where((string x) => (LastSelectedLocationKey ?? string.Empty) != x).ToList() ?? new List<string>();
protected static string? LastSelectedLocationKey { get; private set; }
internal static void SetResourceLocations(IEnumerable<IResourceLocation> locs)
{
if (MusicResourceLocations != null)
{
throw new InvalidOperationException("Can't set locs more than once!");
}
MusicResourceLocations = new Dictionary<string, ManagedResourceLocation<MusicCue>>();
Dictionary<string, IResourceLocation> dictionary = new Dictionary<string, IResourceLocation>();
foreach (IResourceLocation loc in locs)
{
if (!loc.InternalId.EndsWith("None.asset") && !MusicResourceLocations.ContainsKey(loc.InternalId))
{
MusicResourceLocations.Add(loc.InternalId, new ManagedResourceLocation<MusicCue>(loc));
dictionary.Add(loc.InternalId, loc);
}
}
MusicRandoPlugin.InstanceLogger.LogInfo((object)$"Found {MusicResourceLocations.Count} distinct music cues");
GameEvents.OnEnterGame += delegate
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
foreach (ManagedResourceLocation<MusicCue> value in MusicResourceLocations.Values)
{
value.Load();
}
};
GameEvents.OnQuitToMenu += delegate
{
foreach (ManagedResourceLocation<MusicCue> value2 in MusicResourceLocations.Values)
{
value2.Unload();
}
};
}
protected abstract bool TrySelect(MusicCue origToPlay, out string? selected);
public virtual void InitStrategy()
{
}
private MusicAction RunSelection(MusicCue origToPlay, out string? location)
{
location = null;
if ((MusicResourceLocations?.Count ?? 0) <= 0)
{
return MusicAction.Ignore;
}
if (!GameEvents.IsInGame)
{
return MusicAction.Ignore;
}
if (((Object)origToPlay).name == "None")
{
return MusicAction.Ignore;
}
if (!TrySelect(origToPlay, out location))
{
return MusicAction.Replay;
}
return MusicAction.Randomize;
}
internal MusicAction Select(MusicCue origToPlay, out ManagedResourceLocation<MusicCue>? location)
{
string location2;
MusicAction musicAction = RunSelection(origToPlay, out location2);
if (musicAction == MusicAction.Ignore || musicAction == MusicAction.Replay)
{
location = null;
return musicAction;
}
LastSelectedLocationKey = location2;
location = MusicResourceLocations[location2];
return musicAction;
}
public static void Reset()
{
LastSelectedLocationKey = null;
}
}
}
namespace MusicRando.Cache
{
internal class CachedObject<T> where T : class
{
public string? SilksongVersion { get; set; }
public string? PluginVersion { get; set; }
public required T Value { get; set; }
}
public static class CacheManager
{
private static string? _silksongVersion;
public static string SilksongVersion
{
get
{
if (_silksongVersion == null)
{
_silksongVersion = GetSilksongVersion();
}
return _silksongVersion;
}
}
private static string GetSilksongVersion()
{
return (typeof(Constants).GetField("GAME_VERSION", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetRawConstantValue() as string) ?? "UNKNOWN";
}
private static bool MetadataMismatch<T>(CachedObject<T> cached, string earliestAcceptableVersion) where T : class
{
if (cached.SilksongVersion == null || cached.SilksongVersion != SilksongVersion)
{
return true;
}
if (!Version.TryParse(earliestAcceptableVersion, out Version result))
{
return true;
}
if (cached.PluginVersion == null || !Version.TryParse(cached.PluginVersion, out Version result2))
{
return true;
}
if (result2 < result)
{
return true;
}
return false;
}
public static T GetCached<T>(string fileName, string currentPluginVersion, string earliestAcceptableVersion, Func<T> getter) where T : class
{
if (!Version.TryParse(currentPluginVersion, out Version _))
{
throw new ArgumentException("Cannot parse current plugin version to Version");
}
string filePath = Path.Combine(Paths.CachePath, fileName);
if (JsonHelper.TryLoadFromFile<CachedObject<T>>(filePath, out CachedObject<T> obj) && !MetadataMismatch(obj, earliestAcceptableVersion))
{
return obj.Value;
}
T val = getter();
new CachedObject<T>
{
SilksongVersion = SilksongVersion,
PluginVersion = currentPluginVersion,
Value = val
}.SerializeToFile(filePath);
return val;
}
}
internal static class JsonHelper
{
public static void SerializeToFile<T>(this T self, string filePath)
{
string contents = JsonConvert.SerializeObject((object)self, (Formatting)1);
File.WriteAllText(filePath, contents);
}
public static bool TryLoadFromFile<T>(string filePath, [NotNullWhen(true)] out T? obj)
{
obj = default(T);
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
{
return false;
}
try
{
string text = File.ReadAllText(filePath);
obj = JsonConvert.DeserializeObject<T>(text);
return obj != null;
}
catch (Exception)
{
return false;
}
}
}
}