Decompiled source of HTF MoreItemAPI v2.0.0

BepInEx/plugins/HTF-MoreItemAPI/HowToFish.ItemSDK.Contracts.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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("HowToFish.ItemSDK.Contracts")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Shared AssetBundle contracts for HTFItemSDK and HTF MoreItemAPI")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3+4cf7ec4204765620bc4bfcfabac8a7b944cfe3f3")]
[assembly: AssemblyProduct("HowToFish.ItemSDK.Contracts")]
[assembly: AssemblyTitle("HowToFish.ItemSDK.Contracts")]
[assembly: AssemblyVersion("0.1.3.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 HowToFish.ItemSDK
{
	[Serializable]
	public sealed class HTFHandPoseData
	{
		public const int FingerJointCount = 15;

		[SerializeField]
		[InspectorName("Enable This Hand")]
		private bool _enabled;

		[SerializeField]
		[InspectorName("Hand Position (Item Space)")]
		private Vector3 _handPosition;

		[SerializeField]
		[InspectorName("Hand Rotation (Item Space)")]
		private Quaternion _handRotation = Quaternion.identity;

		[SerializeField]
		[InspectorName("15 Finger Joint Local Rotations")]
		private Quaternion[] _fingerLocalRotations = CreateIdentityFingerPose();

		public bool Enabled
		{
			get
			{
				return _enabled;
			}
			set
			{
				_enabled = value;
			}
		}

		public Vector3 HandPosition
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _handPosition;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_handPosition = value;
			}
		}

		public Quaternion HandRotation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _handRotation;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_handRotation = value;
			}
		}

		public Quaternion[] FingerLocalRotations => _fingerLocalRotations;

		public void SetFingerLocalRotations(Quaternion[] rotations)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			_fingerLocalRotations = (Quaternion[])(object)new Quaternion[15];
			for (int i = 0; i < 15; i++)
			{
				_fingerLocalRotations[i] = ((rotations != null && i < rotations.Length) ? rotations[i] : Quaternion.identity);
			}
		}

		public void EnsureValid()
		{
			if (_fingerLocalRotations == null || _fingerLocalRotations.Length != 15)
			{
				SetFingerLocalRotations(_fingerLocalRotations);
			}
		}

		private static Quaternion[] CreateIdentityFingerPose()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Quaternion[] array = (Quaternion[])(object)new Quaternion[15];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Quaternion.identity;
			}
			return array;
		}
	}
	[CreateAssetMenu(fileName = "NewItemHoldPose", menuName = "How to Fish Item SDK/Hold Pose")]
	public sealed class HTFItemHoldPoseAsset : ScriptableObject
	{
		public const int CurrentSchemaVersion = 1;

		[SerializeField]
		[HideInInspector]
		private int _schemaVersion = 1;

		[Header("Item Target Relative to the Player Hold Target")]
		[SerializeField]
		[InspectorName("Held Position")]
		private Vector3 _heldPosition = new Vector3(0.42f, -0.33f, -0.76f);

		[SerializeField]
		[InspectorName("Held Rotation")]
		private Vector3 _heldRotation = new Vector3(0f, 63f, 0f);

		[Header("Inventory Draw Start")]
		[SerializeField]
		[InspectorName("Draw Start Position")]
		private Vector3 _drawStartPosition = new Vector3(0.3f, -1f, 0.5f);

		[SerializeField]
		[InspectorName("Draw Start Rotation")]
		private Vector3 _drawStartRotation = new Vector3(0f, 90f, 0f);

		[Header("Hands")]
		[SerializeField]
		[InspectorName("Right Hand Pose")]
		private HTFHandPoseData _rightHand = HTFOriginalPosePresets.CreateRadioRightHand();

		[SerializeField]
		[InspectorName("Left Hand Pose")]
		private HTFHandPoseData _leftHand = new HTFHandPoseData();

		[Header("Motion")]
		[SerializeField]
		[Min(0f)]
		[InspectorName("Hold Bob Multiplier")]
		private float _holdBobMultiplier = 1f;

		[SerializeField]
		[InspectorName("Override Player Velocity Amount")]
		private bool _overridePlayerVelocityAmount;

		[SerializeField]
		[Range(0f, 1f)]
		[InspectorName("Player Velocity Amount")]
		private float _playerVelocityAmount;

		public int SchemaVersion => _schemaVersion;

		public Vector3 HeldPosition
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _heldPosition;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_heldPosition = value;
			}
		}

		public Vector3 HeldRotation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _heldRotation;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_heldRotation = value;
			}
		}

		public Vector3 DrawStartPosition
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _drawStartPosition;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_drawStartPosition = value;
			}
		}

		public Vector3 DrawStartRotation
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _drawStartRotation;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_drawStartRotation = value;
			}
		}

		public HTFHandPoseData RightHand => _rightHand;

		public HTFHandPoseData LeftHand => _leftHand;

		public float HoldBobMultiplier
		{
			get
			{
				return _holdBobMultiplier;
			}
			set
			{
				_holdBobMultiplier = Mathf.Max(0f, value);
			}
		}

		public bool OverridePlayerVelocityAmount
		{
			get
			{
				return _overridePlayerVelocityAmount;
			}
			set
			{
				_overridePlayerVelocityAmount = value;
			}
		}

		public float PlayerVelocityAmount
		{
			get
			{
				return _playerVelocityAmount;
			}
			set
			{
				_playerVelocityAmount = Mathf.Clamp01(value);
			}
		}

		public bool Validate(out string error)
		{
			//IL_0058: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (_schemaVersion != 1)
			{
				error = $"Unsupported hold-pose schema {_schemaVersion}; expected {1}.";
				return false;
			}
			if (_rightHand == null || _leftHand == null)
			{
				error = "Both hand pose records must exist.";
				return false;
			}
			_rightHand.EnsureValid();
			_leftHand.EnsureValid();
			if (!IsFinite(_heldPosition) || !IsFinite(_heldRotation) || !IsFinite(_drawStartPosition) || !IsFinite(_drawStartRotation) || float.IsNaN(_holdBobMultiplier) || float.IsInfinity(_holdBobMultiplier))
			{
				error = "The pose contains a NaN or infinite value.";
				return false;
			}
			error = null;
			return true;
		}

		private void OnValidate()
		{
			_schemaVersion = 1;
			if (_rightHand == null)
			{
				_rightHand = new HTFHandPoseData();
			}
			if (_leftHand == null)
			{
				_leftHand = new HTFHandPoseData();
			}
			_rightHand.EnsureValid();
			_leftHand.EnsureValid();
			_holdBobMultiplier = Mathf.Max(0f, _holdBobMultiplier);
			_playerVelocityAmount = Mathf.Clamp01(_playerVelocityAmount);
		}

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (IsFinite(value.x) && IsFinite(value.y))
			{
				return IsFinite(value.z);
			}
			return false;
		}

		private static bool IsFinite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}
	}
	public static class HTFOriginalPosePresets
	{
		public static void ApplyRadioSingleHand(HTFItemHoldPoseAsset pose)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			RequirePose(pose);
			pose.HeldPosition = new Vector3(0.42f, -0.33f, -0.76f);
			pose.HeldRotation = new Vector3(0f, 63f, 0f);
			pose.DrawStartPosition = new Vector3(0.3f, -1f, 0.5f);
			pose.DrawStartRotation = new Vector3(0f, 90f, 0f);
			pose.HoldBobMultiplier = 1f;
			pose.OverridePlayerVelocityAmount = false;
			pose.PlayerVelocityAmount = 0f;
			CopyHand(CreateDisabledHand(), pose.LeftHand);
			CopyHand(CreateRadioRightHand(), pose.RightHand);
		}

		public static void ApplyMapTwoHandsOnly(HTFItemHoldPoseAsset pose)
		{
			RequirePose(pose);
			CopyHand(CreateMapLeftHand(), pose.LeftHand);
			CopyHand(CreateMapRightHand(), pose.RightHand);
		}

		public static void ApplyMapTwoHandFullPose(HTFItemHoldPoseAsset pose)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			RequirePose(pose);
			pose.HeldPosition = new Vector3(0f, -0.05f, -1.2f);
			pose.HeldRotation = new Vector3(-80f, 0f, 0f);
			pose.DrawStartPosition = new Vector3(0f, -1f, 0.5f);
			pose.DrawStartRotation = new Vector3(90f, 0f, 0f);
			pose.HoldBobMultiplier = 0.6f;
			pose.OverridePlayerVelocityAmount = true;
			pose.PlayerVelocityAmount = 1f;
			ApplyMapTwoHandsOnly(pose);
		}

		public static HTFHandPoseData CreateRadioRightHand()
		{
			//IL_000f: 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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			return CreateHand(new Vector3(0.09920406f, 0.27439833f, -0.06556702f), new Quaternion(-0.20334123f, 0.6784968f, 0.67723864f, 0.19910352f), (Quaternion[])(object)new Quaternion[15]
			{
				new Quaternion(-0.17645995f, 0.0836007f, -0.02524008f, 0.9804263f),
				new Quaternion(-0.796266f, -0.01515778f, 0.014898457f, 0.6045732f),
				new Quaternion(-0.5076878f, 0.003543657f, 0.007965563f, 0.86149704f),
				new Quaternion(-0.34734228f, 0.006803209f, -0.033399336f, 0.93711877f),
				new Quaternion(-0.8034126f, -0.000761092f, 0.052317597f, 0.59311914f),
				new Quaternion(-0.5316856f, 0.005730562f, 0.0019349393f, 0.84692025f),
				new Quaternion(-0.84903914f, -0.06389f, -0.045607448f, 0.522466f),
				new Quaternion(-0.011965696f, 0.9728566f, -0.22956258f, -0.026608892f),
				new Quaternion(0.024349783f, 0.9218279f, 0.38478187f, 0.039791096f),
				new Quaternion(-0.81334496f, -0.029981144f, -0.05262217f, 0.57862085f),
				new Quaternion(-0.58162737f, -0.002805759f, 0.030088276f, 0.81289387f),
				new Quaternion(-0.114157796f, 0.004546409f, 0.037410397f, 0.9927476f),
				new Quaternion(-0.25394344f, 0.17243882f, -0.31861526f, 0.89680654f),
				new Quaternion(0.30824605f, -0.0608297f, 0.24755368f, 0.9165158f),
				new Quaternion(-0.0007670824f, 0.011516825f, 0.07372607f, 0.99721175f)
			});
		}

		public static HTFHandPoseData CreateMapLeftHand()
		{
			//IL_000f: 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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			return CreateHand(new Vector3(-0.18405652f, 0.033113956f, -0.18624163f), new Quaternion(0.5098463f, 0.4488421f, 0.73206466f, -0.051757783f), (Quaternion[])(object)new Quaternion[15]
			{
				new Quaternion(0.28719264f, 0.06597653f, -0.050667886f, 0.9542538f),
				new Quaternion(0.15671512f, 0.022660088f, 0.07683137f, 0.9843901f),
				new Quaternion(0.015327393f, 0.014648255f, 0.01166631f, 0.9997072f),
				new Quaternion(0.2472412f, -0.015532613f, -0.03278998f, 0.9682745f),
				new Quaternion(0.37844452f, 0.07190943f, 0.029446967f, 0.9223566f),
				new Quaternion(0.08648097f, 0.014685285f, 0.016577924f, 0.9960073f),
				new Quaternion(0.4295139f, -0.06893119f, 0.023413636f, 0.9001213f),
				new Quaternion(0.014603084f, 0.97065073f, 0.23872685f, -0.025167499f),
				new Quaternion(-0.009083921f, 0.9846149f, -0.17359486f, 0.017772298f),
				new Quaternion(0.32728767f, -0.06640267f, -0.00745768f, 0.9425592f),
				new Quaternion(0.3990275f, 0.017894266f, -0.009065839f, 0.91671956f),
				new Quaternion(0.11809985f, 0.04579304f, 0.021999639f, 0.9917013f),
				new Quaternion(0.28361353f, -0.1173431f, -0.11725441f, 0.94448155f),
				new Quaternion(-0.1318681f, 0.118932575f, 0.24238203f, 0.9537908f),
				new Quaternion(-0.025611738f, 0.05958537f, 0.008527417f, 0.9978582f)
			});
		}

		public static HTFHandPoseData CreateMapRightHand()
		{
			//IL_000f: 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)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			return CreateHand(new Vector3(0.19659996f, 0.036249995f, -0.17779994f), new Quaternion(0.6745851f, -0.06982532f, 0.57147884f, 0.4620296f), (Quaternion[])(object)new Quaternion[15]
			{
				new Quaternion(-0.02976632f, 0.078957684f, -0.037307203f, 0.9957349f),
				new Quaternion(-0.5323071f, -0.008939026f, 0.019282252f, 0.84628457f),
				new Quaternion(-0.018548558f, 0.007002061f, 0.0051943185f, 0.99978995f),
				new Quaternion(-0.29350412f, 0.004893422f, -0.033732146f, 0.95535f),
				new Quaternion(-0.21119776f, 0.033995472f, 0.039774686f, 0.9760419f),
				new Quaternion(-0.08805111f, 0.005983259f, -0.00088462787f, 0.9960976f),
				new Quaternion(-0.36304793f, -0.078470595f, 0.0020768049f, 0.92845803f),
				new Quaternion(-0.011840507f, 0.9739258f, -0.224983f, -0.026664995f),
				new Quaternion(0.032568395f, 0.9842087f, 0.1707542f, 0.03339985f),
				new Quaternion(-0.32743385f, -0.054931186f, -0.025505273f, 0.9429312f),
				new Quaternion(-0.24056424f, 0.008496598f, 0.028999517f, 0.97016275f),
				new Quaternion(-0.114157796f, 0.004546409f, 0.037410397f, 0.9927476f),
				new Quaternion(-0.3283949f, 0.33083424f, -0.068605155f, 0.88204247f),
				new Quaternion(0.23251432f, -0.0760676f, 0.22051305f, 0.944206f),
				new Quaternion(-0.0020824517f, 0.011352842f, -0.041103695f, 0.9990883f)
			});
		}

		private static HTFHandPoseData CreateDisabledHand()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new HTFHandPoseData
			{
				Enabled = false,
				HandPosition = Vector3.zero,
				HandRotation = Quaternion.identity
			};
		}

		private static HTFHandPoseData CreateHand(Vector3 position, Quaternion rotation, Quaternion[] fingerRotations)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			HTFHandPoseData hTFHandPoseData = new HTFHandPoseData();
			hTFHandPoseData.Enabled = true;
			hTFHandPoseData.HandPosition = position;
			hTFHandPoseData.HandRotation = rotation;
			hTFHandPoseData.SetFingerLocalRotations(fingerRotations);
			return hTFHandPoseData;
		}

		private static void CopyHand(HTFHandPoseData source, HTFHandPoseData destination)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			destination.Enabled = source.Enabled;
			destination.HandPosition = source.HandPosition;
			destination.HandRotation = source.HandRotation;
			destination.SetFingerLocalRotations(source.FingerLocalRotations);
		}

		private static void RequirePose(HTFItemHoldPoseAsset pose)
		{
			if (!Object.op_Implicit((Object)(object)pose))
			{
				throw new ArgumentNullException("pose");
			}
		}
	}
	[CreateAssetMenu(fileName = "NewItemDefinition", menuName = "How to Fish Item SDK/Item Definition")]
	public sealed class HTFItemDefinitionAsset : ScriptableObject
	{
		public const int CurrentSchemaVersion = 1;

		[SerializeField]
		[HideInInspector]
		private int _schemaVersion = 1;

		[SerializeField]
		[InspectorName("Internal Unique Name")]
		private string _internalName = "custom_item";

		[SerializeField]
		[InspectorName("In-Game Display Name")]
		private string _displayName = "Custom Item";

		[Header("AssetBundle Content")]
		[SerializeField]
		[InspectorName("Content Prefab")]
		private GameObject _contentPrefab;

		[SerializeField]
		[InspectorName("Inventory Icon")]
		private Texture2D _inventoryIcon;

		[SerializeField]
		[InspectorName("Hold Pose")]
		private HTFItemHoldPoseAsset _holdPose;

		[Header("Suggested Registration Settings")]
		[SerializeField]
		[Min(0.01f)]
		[InspectorName("Pickup Radius")]
		private float _pickupRadius = 0.6f;

		[SerializeField]
		[InspectorName("Buoyancy")]
		private float _buoyancy;

		public int SchemaVersion => _schemaVersion;

		public string InternalName => _internalName;

		public string DisplayName => _displayName;

		public GameObject ContentPrefab => _contentPrefab;

		public Texture2D InventoryIcon => _inventoryIcon;

		public HTFItemHoldPoseAsset HoldPose => _holdPose;

		public float PickupRadius => _pickupRadius;

		public float Buoyancy => _buoyancy;

		public bool Validate(out string error)
		{
			if (_schemaVersion != 1)
			{
				error = $"Unsupported item-definition schema {_schemaVersion}; expected {1}.";
				return false;
			}
			if (string.IsNullOrWhiteSpace(_internalName))
			{
				error = "Internal name is required.";
				return false;
			}
			if (!Object.op_Implicit((Object)(object)_contentPrefab))
			{
				error = "Content prefab is required.";
				return false;
			}
			if (!Object.op_Implicit((Object)(object)_inventoryIcon))
			{
				error = "Inventory icon is required.";
				return false;
			}
			if (!Object.op_Implicit((Object)(object)_holdPose))
			{
				error = "Hold pose is required.";
				return false;
			}
			if (!_holdPose.Validate(out error))
			{
				return false;
			}
			if (_pickupRadius <= 0f || float.IsNaN(_pickupRadius) || float.IsInfinity(_pickupRadius))
			{
				error = "Pickup radius must be a positive finite value.";
				return false;
			}
			error = null;
			return true;
		}

		private void OnValidate()
		{
			_schemaVersion = 1;
			_pickupRadius = Mathf.Max(0.01f, _pickupRadius);
		}
	}
}

