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 d__1 : global::System.Collections.Generic.IEnumerator, 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 5__2; Context global::System.Collections.Generic.IEnumerator.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 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 }); 5__2 = 0; goto IL_00e5; } case 1: <>1__state = -1; 5__2++; if (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 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 slotField = ((ContainerWorker)(object)val4).AttachComponent>(true, (Action>)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(d__1))] private static global::System.Collections.Generic.IEnumerator 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 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 val2 = Pool.BorrowDictionary(); 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>)(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>)(object)skmr.Bones).Add().Target = target; } Pool.Return(ref val2); return "Bones setup"; } private static bool attachMissingBones(Dictionary bones, SkinnedMeshRenderer skmr) { for (int i = 0; i < ((SyncElementList>)(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 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"; }