Decompiled source of Cubs Miku Plush v0.0.3

MikuPlush.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using MikuPlush;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "MikuPlush", "0.0.1", "GraciousCub", null)]
[assembly: MelonGame("Keepsake Games", "Jump Space")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MelonLoaderMod1")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MelonLoaderMod1")]
[assembly: AssemblyTitle("MelonLoaderMod1")]
[assembly: NeutralResourcesLanguage("en-US")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MikuPlush
{
	public class Core : MelonMod
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LemonAction <0>__DrawReloadText;
		}

		[CompilerGenerated]
		private sealed class <AutoScanRoutine>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				MeshSwap.TrySwapIncremental();
				<>2__current = null;
				<>1__state = 1;
				return true;
			}

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

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

		[CompilerGenerated]
		private sealed class <DelayedActivate>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Core <>4__this;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					MeshSwap.TrySwapAll();
					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 static float reloadMessageStart = -1f;

		public static MelonPreferences_Category ConfigCategory;

		public static MelonPreferences_Entry<int> BatchSize;

		public override void OnInitializeMelon()
		{
			ConfigCategory = MelonPreferences.CreateCategory("MikuPlush");
			BatchSize = ConfigCategory.CreateEntry<int>("BatchSize", 500, "Objects processed per frame", (string)null, false, false, (ValueValidator)null, (string)null);
			MelonLogger.Msg($"Miku Plush initialized. BatchSize = {BatchSize.Value}");
			MelonCoroutines.Start(AutoScanRoutine());
		}

		public override void OnLateUpdate()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (Keyboard.current != null && ((ButtonControl)Keyboard.current.f5Key).wasPressedThisFrame)
			{
				MelonLogger.Msg("Manual reload triggered.");
				MeshSwap.ClearCache();
				MelonCoroutines.Start(DelayedActivate());
				reloadMessageStart = Time.time;
				MelonEvent onGUI = MelonEvents.OnGUI;
				object obj = <>O.<0>__DrawReloadText;
				if (obj == null)
				{
					LemonAction val = DrawReloadText;
					<>O.<0>__DrawReloadText = val;
					obj = (object)val;
				}
				((MelonEventBase<LemonAction>)(object)onGUI).Subscribe((LemonAction)obj, 100, false);
				ConfigCategory.LoadFromFile(true);
			}
		}

		public static void DrawReloadText()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			if (reloadMessageStart > 0f && Time.time - reloadMessageStart < 3f)
			{
				GUI.Label(new Rect(20f, 20f, 500f, 50f), "<b><color=black><size=30>Reloading...</size></color></b>");
				return;
			}
			MelonEvent onGUI = MelonEvents.OnGUI;
			object obj = <>O.<0>__DrawReloadText;
			if (obj == null)
			{
				LemonAction val = DrawReloadText;
				<>O.<0>__DrawReloadText = val;
				obj = (object)val;
			}
			((MelonEventBase<LemonAction>)(object)onGUI).Unsubscribe((LemonAction)obj);
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			MeshSwap.ClearCache();
			MelonCoroutines.Start(DelayedActivate());
		}

		[IteratorStateMachine(typeof(<DelayedActivate>d__7))]
		private IEnumerator DelayedActivate()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DelayedActivate>d__7(0)
			{
				<>4__this = this
			};
		}

		[IteratorStateMachine(typeof(<AutoScanRoutine>d__8))]
		private static IEnumerator AutoScanRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <AutoScanRoutine>d__8(0);
		}
	}
	public static class MeshSwap
	{
		private static Mesh customMesh;

		private static Texture2D bodyTex;

		private static Texture2D normalTex;

		private static readonly HashSet<int> processedObjects = new HashSet<int>();

		private static GameObject[] sceneObjects;

		private static int scanIndex = 0;

		public static void ClearCache()
		{
			processedObjects.Clear();
			sceneObjects = null;
			scanIndex = 0;
		}

		private static void EnsureAssetsLoaded()
		{
			if ((Object)(object)customMesh != (Object)null)
			{
				return;
			}
			string text = Path.Combine(MelonEnvironment.ModsDirectory, "GraciousCub-Cubs_Miku_Plush", "mikuplush.bundle");
			if (File.Exists(text))
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if (!((Object)(object)val == (Object)null))
				{
					customMesh = val.LoadAsset<Mesh>("Assets/Jump_Gnome.fbx");
					bodyTex = val.LoadAsset<Texture2D>("Assets/Jump_Gnome_T1.png");
					normalTex = val.LoadAsset<Texture2D>("Assets/NormalMiku.png");
					val.Unload(false);
				}
			}
		}

		public static void TrySwapAll()
		{
			EnsureAssetsLoaded();
			if ((Object)(object)customMesh == (Object)null)
			{
				return;
			}
			foreach (GameObject item in Object.FindObjectsOfType<GameObject>())
			{
				if (((Object)item).name == "LabelText" && ((Il2CppObjectBase)item.GetComponent<TextMeshProUGUI>()).Cast<TMP_Text>().text == "Nisse")
				{
					((Il2CppObjectBase)item.GetComponent<TextMeshProUGUI>()).Cast<TMP_Text>().text = "Miku";
				}
				TrySwap(item);
			}
		}

		public static void TrySwapIncremental()
		{
			EnsureAssetsLoaded();
			if (!((Object)(object)customMesh == (Object)null))
			{
				if (sceneObjects == null || scanIndex >= sceneObjects.Length)
				{
					sceneObjects = Il2CppArrayBase<GameObject>.op_Implicit(Object.FindObjectsOfType<GameObject>());
					scanIndex = 0;
				}
				int num = Mathf.Max(1, Core.BatchSize.Value);
				int num2 = 0;
				while (num2 < num && scanIndex < sceneObjects.Length)
				{
					TrySwap(sceneObjects[scanIndex]);
					num2++;
					scanIndex++;
				}
			}
		}

		private static void TrySwap(GameObject targetObj)
		{
			if ((Object)(object)targetObj == (Object)null || ((Object)targetObj).name != "Jump_Gnome")
			{
				return;
			}
			int instanceID = ((Object)targetObj).GetInstanceID();
			if (processedObjects.Contains(instanceID))
			{
				return;
			}
			processedObjects.Add(instanceID);
			MeshFilter component = targetObj.GetComponent<MeshFilter>();
			if (!((Object)(object)component != (Object)null))
			{
				return;
			}
			component.mesh = customMesh;
			MeshRenderer component2 = targetObj.GetComponent<MeshRenderer>();
			Il2CppReferenceArray<Material> materials = ((Renderer)component2).materials;
			if ((Object)(object)bodyTex != (Object)null && ((Il2CppArrayBase<Material>)(object)materials)[0].HasProperty("_T1"))
			{
				((Il2CppArrayBase<Material>)(object)materials)[0].SetTexture("_T1", (Texture)(object)bodyTex);
			}
			foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
			{
				if (item.HasProperty("_T2"))
				{
					item.SetTexture("_T2", (Texture)(object)normalTex);
				}
				if (item.HasProperty("_T3"))
				{
					item.SetTexture("_T3", (Texture)null);
				}
				if (item.HasProperty("_M"))
				{
					item.SetTexture("_M", (Texture)null);
				}
				if (item.HasProperty("_ColorMainLookup"))
				{
					item.SetTexture("_ColorMainLookup", (Texture)null);
				}
				if (item.HasProperty("_ColorSecondaryLookup"))
				{
					item.SetTexture("_ColorSecondaryLookup", (Texture)null);
				}
				if (item.HasProperty("_ColorDetailLookup"))
				{
					item.SetTexture("_ColorDetailLookup", (Texture)null);
				}
			}
			((Renderer)component2).materials = materials;
			Shader val = Shader.Find("Unlit/Texture");
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			foreach (Material item2 in (Il2CppArrayBase<Material>)(object)materials)
			{
				item2.shader = val;
				if ((Object)(object)bodyTex != (Object)null)
				{
					item2.SetTexture("_MainTex", (Texture)(object)bodyTex);
				}
			}
		}
	}
}