using System; using System.Collections; 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.RegularExpressions; using AntlerShed.SkinRegistry; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LegacyEnemySkinsBridge")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.1.0")] [assembly: AssemblyInformationalVersion("1.1.1")] [assembly: AssemblyProduct("LegacyEnemySkinsBridge")] [assembly: AssemblyTitle("LegacyEnemySkinsBridge")] [assembly: AssemblyVersion("1.1.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 LegacyEnemySkinsBridge { [BepInPlugin("legacyskinsbridge.plugin", "Legacy Enemy Skins Bridge", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "legacyskinsbridge.plugin"; public const string PluginName = "Legacy Enemy Skins Bridge"; public const string PluginVersion = "1.1.1"; internal static ManualLogSource Log; private Harmony _harmony; private ConfigEntry _enabled; private ConfigEntry _automaticDiscovery; private ConfigEntry _defaultFrequency; private static readonly LegacySkinDefinition[] Definitions = new LegacySkinDefinition[18] { new LegacySkinDefinition("Better Ghost (Cheems)", "LegacyBridge.Ghost.Cheems", "LethalCompany.GhostGirl", "BetterGhost", "BetterGhost.Patches.DressGirlAIPatch", "StartPatch", "Cheemful-BetterGhost"), new LegacySkinDefinition("Flandre Ghost Girl", "LegacyBridge.Ghost.Flandre", "LethalCompany.GhostGirl", "FlandreGhostGirl", "FlandreGhost.Patches.DressGirlAIPatch", "StartPatch", "Catalyss-FlandreGhostGirl"), new LegacySkinDefinition("FNaF Endoskeleton", "LegacyBridge.Coil.Endo", "LethalCompany.Coilhead", "FNaFEndoCoilhead", "FNaFEndoCoilhead.Patches.SpringManPatch", "Postfix", "OrtonLongGaming-FNaFEndoCoilhead"), new LegacySkinDefinition("SCP-173", "LegacyBridge.Coil.SCP173", "LethalCompany.Coilhead", "SCP_173", "SCP_173.Patches.CoilheadPatch", "Summon173", "raydenoir-SCP173CoilheadSFX"), new LegacySkinDefinition("Weeping Angel", "LegacyBridge.Coil.WeepingAngel", "LethalCompany.Coilhead", "WeepingAngel", "WeepingAngel.Patches.CoilheadPatch", "Summon173", "raydenoir-WeepingAngels"), new LegacySkinDefinition("Better Coilhead", "LegacyBridge.Coil.Better", "LethalCompany.Coilhead", "NewCoil", "NewCoil.Patches.NewCoilPatch", "CoilPreLoadPatch", "lethal_coder-BetterCoilheadModel"), new LegacySkinDefinition("Freddy Bracken", "LegacyBridge.Bracken.Freddy", "LethalCompany.Bracken", "FreddyBracken", "FreddyBracken.Patches.FlowermanPatch", "Postfix", "OrtonLongGaming-FreddyBracken"), new LegacySkinDefinition("Better Bracken", "LegacyBridge.Bracken.Better", "LethalCompany.Bracken", "ModelRequestA", "ModelRequestA.Patches.BrackenPatch", "DioPreLoadPatch", "lethal_coder-BetterBrackenModel"), new LegacySkinDefinition("Freminet Butler", "LegacyBridge.Butler.Freminet", "LethalCompany.Butler", "FreminetButler", "FreminetButler.FremModBase", "PluginDetectButler", "GoblinKingShmee-FreminetButlerMod"), new LegacySkinDefinition("Minecraft Spider", "LegacyBridge.Spider.Minecraft", "LethalCompany.BunkerSpider", "MinecraftSpiderMod", "MinecraftSpiderMod.Patches.SandSpiderAIPatch", "Start", "Legoking236-MinecraftSpiderMod"), new LegacySkinDefinition("FNaF Puppet Jester", "LegacyBridge.Jester.Puppet", "LethalCompany.Jester", "PuppetJester", "PuppetJester.Patches.JesterPatch", "Postfix", "OrtonLongGaming-PuppetJester"), new LegacySkinDefinition("TBH Creature", "LegacyBridge.HoarderBug.TBH", "LethalCompany.HoarderBug", "snrk.tbhCreature", "YippeeBugMod.YippeeBug.Patches.HoarderBugPatch", "Postfix", "snrk-tbhCreatureReplacementMod"), new LegacySkinDefinition("Touhou Sekibanki", "LegacyBridge.Touhou.Sekibanki", "LethalCompany.Coilhead", "TouhouEnemyModels", "TouhouEnemyModels.Patches", "ReplaceEnemyModels", "BeanCan-TouhouEnemyModels"), new LegacySkinDefinition("Touhou Satori", "LegacyBridge.Touhou.Satori", "LethalCompany.Nutcracker", "TouhouEnemyModels", "TouhouEnemyModels.Patches", "ReplaceEnemyModels", "BeanCan-TouhouEnemyModels"), new LegacySkinDefinition("Touhou Suika", "LegacyBridge.Touhou.Suika", "LethalCompany.ForestKeeper", "TouhouEnemyModels", "TouhouEnemyModels.Patches", "ReplaceEnemyModels", "BeanCan-TouhouEnemyModels"), new LegacySkinDefinition("Touhou Marisa", "LegacyBridge.Touhou.Marisa", "LethalCompany.HoarderBug", "TouhouEnemyModels", "TouhouEnemyModels.Patches", "ReplaceEnemyModels", "BeanCan-TouhouEnemyModels"), new LegacySkinDefinition("Touhou Utsuho", "LegacyBridge.Touhou.Utsuho", "LethalCompany.OldBird", "TouhouEnemyModels", "TouhouEnemyModels.V50Patches", "ReplaceUtsuhoTheme", "BeanCan-TouhouEnemyModels"), new LegacySkinDefinition("Touhou Yuyuko", "LegacyBridge.Touhou.Yuyuko", "LethalCompany.EarthLeviathan", "TouhouEnemyModels", "TouhouEnemyModels.Patches", "ReplaceEnemyModels", "BeanCan-TouhouEnemyModels") }; private void Awake() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Convert supported legacy enemy model replacers into Enemy Skin Registry variants. Restart required after changing this option."); _automaticDiscovery = ((BaseUnityPlugin)this).Config.Bind("General", "Automatic discovery", true, "Also detect simple enemy model replacers that are not in the built-in compatibility catalog. Restart required."); _defaultFrequency = ((BaseUnityPlugin)this).Config.Bind("General", "New skin default frequency", 0.25f, new ConfigDescription("Initial Enemy Skin Registry frequency assigned to newly discovered skins.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); _enabled.SettingChanged += delegate { Log.LogWarning((object)"Enabled changed. Restart the game to safely apply the new bridge state."); }; _automaticDiscovery.SettingChanged += delegate { Log.LogWarning((object)"Automatic discovery changed. Restart the game to safely apply the new bridge state."); }; if (!_enabled.Value) { Log.LogInfo((object)"Legacy model conversion is disabled in config. Original replacers will run normally."); return; } _harmony = new Harmony("legacyskinsbridge.plugin"); ((MonoBehaviour)this).StartCoroutine(InitializeAfterPlugins()); } private IEnumerator InitializeAfterPlugins() { yield return null; List list = Definitions.ToList(); if (_automaticDiscovery.Value) { list.AddRange(DiscoverSimpleReplacers(list)); } int num = 0; foreach (LegacySkinDefinition item in list) { if (!item.Resolve()) { Log.LogWarning((object)("Skipping " + item.Label + ": source assembly or patch method was not found.")); continue; } int num2 = UnpatchAutomaticReplacement(item.PatchMethod); if (num2 == 0) { Log.LogWarning((object)(item.Label + ": the automatic replacement patch was not found; duplicate models may still occur.")); } else { Log.LogInfo((object)$"Disabled {num2} automatic patch(es) for {item.Label}."); } try { EnemySkinRegistry.RegisterSkin((Skin)(object)new LegacySkin(item), (DefaultSkinConfigData?)new DefaultSkinConfigData(Array.Empty(), Mathf.Clamp01(_defaultFrequency.Value), 0.25f)); num++; } catch (Exception arg) { Log.LogError((object)$"Could not register {item.Label}: {arg}"); } } Log.LogInfo((object)$"Registered {num} legacy model replacements as mutually exclusive Enemy Skin Registry skins."); } private IEnumerable DiscoverSimpleReplacers(IEnumerable catalog) { List list = new List(); HashSet hashSet = new HashSet(from definition in catalog where definition.Resolve() select definition.PatchMethod); MethodBase[] array = Harmony.GetAllPatchedMethods().ToArray(); foreach (MethodBase methodBase in array) { if (!IsEnemyInitializationMethod(methodBase, out var enemyId, out var label)) { continue; } Patches patchInfo = Harmony.GetPatchInfo(methodBase); if (patchInfo == null) { continue; } foreach (Patch item in patchInfo.Prefixes.Concat(patchInfo.Postfixes)) { MethodInfo patchMethod = item.PatchMethod; if (patchMethod == null || hashSet.Contains(patchMethod)) { continue; } Assembly assembly = patchMethod.DeclaringType?.Assembly; if (!(assembly == null) && !(assembly == typeof(Plugin).Assembly) && !(assembly == typeof(EnemySkinRegistry).Assembly)) { string text = FindPackageRoot(assembly.Location); if (TryReadLegacyModelPackage(text, out var packageName)) { string id = $"AutoBridge.{SanitizeId(assembly.GetName().Name)}.{SanitizeId(label)}.{patchMethod.MetadataToken}"; LegacySkinDefinition legacySkinDefinition = new LegacySkinDefinition(packageName + " (" + label + ")", id, enemyId, patchMethod, Path.Combine(text, "icon.png")); hashSet.Add(patchMethod); list.Add(legacySkinDefinition); Log.LogInfo((object)("Automatically discovered enemy model replacer: " + legacySkinDefinition.Label + ".")); } } } } return list; } private static bool IsEnemyInitializationMethod(MethodBase method, out string enemyId, out string label) { enemyId = null; label = null; Type declaringType = method.DeclaringType; if (declaringType == null || !typeof(EnemyAI).IsAssignableFrom(declaringType) || (method.Name != "Start" && method.Name != "Awake" && method.Name != "OnEnable")) { return false; } (enemyId, label) = declaringType.Name switch { "BaboonBirdAI" => ("LethalCompany.BaboonHawk", "Baboon Hawk"), "ClaySurgeonAI" => ("LethalCompany.Barber", "Barber"), "FlowermanAI" => ("LethalCompany.Bracken", "Bracken"), "SandSpiderAI" => ("LethalCompany.BunkerSpider", "Bunker Spider"), "ButlerEnemyAI" => ("LethalCompany.Butler", "Butler"), "SpringManAI" => ("LethalCompany.Coilhead", "Coilhead"), "SandWormAI" => ("LethalCompany.EarthLeviathan", "Earth Leviathan"), "MouthDogAI" => ("LethalCompany.EyelessDog", "Eyeless Dog"), "ForestGiantAI" => ("LethalCompany.ForestKeeper", "Forest Keeper"), "DressGirlAI" => ("LethalCompany.GhostGirl", "Ghost Girl"), "HoarderBugAI" => ("LethalCompany.HoarderBug", "Hoarding Bug"), "BlobAI" => ("LethalCompany.Hygrodere", "Hygrodere"), "JesterAI" => ("LethalCompany.Jester", "Jester"), "NutcrackerEnemyAI" => ("LethalCompany.Nutcracker", "Nutcracker"), "RadMechAI" => ("LethalCompany.OldBird", "Old Bird"), "CentipedeAI" => ("LethalCompany.SnareFlea", "Snare Flea"), "PufferAI" => ("LethalCompany.SporeLizard", "Spore Lizard"), "CrawlerAI" => ("LethalCompany.Thumper", "Thumper"), _ => (null, null), }; return enemyId != null; } private static string FindPackageRoot(string assemblyPath) { if (string.IsNullOrWhiteSpace(assemblyPath)) { return string.Empty; } DirectoryInfo directoryInfo = new FileInfo(assemblyPath).Directory; string value = Path.GetFullPath(Paths.PluginPath).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; int num = 0; while (directoryInfo != null && num < 5 && directoryInfo.FullName.StartsWith(value, StringComparison.OrdinalIgnoreCase)) { if (File.Exists(Path.Combine(directoryInfo.FullName, "manifest.json"))) { return directoryInfo.FullName; } num++; directoryInfo = directoryInfo.Parent; } return string.Empty; } private static bool TryReadLegacyModelPackage(string packageRoot, out string packageName) { packageName = null; if (string.IsNullOrWhiteSpace(packageRoot)) { return false; } try { string text = File.ReadAllText(Path.Combine(packageRoot, "manifest.json")); if (text.IndexOf("EnemySkinRegistry", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("EnemySkinKit", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } Match match = Regex.Match(text, "\\\"description\\\"\\s*:\\s*\\\"(?(?:\\\\.|[^\\\"])*)\\\"", RegexOptions.IgnoreCase); if (!Regex.IsMatch(match.Success ? match.Groups["value"].Value : string.Empty, "replac|reskin|enemy model|creature model", RegexOptions.IgnoreCase)) { return false; } Match match2 = Regex.Match(text, "\\\"name\\\"\\s*:\\s*\\\"(?(?:\\\\.|[^\\\"])*)\\\"", RegexOptions.IgnoreCase); packageName = (match2.Success ? match2.Groups["value"].Value : new DirectoryInfo(packageRoot).Name); return true; } catch (Exception ex) { Log.LogDebug((object)("Could not inspect package manifest at " + packageRoot + ": " + ex.Message)); return false; } } private static string SanitizeId(string value) { return Regex.Replace(value ?? "Unknown", "[^A-Za-z0-9_.-]", string.Empty); } private int UnpatchAutomaticReplacement(MethodInfo patchMethod) { int num = 0; MethodBase[] array = Harmony.GetAllPatchedMethods().ToArray(); foreach (MethodBase methodBase in array) { Patches patchInfo = Harmony.GetPatchInfo(methodBase); if (patchInfo != null) { Patch[] array2 = (from p in patchInfo.Prefixes.Concat(patchInfo.Postfixes).Concat(patchInfo.Transpilers).Concat(patchInfo.Finalizers) where p.PatchMethod == patchMethod select p).ToArray(); for (int num2 = 0; num2 < array2.Length; num2++) { _ = array2[num2]; _harmony.Unpatch(methodBase, patchMethod); num++; } } } return num; } } internal sealed class LegacySkinDefinition { private Texture2D _icon; private readonly string _iconPath; public string Label { get; } public string Id { get; } public string EnemyId { get; } public string AssemblyName { get; } public string PatchTypeName { get; } public string PatchMethodName { get; } public string PackageFolder { get; } public MethodInfo PatchMethod { get; private set; } public LegacySkinDefinition(string label, string id, string enemyId, string assemblyName, string patchTypeName, string patchMethodName, string packageFolder) { Label = label; Id = id; EnemyId = enemyId; AssemblyName = assemblyName; PatchTypeName = patchTypeName; PatchMethodName = patchMethodName; PackageFolder = packageFolder; } public LegacySkinDefinition(string label, string id, string enemyId, MethodInfo patchMethod, string iconPath) { Label = label; Id = id; EnemyId = enemyId; AssemblyName = patchMethod.DeclaringType?.Assembly.GetName().Name ?? string.Empty; PatchTypeName = patchMethod.DeclaringType?.FullName ?? string.Empty; PatchMethodName = patchMethod.Name; PackageFolder = string.Empty; PatchMethod = patchMethod; _iconPath = iconPath; } public bool Resolve() { if (PatchMethod != null) { return true; } PatchMethod = (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, AssemblyName, StringComparison.OrdinalIgnoreCase))?.GetType(PatchTypeName, throwOnError: false))?.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == PatchMethodName && m.GetParameters().Any((ParameterInfo p) => typeof(EnemyAI).IsAssignableFrom(UnwrapByRef(p.ParameterType)))); return PatchMethod != null; } public Texture2D GetIcon() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if ((Object)(object)_icon != (Object)null) { return _icon; } _icon = new Texture2D(2, 2, (TextureFormat)4, false) { name = Id + ".Icon" }; try { string path = (string.IsNullOrWhiteSpace(_iconPath) ? Path.Combine(Paths.PluginPath, PackageFolder, "icon.png") : _iconPath); if (File.Exists(path)) { ImageConversion.LoadImage(_icon, File.ReadAllBytes(path)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not load icon for " + Label + ": " + ex.Message)); } return _icon; } private static Type UnwrapByRef(Type type) { if (!type.IsByRef) { return type; } return type.GetElementType(); } } internal sealed class LegacySkin : Skin { private readonly LegacySkinDefinition _definition; public string Label => _definition.Label; public string Id => _definition.Id; public string EnemyId => _definition.EnemyId; public Texture2D Icon => _definition.GetIcon(); public LegacySkin(LegacySkinDefinition definition) { _definition = definition; } public Skinner CreateSkinner() { return (Skinner)(object)new LegacySkinner(_definition); } } internal sealed class LegacySkinner : Skinner { private readonly LegacySkinDefinition _definition; private LegacySnapshot _snapshot; public LegacySkinner(LegacySkinDefinition definition) { _definition = definition; } public void Apply(GameObject enemy) { if ((Object)(object)enemy == (Object)null) { return; } try { _snapshot = new LegacySnapshot(enemy); object[] parameters = BuildArguments(_definition.PatchMethod, enemy); object obj = (_definition.PatchMethod.IsStatic ? null : FindPluginInstance(_definition.PatchMethod.DeclaringType)); _definition.PatchMethod.Invoke(obj, parameters); Plugin.Log.LogDebug((object)("Applied " + _definition.Label + " to " + ((Object)enemy).name + ".")); } catch (TargetInvocationException ex) { Plugin.Log.LogError((object)$"{_definition.Label} failed while applying: {ex.InnerException ?? ex}"); _snapshot?.Restore(enemy); } catch (Exception arg) { Plugin.Log.LogError((object)$"{_definition.Label} failed while applying: {arg}"); _snapshot?.Restore(enemy); } } public void Remove(GameObject enemy) { try { _snapshot?.Restore(enemy); _snapshot = null; } catch (Exception arg) { Plugin.Log.LogError((object)$"{_definition.Label} failed while restoring the original model: {arg}"); } } private static object[] BuildArguments(MethodInfo method, GameObject enemy) { EnemyAI val = enemy.GetComponent() ?? enemy.GetComponentInParent(); ParameterInfo[] parameters = method.GetParameters(); object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; Type type = (parameterType.IsByRef ? parameterType.GetElementType() : parameterType); if (type.IsInstanceOfType(val)) { array[i] = val; } else if (type == typeof(GameObject)) { array[i] = enemy; } else if (typeof(Component).IsAssignableFrom(type)) { array[i] = enemy.GetComponent(type) ?? enemy.GetComponentInChildren(type, true); } else { array[i] = (type.IsValueType ? Activator.CreateInstance(type) : null); } } return array; } private static object FindPluginInstance(Type type) { return Object.FindObjectsOfType(type).FirstOrDefault(); } } internal sealed class LegacySnapshot { private sealed class GameObjectState { private readonly Transform _transform; private readonly Transform _parent; private readonly string _name; private readonly bool _active; private readonly int _layer; private readonly Vector3 _position; private readonly Quaternion _rotation; private readonly Vector3 _scale; public GameObjectState(Transform transform) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) _transform = transform; _parent = transform.parent; _name = ((Object)((Component)transform).gameObject).name; _active = ((Component)transform).gameObject.activeSelf; _layer = ((Component)transform).gameObject.layer; _position = transform.localPosition; _rotation = transform.localRotation; _scale = transform.localScale; } public void Restore() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_transform == (Object)null)) { _transform.SetParent(_parent, false); _transform.localPosition = _position; _transform.localRotation = _rotation; _transform.localScale = _scale; ((Object)((Component)_transform).gameObject).name = _name; ((Component)_transform).gameObject.layer = _layer; ((Component)_transform).gameObject.SetActive(_active); } } } private sealed class RendererState { private readonly Renderer _renderer; private readonly bool _enabled; private readonly Material[] _materials; public RendererState(Renderer renderer) { _renderer = renderer; _enabled = renderer.enabled; _materials = renderer.sharedMaterials; } public void Restore() { if (!((Object)(object)_renderer == (Object)null)) { _renderer.enabled = _enabled; _renderer.sharedMaterials = _materials; } } } private sealed class MeshFilterState { private readonly MeshFilter _filter; private readonly Mesh _mesh; public MeshFilterState(MeshFilter filter) { _filter = filter; _mesh = filter.sharedMesh; } public void Restore() { if ((Object)(object)_filter != (Object)null) { _filter.sharedMesh = _mesh; } } } private sealed class SkinnedMeshState { private readonly SkinnedMeshRenderer _renderer; private readonly Mesh _mesh; private readonly Transform _rootBone; private readonly Transform[] _bones; public SkinnedMeshState(SkinnedMeshRenderer renderer) { _renderer = renderer; _mesh = renderer.sharedMesh; _rootBone = renderer.rootBone; _bones = renderer.bones; } public void Restore() { if (!((Object)(object)_renderer == (Object)null)) { _renderer.sharedMesh = _mesh; _renderer.rootBone = _rootBone; _renderer.bones = _bones; } } } private sealed class AnimatorState { private readonly Animator _animator; private readonly RuntimeAnimatorController _controller; private readonly Avatar _avatar; private readonly bool _enabled; private readonly bool _rootMotion; private readonly AnimatorCullingMode _culling; private readonly AnimatorUpdateMode _updateMode; public AnimatorState(Animator animator) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) _animator = animator; _controller = animator.runtimeAnimatorController; _avatar = animator.avatar; _enabled = ((Behaviour)animator).enabled; _rootMotion = animator.applyRootMotion; _culling = animator.cullingMode; _updateMode = animator.updateMode; } public void Restore() { //IL_005a: 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) if (!((Object)(object)_animator == (Object)null)) { _animator.runtimeAnimatorController = _controller; _animator.avatar = _avatar; ((Behaviour)_animator).enabled = _enabled; _animator.applyRootMotion = _rootMotion; _animator.cullingMode = _culling; _animator.updateMode = _updateMode; } } } private readonly HashSet _existingObjects; private readonly List _gameObjects; private readonly List _renderers; private readonly List _meshFilters; private readonly List _skinnedMeshes; private readonly List _animators; public LegacySnapshot(GameObject root) { Transform[] componentsInChildren = root.GetComponentsInChildren(true); _existingObjects = new HashSet(componentsInChildren.Select((Transform t) => ((Object)((Component)t).gameObject).GetInstanceID())); _gameObjects = componentsInChildren.Select((Transform t) => new GameObjectState(t)).ToList(); _renderers = (from r in root.GetComponentsInChildren(true) select new RendererState(r)).ToList(); _meshFilters = (from m in root.GetComponentsInChildren(true) select new MeshFilterState(m)).ToList(); _skinnedMeshes = (from m in root.GetComponentsInChildren(true) select new SkinnedMeshState(m)).ToList(); _animators = (from a in root.GetComponentsInChildren(true) select new AnimatorState(a)).ToList(); } public void Restore(GameObject root) { if ((Object)(object)root == (Object)null) { return; } foreach (Transform item in root.GetComponentsInChildren(true).OrderByDescending(GetDepth)) { if ((Object)(object)item != (Object)(object)root.transform && !_existingObjects.Contains(((Object)((Component)item).gameObject).GetInstanceID())) { Object.Destroy((Object)(object)((Component)item).gameObject); } } foreach (GameObjectState gameObject in _gameObjects) { gameObject.Restore(); } foreach (RendererState renderer in _renderers) { renderer.Restore(); } foreach (MeshFilterState meshFilter in _meshFilters) { meshFilter.Restore(); } foreach (SkinnedMeshState skinnedMesh in _skinnedMeshes) { skinnedMesh.Restore(); } foreach (AnimatorState animator in _animators) { animator.Restore(); } } private static int GetDepth(Transform transform) { int num = 0; while ((Object)(object)transform.parent != (Object)null) { num++; transform = transform.parent; } return num; } } }