Decompiled source of ResourcefulHands v1.0.1

plugins/monksilly.ResourcefulHands.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
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 System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using HarmonyLib;
using Imui.Controls;
using Imui.Core;
using Imui.IO.Touch;
using Imui.Rendering;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ResourcefulHands.Assets;
using ResourcefulHands.Core;
using ResourcefulHands.EmbedResources;
using ResourcefulHands.Systems;
using ResourcefulHands.UI;
using ResourcefulHands.UI.Imui;
using ResourcefulHands.UI.Imui.Utility;
using ResourcefulHands.Utility;
using Steamworks;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WKLib.API;
using WKLib.API.Audio;
using WKLib.API.Input;
using WKLib.API.UI;
using WKLib.Core.Classes;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("monksilly.ResourcefulHands")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+2f0e205450224a1c5af05f853994627a31300ade")]
[assembly: AssemblyProduct("Resourceful Hands")]
[assembly: AssemblyTitle("monksilly.ResourcefulHands")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ResourcefulHands
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("monksilly.resourcefulhands", "Resourceful Hands", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "monksilly.resourcefulhands";

		public const string Name = "Resourceful Hands";

		public const string Version = "1.0.1";

		public const string DeprecatedRHGuid = "triggeredidiot.wkd.resourcefulhands";

		public GameObject? ofHolder;

		public static WKLibAPI WKLibAPI = WKLibAPI.Create("Resourceful Hands", "monksilly.resourcefulhands");

		internal static int TargetFps = 60;

		private static int _mainThreadId;

		public static Plugin Instance { get; private set; } = null;

		private Harmony? Harmony { get; set; }

		public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

		public static bool IsMainThread => Thread.CurrentThread.ManagedThreadId == _mainThreadId;

		public void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ModLogger.InitLog(((BaseUnityPlugin)this).Logger);
			CheckDeprecation();
			VersionChecker.Check();
			RHConfig.InitConfigs(((BaseUnityPlugin)this).Config);
			Harmony = new Harmony("monksilly.resourcefulhands");
			Harmony.PatchAll();
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Task.Run((Func<Task?>)ResourcePacksManager.InitLoad);
			_mainThreadId = Thread.CurrentThread.ManagedThreadId;
			Instance = this;
			WKLibAPI.AddToModList((ModTab)(object)new ModListTab());
			WKLibAPI.AddWindow((WKLibWindow)(object)WindowsDeclarations.PacksWindow);
			WKLibAPI.AddWindow((WKLibWindow)(object)WindowsDeclarations.SettingsWindow);
			RHResources.InitResources();
			SceneManager.sceneLoaded += SceneHandler.OnSceneLoaded;
			ModLogger.Info("Resourceful Hands has loaded!");
		}

		private void CheckDeprecation()
		{
			if (Chainloader.PluginInfos.ContainsKey("triggeredidiot.wkd.resourcefulhands"))
			{
				PluginInfo val = Chainloader.PluginInfos["triggeredidiot.wkd.resourcefulhands"];
				ModLogger.Warning("Detected deprecated mod [" + val.Metadata.Name + "]. Disabling it...");
				BaseUnityPlugin instance = val.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					((Behaviour)instance).enabled = false;
					Harmony.UnpatchID("triggeredidiot.wkd.resourcefulhands");
					Object.Destroy((Object)(object)((Component)instance).gameObject);
				}
			}
		}
	}
	internal class CoroutineDispatcher : MonoBehaviour
	{
		private static CoroutineDispatcher? _instance;

		private static Dictionary<string, Action> updateActions = new Dictionary<string, Action>();

		public static Queue<Action> threadQueue = new Queue<Action>();

		public static Coroutine? Dispatch(IEnumerator routine)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.IsMainThread)
			{
				RunOnMainThread(delegate
				{
					Dispatch(routine);
				});
				return null;
			}
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = new GameObject("CoroutineDispatcher").AddComponent<CoroutineDispatcher>();
				Object.DontDestroyOnLoad((Object)(object)_instance);
			}
			return ((MonoBehaviour)_instance).StartCoroutine(routine);
		}

		public static bool StopDispatch(Coroutine routine)
		{
			if (!Plugin.IsMainThread)
			{
				RunOnMainThread(delegate
				{
					StopDispatch(routine);
				});
				return false;
			}
			if ((Object)(object)_instance == (Object)null)
			{
				return false;
			}
			((MonoBehaviour)_instance).StopCoroutine(routine);
			return true;
		}

		public static async Task RunOnMainThreadAndWait(Action action)
		{
			bool hasRan = false;
			lock (threadQueue)
			{
				threadQueue.Enqueue(delegate
				{
					try
					{
						action();
					}
					catch (Exception data)
					{
						ModLogger.Error(data);
					}
					hasRan = true;
				});
			}
			int fps = Mathf.Clamp(Plugin.TargetFps, -1, 120);
			if (fps < 1)
			{
				fps = 60;
			}
			while (!hasRan)
			{
				await Task.Delay(Mathf.FloorToInt(1f / (float)fps * 1000f));
			}
		}

		public static void RunOnMainThread(Action action)
		{
			lock (threadQueue)
			{
				threadQueue.Enqueue(action);
			}
		}

		public static void RunOnMainThreadOrCurrent(Action action)
		{
			if (Plugin.IsMainThread)
			{
				action();
				return;
			}
			lock (threadQueue)
			{
				threadQueue.Enqueue(action);
			}
		}

		public static string AddToUpdate(Action action)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = new GameObject("CoroutineDispatcher").AddComponent<CoroutineDispatcher>();
				Object.DontDestroyOnLoad((Object)(object)_instance);
			}
			string text = Guid.NewGuid().ToString();
			lock (updateActions)
			{
				updateActions.Add(text, action);
				return text;
			}
		}

		public static void RemoveFromUpdate(string guid)
		{
			lock (updateActions)
			{
				updateActions.Remove(guid);
			}
		}

		public void LateUpdate()
		{
			lock (updateActions)
			{
				foreach (Action value in updateActions.Values)
				{
					value();
				}
			}
			lock (threadQueue)
			{
				while (threadQueue.Count > 0)
				{
					threadQueue.Dequeue()?.Invoke();
				}
			}
		}
	}
	public class RHDispatcher : MonoBehaviour
	{
		private static RHDispatcher? _instance;

		private static readonly Queue<Action> ExecutionQueue = new Queue<Action>();

		public static void Initialize()
		{
			//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_0027: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_instance))
			{
				GameObject val = new GameObject("RH_Dispatcher");
				_instance = val.AddComponent<RHDispatcher>();
				Object.DontDestroyOnLoad((Object)val);
			}
		}

		public static void RunOnMainThread(Action action)
		{
			lock (ExecutionQueue)
			{
				ExecutionQueue.Enqueue(action);
			}
		}

		private void Update()
		{
			lock (ExecutionQueue)
			{
				while (ExecutionQueue.Count > 0)
				{
					ExecutionQueue.Dequeue()();
				}
			}
		}

		public static Coroutine? StartStaticCoroutine(IEnumerator routine)
		{
			RHDispatcher? instance = _instance;
			if (instance == null)
			{
				return null;
			}
			return ((MonoBehaviour)instance).StartCoroutine(routine);
		}
	}
}
namespace ResourcefulHands.Utility
{
	public static class AudioUtils
	{
		public static AudioClip CreateAudioClip(float[] samples, int sampleRate, int channels, string name = "GeneratedClip")
		{
			int num = samples.Length / channels;
			AudioClip obj = AudioClip.Create(name, num, channels, sampleRate, true);
			obj.SetData(samples, 0);
			return obj;
		}

		public static IEnumerator LoadAudioClipFromFile(string path, Action<AudioClip> callback)
		{
			UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip("file://" + path, (AudioType)20);
			try
			{
				yield return uwr.SendWebRequest();
				if ((int)uwr.result == 1)
				{
					AudioClip content = DownloadHandlerAudioClip.GetContent(uwr);
					((Object)content).name = Path.GetFileNameWithoutExtension(path);
					callback?.Invoke(content);
					yield break;
				}
			}
			finally
			{
				((IDisposable)uwr)?.Dispose();
			}
		}
	}
	public interface ICosmeticPack
	{
		Cosmetic_Info CosmeticInfo { get; set; }

		Texture2D Icon { get; set; }

		bool IsActive { get; set; }
	}
	public class CosmeticHandPack : ICosmeticPack
	{
		public Cosmetic_HandItem_Data CosmeticData { get; set; }

		public ExtendedHandItemData ExtendedCosmeticData { get; set; }

		public Cosmetic_Info CosmeticInfo { get; set; }

		public Texture2D Icon { get; set; }

		public bool IsActive { get; set; }
	}
	public class CosmeticVoicePack : ICosmeticPack
	{
		public Cosmetic_Voice_Data CosmeticData { get; set; }

		public Cosmetic_Info CosmeticInfo { get; set; }

		public Texture2D Icon { get; set; }

		public bool IsActive { get; set; }
	}
	public class ExtendedHandItemData : Cosmetic_HandItem_Data
	{
		public List<EmoteEntry>? emotes { get; set; }
	}
	public enum SoundPlayMode
	{
		Random,
		Sequential
	}
	public enum EmotePlayMode
	{
		Loop,
		LoopGlobal,
		Once
	}
	public class EmoteEntry : HandEmote
	{
		public List<string> SpriteNames { get; set; }

		public List<Sprite> Sprites { get; set; }

		public float Framerate { get; set; } = 1f;

		public EmotePlayMode PlayMode { get; set; }

		public Vector3 Scale { get; set; } = Vector3.one;

		public float Rotation { get; set; }

		public string Sound { get; set; }

		public List<string> SoundFiles { get; set; }

		public List<AudioClip?> SoundClips { get; set; }

		public SoundPlayMode SoundPlayMode { get; set; }