BepInEx/plugins/HTF-MoreItemAPI/HTFMoreItemAPI.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using FishNet;
using FishNet.Managing;
using FishNet.Managing.Object;
using FishNet.Object;
using HarmonyLib;
using HowToFish.ItemSDK;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("HTFMoreItemAPI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Runtime custom item registration API for How to Fish")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+4cf7ec4204765620bc4bfcfabac8a7b944cfe3f3")]
[assembly: AssemblyProduct("HTFMoreItemAPI")]
[assembly: AssemblyTitle("HTFMoreItemAPI")]
[assembly: AssemblyVersion("2.0.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 HowToFish.ItemAPI
{
	public sealed class GeneratedItemRegistration
	{
		public string ModGuid { get; set; }

		public string InternalName { get; set; }

		public GameObject ContentPrefab { get; set; }

		public InventoryIcon InventoryIcon { get; set; }

		public HTFItemHoldPoseAsset HoldPose { get; set; }

		public string DisplayName { get; set; }

		public float PickupRadius { get; set; } = 0.6f;

		public float Buoyancy { get; set; }

		public ushort NetworkCollectionId { get; set; }

		public static GeneratedItemRegistration FromDefinition(HTFItemDefinitionAsset definition, string modGuid)
		{
			if (!Object.op_Implicit((Object)(object)definition))
			{
				throw new ArgumentNullException("definition");
			}
			string message = default(string);
			if (!definition.Validate(ref message))
			{
				throw new ArgumentException(message, "definition");
			}
			return new GeneratedItemRegistration
			{
				ModGuid = modGuid,
				InternalName = definition.InternalName,
				ContentPrefab = definition.ContentPrefab,
				InventoryIcon = InventoryIcon.FromTexture((Texture)(object)definition.InventoryIcon),
				HoldPose = definition.HoldPose,
				DisplayName = definition.DisplayName,
				PickupRadius = definition.PickupRadius,
				Buoyancy = definition.Buoyancy
			};
		}
	}
	internal static class GeneratedPrefabFactory
	{
		private const byte GenericTemplateItemId = 55;

		private static readonly Guid SupportedGameMvid = new Guid("48815c0b-02c6-4024-a20a-1cb6cbfee2ec");

		private static readonly FieldInfo ItemIdField = AccessTools.Field(typeof(Item), "_id");

		private static readonly FieldInfo WorldCollidersField = AccessTools.Field(typeof(Item), "_worldColliders");

		private static readonly FieldInfo PickupColliderField = AccessTools.Field(typeof(Item), "_pickUpCollider");

		private static readonly FieldInfo RenderersField = AccessTools.Field(typeof(Item), "_renderers");

		private static readonly FieldInfo SkinRenderersField = AccessTools.Field(typeof(Item), "_skinRenderers");

		private static readonly FieldInfo MeshField = AccessTools.Field(typeof(Item), "_mesh");

		private static readonly FieldInfo WeightField = AccessTools.Field(typeof(Item), "_weight");

		private static readonly FieldInfo BuoyancyField = AccessTools.Field(typeof(Item), "_buoyancy");

		private static readonly FieldInfo HeldPositionField = AccessTools.Field(typeof(Item), "_heldPos");

		private static readonly FieldInfo HeldRotationField = AccessTools.Field(typeof(Item), "_heldRot");

		private static readonly FieldInfo DrawStartPositionField = AccessTools.Field(typeof(Item), "_drawAnimStartPos");

		private static readonly FieldInfo DrawStartRotationField = AccessTools.Field(typeof(Item), "_drawAnimStartRot");

		private static readonly FieldInfo RightHandTransformsField = AccessTools.Field(typeof(Item), "_handTransformsRight");

		private static readonly FieldInfo LeftHandTransformsField = AccessTools.Field(typeof(Item), "_handTransformsLeft");

		private static readonly FieldInfo HoldBobMultiplierField = AccessTools.Field(typeof(Item), "_holdBobMulti");

		private static readonly FieldInfo OverridePlayerVelocityField = AccessTools.Field(typeof(Item), "_overridePlayerVelAmount");

		private static readonly FieldInfo PlayerVelocityAmountField = AccessTools.Field(typeof(Item), "_playerVelAmount");

		private static GameObject _runtimeRoot;

		internal static bool ValidateSource(GeneratedItemRegistration registration, out string error)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			error = null;
			if (!Object.op_Implicit((Object)(object)registration.ContentPrefab))
			{
				error = "ContentPrefab cannot be null.";
				return false;
			}
			Scene scene = registration.ContentPrefab.scene;
			if (((Scene)(ref scene)).IsValid())
			{
				error = "ContentPrefab must be a prefab asset returned by AssetBundle.LoadAsset<GameObject>().";
				return false;
			}
			if (registration.InventoryIcon == null || !Object.op_Implicit((Object)(object)registration.InventoryIcon.Texture))
			{
				error = "A generated item must provide a valid icon from its AssetBundle.";
				return false;
			}
			if (registration.PickupRadius <= 0f || float.IsNaN(registration.PickupRadius) || float.IsInfinity(registration.PickupRadius))
			{
				error = "PickupRadius must be a finite value greater than zero.";
				return false;
			}
			if (float.IsNaN(registration.Buoyancy) || float.IsInfinity(registration.Buoyancy))
			{
				error = "Buoyancy must be a finite value.";
				return false;
			}
			if (Object.op_Implicit((Object)(object)registration.HoldPose) && !registration.HoldPose.Validate(ref error))
			{
				error = "HoldPose is invalid: " + error;
				return false;
			}
			if (Object.op_Implicit((Object)(object)registration.ContentPrefab.GetComponentInChildren<Item>(true)))
			{
				error = "ContentPrefab must not contain Item; the API provides it through the game skeleton.";
				return false;
			}
			if (Object.op_Implicit((Object)(object)registration.ContentPrefab.GetComponentInChildren<RigidbodySync>(true)))
			{
				error = "ContentPrefab must not contain RigidbodySync; the API provides it.";
				return false;
			}
			if (Object.op_Implicit((Object)(object)registration.ContentPrefab.GetComponentInChildren<NetworkObject>(true)))
			{
				error = "ContentPrefab must not contain NetworkObject; the API provides it.";
				return false;
			}
			Rigidbody[] componentsInChildren = registration.ContentPrefab.GetComponentsInChildren<Rigidbody>(true);
			Rigidbody component = registration.ContentPrefab.GetComponent<Rigidbody>();
			if (componentsInChildren.Length != 1 || !Object.op_Implicit((Object)(object)component) || (Object)(object)componentsInChildren[0] != (Object)(object)component)
			{
				error = $"The ContentPrefab root must contain exactly one Rigidbody; the hierarchy currently contains {componentsInChildren.Length}.";
				return false;
			}
			if (registration.ContentPrefab.GetComponentsInChildren<Collider>(true).Length == 0)
			{
				error = "ContentPrefab must contain at least one Collider.";
				return false;
			}
			return true;
		}

		internal static bool TryCreate(string key, byte itemId, GeneratedItemRegistration registration, out Item item, out NetworkObject networkObject, out string error)
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			networkObject = null;
			error = null;
			Guid moduleVersionId = typeof(Item).Assembly.ManifestModule.ModuleVersionId;
			if (moduleVersionId != SupportedGameMvid)
			{
				error = "The current Assembly-CSharp is not supported by the generation pipeline; " + $"MVID={moduleVersionId}, Supported={SupportedGameMvid}.";
				return false;
			}
			if (!ValidateSource(registration, out error))
			{
				return false;
			}
			if (!ValidateReflection(out error))
			{
				return false;
			}
			Item spawnable = GameInfo.GetSpawnable((byte)55);
			if (!ValidateTemplate(spawnable, out error))
			{
				return false;
			}
			EnsureRuntimeRoot();
			GameObject val = null;
			try
			{
				val = Object.Instantiate<GameObject>(((Component)spawnable).gameObject, _runtimeRoot.transform, false);
				((Object)val).name = "HTFMoreItemAPI_" + SanitizeObjectName(key);
				if (val.activeInHierarchy)
				{
					throw new InvalidOperationException("The generation container is unexpectedly active.");
				}
				Item component = val.GetComponent<Item>();
				NetworkObject component2 = val.GetComponent<NetworkObject>();
				Rigidbody component3 = val.GetComponent<Rigidbody>();
				SphereCollider val2 = FindRootPickupCollider(val);
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)component3) || !Object.op_Implicit((Object)(object)val2))
				{
					throw new InvalidOperationException("The cloned base-item skeleton is missing required components.");
				}
				RemoveTemplateChildren(val.transform);
				GameObject val3 = Object.Instantiate<GameObject>(registration.ContentPrefab, val.transform, false);
				((Object)val3).name = "Content";
				val3.transform.localPosition = Vector3.zero;
				val3.transform.localRotation = Quaternion.identity;
				Rigidbody[] componentsInChildren = val3.GetComponentsInChildren<Rigidbody>(true);
				if (componentsInChildren.Length != 1)
				{
					throw new InvalidOperationException("The number of Rigidbodies changed after cloning the content prefab.");
				}
				CopyRigidbodySettings(componentsInChildren[0], component3);
				Object.DestroyImmediate((Object)(object)componentsInChildren[0]);
				Collider[] componentsInChildren2 = val3.GetComponentsInChildren<Collider>(true);
				if (componentsInChildren2.Length == 0)
				{
					throw new InvalidOperationException("The cloned content prefab has no Collider.");
				}
				Collider[] array = componentsInChildren2;
				foreach (Collider obj in array)
				{
					obj.isTrigger = false;
					obj.enabled = true;
				}
				((Collider)val2).isTrigger = true;
				val2.center = Vector3.zero;
				val2.radius = registration.PickupRadius;
				((Collider)val2).enabled = true;
				List<Renderer> list = new List<Renderer>(val3.GetComponentsInChildren<Renderer>(true));
				List<Renderer> list2 = new List<Renderer>();
				foreach (Renderer item2 in list)
				{
					if (item2 is SkinnedMeshRenderer)
					{
						list2.Add(item2);
					}
				}
				Mesh value = FindFirstMesh(val3);
				ItemIdField.SetValue(component, itemId);
				WorldCollidersField.SetValue(component, componentsInChildren2);
				PickupColliderField.SetValue(component, val2);
				RenderersField.SetValue(component, list);
				SkinRenderersField.SetValue(component, list2);
				MeshField.SetValue(component, value);
				WeightField.SetValue(component, component3.mass);
				BuoyancyField.SetValue(component, registration.Buoyancy);
				if (Object.op_Implicit((Object)(object)registration.HoldPose))
				{
					ApplyHoldPose(component, val.transform, registration.HoldPose);
				}
				component2.SetIsSpawnable(true);
				item = component;
				networkObject = component2;
				return true;
			}
			catch (Exception ex)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.DestroyImmediate((Object)(object)val);
				}
				error = "Failed to generate the item skeleton: " + ex.GetType().Name + ": " + ex.Message;
				return false;
			}
		}

		internal static void Shutdown()
		{
			if (Object.op_Implicit((Object)(object)_runtimeRoot))
			{
				Object.Destroy((Object)(object)_runtimeRoot);
			}
			_runtimeRoot = null;
		}

		private static bool ValidateReflection(out string error)
		{
			error = null;
			if (ItemIdField != null && WorldCollidersField != null && PickupColliderField != null && RenderersField != null && SkinRenderersField != null && MeshField != null && WeightField != null && BuoyancyField != null && HeldPositionField != null && HeldRotationField != null && DrawStartPositionField != null && DrawStartRotationField != null && RightHandTransformsField != null && LeftHandTransformsField != null && HoldBobMultiplierField != null && OverridePlayerVelocityField != null && PlayerVelocityAmountField != null)
			{
				return true;
			}
			error = "The current game version is missing Item serialization fields required by the generation pipeline.";
			return false;
		}

		private static bool ValidateTemplate(Item template, out string error)
		{
			error = null;
			if (!Object.op_Implicit((Object)(object)template))
			{
				error = $"The original generic item template ItemId={(byte)55} was not found.";
				return false;
			}
			if (((object)template).GetType() != typeof(Item))
			{
				error = "The generic template must be exactly Item, but was " + ((object)template).GetType().FullName + ".";
				return false;
			}
			if (!Object.op_Implicit((Object)(object)((Component)template).GetComponent<NetworkObject>()) || !Object.op_Implicit((Object)(object)((Component)template).GetComponent<RigidbodySync>()) || !Object.op_Implicit((Object)(object)((Component)template).GetComponent<Rigidbody>()))
			{
				error = "The original generic item template is missing NetworkObject, RigidbodySync, or Rigidbody.";
				return false;
			}
			NetworkBehaviour[] components = ((Component)template).GetComponents<NetworkBehaviour>();
			if (components.Length != 2)
			{
				error = $"The original generic template must contain 2 NetworkBehaviours, but contains {components.Length}.";
				return false;
			}
			if ((Object)(object)FindRootPickupCollider(((Component)template).gameObject) == (Object)null)
			{
				error = "The original generic item template is missing its root pickup SphereCollider.";
				return false;
			}
			return true;
		}

		private static void EnsureRuntimeRoot()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_runtimeRoot))
			{
				_runtimeRoot = new GameObject("HTFMoreItemAPI.RuntimePrefabs");
				((Object)_runtimeRoot).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)_runtimeRoot);
				_runtimeRoot.SetActive(false);
			}
		}

		private static SphereCollider FindRootPickupCollider(GameObject root)
		{
			SphereCollider[] components = root.GetComponents<SphereCollider>();
			foreach (SphereCollider val in components)
			{
				if (((Collider)val).isTrigger)
				{
					return val;
				}
			}
			return null;
		}

		private static void RemoveTemplateChildren(Transform root)
		{
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)root.GetChild(num)).gameObject);
			}
		}

		private static void CopyRigidbodySettings(Rigidbody source, Rigidbody target)
		{
			//IL_003e: 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)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			target.mass = source.mass;
			target.linearDamping = source.linearDamping;
			target.angularDamping = source.angularDamping;
			target.useGravity = source.useGravity;
			target.isKinematic = source.isKinematic;
			target.interpolation = source.interpolation;
			target.collisionDetectionMode = source.collisionDetectionMode;
			target.constraints = source.constraints;
			target.detectCollisions = source.detectCollisions;
			target.maxAngularVelocity = source.maxAngularVelocity;
			target.maxLinearVelocity = source.maxLinearVelocity;
			target.automaticCenterOfMass = source.automaticCenterOfMass;
			if (!source.automaticCenterOfMass)
			{
				target.centerOfMass = source.centerOfMass;
			}
			target.automaticInertiaTensor = source.automaticInertiaTensor;
			if (!source.automaticInertiaTensor)
			{
				target.inertiaTensor = source.inertiaTensor;
				target.inertiaTensorRotation = source.inertiaTensorRotation;
			}
		}

		private static void ApplyHoldPose(Item item, Transform itemRoot, HTFItemHoldPoseAsset pose)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			HeldPositionField.SetValue(item, pose.HeldPosition);
			HeldRotationField.SetValue(item, pose.HeldRotation);
			DrawStartPositionField.SetValue(item, pose.DrawStartPosition);
			DrawStartRotationField.SetValue(item, pose.DrawStartRotation);
			RightHandTransformsField.SetValue(item, CreateGameHandPose(pose.RightHand, itemRoot));
			LeftHandTransformsField.SetValue(item, CreateGameHandPose(pose.LeftHand, itemRoot));
			HoldBobMultiplierField.SetValue(item, pose.HoldBobMultiplier);
			OverridePlayerVelocityField.SetValue(item, pose.OverridePlayerVelocityAmount);
			PlayerVelocityAmountField.SetValue(item, pose.PlayerVelocityAmount);
		}

		private static HandTransforms CreateGameHandPose(HTFHandPoseData source, Transform itemRoot)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (source != null && source.Enabled)
			{
				Quaternion[] fingerLocalRotations = source.FingerLocalRotations;
				if (fingerLocalRotations == null || fingerLocalRotations.Length != 15)
				{
					throw new InvalidOperationException($"An enabled hand pose must contain {15} finger-joint rotations.");
				}
				Quaternion[] array = (Quaternion[])(object)new Quaternion[fingerLocalRotations.Length];
				Array.Copy(fingerLocalRotations, array, array.Length);
				return new HandTransforms(true, source.HandPosition, source.HandRotation, array, itemRoot);
			}
			return new HandTransforms(false);
		}

		private static Mesh FindFirstMesh(GameObject content)
		{
			MeshFilter[] componentsInChildren = content.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.sharedMesh))
				{
					return val.sharedMesh;
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = content.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				if (Object.op_Implicit((Object)(object)val2.sharedMesh))
				{
					return val2.sharedMesh;
				}
			}
			return null;
		}

		private static string SanitizeObjectName(string value)
		{
			return value.Replace(':', '_').Replace('/', '_').Replace('\\', '_');
		}
	}
	public sealed class InventoryIcon
	{
		public Texture Texture { get; }

		public Rect UvRect { get; }

		public Color Tint { get; }

		public InventoryIcon(Texture texture)
			: this(texture, new Rect(0f, 0f, 1f, 1f), Color.white)
		{
		}//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)


		public InventoryIcon(Texture texture, Rect uvRect, Color tint)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)texture))
			{
				throw new ArgumentNullException("texture");
			}
			Texture = texture;
			UvRect = uvRect;
			Tint = tint;
		}

		public static InventoryIcon FromTexture(Texture texture)
		{
			return new InventoryIcon(texture);
		}

		public static InventoryIcon FromSprite(Sprite sprite)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)sprite))
			{
				throw new ArgumentNullException("sprite");
			}
			Texture2D texture = sprite.texture;
			Rect textureRect = sprite.textureRect;
			Rect uvRect = default(Rect);
			((Rect)(ref uvRect))..ctor(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
			return new InventoryIcon((Texture)(object)texture, uvRect, Color.white);
		}
	}
	public static class ItemApiMetadata
	{
		public const string PluginGuid = "xiaohai.HTF.MoreItemAPI";

		public const string PluginName = "HTF MoreItemAPI";

		public const string PluginVersion = "2.0.0";
	}
	[HarmonyPatch(typeof(GameInfo), "Awake")]
	internal static class GameInfoAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			RegistryRuntime.OnGameInfoAwakeCompleted();
		}
	}
	[HarmonyPatch(typeof(Item), "GetName")]
	internal static class CustomItemNamePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Item __instance, ref string __result)
		{
			if (Object.op_Implicit((Object)(object)__instance) && RegistryRuntime.TryGetDisplayName(__instance.ID, out var displayName))
			{
				__result = displayName;
			}
		}
	}
	[HarmonyPatch(typeof(InventorySlot), "SetItem")]
	internal static class InventorySlotIconPatch
	{
		private sealed class NativeImageState
		{
			internal Texture Texture;

			internal Rect UvRect;

			internal Color Color;

			internal bool Enabled;
		}

		private static readonly FieldInfo FilterField = AccessTools.Field(typeof(InventorySlot), "_filter");

		private static readonly FieldInfo ImageField = AccessTools.Field(typeof(InventorySlot), "_itemImage");

		private static readonly Dictionary<RawImage, NativeImageState> NativeStates = new Dictionary<RawImage, NativeImageState>();

		[HarmonyPostfix]
		private static void Postfix(InventorySlot __instance, Item item)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || ImageField == null)
			{
				return;
			}
			object? value = ImageField.GetValue(__instance);
			RawImage val = (RawImage)((value is RawImage) ? value : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			if (!NativeStates.TryGetValue(val, out var value2))
			{
				value2 = new NativeImageState
				{
					Texture = val.texture,
					UvRect = val.uvRect,
					Color = ((Graphic)val).color,
					Enabled = ((Behaviour)val).enabled
				};
				NativeStates.Add(val, value2);
			}
			if (!Object.op_Implicit((Object)(object)item) || !RegistryRuntime.TryGetIcon(item.ID, out var icon))
			{
				val.texture = (Texture)(Object.op_Implicit((Object)(object)value2.Texture) ? ((object)value2.Texture) : ((object)GameInfo.InventoryTexture));
				val.uvRect = value2.UvRect;
				((Graphic)val).color = value2.Color;
				((Behaviour)val).enabled = value2.Enabled;
				return;
			}
			object? obj = FilterField?.GetValue(__instance);
			MeshFilter val2 = (MeshFilter)((obj is MeshFilter) ? obj : null);
			if (Object.op_Implicit((Object)(object)val2))
			{
				val2.mesh = null;
			}
			val.texture = icon.Texture;
			val.uvRect = icon.UvRect;
			((Graphic)val).color = icon.Tint;
			((Behaviour)val).enabled = true;
			((Component)val).transform.localScale = Vector3.one;
		}
	}
	[BepInPlugin("xiaohai.HTF.MoreItemAPI", "HTF MoreItemAPI", "2.0.0")]
	public sealed class ItemApiPlugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			RegistryRuntime.Initialize(((BaseUnityPlugin)this).Logger);
			_harmony = new Harmony("xiaohai.HTF.MoreItemAPI");
			_harmony.PatchAll(typeof(ItemApiPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HTF MoreItemAPI v2.0.0 loaded.");
		}

		private void Update()
		{
			RegistryRuntime.Tick();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			GeneratedPrefabFactory.Shutdown();
			RegistryRuntime.Shutdown();
		}
	}
	internal static class ItemIdAllocator
	{
		internal const int SlotCount = 256;

		internal static Dictionary<string, byte> Allocate(IEnumerable<string> keys, IEnumerable<byte> occupiedIds)
		{
			if (keys == null)
			{
				throw new ArgumentNullException("keys");
			}
			HashSet<byte> hashSet = ((occupiedIds == null) ? new HashSet<byte>() : new HashSet<byte>(occupiedIds));
			hashSet.Add(byte.MaxValue);
			List<string> list = new List<string>();
			foreach (string key in keys)
			{
				if (string.IsNullOrWhiteSpace(key))
				{
					throw new ArgumentException("Allocation keys cannot be null or empty.", "keys");
				}
				list.Add(key);
			}
			list.Sort(StringComparer.Ordinal);
			if (list.Count > 256 - hashSet.Count)
			{
				throw new InvalidOperationException($"No free Item ID slots remain: requested={list.Count}, free={256 - hashSet.Count}.");
			}
			Dictionary<string, byte> dictionary = new Dictionary<string, byte>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in list)
			{
				if (dictionary.ContainsKey(item))
				{
					throw new InvalidOperationException("Duplicate item registration key '" + item + "'.");
				}
				byte b = DerivePreferredId(item);
				bool flag = false;
				for (int i = 0; i < 256; i++)
				{
					byte b2 = (byte)(b + i);
					if (hashSet.Add(b2))
					{
						dictionary.Add(item, b2);
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					throw new InvalidOperationException("No free Item ID slots remain.");
				}
			}
			return dictionary;
		}

		internal static byte DerivePreferredId(string key)
		{
			uint num = 2166136261u;
			byte[] bytes = Encoding.UTF8.GetBytes(key);
			foreach (byte b in bytes)
			{
				num ^= b;
				num *= 16777619;
			}
			return (byte)num;
		}
	}
	public sealed class ItemRegistration
	{
		public string ModGuid { get; set; }

		public string InternalName { get; set; }

		public GameObject Prefab { get; set; }

		public string DisplayName { get; set; }

		public InventoryIcon InventoryIcon { get; set; }

		public ushort NetworkCollectionId { get; set; }
	}
	public enum ItemRegistrationState
	{
		Rejected,
		PendingGameRegistry,
		PendingNetworkManager,
		Registered,
		Failed
	}
	public sealed class ItemRegistrationHandle
	{
		public string Key { get; }

		public byte? ItemId { get; internal set; }

		public bool HasAssignedItemId => ItemId.HasValue;

		public ushort NetworkCollectionId { get; }

		public Item ItemPrefab { get; internal set; }

		public ItemRegistrationState State { get; internal set; }

		public string Message { get; internal set; }

		public bool IsRegistered => State == ItemRegistrationState.Registered;

		internal ItemRegistrationHandle(string key, ushort networkCollectionId, Item itemPrefab, ItemRegistrationState state, string message)
		{
			Key = key;
			NetworkCollectionId = networkCollectionId;
			ItemPrefab = itemPrefab;
			State = state;
			Message = message;
		}

		public override string ToString()
		{
			string text = (ItemId.HasValue ? ItemId.Value.ToString() : "<auto-pending>");
			return $"{Key} (ItemId={text}, CollectionId={NetworkCollectionId}, State={State})";
		}
	}
	public static class ItemRegistry
	{
		public static event Action<ItemRegistrationHandle> RegistrationChanged;

		public static ItemRegistrationHandle Register(ItemRegistration registration)
		{
			return RegistryRuntime.Register(registration);
		}

		public static ItemRegistrationHandle RegisterGenerated(GeneratedItemRegistration registration)
		{
			return RegistryRuntime.RegisterGenerated(registration);
		}

		public static bool TryGet(byte itemId, out ItemRegistrationHandle handle)
		{
			return RegistryRuntime.TryGet(itemId, out handle);
		}

		public static bool TryGet(string modGuid, string internalName, out ItemRegistrationHandle handle)
		{
			return RegistryRuntime.TryGet(RegistryRuntime.BuildKey(modGuid, internalName), out handle);
		}

		public static IReadOnlyList<ItemRegistrationHandle> GetAll()
		{
			return RegistryRuntime.GetAllHandles();
		}

		internal static void RaiseRegistrationChanged(ItemRegistrationHandle handle)
		{
			Action<ItemRegistrationHandle> registrationChanged = ItemRegistry.RegistrationChanged;
			if (registrationChanged == null)
			{
				return;
			}
			try
			{
				registrationChanged(handle);
			}
			catch (Exception exception)
			{
				RegistryRuntime.LogSubscriberException(exception);
			}
		}
	}
	internal static class RegistryRuntime
	{
		private sealed class RegistrationRecord
		{
			internal string Key;

			internal string NormalizedName;

			internal string DisplayName;

			internal Item ItemPrefab;

			internal NetworkObject NetworkPrefab;

			internal InventoryIcon Icon;

			internal GeneratedItemRegistration GeneratedRegistration;

			internal ItemRegistrationHandle Handle;

			internal bool GameRegistryApplied;

			internal readonly HashSet<NetworkManager> RegisteredNetworkManagers = new HashSet<NetworkManager>();
		}

		private static readonly object Sync = new object();

		private static readonly Dictionary<string, RegistrationRecord> ByKey = new Dictionary<string, RegistrationRecord>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<byte, RegistrationRecord> ById = new Dictionary<byte, RegistrationRecord>();

		private static readonly Dictionary<ushort, RegistrationRecord> ByCollectionId = new Dictionary<ushort, RegistrationRecord>();

		private static readonly FieldInfo ItemIdField = AccessTools.Field(typeof(Item), "_id");

		private static readonly FieldInfo GameInfoInstanceField = AccessTools.Field(typeof(GameInfo), "_instance");

		private static readonly FieldInfo AllItemsField = AccessTools.Field(typeof(GameInfo), "_allItems");

		private static readonly FieldInfo NameToSpawnableField = AccessTools.Field(typeof(GameInfo), "_nameToSpawnable");

		private static readonly FieldInfo IdToSpawnableField = AccessTools.Field(typeof(GameInfo), "_idToSpawnable");

		private static ManualLogSource _logger;

		private static int _mainThreadId;

		private static bool _initialized;

		private static bool _gameInfoAwakeCompleted;

		private static float _nextRetryAt;

		internal static void Initialize(ManualLogSource logger)
		{
			_logger = logger;
			_mainThreadId = Thread.CurrentThread.ManagedThreadId;
			_initialized = true;
			_gameInfoAwakeCompleted = GameInfoInstanceField?.GetValue(null) != null;
			if (ItemIdField == null || GameInfoInstanceField == null || AllItemsField == null || NameToSpawnableField == null || IdToSpawnableField == null)
			{
				_logger.LogError((object)"[ItemAPI] The current game version is missing expected Item/GameInfo fields; registration will fail safely.");
			}
		}

		internal static void Shutdown()
		{
			_initialized = false;
			_logger = null;
		}

		internal static ItemRegistrationHandle Register(ItemRegistration registration)
		{
			//IL_00a3: 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 (!_initialized)
			{
				return Rejected("<unknown>", 0, null, "The Item API plugin is not initialized. Declare a hard BepInEx dependency.");
			}
			if (Thread.CurrentThread.ManagedThreadId != _mainThreadId)
			{
				return Rejected("<unknown>", 0, null, "Register must be called from Unity's main thread.");
			}
			if (registration == null)
			{
				return Rejected("<unknown>", 0, null, "registration cannot be null.");
			}
			string key;
			try
			{
				key = BuildKey(registration.ModGuid, registration.InternalName);
			}
			catch (ArgumentException ex)
			{
				return Rejected("<invalid>", 0, null, ex.Message);
			}
			if (!Object.op_Implicit((Object)(object)registration.Prefab))
			{
				return Rejected(key, 0, null, "Prefab cannot be null.");
			}
			Scene scene = registration.Prefab.scene;
			if (((Scene)(ref scene)).IsValid())
			{
				return Rejected(key, 0, null, "Prefab is a scene instance. Pass the prefab asset returned by AssetBundle.LoadAsset<GameObject>() directly.");
			}
			Item component = registration.Prefab.GetComponent<Item>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return Rejected(key, 0, null, "The prefab root is missing an Item component.");
			}
			NetworkObject component2 = registration.Prefab.GetComponent<NetworkObject>();
			if (!Object.op_Implicit((Object)(object)component2))
			{
				return Rejected(key, 0, component, "The prefab root is missing a FishNet NetworkObject component.");
			}
			if (ItemIdField == null)
			{
				return Rejected(key, 0, component, "Item._id could not be located in the current game version.");
			}
			ushort num = ((registration.NetworkCollectionId != 0) ? registration.NetworkCollectionId : DeriveCollectionId(key));
			string text = NormalizeName(registration.InternalName);
			if (text.Length == 0)
			{
				return Rejected(key, num, component, "InternalName cannot be empty after normalization.");
			}
			lock (Sync)
			{
				if (ByKey.TryGetValue(key, out var value))
				{
					if ((Object)(object)value.ItemPrefab == (Object)(object)component)
					{
						return value.Handle;
					}
					return Rejected(key, num, component, "The registration key is already used by another prefab.");
				}
				if (ByCollectionId.TryGetValue(num, out var value2))
				{
					return Rejected(key, num, component, "FishNet collection ID is already used by " + value2.Key + "; explicitly specify another NetworkCollectionId.");
				}
				component2.SetIsSpawnable(true);
				ItemRegistrationHandle itemRegistrationHandle = new ItemRegistrationHandle(key, num, component, ItemRegistrationState.PendingGameRegistry, "Waiting for GameInfo to complete original item registration.");
				RegistrationRecord value3 = new RegistrationRecord
				{
					Key = key,
					NormalizedName = text,
					DisplayName = registration.DisplayName,
					ItemPrefab = component,
					NetworkPrefab = component2,
					Icon = registration.InventoryIcon,
					Handle = itemRegistrationHandle
				};
				ByKey.Add(key, value3);
				ByCollectionId.Add(num, value3);
				_logger.LogInfo((object)$"[ItemAPI] Accepted {itemRegistrationHandle}.");
			}
			ProcessRegistrations();
			return GetHandleByKey(key);
		}

		internal static ItemRegistrationHandle RegisterGenerated(GeneratedItemRegistration registration)
		{
			if (!_initialized)
			{
				return Rejected("<unknown>", 0, null, "The Item API plugin is not initialized. Declare a hard BepInEx dependency.");
			}
			if (Thread.CurrentThread.ManagedThreadId != _mainThreadId)
			{
				return Rejected("<unknown>", 0, null, "RegisterGenerated must be called from Unity's main thread.");
			}
			if (registration == null)
			{
				return Rejected("<unknown>", 0, null, "registration cannot be null.");
			}
			string key;
			try
			{
				key = BuildKey(registration.ModGuid, registration.InternalName);
			}
			catch (ArgumentException ex)
			{
				return Rejected("<invalid>", 0, null, ex.Message);
			}
			ushort num = ((registration.NetworkCollectionId != 0) ? registration.NetworkCollectionId : DeriveCollectionId(key));
			string text = NormalizeName(registration.InternalName);
			if (text.Length == 0)
			{
				return Rejected(key, num, null, "InternalName cannot be empty after normalization.");
			}
			if (!GeneratedPrefabFactory.ValidateSource(registration, out var error))
			{
				return Rejected(key, num, null, error);
			}
			lock (Sync)
			{
				if (ByKey.TryGetValue(key, out var value))
				{
					if (value.GeneratedRegistration != null && (Object)(object)value.GeneratedRegistration.ContentPrefab == (Object)(object)registration.ContentPrefab)
					{
						return value.Handle;
					}
					return Rejected(key, num, null, "The registration key is already used by another generated-item definition.");
				}
				if (ByCollectionId.TryGetValue(num, out var value2))
				{
					return Rejected(key, num, null, "FishNet collection ID is already used by " + value2.Key + "; explicitly specify another NetworkCollectionId.");
				}
				GeneratedItemRegistration generatedItemRegistration = new GeneratedItemRegistration
				{
					ModGuid = registration.ModGuid,
					InternalName = registration.InternalName,
					ContentPrefab = registration.ContentPrefab,
					InventoryIcon = registration.InventoryIcon,
					HoldPose = registration.HoldPose,
					DisplayName = registration.DisplayName,
					PickupRadius = registration.PickupRadius,
					Buoyancy = registration.Buoyancy,
					NetworkCollectionId = num
				};
				ItemRegistrationHandle itemRegistrationHandle = new ItemRegistrationHandle(key, num, null, ItemRegistrationState.PendingGameRegistry, "Waiting for GameInfo before generating the original item skeleton.");
				RegistrationRecord value3 = new RegistrationRecord
				{
					Key = key,
					NormalizedName = text,
					DisplayName = generatedItemRegistration.DisplayName,
					GeneratedRegistration = generatedItemRegistration,
					Icon = generatedItemRegistration.InventoryIcon,
					Handle = itemRegistrationHandle
				};
				ByKey.Add(key, value3);
				ByCollectionId.Add(num, value3);
				_logger.LogInfo((object)$"[ItemAPI] Accepted generated item {itemRegistrationHandle}.");
			}
			ProcessRegistrations();
			return GetHandleByKey(key);
		}

		internal static void Tick()
		{
			if (_initialized && !(Time.unscaledTime < _nextRetryAt))
			{
				_nextRetryAt = Time.unscaledTime + 0.25f;
				ProcessRegistrations();
			}
		}

		internal static void OnGameInfoAwakeCompleted()
		{
			_gameInfoAwakeCompleted = true;
			ProcessRegistrations();
		}

		private static void ProcessRegistrations()
		{
			if (!_initialized || Thread.CurrentThread.ManagedThreadId != _mainThreadId)
			{
				return;
			}
			RegistrationRecord[] array;
			lock (Sync)
			{
				array = new RegistrationRecord[ByKey.Count];
				ByKey.Values.CopyTo(array, 0);
			}
			if (_gameInfoAwakeCompleted)
			{
				AssignPendingItemIds(array);
			}
			RegistrationRecord[] array2 = array;
			foreach (RegistrationRecord registrationRecord in array2)
			{
				if (registrationRecord.Handle.State == ItemRegistrationState.Failed || registrationRecord.Handle.State == ItemRegistrationState.Rejected)
				{
					continue;
				}
				if (!_gameInfoAwakeCompleted)
				{
					SetState(registrationRecord, ItemRegistrationState.PendingGameRegistry, "Waiting for GameInfo before HTF MoreItemAPI assigns a game-local Item ID.");
					continue;
				}
				if (!registrationRecord.Handle.ItemId.HasValue)
				{
					SetState(registrationRecord, ItemRegistrationState.PendingGameRegistry, "Waiting for HTF MoreItemAPI to assign a free game-local Item ID.");
					continue;
				}
				if (!Object.op_Implicit((Object)(object)registrationRecord.ItemPrefab))
				{
					if (registrationRecord.GeneratedRegistration == null)
					{
						Fail(registrationRecord, "The registration record does not contain a valid Item prefab.");
						continue;
					}
					if (!GeneratedPrefabFactory.TryCreate(registrationRecord.Key, registrationRecord.Handle.ItemId.Value, registrationRecord.GeneratedRegistration, out var item, out var networkObject, out var error))
					{
						Fail(registrationRecord, error);
						continue;
					}
					registrationRecord.ItemPrefab = item;
					registrationRecord.NetworkPrefab = networkObject;
					registrationRecord.Handle.ItemPrefab = item;
					_logger.LogInfo((object)("[ItemAPI] Generated the item skeleton for " + registrationRecord.Key + " through the fixed pipeline; " + $"WorldColliders={((Component)item).GetComponentsInChildren<Collider>(true).Length - 1}."));
				}
				if (!registrationRecord.GameRegistryApplied && !TryApplyGameRegistry(registrationRecord, out var error2))
				{
					Fail(registrationRecord, error2);
					continue;
				}
				NetworkManager networkManager = InstanceFinder.NetworkManager;
				if (!Object.op_Implicit((Object)(object)networkManager))
				{
					SetState(registrationRecord, ItemRegistrationState.PendingNetworkManager, "The game registry is ready; waiting for FishNet NetworkManager.");
					continue;
				}
				if (!registrationRecord.RegisteredNetworkManagers.Contains(networkManager))
				{
					if (!TryApplyNetworkRegistry(registrationRecord, networkManager, out var error3))
					{
						Fail(registrationRecord, error3);
						continue;
					}
					registrationRecord.RegisteredNetworkManagers.Add(networkManager);
				}
				SetState(registrationRecord, ItemRegistrationState.Registered, "Registered with GameInfo and the FishNet runtime spawnable collection.");
			}
		}

		private static void AssignPendingItemIds(RegistrationRecord[] records)
		{
			if (AllItemsField == null || IdToSpawnableField == null || ItemIdField == null)
			{
				return;
			}
			Dictionary<byte, Item> dictionary = AllItemsField.GetValue(null) as Dictionary<byte, Item>;
			Dictionary<byte, Item> dictionary2 = IdToSpawnableField.GetValue(null) as Dictionary<byte, Item>;
			if (dictionary == null || dictionary2 == null)
			{
				return;
			}
			List<RegistrationRecord> list = new List<RegistrationRecord>();
			HashSet<byte> hashSet = new HashSet<byte>(dictionary.Keys);
			hashSet.UnionWith(dictionary2.Keys);
			lock (Sync)
			{
				hashSet.UnionWith(ById.Keys);
				foreach (RegistrationRecord registrationRecord in records)
				{
					if (!registrationRecord.Handle.ItemId.HasValue && registrationRecord.Handle.State != ItemRegistrationState.Failed && registrationRecord.Handle.State != ItemRegistrationState.Rejected)
					{
						list.Add(registrationRecord);
					}
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			List<string> list2 = new List<string>(list.Count);
			foreach (RegistrationRecord item in list)
			{
				list2.Add(item.Key);
			}
			Dictionary<string, byte> dictionary3;
			try
			{
				dictionary3 = ItemIdAllocator.Allocate(list2, hashSet);
			}
			catch (InvalidOperationException ex)
			{
				foreach (RegistrationRecord item2 in list)
				{
					Fail(item2, "Automatic Item ID allocation failed: " + ex.Message);
				}
				return;
			}
			lock (Sync)
			{
				foreach (RegistrationRecord item3 in list)
				{
					if (!item3.Handle.ItemId.HasValue)
					{
						byte b = dictionary3[item3.Key];
						item3.Handle.ItemId = b;
						ById.Add(b, item3);
						if (Object.op_Implicit((Object)(object)item3.ItemPrefab))
						{
							ItemIdField.SetValue(item3.ItemPrefab, b);
						}
						_logger.LogInfo((object)($"[ItemAPI] Automatically assigned ItemId={b} to {item3.Key}; " + $"Preferred={ItemIdAllocator.DerivePreferredId(item3.Key)}."));
					}
				}
			}
		}

		private static bool TryApplyGameRegistry(RegistrationRecord record, out string error)
		{
			error = null;
			if (AllItemsField == null || NameToSpawnableField == null || IdToSpawnableField == null)
			{
				error = "GameInfo registry fields could not be located in the current game version.";
				return false;
			}
			Dictionary<byte, Item> dictionary = AllItemsField.GetValue(null) as Dictionary<byte, Item>;
			Dictionary<string, Item> dictionary2 = NameToSpawnableField.GetValue(null) as Dictionary<string, Item>;
			Dictionary<byte, Item> dictionary3 = IdToSpawnableField.GetValue(null) as Dictionary<byte, Item>;
			if (dictionary == null || dictionary2 == null || dictionary3 == null)
			{
				error = "The GameInfo registry is not available yet.";
				return false;
			}
			byte value = record.Handle.ItemId.Value;
			if (dictionary.TryGetValue(value, out var value2) && (Object)(object)value2 != (Object)(object)record.ItemPrefab)
			{
				error = $"Automatically assigned Item ID {value} is already used by {Describe(value2)} from the game or another mod.";
				return false;
			}
			if (dictionary3.TryGetValue(value, out var value3) && (Object)(object)value3 != (Object)(object)record.ItemPrefab)
			{
				error = $"Automatically assigned Spawnable ID {value} is already used by {Describe(value3)}.";
				return false;
			}
			if (dictionary2.TryGetValue(record.NormalizedName, out var value4) && (Object)(object)value4 != (Object)(object)record.ItemPrefab)
			{
				error = "Normalized name '" + record.NormalizedName + "' is already used by " + Describe(value4) + ".";
				return false;
			}
			dictionary[value] = record.ItemPrefab;
			dictionary3[value] = record.ItemPrefab;
			dictionary2[record.NormalizedName] = record.ItemPrefab;
			record.GameRegistryApplied = true;
			_logger.LogInfo((object)$"[ItemAPI] Added {record.Key} to GameInfo, ItemId={value}.");
			return true;
		}

		private static bool TryApplyNetworkRegistry(RegistrationRecord record, NetworkManager manager, out string error)
		{
			error = null;
			ushort networkCollectionId = record.Handle.NetworkCollectionId;
			PrefabObjects prefabObjects = manager.GetPrefabObjects<DefaultPrefabObjects>(networkCollectionId, false);
			if ((Object)(object)prefabObjects != (Object)null && prefabObjects.GetObjectCount() > 0)
			{
				if ((Object)(object)prefabObjects.GetObject(true, 0) == (Object)(object)record.NetworkPrefab)
				{
					return true;
				}
				error = $"FishNet runtime collection {networkCollectionId} is already used by an external mod.";
				return false;
			}
			if (InstanceFinder.IsClientStarted || InstanceFinder.IsServerStarted)
			{
				error = "The network session has already started, so network items cannot be appended safely. Call Register before connecting or hosting.";
				return false;
			}
			PrefabObjects val = prefabObjects ?? manager.GetPrefabObjects<DefaultPrefabObjects>(networkCollectionId, true);
			if ((Object)(object)val == (Object)null)
			{
				error = $"FishNet could not create runtime collection {networkCollectionId}.";
				return false;
			}
			val.AddObject(record.NetworkPrefab, true, true);
			if (val.GetObjectCount() != 1 || (Object)(object)val.GetObject(true, 0) != (Object)(object)record.NetworkPrefab)
			{
				error = $"FishNet runtime collection {networkCollectionId} is inconsistent after initialization.";
				return false;
			}
			_logger.LogInfo((object)$"[ItemAPI] Added {record.Key} to FishNet collection={networkCollectionId}, PrefabId=0.");
			return true;
		}

		internal static bool TryGet(byte itemId, out ItemRegistrationHandle handle)
		{
			lock (Sync)
			{
				if (ById.TryGetValue(itemId, out var value))
				{
					handle = value.Handle;
					return true;
				}
			}
			handle = null;
			return false;
		}

		internal static bool TryGet(string key, out ItemRegistrationHandle handle)
		{
			lock (Sync)
			{
				if (key != null && ByKey.TryGetValue(key, out var value))
				{
					handle = value.Handle;
					return true;
				}
			}
			handle = null;
			return false;
		}

		internal static bool TryGetIcon(byte itemId, out InventoryIcon icon)
		{
			lock (Sync)
			{
				if (ById.TryGetValue(itemId, out var value) && value.Icon != null && Object.op_Implicit((Object)(object)value.Icon.Texture))
				{
					icon = value.Icon;
					return true;
				}
			}
			icon = null;
			return false;
		}

		internal static bool TryGetDisplayName(byte itemId, out string displayName)
		{
			lock (Sync)
			{
				if (ById.TryGetValue(itemId, out var value) && !string.IsNullOrWhiteSpace(value.DisplayName))
				{
					displayName = value.DisplayName;
					return true;
				}
			}
			displayName = null;
			return false;
		}

		internal static IReadOnlyList<ItemRegistrationHandle> GetAllHandles()
		{
			lock (Sync)
			{
				List<ItemRegistrationHandle> list = new List<ItemRegistrationHandle>(ByKey.Count);
				foreach (RegistrationRecord value in ByKey.Values)
				{
					list.Add(value.Handle);
				}
				list.Sort(delegate(ItemRegistrationHandle left, ItemRegistrationHandle right)
				{
					if (left.ItemId.HasValue && right.ItemId.HasValue)
					{
						return left.ItemId.Value.CompareTo(right.ItemId.Value);
					}
					if (left.ItemId.HasValue)
					{
						return -1;
					}
					return right.ItemId.HasValue ? 1 : string.Compare(left.Key, right.Key, StringComparison.Ordinal);
				});
				return list;
			}
		}

		internal static string BuildKey(string modGuid, string internalName)
		{
			if (string.IsNullOrWhiteSpace(modGuid))
			{
				throw new ArgumentException("ModGuid cannot be empty.", "modGuid");
			}
			if (string.IsNullOrWhiteSpace(internalName))
			{
				throw new ArgumentException("InternalName cannot be empty.", "internalName");
			}
			return modGuid.Trim().ToLowerInvariant() + ":" + internalName.Trim().ToLowerInvariant();
		}

		private static string NormalizeName(string value)
		{
			return value.Replace(" ", string.Empty).Trim().ToLowerInvariant();
		}

		private static ushort DeriveCollectionId(string key)
		{
			uint num = 2166136261u;
			byte[] bytes = Encoding.UTF8.GetBytes(key);
			foreach (byte b in bytes)
			{
				num ^= b;
				num *= 16777619;
			}
			return (ushort)(32768 + num % 32767);
		}

		private static ItemRegistrationHandle Rejected(string key, ushort collectionId, Item item, string message)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError((object)("[ItemAPI] Rejected registration " + key + ": " + message));
			}
			return new ItemRegistrationHandle(key, collectionId, item, ItemRegistrationState.Rejected, message);
		}

		private static ItemRegistrationHandle GetHandleByKey(string key)
		{
			lock (Sync)
			{
				return ByKey[key].Handle;
			}
		}

		private static void Fail(RegistrationRecord record, string message)
		{
			SetState(record, ItemRegistrationState.Failed, message);
			_logger.LogError((object)("[ItemAPI] Registration failed for " + record.Key + ": " + message));
		}

		private static void SetState(RegistrationRecord record, ItemRegistrationState state, string message)
		{
			if (record.Handle.State != state || !string.Equals(record.Handle.Message, message, StringComparison.Ordinal))
			{
				record.Handle.State = state;
				record.Handle.Message = message;
				ItemRegistry.RaiseRegistrationChanged(record.Handle);
			}
		}

		private static string Describe(Item item)
		{
			if (!Object.op_Implicit((Object)(object)item))
			{
				return "<null>";
			}
			return "'" + ((Object)item).name + "'";
		}

		internal static void LogSubscriberException(Exception exception)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError((object)$"[ItemAPI] A RegistrationChanged subscriber threw an exception: {exception}");
			}
		}
	}
}