Decompiled source of AnyItemStands v0.5.0

AnyItemStands.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JG224.AnyItemStands.Core;
using JG224.AnyItemStands.Patches;
using JG224.ModCore.API;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("AnyItemStands")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.5.0.0")]
[assembly: AssemblyInformationalVersion("0.5.0")]
[assembly: AssemblyProduct("AnyItemStands")]
[assembly: AssemblyTitle("AnyItemStands")]
[assembly: AssemblyVersion("0.5.0.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 JG224.AnyItemStands
{
	internal sealed class AnyItemStandsConfig
	{
		internal ConfigEntry<bool> DebugLogging { get; }

		internal ConfigEntry<string> TransformOverrides { get; }

		private AnyItemStandsConfig(ConfigFile file)
		{
			DebugLogging = file.Bind<bool>("Diagnostics", "DebugLogging", false, "Enable verbose AnyItemStands diagnostics.");
			TransformOverrides = file.Bind<string>("Display", "TransformOverrides", "", "Per-item prefab=scale,x,y,z,pitch,yaw,roll; entries separated by semicolons. Offsets in metres and rotations in degrees. Example SwordIron=0.8,0,0.1,0,0,90,0. Scale 0.05-10, offsets +/-5, angles +/-360.");
		}

		internal static AnyItemStandsConfig Load(BaseUnityPlugin plugin, string configDirectory)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (!Directory.Exists(configDirectory))
			{
				Directory.CreateDirectory(configDirectory);
			}
			return new AnyItemStandsConfig(PluginConfigFiles.Attach(plugin, new ConfigFile(Path.Combine(configDirectory, "jg224.AnyItemStands.cfg"), true, plugin.Info.Metadata)));
		}

		internal IEnumerable<IDisposable> RegisterMetadata(ICoreServices services, ModuleId owner)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)TransformOverrides).Definition.Section, ((ConfigEntryBase)TransformOverrides).Definition.Key, (ConfigScope)1, (Func<string>)(() => TransformOverrides.Value), 1));
			yield return services.Configuration.Register(new ConfigSettingDescriptor(owner, ((ConfigEntryBase)DebugLogging).Definition.Section, ((ConfigEntryBase)DebugLogging).Definition.Key, (ConfigScope)5, (Func<string>)(() => Convert.ToString(((ConfigEntryBase)DebugLogging).BoxedValue, CultureInfo.InvariantCulture)), 1));
		}
	}
	[BepInPlugin("jg224.AnyItemStands", "AnyItemStands", "0.5.0")]
	[BepInProcess("valheim.exe")]
	[BepInDependency("com.jg224.modcore", "0.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "jg224.AnyItemStands";

		public const string PluginName = "AnyItemStands";

		public const string PluginVersion = "0.5.0";

		public const string ModCoreGuid = "com.jg224.modcore";

		public const string GeneralTweaksGuid = "JG224.GeneralTweaks";

		public const int ProtocolVersion = 1;

		public static readonly ModuleId ModuleId = new ModuleId("anyitemstands");

		private readonly List<IDisposable> _registrations = new List<IDisposable>();

		private Harmony _harmony;

		private bool _shutDown;

		internal static ManualLogSource Log { get; private set; }

		internal static AnyItemStandsConfig Settings { get; private set; }

		internal static ICoreServices Core { get; private set; }

		private void Awake()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = AnyItemStandsConfig.Load((BaseUnityPlugin)(object)this, Paths.ConfigPath);
			try
			{
				if (!ModCoreApi.IsAvailable)
				{
					throw new InvalidOperationException("ModCore did not initialize before AnyItemStands.");
				}
				Core = ModCoreApi.Services;
				RegisterWithCore();
				if (TryGetLegacyOwner(out var version))
				{
					string text = "GeneralTweaks " + version?.ToString() + " still contains Any Item Stands; AnyItemStands is paused to prevent duplicate hooks.";
					Core.Modules.SetState(ModuleId, (ModuleRuntimeState)3, text);
					((BaseUnityPlugin)this).Logger.LogWarning((object)(text + " Update GeneralTweaks to 3.0.0 or newer."));
				}
				else
				{
					_harmony = new Harmony("jg224.AnyItemStands");
					_harmony.PatchAll(Assembly.GetExecutingAssembly());
					Core.Modules.SetState(ModuleId, (ModuleRuntimeState)2, "Player item-stand attachment hooks ready.");
					Game.isModded = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)("AnyItemStands 0.5.0 loaded; protocol " + 1 + "."));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("AnyItemStands failed to initialize safely: " + ex));
				if (Core != null)
				{
					Core.Modules.SetState(ModuleId, (ModuleRuntimeState)5, ex.Message);
				}
				Shutdown();
				throw;
			}
		}

		private void OnDestroy()
		{
			Shutdown();
		}

		private void RegisterWithCore()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			SemanticVersion val = default(SemanticVersion);
			if (!SemanticVersion.TryParse("0.5.0", ref val))
			{
				throw new InvalidOperationException("Invalid plugin version.");
			}
			_registrations.Add(Core.Modules.Register(new ModuleDescriptor(ModuleId, "jg224.AnyItemStands", "AnyItemStands", val, 1, (ModuleSide)1, (ModuleRequirement)1, 0uL, 1, 1)));
			foreach (IDisposable item in Settings.RegisterMetadata(Core, ModuleId))
			{
				_registrations.Add(item);
			}
			_registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)9, (Action<LifecycleEvent>)delegate
			{
				SafeDisplayTemplates.Clear();
			}, 0));
			_registrations.Add(Core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)3, (Action<LifecycleEvent>)delegate
			{
				SafeDisplayTemplates.Clear();
			}, 0));
			_registrations.Add(Core.Compatibility.Register(new CompatibilityRule("jg224.AnyItemStands", "item_stand_all_items", (CompatibilityRuleKind)2, (CompatibilitySeverity)2, "Both mods expand player item stands; remove one implementation.", "item-stands")));
		}

		private static bool TryGetLegacyOwner(out Version version)
		{
			version = null;
			if (!Chainloader.PluginInfos.TryGetValue("JG224.GeneralTweaks", out var value))
			{
				return false;
			}
			version = value.Metadata.Version;
			if (version != null)
			{
				return version.CompareTo(new Version(3, 0, 0)) < 0;
			}
			return false;
		}

		private void Shutdown()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (_shutDown)
			{
				return;
			}
			_shutDown = true;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			ItemStandVisualContext.Current = null;
			SafeDisplayTemplates.Clear();
			for (int num = _registrations.Count - 1; num >= 0; num--)
			{
				try
				{
					_registrations[num].Dispose();
				}
				catch (Exception ex)
				{
					ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
					if (logger != null)
					{
						logger.LogWarning((object)("Registration cleanup failed: " + ex.Message));
					}
				}
			}
			_registrations.Clear();
			if (Core != null)
			{
				Core.Metrics.RemoveOwner(ModuleId);
			}
			Core = null;
			Settings = null;
			Log = null;
		}
	}
}
namespace JG224.AnyItemStands.Patches
{
	internal static class ItemStandVisualContext
	{
		internal sealed class Scope
		{
			internal ItemStand PreviousStand;