		public bool SoundLoop { get; set; }
	}
	public class PaletteEntry : ColorPalette
	{
	}
	public class SwapSpriteEntry : SwapSprite
	{
	}
	public class InteractSwapEntry : InteractSwap
	{
	}
	public class SecondaryTextureEntry : SecondaryTextures
	{
		public List<string> SecondaryTextureNames { get; set; }
	}
	public static class FileUtils
	{
		public static string GetSHA256Checksum(string filePath)
		{
			using FileStream inputStream = File.OpenRead(filePath);
			using SHA256 sHA = SHA256.Create();
			byte[] array = sHA.ComputeHash(inputStream);
			StringBuilder stringBuilder = new StringBuilder();
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("x2"));
			}
			return stringBuilder.ToString();
		}
	}
	public static class RHExtensions
	{
		public static void WriteString(this Stream stream, string value)
		{
			foreach (char c in value)
			{
				stream.WriteByte((byte)c);
			}
		}

		public static void WriteInteger(this Stream stream, uint value)
		{
			stream.WriteByte((byte)(value & 0xFF));
			stream.WriteByte((byte)((value >> 8) & 0xFF));
			stream.WriteByte((byte)((value >> 16) & 0xFF));
			stream.WriteByte((byte)((value >> 24) & 0xFF));
		}

		public static void WriteShort(this Stream stream, ushort value)
		{
			stream.WriteByte((byte)(value & 0xFF));
			stream.WriteByte((byte)((value >> 8) & 0xFF));
		}

		public static RenderTexture ConvertToARGB32(this RenderTexture self)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)self.format == 0)
			{
				return self;
			}
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)self).width, ((Texture)self).height, 0, (RenderTextureFormat)0);
			Graphics.Blit((Texture)(object)self, temporary);
			return temporary;
		}

		public static string CleanString(string str)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char c in invalidFileNameChars)
			{
				str = str.Replace(c.ToString(), "");
			}
			StringBuilder stringBuilder = new StringBuilder();
			string text = str;
			foreach (char c2 in text)
			{
				if (c2 <= '\u007f')
				{
					stringBuilder.Append(c2);
				}
			}
			return stringBuilder.ToString();
		}
	}
	public class TextUtils
	{
		public static string InsertLineBreaks(string text, int maxLineLength)
		{
			if (string.IsNullOrWhiteSpace(text) || maxLineLength <= 0)
			{
				return string.Empty;
			}
			string[] array = text.Trim().Split(' ');
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				if (num + text2.Length + 1 > maxLineLength)
				{
					stringBuilder.AppendLine();
					num = 0;
				}
				else if (num > 0)
				{
					stringBuilder.Append(' ');
					num++;
				}
				stringBuilder.Append(text2);
				num += text2.Length;
			}
			return stringBuilder.ToString();
		}
	}
	public static class TransformExtensions
	{
		public static Transform? FindParentWithName(this Transform current, string name)
		{
			while ((Object)(object)current != (Object)null && ((Object)current).name != name)
			{
				current = current.parent;
			}
			return current;
		}

		public static Transform? FindTopmostParent(this Transform current)
		{
			while ((Object)(object)current.parent != (Object)null)
			{
				current = current.parent;
			}
			return current;
		}

		public static T? FindAt<T>(this Transform t, string path) where T : Component
		{
			string[] array = path.Split('/');
			foreach (string text in array)
			{
				t = t.Find(text);
				if ((Object)(object)t == (Object)null)
				{
					return default(T);
				}
			}
			return ((Component)t).GetComponentInChildren<T>();
		}
	}
}
namespace ResourcefulHands.UI
{
	public class OF_CosmeticPage : MonoBehaviour
	{
		public static OF_CosmeticPage instance;

		private CosmeticPage? cosmeticPage;

		private GameObject? cosmeticsMenuObject;

		private UI_CosmeticsMenu? cosmeticsMenu;

		private UI_Page? pageTemplate;

		private UI_PageHolder? pageHolder;

		private GameObject? RHPage;

		private Tab? RHTab;

		public List<Cosmetic_Base> RHHands = new List<Cosmetic_Base>();

		public bool IsReady { get; private set; }

		private void Awake()
		{
		}

		private void OnSceneLoadedDelegate(Scene scene, LoadSceneMode mode)
		{
			OnSceneLoaded(((Scene)(ref scene)).name);
		}

		private void OnSceneLoaded(string sceneName)
		{
			if (!((Object)(object)instance != (Object)(object)this))
			{
				if (sceneName != "Main-Menu")
				{
					cosmeticPage = null;
					cosmeticsMenuObject = null;
					cosmeticsMenu = null;
					pageTemplate = null;
					RHPage = null;
					RHTab = null;
					((MonoBehaviour)instance).StopAllCoroutines();
				}
				else if (!Object.op_Implicit((Object)(object)RHPage))
				{
					((MonoBehaviour)instance).StartCoroutine(InitializeCosmeticsRoutine());
				}
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoadedDelegate;
		}

		private IEnumerator InitializeCosmeticsRoutine()
		{
			ModLogger.Info("Waiting for Resource Packs to finish loading...");
			Task packTask = ResourcePacksManager.InitialLoadTask;
			while (!packTask.IsCompleted)
			{
				yield return null;
			}
			ModLogger.Info("Packs loaded. Now waiting for Unity Cosmetics Menu to initialize...");
			GameObject candidate = null;
			while ((Object)(object)candidate == (Object)null)
			{
				candidate = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Other/Cosmetics");
				yield return (object)new WaitForSeconds(0.1f);
			}
			UI_CosmeticsMenu menu = candidate.GetComponent<UI_CosmeticsMenu>();
			while ((Object)(object)menu == (Object)null || menu.cosmeticPages == null)
			{
				yield return null;
			}
			ModLogger.Info("Game UI ready. Injecting RH Cosmetic Page...");
			FindCosmeticsTemplate();
			PrepareCosmeticPage();
			PrepareCosmetics();
			IsReady = true;
			ModLogger.Info("RH Cosmetics are ready.");
		}

		private void FindCosmeticsTemplate()
		{
			if (Object.op_Implicit((Object)(object)cosmeticsMenuObject) && Object.op_Implicit((Object)(object)cosmeticsMenu))
			{
				return;
			}
			GameObject val = GameObject.Find("Canvas - Screens/Screens/Canvas - Screen - Other/Cosmetics");
			if (!Object.op_Implicit((Object)(object)val))
			{
				ModLogger.Error("Cosmetics template game object not found");
				return;
			}
			UI_CosmeticsMenu component = val.GetComponent<UI_CosmeticsMenu>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				ModLogger.Error("Cosmetics menu template not found");
				return;
			}
			cosmeticsMenuObject = val;
			cosmeticsMenu = component;
		}

		private void PrepareCosmeticPage()
		{
			//IL_0051: 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_0061: 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_0083: Expected O, but got Unknown
			if (cosmeticPage == null)
			{
				CosmeticPage val = cosmeticsMenu?.cosmeticPages.Find((CosmeticPage p) => p.cosmeticType == "hand");
				ModLogger.Error($"Cosmetic page: {val} | ");
				cosmeticPage = new CosmeticPage
				{
					name = "Hands",
					cosmeticType = "hand",
					pageHolder = val?.pageHolder
				};
			}
		}

