Decompiled source of ShootZombies v1.3.3

plugins/Thanks.ShootZombies.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ShootZombies")]
[assembly: AssemblyDescription("Turns PEAK's blowgun into a configurable zombie-survival weapon mode with selectable gun models, lobby weapon grants, an in-game config panel, and host-synced multiplayer settings.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ShootZombies")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("927916ce-8113-4ce1-a65e-d4bd77e780b4")]
[assembly: AssemblyFileVersion("1.3.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 ShootZombies
{
	internal static class AkLightweightAssetLoader
	{
		private struct ObjVertexKey : IEquatable<ObjVertexKey>
		{
			public int PositionIndex;

			public int UvIndex;

			public int NormalIndex;

			public bool Equals(ObjVertexKey other)
			{
				if (PositionIndex == other.PositionIndex && UvIndex == other.UvIndex)
				{
					return NormalIndex == other.NormalIndex;
				}
				return false;
			}

			public override bool Equals(object obj)
			{
				if (!(obj is ObjVertexKey))
				{
					return false;
				}
				return Equals((ObjVertexKey)obj);
			}

			public override int GetHashCode()
			{
				return ((17 * 31 + PositionIndex) * 31 + UvIndex) * 31 + NormalIndex;
			}
		}

		private struct ObjFaceVertex
		{
			public int PositionIndex;

			public int UvIndex;

			public int NormalIndex;
		}

		[CompilerGenerated]
		private sealed class <GetSearchDirectories>d__18 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private HashSet<string> <seen>5__2;

			private IEnumerator<string> <>7__wrap2;

			private string <fullPath>5__4;

			string IEnumerator<string>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetSearchDirectories>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<seen>5__2 = null;
				<>7__wrap2 = null;
				<fullPath>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<seen>5__2 = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
						<>7__wrap2 = GetSearchRoots().GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
					{
						<>1__state = -3;
						string path = Path.Combine(<fullPath>5__4, "AK_Resources");
						if (Directory.Exists(path))
						{
							string fullPath = GetFullPath(path);
							if (!string.IsNullOrWhiteSpace(fullPath) && <seen>5__2.Add(fullPath))
							{
								<>2__current = fullPath;
								<>1__state = 2;
								return true;
							}
						}
						goto IL_0120;
					}
					case 2:
						{
							<>1__state = -3;
							goto IL_0120;
						}
						IL_0120:
						<fullPath>5__4 = null;
						break;
					}
					while (<>7__wrap2.MoveNext())
					{
						string current = <>7__wrap2.Current;
						if (!string.IsNullOrWhiteSpace(current))
						{
							<fullPath>5__4 = GetFullPath(current);
							if (!string.IsNullOrWhiteSpace(<fullPath>5__4) && Directory.Exists(<fullPath>5__4) && <seen>5__2.Add(<fullPath>5__4))
							{
								<>2__current = <fullPath>5__4;
								<>1__state = 1;
								return true;
							}
						}
					}
					<>m__Finally1();
					<>7__wrap2 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetSearchDirectories>d__18(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetSearchRoots>d__19 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private string <>2__current;

			private int <>l__initialThreadId;

			private string <text2>5__2;

			private string <text3>5__3;

			string IEnumerator<string>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetSearchRoots>d__19(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<text2>5__2 = null;
				<text3>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					string location = Assembly.GetExecutingAssembly().Location;
					string value = (string.IsNullOrWhiteSpace(location) ? string.Empty : (Path.GetDirectoryName(location) ?? string.Empty));
					<text2>5__2 = Paths.PluginPath ?? string.Empty;
					<text3>5__3 = (string.IsNullOrWhiteSpace(<text2>5__2) ? string.Empty : (Directory.GetParent(<text2>5__2)?.FullName ?? string.Empty));
					if (!string.IsNullOrWhiteSpace(value))
					{
						<>2__current = value;
						<>1__state = 1;
						return true;
					}
					goto IL_00c1;
				}
				case 1:
					<>1__state = -1;
					goto IL_00c1;
				case 2:
					<>1__state = -1;
					goto IL_00ea;
				case 3:
					<>1__state = -1;
					goto IL_0113;
				case 4:
					{
						<>1__state = -1;
						return false;
					}
					IL_0113:
					<>2__current = Path.Combine(Environment.CurrentDirectory ?? string.Empty, "AK_Resources");
					<>1__state = 4;
					return true;
					IL_00c1:
					if (!string.IsNullOrWhiteSpace(<text2>5__2))
					{
						<>2__current = <text2>5__2;
						<>1__state = 2;
						return true;
					}
					goto IL_00ea;
					IL_00ea:
					if (!string.IsNullOrWhiteSpace(<text3>5__3))
					{
						<>2__current = <text3>5__3;
						<>1__state = 3;
						return true;
					}
					goto IL_0113;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<string> IEnumerable<string>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <GetSearchRoots>d__19(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<string>)this).GetEnumerator();
			}
		}

		private const string ResourceFolderName = "AK_Resources";

		private const string CanonicalModelFileName = "ak_model.obj";

		private const string CanonicalTextureFileName = "ak_texture.png";

		private const string CanonicalIconFileName = "ak_icon.png";

		private static readonly string[] ModelFileNames = new string[3] { "ak_model.obj", "-3728671120793114700_Cube.obj", "Cube.obj" };

		private static readonly string[] TextureFileNames = new string[3] { "ak_texture.png", "AK-47_type_II.png", "ak47.png" };

		private static readonly string[] IconFileNames = new string[3] { "ak_icon.png", "AK-47_type_II_icon.png", "ak47_icon.png" };

		private static readonly Vector3 MeshLocalPosition = new Vector3(0f, 0f, 0.11863899f);

		private static readonly Quaternion MeshLocalRotation = new Quaternion(1.1009293E-08f, -0.70710677f, -0.7071068f, -2.2351747E-08f);

		private static readonly Vector3 MeshLocalScale = new Vector3(0.3060086f, 0.18934934f, 0.18934931f);

		private static readonly Vector3 SpawnLocalPosition = new Vector3(0.002f, 0.036f, 0.5118f);

		private static readonly Quaternion SpawnLocalRotation = Quaternion.identity;

		private static readonly Vector3 SpawnLocalScale = new Vector3(0.7339988f, 0.7339988f, 0.7339988f);

		public static bool TryLoad(out GameObject prefab, out string diagnostic)
		{
			prefab = null;
			diagnostic = string.Empty;
			if (!TryResolveResourcePaths(out var modelPath, out var texturePath, out diagnostic))
			{
				return false;
			}
			if (!TryLoadObjMesh(modelPath, out var mesh, out var summary))
			{
				diagnostic = "OBJ load failed: " + modelPath + " (" + summary + ")";
				return false;
			}
			string summary2;
			Material val = CreateMaterial(LoadTexture(texturePath, out summary2), texturePath);
			if ((Object)(object)val == (Object)null)
			{
				diagnostic = "Material creation failed for texture: " + texturePath;
				return false;
			}
			prefab = BuildPrefab(mesh, val);
			if ((Object)(object)prefab == (Object)null)
			{
				diagnostic = "Prefab build failed";
				return false;
			}
			diagnostic = "model=" + Path.GetFileName(modelPath) + ", texture=" + Path.GetFileName(texturePath) + ", " + summary + ", " + summary2;
			return true;
		}

		public static bool TryLoadIconTexture(out Texture2D texture, out string diagnostic)
		{
			texture = null;
			diagnostic = string.Empty;
			List<string> list = GetSearchDirectories().Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList();
			foreach (string item in list)
			{
				string text = ResolveFirstExistingPath(item, IconFileNames);
				if (!string.IsNullOrWhiteSpace(text))
				{
					texture = LoadTexture(text, out var summary);
					if ((Object)(object)texture != (Object)null)
					{
						diagnostic = "icon=" + Path.GetFileName(text) + ", " + summary;
						return true;
					}
					diagnostic = "icon decode failed: " + text + ", " + summary;
					return false;
				}
			}
			diagnostic = "searched=" + string.Join(" | ", list);
			return false;
		}

		private static bool TryResolveResourcePaths(out string modelPath, out string texturePath, out string diagnostic)
		{
			modelPath = string.Empty;
			texturePath = string.Empty;
			List<string> list = GetSearchDirectories().Distinct<string>(StringComparer.OrdinalIgnoreCase).ToList();
			foreach (string item in list)
			{
				string text = ResolveFirstExistingPath(item, ModelFileNames);
				string text2 = ResolveFirstExistingPath(item, TextureFileNames);
				if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(text2))
				{
					modelPath = text;
					texturePath = text2;
					diagnostic = "resolved at " + item;
					return true;
				}
			}
			diagnostic = "searched=" + string.Join(" | ", list);
			return false;
		}

		[IteratorStateMachine(typeof(<GetSearchDirectories>d__18))]
		private static IEnumerable<string> GetSearchDirectories()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetSearchDirectories>d__18(-2);
		}

		[IteratorStateMachine(typeof(<GetSearchRoots>d__19))]
		private static IEnumerable<string> GetSearchRoots()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetSearchRoots>d__19(-2);
		}

		private static string GetFullPath(string path)
		{
			try
			{
				return Path.GetFullPath(path);
			}
			catch
			{
				return string.Empty;
			}
		}

		private static string ResolveFirstExistingPath(string directory, IEnumerable<string> fileNames)
		{
			if (string.IsNullOrWhiteSpace(directory) || !Directory.Exists(directory))
			{
				return string.Empty;
			}
			foreach (string fileName in fileNames)
			{
				string text = Path.Combine(directory, fileName);
				if (File.Exists(text))
				{
					return text;
				}
			}
			return string.Empty;
		}

		private static bool TryLoadObjMesh(string modelPath, out Mesh mesh, out string summary)
		{
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			mesh = null;
			summary = string.Empty;
			List<Vector3> list = new List<Vector3>(4096);
			List<Vector2> list2 = new List<Vector2>(4096);
			List<Vector3> list3 = new List<Vector3>(4096);
			List<Vector3> list4 = new List<Vector3>(4096);
			List<Vector2> list5 = new List<Vector2>(4096);
			List<Vector3> list6 = new List<Vector3>(4096);
			List<int> list7 = new List<int>(12288);
			Dictionary<ObjVertexKey, int> cache = new Dictionary<ObjVertexKey, int>();
			bool flag = true;
			try
			{
				foreach (string item in File.ReadLines(modelPath))
				{
					if (string.IsNullOrWhiteSpace(item) || item[0] == '#')
					{
						continue;
					}
					if (item.StartsWith("v ", StringComparison.Ordinal))
					{
						if (TryParseVector3(item, out var vector))
						{
							list.Add(vector);
						}
					}
					else if (item.StartsWith("vt ", StringComparison.Ordinal))
					{
						if (TryParseVector2(item, out var vector2))
						{
							list2.Add(vector2);
						}
					}
					else if (item.StartsWith("vn ", StringComparison.Ordinal))
					{
						if (TryParseVector3(item, out var vector3))
						{
							list3.Add(vector3);
						}
					}
					else
					{
						if (!item.StartsWith("f ", StringComparison.Ordinal))
						{
							continue;
						}
						string[] array = item.Substring(2).Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
						if (array.Length < 3)
						{
							continue;
						}
						List<ObjFaceVertex> list8 = new List<ObjFaceVertex>(array.Length);
						string[] array2 = array;
						for (int i = 0; i < array2.Length; i++)
						{
							if (TryParseFaceVertex(array2[i], list.Count, list2.Count, list3.Count, out var vertex))
							{
								list8.Add(vertex);
								if (vertex.NormalIndex < 0)
								{
									flag = false;
								}
							}
						}
						if (list8.Count >= 3)
						{
							for (int j = 1; j < list8.Count - 1; j++)
							{
								AddTriangleVertex(list8[0], list, list2, list3, list4, list5, list6, list7, cache);
								AddTriangleVertex(list8[j], list, list2, list3, list4, list5, list6, list7, cache);
								AddTriangleVertex(list8[j + 1], list, list2, list3, list4, list5, list6, list7, cache);
							}
						}
					}
				}
				if (list4.Count == 0 || list7.Count == 0)
				{
					summary = "no mesh data";
					return false;
				}
				mesh = new Mesh();
				((Object)mesh).name = "AK_RuntimeMesh";
				if (list4.Count > 65535)
				{
					mesh.indexFormat = (IndexFormat)1;
				}
				mesh.SetVertices(list4);
				if (list5.Count == list4.Count)
				{
					mesh.SetUVs(0, list5);
				}
				mesh.subMeshCount = 1;
				mesh.SetTriangles(list7, 0, true);
				if (flag && list6.Count == list4.Count)
				{
					mesh.SetNormals(list6);
				}
				else
				{
					mesh.RecalculateNormals();
				}
				mesh.RecalculateBounds();
				TryRecalculateTangents(mesh);
				summary = "verts=" + list4.Count + ", tris=" + list7.Count / 3;
				return true;
			}
			catch (Exception ex)
			{
				mesh = null;
				summary = ex.GetType().Name + ": " + ex.Message;
				return false;
			}
		}

		private static bool TryParseVector3(string line, out Vector3 vector)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			vector = Vector3.zero;
			string[] array = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 4)
			{
				return false;
			}
			if (float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				vector = new Vector3(result, result2, result3);
				return true;
			}
			return false;
		}

		private static bool TryParseVector2(string line, out Vector2 vector)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			vector = Vector2.zero;
			string[] array = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 3)
			{
				return false;
			}
			if (float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
			{
				vector = new Vector2(result, result2);
				return true;
			}
			return false;
		}

		private static bool TryParseFaceVertex(string token, int positionCount, int uvCount, int normalCount, out ObjFaceVertex vertex)
		{
			vertex = default(ObjFaceVertex);
			if (string.IsNullOrWhiteSpace(token))
			{
				return false;
			}
			string[] array = token.Split(new char[1] { '/' });
			if (array.Length == 0)
			{
				return false;
			}
			vertex.PositionIndex = ResolveObjIndex(ParseObjIndex(array[0]), positionCount);
			vertex.UvIndex = ((array.Length >= 2 && !string.IsNullOrWhiteSpace(array[1])) ? ResolveObjIndex(ParseObjIndex(array[1]), uvCount) : (-1));
			vertex.NormalIndex = ((array.Length >= 3 && !string.IsNullOrWhiteSpace(array[2])) ? ResolveObjIndex(ParseObjIndex(array[2]), normalCount) : (-1));
			return vertex.PositionIndex >= 0;
		}

		private static int ParseObjIndex(string value)
		{
			int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result);
			return result;
		}

		private static int ResolveObjIndex(int rawIndex, int count)
		{
			if (rawIndex > 0)
			{
				return rawIndex - 1;
			}
			if (rawIndex < 0)
			{
				return count + rawIndex;
			}
			return -1;
		}

		private static void AddTriangleVertex(ObjFaceVertex faceVertex, List<Vector3> positions, List<Vector2> uvs, List<Vector3> normals, List<Vector3> outVertices, List<Vector2> outUvs, List<Vector3> outNormals, List<int> outTriangles, Dictionary<ObjVertexKey, int> cache)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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)
			ObjVertexKey key = default(ObjVertexKey);
			key.PositionIndex = faceVertex.PositionIndex;
			key.UvIndex = faceVertex.UvIndex;
			key.NormalIndex = faceVertex.NormalIndex;
			if (!cache.TryGetValue(key, out var value))
			{
				value = (cache[key] = outVertices.Count);
				outVertices.Add(positions[faceVertex.PositionIndex]);
				outUvs.Add((faceVertex.UvIndex >= 0 && faceVertex.UvIndex < uvs.Count) ? uvs[faceVertex.UvIndex] : Vector2.zero);
				outNormals.Add((faceVertex.NormalIndex >= 0 && faceVertex.NormalIndex < normals.Count) ? normals[faceVertex.NormalIndex] : Vector3.zero);
			}
			outTriangles.Add(value);
		}

		private static void TryRecalculateTangents(Mesh mesh)
		{
			if ((Object)(object)mesh == (Object)null)
			{
				return;
			}
			try
			{
				typeof(Mesh).GetMethod("RecalculateTangents", BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null)?.Invoke(mesh, null);
			}
			catch
			{
			}
		}

		private static Texture2D LoadTexture(string texturePath, out string summary)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			summary = "texture=missing";
			if (string.IsNullOrWhiteSpace(texturePath) || !File.Exists(texturePath))
			{
				return null;
			}
			try
			{
				byte[] data = File.ReadAllBytes(texturePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Object)val).name = Path.GetFileNameWithoutExtension(texturePath);
				if (!TryLoadPngIntoTexture(val, data))
				{
					Object.DestroyImmediate((Object)(object)val);
					summary = "texture=decode-failed";
					return null;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				((Texture)val).anisoLevel = 2;
				summary = "texture=" + ((Texture)val).width + "x" + ((Texture)val).height;
				return val;
			}
			catch (Exception ex)
			{
				summary = "texture-error=" + ex.GetType().Name;
				return null;
			}
		}

		private static bool TryLoadPngIntoTexture(Texture2D texture, byte[] data)
		{
			if ((Object)(object)texture == (Object)null || data == null || data.Length == 0)
			{
				return false;
			}
			try
			{
				MethodInfo method = typeof(Texture2D).GetMethod("LoadImage", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(byte[]) }, null);
				if (method != null)
				{
					if (!(method.Invoke(texture, new object[1] { data }) is bool result))
					{
						return true;
					}
					return result;
				}
			}
			catch
			{
			}
			try
			{
				MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: false)?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				}, null);
				if (methodInfo != null)
				{
					if (!(methodInfo.Invoke(null, new object[3] { texture, data, false }) is bool result2))
					{
						return true;
					}
					return result2;
				}
			}
			catch
			{
			}
			return false;
		}

		private static Material CreateMaterial(Texture2D texture, string texturePath)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Legacy Shaders/Diffuse");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val);
			((Object)val2).name = "M_AK_Runtime";
			if (val2.HasProperty("_BaseMap"))
			{
				val2.SetTexture("_BaseMap", (Texture)(object)texture);
			}
			if (val2.HasProperty("_MainTex"))
			{
				val2.SetTexture("_MainTex", (Texture)(object)texture);
			}
			if (val2.HasProperty("_BaseColor"))
			{
				val2.SetColor("_BaseColor", Color.white);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", Color.white);
			}
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0.12f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0.12f);
			}
			if (val2.HasProperty("_Cull"))
			{
				val2.SetInt("_Cull", 2);
			}
			val2.enableInstancing = true;
			Plugin.LogDiagnosticOnce("ak-light-mat:" + Path.GetFileName(texturePath ?? string.Empty), "Created lightweight AK material with shader=" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "null") + ", texture=" + (((Object)(object)texture != (Object)null) ? (((Texture)texture).width + "x" + ((Texture)texture).height) : "none"));
			return val2;
		}

		private static GameObject BuildPrefab(Mesh mesh, Material material)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0024: 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)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mesh == (Object)null || (Object)(object)material == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("AK");
			GameObject val2 = new GameObject("Mesh");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = MeshLocalPosition;
			val2.transform.localRotation = MeshLocalRotation;
			val2.transform.localScale = MeshLocalScale;
			MeshFilter val3 = val2.AddComponent<MeshFilter>();
			MeshRenderer val4 = val2.AddComponent<MeshRenderer>();
			val3.sharedMesh = mesh;
			((Renderer)val4).sharedMaterials = (Material[])(object)new Material[1] { material };
			((Renderer)val4).enabled = false;
			((Renderer)val4).forceRenderingOff = true;
			((Renderer)val4).shadowCastingMode = (ShadowCastingMode)1;
			((Renderer)val4).receiveShadows = true;
			GameObject val5 = new GameObject("SpawnPos");
			val5.transform.SetParent(val.transform, false);
			val5.transform.localPosition = SpawnLocalPosition;
			val5.transform.localRotation = SpawnLocalRotation;
			val5.transform.localScale = SpawnLocalScale;
			Object.DontDestroyOnLoad((Object)(object)val);
			return val;
		}
	}
	public sealed class AkHeldLegacyVisualMarker : MonoBehaviour
	{
	}
	public sealed class AkInPlaceMarker : MonoBehaviour
	{
		public bool hasBaseRotation;

		public bool hasBaseTransform;

		public bool hasOriginalVisual;

		public Vector3 baseLocalPosition = Vector3.zero;

		public Quaternion baseLocalRotation = Quaternion.identity;

		public Vector3 baseLocalScale = Vector3.one;

		public Mesh originalMesh;

		public Material[] originalMaterials;
	}
	public sealed class AkLocalVisualMarker : MonoBehaviour
	{
	}
	public sealed class AkMuzzleMarker : MonoBehaviour
	{
	}
	public sealed class AkSimpleVisualMarker : MonoBehaviour
	{
	}
	internal static class AkUiPatchHelpers
	{
		private const BindingFlags ReflectionFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo InventoryPrefabField = typeof(InventoryItemUI).GetField("_itemPrefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo InventoryItemDataField = typeof(InventoryItemUI).GetField("_itemData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo SlotItemProperty = typeof(ItemSlot).GetProperty("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo SlotItemField = typeof(ItemSlot).GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly Dictionary<Type, PropertyInfo> InventoryItemDataItemPropertyCache = new Dictionary<Type, PropertyInfo>();

		private static readonly Dictionary<Type, FieldInfo> InventoryItemDataItemFieldCache = new Dictionary<Type, FieldInfo>();

		private static readonly Dictionary<int, int> InventoryUiSourceKeyCache = new Dictionary<int, int>();

		private static readonly Dictionary<int, int> SliceSourceKeyCache = new Dictionary<int, int>();

		private static readonly Rect FullUvRect = new Rect(0f, 0f, 1f, 1f);

		private static readonly HashSet<InventoryItemUI> TrackedInventoryUis = new HashSet<InventoryItemUI>();

		private static readonly HashSet<BackpackWheelSlice> TrackedSlices = new HashSet<BackpackWheelSlice>();

		private static readonly HashSet<BackpackWheel> TrackedWheels = new HashSet<BackpackWheel>();

		private static readonly List<InventoryItemUI> StaleInventoryUis = new List<InventoryItemUI>();

		private static readonly List<BackpackWheelSlice> StaleSlices = new List<BackpackWheelSlice>();

		private static readonly List<BackpackWheel> StaleWheels = new List<BackpackWheel>();

		internal static void ApplyAkIcon(RawImage image, Item item)
		{
			if (!((Object)(object)image == (Object)null) && ItemPatch.IsBlowgunLike(item))
			{
				ApplyAkIconForce(image);
			}
		}

		internal static void ApplyAkIconForce(RawImage image)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if ((Object)(object)image == (Object)null)
			{
				return;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			if (!((Object)(object)akIconTexture == (Object)null))
			{
				Graphic val = (Graphic)image;
				if (!((Object)(object)image.texture == (Object)(object)akIconTexture) || !((Object)(object)val.material == (Object)null) || !(val.color == Color.white) || !(image.uvRect == FullUvRect) || !((Behaviour)image).enabled)
				{
					image.texture = (Texture)akIconTexture;
					val.color = Color.white;
					val.material = null;
					image.uvRect = FullUvRect;
					((Behaviour)image).enabled = true;
				}
			}
		}

		internal static void ApplyAkText(TMP_Text label)
		{
			if (!((Object)(object)label == (Object)null) && !string.Equals(label.text, ItemPatch.DisplayName, StringComparison.Ordinal))
			{
				label.text = ItemPatch.DisplayName;
			}
		}

		internal static void EnsureAkDisplayAndVisual(Item item)
		{
			if (!((Object)(object)item == (Object)null) && ItemPatch.IsBlowgunLike(item))
			{
				ItemPatch.ApplyAkDisplay(item);
			}
		}

		internal static void ApplyAkToInventoryUi(InventoryItemUI ui, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return;
			}
			TrackInventoryUi(ui);
			Item val = (((Object)(object)knownItem != (Object)null) ? knownItem : ResolveItemFromInventoryUi(ui));
			int instanceID = ((Object)ui).GetInstanceID();
			int itemSourceKey = GetItemSourceKey(val);
			if (itemSourceKey != 0 && InventoryUiSourceKeyCache.TryGetValue(instanceID, out var value) && value == itemSourceKey && IsInventoryUiAlreadyShowingAk(ui))
			{
				return;
			}
			if ((Object)(object)val != (Object)null && ItemPatch.IsBlowgunLike(val))
			{
				EnsureAkDisplayAndVisual(val);
				ApplyAkIconForce(ui.icon);
				ApplyAkText((TMP_Text)ui.nameText);
				InventoryUiSourceKeyCache[instanceID] = itemSourceKey;
				return;
			}
			InventoryUiSourceKeyCache[instanceID] = itemSourceKey;
			if ((Object)(object)val != (Object)null)
			{
				RestoreInventoryUi(ui, val);
				return;
			}
			if (itemSourceKey == 0 && IsInventoryUiAlreadyShowingAk(ui))
			{
				ClearInventoryUi(ui);
				return;
			}
			TextMeshProUGUI nameText = ui.nameText;
			string value2 = ((((Object)(object)nameText != (Object)null) ? ((TMP_Text)nameText).text : null) ?? string.Empty).ToLowerInvariant();
			RawImage icon = ui.icon;
			Texture val2 = (((Object)(object)icon != (Object)null) ? icon.texture : null);
			string text = (((Object)(object)val2 != (Object)null) ? ((Object)val2).name : string.Empty).ToLowerInvariant();
			if (ItemPatch.ContainsWeaponKeyword(value2) || text.Contains("dart") || text.Contains("blowgun") || ItemPatch.ContainsWeaponKeyword(text))
			{
				ApplyAkIconForce(ui.icon);
				ApplyAkText((TMP_Text)ui.nameText);
			}
		}

		internal static Item ResolveItemFromInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return null;
			}
			try
			{
				object obj = InventoryPrefabField?.GetValue(ui);
				Item val = (Item)((obj is Item) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				object obj2 = InventoryItemDataField?.GetValue(ui);
				if (obj2 != null)
				{
					Item val2 = ResolveItemFromItemData(obj2);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		internal static Item ResolveItemFromSlot(ItemSlot slot)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if (slot == null || slot.IsEmpty())
			{
				return null;
			}
			try
			{
				object obj = SlotItemProperty?.GetValue(slot);
				Item val = (Item)((obj is Item) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				object obj2 = SlotItemField?.GetValue(slot);
				Item val2 = (Item)((obj2 is Item) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			catch
			{
			}
			return slot.prefab;
		}

		internal static void ApplyAkToSliceImage(BackpackWheelSlice slice, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return;
			}
			TrackSlice(slice);
			Item val = (((Object)(object)knownItem != (Object)null) ? knownItem : ResolveItemFromSlice(slice));
			int instanceID = ((Object)slice).GetInstanceID();
			int itemSourceKey = GetItemSourceKey(val);
			if (itemSourceKey == 0 || !SliceSourceKeyCache.TryGetValue(instanceID, out var value) || value != itemSourceKey || !IsSliceAlreadyShowingAk(slice))
			{
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					EnsureAkDisplayAndVisual(val);
					ApplyAkIconForce(slice.image);
				}
				else
				{
					RestoreSliceImage(slice, val);
				}
				SliceSourceKeyCache[instanceID] = itemSourceKey;
			}
		}

		internal static void ApplyAkToBackpackWheel(BackpackWheel wheel, Item knownItem = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)wheel == (Object)null)
			{
				return;
			}
			TrackWheel(wheel);
			Item val = knownItem;
			if ((Object)(object)val == (Object)null)
			{
				Character localCharacter = Character.localCharacter;
				object obj;
				if (localCharacter == null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = ((data != null) ? data.currentItem : null);
				}
				val = (Item)obj;
			}
			Character localCharacter2 = Character.localCharacter;
			if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val) && ItemPatch.IsLocallyHeldByPlayer(val, localCharacter2))
			{
				ItemPatch.ApplyAkDisplayIfNeeded(val);
				ApplyAkIcon(wheel.currentlyHeldItem, val);
			}
			else
			{
				RestoreBackpackWheel(wheel, ((Object)(object)val != (Object)null && ItemPatch.IsBlowgunLike(val)) ? null : val);
			}
		}

		internal static bool RefreshTrackedUi()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			CleanupStaleTrackedUi();
			bool result = false;
			foreach (InventoryItemUI trackedInventoryUi in TrackedInventoryUis)
			{
				if (!((Object)trackedInventoryUi == (Object)null))
				{
					ApplyAkToInventoryUi(trackedInventoryUi);
					result = true;
				}
			}
			foreach (BackpackWheelSlice trackedSlice in TrackedSlices)
			{
				if (!((Object)trackedSlice == (Object)null))
				{
					ApplyAkToSliceImage(trackedSlice);
					result = true;
				}
			}
			foreach (BackpackWheel trackedWheel in TrackedWheels)
			{
				if (!((Object)trackedWheel == (Object)null))
				{
					ApplyAkToBackpackWheel(trackedWheel);
					result = true;
				}
			}
			return result;
		}

		private static Item ResolveItemFromItemData(object itemData)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (itemData == null)
			{
				return null;
			}
			Type type = itemData.GetType();
			if (!InventoryItemDataItemPropertyCache.TryGetValue(type, out var value))
			{
				value = type.GetProperty("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				InventoryItemDataItemPropertyCache[type] = value;
				InventoryItemDataItemFieldCache[type] = type.GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			try
			{
				object obj = value?.GetValue(itemData) ?? InventoryItemDataItemFieldCache[type]?.GetValue(itemData);
				return (Item)((obj is Item) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		private static int GetItemSourceKey(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				return ((Object)item).GetInstanceID();
			}
			return 0;
		}

		private static bool IsInventoryUiAlreadyShowingAk(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)ui == (Object)null)
			{
				return false;
			}
			TextMeshProUGUI nameText = ui.nameText;
			if (!string.Equals((nameText != null) ? ((TMP_Text)nameText).text : null, ItemPatch.DisplayName, StringComparison.Ordinal))
			{
				return false;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			RawImage icon = ui.icon;
			if ((Object)(object)akIconTexture != (Object)null && !((Object)(object)icon == (Object)null))
			{
				return (Object)(object)icon.texture == (Object)(object)akIconTexture;
			}
			return false;
		}

		private static bool IsSliceAlreadyShowingAk(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return false;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			RawImage image = slice.image;
			if ((Object)(object)akIconTexture != (Object)null && !((Object)(object)image == (Object)null))
			{
				return (Object)(object)image.texture == (Object)(object)akIconTexture;
			}
			return false;
		}

		private static bool IsImageShowingAk(RawImage image)
		{
			if ((Object)(object)image == (Object)null)
			{
				return false;
			}
			Texture2D akIconTexture = Plugin.GetAkIconTexture();
			if ((Object)(object)akIconTexture != (Object)null)
			{
				return (Object)(object)image.texture == (Object)(object)akIconTexture;
			}
			return false;
		}

		private static void RestoreInventoryUi(InventoryItemUI ui, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0072: 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_0045: 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)
			if ((Object)ui == (Object)null || (Object)(object)item == (Object)null)
			{
				return;
			}
			Texture val = ResolveDefaultItemIcon(item);
			if (!((Object)(object)ui.icon == (Object)null))
			{
				if (IsImageShowingAk(ui.icon))
				{
					((Graphic)ui.icon).color = Color.white;
					((Graphic)ui.icon).material = null;
				}
				ui.icon.texture = val;
				ui.icon.uvRect = FullUvRect;
				((Behaviour)ui.icon).enabled = (Object)(object)val != (Object)null;
			}
			if (!((Object)(object)ui.nameText == (Object)null))
			{
				((TMP_Text)ui.nameText).text = ResolveDefaultItemName(item);
			}
		}

		private static void ClearInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)ui == (Object)null))
			{
				if (!((Object)(object)ui.icon == (Object)null))
				{
					ui.icon.texture = null;
					((Behaviour)ui.icon).enabled = false;
				}
				if (!((Object)(object)ui.nameText == (Object)null))
				{
					((TMP_Text)ui.nameText).text = string.Empty;
				}
			}
		}

		private static void RestoreSliceImage(BackpackWheelSlice slice, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)slice == (Object)null) && !((Object)(object)slice.image == (Object)null))
			{
				Texture val = ResolveDefaultItemIcon(item);
				if (IsImageShowingAk(slice.image))
				{
					((Graphic)slice.image).color = Color.white;
					((Graphic)slice.image).material = null;
				}
				slice.image.texture = val;
				slice.image.uvRect = FullUvRect;
				((Behaviour)slice.image).enabled = (Object)(object)val != (Object)null;
			}
		}

		private static void RestoreBackpackWheel(BackpackWheel wheel, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0053: 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_0035: 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)
			if ((Object)wheel == (Object)null)
			{
				return;
			}
			RawImage currentlyHeldItem = wheel.currentlyHeldItem;
			if (!((Object)(object)currentlyHeldItem == (Object)null))
			{
				Texture val = ResolveDefaultItemIcon(item);
				if (IsImageShowingAk(currentlyHeldItem))
				{
					((Graphic)currentlyHeldItem).color = Color.white;
					((Graphic)currentlyHeldItem).material = null;
				}
				currentlyHeldItem.texture = val;
				currentlyHeldItem.uvRect = FullUvRect;
				((Behaviour)currentlyHeldItem).enabled = (Object)(object)val != (Object)null;
			}
		}

		private static Texture ResolveDefaultItemIcon(Item item)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			if ((Object)(object)item == (Object)null || item.UIData == null)
			{
				return null;
			}
			try
			{
				return (Texture)item.UIData.GetIcon();
			}
			catch
			{
				return (Texture)item.UIData.icon;
			}
		}

		private static string ResolveDefaultItemName(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				string itemName = item.GetItemName((ItemInstanceData)null);
				if (!string.IsNullOrWhiteSpace(itemName))
				{
					return itemName;
				}
			}
			catch
			{
			}
			return item.UIData?.itemName ?? string.Empty;
		}

		internal static Item ResolveItemFromSlice(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)slice == (Object)null)
			{
				return null;
			}
			try
			{
				PropertyInfo[] properties = ((object)slice).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (PropertyInfo propertyInfo in properties)
				{
					if (!(propertyInfo == null) && propertyInfo.GetIndexParameters().Length == 0)
					{
						object value = null;
						try
						{
							value = propertyInfo.GetValue(slice);
						}
						catch
						{
						}
						Item val = ExtractItem(value);
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
				FieldInfo[] fields = ((object)slice).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					object value2 = null;
					try
					{
						value2 = fieldInfo.GetValue(slice);
					}
					catch
					{
					}
					Item val2 = ExtractItem(value2);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static void TrackInventoryUi(InventoryItemUI ui)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)ui == (Object)null) && !TrackedInventoryUis.Contains(ui))
			{
				TrackedInventoryUis.Add(ui);
			}
		}

		private static void TrackSlice(BackpackWheelSlice slice)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)slice == (Object)null) && !TrackedSlices.Contains(slice))
			{
				TrackedSlices.Add(slice);
			}
		}

		private static void TrackWheel(BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)wheel == (Object)null) && !TrackedWheels.Contains(wheel))
			{
				TrackedWheels.Add(wheel);
			}
		}

		private static void CleanupStaleTrackedUi()
		{
			RemoveDestroyedTrackedObjects<InventoryItemUI>(TrackedInventoryUis, StaleInventoryUis);
			RemoveDestroyedTrackedObjects<BackpackWheelSlice>(TrackedSlices, StaleSlices);
			RemoveDestroyedTrackedObjects<BackpackWheel>(TrackedWheels, StaleWheels);
		}

		private static void RemoveDestroyedTrackedObjects<T>(HashSet<T> source, List<T> staleBuffer) where T : Object
		{
			if (source.Count == 0)
			{
				return;
			}
			staleBuffer.Clear();
			foreach (T item in source)
			{
				if ((Object)(object)item == (Object)null)
				{
					staleBuffer.Add(item);
				}
			}
			for (int i = 0; i < staleBuffer.Count; i++)
			{
				source.Remove(staleBuffer[i]);
			}
			staleBuffer.Clear();
		}

		private static Item ExtractItem(object value)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Item val = (Item)((value is Item) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			ItemSlot val2 = (ItemSlot)((value is ItemSlot) ? value : null);
			if (val2 != null)
			{
				return ResolveItemFromSlot(val2);
			}
			if (value == null)
			{
				return null;
			}
			Type type = value.GetType();
			if (!(type.FullName ?? string.Empty).StartsWith("System.ValueTuple", StringComparison.Ordinal))
			{
				return null;
			}
			try
			{
				FieldInfo field = type.GetField("Item1");
				FieldInfo? field2 = type.GetField("Item2");
				object obj = field?.GetValue(value);
				object obj2 = field2?.GetValue(value);
				if (obj is BackpackReference)
				{
					BackpackReference backpackRef = (BackpackReference)obj;
					if (obj2 is byte slotIndex)
					{
						return ResolveFromBackpackTuple(backpackRef, slotIndex);
					}
					if (obj2 is int)
					{
						int num = (int)obj2;
						return ResolveFromBackpackTuple(backpackRef, (byte)Mathf.Clamp(num, 0, 255));
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static Item ResolveFromBackpackTuple(BackpackReference backpackRef, byte slotIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((object)backpackRef == null)
				{
					return null;
				}
				object data = ((BackpackReference)(ref backpackRef)).GetData();
				if (data == null)
				{
					return null;
				}
				if (!((data.GetType().GetProperty("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(data) ?? data.GetType().GetField("itemSlots", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(data)) is ItemSlot[] array) || slotIndex >= array.Length)
				{
					return null;
				}
				return ResolveItemFromSlot(array[slotIndex]);
			}
			catch
			{
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(BackpackWheel), "UpdateCookedAmount")]
	public static class BackpackWheelCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(BackpackWheel __instance, Item item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				object obj;
				if (!((Object)(object)item != (Object)null))
				{
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter == (Object)null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = localCharacter.data;
						obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
					}
				}
				else
				{
					obj = item;
				}
				Item val = (Item)obj;
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkIconForce(__instance.currentlyHeldItem);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheel), "InitWheel")]
	public static class BackpackWheelPatch
	{
		[HarmonyPostfix]
		public static void InitWheelPostfix(BackpackWheel __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				AkUiPatchHelpers.ApplyAkToBackpackWheel(__instance);
				BackpackWheelSlice[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<BackpackWheelSlice>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					AkUiPatchHelpers.ApplyAkToSliceImage(componentsInChildren[i]);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelPatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "SetItemIcon")]
	public static class BackpackWheelSetItemIconPatch
	{
		[HarmonyPostfix]
		public static void SetItemIconPostfix(BackpackWheelSlice __instance, Item iconHolder, ItemInstanceData itemInstanceData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Item val = (((Object)(object)iconHolder != (Object)null) ? iconHolder : AkUiPatchHelpers.ResolveItemFromSlice(__instance));
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] BackpackWheelSetItemIconPatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "SharedInit")]
	public static class BackpackWheelSharedInitPatch
	{
		[HarmonyPostfix]
		public static void SharedInitPostfix(BackpackWheelSlice __instance, BackpackReference bpRef, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				AkUiPatchHelpers.ApplyAkToSliceImage(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] BackpackWheelSharedInitPatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "UpdateCookedAmount")]
	public static class BackpackWheelSliceCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(BackpackWheelSlice __instance, Item item, ItemInstanceData itemInstanceData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Item val = (((Object)(object)item != (Object)null) ? item : AkUiPatchHelpers.ResolveItemFromSlice(__instance));
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkIconForce(__instance.image);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "InitItemSlot")]
	public static class BackpackWheelSlicePatch
	{
		[HarmonyPostfix]
		public static void InitItemSlotPostfix(BackpackWheelSlice __instance, (BackpackReference, byte) slot, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				ItemSlot val = ((BackpackReference)(ref slot.Item1)).GetData().itemSlots[slot.Item2];
				if (val != null && !val.IsEmpty() && ItemPatch.IsBlowgunLike(val.prefab))
				{
					Item val2 = AkUiPatchHelpers.ResolveItemFromSlot(val);
					Item val3 = (((Object)(object)val2 != (Object)null) ? val2 : val.prefab);
					ItemPatch.ApplyAkDisplayIfNeeded(val3);
					ItemPatch.ApplyAkDisplayIfNeeded(val.prefab);
					AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val3);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelSlicePatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(BackpackWheelSlice), "InitStashSlot")]
	public static class BackpackWheelStashSlicePatch
	{
		[HarmonyPostfix]
		public static void InitStashSlotPostfix(BackpackWheelSlice __instance, BackpackReference bpRef, BackpackWheel wheel)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Item val = AkUiPatchHelpers.ResolveItemFromSlice(__instance);
				if ((Object)(object)val == (Object)null)
				{
					Character localCharacter = Character.localCharacter;
					object obj;
					if ((Object)(object)localCharacter == (Object)null)
					{
						obj = null;
					}
					else
					{
						CharacterData data = localCharacter.data;
						obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
					}
					val = (Item)obj;
				}
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkToSliceImage(__instance, val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] BackpackWheelStashSlicePatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch]
	public class BlowgunChargeSoundPatch
	{
		private static MethodInfo _targetMethod;

		private static FieldInfo _castProgressField;

		private static float _lastCastProgress;

		private static bool _hasPlayedGunshot;

		private static MethodBase TargetMethod()
		{
			if (_targetMethod == null)
			{
				Type type = typeof(Item).Assembly.GetType("SFX_Instance");
				if (type != null)
				{
					_targetMethod = type.GetMethod("Play", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(Vector3) }, null);
					if (_targetMethod == null)
					{
						_targetMethod = type.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "Play" && m.GetParameters().Length == 1);
					}
				}
			}
			return _targetMethod;
		}

		private static bool Prefix(object __instance)
		{
			try
			{
				Character localCharacter = Character.localCharacter;
				if ((Object)(object)localCharacter == (Object)null)
				{
					return true;
				}
				if ((Object)(object)localCharacter.player == (Object)null)
				{
					return true;
				}
				CharacterData data = localCharacter.data;
				Item val = (((Object)(object)data != (Object)null) ? data.currentItem : null);
				if ((Object)(object)val == (Object)null || !ItemPatch.IsBlowgunLike(val))
				{
					return true;
				}
				if (_castProgressField == null)
				{
					_castProgressField = ((object)val).GetType().GetField("<castProgress>k__BackingField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (_castProgressField == null)
				{
					return true;
				}
				float num = (float)_castProgressField.GetValue(val);
				bool flag = _lastCastProgress >= 0.99f;
				bool flag2 = num >= 0.99f;
				_lastCastProgress = num;
				if (!flag2)
				{
					_hasPlayedGunshot = false;
					return false;
				}
				if (!flag && flag2 && !_hasPlayedGunshot)
				{
					_hasPlayedGunshot = true;
					return false;
				}
				return false;
			}
			catch (Exception)
			{
			}
			return true;
		}
	}
	[HarmonyPatch]
	public class BlowgunInfiniteUsePatch
	{
		private static MethodBase TargetMethod()
		{
			MethodInfo[] methods = typeof(Item).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name.Contains("Use") || methodInfo.Name.Contains("Fire") || methodInfo.Name.Contains("Shoot"))
				{
					return methodInfo;
				}
			}
			return null;
		}

		private static void Postfix(Item __instance)
		{
			try
			{
				if (!ItemPatch.IsBlowgunLike(__instance, (__instance != null) ? __instance.GetName() : null))
				{
					return;
				}
				MethodInfo methodInfo = (from m in typeof(Item).GetMethods(BindingFlags.Instance | BindingFlags.Public)
					where m.Name == "GetData"
					select m).ToList().FirstOrDefault((MethodInfo m) => m.IsGenericMethod);
				if (methodInfo != null)
				{
					Type type = typeof(Item).Assembly.GetTypes().FirstOrDefault((Type t) => t.Name == "OptionableIntItemData");
					if (type != null)
					{
						MethodInfo methodInfo2 = methodInfo.MakeGenericMethod(type);
						ParameterInfo[] parameters = methodInfo2.GetParameters();
						object[] array = new object[parameters.Length];
						for (int i = 0; i < parameters.Length; i++)
						{
							if (parameters[i].ParameterType == typeof(DataEntryKey))
							{
								array[i] = (object)(DataEntryKey)2;
							}
							else
							{
								array[i] = null;
							}
						}
						object obj = methodInfo2.Invoke(__instance, array);
						if (obj != null)
						{
							FieldInfo field = obj.GetType().GetField("Value", BindingFlags.Instance | BindingFlags.Public);
							if (field != null)
							{
								field.SetValue(obj, 9999);
							}
						}
					}
				}
				Type type2 = ((object)__instance).GetType();
				float num = Plugin.FireInterval?.Value ?? 0.4f;
				FieldInfo field2 = type2.GetField("usingTimePrimary", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field2 != null)
				{
					field2.SetValue(__instance, num);
				}
			}
			catch (Exception)
			{
			}
		}
	}
	[HarmonyPatch(typeof(ItemCooking), "Wreck")]
	public class BlowgunWreckPatch
	{
		private static bool Prefix(ItemCooking __instance)
		{
			try
			{
				Item component = ((Component)__instance).GetComponent<Item>();
				if ((Object)(object)component != (Object)null)
				{
					string name = component.GetName();
					if ((name != null && name.Contains("吹箭筒")) || (name != null && name.Contains("Blowgun")) || (name != null && name.Contains("HealingDart")) || (name != null && name.Contains("Dart")))
					{
						return false;
					}
				}
			}
			catch
			{
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class DartImpactPatch
	{
		private static MethodBase _targetMethod;

		public static MethodBase TargetMethod()
		{
			if (_targetMethod != null)
			{
				return _targetMethod;
			}
			try
			{
				MethodInfo methodInfo = typeof(Item).Assembly.GetType("Action_RaycastDart")?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m)
				{
					if (!string.Equals(m.Name, "RPC_DartImpact", StringComparison.Ordinal))
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					if (parameters.Length != 3 && parameters.Length != 4)
					{
						return false;
					}
					return parameters[0].ParameterType == typeof(int) && parameters[1].ParameterType == typeof(Vector3) && parameters[2].ParameterType == typeof(Vector3);
				});
				if (methodInfo != null)
				{
					_targetMethod = methodInfo;
					return _targetMethod;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[DartImpactPatch] TargetMethod error: " + ex));
			}
			Plugin.Log.LogWarning((object)"[DartImpactPatch] TargetMethod returning null - RPC_DartImpact method not found");
			return null;
		}

		[HarmonyPrefix]
		public static bool DartImpactPrefix(MonoBehaviour __instance, int characterID, Vector3 origin, Vector3 endpoint)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Item componentInParent = ((Component)__instance).GetComponentInParent<Item>();
				if (!Plugin.IsWeaponFeatureEnabled() || (Object)(object)componentInParent == (Object)null || !ItemPatch.IsBlowgunLike(componentInParent))
				{
					return true;
				}
				if (characterID > 0)
				{
					PhotonView val = PhotonView.Find(characterID);
					if ((Object)(object)val != (Object)null)
					{
						Character componentInParent2 = ((Component)val).gameObject.GetComponentInParent<Character>();
						if ((Object)(object)componentInParent2 != (Object)null && (componentInParent2.isZombie || componentInParent2.isBot))
						{
							Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
							Plugin.Instance?.HitZombie(componentInParent2, origin);
							return false;
						}
						if ((Object)(object)componentInParent2 != (Object)null && !componentInParent2.isZombie && !componentInParent2.isBot)
						{
							return false;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[DartImpactPatch] Error: " + ex));
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class LocalDartImpactPatch
	{
		private static MethodBase _targetMethod;

		public static MethodBase TargetMethod()
		{
			if (_targetMethod != null)
			{
				return _targetMethod;
			}
			try
			{
				MethodInfo methodInfo = typeof(Item).Assembly.GetType("Action_RaycastDart")?.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => string.Equals(m.Name, "DartImpact", StringComparison.Ordinal) && m.GetParameters().Length == 3 && m.GetParameters()[0].ParameterType == typeof(Character) && m.GetParameters()[1].ParameterType == typeof(Vector3) && m.GetParameters()[2].ParameterType == typeof(Vector3));
				if (methodInfo != null)
				{
					_targetMethod = methodInfo;
					return _targetMethod;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[LocalDartImpactPatch] TargetMethod error: " + ex));
			}
			Plugin.Log.LogWarning((object)"[LocalDartImpactPatch] TargetMethod returning null - DartImpact method not found");
			return null;
		}

		[HarmonyPrefix]
		public static bool DartImpactPrefix(MonoBehaviour __instance, Character hitCharacter, Vector3 origin, Vector3 endpoint)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Item componentInParent = ((Component)__instance).GetComponentInParent<Item>();
				if (!Plugin.IsWeaponFeatureEnabled() || (Object)(object)componentInParent == (Object)null || !ItemPatch.IsBlowgunLike(componentInParent) || (Object)(object)hitCharacter == (Object)null)
				{
					return true;
				}
				if (hitCharacter.isZombie || hitCharacter.isBot)
				{
					Plugin.HandleZombieDartImpactVisual((Component)__instance, endpoint);
					Plugin.Instance?.HitZombie(hitCharacter, origin);
					return false;
				}
				return false;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[LocalDartImpactPatch] Error: " + ex));
			}
			return true;
		}
	}
	[HarmonyPatch]
	public static class DisableZombieSleepPatch
	{
		private const float DefaultTargetSearchInterval = 10f;

		private const float DefaultSamePlayerBiteCooldown = 5f;

		private const float DefaultPostBiteRecoveryTime = 3f;

		private const int LungeRecoveryState = 5;

		private const float PostBiteRecoverySyncThreshold = 0.45999998f;

		internal const float PostBiteRecoveryFallWindow = 0.45f;

		private const float CloseRangeLungeDistanceScale = 0.35f;

		private const float CloseRangeLungeDistanceMin = 2.75f;

		private const float CloseRangeLungeDistanceMax = 4.25f;

		private const float MinimumChaseBeforeLunge = 0.65f;

		private const float MaximumLungeVerticalDelta = 2.25f;

		private static readonly MethodInfo CharacterFallMethod = AccessTools.Method(typeof(Character), "Fall", new Type[2]
		{
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo StartChasingMethod = AccessTools.Method(typeof(MushroomZombie), "StartChasing", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo StartLungingMethod = AccessTools.Method(typeof(MushroomZombie), "StartLunging", Type.EmptyTypes, (Type[])null);

		private static readonly MethodInfo CanSeeTargetMethod = AccessTools.Method(typeof(MushroomZombie), "CanSeeTarget", new Type[1] { typeof(Character) }, (Type[])null);

		private static readonly FieldInfo LungeRecoveryTimerField = AccessTools.Field(typeof(MushroomZombie), "timeSpentRecoveringFromLunge");

		private static readonly FieldInfo TimeSpentChasingField = AccessTools.Field(typeof(MushroomZombie), "timeSpentChasing");

		private static readonly Dictionary<int, float> PostBiteRecoveryUntilByZombieViewId = new Dictionary<int, float>();

		private static bool UseVanillaBehavior()
		{
			return Plugin.IsVanillaZombieBehaviorDifficultyRuntime();
		}

		private static float GetTargetSearchInterval()
		{
			return Plugin.GetZombieTargetSearchIntervalRuntime();
		}

		private static float GetSamePlayerBiteCooldown()
		{
			return Plugin.GetZombieSamePlayerBiteCooldownRuntime();
		}

		private static float GetPostBiteRecoveryTime()
		{
			return Plugin.GetZombieBiteRecoveryTimeRuntime();
		}

		private static int GetZombieViewId(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null || (Object)(object)((MonoBehaviourPun)zombie).photonView == (Object)null)
			{
				return -1;
			}
			return ((MonoBehaviourPun)zombie).photonView.ViewID;
		}

		private static void ResetLungeRecoveryTimer(MushroomZombie zombie)
		{
			if ((Object)(object)zombie != (Object)null && LungeRecoveryTimerField != null)
			{
				LungeRecoveryTimerField.SetValue(zombie, 0f);
			}
		}

		private static void ClearPostBiteRecoveryOverride(MushroomZombie zombie)
		{
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				PostBiteRecoveryUntilByZombieViewId.Remove(zombieViewId);
			}
			ResetLungeRecoveryTimer(zombie);
		}

		private static void SetPostBiteRecoveryOverride(MushroomZombie zombie, float duration)
		{
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				ResetLungeRecoveryTimer(zombie);
				if (duration <= 0f)
				{
					PostBiteRecoveryUntilByZombieViewId.Remove(zombieViewId);
				}
				else
				{
					PostBiteRecoveryUntilByZombieViewId[zombieViewId] = Time.time + duration;
				}
			}
		}

		private static bool TryGetPostBiteRecoveryOverride(MushroomZombie zombie, out float recoverAtTime)
		{
			recoverAtTime = 0f;
			int zombieViewId = GetZombieViewId(zombie);
			if (zombieViewId >= 0)
			{
				return PostBiteRecoveryUntilByZombieViewId.TryGetValue(zombieViewId, out recoverAtTime);
			}
			return false;
		}

		private static float GetCloseRangeLungeDistance(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null)
			{
				return 2.75f;
			}
			return Mathf.Clamp(zombie.zombieLungeDistance * 0.35f, 2.75f, 4.25f);
		}

		private static float GetTimeSpentChasing(MushroomZombie zombie)
		{
			if ((Object)(object)zombie == (Object)null || TimeSpentChasingField == null)
			{
				return 0f;
			}
			object value = TimeSpentChasingField.GetValue(zombie);
			if (value is float)
			{
				return (float)value;
			}
			return 0f;
		}

		private static bool CanSeeTarget(MushroomZombie zombie, Character target)
		{
			if ((Object)(object)zombie == (Object)null || (Object)(object)target == (Object)null || CanSeeTargetMethod == null)
			{
				return false;
			}
			object obj = CanSeeTargetMethod.Invoke(zombie, new object[1] { target });
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		internal static void ResetRuntimeState()
		{
			PostBiteRecoveryUntilByZombieViewId.Clear();
		}

		[HarmonyPatch(typeof(MushroomZombie), "TryLookForTarget")]
		[HarmonyPrefix]
		private static bool TryLookForTargetPrefix(MushroomZombie __instance)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || (Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null || !((MonoBehaviourPun)__instance).photonView.IsMine)
			{
				return true;
			}
			float targetSearchInterval = GetTargetSearchInterval();
			if (__instance.sinceLookForTarget < targetSearchInterval)
			{
				return false;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				__instance.sinceLookForTarget = 0f;
				return false;
			}
			Character val = null;
			float num = float.MaxValue;
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)component) && !allCharacter.isBot && !allCharacter.data.dead && !allCharacter.data.fullyPassedOut)
				{
					float num2 = Vector3.Distance(allCharacter.Center, component.Center);
					if ((Object)(object)val == (Object)null || num2 < num)
					{
						val = allCharacter;
						num = num2;
					}
				}
			}
			int num3 = (((Object)(object)val == (Object)null) ? (-1) : ((MonoBehaviourPun)val).photonView.ViewID);
			((MonoBehaviourPun)__instance).photonView.RPC("RPCA_SetCurrentTarget", (RpcTarget)0, new object[2] { num3, 0f });
			__instance.sinceLookForTarget = 0f;
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombie), "TryLunge")]
		[HarmonyPrefix]
		private static bool TryLungePrefix(MushroomZombie __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (UseVanillaBehavior())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || StartLungingMethod == null)
			{
				return true;
			}
			Character currentTarget = __instance.currentTarget;
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null || (Object)(object)currentTarget == (Object)null)
			{
				return false;
			}
			if ((int)__instance.currentState != 3 || !component.data.isGrounded || !component.input.sprintIsPressed || !CanSeeTarget(__instance, currentTarget))
			{
				return false;
			}
			if (GetTimeSpentChasing(__instance) < Mathf.Max(__instance.chaseTimeBeforeSprint, 0.65f))
			{
				return false;
			}
			Vector3 center = component.Center;
			Vector3 center2 = currentTarget.Center;
			center.y = 0f;
			center2.y = 0f;
			float num = Vector3.Distance(center, center2);
			float num2 = Mathf.Abs(currentTarget.Center.y - component.Center.y);
			if (num > GetCloseRangeLungeDistance(__instance) || num2 > 2.25f)
			{
				return false;
			}
			StartLungingMethod.Invoke(__instance, null);
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombie), "OnBitCharacter")]
		[HarmonyPostfix]
		private static void OnBitCharacterPostfix(MushroomZombie __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null))
			{
				Character component = ((Component)__instance).GetComponent<Character>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)((MonoBehaviourPun)component).photonView == (Object)null))
				{
					float postBiteRecoveryTime = GetPostBiteRecoveryTime();
					SetPostBiteRecoveryOverride(__instance, postBiteRecoveryTime);
					float num = Mathf.Min(0.45f, postBiteRecoveryTime);
					component.data.fallSeconds = num;
					((MonoBehaviourPun)component).photonView.RPC("RPCA_Fall", (RpcTarget)0, new object[1] { num });
					((MonoBehaviourPun)__instance).photonView.RPC("RPC_SyncState", (RpcTarget)0, new object[4]
					{
						5,
						false,
						num,
						component.data.passedOut
					});
				}
			}
		}

		[HarmonyPatch(typeof(MushroomZombie), "RPC_SyncState")]
		[HarmonyPostfix]
		private static void RpcSyncStatePostfix(MushroomZombie __instance, int state, bool isSprinting, float fallSeconds, bool passedOut)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (state == 5)
			{
				if (fallSeconds <= 0.45999998f)
				{
					SetPostBiteRecoveryOverride(__instance, GetPostBiteRecoveryTime());
				}
				else
				{
					ClearPostBiteRecoveryOverride(__instance);
				}
			}
			else
			{
				ClearPostBiteRecoveryOverride(__instance);
			}
		}

		[HarmonyPatch(typeof(MushroomZombie), "DoLungeRecovery")]
		[HarmonyPrefix]
		private static bool DoLungeRecoveryPrefix(MushroomZombie __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (!TryGetPostBiteRecoveryOverride(__instance, out var recoverAtTime))
			{
				return true;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				ClearPostBiteRecoveryOverride(__instance);
				return true;
			}
			if (component.data.fallSeconds > 0f || component.data.passedOut || component.data.fullyPassedOut)
			{
				return false;
			}
			if (Time.time < recoverAtTime)
			{
				return false;
			}
			ClearPostBiteRecoveryOverride(__instance);
			if (StartChasingMethod == null)
			{
				return true;
			}
			StartChasingMethod.Invoke(__instance, null);
			return false;
		}

		[HarmonyPatch(typeof(MushroomZombieBiteCollider), "OnTriggerEnter")]
		[HarmonyPrefix]
		private static bool BiteColliderPrefix(MushroomZombieBiteCollider __instance, Collider other)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			if (UseVanillaBehavior())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.parentZombie == (Object)null)
			{
				return false;
			}
			float samePlayerBiteCooldown = GetSamePlayerBiteCooldown();
			Character val = default(Character);
			if (Time.time - __instance.lastBitLocalCharacter < samePlayerBiteCooldown || !CharacterRagdoll.TryGetCharacterFromCollider(other, ref val) || !val.IsLocal)
			{
				return false;
			}
			__instance.lastBitLocalCharacter = Time.time;
			if (val.data.isSkeleton)
			{
				val.refs.afflictions.AddStatus((STATUSTYPE)0, __instance.parentZombie.biteInitialInjury / 8f * 2f, false, true, true);
			}
			else
			{
				val.refs.afflictions.AddStatus((STATUSTYPE)0, __instance.parentZombie.biteInitialInjury, false, true, true);
			}
			val.refs.afflictions.AddStatus((STATUSTYPE)10, __instance.parentZombie.biteInitialSpores, false, true, true);
			Affliction_ZombieBite val2 = new Affliction_ZombieBite(__instance.parentZombie.totalBiteSporesTime, __instance.parentZombie.biteDelayBeforeSpores, __instance.parentZombie.biteSporesPerSecond);
			val.refs.afflictions.AddAffliction((Affliction)(object)val2, false);
			CharacterFallMethod?.Invoke(val, new object[2]
			{
				__instance.parentZombie.biteStunTime,
				0f
			});
			__instance.parentZombie.OnBitCharacter(val);
			return false;
		}
	}
	[HarmonyPatch(typeof(UI_UseItemProgress), "UpdateFillAmount")]
	public static class HideUseItemProgressPatch
	{
		private static bool Prefix(UI_UseItemProgress __instance, ref bool __result)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			try
			{
				Character localCharacter = Character.localCharacter;
				object obj;
				if ((Object)(object)localCharacter == (Object)null)
				{
					obj = null;
				}
				else
				{
					CharacterData data = localCharacter.data;
					obj = (((Object)(object)data != (Object)null) ? data.currentItem : null);
				}
				Item val = (Item)obj;
				if ((Object)(object)val != (Object)null && ItemPatch.IsBlowgunLike(val))
				{
					if ((Object)(object)__instance.fill != (Object)null)
					{
						__instance.fill.fillAmount = 0f;
					}
					__result = false;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "UpdateCookedAmount")]
	public static class InventoryItemUiCookColorPatch
	{
		[HarmonyPostfix]
		public static void UpdateCookedAmountPostfix(InventoryItemUI __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Item val = AkUiPatchHelpers.ResolveItemFromInventoryUi(__instance);
				if (!((Object)(object)val == (Object)null) && ItemPatch.IsBlowgunLike(val))
				{
					AkUiPatchHelpers.ApplyAkToInventoryUi(__instance, val);
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "UpdateNameText")]
	public static class InventoryItemUiNamePatch
	{
		[HarmonyPostfix]
		public static void UpdateNameTextPostfix(InventoryItemUI __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				AkUiPatchHelpers.ApplyAkToInventoryUi(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[ShootZombies] InventoryItemUiNamePatch failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(InventoryItemUI), "SetItem")]
	public static class InventoryItemUiPatch
	{
		[HarmonyPostfix]
		public static void SetItemPostfix(InventoryItemUI __instance, ItemSlot slot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)__instance == (Object)null || slot == null || slot.IsEmpty())
			{
				return;
			}
			try
			{
				Item val = AkUiPatchHelpers.ResolveItemFromSlot(slot);
				Item val2 = (((Object)(object)val != (Object)null) ? val : slot.prefab);
				if (ItemPatch.IsBlowgunLike(val2))
				{
					ItemPatch.ApplyAkDisplayIfNeeded(val2);
					if ((Object)(object)slot.prefab != (Object)null)
					{
						ItemPatch.ApplyAkDisplayIfNeeded(slot.prefab);
					}
					AkUiPatchHelpers.ApplyAkToInventoryUi(__instance, val2);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("[ShootZombies] InventoryItemUiPatch failed: " + ex));
			}
		}
	}
	[HarmonyPatch]
	public static class ItemPatch
	{
		private struct SourceVisualCandidate
		{
			public Mesh Mesh;

			public Material[] Materials;

			public Transform Transform;

			public int VertexCount;

			public int Score;

			public string Path;

			public string MeshName;
		}

		[CompilerGenerated]
		private sealed class <EnumerateOriginalItemColliders>d__167 : IEnumerable<Collider>, IEnumerable, IEnumerator<Collider>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Collider <>2__current;

			private int <>l__initialThreadId;

			private Item item;

			public Item <>3__item;

			private Collider[] <>7__wrap1;

			private int <>7__wrap2;

			Collider IEnumerator<Collider>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateOriginalItemColliders>d__167(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>7__wrap1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_007a;
				}
				<>1__state = -1;
				if ((Object)(object)item == (Object)null)
				{
					return false;
				}
				Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren<Collider>(true);
				<>7__wrap1 = componentsInChildren;
				<>7__wrap2 = 0;
				goto IL_0088;
				IL_007a:
				<>7__wrap2++;
				goto IL_0088;
				IL_0088:
				if (<>7__wrap2 < <>7__wrap1.Length)
				{
					Collider val = <>7__wrap1[<>7__wrap2];
					if (!((Object)(object)val == (Object)null) && !IsCustomWeaponCollider(val))
					{
						<>2__current = val;
						<>1__state = 1;
						return true;
					}
					goto IL_007a;
				}
				<>7__wrap1 = null;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Collider> IEnumerable<Collider>.GetEnumerator()
			{
				<EnumerateOriginalItemColliders>d__167 <EnumerateOriginalItemColliders>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateOriginalItemColliders>d__ = this;
				}
				else
				{
					<EnumerateOriginalItemColliders>d__ = new <EnumerateOriginalItemColliders>d__167(0);
				}
				<EnumerateOriginalItemColliders>d__.item = <>3__item;
				return <EnumerateOriginalItemColliders>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Collider>)this).GetEnumerator();
			}
		}

		private const string LocalVisualName = "AK_VisualRoot";

		private const string VisualCloneName = "AK_LocalVisualClone";

		private const string SimpleVisualName = "AK47Model";

		private const string MuzzleMarkerName = "AK_MuzzleMarker";

		private const string WorldColliderName = "AK_WorldCollider";

		private const string HeldLegacyVisualName = "AK47_HeldLegacyModel";

		private const string InPlaceVisualRootName = "AK_InPlaceVisualRoot";

		private const string HeldDebugSphereName = "AK_HeldDebugSphere";

		private static readonly Quaternion HeldLegacyRotationOffset = Quaternion.identity;

		private static readonly Vector3 HeldLegacyPositionOffset = new Vector3(-0.01f, 0.01f, 0f);

		private static readonly Quaternion InPlaceYawOffset = Quaternion.Euler(0f, 0f, 0f);

		private static readonly string[] SelectableWeaponKeywords = new string[4] { "ak47", "mpx", "hk416", "hk417" };

		private const float RuntimeVisualBaseScaleMultiplier = 1.275f;

		private static readonly string[] ItemKeywords = new string[5] { "healingdart", "blowgun", "dart", "吹箭筒", "ak47" };

		private static readonly string[] ExcludedVisualKeywords = new string[9] { "hand", "arm", "finger", "collider", "trigger", "vfx", "effect", "spawn", "holiday" };

		private static readonly Dictionary<int, Renderer[]> HiddenRendererCache = new Dictionary<int, Renderer[]>();

		private static readonly HashSet<int> InPlaceSwappedItemIds = new HashSet<int>();

		private static readonly Dictionary<int, int> PendingSetStateValueByItemId = new Dictionary<int, int>();

		private static readonly Dictionary<int, Character> PendingSetStateHolderByItemId = new Dictionary<int, Character>();

		private const bool UseDebugAnchorSphereVisual = false;

		private static Mesh _debugCubeMesh;

		private static Material[] _debugCubeMaterials;

		private static Mesh _debugSphereMesh;

		private static Material[] _debugSphereMaterials;

		private static Material[] _meshOnlyTestMaterials;

		private static Material[] _cachedDirectAkSharedMaterials;

		private static int _cachedDirectAkSharedMaterialsHash;

		private static string _cachedCombinedWeaponSelection = string.Empty;

		private const bool PreferInPlaceMeshSwap = true;

		private const bool PreferLegacyHeldVisualForLocalPlayer = false;

		private const bool EnableHeldDebugSphereVisual = false;

		private static readonly string[] MainRendererFieldNames = new string[6] { "<mainRenderer>k__BackingField", "mainRenderer", "_mainRenderer", "<MainRenderer>k__BackingField", "MainRenderer", "_MainRenderer" };

		private static readonly string[] MainRendererPropertyNames = new string[2] { "mainRenderer", "MainRenderer" };

		private static readonly string[] AddtlRendererFieldNames = new string[6] { "<addtlRenderers>k__BackingField", "addtlRenderers", "_addtlRenderers", "<AddtlRenderers>k__BackingField", "AddtlRenderers", "_AddtlRenderers" };

		internal static string DisplayName => Plugin.GetCurrentWeaponDisplayName();

		private static Quaternion GetDirectAkRotationOverride()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Plugin.GetDirectAkRotationOverride();
		}

		private static float GetDirectAkScaleMultiplier(string selection = null)
		{
			return Plugin.GetEffectiveWeaponModelScale(string.IsNullOrWhiteSpace(selection) ? Plugin.GetCurrentWeaponSelection() : selection);
		}

		private static Vector3 GetDirectAkPositionOverride(string selection = null)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return Plugin.GetDirectAkPositionOverride(string.IsNullOrWhiteSpace(selection) ? Plugin.GetCurrentWeaponSelection() : selection);
		}

		private static string DescribeItemForDiagnostics(Item item)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected I4, but got Unknown
			if ((Object)(object)item == (Object)null)
			{
				return "item=null";
			}
			string text = ((((Object)((Component)item).gameObject).name ?? string.Empty) + "/" + (((Object)((Component)item).transform).name ?? string.Empty)).Trim(new char[1] { '/' });
			string text2 = (((Object)(object)item.holderCharacter != (Object)null) ? ((Object)item.holderCharacter).name : null) ?? "null";
			string text3 = item.UIData?.itemName ?? "null";
			return $"name={text}, itemID={item.itemID}, state={(int)item.itemState}, holder={text2}, uiName={text3}";
		}

		private static string DescribeRendererCandidatesForDiagnostics(Item item, int maxEntries = 6)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if ((Object)(object)item == (Object)null)
			{
				return "no-item";
			}
			List<string> list = new List<string>();
			Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Mesh rendererMesh = GetRendererMesh(val);
					string item2 = string.Format("{0}|renderer={1}|mesh={2}|verts={3}", GetTransformPath(((Component)val).transform), ((Object)val).name, ((Object)rendererMesh != (Object)null) ? ((Object)rendererMesh).name : "null", ((Object)rendererMesh != (Object)null) ? rendererMesh.vertexCount : 0);
					list.Add(item2);
					if (list.Count >= maxEntries)
					{
						break;
					}
				}
			}
			if (list.Count == 0)
			{
				return "no-renderers";
			}
			return string.Join(" || ", list);
		}

		[HarmonyPatch(typeof(Item), "OnDestroy")]
		[HarmonyPrefix]
		public static void ItemOnDestroyPrefix(Item __instance)
		{
			CleanupItem(__instance);
		}

		[HarmonyPatch(typeof(Item), "OnEnable")]
		[HarmonyPostfix]
		public static void ItemOnEnablePostfix(Item __instance)
		{
			TryRefreshItem(__instance, forceRefresh: false);
		}

		[HarmonyPatch(typeof(Item), "Start")]
		[HarmonyPostfix]
		public static void ItemStartPostfix(Item __instance)
		{
			TryRefreshItem(__instance, forceRefresh: false);
		}

		[HarmonyPatch(typeof(Item), "SetState")]
		[HarmonyPrefix]
		public static void ItemSetStatePrefix(Item __instance)
		{
			CachePendingSetStateContext(__instance);
		}

		[HarmonyPatch(typeof(Item), "SetState")]
		[HarmonyPostfix]
		public static void ItemSetStatePostfix(Item __instance)
		{
			NotifyDroppedWeaponIfNeeded(__instance);
			TryRefreshItem(__instance, forceRefresh: false);
			try
			{
				ItemUIDataPatch.ForceRefreshVisibleUi();
			}
			catch
			{
			}
		}

		private static void CachePendingSetStateContext(Item item)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			if (!((Object)(object)item == (Object)null))
			{
				int instanceID = ((Object)item).GetInstanceID();
				PendingSetStateValueByItemId[instanceID] = (int)item.itemState;
				Character itemHolderCharacter = GetItemHolderCharacter(item);
				if ((Object)(object)itemHolderCharacter == (Object)null)
				{
					PendingSetStateHolderByItemId.Remove(instanceID);
				}
				else
				{
					PendingSetStateHolderByItemId[instanceID] = itemHolderCharacter;
				}
			}
		}

		private static void NotifyDroppedWeaponIfNeeded(Item item)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			if ((Object)(object)item == (Object)null || !IsBlowgunLike(item))
			{
				return;
			}
			int instanceID = ((Object)item).GetInstanceID();
			Character value = null;
			PendingSetStateValueByItemId.TryGetValue(instanceID, out var value2);
			PendingSetStateHolderByItemId.TryGetValue(instanceID, out value);
			PendingSetStateValueByItemId.Remove(instanceID);
			PendingSetStateHolderByItemId.Remove(instanceID);
			if (value2 == 1 && !((Object)(object)value == (Object)null) && !value.isBot && !value.isZombie)
			{
				Character itemHolderCharacter = GetItemHolderCharacter(item);
				if ((int)item.itemState != 1 && ((Object)(object)itemHolderCharacter == (Object)null || !((Object)(object)itemHolderCharacter == (Object)(object)value) || IsDroppedWorldItem(item)))
				{
					Plugin.NotifyWeaponDropped(value);
				}
			}
		}

		private static Character GetItemHolderCharacter(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			if (!((Object)(object)item.trueHolderCharacter != (Object)null))
			{
				return item.holderCharacter;
			}
			return item.trueHolderCharacter;
		}

		[HarmonyPatch(typeof(Item), "GetName")]
		[HarmonyPostfix]
		public static void GetNamePostfix(Item __instance, ref string __result)
		{
			if (IsBlowgunLike(__instance, __result))
			{
				__result = Plugin.GetItemWeaponDisplayName(__instance);
			}
		}

		[HarmonyPatch(typeof(Item), "GetItemName")]
		[HarmonyPostfix]
		public static void GetItemNamePostfix(Item __instance, ref string __result)
		{
			if (IsBlowgunLike(__instance, __result))
			{
				__result = Plugin.GetItemWeaponDisplayName(__instance);
			}
		}

		public static int EnsureAkVisualOnAllItems(bool forceRefresh = false)
		{
			int num = 0;
			Item[] array = Object.FindObjectsByType<Item>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				if (EnsureAkVisual(array[i], forceRefresh))
				{
					num++;
				}
			}
			return num;
		}

		public static bool EnsureAkMeshSwap(Item item, bool forceRefreshMarker = false)
		{
			return EnsureAkVisual(item, forceRefreshMarker);
		}

		public static bool EnsureAkVisual(Item item, bool forceRefreshMarker = false)
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			if (!ShouldProcessRuntimeItem(item))
			{
				return false;
			}
			if (!IsBlowgunLike(item))
			{
				RestoreOriginalVisual(item);
				CleanupSimpleAkVisual(item);
				DestroyLegacyHeldVisual(item, restoreRenderers: true);
				return false;
			}
			ApplyAkDisplay(item);
			Transform val = ResolveTargetVisualRoot(item);
			bool flag = HasReplacementVisualSource(item);
			if ((Object)(object)val == (Object)null || !flag)
			{
				Plugin.LogDiagnosticOnce("ak-ensure-abort:" + ((Object)item).GetInstanceID(), $"EnsureAkVisual aborted: {DescribeItemForDiagnostics(item)}, targetRoot={GetTransformPath(val)}, hasReplacementSource={flag}, prefab={Plugin.DescribeAkVisualPrefabForDiagnostics(Plugin.GetWeaponSelectionForItem(item))}");
				RestoreOriginalVisual(item);
				CleanupSimpleAkVisual(item);
				DestroyLegacyHeldVisual(item, restoreRenderers: true);
				return false;
			}
			if (forceRefreshMarker)
			{
				RestoreOriginalVisual(item);
				CleanupSimpleAkVisual(item);
			}
			DestroyLegacyHeldVisual(item, restoreRenderers: false);
			RestoreInPlaceVisual(item);
			InPlaceSwappedItemIds.Remove(((Object)item).GetInstanceID());
			if (ShouldUseSeparateLocalFirstPersonVisual(item))
			{
				AkLocalVisualMarker componentInChildren = ((Component)item).GetComponentInChildren<AkLocalVisualMarker>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					Object.Destroy((Object)((Component)componentInChildren).gameObject);
				}
				CleanupSimpleAkVisual(item);
				HideOriginalRenderers(item, val);
				SyncWeaponColliderState(item, null);
				return true;
			}
			Transform orCreateSimpleAkVisual = GetOrCreateSimpleAkVisual(item, val, forceRefreshMarker);
			if ((Object)(object)orCreateSimpleAkVisual == (Object)null)
			{
				Plugin.LogDiagnosticOnce("ak-ensure-create-fail:" + ((Object)item).GetInstanceID(), "GetOrCreateSimpleAkVisual failed: " + DescribeItemForDiagnostics(item) + ", targetRoot=" + GetTransformPath(val) + ", prefab=" + Plugin.DescribeAkVisualPrefabForDiagnostics(Plugin.GetWeaponSelectionForItem(item)));
				RestoreOriginalVisual(item);
				return false;
			}
			if (ShouldShowSimpleAkVisual(item))
			{
				HideOriginalRenderers(item, val);
				SetCustomVisualRenderersVisible(orCreateSimpleAkVisual, visible: true);
				SyncWeaponColliderState(item, null);
			}
			else
			{
				SetCustomVisualRenderersVisible(orCreateSimpleAkVisual, visible: false);
				RestoreOriginalVisual(item);
			}
			InPlaceSwappedItemIds.Remove(((Object)item).GetInstanceID());
			return true;
		}

		public static void ApplyAkDisplay(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				ApplyUiData(item, item.UIData);
				if ((Object)(object)item.isSecretlyOtherItemPrefab != (Object)null)
				{
					ApplyUiData(item, item.isSecretlyOtherItemPrefab.UIData);
				}
			}
		}

		internal static void ApplyAkDisplayIfNeeded(Item item)
		{
			if (!((Object)(object)item == (Object)null) && IsBlowgunLike(item))
			{
				ApplyAkDisplay(item);
			}
		}

		public static bool IsBlowgunLike(Item item, string knownDisplayName = null)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)item).GetComponentInChildren<AkLocalVisualMarker>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponentInChildren<AkInPlaceMarker>(true) != (Object)null)
			{
				return true;
			}
			if ((Object)(object)((Component)item).GetComponentInChildren<AkHeldLegacyVisualMarker>(true) != (Object)null)
			{
				return true;
			}
			if (item.itemID == 70)
			{
				return true;
			}
			if ((