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";
}