		public void PrepareCosmetics()
		{
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Expected O, but got Unknown
			if (RHHands.Count > 0)
			{
				return;
			}
			foreach (ResourcePack loadedPack in ResourcePacksManager.LoadedPacks)
			{
				bool flag = false;
				foreach (KeyValuePair<string, Texture2D> texture in loadedPack.Textures)
				{
					if (texture.Key.Contains("Sprite_Library"))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				Cosmetic_HandItem val = ScriptableObject.CreateInstance<Cosmetic_HandItem>();
				((Object)val).name = loadedPack.name;
				val.currentEmoteIds = new List<int>(2) { 0, 0 };
				val.currentPaletteId = 0;
				Sprite sprite = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite s) => ((Object)s).name == "card-blank-foreground"));
				Texture2D tex = TextureCompositor.CreatePackCard(loadedPack.Icon, TextureCompositor.SpriteToTexture(sprite));
				((Cosmetic_Base)val).cosmeticInfo = new Cosmetic_Info
				{
					id = loadedPack.guid,
					cosmeticName = loadedPack.name,
					tag = "hand",
					author = loadedPack.author,
					description = loadedPack.desc,
					unlock = "",
					cardForeground = TextureCompositor.TextureToSprite(tex)
				};
				val.cosmeticData = new Cosmetic_HandItem_Data
				{
					swapSprites = new List<SwapSprite>(),
					cosmeticName = loadedPack.name,
					author = loadedPack.author,
					description = loadedPack.desc,
					unlock = "",
					id = loadedPack.guid
				};
				Dictionary<string, SwapSprite> dictionary = new Dictionary<string, SwapSprite>();
				Dictionary<string, InteractSwap> dictionary2 = new Dictionary<string, InteractSwap>();
				foreach (KeyValuePair<string, Texture2D> texture2 in loadedPack.Textures)
				{
					if (texture2.Value == null)
					{
						continue;
					}
					if (texture2.Key.Contains("Sprite_Library"))
					{
						int layer = int.Parse(texture2.Key.Split('_')[^1]);
						bool sheetType = !texture2.Key.Contains("Background");
						Dictionary<Vector2, Texture2D> slices = DynamicHandSlicer.SliceSheet(texture2.Value, 4, 4);
						foreach (KeyValuePair<string, Texture2D> item in DynamicHandSlicer.GetNamedSlicesFromSlicedSheet(sheetType ? DynamicHandSlicer.SheetType.Foreground : DynamicHandSlicer.SheetType.Background, slices, layer))
						{
							string key = item.Key;
							Texture2D value = item.Value;
							SwapSprite val2 = new SwapSprite
							{
								framerate = 1f,
								hand = -1,
								loopTimeOffset = 0f,
								offset = Vector2.zero
							};
							Sprite val3 = TextureCompositor.TextureToSprite(value);
							((Object)val3).name = key;
							val2.materialBase = "";
							val2.replacementSpriteNames = new List<string>(1) { key };
							val2.replacementSprites = new List<Sprite>(1) { val3 };
							val2.rotation = 0f;
							val2.scale = 1f;
							val2.secondaryTextures = new List<SecondaryTextures>();
							val2.spriteName = key;
							val2.usePalette = true;
							dictionary.TryAdd(val2.spriteName, val2);
						}
					}
					if (!texture2.Key.Contains("hand-sheet"))
					{
						continue;
					}
					Dictionary<Vector2, Texture2D> dictionary3 = DynamicHandSlicer.SliceSheet(texture2.Value, 4, 4);
					for (int num = 0; num < 4; num++)
					{
						dictionary3.TryGetValue(new Vector2(0f, (float)num), out var value2);
						Sprite replacementSprite = TextureCompositor.TextureToSprite(value2);
						string text = "";
						switch (num)
						{
						case 0:
							text = "interact-hand-open";
							break;
						case 1:
							text = "interact-hand-grabbed";
							break;
						case 2:
							text = "interact-hand-point";
							break;
						case 3:
							text = "interact-hand-item";
							break;
						}
						InteractSwap val4 = new InteractSwap
						{
							replacementSprite = replacementSprite,
							replacementSpriteName = text,
							spriteName = text
						};
						dictionary2.TryAdd(val4.spriteName, val4);
					}
				}
				Cosmetic_HandItem_Data cosmeticData = val.cosmeticData;
				if (cosmeticData.swapSprites == null)
				{
					cosmeticData.swapSprites = new List<SwapSprite>();
				}
				cosmeticData = val.cosmeticData;
				if (cosmeticData.interactSwaps == null)
				{
					cosmeticData.interactSwaps = new List<InteractSwap>();
				}
				foreach (string key2 in dictionary.Keys)
				{
					_ = key2;
				}
				foreach (string key3 in dictionary2.Keys)
				{
					_ = key3;
				}
				val.cosmeticData.swapSprites.AddRange(dictionary.Values);
				val.cosmeticData.interactSwaps.AddRange(dictionary2.Values);
				RHHands.Add((Cosmetic_Base)(object)val);
				SafeInitialize(val);
			}
		}

		private void SafeInitialize(Cosmetic_HandItem item)
		{
			if (typeof(Cosmetic_HandItem).GetField("swapDict", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(item) is IDictionary { Count: not 0 })
			{
				ModLogger.Warning(((Object)item).name + " was already initialized! Skipping to avoid Dictionary crash.");
			}
			else
			{
				InvokePrivateMethod(item, "Initialize");
			}
		}

		private void ApplyCosmetics()
		{
			if (!Object.op_Implicit((Object)(object)cosmeticsMenu) || RHHands.Count == 0)
			{
				return;
			}
			InjectIntoCosmeticManager();
			FieldInfo field = typeof(CosmeticPage).GetField("cosmetics", BindingFlags.Instance | BindingFlags.NonPublic);
			if (cosmeticPage != null && field != null)
			{
				List<Cosmetic_Base> list = new List<Cosmetic_Base>();
				list.AddRange(RHHands);
				field.SetValue(cosmeticPage, list);
			}
			try
			{
				cosmeticsMenu.FillCosmeticPage(RHHands, "Only RH", cosmeticPage);
			}
			catch (Exception ex)
			{
				ModLogger.Error("FillCosmeticPage failed: " + ex.Message);
			}
		}

		public void InjectIntoCosmeticManager()
		{
			try
			{
				Type? typeFromHandle = typeof(CL_CosmeticManager);
				FieldInfo field = typeFromHandle.GetField("cosmeticHands", BindingFlags.Static | BindingFlags.NonPublic);
				FieldInfo field2 = typeFromHandle.GetField("cosmeticHandDict", BindingFlags.Static | BindingFlags.NonPublic);
				FieldInfo? field3 = typeFromHandle.GetField("loadedCosmetics", BindingFlags.Static | BindingFlags.NonPublic);
				List<Cosmetic_HandItem> list = (List<Cosmetic_HandItem>)field.GetValue(null);
				Dictionary<string, Cosmetic_HandItem> dictionary = (Dictionary<string, Cosmetic_HandItem>)field2.GetValue(null);
				List<Cosmetic_Base> list2 = (List<Cosmetic_Base>)field3.GetValue(null);
				foreach (Cosmetic_Base rHHand in RHHands)
				{
					Cosmetic_HandItem val = (Cosmetic_HandItem)(object)((rHHand is Cosmetic_HandItem) ? rHHand : null);
					if (!((Object)(object)val == (Object)null) && !dictionary.ContainsKey(((Cosmetic_Base)val).cosmeticInfo.id))
					{
						list.Add(val);
						dictionary.Add(((Cosmetic_Base)val).cosmeticInfo.id, val);
						list2.Add((Cosmetic_Base)(object)val);
						SettingsManager.settings.cosmeticSaveData.FillNewCosmeticInfo((Cosmetic_Base)(object)val);
						ModLogger.Info("Successfully injected " + ((Object)val).name + " into CL_CosmeticManager");
					}
				}
			}
			catch (Exception ex)
			{
				ModLogger.Error("Failed to inject into CL_CosmeticManager: " + ex.Message);
			}
		}

		public static void InvokePrivateMethod(object obj, string methodName, params object[] args)
		{
			MethodInfo method = obj.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(obj, args);
			}
			else
			{
				ModLogger.Error("Method '" + methodName + "' not found on " + obj.GetType().Name);
			}
		}
	}
}
namespace ResourcefulHands.UI.Imui
{
	public class ModListTab : ModTab
	{
		public override string DisplayName => "Resourceful Hands";