			internal bool PreviousForceDisable;

			internal bool ChangedForceDisable;

			internal bool Restored;
		}

		[ThreadStatic]
		internal static ItemStand Current;

		internal static bool IsPlayerStand(ItemStand stand)
		{
			Piece val = (Object.op_Implicit((Object)(object)stand) ? ((Component)stand).GetComponentInParent<Piece>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				return val.IsPlacedByPlayer();
			}
			return false;
		}

		internal static GameObject ResolveFallback(GameObject itemPrefab)
		{
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				return null;
			}
			Transform val = itemPrefab.transform.Find("attach");
			return (GameObject)(ItemStandRules.SelectFallback(Object.op_Implicit((Object)(object)val), Object.op_Implicit((Object)(object)itemPrefab.GetComponentInChildren<Renderer>(true)), itemPrefab.transform.childCount) switch
			{
				FallbackKind.NativeAttach => ((Component)val).gameObject, 
				FallbackKind.Root => SafeDisplayTemplates.Get(itemPrefab), 
				_ => null, 
			});
		}

		internal static Scope Enter(ItemStand stand, bool disableNetworkInit)
		{
			Scope scope = new Scope
			{
				PreviousStand = Current,
				PreviousForceDisable = ZNetView.m_forceDisableInit
			};
			Current = stand;
			if (disableNetworkInit && IsPlayerStand(stand))
			{
				ZNetView.m_forceDisableInit = true;
				scope.ChangedForceDisable = true;
			}
			return scope;
		}

