Decompiled source of NailongAvatar v1.4.1
plugins/NailongAvatar/NailongSwap.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Agents; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CellMenu; using GTFO.API; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using Player; using RigTools; using SNetwork; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [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 LocalSuteraSwap { internal static class ArmRetargeting { internal static Quaternion MirrorRotation(Quaternion rotation) { return new Quaternion(rotation.X, 0f - rotation.Y, 0f - rotation.Z, rotation.W); } internal static Vector3 MirrorDirection(Vector3 direction) { return new Vector3(0f - direction.X, direction.Y, direction.Z); } internal static Quaternion FromBind(Quaternion bindRotation, Vector3 bindDirection, Vector3 targetDirection) { Vector3 vector = Vector3.Normalize(bindDirection); Vector3 vector2 = Vector3.Normalize(targetDirection); float num = Math.Clamp(Vector3.Dot(vector, vector2), -1f, 1f); Quaternion quaternion; if (num < -0.9999f) { Vector3 value = Vector3.Cross(vector, Vector3.UnitY); if (value.LengthSquared() < 0.0001f) { value = Vector3.Cross(vector, Vector3.UnitZ); } quaternion = Quaternion.CreateFromAxisAngle(Vector3.Normalize(value), (float)Math.PI); } else { quaternion = Quaternion.Normalize(new Quaternion(Vector3.Cross(vector, vector2), 1f + num)); } return Quaternion.Normalize(quaternion * bindRotation); } internal static Quaternion FollowChest(Quaternion chest, Quaternion bindChest, Quaternion bindBone) { return Quaternion.Normalize(chest * Quaternion.Inverse(bindChest) * bindBone); } internal static void ClearTorso(Vector3 shoulder, Vector3 upper, Vector3 lower, float upperLength, float lowerLength, float side, out Vector3 elbow, out Vector3 wrist) { Vector3 vector = Downward(upper, side, (0.52f - shoulder.X * side) / upperLength); elbow = shoulder + vector * upperLength; Vector3 vector2 = Downward(lower, side, (0.54f - elbow.X * side) / lowerLength); float num = MathF.Acos(Math.Clamp(Vector3.Dot(vector, vector2), -1f, 1f)); if (num > 0.43633232f) { float num2 = 0.43633232f / num; vector2 = Vector3.Normalize((MathF.Sin((1f - num2) * num) * vector + MathF.Sin(num2 * num) * vector2) / MathF.Sin(num)); } wrist = elbow + vector2 * lowerLength; } private static Vector3 Downward(Vector3 desired, float side, float minimumOutward) { if (desired.LengthSquared() > 1E-06f) { desired = Vector3.Normalize(desired); } float num = Math.Clamp(MathF.Max(desired.X * side, minimumOutward), 0.15f, 0.85f); float num2 = Math.Clamp(desired.Z, -0.2f, 0.2f); return new Vector3(side * num, 0f - MathF.Sqrt(1f - num * num - num2 * num2), num2); } } internal sealed class AttachmentBudget { private int lastFrame = -1; internal bool TryAcquire(int frame) { if (lastFrame == frame) { return false; } lastFrame = frame; return true; } } internal sealed class AvatarData { public Texture2D SurfaceAtlas; public Shader SheenShader; public Shader ToonShader; private AssetBundle toonBundle; private static AssetBundle sharedToonBundle; private static int toonUsers; private bool toonLoaded; private AssetBundle materialBundle; public readonly Dictionary<string, Rect> MaterialRegions = new Dictionary<string, Rect>(); public Texture2D StockingMatcap; public Texture2D CrystalMatcap; public Node[] Nodes; internal readonly Dictionary<int, Vector3> PalmDirections = new Dictionary<int, Vector3>(); public Part[] Renderers; public bool[] ArmNodes; public bool[] FPSNodes; private readonly Dictionary<string, Texture2D> textures = new Dictionary<string, Texture2D>(); private readonly List<Material> materials = new List<Material>(); internal bool SharedResourcesAlive { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if ((!toonLoaded || Ic.B((Object)ToonShader)) && materials.All((Material m) => Ic.B((Object)m) && Ic.B((Object)m.shader))) { return textures.Values.All((Texture2D t) => Ic.B((Object)t)); } return false; } } private static Vector3 Vec(BinaryReader r) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } private static Quaternion Quat(BinaryReader r) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } private static Color Col(BinaryReader r) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } private static T[] Read<T>(BinaryReader r, Func<T> read) { int num = r.ReadInt32(); if (num < 0 || num > 4000000) { throw new InvalidDataException("Invalid array length"); } T[] array = new T[num]; for (int i = 0; i < num; i++) { array[i] = read(); } return array; } public static AvatarData Load(string path) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Expected O, but got Unknown //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Expected O, but got Unknown //IL_0786: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_07d1: Unknown result type (might be due to invalid IL or missing references) //IL_07d8: Unknown result type (might be due to invalid IL or missing references) //IL_0801: Unknown result type (might be due to invalid IL or missing references) //IL_080b: Expected O, but got Unknown //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_0840: Expected O, but got Unknown //IL_081e: Unknown result type (might be due to invalid IL or missing references) //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_085a: Unknown result type (might be due to invalid IL or missing references) AvatarData data = new AvatarData(); string text = Path.Combine(Path.GetDirectoryName(path), "nailong-liltoon.bundle"); if (File.Exists(text)) { try { if (!Ic.B((Object)sharedToonBundle)) { sharedToonBundle = AssetBundle.LoadFromFile(text); } data.toonBundle = sharedToonBundle; if (Ic.B((Object)data.toonBundle)) { toonUsers++; } if (!Ic.B((Object)data.toonBundle)) { throw new InvalidDataException("lilToon bundle failed"); } foreach (Object item in (Il2CppArrayBase<Object>)(object)data.toonBundle.LoadAllAssets(Il2CppType.Of<Shader>())) { Shader val = ((Il2CppObjectBase)item).TryCast<Shader>(); if (Ic.B((Object)val) && ((Object)val).name == "Hidden/lilToonCutout") { data.ToonShader = val; } } if (!Ic.B((Object)data.ToonShader) || !data.ToonShader.isSupported) { throw new InvalidDataException("lilToon shader unsupported"); } data.toonLoaded = true; Shader toonShader = data.ToonShader; ((Object)toonShader).hideFlags = (HideFlags)(((Object)toonShader).hideFlags | 0x3D); AssetBundle val2 = data.toonBundle; ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x3D); Plugin.Logger.LogInfo((object)("SUTERA_LILTOON_LOADED shader=" + ((Object)data.ToonShader).name)); } catch (Exception ex) { data.ToonShader = null; Plugin.Logger.LogWarning((object)("SUTERA_LILTOON_FALLBACK " + ex.Message)); } } string path2 = Path.Combine(Path.GetDirectoryName(path), "surface-atlas.png"); if (File.Exists(path2)) { Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, true, true); if (!ImageConversion.LoadImage(val3, Ic.A(File.ReadAllBytes(path2)), false)) { throw new InvalidDataException("Surface atlas failed to load"); } data.SurfaceAtlas = val3; data.textures["surface-atlas.png"] = val3; } string directoryName = Path.GetDirectoryName(path); string path3 = Path.Combine(directoryName, "material-regions.bin"); string text2 = Path.Combine(directoryName, "sutera-materials.bundle"); if (File.Exists(path3) && File.Exists(text2)) { try { using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path3))) { if (binaryReader.ReadString() != "SUTERA_MATERIAL_REGIONS") { throw new InvalidDataException("Material region header"); } int num = binaryReader.ReadInt32(); if (num < 0 || num > 1000) { throw new InvalidDataException("Material region count"); } for (int i = 0; i < num; i++) { data.MaterialRegions.Add(binaryReader.ReadString(), new Rect(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle())); } } data.materialBundle = AssetBundle.LoadFromFile(text2); if (!Ic.B((Object)data.materialBundle)) { throw new InvalidDataException("Material bundle could not be loaded"); } data.SheenShader = ((Il2CppObjectBase)data.materialBundle.LoadAsset("Assets/Shaders/MatcapSheen.shader", Il2CppType.Of<Shader>())).TryCast<Shader>(); if (!Ic.B((Object)data.SheenShader) || !data.SheenShader.isSupported) { throw new InvalidDataException("MatCap shader unsupported"); } data.StockingMatcap = data.ReadTexture(Path.Combine(directoryName, "stockings-matcap.png")); data.CrystalMatcap = data.ReadTexture(Path.Combine(directoryName, "crystal-matcap.png")); Plugin.Logger.LogInfo((object)("MATERIAL_DETAILS_LOADED shader=" + ((Object)data.SheenShader).name + " regions=" + data.MaterialRegions.Count)); } catch (Exception ex2) { data.SheenShader = null; Plugin.Logger.LogWarning((object)("Material details unavailable; stable GTFO material retained: " + ex2.Message)); } } BinaryReader r = new BinaryReader(File.OpenRead(path)); try { if (r.ReadString() != "GTFOAVATAR" || r.ReadInt32() != 1) { throw new InvalidDataException("Unknown avatar format"); } r.ReadString(); data.Nodes = Read(r, () => new Node { Name = r.ReadString(), Parent = r.ReadInt32(), Position = Vec(r), Rotation = Quat(r), Scale = Vec(r), Human = r.ReadInt32(), WorldRotation = Quat(r), WorldPosition = Vec(r) }); Dictionary<string, int> dictionary = data.Nodes.Where((Node n) => n.Human >= 0).ToDictionary((Node n) => BoneBase(n.Name), (Node n) => n.Human); Node[] nodes = data.Nodes; int value = 0; Node[] array = nodes; foreach (Node node in array) { if (node.Human < 0 && dictionary.TryGetValue(BoneBase(node.Name), out value)) { node.Human = value; } } data.ArmNodes = new bool[data.Nodes.Length]; data.FPSNodes = new bool[data.Nodes.Length]; for (int num3 = 0; num3 < data.Nodes.Length; num3++) { for (int num4 = num3; num4 >= 0; num4 = data.Nodes[num4].Parent) { int human = data.Nodes[num4].Human; if (human == 13 || human == 14) { data.ArmNodes[num3] = true; break; } } } for (int num5 = 0; num5 < data.Nodes.Length; num5++) { int num6 = num5; bool flag = false; bool flag2 = false; while (num6 >= 0) { int human2 = data.Nodes[num6].Human; if (human2 == 10 || human2 == 9) { flag2 = true; break; } if (human2 >= 0) { flag = true; } num6 = data.Nodes[num6].Parent; } data.FPSNodes[num5] = flag && !flag2; } data.Renderers = Read(r, () => new Part { Name = r.ReadString(), Transform = r.ReadInt32(), Skinned = r.ReadBoolean(), Vertices = Read(r, () => Vec(r)), Normals = Read(r, () => Vec(r)), UV = Read(r, (Func<Vector2>)(() => new Vector2(r.ReadSingle(), r.ReadSingle()))), Tangents = Read(r, (Func<Vector4>)(() => new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()))), Colors = Read(r, () => Col(r)), Weights = Read(r, delegate { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) BoneWeight result = default(BoneWeight); ((BoneWeight)(ref result)).boneIndex0 = r.ReadInt32(); ((BoneWeight)(ref result)).boneIndex1 = r.ReadInt32(); ((BoneWeight)(ref result)).boneIndex2 = r.ReadInt32(); ((BoneWeight)(ref result)).boneIndex3 = r.ReadInt32(); ((BoneWeight)(ref result)).weight0 = r.ReadSingle(); ((BoneWeight)(ref result)).weight1 = r.ReadSingle(); ((BoneWeight)(ref result)).weight2 = r.ReadSingle(); ((BoneWeight)(ref result)).weight3 = r.ReadSingle(); return result; }), Bindposes = Read(r, delegate { //IL_0002: 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) Matrix4x4 result = default(Matrix4x4); for (int j = 0; j < 16; j++) { ((Matrix4x4)(ref result))[j] = r.ReadSingle(); } return result; }), Bones = Read(r, () => r.ReadInt32()), RootBone = r.ReadInt32(), Bounds = new Bounds(Vec(r), Vec(r)), Surfaces = Read(r, delegate { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown Surface surface = new Surface { Triangles = Read(r, () => r.ReadInt32()) }; string text3 = r.ReadString(); string text4 = r.ReadString(); Color color = Col(r); Vector2 mainTextureScale = default(Vector2); ((Vector2)(ref mainTextureScale))..ctor(r.ReadSingle(), r.ReadSingle()); Vector2 mainTextureOffset = default(Vector2); ((Vector2)(ref mainTextureOffset))..ctor(r.ReadSingle(), r.ReadSingle()); int num7 = r.ReadInt32(); float num8 = r.ReadSingle(); int num9 = r.ReadInt32(); Shader val5 = Shader.Find("Standard"); if (!Ic.B((Object)val5)) { throw new InvalidOperationException("Standard shader unavailable"); } surface.Material = new Material(val5); ((Object)surface.Material).name = text3 + "_GTFO"; surface.Material.color = color; surface.Material.SetFloat("_Glossiness", 0.1f); surface.Material.SetFloat("_Metallic", 0f); if (!string.IsNullOrEmpty(text4)) { Texture2D value2 = null; if (!data.textures.TryGetValue(text4, out value2)) { value2 = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(value2, Ic.A(File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(path), text4))), false)) { throw new InvalidDataException("Texture failed: " + text4); } data.textures[text4] = value2; } surface.Material.mainTexture = (Texture)value2; } surface.Material.mainTextureScale = mainTextureScale; surface.Material.mainTextureOffset = mainTextureOffset; surface.Material.SetInt("_Cull", num9); if (num7 == 1) { surface.Material.SetFloat("_Mode", 1f); surface.Material.SetFloat("_Cutoff", num8); surface.Material.SetInt("_SrcBlend", 1); surface.Material.SetInt("_DstBlend", 0); surface.Material.SetInt("_ZWrite", 1); surface.Material.EnableKeyword("_ALPHATEST_ON"); surface.Material.SetOverrideTag("RenderType", "TransparentCutout"); surface.Material.renderQueue = 2450; } data.materials.Add(surface.Material); return surface; }) }); if (r.BaseStream.Position != r.BaseStream.Length) { throw new InvalidDataException("Unexpected avatar bytes"); } } finally { if (r != null) { ((IDisposable)r).Dispose(); } } foreach (Material material in data.materials) { ((Object)material).hideFlags = (HideFlags)(((Object)material).hideFlags | 0x3D); } foreach (Texture2D value3 in data.textures.Values) { ((Object)value3).hideFlags = (HideFlags)(((Object)value3).hideFlags | 0x3D); } if (Ic.B((Object)data.SheenShader)) { Shader sheenShader = data.SheenShader; ((Object)sheenShader).hideFlags = (HideFlags)(((Object)sheenShader).hideFlags | 0x3D); } if (Ic.B((Object)data.materialBundle)) { AssetBundle val4 = data.materialBundle; ((Object)val4).hideFlags = (HideFlags)(((Object)val4).hideFlags | 0x3D); } return data; } private Texture2D ReadTexture(string path) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false); textures[path] = val; if (!ImageConversion.LoadImage(val, Ic.A(File.ReadAllBytes(path)), false)) { throw new InvalidDataException("Texture failed: " + Path.GetFileName(path)); } ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } public void Dispose() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown Part[] renderers = Renderers; foreach (Part part in renderers) { if (Ic.B((Object)part.BodyMesh)) { Object.Destroy((Object)part.BodyMesh); } if (Ic.B((Object)part.ArmsMesh)) { Object.Destroy((Object)part.ArmsMesh); } } foreach (Material material in materials) { if (Ic.B((Object)material)) { Object.Destroy((Object)material); } } foreach (Texture2D value in textures.Values) { if (Ic.B((Object)value)) { Object.Destroy((Object)value); } } if (Ic.B((Object)materialBundle)) { materialBundle.Unload(true); } if (Ic.B((Object)toonBundle)) { toonBundle = null; if (--toonUsers == 0) { sharedToonBundle.Unload(true); sharedToonBundle = null; } } } private static string BoneBase(string name) { int num = name.IndexOf('('); if (num >= 0) { name = name.Substring(0, num); } return new string(name.ToLowerInvariant().Where(char.IsLetterOrDigit).ToArray()); } } internal static class Compatibility { private const BindingFlags Static = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags Instance = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static Type manukaOutfit; private static Type manukaDriver; private static bool ownSelection; internal static void Initialize(Harmony harmony) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown manukaOutfit = (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetType("LocalAvatarSwap.ManukaOutfit", throwOnError: false)).FirstOrDefault((Type t) => t != null); if (!(manukaOutfit == null)) { manukaDriver = manukaOutfit.Assembly.GetType("LocalAvatarSwap.Driver"); harmony.Patch((MethodBase)manukaOutfit.GetMethod("Choose", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), new HarmonyMethod(typeof(Compatibility), "ManukaChoice", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)manukaOutfit.GetMethod("Receive", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), new HarmonyMethod(typeof(Compatibility), "ManukaReceive", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Logger.LogInfo((object)"SUTERA_COEXIST MANUKA wardrobe compatibility installed; independent player selections remain."); } } private static void ManukaChoice(bool __0) { if (__0 && !ownSelection) { SuteraOutfit.ClearLocalForManuka(); } } private static void ManukaReceive(ulong __0, byte[] __1) { if (__1 != null && __1.Length == 3 && __1[0] == 1 && __1[2] == 1) { SuteraOutfit.ClearRemoteForManuka(__0); } } internal static void OnSelectingSutera() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown if (manukaOutfit == null || ownSelection) { return; } ownSelection = true; try { object value = manukaOutfit.GetField("previews", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); ((IDictionary)((value is IDictionary) ? value : null))?.Clear(); SNet_Player localPlayer = SNet.LocalPlayer; if ((Object)localPlayer != (Object)null) { ReleaseOther(localPlayer.Lookup); } manukaOutfit.GetMethod("Choose", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Invoke(null, new object[1] { false }); } finally { ownSelection = false; } } internal static void OnRemoteSutera(ulong lookup) { if (!(manukaOutfit == null)) { object value = manukaOutfit.GetField("remote", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); IDictionary dictionary = (IDictionary)((value is IDictionary) ? value : null); if (dictionary != null) { dictionary[lookup] = false; } ReleaseOther(lookup); } } private static bool Includes(SNet_Player owner, ulong lookup) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if ((Object)owner == (Object)null) { return false; } if (owner.Lookup == lookup) { return true; } SNet_Player master = SNet.Master; if (owner.IsBot && (Object)master != (Object)null) { return master.Lookup == lookup; } return false; } internal static void ReleaseSutera(ulong lookup) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown Driver instance = Driver.Instance; if (!Ic.B((Object)instance)) { return; } IEnumerable obj = typeof(Driver).GetField("rigs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(instance) as IEnumerable; List<GameObject> list = new List<GameObject>(); foreach (Rig item in obj) { if (Includes(item.NetworkOwner, lookup) && Ic.B((Object)item.RenderRoot)) { list.Add(item.RenderRoot); } } foreach (GameObject item2 in list) { instance.RestoreRoot(item2); } } private static void ReleaseOther(ulong lookup) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown Type type = manukaDriver; object obj; if (type == null) { obj = null; } else { FieldInfo field = type.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); obj = ((field != null) ? field.GetValue(null) : null); } object obj2 = obj; if (obj2 == null) { return; } IEnumerable obj3 = manukaDriver.GetField("rigs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(obj2) as IEnumerable; List<GameObject> list = new List<GameObject>(); foreach (object item in obj3) { Type type2 = item.GetType(); object value = type2.GetField("NetworkOwner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(item); SNet_Player owner = (SNet_Player)((value is SNet_Player) ? value : null); object value2 = type2.GetField("RenderRoot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(item); GameObject val = (GameObject)((value2 is GameObject) ? value2 : null); if (Includes(owner, lookup) && Ic.B((Object)val)) { list.Add(val); } } MethodInfo method = manukaDriver.GetMethod("RestoreRoot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (GameObject item2 in list) { method.Invoke(obj2, new object[1] { item2 }); } } } public sealed class Driver : MonoBehaviour { internal static Driver Instance; private readonly Dictionary<int, AvatarData> datas = new Dictionary<int, AvatarData>(); private readonly List<Rig> rigs = new List<Rig>(); private readonly Dictionary<int, float> rejected = new Dictionary<int, float>(); private float nextScan; private readonly AttachmentBudget attachmentBudget = new AttachmentBudget(); private bool failed; private float nextConfig; private readonly EquipmentSettlement equipmentSettlement = new EquipmentSettlement(); private bool gameplayView; private float performanceAt; private int performanceFrames; private double animationMilliseconds; private double fpsAnimationMilliseconds; private double fpsAnimationMaximum; private int fpsAnimationSamples; private float nextFpsReport = 30f; private long updateAllocated; private long animationAllocated; private float worstFrame; private PlayerAgent[] cachedPlayers = (PlayerAgent[])(object)new PlayerAgent[0]; private CM_PlayerLobbyBar[] cachedLobby = (CM_PlayerLobbyBar[])(object)new CM_PlayerLobbyBar[0]; private double worstUpdate; private double worstDiscovery; private double previousUpdate; private int previousGc0; private int previousGc1; private int previousGc2; public Driver(IntPtr p) : base(p) { } internal void RestoreRoot(GameObject root, bool waitForEquipment = true) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0068: Expected O, but got Unknown if (waitForEquipment) { equipmentSettlement.Changed(((Object)root).GetInstanceID(), Time.unscaledTime); } else { equipmentSettlement.Selected(((Object)root).GetInstanceID()); } nextScan = 0f; for (int num = rigs.Count - 1; num >= 0; num--) { if ((Object)rigs[num].RenderRoot == (Object)root) { Plugin.Logger.LogDebug((object)("AVATAR_REMOVE reason=native-equip arms=" + rigs[num].Arms)); rigs[num].Dispose(); rigs.RemoveAt(num); } } } internal void RefreshOutfit() { nextScan = 0f; } public void Update() { long timestamp = Stopwatch.GetTimestamp(); long allocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread(); try { UpdateCore(); } finally { previousUpdate = (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; worstUpdate = Math.Max(worstUpdate, previousUpdate); updateAllocated += GC.GetAllocatedBytesForCurrentThread() - allocatedBytesForCurrentThread; } } private void UpdateCore() { //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Expected O, but got Unknown //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Expected O, but got Unknown //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Expected O, but got Unknown //IL_075c: Unknown result type (might be due to invalid IL or missing references) //IL_0766: Expected O, but got Unknown //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e4: Expected O, but got Unknown //IL_07a1: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Expected O, but got Unknown //IL_08f0: Unknown result type (might be due to invalid IL or missing references) //IL_08fa: Expected O, but got Unknown //IL_0939: Unknown result type (might be due to invalid IL or missing references) //IL_0943: Expected O, but got Unknown //IL_0912: Unknown result type (might be due to invalid IL or missing references) //IL_091c: Expected O, but got Unknown //IL_083c: Unknown result type (might be due to invalid IL or missing references) //IL_0846: Expected O, but got Unknown //IL_0856: Unknown result type (might be due to invalid IL or missing references) //IL_0860: Expected O, but got Unknown Hotkeys.Poll(); Instance = this; if (Time.unscaledTime >= nextConfig) { nextConfig = Time.unscaledTime + 1f; SuteraOutfit.Tick(); string path = Path.Combine(Plugin.Folder, "reload.request"); if (File.Exists(path)) { File.Delete(path); foreach (Rig rig in rigs) { rig.Dispose(); } rigs.Clear(); rejected.Clear(); foreach (AvatarData value in datas.Values) { value.Dispose(); } datas.Clear(); failed = false; Plugin.Logger.LogInfo((object)"Avatar resources reset for live diagnostic reload."); } } if (Hotkeys.Pressed((KeyCode)288)) { Plugin.Enabled.Value = !Plugin.Enabled.Value; Plugin.Logger.LogInfo((object)("Replacement enabled: " + Plugin.Enabled.Value)); } if (Hotkeys.Pressed((KeyCode)285)) { Plugin.SecondaryMotion.Value = !Plugin.SecondaryMotion.Value; Plugin.Logger.LogInfo((object)("SUTERA_SECONDARY_MOTION enabled=" + Plugin.SecondaryMotion.Value)); } if (Hotkeys.Pressed((KeyCode)287)) { Plugin.UseLilToon.Value = !Plugin.UseLilToon.Value; foreach (Rig rig2 in rigs) { rig2.Dispose(); } rigs.Clear(); rejected.Clear(); nextScan = 0f; Plugin.Logger.LogInfo((object)("SUTERA_LILTOON enabled=" + Plugin.UseLilToon.Value)); } if (Hotkeys.Pressed((KeyCode)286)) { Plugin.StockingDetails.Value = !Plugin.StockingDetails.Value; Plugin.Logger.LogInfo((object)("Stocking fabric sheen: " + Plugin.StockingDetails.Value)); } if (Hotkeys.Pressed((KeyCode)290)) { Plugin.FirstPerson.Value = !Plugin.FirstPerson.Value; nextScan = 0f; Plugin.Logger.LogInfo((object)("First person global switch: " + Plugin.FirstPerson.Value + "; per-outfit settings preserved.")); } if (Hotkeys.Pressed((KeyCode)289)) { string text = Path.Combine(Plugin.Folder, "in-game-" + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".png"); ScreenCapture.CaptureScreenshot(text); Plugin.Logger.LogInfo((object)("Screenshot requested: " + text)); foreach (Rig rig3 in rigs) { DiagnoseSafely(rig3); } } for (int num = rigs.Count - 1; num >= 0; num--) { if (!rigs[num].Valid || !Plugin.Enabled.Value || (!Plugin.AllPlayers.Value && Ic.B((Object)rigs[num].Owner) && !((Agent)rigs[num].Owner).IsLocallyOwned) || (rigs[num].Arms && (!Plugin.FirstPerson.Value || !Plugin.OutfitUsesFirstPerson(rigs[num].Outfit)))) { Plugin.Logger.LogDebug((object)("AVATAR_REMOVE reason=invalid-or-disabled arms=" + rigs[num].Arms)); rigs[num].Dispose(); rigs.RemoveAt(num); } } if (!Plugin.Enabled.Value || failed || Time.unscaledTime < nextScan) { return; } nextScan = Time.unscaledTime + 1f; try { gameplayView = false; foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras) { if (Ic.B((Object)item) && ((Behaviour)item).isActiveAndEnabled && ((Component)item).gameObject.activeInHierarchy && ((Object)item).name == "FPSLookCamera") { gameplayView = true; break; } } for (int num2 = rigs.Count - 1; num2 >= 0; num2--) { if (rigs[num2].Arms && !gameplayView) { Plugin.Logger.LogDebug((object)"AVATAR_REMOVE reason=no-gameplay-camera"); rigs[num2].Dispose(); rigs.RemoveAt(num2); } } for (int num3 = rigs.Count - 1; num3 >= 0; num3--) { if (!SuteraOutfit.ShouldUse(rigs[num3].NetworkOwner, rigs[num3].RenderRoot)) { rigs[num3].Dispose(); rigs.RemoveAt(num3); } } bool flag = false; foreach (AvatarData value2 in datas.Values) { if (!value2.SharedResourcesAlive) { flag = true; break; } } if (flag) { foreach (Rig rig4 in rigs) { rig4.Dispose(); } rigs.Clear(); rejected.Clear(); foreach (AvatarData value3 in datas.Values) { value3.Dispose(); } datas.Clear(); Plugin.Logger.LogWarning((object)"AVATAR_RESOURCE_RECOVERY cached Unity assets expired; reload on next selected player."); } long timestamp = Stopwatch.GetTimestamp(); List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel; cachedPlayers = ((playerAgentsInLevel != null) ? Ic.A2<PlayerAgent>(playerAgentsInLevel.ToArray()) : Array.Empty<PlayerAgent>()); CM_PageLoadout current2 = CM_PageLoadout.Current; Il2CppReferenceArray<CM_PlayerLobbyBar> val = (Ic.B((Object)current2) ? current2.m_playerLobbyBars : null); cachedLobby = ((val != null) ? ((IEnumerable<CM_PlayerLobbyBar>)val).ToArray() : Array.Empty<CM_PlayerLobbyBar>()); worstDiscovery = Math.Max(worstDiscovery, (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency); PlayerAgent[] array = cachedPlayers; foreach (PlayerAgent val2 in array) { if (!Ic.B((Object)val2) || (!Plugin.AllPlayers.Value && !((Agent)val2).IsLocallyOwned)) { continue; } GameObject renderRoot = ((val2.RigSwitch != null && val2.RigSwitch.m_data != null) ? val2.RigSwitch.m_data.m_rootObject : (Ic.B((Object)val2.PlayerSyncModel) ? ((Component)val2.PlayerSyncModel).gameObject : null)); int num4 = SuteraOutfit.OutfitOf(val2.Owner); if (num4 < 0) { continue; } Attach(val2, val2.AnimatorBody, arms: false, renderRoot, val2.Owner, num4); if (gameplayView && ((Agent)val2).IsLocallyOwned && Plugin.FirstPerson.Value && Plugin.OutfitUsesFirstPerson(num4)) { FirstPersonItemHolder fPItemHolder = val2.FPItemHolder; PlayerFPSBody val3 = (Ic.B((Object)fPItemHolder) ? fPItemHolder.FPSArms : null); if (Ic.B((Object)val3)) { GameObject renderRoot2 = ((val3.m_rigSwitch != null && val3.m_rigSwitch.m_data != null) ? val3.m_rigSwitch.m_data.m_rootObject : val3.m_modelRoot); Attach(val2, val3.m_anim, arms: true, renderRoot2, val2.Owner, num4); } } } CM_PlayerLobbyBar[] array2 = cachedLobby; foreach (CM_PlayerLobbyBar val4 in array2) { if (Ic.B((Object)val4) && Ic.B((Object)val4.m_playerModel) && (Plugin.AllPlayers.Value || (Ic.B((Object)val4.m_player) && val4.m_player.IsLocal))) { Animator animator = (Ic.B((Object)val4.m_playerAnim) ? val4.m_playerAnim : val4.m_playerModel.GetComponentInChildren<Animator>()); GameObject renderRoot3 = ((val4.m_rigSwitch != null && val4.m_rigSwitch.m_data != null) ? val4.m_rigSwitch.m_data.m_rootObject : val4.m_playerModel); int num5 = SuteraOutfit.OutfitOf(val4.m_player); if (num5 >= 0) { Attach(null, animator, arms: false, renderRoot3, val4.m_player, num5); } } } } catch (Exception ex) { failed = true; Plugin.Logger.LogError((object)("Avatar load failed; original models retained: " + ex)); } } private void Attach(PlayerAgent owner, Animator animator, bool arms, GameObject renderRoot, SNet_Player networkOwner, int outfit) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00e3: Expected O, but got Unknown //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Expected O, but got Unknown //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Expected O, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Expected O, but got Unknown if (!Ic.B((Object)animator) || !((Component)animator).gameObject.activeInHierarchy || !Ic.B((Object)renderRoot) || !renderRoot.activeInHierarchy) { return; } if (!equipmentSettlement.Ready(((Object)renderRoot).GetInstanceID(), Time.unscaledTime)) { nextScan = 0f; return; } Rig rig = rigs.FirstOrDefault((Rig x) => (Object)x.Animator == (Object)animator); if (rig != null) { bool flag = (Object)rig.NetworkOwner != (Object)null && (Object)networkOwner != (Object)null && rig.NetworkOwner.Lookup == networkOwner.Lookup; if (rig.Installed && (Object)rig.RenderRoot == (Object)renderRoot && flag && rig.Outfit == outfit) { return; } } int instanceID = ((Object)animator).GetInstanceID(); float value = 0f; if (rejected.TryGetValue(instanceID, out value) && Time.unscaledTime < value) { return; } if (!attachmentBudget.TryAcquire(Time.frameCount)) { nextScan = 0f; return; } try { if (!datas.TryGetValue(outfit, out var value2)) { int num = Mathf.Clamp(outfit, 0, Plugin.OutfitFiles.Length - 1); string text = Plugin.OutfitFiles[num]; value2 = AvatarData.Load(Path.Combine(Plugin.Folder, text)); datas[outfit] = value2; Plugin.Logger.LogInfo((object)("AVATAR_LOADED outfit=" + outfit + " file=" + text + " nodes=" + value2.Nodes.Length + " renderers=" + value2.Renderers.Length)); nextScan = 0f; return; } if (rig != null) { rig.Dispose(); rigs.Remove(rig); Plugin.Logger.LogDebug((object)"AVATAR_REATTACH reason=renderer-root-owner-or-outfit-changed"); } Rig rig2 = new Rig(value2, owner, animator, arms, renderRoot, outfit); rig2.NetworkOwner = networkOwner; rigs.Add(rig2); rejected.Remove(instanceID); Plugin.Logger.LogDebug((object)("AVATAR_ATTACHED slot=" + (Ic.B((Object)owner) ? owner.PlayerSlotIndex.ToString() : "lobby") + " arms=" + arms + " mappedBones=" + rig2.MappingCount + " player_lookup=" + (((Object)networkOwner != (Object)null) ? networkOwner.Lookup.ToString() : "none") + " bot=" + ((Object)networkOwner != (Object)null && networkOwner.IsBot) + " local=" + ((Object)networkOwner != (Object)null && networkOwner.IsLocal))); } catch (Exception ex) { rejected[instanceID] = Time.unscaledTime + 5f; Plugin.Logger.LogWarning((object)("Avatar attachment skipped; original model retained: " + ex.Message)); } } public void LateUpdate() { long timestamp = Stopwatch.GetTimestamp(); long allocatedBytesForCurrentThread = GC.GetAllocatedBytesForCurrentThread(); foreach (Rig rig in rigs) { try { if (rig.Valid) { long num = (rig.Arms ? Stopwatch.GetTimestamp() : 0); rig.Animate(); if (rig.Arms) { double num2 = (double)(Stopwatch.GetTimestamp() - num) * 1000.0 / (double)Stopwatch.Frequency; fpsAnimationMilliseconds += num2; fpsAnimationMaximum = Math.Max(fpsAnimationMaximum, num2); fpsAnimationSamples++; } } } catch (Exception ex) { rig.Dispose(); Plugin.Logger.LogWarning((object)("Retargeting stopped: " + ex.Message)); } } animationMilliseconds += (double)(Stopwatch.GetTimestamp() - timestamp) * 1000.0 / (double)Stopwatch.Frequency; animationAllocated += GC.GetAllocatedBytesForCurrentThread() - allocatedBytesForCurrentThread; performanceFrames++; if (Time.unscaledTime >= nextFpsReport) { if (fpsAnimationSamples > 0) { Plugin.Logger.LogInfo((object)("AVATAR_FPS_COST cpu_avg_ms=" + (fpsAnimationMilliseconds / (double)fpsAnimationSamples).ToString("F3") + " cpu_max_ms=" + fpsAnimationMaximum.ToString("F3") + " samples=" + fpsAnimationSamples + " toon=" + FirstPersonRendering.UseToon(arms: true, Plugin.UseLilToon.Value, Plugin.FirstPersonLilToon.Value))); } fpsAnimationMilliseconds = (fpsAnimationMaximum = 0.0); fpsAnimationSamples = 0; nextFpsReport = Time.unscaledTime + 30f; } worstFrame = Math.Max(worstFrame, Time.unscaledDeltaTime * 1000f); if (Time.unscaledTime >= performanceAt + 10f) { float num3 = Time.unscaledTime - performanceAt; int num4 = GC.CollectionCount(0); int num5 = GC.CollectionCount(1); int num6 = GC.CollectionCount(2); Plugin.Logger.LogDebug((object)("AVATAR_PERFORMANCE fps=" + ((float)performanceFrames / num3).ToString("F1") + " retarget_ms=" + (animationMilliseconds / (double)Math.Max(1, performanceFrames)).ToString("F3") + " worst_frame_ms=" + worstFrame.ToString("F1") + " update_max_ms=" + worstUpdate.ToString("F2") + " discovery_max_ms=" + worstDiscovery.ToString("F2") + " update_bytes_frame=" + updateAllocated / Math.Max(1, performanceFrames) + " animate_bytes_frame=" + animationAllocated / Math.Max(1, performanceFrames) + " managed_gc=" + (num4 - previousGc0) + "," + (num5 - previousGc1) + "," + (num6 - previousGc2) + " enabled=" + Plugin.Enabled.Value + " rigs=" + rigs.Count)); updateAllocated = 0L; animationAllocated = 0L; previousGc0 = num4; previousGc1 = num5; previousGc2 = num6; worstUpdate = 0.0; worstDiscovery = 0.0; performanceAt = Time.unscaledTime; performanceFrames = 0; animationMilliseconds = 0.0; worstFrame = 0f; } } private static void DiagnoseSafely(Rig rig) { try { rig.Diagnose(); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Avatar diagnostics unavailable: " + ex.Message)); } } public void OnDestroy() { foreach (Rig rig in rigs) { rig.Dispose(); } rigs.Clear(); foreach (AvatarData value in datas.Values) { value.Dispose(); } datas.Clear(); } } internal sealed class EquipmentSettlement { private readonly Dictionary<int, float> readyAt = new Dictionary<int, float>(); internal void Changed(int root, float now) { readyAt[root] = now + 0.1f; } internal void Selected(int root) { readyAt.Remove(root); } internal bool Ready(int root, float now) { if (!readyAt.TryGetValue(root, out var value)) { return true; } if (now < value) { return false; } readyAt.Remove(root); return true; } } internal static class FirstPersonRendering { internal static bool UseToon(bool arms, bool enabled, bool firstPersonEnabled) { if (enabled) { return !arms || firstPersonEnabled; } return false; } } internal sealed class FpsDiscoveryBudget { private int attempts; private float nextAttempt; internal bool TryAcquire(float now) { if (attempts >= 3 || now < nextAttempt) { return false; } attempts++; nextAttempt = now + 2f; return true; } } internal static class Hotkeys { private static readonly bool[] held = new bool[6]; private static readonly bool[] pressed = new bool[6]; private static readonly uint processId = (uint)Process.GetCurrentProcess().Id; private static bool nativeAvailable = true; private static bool unityAvailable = true; [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int key); [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr window, out uint id); internal static void Poll() { bool flag = Application.isFocused; if (nativeAvailable) { try { GetWindowThreadProcessId(GetForegroundWindow(), out var id); flag = id == processId; } catch (Exception ex) { nativeAvailable = false; Plugin.Logger.LogWarning((object)("Native hotkey fallback unavailable: " + ex.Message)); } } for (int i = 0; i < held.Length; i++) { bool flag2 = false; if (flag && unityAvailable) { try { flag2 = Input.GetKey((KeyCode)(285 + i)); } catch (Exception ex2) { unityAvailable = false; Plugin.Logger.LogWarning((object)("Unity hotkeys unavailable; using Windows: " + ex2.Message)); } } if (flag && nativeAvailable) { try { flag2 |= (GetAsyncKeyState(115 + i) & 0x8000) != 0; } catch (Exception) { nativeAvailable = false; } } pressed[i] = flag2 && !held[i]; held[i] = flag2; if (pressed[i]) { Plugin.Logger.LogInfo((object)("AVATAR_HOTKEY F" + (i + 4))); } } } internal static bool Pressed(KeyCode key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return pressed[key - 285]; } } internal static class Ic { public static bool B(Object o) { return o != (Object)null; } public static Il2CppStructArray<T> A<T>(T[] src) where T : unmanaged { return Il2CppStructArray<T>.op_Implicit(src); } public static Il2CppReferenceArray<T> R<T>(T[] src) where T : Il2CppObjectBase { return Il2CppReferenceArray<T>.op_Implicit(src); } public static Action<T> D<T>(Action<T> src) { return Action<T>.op_Implicit(src); } public static T[] A2<T>(Il2CppArrayBase<T> src) { return Il2CppArrayBase<T>.op_Implicit(src); } } internal sealed class Node { public string Name; public int Parent; public int Human; public Vector3 Position; public Vector3 Scale; public Vector3 WorldPosition; public Quaternion Rotation; public Quaternion WorldRotation; } internal static class OutfitSelection { internal static bool Changed(bool wasSelected, int previousIndex, bool selected, int index) { if (wasSelected == selected) { if (selected) { return previousIndex != index; } return false; } return true; } } internal sealed class Part { public string Name; public int Transform; public int RootBone; public bool Skinned; public int[] Bones; public BoneWeight[] Weights; public Vector3[] Vertices; public Vector3[] Normals; public Vector2[] UV; public Vector4[] Tangents; public Color[] Colors; public Matrix4x4[] Bindposes; public Bounds Bounds; public Surface[] Surfaces; public Mesh BodyMesh; public Mesh ArmsMesh; public int[] FPSBones; public Mesh Build(bool arms, bool[] armNodes) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Expected O, but got Unknown //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_051b: Unknown result type (might be due to invalid IL or missing references) if (arms && Ic.B((Object)ArmsMesh)) { return ArmsMesh; } if (!arms && Ic.B((Object)BodyMesh)) { return BodyMesh; } if (arms && !Skinned) { return null; } int[][] array = Surfaces.Select((Surface s) => (!arms) ? s.Triangles : FilterArms(s.Triangles, armNodes)).ToArray(); if (array.All((int[] t) => t.Length == 0)) { return null; } int[] array2 = (arms ? (from i in array.SelectMany((int[] t) => t).Distinct() orderby i select i).ToArray() : Enumerable.Range(0, Vertices.Length).ToArray()); int[] vertexRemap = new int[Vertices.Length]; for (int num = 0; num < array2.Length; num++) { vertexRemap[array2[num]] = num; } BoneWeight[] array3 = (BoneWeight[])(Skinned ? ((Array)array2.Select((int i) => Weights[i]).ToArray()) : ((Array)new BoneWeight[0])); int[] array4 = Enumerable.Range(0, Bones.Length).ToArray(); if (arms) { HashSet<int> hashSet = new HashSet<int>(); BoneWeight[] array5 = array3; for (int num2 = 0; num2 < array5.Length; num2++) { BoneWeight val = array5[num2]; if (((BoneWeight)(ref val)).weight0 > 0f) { hashSet.Add(((BoneWeight)(ref val)).boneIndex0); } if (((BoneWeight)(ref val)).weight1 > 0f) { hashSet.Add(((BoneWeight)(ref val)).boneIndex1); } if (((BoneWeight)(ref val)).weight2 > 0f) { hashSet.Add(((BoneWeight)(ref val)).boneIndex2); } if (((BoneWeight)(ref val)).weight3 > 0f) { hashSet.Add(((BoneWeight)(ref val)).boneIndex3); } } array4 = hashSet.OrderBy((int i) => i).ToArray(); int[] array6 = new int[Bones.Length]; for (int num3 = 0; num3 < array4.Length; num3++) { array6[array4[num3]] = num3; } for (int num4 = 0; num4 < array3.Length; num4++) { BoneWeight val2 = array3[num4]; ((BoneWeight)(ref val2)).boneIndex0 = array6[((BoneWeight)(ref val2)).boneIndex0]; ((BoneWeight)(ref val2)).boneIndex1 = array6[((BoneWeight)(ref val2)).boneIndex1]; ((BoneWeight)(ref val2)).boneIndex2 = array6[((BoneWeight)(ref val2)).boneIndex2]; ((BoneWeight)(ref val2)).boneIndex3 = array6[((BoneWeight)(ref val2)).boneIndex3]; array3[num4] = val2; } FPSBones = array4.Select((int i) => Bones[i]).ToArray(); } Mesh val3 = new Mesh(); ((Object)val3).name = Name + (arms ? "_FPS" : "_Body"); ((Object)val3).hideFlags = (HideFlags)(((Object)val3).hideFlags | 0x3D); val3.indexFormat = (IndexFormat)(array2.Length > 65535); val3.vertices = Ic.A<Vector3>(array2.Select((int i) => Vertices[i]).ToArray()); if (Normals.Length == Vertices.Length) { val3.normals = Ic.A<Vector3>(array2.Select((int i) => Normals[i]).ToArray()); } if (UV.Length == Vertices.Length) { val3.uv = Ic.A<Vector2>(array2.Select((int i) => UV[i]).ToArray()); } if (Tangents.Length == Vertices.Length) { val3.tangents = Ic.A<Vector4>(array2.Select((int i) => Tangents[i]).ToArray()); } if (Colors.Length == Vertices.Length) { val3.colors = Ic.A<Color>(array2.Select((int i) => Colors[i]).ToArray()); } if (Skinned) { val3.boneWeights = Ic.A<BoneWeight>(array3); val3.bindposes = Ic.A<Matrix4x4>(array4.Select((int i) => Bindposes[i]).ToArray()); } val3.subMeshCount = Surfaces.Length; for (int num5 = 0; num5 < array.Length; num5++) { val3.SetTriangles(Ic.A(arms ? array[num5].Select((int v) => vertexRemap[v]).ToArray() : array[num5]), num5, false); } val3.bounds = Bounds; if (Normals.Length != Vertices.Length) { val3.RecalculateNormals(); } if (arms) { ArmsMesh = val3; } else { BodyMesh = val3; } Plugin.Logger.LogInfo((object)("COMPACT_MESH fps=" + arms + " vertices=" + array2.Length + " bones=" + array4.Length)); return val3; } private int[] FilterArms(int[] triangles, bool[] armNodes) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) bool[] array = new bool[Vertices.Length]; for (int i = 0; i < array.Length && i < Weights.Length; i++) { BoneWeight val = Weights[i]; float num = ArmWeight(((BoneWeight)(ref val)).boneIndex0, ((BoneWeight)(ref val)).weight0, armNodes) + ArmWeight(((BoneWeight)(ref val)).boneIndex1, ((BoneWeight)(ref val)).weight1, armNodes) + ArmWeight(((BoneWeight)(ref val)).boneIndex2, ((BoneWeight)(ref val)).weight2, armNodes) + ArmWeight(((BoneWeight)(ref val)).boneIndex3, ((BoneWeight)(ref val)).weight3, armNodes); array[i] = num >= 0.6f; } List<int> list = new List<int>(); for (int j = 0; j < triangles.Length; j += 3) { if (array[triangles[j]] && array[triangles[j + 1]] && array[triangles[j + 2]]) { list.Add(triangles[j]); list.Add(triangles[j + 1]); list.Add(triangles[j + 2]); } } return list.ToArray(); } private float ArmWeight(int index, float weight, bool[] nodes) { if (index < 0 || index >= Bones.Length || !nodes[Bones[index]]) { return 0f; } return weight; } } [BepInPlugin("local.gtfo.nailong.avatar", "NAILONG Avatar Replacement", "1.4.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { internal static ManualLogSource Logger; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> AllPlayers; internal static ConfigEntry<bool> FirstPerson; internal static ConfigEntry<int> OutfitIndex; internal static ConfigEntry<bool> FirstPersonLilToon; internal static readonly ConfigEntry<float>[] OutfitScaleEntry = new ConfigEntry<float>[4]; internal static readonly ConfigEntry<bool>[] OutfitFirstPersonEntry = new ConfigEntry<bool>[4]; internal static readonly ConfigEntry<float>[] OutfitVerticalEntry = new ConfigEntry<float>[4]; internal static readonly string[] OutfitFiles = new string[4] { "nailong.avatar", "naidan.avatar", "naiwa.avatar", "nai.avatar" }; internal static readonly string[] OutfitLabels = new string[4] { "NAILONG", "NAIDAN", "NAIWA", "nai" }; internal static readonly string[] OutfitDescriptions = new string[4] { "小奶龙", "奶蛋", "奶娃", "奶龙小可爱" }; internal static ConfigEntry<float> Scale; internal static ConfigEntry<float> LobbyArmClearance; internal static ConfigEntry<float> WideArmLateralOffset; internal static ConfigEntry<float> BackwardOffset; internal static ConfigEntry<float> LilToonBrightness; internal static ConfigEntry<float> LilToonEmissionRatio; internal static ConfigEntry<float> LobbyBrightness; internal static ConfigEntry<bool> GameShader; internal static ConfigEntry<bool> UseLilToon; internal static ConfigEntry<bool> MaterialDetails; internal static ConfigEntry<bool> StockingDetails; internal static ConfigEntry<bool> SecondaryMotion; internal static ConfigEntry<float> MotionStrength; internal static string Folder; internal static float OutfitScale(int outfit) { if (outfit < 0 || outfit >= OutfitScaleEntry.Length || OutfitScaleEntry[outfit] == null) { return 1f; } float value = OutfitScaleEntry[outfit].Value; if (!(value > 0f)) { return 1f; } return value; } internal static bool OutfitUsesFirstPerson(int outfit) { if (outfit < 0 || outfit >= OutfitFirstPersonEntry.Length || OutfitFirstPersonEntry[outfit] == null) { return true; } return OutfitFirstPersonEntry[outfit].Value; } internal static float OutfitVerticalOffset(int outfit) { if (outfit < 0 || outfit >= OutfitVerticalEntry.Length || OutfitVerticalEntry[outfit] == null) { return 0f; } return OutfitVerticalEntry[outfit].Value; } public override void Load() { Logger = ((BasePlugin)this).Log; Folder = Path.GetDirectoryName(typeof(Plugin).Assembly.Location); Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "启用人物模型替换。游戏中按 F7 开关。"); AllPlayers = ((BasePlugin)this).Config.Bind<bool>("General", "ReplaceAllPlayers", true, "同时替换其他也选了这套模型的玩家。改成 false 则只替换本地玩家。"); FirstPerson = ((BasePlugin)this).Config.Bind<bool>("General", "ReplaceFirstPersonArms", false, "替换第一人称的手臂、躯干和腿(沿用原版骨骼,不含头部)。默认关闭,游戏中按 F9 开关;开启后还需对应服装的 ReplaceFirstPerson 为 true。"); OutfitIndex = ((BasePlugin)this).Config.Bind<int>("Outfit", "SelectedOutfit", 0, "当前使用的自定义服装:0 = NAILONG,1 = NAIDAN,2 = NAIWA,3 = nai。在衣柜里点对应卡片会自动写入。"); FirstPersonLilToon = ((BasePlugin)this).Config.Bind<bool>("Rendering", "FirstPersonUseLilToon", false, "第一人称也使用 lilToon。默认 false,手模优先使用游戏兼容材质以降低渲染负担;第三人称仍由 UseLilToon 控制。修改后重启游戏生效。"); float[] array = new float[4] { 1f, 0.7f, 1f, 0.4f }; bool[] array2 = new bool[4] { true, true, true, true }; for (int i = 0; i < OutfitFiles.Length; i++) { string text = "Outfit." + OutfitLabels[i]; float num = ((i < array.Length) ? array[i] : 1f); bool flag = i < array2.Length && array2[i]; OutfitScaleEntry[i] = ((BasePlugin)this).Config.Bind<float>(text, "ScaleMultiplier", num, "这套服装额外的缩放倍率。1 = 不额外缩放(只吃 [General] 的 BodyScaleMultiplier)。和全局倍率一样绕胯骨等比缩放,常用 0.5~0.8。"); OutfitFirstPersonEntry[i] = ((BasePlugin)this).Config.Bind<bool>(text, "ReplaceFirstPerson", flag, "这套服装是否替换第一人称模型。关掉后第一人称保持原版手臂,模型只出现在第三人称。"); OutfitVerticalEntry[i] = ((BasePlugin)this).Config.Bind<float>(text, "VerticalOffset", 0f, "这套服装额外的垂直偏移,单位米。正数上移、负数下沉。默认 0。"); } Scale = ((BasePlugin)this).Config.Bind<float>("General", "BodyScaleMultiplier", 0.65f, "整体缩放倍率。1 = 与原版骨架腿长一致;小于 1 是绕胯骨等比缩小,脚会离地(0.8 约浮空 15 cm),常用 0.6~0.7。"); GameShader = ((BasePlugin)this).Config.Bind<bool>("Rendering", "UseGameCharacterShader", true, "使用 GTFO 原版人物着色器,兼容游戏内光照。"); MaterialDetails = ((BasePlugin)this).Config.Bind<bool>("Rendering", "EnhancedStockingsAndCrystals", true, "给丝袜和水晶加原版的视角相关 MatCap 高光。F6 可临时对比。"); StockingDetails = ((BasePlugin)this).Config.Bind<bool>("Rendering", "StockingFabricSheen", true, "丝袜布料的柔光效果。F5 单独开关丝袜,不影响水晶增强。"); UseLilToon = ((BasePlugin)this).Config.Bind<bool>("Rendering", "UseLilToon", true, "使用 Unity2019 编译的 lilToon。F6 与兼容 GTFO 材质对比。"); LilToonBrightness = ((BasePlugin)this).Config.Bind<float>("Rendering", "LilToonBrightness", 0.3f, "反照率亮度补偿,用来抵消 GTFO 的曝光。原贴图和 alpha 通道不变。"); LilToonEmissionRatio = ((BasePlugin)this).Config.Bind<float>("Rendering", "LilToonEmissionRatio", 0.125f, "贴图色自发光强度,相对原版 0.20 最低光照基线。0.125 = 0.025 自发光下限,0 = 关闭自发光。光照着色和场景光照探针仍然生效,实际观感取决于游戏曝光。"); LobbyBrightness = ((BasePlugin)this).Config.Bind<float>("Rendering", "LobbyBrightness", 0.8f, "大厅预览单独的反照率补偿。大厅 UI 相机不走关卡曝光,所以用固定 0.60 光底。不会照亮关卡内的模型。"); LobbyArmClearance = ((BasePlugin)this).Config.Bind<float>("Animation", "LobbyArmClearanceDegrees", 14f, "大厅预览时上臂外张的角度,避免手穿裙子。不改权重和骨长,关卡内瞄准不受影响。"); WideArmLateralOffset = ((BasePlugin)this).Config.Bind<float>("Animation", "WideModelArmLateralOffsetMeters", 0.16f, "胖体型模型(NAIDAN / NAIWA)的手臂横向外移距离。奶娃躯干很宽,手臂放下会陷进身体;这里只平移自定义模型的上臂骨骼,让整条手臂悬在躯干外侧,不会旋转手臂,也不会影响原版武器/装备挂点。手臂抬起或瞄准时会自动减弱。"); BackwardOffset = ((BasePlugin)this).Config.Bind<float>("General", "ModelBackwardOffset", 0f, "整体沿角色自身背向平移,单位米。正数把模型挪到镜头后方,负数往前。脚会跟着挪,建议 0~0.15,0 = 原对齐。"); SecondaryMotion = ((BasePlugin)this).Config.Bind<bool>("Animation", "SecondaryMotion", true, "头发、袖子、裙摆、飘带的轻量弹簧晃动。F4 开关。不改权重、骨长和人形骨骼旋转。"); MotionStrength = ((BasePlugin)this).Config.Bind<float>("Animation", "SecondaryMotionStrength", 1f, "弹簧晃动强度倍率(0~1.5)。角度安全上限始终生效。"); SuteraOutfit.Initialize(((BasePlugin)this).Config); ClassInjector.RegisterTypeInIl2Cpp<Driver>(); ((BasePlugin)this).AddComponent<Driver>(); ((BasePlugin)this).Log.LogInfo((object)"Avatar replacement installed; visual changes are local to this client. F7 toggles, F8 captures a screenshot."); } } internal sealed class Rig : IDisposable { private sealed class SkinSnapshot { public SkinnedMeshRenderer Skin; public Mesh Mesh; public Transform[] Bones; public Transform RootBone; public Material[] Materials; public Bounds Bounds; public bool UpdateOffscreen; public bool MotionVectors; public ShadowCastingMode Shadows; public bool ReceiveShadows; public LightProbeUsage LightProbes; public ReflectionProbeUsage ReflectionProbes; public Transform ProbeAnchor; } private sealed class Mapping { public int Node; public int Human; public Transform Target; public Transform ChildTarget; public Quaternion TargetRest; public Quaternion Offset; public Vector3 Direction; public TargetPose Pose; public TargetPose ChildPose; } private sealed class TargetPose { public Transform Target; public Quaternion Rotation; public Vector3 Position; public bool NeedsPosition; public bool Alive; } public PlayerAgent Owner; public SNet_Player NetworkOwner; public Animator Animator; public bool Arms; public int Outfit; private bool loggedPlacement; private bool loggedArmClearance; public GameObject RenderRoot; private GameObject Root; private Transform[] nodes; private AvatarData data; private readonly List<Mapping> mappings = new List<Mapping>(); private readonly List<TargetPose> targetPoses = new List<TargetPose>(); private readonly List<GameObject> originalObjects = new List<GameObject>(); private readonly List<Tuple<Renderer, bool>> originals = new List<Tuple<Renderer, bool>>(); private readonly List<Renderer> visuals = new List<Renderer>(); private readonly List<Material> ownMaterials = new List<Material>(); private readonly List<SkinnedMeshRenderer> sheenRenderers = new List<SkinnedMeshRenderer>(); private SkinnedMeshRenderer stockingSheen; private readonly List<Tuple<PlayerFaceController, bool>> nativeFaces = new List<Tuple<PlayerFaceController, bool>>(); private readonly List<FPSRenderer> fpsRenderers = new List<FPSRenderer>(); private readonly FpsDiscoveryBudget fpsDiscovery = new FpsDiscoveryBudget(); private static FPSRenderer[] cachedFpsRenderers; private static float nextFpsSceneSearch; private readonly Dictionary<int, int> fpsPasses = new Dictionary<int, int>(); private readonly Dictionary<int, RendererData[]> fpsSnapshots = new Dictionary<int, RendererData[]>(); private float scaleMultiplier = 1f; private Vector3 targetScale; private Transform anchor; private Transform lightingAnchor; private Transform rootTransform; private Vector3 lastScale; private float maintenanceAt; private int mappedRootNode = -1; private SkinnedMeshRenderer host; private GameObject hostObject; private Mesh emptyMesh; private readonly List<Mesh> ownMeshes = new List<Mesh>(); private readonly List<SkinSnapshot> skinSnapshots = new List<SkinSnapshot>(); private readonly Dictionary<int, Mapping> mainMappings = new Dictionary<int, Mapping>(); private SpringMotion spring; private static readonly Dictionary<int, int> Segments; public bool Valid { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (Ic.B((Object)Root) && Ic.B((Object)Animator)) { return Ic.B((Object)host); } return false; } } public bool Installed { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0092: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown if (!Ic.B((Object)host) || !ownMeshes.Any((Mesh m) => Ic.B((Object)m) && (Object)m == (Object)host.sharedMesh)) { return false; } foreach (SkinSnapshot skinSnapshot in skinSnapshots) { if (Ic.B((Object)skinSnapshot.Skin) && (Object)skinSnapshot.Skin != (Object)host && (Object)skinSnapshot.Skin.sharedMesh != (Object)emptyMesh) { return false; } } if (!((Component)host).gameObject.activeInHierarchy && Ic.B((Object)RenderRoot) && RenderRoot.activeInHierarchy && skinSnapshots.Any((SkinSnapshot s) => Ic.B((Object)s.Skin) && (Object)s.Skin != (Object)host && ((Renderer)s.Skin).enabled && ((Component)s.Skin).gameObject.activeInHierarchy)) { return false; } return true; } } public int MappingCount => mappings.Count; private static float NativeLegLength(Animator animator, Animator prefab, Transform hips, Transform foot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (Ic.B((Object)prefab) && prefab.isHuman) { Transform boneTransform = prefab.GetBoneTransform((HumanBodyBones)0); Transform boneTransform2 = prefab.GetBoneTransform((HumanBodyBones)5); if (Ic.B((Object)boneTransform) && Ic.B((Object)boneTransform2)) { Transform transform = ((Component)prefab).transform; float num = Mathf.Abs(transform.InverseTransformPoint(boneTransform.position).y - transform.InverseTransformPoint(boneTransform2.position).y); if (float.IsFinite(num) && num > 0.01f) { return num; } } } Transform transform2 = ((Component)animator).transform; float num2 = 0f; Transform val = foot; for (int i = 0; i < 16; i++) { if (!Ic.B((Object)val)) { break; } if (!((Object)(object)val != (Object)(object)hips)) { break; } Transform parent = val.parent; if (!Ic.B((Object)parent)) { break; } num2 += Vector3.Distance(transform2.InverseTransformPoint(val.position), transform2.InverseTransformPoint(parent.position)); val = parent; } if (!((Object)(object)val == (Object)(object)hips) || !float.IsFinite(num2)) { return 0f; } return num2; } private Vector3 PalmDirection(int nodeIndex, Vector3 fallback) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (data.PalmDirections.TryGetValue(nodeIndex, out var value)) { return value; } Vector3 val = Vec(0f, 0f, 0f); float num = 0f; Part[] renderers = data.Renderers; foreach (Part part in renderers) { int num2 = Array.IndexOf(part.Bones, nodeIndex); if (num2 < 0 || num2 >= part.Bindposes.Length) { continue; } Surface[] surfaces = part.Surfaces; for (int j = 0; j < surfaces.Length; j++) { int[] triangles = surfaces[j].Triangles; foreach (int num3 in triangles) { if (num3 >= 0 && num3 < part.Weights.Length && num3 < part.Vertices.Length) { BoneWeight val2 = part.Weights[num3]; float num4 = ((((BoneWeight)(ref val2)).boneIndex0 == num2) ? ((BoneWeight)(ref val2)).weight0 : 0f) + ((((BoneWeight)(ref val2)).boneIndex1 == num2) ? ((BoneWeight)(ref val2)).weight1 : 0f) + ((((BoneWeight)(ref val2)).boneIndex2 == num2) ? ((BoneWeight)(ref val2)).weight2 : 0f) + ((((BoneWeight)(ref val2)).boneIndex3 == num2) ? ((BoneWeight)(ref val2)).weight3 : 0f); if (!(num4 <= 0f)) { val += FastPoint(part.Bindposes[num2], part.Vertices[num3]) * num4; num += num4; } } } } } Vector3 val3 = ((num > 0f) ? QRotate(data.Nodes[nodeIndex].WorldRotation, val * (1f / num)) : fallback); if (((Vector3)(ref val3)).sqrMagnitude < 1E-06f) { val3 = fallback; } data.PalmDirections[nodeIndex] = val3; return val3; } private static Vector3 Managed(Vector3 p) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Vector3(p.x, p.y, p.z); } private static Quaternion Managed(Quaternion q) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Quaternion(q.x, q.y, q.z, q.w); } private void InitializeSpring(bool[] needed) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0293: 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) SpringMotion.Definition[] array = new SpringMotion.Definition[data.Nodes.Length]; for (int i = 0; i < array.Length; i++) { Node node = data.Nodes[i]; array[i] = new SpringMotion.Definition { Name = node.Name, Parent = node.Parent, Human = node.Human, LocalPosition = Managed(node.Position), LocalRotation = Managed(node.Rotation) }; } spring = new SpringMotion(array, needed); List<SpringMotion.SkinVertex> list = new List<SpringMotion.SkinVertex>(); Part[] renderers = data.Renderers; foreach (Part part in renderers) { if (!part.Skinned) { continue; } for (int k = 0; k < part.Vertices.Length; k++) { BoneWeight val = part.Weights[k]; int num = part.Bones[((BoneWeight)(ref val)).boneIndex0]; int num2 = part.Bones[((BoneWeight)(ref val)).boneIndex1]; int num3 = part.Bones[((BoneWeight)(ref val)).boneIndex2]; int num4 = part.Bones[((BoneWeight)(ref val)).boneIndex3]; int root = -1; float dominant = 0f; float total = 0f; Pick(num, ((BoneWeight)(ref val)).weight0); Pick(num2, ((BoneWeight)(ref val)).weight1); Pick(num3, ((BoneWeight)(ref val)).weight2); Pick(num4, ((BoneWeight)(ref val)).weight3); if (root >= 0 && !(total < 0.5f)) { list.Add(new SpringMotion.SkinVertex { Root = root, B0 = num, B1 = num2, B2 = num3, B3 = num4, L0 = Managed(FastPoint(part.Bindposes[((BoneWeight)(ref val)).boneIndex0], part.Vertices[k])), L1 = Managed(FastPoint(part.Bindposes[((BoneWeight)(ref val)).boneIndex1], part.Vertices[k])), L2 = Managed(FastPoint(part.Bindposes[((BoneWeight)(ref val)).boneIndex2], part.Vertices[k])), L3 = Managed(FastPoint(part.Bindposes[((BoneWeight)(ref val)).boneIndex3], part.Vertices[k])), Weights = new Vector4(((BoneWeight)(ref val)).weight0, ((BoneWeight)(ref val)).weight1, ((BoneWeight)(ref val)).weight2, ((BoneWeight)(ref val)).weight3) }); } void Pick(int bone, float weight) { int num5 = spring.ClothRoot(bone); if (num5 >= 0) { total += weight; if (weight > dominant) { dominant = weight; root = num5; } } } } } spring.ConfigureCloth(list.ToArray()); Plugin.Logger.LogDebug((object)("SUTERA_SPRINGS joints=" + spring.Count + " hair=" + spring.HairCount + " skirt=" + spring.SkirtCount + " sleeves=" + spring.SleeveCount + " ribbons=" + spring.RibbonCount + " cloth_probes=" + spring.ProbeCount + " fps=" + Arms)); } private static IEnumerable<FPSRenderer> AllFPS() { foreach (FPSRenderer item in Object.FindObjectsOfType<FPSRenderer>()) { int num; if (Ic.B((Object)item)) { Scene scene = ((Component)item).gameObject.scene; num = (((Scene)(ref scene)).IsValid() ? 1 : 0); } else { num = 0; } if (num != 0) { yield return item; } } } public Rig(AvatarData avatar, PlayerAgent owner, Animator animator, bool arms, GameObject renderRoot, int outfit) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Expected O, but got Unknown //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Expected O, but got Unknown //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Expected O, but got Unknown //IL_05ac: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_05dd: Unknown result type (might be due to invalid IL or missing references) //IL_065a: Unknown result type (might be due to invalid IL or missing references) //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_069e: Unknown result type (might be due to invalid IL or missing references) //IL_06a8: Expected O, but got Unknown //IL_076d: Unknown result type (might be due to invalid IL or missing references) //IL_0777: Expected O, but got Unknown //IL_088c: Unknown result type (might be due to invalid IL or missing references) //IL_07a4: Unknown result type (might be due to invalid IL or missing references) //IL_07ae: Expected O, but got Unknown //IL_08e4: Unknown result type (might be due to invalid IL or missing references) //IL_08ee: Expected O, but got Unknown //IL_07b9: Unknown result type (might be due to invalid IL or missing references) //IL_07c5: Unknown result type (might be due to invalid IL or missing references) //IL_07ca: Unknown result type (might be due to invalid IL or missing references) //IL_07d8: Unknown result type (might be due to invalid IL or missing references) //IL_07dd: Unknown result type (might be due to invalid IL or missing references) //IL_07e1: Unknown result type (might be due to invalid IL or missing references) //IL_07e6: Unknown result type (might be due to invalid IL or missing references) //IL_07eb: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Unknown result type (might be due to invalid IL or missing references) //IL_0823: Unknown result type (might be due to invalid IL or missing references) //IL_082a: Unknown result type (might be due to invalid IL or missing references) //IL_0831: Unknown result type (might be due to invalid IL or missing references) //IL_0838: Unknown result type (might be due to invalid IL or missing references) //IL_090b: Unknown result type (might be due to invalid IL or missing references) //IL_0915: Expected O, but got Unknown //IL_0bdd: Unknown result type (might be due to invalid IL or missing references) //IL_0920: Unknown result type (might be due to invalid IL or missing references) //IL_092a: Expected O, but got Unknown //IL_0917: Unknown result type (might be due to invalid IL or missing references) //IL_0951: Unknown result type (might be due to invalid IL or missing references) //IL_095a: Unknown result type (might be due to invalid IL or missing references) //IL_0964: Expected O, but got Unknown //IL_0bf0: Unknown result type (might be due to invalid IL or missing references) //IL_0bf8: Unknown result type (might be due to invalid IL or missing references) //IL_0c01: Expected I4, but got Unknown //IL_093b: Unknown result type (might be due to invalid IL or missing references) //IL_0940: Unknown result type (might be due to invalid IL or missing references) //IL_0947: Unknown result type (might be due to invalid IL or missing references) //IL_094c: Unknown result type (might be due to invalid IL or missing references) //IL_09bf: Unknown result type (might be due to invalid IL or missing references) //IL_09c9: Expected O, but got Unknown //IL_097e: Unknown result type (might be due to invalid IL or missing references) //IL_0988: Expected O, but got Unknown //IL_09ee: Unknown result type (might be due to invalid IL or missing references) //IL_09f8: Expected O, but got Unknown //IL_09a3: Unknown result type (might be due to invalid IL or missing references) //IL_09ad: Expected O, but got Unknown //IL_0c37: Unknown result type (might be due to invalid IL or missing references) //IL_0c61: Unknown result type (might be due to invalid IL or missing references) //IL_0c66: Unknown result type (might be due to invalid IL or missing references) //IL_0c6b: Unknown result type (might be due to invalid IL or missing references) //IL_0c81: Unknown result type (might be due to invalid IL or missing references) //IL_0c83: Unknown result type (might be due to invalid IL or missing references) //IL_0c88: Unknown result type (might be due to invalid IL or missing references) //IL_0a95: Unknown result type (might be due to invalid IL or missing references) //IL_0a9f: Expected O, but got Unknown //IL_0a28: Unknown result type (might be due to invalid IL or missing references) //IL_0a32: Expected O, but got Unknown //IL_0b1e: Unknown result type (might be due to invalid IL or missing references) //IL_0b20: Unknown result type (might be due to invalid IL or missing references) //IL_0abd: Unknown result type (might be due to invalid IL or missing references) //IL_0ac7: Expected O, but got Unknown //IL_0a3a: Unknown result type (might be due to invalid IL or missing references) //IL_0a44: Expected O, but got Unknown //IL_0aec: Unknown result type (might be due to invalid IL or missing references) //IL_0acf: Unknown result type (might be due to invalid IL or missing references) //IL_0ad4: Unknown result type (might be due to invalid IL or missing references) //IL_0ae0: Unknown result type (might be due to invalid IL or missing references) //IL_0ae5: Unknown result type (might be due to invalid IL or missing references) //IL_0aee: Unknown result type (might be due to invalid IL or missing references) //IL_0d9d: Unknown result type (might be due to invalid IL or missing references) //IL_0da7: Expected O, but got Unknown //IL_0dad: Unknown result type (might be due to invalid IL or missing references) //IL_0db7: Expected O, but got Unknown //IL_0dce: Unknown result type (might be due to invalid IL or missing references) //IL_0e00: Unknown result type (might be due to invalid IL or missing references) //IL_0e1b: Unknown result type (might be due to invalid IL or missing references) //IL_0e2c: Unknown result type (might be due to invalid IL or missing references) //IL_0e31: Unknown result type (might be due to invalid IL or missing references) //IL_0e42: Unknown result type (might be due to invalid IL or missing references) //IL_0a79: Unknown result type (might be due to invalid IL or missing references) //IL_0a83: Expected O, but got Unknown //IL_0ead: Unknown result type (might be due to invalid IL or missing references) //IL_0eb7: Expected O, but got Unknown //IL_103f: Unknown result type (might be due to invalid IL or missing references) //IL_1044: Unknown result type (might be due to invalid IL or missing references) //IL_105c: Unknown result type (might be due to invalid IL or missing references) //IL_1061: Unknown result type (might be due to invalid IL or missing references) //IL_1066: Unknown result type (might be due to invalid IL or missing references) //IL_10b4: Unknown result type (might be due to invalid IL or missing references) //IL_10b9: Unknown result type (might be due to invalid IL or missing references) //IL_10d1: Unknown result type (might be due to invalid IL or missing references) //IL_10e9: Unknown result type (might be due to invalid IL or missing references) //IL_10ee: Unknown result type (might be due to invalid IL or missing references) //IL_10f3: Unknown result type (might be due to invalid IL or missing references) //IL_10f8: Unknown result type (might be due to invalid IL or missing references) //IL_116c: Unknown result type (might be due to invalid IL or missing references) //IL_1176: Expected O, but got Unknown //IL_1208: Unknown result type (might be due to invalid IL or missing references) //IL_120f: Expected O, but got Unknown //IL_125e: Unknown result type (might be due to invalid IL or missing references) //IL_1273: Unknown result type (might be due to invalid IL or missing references) //IL_1288: Unknown result type (might be due to invalid IL or missing references) //IL_13be: Unknown result type (might be due to invalid IL or missing references) //IL_13c9: Unknown result type (might be due to invalid IL or missing references) //IL_13d9: Unknown result type (might be due to invalid IL or missing references) //IL_13ef: Unknown result type (might be due to invalid IL or missing references) //IL_13f4: Unknown result type (might be due to invalid IL or missing references) //IL_14a8: Unknown result type (might be due to invalid IL or missing references) //IL_14ad: Unknown result type (might be due to invalid IL or missing references) //IL_1501: Unknown result type (might be due to invalid IL or missing references) //IL_150b: Expected O, but got Unknown //IL_153e: Unknown result type (might be due to invalid IL or missing references) //IL_1548: Expected O, but got Unknown //IL_15ae: Unknown result type (might be due to invalid IL or missing references) //IL_15b8: Expected O, but got Unknown //IL_15c6: Unknown result type (might be due to invalid IL or missing references) //IL_15d0: Expected O, but got Unknown //IL_1647: Unknown result type (might be due to invalid IL or missing references) //IL_164c: Unknown result type (might be due to invalid IL or missing references) //IL_166e: Unknown result type (might be due to invalid IL or missing references) //IL_1673: Unknown result type (might be due to invalid IL or missing references) //IL_1688: Unknown result type (might be due to invalid IL or missing references) //IL_168d: Unknown result type (might be due to invalid IL or missing references) //IL_1695: Unknown result type (might be due to invalid IL or missing references) //IL_169a: Unknown result type (might be due to invalid IL or missing references) //IL_171d: Unknown result type (might be due to invalid IL or missing references) //IL_1727: Expected O, but got Unknown //IL_19cf: Unknown result type (might be due to invalid IL or missing references) //IL_19d6: Expected O, but got Unknown //IL_175b: Unknown result type (might be due to invalid IL or missing references) //IL_176e: Unknown result type (might be due to invalid IL or missing references) //IL_1773: Unknown result type (might be due to invalid IL or missing references) //IL_1778: Unknown result type (might be due to invalid IL or missing references) //IL_179a: Unknown result type (might be due to invalid IL or missing references) //IL_179f: Unknown result type (might be due to invalid IL or missing references) //IL_17ab: Unknown result type (might be due to invalid IL or missing references) //IL_17b0: Unknown result type (might be due to invalid IL or missing references) //IL_1b33: Unknown result type (might be due to invalid IL or missing references) //IL_1b3e: Unknown result type (might be due to invalid IL or missing references) //IL_1b48: Expected O, but got Unknown //IL_1b48: Expected O, but got Unknown //IL_17bb: Unknown result type (might be due to invalid IL or missing references) //IL_17c1: Unknown result type (might be due to invalid IL or missing references) //IL_17c6: Unknown result type (might be due to invalid IL or missing references) //IL_17cb: Unknown result type (might be due to invalid IL or missing references) //IL_1a5c: Unknown result type (might be due to invalid IL or missing references) //IL_1a8e: Unknown result type (might be due to invalid IL or missing references) //IL_1a98: Expected O, but got Unknown //IL_17e7: Unknown result type (might be due to invalid IL or missing references) //IL_17ed: Unknown result type (might be due to invalid IL or missing references) //IL_17f2: Unknown result type (might be due to invalid IL or missing references) //IL_17f7: Unknown result type (might be due to invalid IL or missing references) //IL_1b8c: Unknown result type (might be due to invalid IL or missing references) //IL_1b9d: Expected O, but got Unknown //IL_1bb2: Unknown result type (might be due to invalid IL or missing references) //IL_1bbc: Expected O, but got Unknown //IL_18e9: Unknown result type (might be due to invalid IL or missing references) //IL_18f7: Unknown result type (might be due to invalid IL or missing references) //IL_1920: Unknown result type (might be due to invalid IL or missing references) //IL_1927: Expected O, but got Unknown //IL_193d: Unknown result type (might be due to invalid IL or missing references) //IL_1947: Expected O, but got Unknown //IL_1c4b: Unknown result type (might be due to invalid IL or missing references) //IL_1c5c: Expected O, but got Unknown //IL_1c9c: Unknown result type (might be due to invalid IL or missing references) //IL_1ca6: Expected O, but got Unknown //IL_1caf: Unknown result type (might be due to invalid IL or missing references) //IL_1cba: Unknown result type (might be due to invalid IL or missing references) //IL_1cc4: Expected O, but got Unknown //IL_1cc4: Expected O, but got Unknown //IL_1d45: Unknown result type (might be due to invalid IL or missing references) //IL_1d4f: Expected O, but got Unknown //IL_1f9b: Unknown result type (might be due to invalid IL or missing references) //IL_1fa0: Unknown result type (might be due to invalid IL or missing references) //IL_1fa5: Unknown result type (might be due to invalid IL or missing references) //IL_1e2e: Unknown result type (might be due to invalid IL or missing references) //IL_1e38: Expected O, but got Unknown Outfit = outfit; Rig rig = this; Stopwatch stopwatch = Stopwatch.StartNew(); data = avatar; Owner = owner; Animator = animator; Arms = arms; RenderRoot = renderRoot; try { anchor = ((Component)animator).transform; SkinnedMeshRenderer[] array = ((IEnumerable<SkinnedMeshRenderer>)(Ic.B((Object)renderRoot) ? renderRoot.GetComponentsInChildren<SkinnedMeshRenderer>(true) : ((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>(true))).ToArray(); if (array.Length == 0) { array = ((IEnumerable<SkinnedMeshRenderer>)((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>(true)).ToArray(); } Transform[] array2 = (from b in array.Where((SkinnedMeshRenderer s) => ((Renderer)s).enabled && ((Component)s).gameObject.activeInHierarchy).SelectMany((SkinnedMeshRenderer s) => ((IEnumerable<Transform>)s.bones).ToArray()) where Ic.B((Object)b) group b by ((Object)b).GetInstanceID() into g select g.First()).ToArray(); Animator val = null; foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<Animator>())) { Animator val2 = ((Il2CppObjectBase)item).TryCast<Animator>(); if (!Ic.B((Object)val2) || !val2.isHuman) { continue; } Scene scene = ((Component)val2).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { if (((Object)val2).name == ((Object)animator).name.Replace("(Clone)", "")) { val = val2; break; } if (((Object)val2).name == "PlayerCharacter_rig") { val = val2; } } } Plugin.Logger.LogDebug((object)("BIND_BASELINE arms=" + arms + " name=" + (Ic.B((Object)val) ? ((Object)val).name : "legacy animator"))); Plugin.Logger.LogDebug((object)("ACTIVE_BONE_SET arms=" + arms + " count=" + array2.Length + " names=" + string.Join(",", from b in array2.Take(65) select ((Object)b).name))); Material template = (from s in array where ((Renderer)s).enabled && ((Component)s).gameObject.activeInHierarchy && Ic.B((Object)((Renderer)s).sharedMaterial) && Ic.B((Object)((Renderer)s).sharedMaterial.shader) select ((Renderer)s).sharedMaterial).FirstOrDefault(); if (!Ic.B((Object)template)) { template = (from s in array where Ic.B((Object)((Renderer)s).sharedMaterial) && Ic.B((Object)((Renderer)s).sharedMaterial.shader) select ((Renderer)s).sharedMaterial).FirstOrDefault(); } SkinnedMeshRenderer[] array3 = array; foreach (SkinnedMeshRenderer val3 in array3) { Plugin.Logger.LogDebug((object)("ORIGINAL_SKIN arms=" + arms + " name=" + ((Object)val3).name + " active=" + ((Component)val3).gameObject.activeInHierarchy + " enabled=" + ((Renderer)val3).enabled + " layer=" + ((Component)val3).gameObject.layer + " shader=" + (Ic.B((Object)((Renderer)val3).sharedMaterial) ? ((Object)((Renderer)val3).sharedMaterial.shader).name : "null"))); } ManualLogSource logger = Plugin.Logger; string[] arr