Decompiled source of SemiBot Train Menu v1.0.0

MenuParty.dll

Decompiled 4 days ago
using System;
using System.Collections;
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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MenuParty")]
[assembly: AssemblyTitle("MenuParty")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
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;
		}
	}
}
[BepInPlugin("omni.repo.harmony.mainmenu.swap", "MainMenu Prefab+Music Swap", "1.1.1")]
public class MainMenuPrefabSwapPlugin : BaseUnityPlugin
{
	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		Harmony val = new Harmony("omni.repo.harmony.mainmenu.swap");
		val.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"MainMenu Prefab+Music Swap loaded");
	}
}
[HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")]
public static class Patch_LevelGenerator_StartRoomGeneration
{
	[CompilerGenerated]
	private sealed class <ReplacementCoroutine>d__13 : IEnumerator<object>, IEnumerator, IDisposable
	{
		private int <>1__state;

		private object <>2__current;

		public LevelGenerator gen;

		public GameObject customPrefab;

		public AudioClip music;

		private GameObject <go>5__1;

		private Camera[] <>s__2;

		private int <>s__3;

		private Camera <cam>5__4;

		private GameObject <musicGO>5__5;

		private AudioSource <audio>5__6;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ReplacementCoroutine>d__13(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<go>5__1 = null;
			<>s__2 = null;
			<cam>5__4 = null;
			<musicGO>5__5 = null;
			<audio>5__6 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (WaitingFlag != null)
				{
					WaitingFlag.SetValue(gen, true);
				}
				gen.State = (LevelState)3;
				YeetGamesMenuMusic();
				<go>5__1 = Object.Instantiate<GameObject>(customPrefab, Vector3.zero, Quaternion.identity);
				<>s__2 = <go>5__1.GetComponentsInChildren<Camera>(true);
				for (<>s__3 = 0; <>s__3 < <>s__2.Length; <>s__3++)
				{
					<cam>5__4 = <>s__2[<>s__3];
					if ((Object)(object)<cam>5__4 != (Object)null && (Object)(object)<cam>5__4.targetTexture != (Object)null)
					{
						<cam>5__4.targetTexture = null;
					}
					<cam>5__4 = null;
				}
				<>s__2 = null;
				if ((Object)(object)gen.LevelParent != (Object)null)
				{
					<go>5__1.transform.parent = gen.LevelParent.transform;
				}
				if ((Object)(object)music != (Object)null)
				{
					<musicGO>5__5 = new GameObject("MainMenuMusic_Swap");
					<musicGO>5__5.transform.SetParent(<go>5__1.transform, false);
					<audio>5__6 = <musicGO>5__5.AddComponent<AudioSource>();
					<audio>5__6.clip = music;
					<audio>5__6.loop = true;
					<audio>5__6.playOnAwake = true;
					<audio>5__6.spatialBlend = 0f;
					<audio>5__6.volume = 1f;
					<audio>5__6.priority = 128;
					<audio>5__6.Play();
					<musicGO>5__5 = null;
					<audio>5__6 = null;
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (WaitingFlag != null)
				{
					WaitingFlag.SetValue(gen, false);
				}
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private const string BundleStem = "omnilikeag6";

	private const string PreferredFolder = "Omniscye-SemiBotMenu";

	private const string PrefabName = "Start Room - Main Menu";

	private const string MusicAssetName = "Constant Music - Main Menu";

	private const string GameMusicClipName = "msc main menu";

	private const string GameMusicSOName = "Constant Music - Main Menu";

	private static AssetBundle _bundle;

	private static GameObject _cachedPrefab;

	private static AudioClip _cachedMusic;

	private static bool _attemptedLoad;

	private static readonly FieldInfo WaitingFlag = AccessTools.Field(typeof(LevelGenerator), "waitingForSubCoroutine");

	private static bool InMainMenu()
	{
		RunManager instance = RunManager.instance;
		return (Object)(object)instance != (Object)null && (Object)(object)instance.levelCurrent == (Object)(object)instance.levelMainMenu;
	}

	private static bool Prefix(LevelGenerator __instance, ref IEnumerator __result)
	{
		if (!InMainMenu())
		{
			return true;
		}
		if (!EnsureAssetsLoaded())
		{
			return true;
		}
		__result = ReplacementCoroutine(__instance, _cachedPrefab, _cachedMusic);
		return false;
	}

	[IteratorStateMachine(typeof(<ReplacementCoroutine>d__13))]
	private static IEnumerator ReplacementCoroutine(LevelGenerator gen, GameObject customPrefab, AudioClip music)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ReplacementCoroutine>d__13(0)
		{
			gen = gen,
			customPrefab = customPrefab,
			music = music
		};
	}

	private static void YeetGamesMenuMusic()
	{
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		try
		{
			AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
			AudioSource[] array2 = array;
			foreach (AudioSource val in array2)
			{
				AudioClip val2 = (((Object)(object)val != (Object)null) ? val.clip : null);
				if ((Object)(object)val2 != (Object)null && StringEquals(((Object)val2).name, "msc main menu"))
				{
					try
					{
						val.Stop();
						val.mute = true;
						val.loop = false;
						val.clip = null;
						num++;
					}
					catch
					{
					}
				}
			}
		}
		catch
		{
		}
		try
		{
			AudioClip[] array3 = Resources.FindObjectsOfTypeAll<AudioClip>();
			AudioClip[] array4 = array3;
			foreach (AudioClip val3 in array4)
			{
				if ((Object)(object)val3 != (Object)null && StringEquals(((Object)val3).name, "msc main menu"))
				{
					try
					{
						Resources.UnloadAsset((Object)(object)val3);
						num2++;
					}
					catch (Exception ex)
					{
						Debug.LogWarning((object)("[MainMenuSwap] Couldn't UnloadAsset for 'msc main menu': " + ex.Message));
					}
				}
			}
		}
		catch
		{
		}
		try
		{
			ScriptableObject[] array5 = Resources.FindObjectsOfTypeAll<ScriptableObject>();
			ScriptableObject[] array6 = array5;
			foreach (ScriptableObject val4 in array6)
			{
				if ((Object)(object)val4 == (Object)null || !StringEquals(((Object)val4).name, "Constant Music - Main Menu"))
				{
					continue;
				}
				Type type = ((object)val4).GetType();
				bool flag = false;
				PropertyInfo property = type.GetProperty("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && typeof(AudioClip).IsAssignableFrom(property.PropertyType))
				{
					try
					{
						property.SetValue(val4, null);
						flag = true;
					}
					catch
					{
					}
				}
				FieldInfo field = type.GetField("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!flag && field != null && typeof(AudioClip).IsAssignableFrom(field.FieldType))
				{
					try
					{
						field.SetValue(val4, null);
						flag = true;
					}
					catch
					{
					}
				}
				FieldInfo field2 = type.GetField("music", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!flag && field2 != null && typeof(AudioClip).IsAssignableFrom(field2.FieldType))
				{
					try
					{
						field2.SetValue(val4, null);
						flag = true;
					}
					catch
					{
					}
				}
				if (flag)
				{
					((Object)val4).hideFlags = (HideFlags)(((Object)val4).hideFlags | 0x37);
					num3++;
				}
			}
		}
		catch
		{
		}
		Debug.Log((object)string.Format("[MainMenuSwap] Stopped {0} source(s), unloaded {1} clip(s), neutered {2} SO(s) for '{3}'.", num, num2, num3, "msc main menu"));
	}

	private static bool EnsureAssetsLoaded()
	{
		if (_attemptedLoad)
		{
			return (Object)(object)_cachedPrefab != (Object)null;
		}
		_attemptedLoad = true;
		try
		{
			string text = FindBundlePath(Paths.PluginPath, "omnilikeag6", "Omniscye-SemiBotMenu");
			if (text == null)
			{
				Debug.LogError((object)"[MainMenuSwap] Could not find asset bundle starting with 'omnilikeag6' under plugins (searched recursively).");
				return false;
			}
			_bundle = AssetBundle.LoadFromFile(text);
			if ((Object)(object)_bundle == (Object)null)
			{
				Debug.LogError((object)("[MainMenuSwap] Failed to load AssetBundle at: " + text));
				return false;
			}
			_cachedPrefab = _bundle.LoadAsset<GameObject>("Start Room - Main Menu");
			if ((Object)(object)_cachedPrefab == (Object)null)
			{
				Debug.LogError((object)("[MainMenuSwap] Prefab 'Start Room - Main Menu' not found in bundle: " + text));
				return false;
			}
			Debug.Log((object)("[MainMenuSwap] Loaded 'Start Room - Main Menu' from: " + text));
			_cachedMusic = TryLoadMusicClip(_bundle, "Constant Music - Main Menu");
			if ((Object)(object)_cachedMusic != (Object)null)
			{
				Debug.Log((object)"[MainMenuSwap] Loaded music 'Constant Music - Main Menu'.");
			}
			else
			{
				Debug.LogWarning((object)"[MainMenuSwap] Music asset 'Constant Music - Main Menu' not found or not an AudioClip; continuing without music swap.");
			}
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[MainMenuSwap] Exception loading assets: {arg}");
			return false;
		}
		return true;
	}

	private static AudioClip TryLoadMusicClip(AssetBundle bundle, string name)
	{
		AudioClip val = bundle.LoadAsset<AudioClip>(name);
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		Object val2 = bundle.LoadAsset(name);
		if (val2 == (Object)null)
		{
			return null;
		}
		Type type = ((object)val2).GetType();
		PropertyInfo property = type.GetProperty("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (property != null && typeof(AudioClip).IsAssignableFrom(property.PropertyType))
		{
			try
			{
				object? value = property.GetValue(val2);
				return (AudioClip)((value is AudioClip) ? value : null);
			}
			catch
			{
			}
		}
		FieldInfo field = type.GetField("clip", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null && typeof(AudioClip).IsAssignableFrom(field.FieldType))
		{
			try
			{
				object? value2 = field.GetValue(val2);
				return (AudioClip)((value2 is AudioClip) ? value2 : null);
			}
			catch
			{
			}
		}
		return null;
	}

	private static string FindBundlePath(string pluginsRoot, string stem, string preferredFolder)
	{
		string stem2 = stem;
		string preferredFolder2 = preferredFolder;
		if (string.IsNullOrEmpty(pluginsRoot) || !Directory.Exists(pluginsRoot))
		{
			Debug.LogError((object)("[MainMenuSwap] Plugins folder not found: '" + pluginsRoot + "'"));
			return null;
		}
		List<string> list = (from p in Directory.EnumerateFiles(pluginsRoot, "*", SearchOption.AllDirectories)
			where Path.GetFileName(p)?.StartsWith(stem2, StringComparison.OrdinalIgnoreCase) ?? false
			select p).ToList();
		if (list.Count == 0)
		{
			return null;
		}
		return Pick(list.ToArray());
		string Pick(string[] arr)
		{
			return (from p in arr
				orderby p.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).Any((string seg) => seg.Equals(preferredFolder2, StringComparison.OrdinalIgnoreCase)) descending, p.Count((char ch) => ch == Path.DirectorySeparatorChar || ch == Path.AltDirectorySeparatorChar), Path.GetFileName(p).Length
				select p).First();
		}
	}

	private static bool StringEquals(string a, string b)
	{
		return string.Equals(a?.Trim(), b?.Trim(), StringComparison.OrdinalIgnoreCase);
	}
}
namespace MenuParty
{
	[BepInPlugin("Omniscye.MenuParty", "MenuParty", "1.0")]
	public class MenuParty : BaseUnityPlugin
	{
		internal static MenuParty Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}