		public override void DrawSubMenu(ImGui gui)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			if (ImButton.Button(gui, "Pack menu".AsSpan(), default(ImSize), (ImButtonFlag)0))
			{
				((WKLibWindow)WindowsDeclarations.PacksWindow).isOpen = !((WKLibWindow)WindowsDeclarations.PacksWindow).isOpen;
			}
			if (ImButton.Button(gui, "Settings menu".AsSpan(), default(ImSize), (ImButtonFlag)0))
			{
				((WKLibWindow)WindowsDeclarations.SettingsWindow).isOpen = !((WKLibWindow)WindowsDeclarations.SettingsWindow).isOpen;
			}
		}
	}
	public class PacksMenu : WKLibWindow
	{
		private ImScrollFlag scrollBarFlags = (ImScrollFlag)10;

		private string searchBuffer = "";

		public override void Draw(ImGui gui, bool isRootPanelOpen)
		{
			//IL_001a: 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_0073: 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)
			if (isRootPanelOpen && ImWindow.BeginWindow(gui, "RH Packs", ref base.isOpen, new ImSize(800f, 400f), (ImWindowFlag)0))
			{
				ImSeparator.Separator(gui, "Pack selection".AsSpan());
				float layoutWidth = ImLayoutUtility.GetLayoutWidth(gui);
				float spacing = gui.Style.Layout.Spacing;
				ImLayoutUtility.AddSpacing(gui, spacing);
				ref string reference = ref searchBuffer;
				ReadOnlySpan<char> readOnlySpan = "Search for a pack here.".AsSpan();
				ImTextEdit.TextEdit(gui, ref reference, default(ImSize), (bool?)null, 0, (ImTouchKeyboardType)0, readOnlySpan);
				ImLayoutUtility.AddSpacing(gui, spacing * 2f);
				float layoutHeight = ImLayoutUtility.GetLayoutHeight(gui);
				float num = layoutWidth * 0.5f - spacing * 0.5f;
				float num2 = layoutHeight - ImLayoutUtility.GetRowHeight(gui) - spacing * 3f;
				ImLayoutUtility.BeginHorizontal(gui, num, num2);
				ImLayoutUtility.BeginVertical(gui, 0f, 0f);
				DrawInactivePacks(gui);
				ImLayoutUtility.EndVertical(gui);
				ImLayoutUtility.AddSpacing(gui, spacing);
				ImLayoutUtility.BeginVertical(gui, num, num2);
				DrawActivePacks(gui);
				ImLayoutUtility.EndVertical(gui);
				ImLayoutUtility.EndHorizontal(gui);
				ImLayoutUtility.AddSpacing(gui, spacing * 2f);
				DrawActions(gui);
				gui.EndWindow(scrollBarFlags);
			}
		}

		private void DrawActions(ImGui gui)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			ImLayoutUtility.BeginHorizontal(gui, 0f, 0f);
			if (ImButton.Button(gui, "Open Packs folder".AsSpan(), ImSize.op_Implicit((ImLayoutUtility.GetLayoutWidth(gui) * 0.5f - spacing * 0.5f, ImLayoutUtility.GetRowHeight(gui))), (ImButtonFlag)0))
			{
				Application.OpenURL("file://" + RHConfig.PacksFolder.Replace("\\", "/"));
			}
			if (ImButton.Button(gui, "Reload Packs".AsSpan(), ImSize.op_Implicit((ImSizeMode)3), (ImButtonFlag)0))
			{
				ResourcePacksManager.ReloadPacks();
			}
			ImLayoutUtility.EndHorizontal(gui);
		}

		private void DrawActivePacks(ImGui gui)
		{
			//IL_005e: 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_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: 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_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			gui.PushId("ActivePacks".AsSpan());
			bool flag = searchBuffer.Trim().Length > 0;
			float spacing = gui.Style.Layout.Spacing;
			float num = 100f;
			ImSeparator.Separator(gui, "Active packs".AsSpan());
			ImList.BeginList(gui, ImSize.op_Implicit((ImLayoutUtility.GetLayoutWidth(gui), ImLayoutUtility.GetLayoutHeight(gui))));
			ImGridState val = ImGrid.BeginGrid(gui, 1, num);
			bool flag2 = false;
			bool flag3 = false;
			int num2 = -1;
			for (int i = 0; i < ResourcePacksManager.ActivePacks.Length; i++)
			{
				ResourcePack loadedPack = ResourcePacksManager.ActivePacks[i];
				if (loadedPack == null || (flag && !loadedPack.name.ToLower().Contains(searchBuffer.Trim().ToLower()) && !loadedPack.author.ToLower().Contains(searchBuffer.Trim().ToLower()) && !loadedPack.desc.ToLower().Contains(searchBuffer.Trim().ToLower())))
				{
					continue;
				}
				ImRect val2 = ImGrid.GridNextCell(gui, ref val);
				uint nextControlId = gui.GetNextControlId();
				gui.RegisterGroup(nextControlId, val2);
				bool flag4 = gui.IsGroupHovered(nextControlId);
				if (flag4)
				{
					gui.Canvas.RectOutline(val2, gui.Style.Button.Normal.BorderColor, 2f, ImRectRadius.op_Implicit(2f), 0f);
					string text = TextUtils.InsertLineBreaks(loadedPack.desc, 40);
					if (text != string.Empty)
					{
						ImTooltip.Tooltip(gui, text.AsSpan(), gui.Input.MousePosition + gui.Style.Tooltip.OffsetPixels / gui.Canvas.ScreenScale);
					}
				}
				float w = val2.W;
				ImRect val3 = DrawIcon(gui, loadedPack, val2, num, w);
				w -= val3.W + spacing;
				if (w <= 0f)
				{
					continue;
				}
				ImRect val4 = DrawTitle(gui, loadedPack, val2, val3, num, w);
				DrawAuthor(gui, loadedPack, val2, val3, num, w);
				w -= val4.W + spacing;
				if (w <= 0f || !flag4)
				{
					continue;
				}
				bool flag5 = ResourcePacksManager.ActivePacks.Length == 1;
				ImRect val5 = DrawMakeInactive(gui, ref loadedPack, val2, val4, flag5, num, w);
				w -= val5.W + spacing;
				if (w <= 0f)
				{
					continue;
				}
				bool flag6 = i == 0;
				bool flag7 = i == ResourcePacksManager.ActivePacks.Length - 1;
				if (flag5)
				{
					continue;
				}
				if (flag6)
				{
					flag3 = DrawMoveDown(gui, loadedPack, val2, val5, num, w);
				}
				else if (flag7)
				{
					flag2 = DrawMoveUp(gui, loadedPack, val2, val5, num, w);
				}
				else
				{
					flag2 = DrawMoveUp(gui, loadedPack, val2, val5, num, w);
					flag3 = DrawMoveDown(gui, loadedPack, val2, val5, num, w);
				}
				if (!(flag3 || flag2))
				{
					continue;
				}
				for (int j = 0; j < ResourcePacksManager.LoadedPacks.Count; j++)
				{
					if (ResourcePacksManager.LoadedPacks[j] == loadedPack)
					{
						num2 = j;
						break;
					}
				}
			}
			if (num2 >= 0 && num2 < ResourcePacksManager.LoadedPacks.Count)
			{
				if (flag2)
				{
					int num3 = -1;
					for (int k = 0; k < ResourcePacksManager.LoadedPacks.Count; k++)
					{
						if (ResourcePacksManager.LoadedPacks[k].IsActive)
						{
							if (k >= num2)
							{
								break;
							}
							num3 = k;
						}
					}
					List<ResourcePack> loadedPacks = ResourcePacksManager.LoadedPacks;
					ResourcePack item = loadedPacks[num2];
					loadedPacks.RemoveAt(num2);
					int num4 = ((num3 >= 0) ? num3 : 0);
					if (num4 > num2)
					{
						num4--;
					}
					loadedPacks.Insert(num4, item);
				}
				else if (flag3)
				{
					int num5 = -1;
					for (int l = num2 + 1; l < ResourcePacksManager.LoadedPacks.Count; l++)
					{
						if (ResourcePacksManager.LoadedPacks[l].IsActive)
						{
							num5 = l;
							break;
						}
					}
					List<ResourcePack> loadedPacks2 = ResourcePacksManager.LoadedPacks;
					ResourcePack item2 = loadedPacks2[num2];
					loadedPacks2.RemoveAt(num2);
					int num6 = -1;
					num6 = ((num5 < 0) ? loadedPacks2.Count : num5);
					loadedPacks2.Insert(num6, item2);
				}
				ResourcePacksManager.SaveDisabledPacks();
				ResourcePacksManager.SavePackOrder();
			}
			ImGrid.EndGrid(gui, ref val);
			gui.EndList(scrollBarFlags);
			gui.PopId();
		}

		private void DrawInactivePacks(ImGui gui)
		{
			//IL_005e: 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_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			gui.PushId("InactivePacks".AsSpan());
			bool flag = searchBuffer.Trim().Length > 0;
			float spacing = gui.Style.Layout.Spacing;
			float num = 100f;
			ImSeparator.Separator(gui, "Inactive packs".AsSpan());
			ImList.BeginList(gui, ImSize.op_Implicit((ImLayoutUtility.GetLayoutWidth(gui), ImLayoutUtility.GetLayoutHeight(gui))));
			ImGridState val = ImGrid.BeginGrid(gui, 1, num);
			int num2 = -1;
			for (int i = 0; i < ResourcePacksManager.LoadedPacks.Count; i++)
			{
				ResourcePack loadedPack = ResourcePacksManager.LoadedPacks[i];
				if (loadedPack == null || loadedPack.IsActive || (flag && !loadedPack.name.ToLower().Contains(searchBuffer.Trim().ToLower()) && !loadedPack.author.ToLower().Contains(searchBuffer.Trim().ToLower()) && !loadedPack.desc.ToLower().Contains(searchBuffer.Trim().ToLower())))
				{
					continue;
				}
				ImRect val2 = ImGrid.GridNextCell(gui, ref val);
				uint nextControlId = gui.GetNextControlId();
				gui.RegisterGroup(nextControlId, val2);
				bool flag2 = gui.IsGroupHovered(nextControlId);
				if (flag2)
				{
					gui.Canvas.RectOutline(val2, gui.Style.Button.Normal.BorderColor, 2f, ImRectRadius.op_Implicit(2f), 0f);
					string text = TextUtils.InsertLineBreaks(loadedPack.desc, 40);
					if (text != string.Empty)
					{
						ImTooltip.Tooltip(gui, text.AsSpan(), gui.Input.MousePosition + gui.Style.Tooltip.OffsetPixels / gui.Canvas.ScreenScale);
					}
				}
				float w = val2.W;
				ImRect val3 = DrawIcon(gui, loadedPack, val2, num, w);
				w -= val3.W + spacing;
				if (w <= 0f)
				{
					continue;
				}
				ImRect val4 = DrawTitle(gui, loadedPack, val2, val3, num, w);
				DrawAuthor(gui, loadedPack, val2, val3, num, w);
				w -= val4.W + spacing;
				if (!(w <= 0f) && flag2)
				{
					if (DrawMakeActive(gui, ref loadedPack, val2, val4, num, w, out var rect))
					{
						loadedPack.IsActive = true;
						num2 = i;
					}
					w -= rect.W + spacing;
					_ = 0f;
				}
			}
			if (num2 != -1)
			{
				List<ResourcePack> loadedPacks = ResourcePacksManager.LoadedPacks;
				ResourcePack item = loadedPacks[num2];
				loadedPacks.RemoveAt(num2);
				loadedPacks.Insert(0, item);
				ResourcePacksManager.SaveDisabledPacks();
				ResourcePacksManager.SavePackOrder();
			}
			ImGrid.EndGrid(gui, ref val);
			gui.EndList(scrollBarFlags);
			gui.PopId();
		}

		private ImRect DrawIcon(ImGui gui, ResourcePack loadedPack, ImRect gridRect, float cellHeight, float cellWidth)
		{
			//IL_0013: 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_0098: 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_0062: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += spacing;
			val.H -= spacing;
			val.Y += spacing / 2f;
			val.W = val.H;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32(byte.MaxValue, byte.MaxValue, (byte)0, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			ImImage.Image(gui, (Texture)(object)loadedPack.Icon, val, true);
			return val;
		}

		private ImRect DrawTitle(ImGui gui, ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth)
		{
			//IL_002e: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float w = cellWidth * 0.8f - spacing * 2f;
			float h = cellHeight * 0.25f - spacing;
			float num = spacing + previousRect.W + spacing;
			float num2 = cellHeight * 0.75f;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num;
			val.Y += num2;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, (byte)125, byte.MaxValue, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			ImText.Text(gui, loadedPack.name.AsSpan(), val, false, (ImTextOverflow)0);
			return val;
		}

		private ImRect DrawAuthor(ImGui gui, ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth)
		{
			//IL_002e: 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_00c4: 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_0088: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float w = cellWidth * 0.8f - spacing * 2f;
			float h = cellHeight * 0.25f - spacing;
			float num = spacing + previousRect.W + spacing;
			float num2 = cellHeight * 0.5f + spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num;
			val.Y += num2;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			ImText.Text(gui, loadedPack.author.AsSpan(), val, false, (ImTextOverflow)0);
			return val;
		}

		private ImRect DrawDescription(ImGui gui, ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth)
		{
			//IL_002e: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			float spacing = gui.Style.Layout.Spacing;
			float w = cellWidth * 0.8f - spacing * 2f;
			float h = cellHeight * 0.5f - spacing;
			float num = spacing + previousRect.W + spacing;
			float num2 = spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num;
			val.Y += num2;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)125, (byte)0, byte.MaxValue, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			ImText.Text(gui, loadedPack.desc.AsSpan(), val, true, (ImTextOverflow)1);
			return val;
		}

		private bool DrawMakeActive(ImGui gui, ref ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth, out ImRect rect)
		{
			//IL_0011: 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_0046: 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_0087: 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_00d8: 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)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float num = Math.Abs(previousRect.X - gridRect.X);
			float w = cellWidth * 1f - spacing * 2f;
			float h = cellHeight * 1f - spacing * 2f;
			float num2 = num + previousRect.W + spacing;
			float num3 = spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num2;
			val.Y += num3;
			val.H = h;
			val.W = w;
			rect = val;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, (byte)67, (byte)245, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			return ImButton.Button(gui, ">".AsSpan(), val, (ImButtonFlag)0);
		}

		private ImRect DrawMakeInactive(ImGui gui, ref ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, bool isOnlyElement, float cellHeight, float cellWidth)
		{
			//IL_0011: 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_0051: 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_00da: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float num = Math.Abs(previousRect.X - gridRect.X);
			float w = cellWidth * (isOnlyElement ? 1f : 0.5f) - spacing * 2f;
			float h = cellHeight * 1f - spacing * 2f;
			float num2 = num + previousRect.W + spacing;
			float num3 = spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num2;
			val.Y += num3;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, (byte)67, (byte)245, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			if (ImButton.Button(gui, "<".AsSpan(), val, (ImButtonFlag)0))
			{
				loadedPack.IsActive = false;
			}
			return val;
		}

		private bool DrawMoveUp(ImGui gui, ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth)
		{
			//IL_0011: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float num = Math.Abs(previousRect.X - gridRect.X);
			float w = cellWidth * 1f - spacing * 2f;
			float h = cellHeight * 0.5f - spacing;
			float num2 = num + previousRect.W + spacing;
			float num3 = cellHeight * 0.5f;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num2;
			val.Y += num3;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, (byte)67, (byte)245, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			return ImButton.Button(gui, "^".AsSpan(), val, (ImButtonFlag)0);
		}

		private bool DrawMoveDown(ImGui gui, ResourcePack loadedPack, ImRect gridRect, ImRect previousRect, float cellHeight, float cellWidth)
		{
			//IL_0011: 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_0046: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			float spacing = gui.Style.Layout.Spacing;
			float num = Math.Abs(previousRect.X - gridRect.X);
			float w = cellWidth * 1f - spacing * 2f;
			float h = cellHeight * 0.5f - spacing * 2f;
			float num2 = num + previousRect.W + spacing;
			float num3 = spacing;
			ImRect val = default(ImRect);
			((ImRect)(ref val))..ctor(gridRect);
			val.X += num2;
			val.Y += num3;
			val.H = h;
			val.W = w;
			if (WindowsDeclarations.SettingsWindow.DebugUIBoxes)
			{
				gui.Canvas.RectOutline(val, new Color32((byte)0, (byte)67, (byte)245, byte.MaxValue), 2f, ImRectRadius.op_Implicit(0f), 0f);
			}
			return ImButton.Button(gui, "v".AsSpan(), val, (ImButtonFlag)0);
		}

		public override void HandleInput(ImGui gui)
		{
		}
	}
	public class SettingsMenu : WKLibWindow
	{
		public bool DebugUIBoxes;

		public override void Draw(ImGui gui, bool isRootPanelOpen)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (isRootPanelOpen && ImWindow.BeginWindow(gui, "RH Settings", ref base.isOpen, new ImSize(400f, 400f), (ImWindowFlag)0))
			{
				ImSeparator.Separator(gui, "General".AsSpan());
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.LazyManip);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.UseOldSprReplace);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.UseOutdatedPacks);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.ExpandVanillaAudioOverrides);
				ImLayoutUtility.AddSpacing(gui);
				ImSeparator.Separator(gui, "Emotes".AsSpan());
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteWheelKey);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteWheelKeyAlt);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.ToggleWheel);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteLeftKey);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteLeftKeyAlt);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteRightKey);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.EmoteRightKeyAlt);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.ToggleEmotes);
				ImLayoutUtility.AddSpacing(gui);
				ImSeparator.Separator(gui, "Debugging".AsSpan());
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.ColorConsole);
				UIUtility.DrawConfigEntry(gui, (ConfigEntryBase)(object)RHConfig.AlwaysDebug);
				ImWindow.EndWindow(gui);
			}
		}

		public override void HandleInput(ImGui gui)
		{
		}
	}
	public static class WindowsDeclarations
	{
		public static PacksMenu PacksWindow = new PacksMenu();

		public static SettingsMenu SettingsWindow = new SettingsMenu();
	}
}
namespace ResourcefulHands.UI.Imui.Utility
{
	public static class CustomImList
	{
		public static void EndList(this ImGui gui, ImScrollFlag flags = (ImScrollFlag)0)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ImScroll.EndScrollable(gui, flags);
			gui.Canvas.PopClipRect();
			gui.Canvas.PopRectMask();
			gui.Layout.Pop();
		}
	}
	public static class CustomImWindow
	{
		public static void EndWindow(this ImGui gui, ImScrollFlag scrollFlags)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			ImScroll.EndScrollable(gui, scrollFlags);
			gui.Layout.Pop();
			gui.WindowManager.EndWindow();
			gui.Canvas.PopClipRect();
			gui.Canvas.PopRectMask();
			gui.Canvas.PopOrder();
			gui.PopId();
		}
	}
}
namespace ResourcefulHands.Systems
{
	public static class RHCommands
	{
		private static readonly string[] ordinals = new string[6] { "first", "second", "third", "fourth", "fifth", "sixth" };

