Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MusicRando v0.1.2
MusicRando.dll
Decompiled 4 months agousing 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; } } } }