Decompiled source of How to Karambit v1.1.0

KeyErrorFinn.Karambit.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("KeyErrorFinn.Karambit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+bc04d73ae4fad07de8140ae2c99315816af218cb")]
[assembly: AssemblyProduct("How to Karambit")]
[assembly: AssemblyTitle("KeyErrorFinn.Karambit")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace KeyErrorFinn.Karambit
{
	[HarmonyPatch(typeof(Item), "Awake")]
	internal static class ItemAwakePatch
	{
		private static void Postfix(Item __instance)
		{
			KarambitPlugin.Instance?.Replacer.TryReplace(__instance);
		}
	}
	[HarmonyPatch(typeof(Item), "OnPickUp")]
	internal static class ItemOnPickUpPatch
	{
		private static void Postfix(Item __instance)
		{
			KarambitPlugin.Instance?.Replacer.TryReplace(__instance);
		}
	}
	[HarmonyPatch(typeof(Item), "OnCurSkinChange")]
	internal static class ItemSkinPatch
	{
		private static void Postfix(Item __instance, byte next, bool asServer)
		{
			if (!asServer)
			{
				KarambitReplacer obj = KarambitPlugin.Instance?.Replacer;
				obj?.TryReplace(__instance);
				obj?.RefreshSkin(__instance, next);
				obj?.RefreshInventoryPreviews(__instance, next);
			}
		}
	}
	[HarmonyPatch(typeof(InventorySlot), "SetItem")]
	internal static class InventorySlotSetItemPatch
	{
		private static void Postfix(InventorySlot __instance, Item item)
		{
			KarambitPlugin.Instance?.Replacer.RefreshInventoryPreview(__instance, item, ((Object)(object)item != (Object)null) ? item.CurSkin : 0);
		}
	}
	[HarmonyPatch(typeof(InventorySlot), "ApplySkin")]
	internal static class InventorySlotApplySkinPatch
	{
		private static void Postfix(InventorySlot __instance, Item item)
		{
			KarambitPlugin.Instance?.Replacer.RefreshInventoryPreview(__instance, item, ((Object)(object)item != (Object)null) ? item.CurSkin : 0);
		}
	}
	internal sealed class KarambitInventoryPreview : MonoBehaviour
	{
		private const string PreviewName = "KeyErrorFinn Karambit Inventory Preview";

		private GameObject _root;

		private KarambitModel _model;

		internal static KarambitInventoryPreview GetOrCreate(MeshFilter filter)
		{
			KarambitInventoryPreview component = ((Component)filter).GetComponent<KarambitInventoryPreview>();
			if (!((Object)(object)component != (Object)null))
			{
				return ((Component)filter).gameObject.AddComponent<KarambitInventoryPreview>();
			}
			return component;
		}

		internal static void Clear(MeshFilter filter, Item item)
		{
			if ((Object)(object)filter == (Object)null)
			{
				return;
			}
			KarambitInventoryPreview component = ((Component)filter).GetComponent<KarambitInventoryPreview>();
			if (!((Object)(object)component == (Object)null))
			{
				component.RemovePreview();
				if ((Object)(object)item != (Object)null)
				{
					filter.sharedMesh = item.Mesh;
				}
			}
		}

		internal KarambitModel Apply(Material sourceMaterial, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset, Vector3 position, Vector3 rotation, float scale)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root == (Object)null)
			{
				_root = new GameObject("KeyErrorFinn Karambit Inventory Preview")
				{
					hideFlags = (HideFlags)52
				};
				_root.transform.SetParent(((Component)this).transform, false);
				_root.layer = ((Component)this).gameObject.layer;
			}
			ApplyTransform(position, rotation, scale);
			if (_model == null)
			{
				_model = ObjKarambitModel.Create(_root.transform, sourceMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset);
			}
			else
			{
				ObjKarambitModel.ApplyMaterialMode(_model.BladeRenderer, _model.HandleRenderer, sourceMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset);
			}
			return _model;
		}

		internal void ApplyTransform(Vector3 position, Vector3 rotation, float scale)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_root == (Object)null))
			{
				_root.transform.localPosition = position;
				_root.transform.localRotation = Quaternion.Euler(rotation);
				_root.transform.localScale = Vector3.one * Mathf.Max(0.01f, scale);
			}
		}

		private void RemovePreview()
		{
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(false);
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_model = null;
		}

		private void OnDestroy()
		{
			RemovePreview();
		}
	}
	internal static class KarambitMeshFactory
	{
		internal static Mesh Create()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh
			{
				name = "KeyErrorFinn Karambit Mesh"
			};
			Combine(val, CreateCurvedBlade(), CreateBox(-0.075f, 0.03f, 0.075f, 0.32f, 0.075f), CreateTorus(0.085f, 0.022f, 20, 7, new Vector3(0f, 0.02f, 0f)), CreateBox(-0.105f, 0.285f, 0.105f, 0.335f, 0.075f));
			val.RecalculateNormals();
			val.RecalculateBounds();
			Bounds bounds = val.bounds;
			Vector2[] array = (Vector2[])(object)new Vector2[val.vertexCount];
			for (int i = 0; i < val.vertexCount; i++)
			{
				Vector3 val2 = val.vertices[i];
				array[i] = new Vector2(Mathf.InverseLerp(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x, val2.x), Mathf.InverseLerp(((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y, val2.y));
			}
			val.uv = array;
			return val;
		}

		private static Mesh CreateCurvedBlade()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			Vector2[] array = (Vector2[])(object)new Vector2[7]
			{
				new Vector2(0f, 0.29f),
				new Vector2(0.2f, 0.4f),
				new Vector2(0.34f, 0.58f),
				new Vector2(0.32f, 0.77f),
				new Vector2(0.16f, 0.94f),
				new Vector2(-0.08f, 1.02f),
				new Vector2(-0.28f, 0.93f)
			};
			Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length * 4];
			List<int> triangles = new List<int>();
			Vector2 val2 = default(Vector2);
			for (int i = 0; i < array.Length; i++)
			{
				Vector2 val = ((i == 0) ? (array[1] - array[0]) : ((i == array.Length - 1) ? (array[i] - array[i - 1]) : (array[i + 1] - array[i - 1])));
				((Vector2)(ref val)).Normalize();
				((Vector2)(ref val2))..ctor(0f - val.y, val.x);
				float num = Mathf.Lerp(1f, 0.12f, (float)i / (float)(array.Length - 1));
				Vector2 val3 = array[i] + val2 * 0.055f * num;
				Vector2 val4 = array[i] - val2 * 0.055f * num;
				int num2 = i * 4;
				array2[num2] = new Vector3(val3.x, val3.y, -0.0175f);
				array2[num2 + 1] = new Vector3(val4.x, val4.y, -0.0175f);
				array2[num2 + 2] = new Vector3(val3.x, val3.y, 0.0175f);
				array2[num2 + 3] = new Vector3(val4.x, val4.y, 0.0175f);
			}
			for (int j = 0; j < array.Length - 1; j++)
			{
				int num3 = j * 4;
				int num4 = num3 + 4;
				AddQuad(triangles, num3, num4, num4 + 1, num3 + 1);
				AddQuad(triangles, num3 + 2, num3 + 3, num4 + 3, num4 + 2);
				AddQuad(triangles, num3, num3 + 2, num4 + 2, num4);
				AddQuad(triangles, num3 + 1, num4 + 1, num4 + 3, num3 + 3);
			}
			AddQuad(triangles, 0, 1, 3, 2);
			int num5 = (array.Length - 1) * 4;
			AddQuad(triangles, num5, num5 + 2, num5 + 3, num5 + 1);
			return Finish("Karambit Curved Blade", array2, triangles);
		}

		private static Mesh CreateBox(float xMin, float yMin, float xMax, float yMax, float depth)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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)
			Vector3[] vertices = (Vector3[])(object)new Vector3[8]
			{
				new Vector3(xMin, yMin, (0f - depth) / 2f),
				new Vector3(xMax, yMin, (0f - depth) / 2f),
				new Vector3(xMax, yMax, (0f - depth) / 2f),
				new Vector3(xMin, yMax, (0f - depth) / 2f),
				new Vector3(xMin, yMin, depth / 2f),
				new Vector3(xMax, yMin, depth / 2f),
				new Vector3(xMax, yMax, depth / 2f),
				new Vector3(xMin, yMax, depth / 2f)
			};
			List<int> triangles = new List<int>();
			AddQuad(triangles, 0, 3, 2, 1);
			AddQuad(triangles, 4, 5, 6, 7);
			AddQuad(triangles, 0, 4, 7, 3);
			AddQuad(triangles, 1, 2, 6, 5);
			AddQuad(triangles, 3, 7, 6, 2);
			AddQuad(triangles, 0, 1, 5, 4);
			return Finish("Karambit Handle", vertices, triangles);
		}

		private static Mesh CreateTorus(float radius, float tube, int segments, int sides, Vector3 offset)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<int> triangles = new List<int>();
			for (int i = 0; i < segments; i++)
			{
				float num = (float)i / (float)segments * (float)Math.PI * 2f;
				for (int j = 0; j < sides; j++)
				{
					float num2 = (float)j / (float)sides * (float)Math.PI * 2f;
					float num3 = radius + tube * Mathf.Cos(num2);
					list.Add(offset + new Vector3(Mathf.Cos(num) * num3, Mathf.Sin(num) * num3, tube * Mathf.Sin(num2)));
				}
			}
			for (int k = 0; k < segments; k++)
			{
				for (int l = 0; l < sides; l++)
				{
					int a = k * sides + l;
					int b = (k + 1) % segments * sides + l;
					int c = (k + 1) % segments * sides + (l + 1) % sides;
					int d = k * sides + (l + 1) % sides;
					AddQuad(triangles, a, b, c, d);
				}
			}
			return Finish("Karambit Finger Ring", list.ToArray(), triangles);
		}

		private static Mesh Finish(string name, Vector3[] vertices, List<int> triangles)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			Mesh val = new Mesh
			{
				name = name,
				hideFlags = (HideFlags)52,
				vertices = vertices,
				triangles = triangles.ToArray()
			};
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private static void AddQuad(List<int> triangles, int a, int b, int c, int d)
		{
			triangles.Add(a);
			triangles.Add(b);
			triangles.Add(c);
			triangles.Add(a);
			triangles.Add(c);
			triangles.Add(d);
		}

		private static void Combine(Mesh destination, params Mesh[] parts)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			CombineInstance[] array = (CombineInstance[])(object)new CombineInstance[parts.Length];
			for (int i = 0; i < parts.Length; i++)
			{
				int num = i;
				CombineInstance val = default(CombineInstance);
				((CombineInstance)(ref val)).mesh = parts[i];
				array[num] = val;
			}
			destination.CombineMeshes(array, true, false);
			for (int j = 0; j < parts.Length; j++)
			{
				Object.Destroy((Object)(object)parts[j]);
			}
		}
	}
	[BepInPlugin("com.keyerrorfinn.karambit", "How to Karambit", "1.1.0")]
	public sealed class KarambitPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.keyerrorfinn.karambit";

		public const string PluginName = "How to Karambit";

		public const string PluginVersion = "1.1.0";

		private ConfigEntry<bool> _enabled;

		private ConfigEntry<bool> _alternatePose;

		private ConfigEntry<KeyboardShortcut> _menuToggleHotkey;

		private ConfigEntry<bool> _useOriginalTexture;

		private bool _showMenu;

		private static readonly MethodInfo UpdateInventoryCameraMethod = AccessTools.Method(typeof(PlayerInventory), "UpdateInventoryCamera", (Type[])null, (Type[])null);

		internal static KarambitPlugin Instance { get; private set; }

		internal KarambitReplacer Replacer { get; private set; }

		private void Awake()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Karambit", "Enabled", true, "Replace the held knife mesh with the karambit.");
			_alternatePose = ((BaseUnityPlugin)this).Config.Bind<bool>("Karambit", "Use alternate pose", false, "Use the alternate karambit grip pose.");
			_useOriginalTexture = ((BaseUnityPlugin)this).Config.Bind<bool>("Karambit", "Use original texture", false, "Use the model's original texture on the whole karambit instead of applying the selected knife skin to its blade and ring.");
			_menuToggleHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Karambit", "Toggle menu hotkey", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Open or close the karambit settings menu.");
			Replacer = new KarambitReplacer(((BaseUnityPlugin)this).Logger, _enabled, _alternatePose, _useOriginalTexture, ((BaseUnityPlugin)this).Config.Bind<float>("Skin pattern", "UV scale", 1f, "Scale applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind<float>("Skin pattern", "UV rotation", -60f, "Rotation applied to the knife skin pattern."), ((BaseUnityPlugin)this).Config.Bind<Vector2>("Skin pattern", "UV offset", new Vector2(0.2f, 0.2f), "Offset applied to the knife skin pattern."));
			new Harmony("com.keyerrorfinn.karambit").PatchAll(typeof(KarambitPlugin).Assembly);
			Replacer.ApplyMaterialMode();
			Replacer.ApplyEnabledState();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"How to Karambit 1.1.0 loaded.");
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _menuToggleHotkey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				_showMenu = !_showMenu;
			}
			if (_showMenu && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)))
			{
				if (Input.GetKeyDown((KeyCode)275))
				{
					SetPose(!_alternatePose.Value, save: true);
				}
				else if (Input.GetKeyDown((KeyCode)276))
				{
					SetMaterialMode(!_useOriginalTexture.Value, save: true);
				}
				else if (Input.GetKeyDown((KeyCode)274))
				{
					SetEnabled(!_enabled.Value, save: true);
				}
			}
		}

		private void OnGUI()
		{
			if (_showMenu)
			{
				DrawSettingsMenu();
			}
		}

		private void DrawSettingsMenu()
		{
			//IL_0022: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			float num = ((float)Screen.width - 360f) * 0.5f;
			GUI.Box(new Rect(num, 20f, 360f, 224f), "Karambit settings (F10 closes)");
			GUI.Label(new Rect(num + 14f, 50f, 320f, 20f), "Pose: Ctrl+Right Arrow");
			if (GUI.Button(new Rect(num + 14f, 74f, 150f, 28f), _alternatePose.Value ? "Blade Down" : "Blade Down  ✓"))
			{
				SetPose(alternate: false, save: true);
			}
			if (GUI.Button(new Rect(num + 174f, 74f, 150f, 28f), _alternatePose.Value ? "Blade Up  ✓" : "Blade Up"))
			{
				SetPose(alternate: true, save: true);
			}
			GUI.Label(new Rect(num + 14f, 110f, 320f, 20f), "Material: Ctrl+Left Arrow");
			if (GUI.Button(new Rect(num + 14f, 134f, 150f, 28f), _useOriginalTexture.Value ? "Skins" : "Skins  ✓"))
			{
				SetMaterialMode(useOriginalTexture: false, save: true);
			}
			if (GUI.Button(new Rect(num + 174f, 134f, 150f, 28f), _useOriginalTexture.Value ? "Model Default  ✓" : "Model Default"))
			{
				SetMaterialMode(useOriginalTexture: true, save: true);
			}
			GUI.Label(new Rect(num + 14f, 170f, 320f, 20f), "Knife: Ctrl+Down Arrow");
			if (GUI.Button(new Rect(num + 14f, 194f, 150f, 28f), _enabled.Value ? "Karambit  ✓" : "Karambit"))
			{
				SetEnabled(enabled: true, save: true);
			}
			if (GUI.Button(new Rect(num + 174f, 194f, 150f, 28f), _enabled.Value ? "Default Knife" : "Default Knife  ✓"))
			{
				SetEnabled(enabled: false, save: true);
			}
		}

		private void SetPose(bool alternate, bool save)
		{
			_alternatePose.Value = alternate;
			Replacer?.ApplyLiveTransform();
			if (save)
			{
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void SetMaterialMode(bool useOriginalTexture, bool save)
		{
			_useOriginalTexture.Value = useOriginalTexture;
			Replacer?.ApplyMaterialMode();
			RefreshInventoryCamera();
			((BaseUnityPlugin)this).Logger.LogInfo((object)(useOriginalTexture ? "Karambit material: original model texture." : "Karambit material: original textured handle with selected knife skin on blade and ring."));
			if (save)
			{
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void SetEnabled(bool enabled, bool save)
		{
			_enabled.Value = enabled;
			Replacer?.ApplyEnabledState();
			RefreshInventoryCamera();
			((BaseUnityPlugin)this).Logger.LogInfo((object)(enabled ? "Knife model: karambit." : "Knife model: game default."));
			if (save)
			{
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private static void RefreshInventoryCamera()
		{
			if ((Object)(object)Player.LocalPlayer != (Object)null && (Object)(object)Player.LocalPlayer.Inventory != (Object)null)
			{
				UpdateInventoryCameraMethod?.Invoke(Player.LocalPlayer.Inventory, null);
			}
		}
	}
	internal sealed class KarambitReplacer
	{
		private const string ReplacementName = "KeyErrorFinn Karambit";

		private static readonly MethodInfo ApplySkinToRendererMethod = AccessTools.Method(AccessTools.TypeByName("ShaderManager"), "ApplyItemSkin", new Type[3]
		{
			typeof(ItemSkin),
			typeof(Renderer),
			typeof(bool)
		}, (Type[])null);

		private static readonly FieldInfo InHandHolderField = AccessTools.Field(typeof(Item), "_inHandHolder");

		private static readonly FieldInfo OutOfHandHolderField = AccessTools.Field(typeof(Item), "_outOfHandHolder");

		private static readonly FieldInfo HandModelRightField = AccessTools.Field(typeof(Item), "_handModelRight");

		private static readonly FieldInfo HandModelLeftField = AccessTools.Field(typeof(Item), "_handModelLeft");

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

		private static readonly FieldInfo InventoryRendererField = AccessTools.Field(typeof(InventorySlot), "_renderer");

		private readonly ManualLogSource _logger;

		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<bool> _alternatePose;

		private readonly ConfigEntry<bool> _useOriginalTexture;

		private readonly ConfigEntry<float> _skinUvScale;

		private readonly ConfigEntry<float> _skinUvRotation;

		private readonly ConfigEntry<Vector2> _skinUvOffset;

		private static readonly Vector3 BladeDownPosition = new Vector3(1.06f, -1.76f, 1.74f);

		private static readonly Vector3 BladeDownRotation = new Vector3(183.49f, -442.97f, 200f);

		private static readonly Vector3 BladeUpPosition = new Vector3(0.22f, 1.51f, 2.75f);

		private static readonly Vector3 BladeUpRotation = new Vector3(183.7f, -260.97f, 0f);

		private static readonly Vector3 InventoryPosition = new Vector3(0.87f, -0.05f, 0f);

		private static readonly Vector3 InventoryRotation = new Vector3(179f, 90f, -80f);

		private const float KarambitScale = 0.875f;

		private const float InventoryScale = 0.72f;

		private Vector3 CurrentPosition
		{
			get
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!_alternatePose.Value)
				{
					return BladeDownPosition;
				}
				return BladeUpPosition;
			}
		}

		private Vector3 CurrentRotation
		{
			get
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!_alternatePose.Value)
				{
					return BladeDownRotation;
				}
				return BladeUpRotation;
			}
		}

		internal KarambitReplacer(ManualLogSource logger, ConfigEntry<bool> enabled, ConfigEntry<bool> alternatePose, ConfigEntry<bool> useOriginalTexture, ConfigEntry<float> skinUvScale, ConfigEntry<float> skinUvRotation, ConfigEntry<Vector2> skinUvOffset)
		{
			_logger = logger;
			_enabled = enabled;
			_alternatePose = alternatePose;
			_useOriginalTexture = useOriginalTexture;
			_skinUvScale = skinUvScale;
			_skinUvRotation = skinUvRotation;
			_skinUvOffset = skinUvOffset;
		}

		internal void TryReplace(Item item)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if (!_enabled.Value || (Object)(object)item == (Object)null || !IsKnife(item))
			{
				return;
			}
			if (HasReplacement(((Component)item).transform))
			{
				RefreshExistingSkin(item);
				return;
			}
			Transform val = FindDeepChild(((Component)item).transform, "KnifeAnimated");
			Transform val2 = (((Object)(object)val != (Object)null) ? FindDeepChild(val, "r_IK") : null);
			Transform val3 = (((Object)(object)val2 != (Object)null) ? FindDirectChild(val2, "Knife") : null);
			if ((Object)(object)val3 == (Object)null)
			{
				_logger.LogWarning((object)("Found knife item '" + ((Object)item).name + "', but could not find KnifeAnimated/r_IK/Knife."));
				return;
			}
			SkinnedMeshRenderer val4 = FindVanillaKnifeRenderer(val);
			if ((Object)(object)val4 == (Object)null)
			{
				_logger.LogWarning((object)"Found the right knife bone, but no vanilla SkinnedMeshRenderer named Knife.");
				return;
			}
			GameObject val5 = new GameObject("KeyErrorFinn Karambit")
			{
				hideFlags = (HideFlags)52
			};
			val5.transform.SetParent(val3, false);
			val5.transform.localPosition = CurrentPosition;
			val5.transform.localRotation = Quaternion.Euler(CurrentRotation);
			val5.transform.localScale = Vector3.one * 25f * 0.875f;
			KarambitModel karambitModel = ObjKarambitModel.Create(val5.transform, ((Renderer)val4).material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value);
			SkinnedMeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val6 in componentsInChildren)
			{
				if (string.Equals(((Object)((Component)val6).gameObject).name, "Knife", StringComparison.Ordinal))
				{
					((Renderer)val6).enabled = false;
				}
			}
			if (!_useOriginalTexture.Value)
			{
				ApplyCurrentSkin(item, karambitModel.BladeRenderer);
			}
			_logger.LogInfo((object)("Replaced knife mesh on '" + ((Object)item).name + "'. Blade shader: " + ((Object)karambitModel.BladeRenderer.material.shader).name + "; handle shader: " + ((Object)karambitModel.HandleRenderer.material.shader).name + "."));
		}

		internal void ApplyLiveTransform()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
			foreach (Transform val in array)
			{
				if (string.Equals(((Object)val).name, "KeyErrorFinn Karambit", StringComparison.Ordinal))
				{
					val.localPosition = CurrentPosition;
					val.localRotation = Quaternion.Euler(CurrentRotation);
					val.localScale = Vector3.one * 25f * 0.875f;
				}
			}
		}

		internal void RefreshSkin(Item item, byte skinIndex)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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)
			if (_enabled.Value && !_useOriginalTexture.Value && !((Object)(object)item == (Object)null) && IsKnife(item))
			{
				Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade");
				Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
				if (!((Object)(object)val == (Object)null) && ApplySkin(item, skinIndex, val))
				{
					ItemSkin val2 = item.SkinPreset.Skins[skinIndex];
					_logger.LogInfo((object)$"Applied knife skin {skinIndex} '{((ItemSkin)(ref val2)).Name}' to karambit blade (UseSkin={((ItemSkin)(ref val2)).UseSkin}, Rainbow={((ItemSkin)(ref val2)).IsRainbowSkin}, Affects={((ItemSkin)(ref val2)).SkinAffects}).");
				}
			}
		}

		internal void ApplyMaterialMode()
		{
			Item[] array = Resources.FindObjectsOfTypeAll<Item>();
			foreach (Item val in array)
			{
				if ((Object)(object)val != (Object)null && IsKnife(val) && HasReplacement(((Component)val).transform))
				{
					ApplyMaterialMode(val);
				}
			}
			RefreshAllInventoryPreviews();
		}

		internal void ApplyEnabledState()
		{
			Item[] array = Resources.FindObjectsOfTypeAll<Item>();
			foreach (Item val in array)
			{
				if ((Object)(object)val == (Object)null || !IsKnife(val))
				{
					continue;
				}
				Transform animated = FindDeepChild(((Component)val).transform, "KnifeAnimated");
				Transform val2 = FindDeepChild(((Component)val).transform, "KeyErrorFinn Karambit");
				if (_enabled.Value)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						TryReplace(val);
						continue;
					}
					((Component)val2).gameObject.SetActive(true);
					SetVanillaKnifeRenderers(animated, enabled: false);
					ApplyMaterialMode(val);
				}
				else
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Component)val2).gameObject.SetActive(false);
					}
					SetVanillaKnifeRenderers(animated, enabled: true);
				}
			}
			RefreshAllInventoryPreviews();
		}

		internal void RefreshInventoryPreview(InventorySlot slot, Item item, int skinIndex)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)slot == (Object)null)
			{
				return;
			}
			object? obj = InventoryFilterField?.GetValue(slot);
			MeshFilter val = (MeshFilter)((obj is MeshFilter) ? obj : null);
			object? obj2 = InventoryRendererField?.GetValue(slot);
			Renderer val2 = (Renderer)((obj2 is Renderer) ? obj2 : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (!_enabled.Value || (Object)(object)item == (Object)null || !IsKnife(item) || (Object)(object)val2 == (Object)null)
			{
				KarambitInventoryPreview.Clear(val, item);
				return;
			}
			KarambitModel karambitModel = KarambitInventoryPreview.GetOrCreate(val).Apply(val2.material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value, InventoryPosition, InventoryRotation, 0.72f);
			val.sharedMesh = null;
			if (!_useOriginalTexture.Value)
			{
				ApplySkin(item, skinIndex, karambitModel.BladeRenderer);
			}
		}

		internal void RefreshInventoryPreviews(Item item, int skinIndex)
		{
			if ((Object)(object)item == (Object)null || !IsKnife(item))
			{
				return;
			}
			InventorySlot[] array = Resources.FindObjectsOfTypeAll<InventorySlot>();
			foreach (InventorySlot val in array)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.Item == (Object)(object)item)
				{
					RefreshInventoryPreview(val, item, skinIndex);
				}
			}
		}

		internal void RefreshAllInventoryPreviews()
		{
			InventorySlot[] array = Resources.FindObjectsOfTypeAll<InventorySlot>();
			foreach (InventorySlot val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					RefreshInventoryPreview(val, val.Item, ((Object)(object)val.Item != (Object)null) ? val.Item.CurSkin : 0);
				}
			}
		}

		private void ApplyMaterialMode(Item item)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			Transform val = FindDeepChild(((Component)item).transform, "KnifeAnimated");
			SkinnedMeshRenderer val2 = (((Object)(object)val != (Object)null) ? FindVanillaKnifeRenderer(val) : null);
			Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade");
			Renderer val3 = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
			Transform obj2 = FindDeepChild(((Component)item).transform, "Karambit Handle");
			Renderer val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<Renderer>() : null);
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null))
			{
				ObjKarambitModel.ApplyMaterialMode(val3, val4, ((Renderer)val2).material, _useOriginalTexture.Value, _skinUvScale.Value, _skinUvRotation.Value, _skinUvOffset.Value);
				if (!_useOriginalTexture.Value)
				{
					ApplyCurrentSkin(item, val3);
				}
			}
		}

		private static bool IsKnife(Item item)
		{
			if (!string.Equals(((Object)item).name, "Knife", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(item.GetName(), "Knife", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		private static Transform FindDirectChild(Transform parent, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (string.Equals(((Object)val).name, name, StringComparison.Ordinal))
				{
					return val;
				}
			}
			return null;
		}

		private static Transform FindDeepChild(Transform parent, string name)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if ((Object)(object)parent == (Object)null)
			{
				return null;
			}
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (string.Equals(((Object)val).name, name, StringComparison.Ordinal))
				{
					return val;
				}
				Transform val2 = FindDeepChild(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static bool HasReplacement(Transform root)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (string.Equals(((Object)componentsInChildren[i]).name, "KeyErrorFinn Karambit", StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		private static SkinnedMeshRenderer FindVanillaKnifeRenderer(Transform animated)
		{
			SkinnedMeshRenderer[] componentsInChildren = ((Component)animated).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				if (string.Equals(((Object)((Component)val).gameObject).name, "Knife", StringComparison.Ordinal))
				{
					return val;
				}
			}
			return null;
		}

		private static void SetVanillaKnifeRenderers(Transform animated, bool enabled)
		{
			if ((Object)(object)animated == (Object)null)
			{
				return;
			}
			SkinnedMeshRenderer[] componentsInChildren = ((Component)animated).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				if (string.Equals(((Object)((Component)val).gameObject).name, "Knife", StringComparison.Ordinal))
				{
					((Renderer)val).enabled = enabled;
				}
			}
		}

		private static void ApplyCurrentSkin(Item item, Renderer bladeRenderer)
		{
			ApplySkin(item, item.CurSkin, bladeRenderer);
		}

		private static bool ApplySkin(Item item, int skinIndex, Renderer bladeRenderer)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			SkinPreset skinPreset = item.SkinPreset;
			IReadOnlyList<ItemSkin> readOnlyList = ((skinPreset != null) ? skinPreset.Skins : null);
			if (readOnlyList == null || skinIndex < 0 || skinIndex >= readOnlyList.Count || (Object)(object)bladeRenderer == (Object)null)
			{
				return false;
			}
			if ((Object)(object)bladeRenderer.sharedMaterial == (Object)null || !string.Equals(((Object)bladeRenderer.sharedMaterial.shader).name, "Shader Graphs/DefaultShader", StringComparison.Ordinal))
			{
				return false;
			}
			ApplySkinToRendererMethod?.Invoke(null, new object[3]
			{
				readOnlyList[skinIndex],
				bladeRenderer,
				false
			});
			return ApplySkinToRendererMethod != null;
		}

		private static void RefreshExistingSkin(Item item)
		{
			Transform obj = FindDeepChild(((Component)item).transform, "Karambit Blade");
			Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				ApplyCurrentSkin(item, val);
			}
		}
	}
	internal sealed class KarambitModel
	{
		internal Renderer BladeRenderer;

		internal Renderer HandleRenderer;
	}
	internal static class ObjKarambitModel
	{
		private static Texture2D _originalTexture;

		private static ObjData _objData;

		internal static KarambitModel Create(Transform parent, Material bladeMaterial, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ObjData objData = GetObjData();
			KarambitModel karambitModel = new KarambitModel();
			karambitModel.BladeRenderer = CreatePart("Karambit Blade", parent, objData.BladeTriangles, objData, null, !useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset);
			karambitModel.HandleRenderer = CreatePart("Karambit Handle", parent, objData.HandleTriangles, objData, null, useKnifeSkinUv: false, 1f, 0f, Vector2.zero);
			ApplyMaterialMode(karambitModel.BladeRenderer, karambitModel.HandleRenderer, bladeMaterial, useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset);
			return karambitModel;
		}

		internal static void ApplyMaterialMode(Renderer blade, Renderer handle, Material source, bool useOriginalTexture, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			RebuildBladeMesh(blade, !useOriginalTexture, skinUvScale, skinUvRotation, skinUvOffset);
			if (useOriginalTexture)
			{
				Material sharedMaterial = (blade.sharedMaterial = CreateOriginalTextureMaterial());
				handle.sharedMaterial = sharedMaterial;
			}
			else
			{
				blade.sharedMaterial = CreateSkinnableBladeMaterial(source);
				handle.sharedMaterial = CreateOriginalTextureMaterial();
			}
		}

		private static Material CreateSkinnableBladeMaterial(Material source)
		{
			//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_002a: 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_0041: Expected O, but got Unknown
			//IL_0042: Expected O, but got Unknown
			Material val = new Material(source)
			{
				name = "Karambit Blade Skin Material"
			};
			Texture2D texture = CreateSolidTexture("Karambit Neutral Normal", new Color(0.5f, 0.5f, 1f, 1f));
			SetTextureIfPresent(val, "_Normal_Map", (Texture)(object)texture);
			return val;
		}

		private static Material CreateOriginalTextureMaterial()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_01a4: Expected O, but got Unknown
			//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)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("UI/Default");
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Could not find a shader for the original karambit texture.");
			}
			if ((Object)(object)_originalTexture == (Object)null)
			{
				string path = ResolveAssetDirectory();
				_originalTexture = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					name = "Original Karambit Texture",
					hideFlags = (HideFlags)52,
					wrapMode = (TextureWrapMode)0,
					filterMode = (FilterMode)1
				};
				MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				}, null);
				if (!(methodInfo != null) || !(bool)methodInfo.Invoke(null, new object[3]
				{
					_originalTexture,
					File.ReadAllBytes(Path.Combine(path, "karambit.png")),
					false
				}))
				{
					throw new InvalidDataException("Could not decode assets/karambit.png.");
				}
			}
			Material val2 = new Material(val)
			{
				name = "Original Karambit Material",
				color = Color.white,
				mainTexture = (Texture)(object)_originalTexture
			};
			SetTextureIfPresent(val2, "_BaseMap", (Texture)(object)_originalTexture);
			SetTextureIfPresent(val2, "_MainTex", (Texture)(object)_originalTexture);
			SetColorIfPresent(val2, "_BaseColor", Color.white);
			SetColorIfPresent(val2, "_Color", Color.white);
			SetFloatIfPresent(val2, "_Metallic", 0.35f);
			SetFloatIfPresent(val2, "_Smoothness", 0.45f);
			return val2;
		}

		private static string ResolveAssetDirectory()
		{
			string location = Assembly.GetExecutingAssembly().Location;
			if (!string.IsNullOrEmpty(location))
			{
				string text = Path.Combine(Path.GetDirectoryName(location), "assets");
				if (File.Exists(Path.Combine(text, "karanbit.obj")))
				{
					return text;
				}
			}
			string text2 = Path.Combine(Paths.BepInExRootPath, "scripts", "assets");
			if (File.Exists(Path.Combine(text2, "karanbit.obj")))
			{
				return text2;
			}
			string text3 = Path.Combine(Paths.PluginPath, "KeyErrorFinn-Karambit", "assets");
			if (File.Exists(Path.Combine(text3, "karanbit.obj")))
			{
				return text3;
			}
			throw new DirectoryNotFoundException("Could not find the Karambit assets directory.");
		}

		private static ObjData GetObjData()
		{
			return _objData ?? (_objData = ObjData.Load(Path.Combine(ResolveAssetDirectory(), "karanbit.obj")));
		}

		internal static void RebuildBladeMesh(Renderer blade, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter component = ((Component)blade).GetComponent<MeshFilter>();
			if (!((Object)(object)component == (Object)null))
			{
				ObjData objData = GetObjData();
				Mesh sharedMesh = component.sharedMesh;
				component.sharedMesh = objData.BuildMesh("Karambit Blade", objData.BladeTriangles, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
				if ((Object)(object)sharedMesh != (Object)null)
				{
					Object.Destroy((Object)(object)sharedMesh);
				}
			}
		}

		private static Texture2D CreateSolidTexture(string name, Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				name = name,
				hideFlags = (HideFlags)52,
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)1
			};
			val.SetPixels((Color[])(object)new Color[4] { color, color, color, color });
			val.Apply(false, true);
			return val;
		}

		private static void SetTextureIfPresent(Material material, string property, Texture texture)
		{
			if (material.HasProperty(property))
			{
				material.SetTexture(property, texture);
			}
		}

		private static void SetFloatIfPresent(Material material, string property, float value)
		{
			if (material.HasProperty(property))
			{
				material.SetFloat(property, value);
			}
		}

		private static void SetColorIfPresent(Material material, string property, Color value)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty(property))
			{
				material.SetColor(property, value);
			}
		}

		private static Renderer CreatePart(string name, Transform parent, List<ObjTriangle> triangles, ObjData data, Material material, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			GameObject val = new GameObject(name)
			{
				hideFlags = (HideFlags)52
			};
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			val.AddComponent<MeshFilter>().sharedMesh = data.BuildMesh(name, triangles, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = material;
			return (Renderer)(object)obj;
		}
	}
	internal sealed class ObjData
	{
		internal readonly List<Vector3> Positions = new List<Vector3>();

		internal readonly List<Vector2> Uvs = new List<Vector2>();

		internal readonly List<ObjTriangle> BladeTriangles = new List<ObjTriangle>();

		internal readonly List<ObjTriangle> HandleTriangles = new List<ObjTriangle>();

		internal static ObjData Load(string path)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			ObjData objData = new ObjData();
			bool flag = true;
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length == 0)
				{
					continue;
				}
				if (array2[0] == "v" && array2.Length >= 4)
				{
					objData.Positions.Add(new Vector3(Parse(array2[1]), Parse(array2[2]), Parse(array2[3])));
				}
				else if (array2[0] == "vt" && array2.Length >= 3)
				{
					objData.Uvs.Add(new Vector2(Parse(array2[1]), Parse(array2[2])));
				}
				else if (array2[0] == "usemtl" && array2.Length >= 2)
				{
					flag = string.Equals(array2[1], "blade", StringComparison.OrdinalIgnoreCase);
				}
				else if (array2[0] == "f" && array2.Length >= 4)
				{
					ObjIndex[] array3 = new ObjIndex[array2.Length - 1];
					for (int j = 1; j < array2.Length; j++)
					{
						array3[j - 1] = ObjIndex.Parse(array2[j]);
					}
					for (int k = 1; k < array3.Length - 1; k++)
					{
						ObjTriangle item = new ObjTriangle(array3[0], array3[k], array3[k + 1]);
						(flag ? objData.BladeTriangles : objData.HandleTriangles).Add(item);
					}
				}
			}
			if (objData.BladeTriangles.Count == 0 || objData.HandleTriangles.Count == 0)
			{
				throw new InvalidDataException("The karambit OBJ must contain both blade and karambit material groups.");
			}
			return objData;
		}

		internal Mesh BuildMesh(string name, List<ObjTriangle> triangles, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			Dictionary<ObjIndex, int> map = new Dictionary<ObjIndex, int>();
			List<Vector3> vertices = new List<Vector3>();
			List<Vector2> list = new List<Vector2>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector2> list3 = new List<Vector2>();
			List<Vector2> list4 = new List<Vector2>();
			List<int> list5 = new List<int>();
			foreach (ObjTriangle triangle in triangles)
			{
				Add(triangle.A, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
				Add(triangle.B, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
				Add(triangle.C, map, vertices, list, list2, list3, list4, list5, useKnifeSkinUv, skinUvScale, skinUvRotation, skinUvOffset);
			}
			Mesh val = new Mesh
			{
				name = name,
				hideFlags = (HideFlags)52
			};
			val.SetVertices(vertices);
			val.SetUVs(0, list);
			val.SetUVs(1, list2);
			val.SetUVs(2, list3);
			val.SetUVs(3, list4);
			val.SetTriangles(list5, 0);
			val.RecalculateNormals();
			val.RecalculateBounds();
			return val;
		}

		private void Add(ObjIndex source, Dictionary<ObjIndex, int> map, List<Vector3> vertices, List<Vector2> uv0, List<Vector2> uv1, List<Vector2> uv2, List<Vector2> uv3, List<int> indices, bool useKnifeSkinUv, float skinUvScale, float skinUvRotation, Vector2 skinUvOffset)
		{
			//IL_002c: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			if (!map.TryGetValue(source, out var value))
			{
				value = vertices.Count;
				map.Add(source, value);
				vertices.Add(Positions[source.Position - 1]);
				Vector2 val = ((source.Uv > 0) ? Uvs[source.Uv - 1] : Vector2.zero);
				if (useKnifeSkinUv)
				{
					uv0.Add(new Vector2(0.9858f, 0.6968f));
					uv1.Add(new Vector2(0.9775f, 0.6334f));
					uv2.Add(new Vector2(0.9858f, 0.5171f));
					Vector2 val2 = TransformPatternUv(new Vector2(Mathf.InverseLerp(0.04f, 0.94f, val.x), Mathf.InverseLerp(0.09f, 0.8f, val.y)), skinUvScale, skinUvRotation, skinUvOffset);
					uv3.Add(new Vector2(Mathf.LerpUnclamped(0.45f, 0.54f, val2.x), Mathf.LerpUnclamped(0.55f, 0.85f, val2.y)));
				}
				else
				{
					uv0.Add(val);
					uv1.Add(val);
					uv2.Add(val);
					uv3.Add(val);
				}
			}
			indices.Add(value);
		}

		private static Vector2 TransformPatternUv(Vector2 uv, float scale, float rotationDegrees, Vector2 offset)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = (uv - new Vector2(0.5f, 0.5f)) * Mathf.Max(0.01f, scale);
			float num = rotationDegrees * ((float)Math.PI / 180f);
			float num2 = Mathf.Cos(num);
			float num3 = Mathf.Sin(num);
			return new Vector2(val.x * num2 - val.y * num3, val.x * num3 + val.y * num2) + new Vector2(0.5f, 0.5f) + offset;
		}

		private static float Parse(string value)
		{
			return float.Parse(value, CultureInfo.InvariantCulture);
		}
	}
	internal struct ObjIndex : IEquatable<ObjIndex>
	{
		internal int Position;

		internal int Uv;

		internal static ObjIndex Parse(string value)
		{
			string[] array = value.Split(new char[1] { '/' });
			return new ObjIndex
			{
				Position = int.Parse(array[0], CultureInfo.InvariantCulture),
				Uv = ((array.Length > 1 && array[1].Length > 0) ? int.Parse(array[1], CultureInfo.InvariantCulture) : 0)
			};
		}

		public bool Equals(ObjIndex other)
		{
			if (Position == other.Position)
			{
				return Uv == other.Uv;
			}
			return false;
		}

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

		public override int GetHashCode()
		{
			return (Position * 397) ^ Uv;
		}
	}
	internal struct ObjTriangle
	{
		internal ObjIndex A;

		internal ObjIndex B;

		internal ObjIndex C;

		internal ObjTriangle(ObjIndex a, ObjIndex b, ObjIndex c)
		{
			A = a;
			B = b;
			C = c;
		}
	}
}