using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("XMC.VillagerCharacter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("XMC.VillagerCharacter")]
[assembly: AssemblyTitle("XMC.VillagerCharacter")]
[assembly: AssemblyVersion("1.0.3.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace Xmc.VillagerCharacter
{
public sealed class CharacterDriver : MonoBehaviour
{
private readonly Dictionary<int, VillagerRig> rigs = new Dictionary<int, VillagerRig>();
private readonly Dictionary<int, float> retryAt = new Dictionary<int, float>();
private ModelData? model;
private Texture2D? texture;
private float nextScan;
public CharacterDriver(IntPtr pointer)
: base(pointer)
{
}
public void Start()
{
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Expected O, but got Unknown
try
{
model = ModelData.Read(Path.Combine(Plugin.AssetFolder, "villager_model.json"));
string text = Path.Combine(Plugin.AssetFolder, model.Texture);
if (new FileInfo(text).Length > 4194304)
{
throw new InvalidDataException("人物贴图超过 4 MB");
}
byte[] array = File.ReadAllBytes(text);
if (array.Length < 24 || !array.Take(8).SequenceEqual(new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }))
{
throw new InvalidDataException("人物贴图不是有效 PNG");
}
uint num = ReadBigEndian(array, 16);
uint num2 = ReadBigEndian(array, 20);
bool flag = ((num < 1 || num > 2048) ? true : false);
bool flag2 = flag;
if (!flag2)
{
bool flag3 = ((num2 < 1 || num2 > 2048) ? true : false);
flag2 = flag3;
}
if (flag2)
{
throw new InvalidDataException("人物贴图尺寸超过限制");
}
texture = new Texture2D(2, 2, (TextureFormat)4, false);
if (!ImageConversion.LoadImage(texture, Il2CppStructArray<byte>.op_Implicit(array), false))
{
throw new InvalidDataException("人物贴图解码失败");
}
((Object)texture).name = "XMC_Villager_PixelAtlas";
((Texture)texture).filterMode = (FilterMode)0;
((Texture)texture).wrapMode = (TextureWrapMode)1;
}
catch (Exception ex)
{
model = null;
Plugin.Logger.LogError((object)("人物皮肤未启用,原人物保持不变:" + ex));
}
}
private static uint ReadBigEndian(byte[] bytes, int offset)
{
return (uint)((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]);
}
public void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(Plugin.Toggle.Value))
{
Plugin.Enabled.Value = !Plugin.Enabled.Value;
nextScan = 0f;
Plugin.Logger.LogInfo((object)(Plugin.Enabled.Value ? "方块村民外观已开启" : "方块村民外观已关闭,恢复原人物"));
}
if (!Plugin.Enabled.Value && rigs.Count > 0)
{
Clear();
}
}
public void LateUpdate()
{
if (!Plugin.Enabled.Value || model == null || (Object)(object)texture == (Object)null)
{
return;
}
if (Time.unscaledTime >= nextScan)
{
nextScan = Time.unscaledTime + 1f;
try
{
Scan();
}
catch (Exception ex)
{
Plugin.Logger.LogWarning((object)("人物扫描失败,稍后重试:" + ex.Message));
}
}
foreach (VillagerRig value in rigs.Values)
{
value.HideOriginals();
}
}
private void Scan()
{
HashSet<int> hashSet = new HashSet<int>();
string[] array = Plugin.Slots.Value.Split(',');
for (int i = 0; i < array.Length; i++)
{
if (int.TryParse(array[i].Trim(), out var result) && result >= 0 && result <= 3)
{
hashSet.Add(result);
}
}
HashSet<int> alive = new HashSet<int>();
foreach (int item in hashSet)
{
PlayerManager current2 = PlayerManager.Current;
PlayerAgent val = ((current2 != null) ? current2.GetPlayerAgentInSlot(item) : null);
if ((Object)(object)val == (Object)null || val.IsBeingDestroyed || val.IsBeingDespawned || !((Component)val).gameObject.activeInHierarchy)
{
continue;
}
PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
if (!Plugin.IncludeLocal.Value && (Object)(object)localPlayerAgent != (Object)null && ((Object)localPlayerAgent).GetInstanceID() == ((Object)val).GetInstanceID())
{
continue;
}
int instanceID = ((Object)val).GetInstanceID();
alive.Add(instanceID);
if (rigs.TryGetValue(instanceID, out VillagerRig value))
{
if (value.Valid(val))
{
continue;
}
value.Dispose();
rigs.Remove(instanceID);
}
if (!retryAt.TryGetValue(instanceID, out var value2) || !(Time.unscaledTime < value2))
{
VillagerRig villagerRig = null;
try
{
villagerRig = new VillagerRig(val, model, texture);
rigs.Add(instanceID, villagerRig);
retryAt.Remove(instanceID);
Plugin.Logger.LogInfo((object)("村民外观已挂载:槽位 " + item + " / " + val.PlayerName + " / " + villagerRig.Parts + " 个骨骼分组"));
}
catch (Exception ex)
{
villagerRig?.Dispose();
retryAt[instanceID] = Time.unscaledTime + 15f;
Plugin.Logger.LogWarning((object)("槽位 " + item + " 保留原人物,未替换:" + ex.Message));
}
}
}
int[] array2 = rigs.Keys.Where((int id) => !alive.Contains(id)).ToArray();
foreach (int key in array2)
{
rigs[key].Dispose();
rigs.Remove(key);
}
array2 = retryAt.Keys.Where((int id) => !alive.Contains(id)).ToArray();
foreach (int key2 in array2)
{
retryAt.Remove(key2);
}
}
private void Clear()
{
foreach (VillagerRig value in rigs.Values)
{
value.Dispose();
}
rigs.Clear();
retryAt.Clear();
}
public void OnDestroy()
{
Clear();
if ((Object)(object)texture != (Object)null)
{
Object.Destroy((Object)(object)texture);
}
}
}
internal sealed class LobbyVillagerRig : IDisposable
{
private readonly List<GameObject> objects = new List<GameObject>();
private readonly List<Mesh> meshes = new List<Mesh>();
private readonly List<(Renderer Renderer, bool Enabled)> originals = new List<(Renderer, bool)>();
private readonly Material material;
private bool disposed;
internal LobbyVillagerRig(CM_PlayerLobbyBar bar, ModelData model, Texture2D texture)
{
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_025f: Expected O, but got Unknown
//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0307: Expected O, but got Unknown
Animator val = bar.m_playerAnim ?? throw new InvalidOperationException("大厅人物动画未生成");
SkinnedMeshRenderer[] array = ((IEnumerable<SkinnedMeshRenderer>)bar.m_playerModelRenderers)?.Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer != (Object)null && (Object)(object)renderer.sharedMesh != (Object)null).ToArray() ?? Array.Empty<SkinnedMeshRenderer>();
if (array.Length == 0)
{
throw new InvalidOperationException("大厅人物蒙皮网格未生成");
}
try
{
Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>(StringComparer.Ordinal);
foreach (string boneName in ModelData.BoneNames)
{
Transform val2 = null;
if (val.isHuman && Enum.TryParse<HumanBodyBones>(boneName, out HumanBodyBones result))
{
val2 = val.GetBoneTransform(result);
}
if ((Object)(object)val2 == (Object)null)
{
val2 = FindBone(((Component)val).transform, boneName);
}
if ((Object)(object)val2 == (Object)null)
{
throw new InvalidOperationException("大厅人物缺少骨骼 " + boneName);
}
dictionary.Add(boneName, val2);
}
Transform root = bar.m_playerModelAlign ?? ((Component)val).transform;
Vector3 val3 = root.InverseTransformPoint(dictionary["Head"].position);
Vector3 val4 = root.InverseTransformPoint(dictionary["LeftFoot"].position);
float scale = Mathf.Abs(val3.y - val4.y) / (model.SourceHeadHeight - model.SourceFootHeight);
if (!float.IsFinite(scale) || scale < 0.25f || scale > 3f)
{
throw new InvalidOperationException("大厅人物比例异常");
}
material = CreateMaterial(texture);
foreach (ModelPart part in model.Parts)
{
Transform bone = dictionary[part.Bone];
Vector3[] array2 = part.Vertices.Select((float[] vertex) => bone.InverseTransformPoint(root.TransformPoint(new Vector3(vertex[0], vertex[1], vertex[2]) * scale))).ToArray();
Mesh val5 = new Mesh
{
name = "XMC_LobbyVillager_" + part.Name
};
val5.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2);
val5.uv = Il2CppStructArray<Vector2>.op_Implicit(((IEnumerable<float[]>)part.UV).Select((Func<float[], Vector2>)((float[] uv) => new Vector2(uv[0], uv[1]))).ToArray());
val5.triangles = Il2CppStructArray<int>.op_Implicit(part.Triangles.ToArray());
val5.RecalculateNormals();
val5.RecalculateBounds();
meshes.Add(val5);
GameObject val6 = new GameObject("XMC_LobbyVillager_" + part.Name)
{
layer = ((Component)array[0]).gameObject.layer
};
val6.transform.SetParent(bone, false);
val6.AddComponent<MeshFilter>().sharedMesh = val5;
((Renderer)val6.AddComponent<MeshRenderer>()).sharedMaterial = material;
objects.Add(val6);
}
SkinnedMeshRenderer[] array3 = array;
foreach (SkinnedMeshRenderer val7 in array3)
{
originals.Add(((Renderer)(object)val7, ((Renderer)val7).enabled));
((Renderer)val7).enabled = false;
}
}
catch
{
Dispose();
throw;
}
}
private static Transform? FindBone(Transform root, string name)
{
string text = name.ToLowerInvariant();
foreach (Transform componentsInChild in ((Component)root).GetComponentsInChildren<Transform>(true))
{
string text2 = new string(((Object)componentsInChild).name.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
if (text2 == text || text2.EndsWith("bip01" + text, StringComparison.Ordinal) || text2.EndsWith("mixamorig" + text, StringComparison.Ordinal))
{
return componentsInChild;
}
}
return null;
}
private static Material CreateMaterial(Texture2D texture)
{
//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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
string[] array = new string[3] { "Standard", "Legacy Shaders/Diffuse", "Unlit/Texture" };
for (int i = 0; i < array.Length; i++)
{
Shader val = Shader.Find(array[i]);
if (!((Object)(object)val == (Object)null) && val.isSupported)
{
Material val2 = new Material(val)
{
name = "XMC_LobbyVillager_PixelCloth",
mainTexture = (Texture)(object)texture
};
if (val2.HasProperty("_Color"))
{
val2.SetColor("_Color", Color.white);
}
if (val2.HasProperty("_Glossiness"))
{
val2.SetFloat("_Glossiness", 0f);
}
if (val2.HasProperty("_Metallic"))
{
val2.SetFloat("_Metallic", 0f);
}
return val2;
}
}
throw new InvalidOperationException("大厅没有可用人物材质");
}
internal void HideOriginals()
{
if (disposed)
{
return;
}
foreach (var original in originals)
{
if ((Object)(object)original.Renderer != (Object)null)
{
original.Renderer.enabled = false;
}
}
}
public void Dispose()
{
if (disposed)
{
return;
}
disposed = true;
foreach (var original in originals)
{
if ((Object)(object)original.Renderer != (Object)null)
{
original.Renderer.enabled = original.Enabled;
}
}
foreach (GameObject @object in objects)
{
if ((Object)(object)@object != (Object)null)
{
Object.Destroy((Object)(object)@object);
}
}
foreach (Mesh mesh in meshes)
{
if ((Object)(object)mesh != (Object)null)
{
Object.Destroy((Object)(object)mesh);
}
}
if ((Object)(object)material != (Object)null)
{
Object.Destroy((Object)(object)material);
}
objects.Clear();
meshes.Clear();
originals.Clear();
}
}
public sealed class ModelData
{
public static readonly HashSet<string> BoneNames = new HashSet<string>(StringComparer.Ordinal)
{
"Head", "Chest", "Hips", "LeftUpperLeg", "LeftLowerLeg", "LeftFoot", "RightUpperLeg", "RightLowerLeg", "RightFoot", "LeftUpperArm",
"LeftLowerArm", "LeftHand", "RightUpperArm", "RightLowerArm", "RightHand"
};
public int Version { get; set; }
public string Name { get; set; } = string.Empty;
public string Texture { get; set; } = string.Empty;
public float SourceHeadHeight { get; set; }
public float SourceFootHeight { get; set; }
public List<ModelPart> Parts { get; set; } = new List<ModelPart>();
public static ModelData Read(string path)
{
if (new FileInfo(path).Length > 2097152)
{
throw new InvalidDataException("人物模型配置过大");
}
ModelData? obj = JsonSerializer.Deserialize<ModelData>(File.ReadAllText(path)) ?? throw new InvalidDataException("人物模型为空");
obj.Validate();
return obj;
}
public void Validate()
{
bool flag = Version != 1 || Parts == null;
if (!flag)
{
int count = Parts.Count;
bool flag2 = ((count < 1 || count > 64) ? true : false);
flag = flag2;
}
if (flag)
{
throw new InvalidDataException("人物模型版本或分组数量无效");
}
if (!float.IsFinite(SourceHeadHeight) || !float.IsFinite(SourceFootHeight) || SourceHeadHeight - SourceFootHeight < 0.5f)
{
throw new InvalidDataException("人物参考身高无效");
}
if (string.IsNullOrWhiteSpace(Texture) || Texture.Contains('/') || Texture.Contains('\\') || Texture.Contains(':') || !Texture.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidDataException("贴图必须是模型目录内的 PNG 文件");
}
HashSet<string> bones = new HashSet<string>(StringComparer.Ordinal);
foreach (ModelPart part in Parts)
{
if (part == null || string.IsNullOrWhiteSpace(part.Name) || !BoneNames.Contains(part.Bone) || !bones.Add(part.Bone))
{
throw new InvalidDataException("人物骨骼名称重复或无效");
}
if (part.Anchor == null || part.Anchor.Length != 3 || part.Anchor.Any((float value) => !float.IsFinite(value) || Math.Abs(value) > 4f))
{
throw new InvalidDataException("人物分组锚点无效");
}
if (!float.IsFinite(part.Length) || part.Length < 0f || part.Length > 2f || part.EndBone == null || (part.EndBone.Length > 0 && (!BoneNames.Contains(part.EndBone) || part.Length <= 0f)))
{
throw new InvalidDataException("人物肢体参考长度无效");
}
flag = part.Vertices == null || part.UV == null || part.Triangles == null;
if (!flag)
{
int count = part.Vertices.Count;
bool flag3 = ((count < 3 || count > 10000) ? true : false);
flag = flag3;
}
bool flag2 = flag || part.UV.Count != part.Vertices.Count;
if (!flag2)
{
int count = part.Triangles.Count;
bool flag3 = ((count < 3 || count > 60000) ? true : false);
flag2 = flag3;
}
if (flag2 || part.Triangles.Count % 3 != 0)
{
throw new InvalidDataException("人物网格数量无效");
}
if (part.Vertices.Any((float[] vertex) => vertex == null || vertex.Length != 3 || vertex.Any((float value) => !float.IsFinite(value) || Math.Abs(value) > 4f)))
{
throw new InvalidDataException("人物顶点无效");
}
if (part.UV.Any((float[] uv) => uv == null || uv.Length != 2 || uv.Any((float value) => !float.IsFinite(value) || value < 0f || value > 1f)))
{
throw new InvalidDataException("人物 UV 无效");
}
if (part.Triangles.Any((int index) => index < 0 || index >= part.Vertices.Count))
{
throw new InvalidDataException("人物三角形索引越界");
}
}
if (BoneNames.Any((string bone) => !bones.Contains(bone)))
{
throw new InvalidDataException("人物必须包含完整的头、身体和四肢");
}
}
}
public sealed class ModelPart
{
public string Name { get; set; } = string.Empty;
public string Bone { get; set; } = string.Empty;
public float[] Anchor { get; set; } = Array.Empty<float>();
public string EndBone { get; set; } = string.Empty;
public float Length { get; set; }
public List<float[]> Vertices { get; set; } = new List<float[]>();
public List<float[]> UV { get; set; } = new List<float[]>();
public List<int> Triangles { get; set; } = new List<int>();
}
[BepInPlugin("xmc.gtfo.villager_character", "XMC Brown Robe Villager", "1.0.3")]
public sealed class Plugin : BasePlugin
{
internal static ManualLogSource Logger = null;
internal static ConfigEntry<bool> Enabled = null;
internal static ConfigEntry<bool> IncludeLocal = null;
internal static ConfigEntry<string> Slots = null;
internal static ConfigEntry<KeyCode> Toggle = null;
internal static string AssetFolder = string.Empty;
public override void Load()
{
Logger = ((BasePlugin)this).Log;
AssetFolder = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "Assets");
Enabled = ((BasePlugin)this).Config.Bind<bool>("Appearance", "Enabled", true, "开启方块村民人物外观,仅改变本机显示。");
IncludeLocal = ((BasePlugin)this).Config.Bind<bool>("Appearance", "IncludeLocalPlayer", false, "是否替换本机玩家身体;关闭后只替换其他玩家,不处理大厅预览。");
Slots = ((BasePlugin)this).Config.Bind<string>("Appearance", "PlayerSlots", "0,1,2,3", "需要替换的玩家槽位,从 0 开始,逗号分隔;默认覆盖本机看到的全部队友和机器人。");
Toggle = ((BasePlugin)this).Config.Bind<KeyCode>("Hotkeys", "Toggle", (KeyCode)287, "切换人物外观;关闭后恢复原身体渲染。");
ClassInjector.RegisterTypeInIl2Cpp<CharacterDriver>();
((BasePlugin)this).AddComponent<CharacterDriver>();
((BasePlugin)this).Log.LogInfo((object)"棕袍方块村民 1.0.3 已载入:F6 开关;只替换任务内其他玩家,不处理本机和大厅预览。");
}
}
internal sealed class VillagerRig : IDisposable
{
private readonly Animator animator;
private readonly List<GameObject> objects = new List<GameObject>();
private readonly List<Mesh> meshes = new List<Mesh>();
private readonly Dictionary<int, (Renderer Renderer, bool Enabled)> originals = new Dictionary<int, (Renderer, bool)>();
private Material? material;
private bool disposed;
internal int Parts => objects.Count;
internal VillagerRig(PlayerAgent player, ModelData model, Texture2D texture)
{
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_0324: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_0343: Unknown result type (might be due to invalid IL or missing references)
//IL_0347: Unknown result type (might be due to invalid IL or missing references)
//IL_034c: Unknown result type (might be due to invalid IL or missing references)
//IL_0351: Unknown result type (might be due to invalid IL or missing references)
//IL_0369: Unknown result type (might be due to invalid IL or missing references)
//IL_036e: Unknown result type (might be due to invalid IL or missing references)
//IL_0372: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0381: Unknown result type (might be due to invalid IL or missing references)
//IL_0388: Unknown result type (might be due to invalid IL or missing references)
//IL_0419: Unknown result type (might be due to invalid IL or missing references)
//IL_041e: Unknown result type (might be due to invalid IL or missing references)
//IL_0424: Unknown result type (might be due to invalid IL or missing references)
//IL_0429: Unknown result type (might be due to invalid IL or missing references)
//IL_0432: Unknown result type (might be due to invalid IL or missing references)
//IL_0437: Unknown result type (might be due to invalid IL or missing references)
//IL_043c: Unknown result type (might be due to invalid IL or missing references)
//IL_0443: Unknown result type (might be due to invalid IL or missing references)
//IL_0448: Unknown result type (might be due to invalid IL or missing references)
//IL_051f: Unknown result type (might be due to invalid IL or missing references)
//IL_0524: Unknown result type (might be due to invalid IL or missing references)
//IL_0549: Unknown result type (might be due to invalid IL or missing references)
//IL_054e: Unknown result type (might be due to invalid IL or missing references)
//IL_0567: Expected O, but got Unknown
//IL_047b: Unknown result type (might be due to invalid IL or missing references)
//IL_0480: Unknown result type (might be due to invalid IL or missing references)
//IL_0484: Unknown result type (might be due to invalid IL or missing references)
//IL_0489: Unknown result type (might be due to invalid IL or missing references)
//IL_048e: Unknown result type (might be due to invalid IL or missing references)
//IL_0492: Unknown result type (might be due to invalid IL or missing references)
//IL_0496: Unknown result type (might be due to invalid IL or missing references)
//IL_049b: Unknown result type (might be due to invalid IL or missing references)
//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
//IL_060f: Expected O, but got Unknown
//IL_0500: Unknown result type (might be due to invalid IL or missing references)
//IL_0507: Unknown result type (might be due to invalid IL or missing references)
//IL_050c: Unknown result type (might be due to invalid IL or missing references)
//IL_0511: Unknown result type (might be due to invalid IL or missing references)
animator = player.AnimatorBody ?? throw new InvalidOperationException("第三人称动画骨架尚未生成");
try
{
SkinnedMeshRenderer[] array = ((IEnumerable<SkinnedMeshRenderer>)((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>(true)).Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer != (Object)null && (Object)(object)renderer.sharedMesh != (Object)null && !((Object)renderer).name.StartsWith("XMC_", StringComparison.Ordinal)).ToArray();
if (array.Length == 0 && (Object)(object)player.m_rigBaseForClothes != (Object)null)
{
array = ((IEnumerable<SkinnedMeshRenderer>)player.m_rigBaseForClothes.GetComponentsInChildren<SkinnedMeshRenderer>(true)).Where((SkinnedMeshRenderer renderer) => (Object)(object)renderer != (Object)null && (Object)(object)renderer.sharedMesh != (Object)null).ToArray();
}
if (array.Length == 0)
{
throw new InvalidOperationException("未找到原身体蒙皮网格");
}
Dictionary<string, Transform> dictionary = new Dictionary<string, Transform>(StringComparer.Ordinal);
foreach (string boneName in ModelData.BoneNames)
{
Transform val = null;
if (animator.isHuman && Enum.TryParse<HumanBodyBones>(boneName, out HumanBodyBones result))
{
val = animator.GetBoneTransform(result);
}
if ((Object)(object)val == (Object)null && boneName == "Chest" && animator.isHuman)
{
val = animator.GetBoneTransform((HumanBodyBones)7);
}
if ((Object)(object)val == (Object)null)
{
val = FindBone(((Component)animator).transform, boneName);
}
if ((Object)(object)val == (Object)null)
{
throw new InvalidOperationException("缺少骨骼 " + boneName + ";不隐藏原人物");
}
dictionary.Add(boneName, val);
}
Dictionary<int, Matrix4x4> dictionary2 = new Dictionary<int, Matrix4x4>();
Matrix4x4 val2;
foreach (SkinnedMeshRenderer item in array.OrderByDescending((SkinnedMeshRenderer renderer) => renderer.sharedMesh.vertexCount))
{
Il2CppStructArray<Matrix4x4> bindposes = item.sharedMesh.bindposes;
Il2CppReferenceArray<Transform> bones = item.bones;
if (((Il2CppArrayBase<Transform>)(object)bones).Length != ((Il2CppArrayBase<Matrix4x4>)(object)bindposes).Length)
{
continue;
}
for (int num = 0; num < ((Il2CppArrayBase<Transform>)(object)bones).Length; num++)
{
if ((Object)(object)((Il2CppArrayBase<Transform>)(object)bones)[num] != (Object)null && !dictionary2.ContainsKey(((Object)((Il2CppArrayBase<Transform>)(object)bones)[num]).GetInstanceID()))
{
int instanceID = ((Object)((Il2CppArrayBase<Transform>)(object)bones)[num]).GetInstanceID();
Matrix4x4 localToWorldMatrix = ((Component)item).transform.localToWorldMatrix;
val2 = ((Il2CppArrayBase<Matrix4x4>)(object)bindposes)[num];
dictionary2.Add(instanceID, localToWorldMatrix * ((Matrix4x4)(ref val2)).inverse);
}
}
}
foreach (KeyValuePair<string, Transform> item2 in dictionary)
{
if (!dictionary2.ContainsKey(((Object)item2.Value).GetInstanceID()))
{
throw new InvalidOperationException("原蒙皮缺少 " + item2.Key + " 的绑定姿态;不使用当前动画姿态猜测");
}
}
Matrix4x4 root = ((Component)player).transform.localToWorldMatrix;
Matrix4x4 inverse = ((Matrix4x4)(ref root)).inverse;
val2 = dictionary2[((Object)dictionary["Head"]).GetInstanceID()];
Vector3 val3 = ((Matrix4x4)(ref inverse)).MultiplyPoint3x4(((Matrix4x4)(ref val2)).MultiplyPoint3x4(Vector3.zero));
val2 = dictionary2[((Object)dictionary["LeftFoot"]).GetInstanceID()];
Vector3 val4 = ((Matrix4x4)(ref inverse)).MultiplyPoint3x4(((Matrix4x4)(ref val2)).MultiplyPoint3x4(Vector3.zero));
float num2 = Mathf.Abs(val3.y - val4.y) / (model.SourceHeadHeight - model.SourceFootHeight);
if (!float.IsFinite(num2) || num2 < 0.35f || num2 > 2f)
{
throw new InvalidOperationException("人物骨架比例异常");
}
material = CreateMaterial(texture, array);
foreach (ModelPart part in model.Parts)
{
Transform val5 = dictionary[part.Bone];
Matrix4x4 val6 = dictionary2[((Object)val5).GetInstanceID()];
Matrix4x4 inverseBone = ((Matrix4x4)(ref val6)).inverse;
Vector3 start = ((Matrix4x4)(ref val6)).MultiplyPoint3x4(Vector3.zero);
Quaternion rotation = Quaternion.identity;
float partScale = num2;
if (part.EndBone.Length > 0)
{
val2 = dictionary2[((Object)dictionary[part.EndBone]).GetInstanceID()];
Vector3 val7 = ((Matrix4x4)(ref val2)).MultiplyPoint3x4(Vector3.zero);
Vector3 val8 = ((Matrix4x4)(ref inverse)).MultiplyVector(val7 - start);
partScale = ((Vector3)(ref val8)).magnitude / part.Length;
if (!float.IsFinite(partScale) || partScale < 0.2f || partScale > 3f)
{
throw new InvalidOperationException("肢体比例异常:" + part.Bone);
}
rotation = Quaternion.FromToRotation(Vector3.down, ((Vector3)(ref val8)).normalized);
}
Vector3 anchor = Vector(part.Anchor);
Vector3[] array2 = part.Vertices.Select((float[] vertex) => ((Matrix4x4)(ref inverseBone)).MultiplyPoint3x4(start + ((Matrix4x4)(ref root)).MultiplyVector(rotation * ((Vector(vertex) - anchor) * partScale)))).ToArray();
Mesh val9 = new Mesh
{
name = "XMC_Villager_" + part.Name
};
meshes.Add(val9);
val9.vertices = Il2CppStructArray<Vector3>.op_Implicit(array2);
val9.uv = Il2CppStructArray<Vector2>.op_Implicit(((IEnumerable<float[]>)part.UV).Select((Func<float[], Vector2>)((float[] uv) => new Vector2(uv[0], uv[1]))).ToArray());
val9.triangles = Il2CppStructArray<int>.op_Implicit(part.Triangles.ToArray());
val9.RecalculateNormals();
val9.RecalculateBounds();
GameObject val10 = new GameObject("XMC_Villager_" + part.Name)
{
layer = ((Component)array[0]).gameObject.layer
};
objects.Add(val10);
val10.transform.SetParent(val5, false);
val10.AddComponent<MeshFilter>().sharedMesh = val9;
((Renderer)val10.AddComponent<MeshRenderer>()).sharedMaterial = material;
}
HashSet<int> ids = new HashSet<int>(dictionary.Values.Select((Transform bone) => ((Object)bone).GetInstanceID()));
SkinnedMeshRenderer[] array3 = array;
foreach (SkinnedMeshRenderer val11 in array3)
{
if (((IEnumerable<Transform>)val11.bones).Any((Transform bone) => (Object)(object)bone != (Object)null && ids.Contains(((Object)bone).GetInstanceID())) && (Object)(object)((Component)val11).GetComponentInParent<ItemEquippable>() == (Object)null)
{
originals[((Object)val11).GetInstanceID()] = ((Renderer)(object)val11, ((Renderer)val11).enabled);
}
}
if (originals.Count == 0)
{
throw new InvalidOperationException("没有可安全隐藏的身体网格");
}
HideOriginals();
}
catch
{
Dispose();
throw;
}
}
private static Vector3 Vector(float[] values)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
return new Vector3(values[0], values[1], values[2]);
}
private static Transform? FindBone(Transform root, string semantic)
{
if (semantic == null)
{
goto IL_02c4;
}
int length = semantic.Length;
string[] array;
if (length <= 5)
{
if (length != 4)
{
if (length != 5 || !(semantic == "Chest"))
{
goto IL_02c4;
}
array = new string[4] { "spine2", "spine02", "chest", "spine1" };
}
else
{
char c = semantic[1];
if (c != 'e')
{
if (c != 'i' || !(semantic == "Hips"))
{
goto IL_02c4;
}
array = new string[2] { "hips", "pelvis" };
}
else
{
if (!(semantic == "Head"))
{
goto IL_02c4;
}
array = new string[1] { "head" };
}
}
}
else if (length != 12)
{
if (length != 13)
{
goto IL_02c4;
}
char c = semantic[5];
if (c != 'L')
{
if (c != 'U')
{
goto IL_02c4;
}
if (!(semantic == "RightUpperArm"))
{
if (!(semantic == "RightUpperLeg"))
{
goto IL_02c4;
}
array = new string[3] { "rightupleg", "rthigh", "rightthigh" };
}
else
{
array = new string[3] { "rightupperarm", "rupperarm", "rightarm" };
}
}
else if (!(semantic == "RightLowerArm"))
{
if (!(semantic == "RightLowerLeg"))
{
goto IL_02c4;
}
array = new string[3] { "rightleg", "rcalf", "rightcalf" };
}
else
{
array = new string[3] { "rightforearm", "rforearm", "rightlowerarm" };
}
}
else
{
char c = semantic[4];
if (c != 'L')
{
if (c != 'U')
{
goto IL_02c4;
}
if (!(semantic == "LeftUpperArm"))
{
if (!(semantic == "LeftUpperLeg"))
{
goto IL_02c4;
}
array = new string[3] { "leftupleg", "lthigh", "leftthigh" };
}
else
{
array = new string[3] { "leftupperarm", "lupperarm", "leftarm" };
}
}
else if (!(semantic == "LeftLowerArm"))
{
if (!(semantic == "LeftLowerLeg"))
{
goto IL_02c4;
}
array = new string[3] { "leftleg", "lcalf", "leftcalf" };
}
else
{
array = new string[3] { "leftforearm", "lforearm", "leftlowerarm" };
}
}
goto IL_02fb;
IL_02fb:
string[] array2 = array;
Il2CppArrayBase<Transform> componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
array = array2;
foreach (string text in array)
{
foreach (Transform item in componentsInChildren)
{
string text2 = new string(((Object)item).name.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
if (text2 == text || text2.EndsWith("bip01" + text, StringComparison.Ordinal) || text2.EndsWith("mixamorig" + text, StringComparison.Ordinal))
{
return item;
}
}
}
return null;
IL_02c4:
array = new string[2]
{
semantic.ToLowerInvariant(),
semantic.Replace("Left", "L").Replace("Right", "R").ToLowerInvariant()
};
goto IL_02fb;
}
private static Material CreateMaterial(Texture2D texture, SkinnedMeshRenderer[] renderers)
{
//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_0052: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
string[] array = new string[3] { "Standard", "Legacy Shaders/Diffuse", "Unlit/Texture" };
for (int i = 0; i < array.Length; i++)
{
Shader val = Shader.Find(array[i]);
if (!((Object)(object)val == (Object)null) && val.isSupported)
{
Material val2 = new Material(val)
{
name = "XMC_Villager_PixelCloth"
};
val2.mainTexture = (Texture)(object)texture;
if (val2.HasProperty("_Color"))
{
val2.SetColor("_Color", Color.white);
}
if (val2.HasProperty("_Glossiness"))
{
val2.SetFloat("_Glossiness", 0f);
}
if (val2.HasProperty("_Metallic"))
{
val2.SetFloat("_Metallic", 0f);
}
return val2;
}
}
for (int i = 0; i < renderers.Length; i++)
{
foreach (Material item in (Il2CppArrayBase<Material>)(object)((Renderer)renderers[i]).sharedMaterials)
{
if (!((Object)(object)item == (Object)null) && !((Object)(object)item.shader == (Object)null) && item.shader.isSupported && item.HasProperty("_MainTex"))
{
Material val3 = new Material(item)
{
name = "XMC_Villager_NativeCloth"
};
val3.SetTexture("_MainTex", (Texture)(object)texture);
if (val3.HasProperty("_Color"))
{
val3.SetColor("_Color", Color.white);
}
if (val3.HasProperty("_EmissionColor"))
{
val3.SetColor("_EmissionColor", Color.black);
}
val3.DisableKeyword("_EMISSION");
return val3;
}
}
}
throw new InvalidOperationException("未找到可显示像素贴图的兼容材质");
}
internal bool Valid(PlayerAgent player)
{
if (!disposed && (Object)(object)animator != (Object)null && (Object)(object)player.AnimatorBody != (Object)null && ((Object)animator).GetInstanceID() == ((Object)player.AnimatorBody).GetInstanceID())
{
return objects.All((GameObject obj) => (Object)(object)obj != (Object)null);
}
return false;
}
internal void HideOriginals()
{
if (disposed)
{
return;
}
foreach (var value in originals.Values)
{
if ((Object)(object)value.Renderer != (Object)null)
{
value.Renderer.enabled = false;
}
}
}
public void Dispose()
{
if (disposed)
{
return;
}
disposed = true;
foreach (var value in originals.Values)
{
if ((Object)(object)value.Renderer != (Object)null)
{
value.Renderer.enabled = value.Enabled;
}
}
originals.Clear();
foreach (GameObject @object in objects)
{
if ((Object)(object)@object != (Object)null)
{
Object.Destroy((Object)(object)@object);
}
}
foreach (Mesh mesh in meshes)
{
if ((Object)(object)mesh != (Object)null)
{
Object.Destroy((Object)(object)mesh);
}
}
objects.Clear();
meshes.Clear();
if ((Object)(object)material != (Object)null)
{
Object.Destroy((Object)(object)material);
}
}
}
}