		internal static void Exit(Scope scope)
		{
			if (scope != null && !scope.Restored)
			{
				if (scope.ChangedForceDisable)
				{
					ZNetView.m_forceDisableInit = scope.PreviousForceDisable;
				}
				Current = scope.PreviousStand;
				scope.Restored = true;
			}
		}
	}
	[HarmonyPatch(typeof(ItemStand), "CanAttach")]
	internal static class ItemStandCanAttachPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ItemStand __instance, out ItemStandVisualContext.Scope __state)
		{
			__state = ItemStandVisualContext.Enter(__instance, disableNetworkInit: false);
		}

		[HarmonyPostfix]
		private static void Postfix(ItemStand __instance, ItemData item, ref bool __result, ItemStandVisualContext.Scope __state)
		{
			if (!__result && ItemStandVisualContext.IsPlayerStand(__instance) && item != null && Object.op_Implicit((Object)(object)ItemStandVisualContext.ResolveFallback(item.m_dropPrefab)))
			{
				__result = true;
			}
			ItemStandVisualContext.Exit(__state);
		}

		[HarmonyFinalizer]
		private static Exception Finalizer(Exception __exception, ItemStandVisualContext.Scope __state)
		{
			ItemStandVisualContext.Exit(__state);
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ItemStand), "GetAttachPrefab")]
	internal static class ItemStandFallbackPrefabPatch
	{
		[HarmonyPostfix]
		private static void Postfix(GameObject item, ref GameObject __result)
		{
			if (!Object.op_Implicit((Object)(object)__result) && ItemStandVisualContext.IsPlayerStand(ItemStandVisualContext.Current))
			{
				__result = ItemStandVisualContext.ResolveFallback(item);
			}
		}
	}
	[HarmonyPatch(typeof(ItemStand), "SetVisualItem", new Type[]
	{
		typeof(int),
		typeof(int),
		typeof(int),
		typeof(int)
	})]
	internal static class ItemStandVisualPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ItemStand __instance, out ItemStandVisualContext.Scope __state)
		{
			__state = ItemStandVisualContext.Enter(__instance, disableNetworkInit: true);
		}

		[HarmonyPostfix]
		private static void Postfix(ItemStand __instance, int itemHash, ref GameObject ___m_visualItem, ItemStandVisualContext.Scope __state)
		{
			if (ItemStandVisualContext.IsPlayerStand(__instance))
			{
				SanitizeFallback(ref ___m_visualItem);
				GameObject val = ((itemHash != 0 && Object.op_Implicit((Object)(object)ObjectDB.instance)) ? ObjectDB.instance.GetItemPrefab(itemHash) : null);
				SafeDisplayTemplates.ApplyTransform(___m_visualItem, Object.op_Implicit((Object)(object)val) ? ((Object)val).name : string.Empty);
			}
			ItemStandVisualContext.Exit(__state);
		}

		[HarmonyFinalizer]
		private static Exception Finalizer(Exception __exception, ItemStandVisualContext.Scope __state)
		{
			ItemStandVisualContext.Exit(__state);
			return __exception;
		}

		private static void SanitizeFallback(ref GameObject visualItem)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)visualItem))
			{
				return;
			}
			SafeDisplayMarker component = visualItem.GetComponent<SafeDisplayMarker>();
			if (Object.op_Implicit((Object)(object)component) && component.IsFallback)
			{
				DisableGameplayComponents(visualItem);
			}
			else
			{
				if (!Object.op_Implicit((Object)(object)visualItem.GetComponent<ItemDrop>()))
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)visualItem.GetComponent<Renderer>()))
				{
					DisableGameplayComponents(visualItem);
					return;
				}
				Transform transform = visualItem.transform;
				GameObject val = new GameObject(((Object)transform).name + ".Display");
				val.layer = visualItem.layer;
				Transform transform2 = val.transform;
				transform2.SetParent(transform.parent, false);
				transform2.localPosition = transform.localPosition;
				transform2.localRotation = transform.localRotation;
				transform2.localScale = transform.localScale;
				for (int num = transform.childCount - 1; num >= 0; num--)
				{
					Transform child = transform.GetChild(num);
					if (Object.op_Implicit((Object)(object)((Component)child).GetComponentInChildren<Renderer>(true)))
					{
						child.SetParent(transform2, false);
					}
				}
				Object.Destroy((Object)(object)visualItem);
				DisableGameplayComponents(val);
				visualItem = val;
			}
		}

		private static void DisableGameplayComponents(GameObject visual)
		{
			Collider[] componentsInChildren = visual.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Rigidbody[] componentsInChildren2 = visual.GetComponentsInChildren<Rigidbody>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				componentsInChildren2[j].detectCollisions = false;
				componentsInChildren2[j].isKinematic = true;
			}
			MonoBehaviour[] componentsInChildren3 = visual.GetComponentsInChildren<MonoBehaviour>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				if (!(componentsInChildren3[k] is SafeDisplayMarker))
				{
					((Behaviour)componentsInChildren3[k]).enabled = false;
				}
			}
		}
	}
	internal sealed class SafeDisplayMarker : MonoBehaviour
	{
		public string PrefabName;

		public bool IsFallback;

		internal bool Captured;

		internal Vector3 Position;

		internal Vector3 Scale;

		internal Quaternion Rotation;
	}
	internal static class SafeDisplayTemplates
	{
		private static readonly Dictionary<int, GameObject> Templates = new Dictionary<int, GameObject>();

		private static GameObject _root;

		private static string _raw;

		private static Dictionary<string, DisplayTransform> _overrides = DisplayTransform.Parse("");

		internal static GameObject Get(GameObject prefab)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			int instanceID = ((Object)prefab).GetInstanceID();
			if (Templates.TryGetValue(instanceID, out var value))
			{
				return value;
			}
			if (!Object.op_Implicit((Object)(object)_root))
			{
				_root = new GameObject("JG224.AnyItemStands.Templates");
				_root.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_root);
			}
			Dictionary<Transform, Transform> dictionary = new Dictionary<Transform, Transform>();
			Transform val = CopyHierarchy(prefab.transform, _root.transform, dictionary);
			int num = 0;
			foreach (KeyValuePair<Transform, Transform> item in dictionary)
			{
				MeshFilter component = ((Component)item.Key).GetComponent<MeshFilter>();
				MeshRenderer component2 = ((Component)item.Key).GetComponent<MeshRenderer>();
				if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.sharedMesh) && Object.op_Implicit((Object)(object)component2))
				{
					((Component)item.Value).gameObject.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
					CopyRenderer((Renderer)(object)component2, (Renderer)(object)((Component)item.Value).gameObject.AddComponent<MeshRenderer>());
					num++;
				}
				SkinnedMeshRenderer component3 = ((Component)item.Key).GetComponent<SkinnedMeshRenderer>();
				if (!Object.op_Implicit((Object)(object)component3) || !Object.op_Implicit((Object)(object)component3.sharedMesh))
				{
					continue;
				}
				SkinnedMeshRenderer val2 = ((Component)item.Value).gameObject.AddComponent<SkinnedMeshRenderer>();
				val2.sharedMesh = component3.sharedMesh;
				Transform[] bones = component3.bones;
				Transform[] array = (Transform[])(object)new Transform[bones.Length];
				for (int i = 0; i < bones.Length; i++)
				{
					if (Object.op_Implicit((Object)(object)bones[i]) && dictionary.TryGetValue(bones[i], out var value2))
					{
						array[i] = value2;
					}
				}
				val2.bones = array;
				if (Object.op_Implicit((Object)(object)component3.rootBone) && dictionary.TryGetValue(component3.rootBone, out var value3))
				{
					val2.rootBone = value3;
				}
				((Renderer)val2).localBounds = ((Renderer)component3).localBounds;
				val2.updateWhenOffscreen = true;
				for (int j = 0; j < component3.sharedMesh.blendShapeCount; j++)
				{
					val2.SetBlendShapeWeight(j, component3.GetBlendShapeWeight(j));
				}
				CopyRenderer((Renderer)(object)component3, (Renderer)(object)val2);
				num++;
			}
			if (num == 0)
			{
				Templates[instanceID] = null;
				Object.Destroy((Object)(object)((Component)val).gameObject);
				return null;
			}
			Transform val3 = val.Find("attachobj");
			if (Object.op_Implicit((Object)(object)val3))
			{
				((Object)val3).name = "attachobj.AnyItemStands";
			}
			SafeDisplayMarker safeDisplayMarker = ((Component)val).gameObject.AddComponent<SafeDisplayMarker>();
			safeDisplayMarker.PrefabName = ((Object)prefab).name.Replace("(Clone)", "").Trim();
			safeDisplayMarker.IsFallback = true;
			((Component)val).gameObject.SetActive(true);
			Templates[instanceID] = ((Component)val).gameObject;
			return ((Component)val).gameObject;
		}

		private static Transform CopyHierarchy(Transform source, Transform parent, Dictionary<Transform, Transform> map)
		{
			//IL_0006: 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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(((Object)source).name)
			{
				layer = ((Component)source).gameObject.layer
			};
			Transform transform = val.transform;
			transform.SetParent(parent, false);
			transform.localPosition = source.localPosition;
			transform.localRotation = source.localRotation;
			transform.localScale = source.localScale;
			val.SetActive(((Component)source).gameObject.activeSelf);
			map[source] = transform;
			for (int i = 0; i < source.childCount; i++)
			{
				CopyHierarchy(source.GetChild(i), transform, map);
			}
			return transform;
		}

		private static void CopyRenderer(Renderer source, Renderer target)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			target.sharedMaterials = source.sharedMaterials;
			target.enabled = source.enabled;
			target.shadowCastingMode = source.shadowCastingMode;
			target.receiveShadows = source.receiveShadows;
		}

		internal static void ApplyTransform(GameObject visual, string prefabName)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)visual))
			{
				SafeDisplayMarker safeDisplayMarker = visual.GetComponent<SafeDisplayMarker>();
				if (!Object.op_Implicit((Object)(object)safeDisplayMarker))
				{
					safeDisplayMarker = visual.AddComponent<SafeDisplayMarker>();
					safeDisplayMarker.PrefabName = (prefabName ?? "").Replace("(Clone)", "").Trim();
				}
				Transform transform = visual.transform;
				if (!safeDisplayMarker.Captured)
				{
					safeDisplayMarker.Position = transform.localPosition;
					safeDisplayMarker.Rotation = transform.localRotation;
					safeDisplayMarker.Scale = transform.localScale;
					safeDisplayMarker.Captured = true;
				}
				string text = Plugin.Settings?.TransformOverrides.Value ?? "";
				if (_raw != text)
				{
					_raw = text;
					_overrides = DisplayTransform.Parse(text);
				}
				transform.localPosition = safeDisplayMarker.Position;
				transform.localRotation = safeDisplayMarker.Rotation;
				transform.localScale = safeDisplayMarker.Scale;
				if (_overrides.TryGetValue(safeDisplayMarker.PrefabName, out var value))
				{
					transform.localPosition += new Vector3(value.X, value.Y, value.Z);
					transform.localRotation *= Quaternion.Euler(value.Pitch, value.Yaw, value.Roll);
					transform.localScale *= value.Scale;
				}
			}
		}

		internal static void Clear()
		{
			if (Object.op_Implicit((Object)(object)_root))
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			Templates.Clear();
			_raw = null;
		}
	}
}
namespace JG224.AnyItemStands.Core
{
	internal readonly struct DisplayTransform
	{
		internal float Scale { get; }

		internal float X { get; }

		internal float Y { get; }

		internal float Z { get; }

		internal float Pitch { get; }

		internal float Yaw { get; }

		internal float Roll { get; }

		internal DisplayTransform(float[] values)
		{
			Scale = values[0];
			X = values[1];
			Y = values[2];
			Z = values[3];
			Pitch = values[4];
			Yaw = values[5];
			Roll = values[6];
		}

		internal static Dictionary<string, DisplayTransform> Parse(string raw)
		{
			Dictionary<string, DisplayTransform> dictionary = new Dictionary<string, DisplayTransform>(StringComparer.OrdinalIgnoreCase);
			string[] array = (raw ?? "").Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '=' });
				if (array2.Length != 2 || array2[0].Trim().Length == 0)
				{
					continue;
				}
				string[] array3 = array2[1].Split(new char[1] { ',' });
				if (array3.Length != 7)
				{
					continue;
				}
				float[] array4 = new float[7];
				bool flag = true;
				for (int j = 0; j < array4.Length; j++)
				{
					if (float.TryParse(array3[j], NumberStyles.Float, CultureInfo.InvariantCulture, out array4[j]) && !float.IsNaN(array4[j]) && !float.IsInfinity(array4[j]))
					{
						bool num;
						if (j != 0)
						{
							num = Math.Abs(array4[j]) > ((j < 4) ? 5f : 360f);
						}
						else
						{
							if (array4[j] < 0.05f)
							{
								goto IL_0105;
							}
							num = array4[j] > 10f;
						}
						if (!num)
						{
							continue;
						}
					}
					goto IL_0105;
					IL_0105:
					flag = false;
				}
				if (flag)
				{
					dictionary[array2[0].Trim()] = new DisplayTransform(array4);
				}
			}
			return dictionary;
		}
	}
	internal enum FallbackKind
	{
		None,
		NativeAttach,
		SingleChild,
		Root
	}
	internal static class ItemStandRules
	{
		internal static FallbackKind SelectFallback(bool hasNativeAttach, bool hasRenderer, int childCount)
		{
			if (hasNativeAttach)
			{
				return FallbackKind.NativeAttach;
			}
			if (!hasRenderer)
			{
				return FallbackKind.None;
			}
			return FallbackKind.Root;
		}
	}
}