Decompiled source of rearmature v1.0.0

BepInEx/plugins/ReArmature.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using Elements.Assets;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.UIX;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
[assembly: AssemblyCompany("CatSharkShin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.6.0")]
[assembly: AssemblyInformationalVersion("2.1.6+8dd81f21679b4f86a8e1b5049f884c15dbca07a8")]
[assembly: AssemblyProduct("ReArmature")]
[assembly: AssemblyTitle("ReArmature")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/CatSharkShin/ReArmature")]
[assembly: AssemblyVersion("2.1.6.0")]
[module: RefSafetyRules(11)]
namespace ReArmature;

[ResonitePlugin("CatSharkShin.ReArmature", "ReArmature", "2.1.6", "CatSharkShin", "https://github.com/CatSharkShin/ReArmature")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ReArmature : BasePlugin
{
	[HarmonyPatch(typeof(SkinnedMeshRenderer))]
	private class ReplaceOldMesh
	{
		[CompilerGenerated]
		private sealed class <Process>d__1 : global::System.Collections.Generic.IEnumerator<Context>, global::System.Collections.IEnumerator, global::System.IDisposable
		{
			private int <>1__state;

			private Context <>2__current;

			public SkinnedMeshRenderer skmr;

			public IButton button;

			public ButtonEventData data;

			public Slot RefArmature;

			private int <elapsedUpdates>5__2;

			Context global::System.Collections.Generic.IEnumerator<Context>.Current
			{
				[DebuggerHidden]
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return <>2__current;
				}
			}

			object global::System.Collections.IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return <>2__current;
				}
			}

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

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

			private bool MoveNext()
			{
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_0195: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					Mesh asset = ((MeshRenderer)skmr).Mesh.Asset;
					if (((asset != null) ? asset.Data : null) == null)
					{
						button.LabelText = "Cannot setup bones without a loaded asset";
						return false;
					}
					((MethodBase)((object)skmr).GetType().GetMethod("StripEmptyBones", (BindingFlags)36)).Invoke((object)skmr, new object[2] { button, data });
					<elapsedUpdates>5__2 = 0;
					goto IL_00e5;
				}
				case 1:
					<>1__state = -1;
					<elapsedUpdates>5__2++;
					if (<elapsedUpdates>5__2 > 600)
					{
						button.LabelText = "Cannot setup bones without a loaded asset";
						return false;
					}
					goto IL_00e5;
				case 2:
					{
						<>1__state = -1;
						button.LabelText = "Re-Setup bones";
						return false;
					}
					IL_00e5:
					if (((IComponentBase)button).Enabled)
					{
						Mesh asset2 = ((MeshRenderer)skmr).Mesh.Asset;
						if (((asset2 != null) ? asset2.Data : null) != null)
						{
							if (RefArmature == null)
							{
								Slot root = ObjectRootExtensions.GetObjectRoot(((Component)skmr).Slot, false).FindChild((Predicate<Slot>)((Slot s) => s.Name == "Armature"), -1);
								button.LabelText = SetupBones(skmr, root);
							}
							else
							{
								Slot root2 = RefArmature;
								button.LabelText = SetupBones(skmr, root2);
							}
							<>2__current = Context.WaitForSeconds(5.0);
							<>1__state = 2;
							return true;
						}
					}
					<>2__current = Context.WaitForNextUpdate();
					<>1__state = 1;
					return true;
				}
			}

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

			[DebuggerHidden]
			void global::System.Collections.IEnumerator.Reset()
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				throw new NotSupportedException();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SkinnedMeshRenderer), "BuildInspectorUI")]
		public static void Postfix(SkinnedMeshRenderer __instance, UIBuilder ui)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			ui.Style.MinHeight = 60f;
			ui.NestInto(ui.Empty("Re_Armature_Helper"));
			RectTransform val = default(RectTransform);
			RectTransform val2 = default(RectTransform);
			ui.HorizontalHeader(36f, ref val, ref val2);
			ui.Style.MinHeight = 24f;
			ui.NestInto(val);
			LocaleString val3 = LocaleString.op_Implicit("Re-Armature");
			ui.Text(ref val3, true, (Alignment?)(Alignment)4, true, (string)null);
			ui.NestOut();
			ui.NestInto(val2);
			Slot val4 = ui.Empty("Slot Reader");
			ui.NestInto(val4);
			ui.HorizontalLayout(4f, 0f, (Alignment?)null);
			ReferenceField<Slot> slotField = ((ContainerWorker<Component>)(object)val4).AttachComponent<ReferenceField<Slot>>(true, (Action<ReferenceField<Slot>>)null);
			SyncMemberEditorBuilder.Build(((Worker)slotField).GetSyncMember(3), "Armature", ((Worker)slotField).GetSyncMemberFieldInfo(3), ui, 0.3f);
			val3 = LocaleString.op_Implicit("Re-Setup bones");
			ui.Button(ref val3).LocalPressed += (ButtonEventHandler)delegate(IButton button, ButtonEventData data)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				((Worker)((Component)__instance).Slot).StartCoroutine(Process(button, data, __instance, slotField.Reference.Target));
			};
			ui.NestOut();
			ui.NestOut();
			ui.NestOut();
			ui.NestOut();
		}

		[IteratorStateMachine(typeof(<Process>d__1))]
		private static global::System.Collections.Generic.IEnumerator<Context> Process(IButton button, ButtonEventData data, SkinnedMeshRenderer skmr, Slot RefArmature)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			Mesh asset = ((MeshRenderer)skmr).Mesh.Asset;
			if (((asset != null) ? asset.Data : null) == null)
			{
				button.LabelText = "Cannot setup bones without a loaded asset";
				yield break;
			}
			((MethodBase)((object)skmr).GetType().GetMethod("StripEmptyBones", (BindingFlags)36)).Invoke((object)skmr, new object[2] { button, data });
			int elapsedUpdates = 0;
			while (true)
			{
				if (((IComponentBase)button).Enabled)
				{
					Mesh asset2 = ((MeshRenderer)skmr).Mesh.Asset;
					if (((asset2 != null) ? asset2.Data : null) != null)
					{
						break;
					}
				}
				yield return Context.WaitForNextUpdate();
				elapsedUpdates++;
				if (elapsedUpdates > 600)
				{
					button.LabelText = "Cannot setup bones without a loaded asset";
					yield break;
				}
			}
			if (RefArmature == null)
			{
				Slot root = ObjectRootExtensions.GetObjectRoot(((Component)skmr).Slot, false).FindChild((Predicate<Slot>)((Slot s) => s.Name == "Armature"), -1);
				button.LabelText = SetupBones(skmr, root);
			}
			else
			{
				button.LabelText = SetupBones(skmr, RefArmature);
			}
			yield return Context.WaitForSeconds(5.0);
			button.LabelText = "Re-Setup bones";
		}
	}

	public override void Load()
	{
		((BasePlugin)this).HarmonyInstance.PatchAll();
	}

	public static string SetupBones(SkinnedMeshRenderer skmr, Slot root)
	{
		MethodInfo method = ((object)skmr).GetType().GetMethod("GetBoneCandidates", (BindingFlags)36);
		Mesh asset = ((MeshRenderer)skmr).Mesh.Asset;
		MeshX val = ((asset != null) ? asset.Data : null);
		if (root == null)
		{
			return "Cannot setup bones without an Armature (not found)";
		}
		Dictionary<string, Slot> val2 = Pool.BorrowDictionary<string, Slot>();
		do
		{
			((MethodBase)method).Invoke((object)skmr, new object[2] { root, val2 });
		}
		while (attachMissingBones(val2, skmr));
		((MethodBase)method).Invoke((object)skmr, new object[2] { root, val2 });
		((SyncElementList<SyncRef<Slot>>)(object)skmr.Bones).Clear();
		Slot target = default(Slot);
		for (int i = 0; i < val.BoneCount; i++)
		{
			string name = val.GetBone(i).Name;
			val2.TryGetValue(name, ref target);
			((SyncElementList<SyncRef<Slot>>)(object)skmr.Bones).Add().Target = target;
		}
		Pool.Return<string, Slot>(ref val2);
		return "Bones setup";
	}

	private static bool attachMissingBones(Dictionary<string, Slot> bones, SkinnedMeshRenderer skmr)
	{
		for (int i = 0; i < ((SyncElementList<SyncRef<Slot>>)(object)skmr.Bones).Count; i++)
		{
			if (!bones.ContainsKey(skmr.Bones[i].Name))
			{
				attachBoneGroup(skmr.Bones[i], bones);
				return true;
			}
		}
		return false;
	}

	private static void attachBoneGroup(Slot boneToAttach, Dictionary<string, Slot> newArmatureDictionary)
	{
		Slot val = default(Slot);
		if (newArmatureDictionary.TryGetValue(boneToAttach.Parent.Name, ref val))
		{
			boneToAttach.Duplicate(val, false, (DuplicationSettings)null, false);
		}
		else
		{
			attachBoneGroup(boneToAttach.Parent, newArmatureDictionary);
		}
	}
}
public static class PluginMetadata
{
	public const string GUID = "CatSharkShin.ReArmature";

	public const string NAME = "ReArmature";

	public const string VERSION = "2.1.6";

	public const string AUTHORS = "CatSharkShin";

	public const string REPOSITORY_URL = "https://github.com/CatSharkShin/ReArmature";
}