		public const string DumpCommand = "dumptopack";

		public const string ReloadCommand = "reloadpacks";

		public const string MoveCommand = "reorderpack";

		public const string ListCommand = "listpacks";

		public const string EnableCommand = "enablepack";

		public const string DisableCommand = "disablepack";

		public const string EnableAllCommand = "enablepack_all";

		public const string DisableAllCommand = "disablepack_all";

		public const string ToggleDebug = "rhtoggledebug";

		public const string DumpPackInfo = "dumppackinfo";

		public const string AssignHandPack = "assignhandpack";

		public const string ClearHandPack = "clearhandpack";

		public const string ListHandPacks = "listhandpacks";

		public static void RefreshCommands()
		{
			if (!Object.op_Implicit((Object)(object)CommandConsole.instance))
			{
				return;
			}
			CommandConsole.RemoveCommand("dumptopack");
			CommandConsole.RemoveCommand("reloadpacks");
			CommandConsole.RemoveCommand("reorderpack");
			CommandConsole.RemoveCommand("listpacks");
			CommandConsole.RemoveCommand("enablepack");
			CommandConsole.RemoveCommand("disablepack");
			CommandConsole.RemoveCommand("enablepack_all");
			CommandConsole.RemoveCommand("disablepack_all");
			CommandConsole.RemoveCommand("rhtoggledebug");
			CommandConsole.RemoveCommand("dumppackinfo");
			CommandConsole.AddCommand("dumptopack", (Action<string[]>)DumpAllToPack, false);
			CommandConsole.AddCommand("reloadpacks", (Action<string[]>)ReloadPacks, false);
			CommandConsole.AddCommand("reorderpack", (Action<string[]>)MovePacks, false);
			CommandConsole.AddCommand("listpacks", (Action<string[]>)ListPacks, false);
			CommandConsole.AddCommand("enablepack", (Action<string[]>)EnablePack, false);
			CommandConsole.AddCommand("disablepack", (Action<string[]>)DisablePack, false);
			CommandConsole.AddCommand("enablepack_all", (Action<string[]>)EnableAll, false);
			CommandConsole.AddCommand("disablepack_all", (Action<string[]>)DisableAll, false);
			CommandConsole.AddCommand("rhtoggledebug", (Action<string[]>)delegate
			{
				RHDebugTools.isOn = !RHDebugTools.isOn;
			}, false);
			CommandConsole.AddCommand("dumppackinfo", (Action<string[]>)delegate(string[] args)
			{
				ResourcePack packFromArgs = GetPackFromArgs(args, ModLogger.Player.Error);
				if (packFromArgs == null)
				{
					ModLogger.Player.Info("The first argument must be a pack!");
				}
				else
				{
					ModLogger.Player.Info("-- " + packFromArgs.name + " --");
					ModLogger.Player.Info("-  [textures]  -");
					ModLogger.Player.Info(packFromArgs.relativeTexturesPath ?? "");
					foreach (KeyValuePair<string, Texture2D> texture in packFromArgs.Textures)
					{
						ModLogger.Player.Info($"{texture.Key}: {texture.Value}");
					}
					ModLogger.Player.Info("-  [sounds]  -");
					ModLogger.Player.Info(packFromArgs.relativeSoundsPath ?? "");
					foreach (KeyValuePair<string, AudioClip> sound in packFromArgs.Sounds)
					{
						ModLogger.Player.Info($"{sound.Key}: {sound.Value}");
					}
					ModLogger.Player.Info("-  [misc]  -");
					ModLogger.Player.Info($"{packFromArgs.relativeIconPath}: {packFromArgs.Icon}");
					ModLogger.Player.Info("packVer: " + packFromArgs.packVersion);
					ModLogger.Player.Info("gameVer: " + packFromArgs.gameVersionString);
					ModLogger.Player.Info($"frmtVer: {packFromArgs.formatVersion}");
				}
			}, false);
			CommandConsole.AddCommand("assignhandpack", (Action<string[]>)AssignHandResourcePack, false);
			CommandConsole.AddCommand("clearhandpack", (Action<string[]>)ClearHandResourcePack, false);
			CommandConsole.AddCommand("listhandpacks", (Action<string[]>)ListHandResourcePack, false);
		}

		private static void MovePacks(string[] args)
		{
			if (args.Length != 2)
			{
				ModLogger.Player.Error("Invalid number of arguments!");
				ModLogger.Player.Info("Usage: reorderpack [pack guid/pack index] [up/down]\nResource packs at the bottom of the loaded list will override textures at the top, use this command to move a resource pack up or down the list.");
				return;
			}
			ResourcePack pack = GetPackFromArgs(args, ModLogger.Player.Error);
			if (pack == null)
			{
				ModLogger.Player.Info("Usage: reorderpack [pack guid/pack index] [up/down]\nResource packs at the bottom of the loaded list will override textures at the top, use this command to move a resource pack up or down the list.");
				return;
			}
			string text = args[1].ToLower();
			bool flag;
			switch (text)
			{
			case "up":
			case "down":
			case "u":
			case "d":
				flag = true;
				break;
			default:
				flag = false;
				break;
			}
			if (!flag)
			{
				ModLogger.Player.Error("Invalid second argument!\nExpected: up or down");
				ModLogger.Player.Info("Usage: reorderpack [pack guid/pack index] [up/down]\nResource packs at the bottom of the loaded list will override textures at the top, use this command to move a resource pack up or down the list.");
				return;
			}
			flag = ((text == "up" || text == "u") ? true : false);
			bool isUp = flag;
			ResourcePacksManager.MovePack(pack, isUp);
			ModLogger.Player.Info("Reloading packs...");
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info(string.Format("Moved {0} {1}{2}{3} {4} successfully!", pack.name, '{', pack.guid, '}', isUp ? "up" : "down"));
			});
		}

		private static void ListPacks(string[] args)
		{
			for (int i = 0; i < ResourcePacksManager.LoadedPacks.Count; i++)
			{
				ResourcePack resourcePack = ResourcePacksManager.LoadedPacks[i];
				ModLogger.Player.Info(((!resourcePack.IsActive) ? "[DISABLED] " : $"[{i}] ") + resourcePack.name + " by " + resourcePack.author + "\n-- description:\n" + resourcePack.desc + "\n-- guid: '" + resourcePack.guid + "'\n____");
			}
		}

		private static void ReloadPacks(string[] args)
		{
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info("Resource packs reloaded successfully!");
			});
		}

		private static ResourcePack? GetPackFromArgs(string[] args, Action<string> logErr, int indexOverride = 0)
		{
			string text = "first";
			if (indexOverride != 0)
			{
				text = ((indexOverride > 6) ? indexOverride.ToString() : ordinals[indexOverride - 1]);
			}
			ResourcePack resourcePack = null;
			if (int.TryParse(args[indexOverride], out var result))
			{
				resourcePack = ((result >= 0 && result < ResourcePacksManager.LoadedPacks.Count) ? ResourcePacksManager.LoadedPacks[result] : null);
				if (resourcePack == null)
				{
					logErr($"Invalid {text} argument!\nThe resource pack at index {result} doesn't exist!");
					return null;
				}
			}
			else
			{
				string packName = args[indexOverride].ToLower();
				resourcePack = ResourcePacksManager.LoadedPacks.FirstOrDefault((ResourcePack p) => p.guid.ToLower() == packName);
				if (resourcePack == null)
				{
					logErr("Invalid " + text + " argument!\nThe resource pack with guid '" + packName + "' doesn't exist!");
					return null;
				}
			}
			return resourcePack;
		}

		private static void DisablePack(string[] args)
		{
			ResourcePack pack = GetPackFromArgs(args, ModLogger.Player.Error);
			if (pack == null)
			{
				ModLogger.Player.Info("Usage: disablepack [pack guid/pack index]\nDisables a resource pack.");
				return;
			}
			pack.IsActive = false;
			ModLogger.Player.Info("Reloading packs...");
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info($"Disabled {pack.name} {'{'}{pack.guid}{'}'} successfully!");
			});
		}

		private static void EnablePack(string[] args)
		{
			ResourcePack pack = GetPackFromArgs(args, ModLogger.Player.Error);
			if (pack == null)
			{
				ModLogger.Player.Info("Usage: enablepack [pack guid/pack index]\nEnables a resource pack.");
				return;
			}
			pack.IsActive = true;
			ModLogger.Player.Info("Reloading packs...");
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info($"Enabled {pack.name} {'{'}{pack.guid}{'}'} successfully!");
			});
			ModLogger.Player.Info($"Enabled {pack.name} {'{'}{pack.guid}{'}'} successfully!");
		}

		private static void DisableAll(string[] args)
		{
			ResourcePacksManager.LoadedPacks.ForEach(delegate(ResourcePack p)
			{
				p.IsActive = false;
			});
			ModLogger.Player.Info("Reloading packs...");
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info("Disabled all packs successfully!");
			});
		}

		private static void EnableAll(string[] args)
		{
			ResourcePacksManager.LoadedPacks.ForEach(delegate(ResourcePack p)
			{
				p.IsActive = true;
			});
			ModLogger.Player.Info("Reloading packs...");
			ResourcePacksManager.ReloadPacks(waitTillReady: true, delegate
			{
				ModLogger.Player.Info("Enabled all packs successfully!");
			});
		}

		private static void DumpAllToPack(string[] args)
		{
			if (args.Any((string arg) => arg.ToLower() == "help"))
			{
				ModLogger.Player.Info("Use this command to generate a resource pack that contains every in-game asset. Good to find assets to replace but beware that there will probably be unused assets!");
				return;
			}
			if (!args.Any((string arg) => arg.ToLower() == "confirm"))
			{
				ModLogger.Player.Error("Warning: This takes up alot of storage space due to uncompressed audio!\nTHIS WILL ALSO END YOUR RUN AND LOAD YOU BACK TO THE MAIN MENU!!\nARE YOU SURE? (type 'dumptopack confirm')");
				return;
			}
			ModLogger.Player.Info("Dumping all resources to a template resource pack [this will take some time]...");
			List<Texture2D> textures = new List<Texture2D>();
			List<Texture2D> spriteTextures = new List<Texture2D>();
			List<AudioClip> sounds = new List<AudioClip>();
			Texture2D[] source = Resources.FindObjectsOfTypeAll<Texture2D>();
			textures.AddRange(source.Where((Texture2D tex) => !textures.Contains(tex)));
			AudioClip[] source2 = Resources.FindObjectsOfTypeAll<AudioClip>();
			sounds.AddRange(source2.Where((AudioClip sound) => !sounds.Contains(sound)));
			Sprite[] source3 = Resources.FindObjectsOfTypeAll<Sprite>();
			spriteTextures.AddRange(from sprite in source3
				where Object.op_Implicit((Object)(object)sprite.texture) && !spriteTextures.Contains(sprite.texture)
				select sprite.texture);
			ModLogger.Player.Info("Loading Playground [to extract assets]");
			SceneManager.LoadScene("Playground");
			source = Resources.FindObjectsOfTypeAll<Texture2D>();
			textures.AddRange(source.Where((Texture2D tex) => !textures.Contains(tex)));
			source2 = Resources.FindObjectsOfTypeAll<AudioClip>();
			sounds.AddRange(source2.Where((AudioClip sound) => !sounds.Contains(sound)));
			source3 = Resources.FindObjectsOfTypeAll<Sprite>();
			spriteTextures.AddRange(from sprite in source3
				where Object.op_Implicit((Object)(object)sprite.texture) && !spriteTextures.Contains(sprite.texture)
				select sprite.texture);
			ModLogger.Player.Info("Loading Training-Level [to extract assets]");
			SceneManager.LoadScene("Training-Level");
			source = Resources.FindObjectsOfTypeAll<Texture2D>();
			textures.AddRange(source.Where((Texture2D tex) => !textures.Contains(tex)));
			source2 = Resources.FindObjectsOfTypeAll<AudioClip>();
			sounds.AddRange(source2.Where((AudioClip sound) => !sounds.Contains(sound)));
			source3 = Resources.FindObjectsOfTypeAll<Sprite>();
			spriteTextures.AddRange(from sprite in source3
				where Object.op_Implicit((Object)(object)sprite.texture) && !spriteTextures.Contains(sprite.texture)
				select sprite.texture);
			ModLogger.Player.Info("Loading Main-Menu [to extract assets and finish]");
			SceneManager.LoadScene("Main-Menu");
			source = Resources.FindObjectsOfTypeAll<Texture2D>();
			textures.AddRange(source.Where((Texture2D tex) => !textures.Contains(tex)));
			source2 = Resources.FindObjectsOfTypeAll<AudioClip>();
			sounds.AddRange(source2.Where((AudioClip sound) => !sounds.Contains(sound)));
			source3 = Resources.FindObjectsOfTypeAll<Sprite>();
			spriteTextures.AddRange(from sprite in source3
				where Object.op_Implicit((Object)(object)sprite.texture) && !spriteTextures.Contains(sprite.texture)
				select sprite.texture);
			ModLogger.Player.Info("Packing assets...");
			int count = textures.Count;
			int count2 = spriteTextures.Count;
			int count3 = sounds.Count;
			string text = Path.Combine(RHConfig.PacksFolder, $"extracted-assets-{count + count3 + count2}-{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string texturesPath = Path.Combine(text, "Textures");
			string path = Path.Combine(texturesPath, "Sprites");
			string text2 = Path.Combine(text, "Sounds");
			if (!Directory.Exists(texturesPath))
			{
				Directory.CreateDirectory(texturesPath);
			}
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}
			if (!Directory.Exists(text2))
			{
				Directory.CreateDirectory(text2);
			}
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = new StringBuilder();
			StringBuilder stringBuilder3 = new StringBuilder();
			stringBuilder.AppendLine("-- ingame textures list --");
			stringBuilder2.AppendLine("-- ingame sprite textures list --");
			stringBuilder3.AppendLine("-- ingame sounds list --");
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			for (int num4 = 0; num4 < count; num4++)
			{
				Texture2D val = textures[num4];
				ModLogger.Player.Info($"Saving textures ({num4}/{count})");
				stringBuilder.Append(((Object)val).name);
				bool flag = false;
				try
				{
					flag = ExportTexture(val);
				}
				catch (Exception ex)
				{
					ModLogger.Player.Error(((Object)val).name + " failed because " + ex.Message);
				}
				if (flag)
				{
					num++;
				}
				stringBuilder.AppendLine(flag ? "" : " [failed to extract]");
			}
			for (int num5 = 0; num5 < count2; num5++)
			{
				Texture2D val2 = spriteTextures[num5];
				ModLogger.Player.Info($"Saving textures ({num5}/{count2})");
				stringBuilder2.Append(((Object)val2).name);
				bool flag2 = false;
				try
				{
					flag2 = ExportTexture(val2);
				}
				catch (Exception ex2)
				{
					ModLogger.Player.Error(((Object)val2).name + " failed because " + ex2.Message);
				}
				if (flag2)
				{
					num3++;
				}
				stringBuilder2.AppendLine(flag2 ? "" : " [failed to extract]");
			}
			for (int num6 = 0; num6 < count3; num6++)
			{
				AudioClip val3 = sounds[num6];
				ModLogger.Player.Info($"Saving sounds ({num6}/{count3})");
				stringBuilder3.Append(((Object)val3).name);
				bool flag3 = false;
				try
				{
					string path2 = Path.Combine(text2, ((Object)val3).name + ".wav");
					float[] array = new float[val3.samples * val3.channels];
					if (!val3.GetData(array, 0))
					{
						ModLogger.Player.Error("Failed to access " + ((Object)val3).name + "'s audio data!");
						stringBuilder3.AppendLine(" [failed to extract]");
						continue;
					}
					using FileStream stream = new FileStream(path2, FileMode.CreateNew, FileAccess.Write);
					ushort num7 = 16;
					string value = "RIFF";
					string value2 = "WAVE";
					string value3 = "fmt ";
					uint value4 = 16u;
					ushort value5 = 1;
					ushort num8 = (ushort)val3.channels;
					uint frequency = (uint)val3.frequency;
					uint value6 = (uint)(frequency * val3.channels * num7 / 8);
					ushort value7 = (ushort)(num8 * num7 / 8);
					string value8 = "data";
					uint num9 = (uint)(array.Length * val3.channels * num7 / 8);
					uint value9 = 36 + num9;
					stream.WriteString(value);
					stream.WriteInteger(value9);
					stream.WriteString(value2);
					stream.WriteString(value3);
					stream.WriteInteger(value4);
					stream.WriteShort(value5);
					stream.WriteShort(num8);
					stream.WriteInteger(frequency);
					stream.WriteInteger(value6);
					stream.WriteShort(value7);
					stream.WriteShort(num7);
					stream.WriteString(value8);
					stream.WriteInteger(num9);
					float[] array2 = array;
					foreach (float num11 in array2)
					{
						short num12 = 0;
						if (num11 > 0f)
						{
							float num13 = num11 * 32767f;
							if (num13 > 32767f)
							{
								num13 = 32767f;
							}
							num12 = (short)num13;
						}
						if (num11 < 0f)
						{
							float num14 = num11 * 32768f;
							if (num14 < -32768f)
							{
								num14 = -32768f;
							}
							num12 = (short)num14;
						}
						stream.WriteShort((ushort)num12);
					}
					num2++;
					flag3 = true;
				}
				catch (Exception ex3)
				{
					ModLogger.Player.Info(((Object)val3).name + " failed because " + ex3.Message);
				}
				stringBuilder3.AppendLine(flag3 ? "" : " [failed to extract]");
			}
			ModLogger.Player.Info("Writing data files");
			File.WriteAllText(Path.Combine(text, "info.json"), "{\r\n    \"name\":\"generated-game-assets\",\r\n    \"desc\":\"Every game asset\",\r\n    \"author\":\"Dark Machine Games\",\r\n    \r\n    \"pack-version\":\"0.50\",\r\n    \"steamid\":0,\r\n    \r\n    \"guid\":\"generated.game.assets.unique\",\r\n    \"hidden-from-list\":true,\r\n    \"only-in-full-game\":false,\r\n    \r\n    \"game-string\":\"b0.50p\",\r\n    \r\n    \"textures-folder\":\"Textures\",\r\n    \"sounds-folder\":\"Sounds\",\r\n    \"icon-file\":\"pack.png\",\r\n    \"icon-filter\":false,\r\n    \r\n    \"format-version\":3\r\n}");
			File.WriteAllText(Path.Combine(text, "textures_list.txt"), stringBuilder.ToString());
			File.WriteAllText(Path.Combine(text, "sprite_textures_list.txt"), stringBuilder2.ToString());
			File.WriteAllText(Path.Combine(text, "audio_list.txt"), stringBuilder3.ToString());
			ModLogger.Player.Info($"Successfully saved {num} of {count} textures!");
			ModLogger.Player.Info($"Successfully saved {num3} of {count2} sprite textures!");
			ModLogger.Player.Info($"Successfully saved {num2} of {count3} sounds!");
			ModLogger.Player.Info("Packed all assets to '" + text + "'");
			bool ExportTexture(Texture2D texture)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Expected O, but got Unknown
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//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_0087: 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_00a4: Expected O, but got Unknown
				bool result = false;
				try
				{
					if (!((Texture)texture).isReadable)
					{
						ModLogger.Player.Info(((Object)texture).name + " isn't readable, saving the slow way...");
						RenderTexture val4 = new RenderTexture(((Texture)texture).width, ((Texture)texture).height, 24);
						RenderTexture active = RenderTexture.active;
						try
						{
							RenderTexture.active = val4;
							Graphics.Blit((Texture)(object)texture, val4);
							RenderTexture val5 = (RenderTexture.active = val4.ConvertToARGB32());
							Texture2D val7 = new Texture2D(((Texture)texture).width, ((Texture)texture).height, texture.format, false);
							val7.ReadPixels(new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), 0, 0);
							val7.Apply();
							val5.Release();
							byte[] bytes = ImageConversion.EncodeToPNG(val7);
							File.WriteAllBytes(Path.Combine(texturesPath, ((Object)texture).name + ".png"), bytes);
							result = true;
						}
						catch
						{
						}
						RenderTexture.active = active;
						val4.Release();
					}
					else
					{
						byte[] bytes2 = ImageConversion.EncodeToPNG(texture);
						File.WriteAllBytes(Path.Combine(texturesPath, ((Object)texture).name + ".png"), bytes2);
						result = true;
					}
				}
				catch (Exception ex4)
				{
					ModLogger.Player.Error(((Object)texture).name + " failed because " + ex4.Message);
				}
				return result;
			}
		}

		private static void AssignHandResourcePack(string[] args)
		{
			if (args.Length != 2)
			{
				ModLogger.Player.Error("Invalid number of arguments!");
				ModLogger.Player.Info("Usage: assignhandpack [hand] [pack guid/pack index]\nHand: left or right (case insensitive)\nUse 'listpacks' to see available pack GUIDs");
				return;
			}
			int handIdFromString = GetHandIdFromString(args[0]);
			if (handIdFromString < 0)
			{
				ModLogger.Player.Error("Invalid hand! Must be 'left' or 'right'");
				ModLogger.Player.Info("Usage: assignhandpack [hand] [pack guid/pack index]\nHand: left or right (case insensitive)\nUse 'listpacks' to see available pack GUIDs");
				return;
			}
			ResourcePack packFromArgs = GetPackFromArgs(args, ModLogger.Player.Error, 1);
			if (packFromArgs == null)
			{
				ModLogger.Player.Error("Invalid pack!");
				ModLogger.Player.Info("Usage: assignhandpack [hand] [pack guid/pack index]\nHand: left or right (case insensitive)\nUse 'listpacks' to see available pack GUIDs");
				return;
			}
			RHSpriteManager.OverrideHands(packFromArgs.guid, handIdFromString == 0);
			if (handIdFromString == 0)
			{
				RHConfig.PackPrefs.LeftHandPack = packFromArgs.guid;
			}
			else
			{
				RHConfig.PackPrefs.RightHandPack = packFromArgs.guid;
			}
			RHSpriteManager.ClearHandSprites();
			string text = ((handIdFromString == 0) ? "left" : "right");
			ModLogger.Player.Info("Assigned resource pack '" + packFromArgs.guid + "' to " + text + " hand");
		}

		private static void ClearHandResourcePack(string[] args)
		{
			if (args.Length != 1)
			{
				ModLogger.Player.Error("Invalid number of arguments!");
				ModLogger.Player.Info("Usage: clearhandpack [hand]\nHand: left or right (case insensitive)");
				return;
			}
			int handIdFromString = GetHandIdFromString(args[0]);
			if (handIdFromString < 0)
			{
				ModLogger.Player.Error("Invalid hand! Must be 'left' or 'right'");
				ModLogger.Player.Info("Usage: clearhandpack [hand]\nHand: left or right (case insensitive)");
				return;
			}
			RHSpriteManager.ClearHandsOverride(handIdFromString == 0);
			if (handIdFromString == 0)
			{
				RHConfig.PackPrefs.LeftHandPack = "";
			}
			else
			{
				RHConfig.PackPrefs.RightHandPack = "";
			}
			RHSpriteManager.ClearHandSprites();
			string text = ((handIdFromString == 0) ? "left" : "right");
			ModLogger.Player.Info("Cleared resource pack from " + text + " hand");
		}

		private static void ListHandResourcePack(string[] args)
		{
			ModLogger.Player.Info("Hand Resource Pack Assignments:");
			for (int i = 0; i < 2; i++)
			{
				string text = ((i == 0) ? "Left" : "Right");
				string packGuid = RHSpriteManager.GetHandsOverride(i == 0);
				if (string.IsNullOrEmpty(packGuid))
				{
					ModLogger.Player.Info(text + " Hand: No custom pack assigned");
					continue;
				}
				string text2 = ResourcePacksManager.LoadedPacks.FirstOrDefault((ResourcePack p) => p.guid == packGuid)?.name ?? "Unknown Pack";
				ModLogger.Player.Info(text + " Hand: " + text2 + " (" + packGuid + ")");
			}
			ModLogger.Player.Info("Use 'assignhandpack [hand] [pack guid/pack index]' to assign a pack");
			ModLogger.Player.Info("Use 'clearhandpack [hand]' to clear a hand's pack");
		}

		private static int GetHandIdFromString(string handString)
		{
			if (string.IsNullOrEmpty(handString))
			{
				return -1;
			}
			switch (handString.Trim().ToLowerInvariant())
			{
			case "left":
			case "l":
				return 0;
			case "right":
			case "r":
				return 1;
			default:
				return -1;
			}
		}
	}
	public static class CosmeticStructureRepairer
	{
		private static readonly HashSet<string> ProcessedFolders = new HashSet<string>();

		private static readonly HashSet<string> ReservedNames = new HashSet<string> { "icon", "manifest", "readme", "card-foreground", "card-background" };

		public static bool NeedsFixing(string modFolderPath)
		{
			if (Directory.Exists(Path.Combine(modFolderPath, "Sprites")))
			{
				return !Directory.Exists(Path.Combine(modFolderPath, "Interacts"));
			}
			return true;
		}

		public static void FixModStructure(string modFolderPath, string jsonFileName = "cosmetic-handitem-settings.json")
		{
			if (string.IsNullOrEmpty(modFolderPath) || !Directory.Exists(modFolderPath))
			{
				ModLogger.Warning("[Fixer] Provided path is invalid: " + modFolderPath);
			}
			else
			{
				if (ProcessedFolders.Contains(modFolderPath))
				{
					return;
				}
				try
				{
					string text = Path.Combine(modFolderPath, jsonFileName);
					if (!File.Exists(text))
					{
						return;
					}
					ModLogger.Info("[Fixer] Checking structure for mod: " + Path.GetFileName(modFolderPath));
					Cosmetic_HandItem_Data val = JsonConvert.DeserializeObject<Cosmetic_HandItem_Data>(File.ReadAllText(text));
					if (val == null)
					{
						ModLogger.Error("[Fixer] Failed to deserialize JSON at " + text);
						return;
					}
					string path = Path.Combine(modFolderPath, "Sprites");
					string path2 = Path.Combine(modFolderPath, "Interacts");
					string text2 = Path.Combine(modFolderPath, "Palettes");
					Directory.CreateDirectory(path);
					Directory.CreateDirectory(path2);
					Directory.CreateDirectory(text2);
					HashSet<string> targets = new HashSet<string>();
					HashSet<string> targets2 = new HashSet<string>();
					HashSet<string> hashSet = new HashSet<string>();
					if (val.globalSecondary != null)
					{
						foreach (SecondaryTextures item2 in val.globalSecondary)
						{
							foreach (string secondaryTextureName in item2.secondaryTextureNames)
							{
								hashSet.Add(secondaryTextureName.ToLower());
							}
						}
					}
					MoveMatchingFiles(modFolderPath, targets, "Sprites", "HND_");
					MoveMatchingFiles(modFolderPath, targets, "Sprites", "stamina_");
					MoveMatchingFiles(modFolderPath, targets2, "Interacts", "interact-");
					MoveMatchingFiles(modFolderPath, hashSet, "Palettes", "stamina");
					string[] files = Directory.GetFiles(modFolderPath, "*.png");
					foreach (string text3 in files)
					{
						string item = Path.GetFileNameWithoutExtension(text3).ToLower();
						if (ReservedNames.Contains(item))
						{
							continue;
						}
						try
						{
							string fileName = Path.GetFileName(text3);
							string text4 = Path.Combine(text2, fileName);
							if (File.Exists(text4))
							{
								File.Delete(text4);
							}
							File.Move(text3, text4);
						}
						catch (Exception ex)
						{
							ModLogger.Error("[Fixer] Failed to move leftover file " + text3 + ": " + ex.Message);
						}
					}
					ModLogger.Info("[Fixer] Finished organizing " + Path.GetFileName(modFolderPath));
					ProcessedFolders.Add(modFolderPath);
				}
				catch (Exception ex2)
				{
					ModLogger.Error("[Fixer] CRITICAL ERROR fixing structure at " + modFolderPath + ": " + ex2.Message + "\n" + ex2.StackTrace);
				}
			}
		}

		private static void MoveMatchingFiles(string root, HashSet<string> targets, string subFolder, string prefixFallback = null)
		{
			string text = Path.Combine(root, subFolder);
			string[] files = Directory.GetFiles(root, "*.png");
			foreach (string text2 in files)
			{
				string text3 = Path.GetFileNameWithoutExtension(text2).ToLower();
				string fileName = Path.GetFileName(text2);
				bool flag = targets.Contains(text3);
				if (!flag && !string.IsNullOrEmpty(prefixFallback) && text3.StartsWith(prefixFallback.ToLower()))
				{
					flag = true;
				}
				if (!flag)
				{
					continue;
				}
				try
				{
					if (!Directory.Exists(text))
					{
						Directory.CreateDirectory(text);
					}
					string text4 = Path.Combine(text, fileName);
					if (File.Exists(text4))
					{
						ModLogger.Warning("[Fixer] File " + fileName + " already exists in " + subFolder + ". Overwriting.");
						File.Delete(text4);
					}
					File.Move(text2, text4);
				}
				catch (IOException ex)
				{
					ModLogger.Error("[Fixer] Failed to move " + fileName + ". File may be in use. Error: " + ex.Message);
				}
			}
		}
	}
	public static class CosmeticSystem
	{
		private static GameObject? _holder;

		public static void EnsureExists()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)_holder != (Object)null))
			{
				_holder = new GameObject("RHCosmeticSystem");
				_holder.AddComponent<OF_CosmeticPage>();
				Object.DontDestroyOnLoad((Object)(object)_holder);
				ModLogger.Info("Official Cosmetic Integration initialized.");
			}
		}
	}
	public class RHDebugTools : MonoBehaviour
	{
		public static RHDebugTools? Instance;

		public static bool isOn;

		private static readonly List<AudioClip> PlayingClips = new List<AudioClip>();

		private GUIStyle _style = GUIStyle.none;

		private bool _enableNextFrame;

		internal static void Create()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Instance = new GameObject("DebugTools").AddComponent<RHDebugTools>();
			Object.DontDestroyOnLoad((Object)(object)Instance);
		}

		public static void QueueSound(AudioClip clip, bool force = false)
		{
			CoroutineDispatcher.Dispatch(_queueSound(clip, force));
		}

		private static IEnumerator _queueSound(AudioClip clip, bool force)
		{
			if (force || !PlayingClips.Contains(clip))
			{
				PlayingClips.Add(clip);
				yield return (object)new WaitForSeconds(1f);
				if (Object.op_Implicit((Object)(object)clip))
				{
					PlayingClips.Remove(clip);
				}
			}
		}

		public void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0041: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_005c: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)Instance))
			{
				Instance = this;
			}
			else
			{
				Object.Destroy((Object)(object)this);
			}
			if (RHConfig.AlwaysDebug.Value)
			{
				isOn = true;
			}
			_style = new GUIStyle
			{
				fontSize = 32,
				fontStyle = (FontStyle)1,
				normal = new GUIStyleState
				{
					textColor = Color.white
				}
			};
			SceneManager.sceneUnloaded += delegate
			{
				_enableNextFrame |= isOn;
				isOn = false;
			};
			SceneManager.sceneLoaded += delegate(Scene _, LoadSceneMode mode)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				if ((int)mode == 0)
				{
					PlayingClips.Clear();
					_enableNextFrame |= isOn;
					isOn = false;
				}
			};
		}

		public void OnGUI()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (!isOn)
			{
				return;
			}
			Color contentColor = GUI.contentColor;
			GUI.contentColor = Color.white;
			GUILayout.Label("Recent sounds:", _style, Array.Empty<GUILayoutOption>());
			for (int num = PlayingClips.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)PlayingClips[num] == (Object)null)
				{
					PlayingClips.RemoveAt(num);
				}
			}
			foreach (AudioClip playingClip in PlayingClips)
			{
				GUILayout.Label(((Object)playingClip).name, _style, Array.Empty<GUILayoutOption>());
			}
			GUI.contentColor = contentColor;
		}

		public void LateUpdate()
		{
			if (_enableNextFrame)
			{
				isOn = true;
				_enableNextFrame = false;
			}
		}
	}
	[HarmonyPatch(typeof(Object))]
	public static class DEBUG_InstantiatePatches
	{
		private static void OnInstantiated(Object result, Object original)
		{
			if (!Object.op_Implicit(result))
			{
				return;
			}
			GameObject val = (GameObject)(object)((result is GameObject) ? result : null);
			if (val == null)
			{
				Component val2 = (Component)(object)((result is Component) ? result : null);
				if (val2 != null)
				{
					Component[] componentsInChildren = val2.GetComponentsInChildren<Component>();
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						PatchObject((Object)(object)componentsInChildren[i]);
					}
				}
			}
			else
			{
				Component[] componentsInChildren = val.GetComponentsInChildren<Component>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					PatchObject((Object)(object)componentsInChildren[i]);
				}
			}
			static void PatchObject(Object obj)
			{
				AudioSource val3 = (AudioSource)(object)((obj is AudioSource) ? obj : null);
				if (val3 != null && val3 != null && ((Behaviour)val3).isActiveAndEnabled && val3.playOnAwake)
				{
					RHDebugTools.QueueSound(val3.clip);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[] { typeof(Object) })]
		private static void Postfix_1(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Scene)
		})]
		private static void Postfix_2(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Transform)
		})]
		private static void Postfix_3(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Transform),
			typeof(bool)
		})]
		private static void Postfix_4(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion)
		})]
		private static void Postfix_5(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}

		[HarmonyPostfix]
		[HarmonyPatch("Instantiate", new Type[]
		{
			typeof(Object),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(Transform)
		})]
		private static void Postfix_6(Object __result, Object original)
		{
			OnInstantiated(__result, original);
		}
	}
	[HarmonyPatch(typeof(AudioSource))]
	[HarmonyPriority(200)]
	public static class DEBUG_AudioSourcePatches
	{
		[HarmonyPatch("Play", new Type[] { })]
		[HarmonyPrefix]
		private static void Play_NoArgs_Postfix(AudioSource __instance)
		{
			LogClip(__instance);
		}

		[HarmonyPatch("Play", new Type[] { typeof(double) })]
		[HarmonyPrefix]
		private static void Play_DelayDouble_Postfix(AudioSource __instance)
		{
			LogClip(__instance);
		}

		[HarmonyPatch("Play", new Type[] { typeof(ulong) })]
		[HarmonyPrefix]
		private static void Play_DelayUlong_Postfix(AudioSource __instance)
		{
			LogClip(__instance);
		}

		[HarmonyPatch("PlayOneShot", new Type[] { typeof(AudioClip) })]
		[HarmonyPrefix]
		private static void PlayOneShot_ClipOnly_Postfix(AudioSource __instance, ref AudioClip __0)
		{
			LogClip(null, __0);
		}

		[HarmonyPatch("PlayOneShot", new Type[]
		{
			typeof(AudioClip),
			typeof(float)
		})]
		[HarmonyPrefix]
		private static void PlayOneShot_ClipAndVolume_Postfix(AudioSource __instance, ref AudioClip __0)
		{
			LogClip(null, __0);
		}

		private static void LogClip(AudioSource src = null, AudioClip clip = null)
		{
			if (RHDebugTools.isOn && Object.op_Implicit((Object)(object)clip))
			{
				if (Object.op_Implicit((Object)(object)src))
				{
					clip = src.clip;
				}
				RHDebugTools.QueueSound(clip);
			}
		}
	}
	public static class DynamicHandSlicer
	{
		public enum SheetType
		{
			Background,
			Foreground
		}

		public static Dictionary<Vector2, Texture2D> SliceSheet(Texture2D sheet, int cols, int rows)
		{
			//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_0038: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Vector2, Texture2D> dictionary = new Dictionary<Vector2, Texture2D>();
			int num = ((Texture)sheet).width / cols;
			int num2 = ((Texture)sheet).height / rows;
			Vector2 key = default(Vector2);
			for (int i = 0; i < rows; i++)
			{
				for (int j = 0; j < cols; j++)
				{
					int num3 = rows - 1 - i;
					Texture2D val = new Texture2D(num, num2)
					{
						filterMode = (FilterMode)0
					};
					Color[] pixels = sheet.GetPixels(j * num, num3 * num2, num, num2);
					val.SetPixels(pixels);
					val.Apply();
					((Vector2)(ref key))..ctor((float)i, (float)j);
					dictionary.Add(key, val);
				}
			}
			return dictionary;
		}

		public static Dictionary<string, Texture2D> GetNamedSlicesFromSlicedSheet(SheetType sheetType, Dictionary<Vector2, Texture2D> slices, int layer = 1)
		{
			//IL_002c: 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_003c: 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)
			Dictionary<string, Texture2D> dictionary = new Dictionary<string, Texture2D>();
			string text = ((sheetType == SheetType.Background) ? "B" : "F");
			foreach (KeyValuePair<Vector2, Texture2D> slice in slices)
			{
				Vector2 key = slice.Key;
				Texture2D value = slice.Value;
				int num = (int)Mathf.Abs(key.x);
				string text2 = "";
				text2 = num switch
				{
					0 => "A", 
					1 => "B", 
					2 => "C", 
					3 => "D", 
					_ => "A", 
				};
				string key2 = $"HND_{text}{layer}{text2}{key.y + 1f}";
				dictionary.Add(key2, value);
			}
			return dictionary;
		}
	}
	internal class EmoteWheel : MonoBehaviour
	{
		private Canvas _canvas;

		private RawImage _centerButton;

		private RawImage[] _wheelButtons;

		private Image[] _wheelEmotes;

		private RawImage _cursor;

		private Image _emoteLeft;

		private Image _emoteRight;

		private Vector2 _cursorPos;

		private static readonly Color ActiveColor = new Color(0.6981f, 0.1153f, 0.1153f, 1f);

		private const string KeyInteractLeft = "Hand-Left";

		private const string KeyInteractRight = "Hand-Right";

		private static bool _active;

		public static bool IsActive => _active;

		private void Start()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			if (!HandExtensions.TryGet(0, out HandExtensions ext))
			{
				return;
			}
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = -1;
			((Behaviour)_canvas).enabled = false;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.referenceResolution = new Vector2(400f, 400f);
			obj.uiScaleMode = (ScaleMode)1;
			_centerButton = new GameObject("CenterButton", new Type[1] { typeof(RectTransform) }).AddComponent<RawImage>();
			((Component)_centerButton).transform.SetParent(((Component)_canvas).transform, false);
			_centerButton.texture = (Texture)(object)RHResources.TryGetTexture("EmoteWheel/Wheel_