Decompiled source of HeadElfPlus v1.0.3

HeadElfPlus.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HeadElfPlus")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HeadElfPlus")]
[assembly: AssemblyTitle("HeadElfPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HeadElfPlus
{
	public class BoneScaler : MonoBehaviour
	{
		public static readonly int HashRace = StringExtensionMethods.GetStableHashCode("HeadElfPlus_Race");

		private Player player;

		private Transform spine;

		private Transform neck;

		private Transform head;

		private Transform leftLeg;

		private Transform rightLeg;

		private Race lastRace = Race.Human;

		private void Start()
		{
			player = ((Component)this).GetComponent<Player>();
			FindBones();
		}

		private void FindBones()
		{
			if (!((Object)(object)player == (Object)null))
			{
				GameObject visual = ((Character)player).GetVisual();
				if (!((Object)(object)visual == (Object)null))
				{
					Transform transform = visual.transform;
					spine = FindDeepChild(transform, "Spine");
					neck = FindDeepChild(transform, "Neck");
					head = FindDeepChild(transform, "Head");
					leftLeg = FindDeepChild(transform, "LeftUpLeg") ?? FindDeepChild(transform, "LeftLeg");
					rightLeg = FindDeepChild(transform, "RightUpLeg") ?? FindDeepChild(transform, "RightLeg");
				}
			}
		}

		private void LateUpdate()
		{
			//IL_00d2: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			GameObject visual = ((Character)player).GetVisual();
			if ((Object)(object)visual == (Object)null)
			{
				return;
			}
			if ((Object)(object)spine == (Object)null)
			{
				FindBones();
			}
			Race playerRace = GetPlayerRace(player);
			if (playerRace != lastRace)
			{
				lastRace = playerRace;
				VisEquipment component = ((Component)player).GetComponent<VisEquipment>();
				if ((Object)(object)component != (Object)null)
				{
					((object)component).GetType().GetMethod("UpdateVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component, null);
				}
			}
			ModConfig.RaceConfig config = ModConfig.GetConfig(playerRace);
			Vector3 localScale = ModConfig.ParseVector3(config.HeightScale?.Value, Vector3.one);
			visual.transform.localScale = localScale;
			float num = 0f;
			ZNetView component2 = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component2 != (Object)null && component2.GetZDO() != null)
			{
				num = component2.GetZDO().GetFloat(StringExtensionMethods.GetStableHashCode("player_offset"), 0f);
			}
			float num2 = ((config.VisualOffset != null) ? config.VisualOffset.Value : 0f);
			visual.transform.localPosition = new Vector3(0f, num2 + num, 0f);
			if ((Object)(object)spine != (Object)null)
			{
				Vector3 localScale2 = ((config.BoneSpineScale != null) ? ModConfig.ParseVector3(config.BoneSpineScale.Value, Vector3.one) : Vector3.one);
				spine.localScale = localScale2;
			}
			if ((Object)(object)neck != (Object)null)
			{
				Vector3 localScale3 = ((config.BoneNeckScale != null) ? ModConfig.ParseVector3(config.BoneNeckScale.Value, Vector3.one) : Vector3.one);
				neck.localScale = localScale3;
			}
			if ((Object)(object)head != (Object)null)
			{
				Vector3 localScale4 = ((config.BoneHeadScale != null) ? ModConfig.ParseVector3(config.BoneHeadScale.Value, Vector3.one) : Vector3.one);
				head.localScale = localScale4;
			}
			Vector3 localScale5 = ((config.BoneLegsScale != null) ? ModConfig.ParseVector3(config.BoneLegsScale.Value, Vector3.one) : Vector3.one);
			if ((Object)(object)leftLeg != (Object)null)
			{
				leftLeg.localScale = localScale5;
			}
			if ((Object)(object)rightLeg != (Object)null)
			{
				rightLeg.localScale = localScale5;
			}
		}

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

		public static Race GetPlayerRace(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return Race.Human;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return Race.Human;
			}
			return (Race)component.GetZDO().GetInt(HashRace, 0);
		}

		public static void SetPlayerRace(Player player, Race race)
		{
			if (!((Object)(object)player == (Object)null))
			{
				ZNetView component = ((Component)player).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.GetZDO() != null && component.IsOwner())
				{
					component.GetZDO().Set(HashRace, (int)race, false);
				}
			}
		}
	}
	public class TransformationRitual : MonoBehaviour
	{
		public static TransformationRitual Instance;

		private Player player;

		private bool isPerforming = false;

		private void Awake()
		{
			Instance = this;
			player = ((Component)this).GetComponent<Player>();
		}

		public void StartRitual(Race targetRace, string key)
		{
			if (!isPerforming)
			{
				((MonoBehaviour)this).StartCoroutine(RitualCoroutine(targetRace, key));
			}
		}

		private IEnumerator RitualCoroutine(Race targetRace, string key)
		{
			isPerforming = true;
			((Character)player).Message((MessageType)2, $"Ritual de transformação em {targetRace} iniciado...", 0, (Sprite)null);
			PlayVFX("fx_shaman_protect");
			yield return (object)new WaitForSeconds(0.3f);
			PlayVFX("vfx_ghost_death");
			yield return (object)new WaitForSeconds(2.5f);
			PlayVFX("vfx_spawn");
			yield return (object)new WaitForSeconds(0.2f);
			PlayVFX("vfx_corpse_destruction_small");
			if ((Object)(object)player != (Object)null)
			{
				BoneScaler.SetPlayerRace(player, targetRace);
				TransformationPatches.BypassBlock = true;
				TransformationPatches.RemoveAllRaceKeys(player, key);
				((Humanoid)player).AddUniqueKey(key);
				TransformationPatches.BypassBlock = false;
				((Character)player).Message((MessageType)2, $"Transformação em {targetRace} concluída!", 0, (Sprite)null);
			}
			isPerforming = false;
		}

		private void PlayVFX(string vfxName)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ZNetScene.instance == (Object)null))
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(vfxName);
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, ((Component)player).transform.position, Quaternion.identity);
				}
			}
		}
	}
	public static class ModConfig
	{
		public class RaceConfig
		{
			public ConfigEntry<string> SkinColor;

			public ConfigEntry<string> ItemColor;

			public ConfigEntry<string> ItemPosition;

			public ConfigEntry<string> ItemRotation;

			public ConfigEntry<string> ItemScale;

			public ConfigEntry<string> ItemPositionMale;

			public ConfigEntry<string> ItemRotationMale;

			public ConfigEntry<string> ItemScaleMale;

			public ConfigEntry<string> ItemPositionFemale;

			public ConfigEntry<string> ItemRotationFemale;

			public ConfigEntry<string> ItemScaleFemale;

			public ConfigEntry<string> HeightScale;

			public ConfigEntry<float> VisualOffset;

			public ConfigEntry<string> BoneSpineScale;

			public ConfigEntry<string> BoneNeckScale;

			public ConfigEntry<string> BoneHeadScale;

			public ConfigEntry<string> BoneLegsScale;
		}

		public static ConfigFile ConfigFile;

		public static string LastServerConfigString = "";

		public static bool ReloadPending = false;

		private static bool isDeserializing = false;

		public static RaceConfig Human = new RaceConfig();

		public static RaceConfig Elf = new RaceConfig();

		public static RaceConfig HalfOrc = new RaceConfig();

		public static RaceConfig Undead = new RaceConfig();

		public static RaceConfig Drow = new RaceConfig();

		public static RaceConfig Dwarf = new RaceConfig();

		public static RaceConfig Halfling = new RaceConfig();

		public static RaceConfig HighElf = new RaceConfig();

		public static RaceConfig Child = new RaceConfig();

		public static void Init(ConfigFile config)
		{
			ConfigFile = config;
			Human.HeightScale = config.Bind<string>("0. Human", "HeightScale", "1, 1, 1", "Escala de altura.");
			Human.VisualOffset = config.Bind<float>("0. Human", "VisualOffset", 0f, "Offset visual vertical.");
			Elf.SkinColor = config.Bind<string>("1. Elf", "SkinColor", "#8080CC", "Cor de pele padrão do Elfo.");
			Elf.ItemColor = config.Bind<string>("1. Elf", "ItemColor", "#7e4df192", "Cor da orelha do Elfo.");
			Elf.ItemPosition = config.Bind<string>("1. Elf", "ItemPosition", "0, 0.1, 0", "Posição da orelha.");
			Elf.ItemRotation = config.Bind<string>("1. Elf", "ItemRotation", "-10, -90, 0", "Rotação da orelha.");
			Elf.ItemScale = config.Bind<string>("1. Elf", "ItemScale", "0.55, 0.55, 0.55", "Escala da orelha.");
			Elf.HeightScale = config.Bind<string>("1. Elf", "HeightScale", "0.95, 1, 0.95", "Escala de altura.");
			HalfOrc.SkinColor = config.Bind<string>("2. Half-Orc", "SkinColor", "#6B8E23", "Cor de pele do Meio-Orc.");
			HalfOrc.ItemColor = config.Bind<string>("2. Half-Orc", "ItemColor", "vanilla", "Cor das presas do Meio-Orc.");
			HalfOrc.ItemPositionMale = config.Bind<string>("2. Half-Orc", "ItemPosition_Male", "-0.064, 0.18, 0.003", "Posição das presas (Homem).");
			HalfOrc.ItemRotationMale = config.Bind<string>("2. Half-Orc", "ItemRotation_Male", "9, 270, 1", "Rotação das presas (Homem).");
			HalfOrc.ItemScaleMale = config.Bind<string>("2. Half-Orc", "ItemScale_Male", "0.7, 0.7, 0.75", "Escala das presas (Homem).");
			HalfOrc.ItemPositionFemale = config.Bind<string>("2. Half-Orc", "ItemPosition_Female", "-0.075, 0.17, 0.003", "Posição das presas (Mulher).");
			HalfOrc.ItemRotationFemale = config.Bind<string>("2. Half-Orc", "ItemRotation_Female", "9, 270, 1", "Rotação das presas (Mulher).");
			HalfOrc.ItemScaleFemale = config.Bind<string>("2. Half-Orc", "ItemScale_Female", "0.5, 0.65, 0.6", "Escala das presas (Mulher).");
			HalfOrc.HeightScale = config.Bind<string>("2. Half-Orc", "HeightScale", "1, 1, 1", "Escala de altura.");
			HalfOrc.BoneSpineScale = config.Bind<string>("2. Half-Orc", "BoneSpineScale", "1.3, 1, 1.3", "Escala do osso Spine.");
			HalfOrc.BoneNeckScale = config.Bind<string>("2. Half-Orc", "BoneNeckScale", "0.83, 1, 0.83", "Escala do osso Neck.");
			HalfOrc.BoneHeadScale = config.Bind<string>("2. Half-Orc", "BoneHeadScale", "1, 1, 1", "Escala do osso Head.");
			HalfOrc.BoneLegsScale = config.Bind<string>("2. Half-Orc", "BoneLegsScale", "1.15, 1, 1.15", "Escala dos ossos da Perna.");
			Undead.SkinColor = config.Bind<string>("3. Undead", "SkinColor", "vanilla", "Cor de pele do Undead.");
			Undead.ItemColor = config.Bind<string>("3. Undead", "ItemColor", "#ffffff71", "Cor do item do Undead.");
			Undead.ItemPosition = config.Bind<string>("3. Undead", "ItemPosition", "0.04, 0.13, 0.01", "Posição do item.");
			Undead.ItemRotation = config.Bind<string>("3. Undead", "ItemRotation", "-10, 267, 0", "Rotação do item.");
			Undead.ItemScale = config.Bind<string>("3. Undead", "ItemScale", "1, 1, 1", "Escala do item.");
			Undead.HeightScale = config.Bind<string>("3. Undead", "HeightScale", "1, 1, 1", "Escala de altura.");
			Drow.SkinColor = config.Bind<string>("4. Drow", "SkinColor", "#312626", "Cor de pele do Drow.");
			Drow.ItemColor = config.Bind<string>("4. Drow", "ItemColor", "#312626", "Cor da orelha do Drow.");
			Drow.ItemPosition = config.Bind<string>("4. Drow", "ItemPosition", "0, 0.1, 0", "Posição da orelha.");
			Drow.ItemRotation = config.Bind<string>("4. Drow", "ItemRotation", "-10, -90, 0", "Rotação da orelha.");
			Drow.ItemScale = config.Bind<string>("4. Drow", "ItemScale", "0.6, 0.55, 0.6", "Escala da orelha.");
			Drow.HeightScale = config.Bind<string>("4. Drow", "HeightScale", "0.95, 1, 0.95", "Escala de altura.");
			Dwarf.SkinColor = config.Bind<string>("5. Dwarf", "SkinColor", "vanilla", "Cor de pele do Anão.");
			Dwarf.HeightScale = config.Bind<string>("5. Dwarf", "HeightScale", "0.85, 0.85, 0.85", "Escala de altura.");
			Dwarf.VisualOffset = config.Bind<float>("5. Dwarf", "VisualOffset", 0f, "Offset visual vertical.");
			Dwarf.BoneSpineScale = config.Bind<string>("5. Dwarf", "BoneSpineScale", "1.4, 1, 1.4", "Escala do osso Spine.");
			Dwarf.BoneNeckScale = config.Bind<string>("5. Dwarf", "BoneNeckScale", "0.85, 0.85, 0.85", "Escala do osso Neck.");
			Dwarf.BoneHeadScale = config.Bind<string>("5. Dwarf", "BoneHeadScale", "1.1, 1.1, 1.1", "Escala do osso Head.");
			Dwarf.BoneLegsScale = config.Bind<string>("5. Dwarf", "BoneLegsScale", "1.2, 1, 1.2", "Escala dos ossos da Perna.");
			Halfling.SkinColor = config.Bind<string>("6. Halfling", "SkinColor", "#eedf9c", "Cor de pele.");
			Halfling.ItemColor = config.Bind<string>("6. Halfling", "ItemColor", "#bb9903", "Cor da orelha.");
			Halfling.ItemPosition = config.Bind<string>("6. Halfling", "ItemPosition", "0, 0.1, 0", "Posição da orelha.");
			Halfling.ItemRotation = config.Bind<string>("6. Halfling", "ItemRotation", "-10, -90, 0", "Rotação da orelha.");
			Halfling.ItemScale = config.Bind<string>("6. Halfling", "ItemScale", "0.7, 0.6, 0.4", "Escala da orelha.");
			Halfling.HeightScale = config.Bind<string>("6. Halfling", "HeightScale", "0.8, 0.8, 0.8", "Escala de altura.");
			HighElf.SkinColor = config.Bind<string>("7. High-Elf", "SkinColor", "#f7f6f6", "Cor de pele.");
			HighElf.ItemColor = config.Bind<string>("7. High-Elf", "ItemColor", "#ffc5e9", "Cor da orelha.");
			HighElf.ItemPosition = config.Bind<string>("7. High-Elf", "ItemPosition", "0, 0.1, 0", "Posição.");
			HighElf.ItemRotation = config.Bind<string>("7. High-Elf", "ItemRotation", "-10, -90, 0", "Rotação.");
			HighElf.ItemScale = config.Bind<string>("7. High-Elf", "ItemScale", "0.55, 0.55, 0.55", "Escala.");
			HighElf.HeightScale = config.Bind<string>("7. High-Elf", "HeightScale", "0.95, 1, 0.95", "Escala de altura.");
			Child.HeightScale = config.Bind<string>("8. Child", "HeightScale", "0.75, 0.75, 0.75", "Escala de altura.");
			try
			{
				FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(config.ConfigFilePath), Path.GetFileName(config.ConfigFilePath));
				fileSystemWatcher.Changed += delegate
				{
					if (!NetworkManager.IsServerLocked)
					{
						ReloadPending = true;
					}
				};
				fileSystemWatcher.EnableRaisingEvents = true;
			}
			catch
			{
			}
			config.SettingChanged += delegate
			{
				if (!isDeserializing)
				{
					if (NetworkManager.IsServerLocked && !string.IsNullOrEmpty(LastServerConfigString))
					{
						DeserializeConfig(LastServerConfigString);
					}
					else
					{
						if ((Object)(object)ZNet.instance != (Object)null && (ZNet.instance.IsServer() || ZNet.instance.IsDedicated()) && ZRoutedRpc.instance != null)
						{
							ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "HeadElfPlus_SyncConfig", new object[1] { SerializeConfig() });
						}
						ForceUpdateAllVisuals();
					}
				}
			};
		}

		public static void ForceUpdateAllVisuals()
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				VisEquipment component = ((Component)allPlayer).GetComponent<VisEquipment>();
				if ((Object)(object)component != (Object)null)
				{
					((object)component).GetType().GetMethod("UpdateVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component, null);
				}
			}
		}

		public static RaceConfig GetConfig(Race race)
		{
			return race switch
			{
				Race.Elf => Elf, 
				Race.HalfOrc => HalfOrc, 
				Race.Undead => Undead, 
				Race.Drow => Drow, 
				Race.Dwarf => Dwarf, 
				Race.Halfling => Halfling, 
				Race.HighElf => HighElf, 
				Race.Child => Child, 
				_ => Human, 
			};
		}

		public static Vector3 ParseVector3(string val, Vector3 defaultVal)
		{
			//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_008c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(val))
			{
				return defaultVal;
			}
			string[] array = val.Split(',');
			if (array.Length == 3 && float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return new Vector3(result, result2, result3);
			}
			return defaultVal;
		}

		public static Color? ParseColor(string val)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(val) || val.Equals("vanilla", StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			Color value = default(Color);
			if (ColorUtility.TryParseHtmlString(val, ref value))
			{
				return value;
			}
			return null;
		}

		public static string SerializeConfig()
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (Race value in Enum.GetValues(typeof(Race)))
			{
				RaceConfig config = GetConfig(value);
				stringBuilder.Append((config.SkinColor?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemColor?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemPosition?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemRotation?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemScale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemPositionMale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemRotationMale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemScaleMale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemPositionFemale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemRotationFemale?.Value ?? "null") + "|");
				stringBuilder.Append((config.ItemScaleFemale?.Value ?? "null") + "|");
				stringBuilder.Append((config.HeightScale?.Value ?? "null") + "|");
				stringBuilder.Append(((config.VisualOffset != null) ? config.VisualOffset.Value.ToString(CultureInfo.InvariantCulture) : "null") + "|");
				stringBuilder.Append((config.BoneSpineScale?.Value ?? "null") + "|");
				stringBuilder.Append((config.BoneNeckScale?.Value ?? "null") + "|");
				stringBuilder.Append((config.BoneHeadScale?.Value ?? "null") + "|");
				stringBuilder.Append((config.BoneLegsScale?.Value ?? "null") ?? "");
				stringBuilder.Append("||");
			}
			return stringBuilder.ToString();
		}

		public static void DeserializeConfig(string data)
		{
			isDeserializing = true;
			LastServerConfigString = data;
			string[] array = data.Split(new string[1] { "||" }, StringSplitOptions.None);
			int num = 0;
			foreach (Race value in Enum.GetValues(typeof(Race)))
			{
				if (num >= array.Length || string.IsNullOrEmpty(array[num]))
				{
					break;
				}
				RaceConfig config = GetConfig(value);
				string[] array2 = array[num].Split('|');
				if (array2.Length >= 17)
				{
					if (config.SkinColor != null && array2[0] != "null")
					{
						config.SkinColor.Value = array2[0];
					}
					if (config.ItemColor != null && array2[1] != "null")
					{
						config.ItemColor.Value = array2[1];
					}
					if (config.ItemPosition != null && array2[2] != "null")
					{
						config.ItemPosition.Value = array2[2];
					}
					if (config.ItemRotation != null && array2[3] != "null")
					{
						config.ItemRotation.Value = array2[3];
					}
					if (config.ItemScale != null && array2[4] != "null")
					{
						config.ItemScale.Value = array2[4];
					}
					if (config.ItemPositionMale != null && array2[5] != "null")
					{
						config.ItemPositionMale.Value = array2[5];
					}
					if (config.ItemRotationMale != null && array2[6] != "null")
					{
						config.ItemRotationMale.Value = array2[6];
					}
					if (config.ItemScaleMale != null && array2[7] != "null")
					{
						config.ItemScaleMale.Value = array2[7];
					}
					if (config.ItemPositionFemale != null && array2[8] != "null")
					{
						config.ItemPositionFemale.Value = array2[8];
					}
					if (config.ItemRotationFemale != null && array2[9] != "null")
					{
						config.ItemRotationFemale.Value = array2[9];
					}
					if (config.ItemScaleFemale != null && array2[10] != "null")
					{
						config.ItemScaleFemale.Value = array2[10];
					}
					if (config.HeightScale != null && array2[11] != "null")
					{
						config.HeightScale.Value = array2[11];
					}
					if (config.VisualOffset != null && array2[12] != "null" && float.TryParse(array2[12], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
					{
						config.VisualOffset.Value = result;
					}
					if (config.BoneSpineScale != null && array2[13] != "null")
					{
						config.BoneSpineScale.Value = array2[13];
					}
					if (config.BoneNeckScale != null && array2[14] != "null")
					{
						config.BoneNeckScale.Value = array2[14];
					}
					if (config.BoneHeadScale != null && array2[15] != "null")
					{
						config.BoneHeadScale.Value = array2[15];
					}
					if (config.BoneLegsScale != null && array2[16] != "null")
					{
						config.BoneLegsScale.Value = array2[16];
					}
				}
				num++;
			}
			isDeserializing = false;
		}
	}
	[HarmonyPatch]
	public static class NetworkManager
	{
		public static bool IsServerLocked;

		[HarmonyPatch(typeof(ZNet), "Awake")]
		[HarmonyPostfix]
		private static void ZNetAwakePostfix(ZNet __instance)
		{
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.Register<string>("HeadElfPlus_SyncConfig", (Action<long, string>)RPC_SyncConfig);
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPostfix]
		private static void RPCPeerInfoPostfix(ZNet __instance, ZRpc rpc, ZPackage pkg)
		{
			if (!__instance.IsServer() && !__instance.IsDedicated())
			{
				return;
			}
			foreach (ZNetPeer peer in __instance.GetPeers())
			{
				if (peer.m_rpc == rpc)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "HeadElfPlus_SyncConfig", new object[1] { ModConfig.SerializeConfig() });
					break;
				}
			}
		}

		private static void RPC_SyncConfig(long sender, string configData)
		{
			if (ZNet.instance.IsServer() || ZNet.instance.IsDedicated())
			{
				return;
			}
			IsServerLocked = true;
			ModConfig.DeserializeConfig(configData);
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				VisEquipment component = ((Component)allPlayer).GetComponent<VisEquipment>();
				if ((Object)(object)component != (Object)null)
				{
					((object)component).GetType().GetMethod("UpdateVisuals", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component, null);
				}
			}
		}
	}
	public static class VisualsManager
	{
		private static Material undeadMaterial;

		private static Dictionary<VisEquipment, Material[]> originalMaterials = new Dictionary<VisEquipment, Material[]>();

		public static void ApplyRacialAttachments(VisEquipment vis)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_012b: 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_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: 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_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Expected O, but got Unknown
			Player componentInParent = ((Component)vis).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			Race playerRace = BoneScaler.GetPlayerRace(componentInParent);
			Transform val = BoneScaler.FindDeepChild(((Component)vis).transform, "Head");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			foreach (Transform item in val)
			{
				Transform val2 = item;
				if (((Object)val2).name.StartsWith("RaceVisual_Hack") || ((Object)val2).name == "HeadElf_Container" || ((Object)val2).name == "HeadElf_Container_V2")
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
			if (playerRace == Race.Human || playerRace == Race.Child)
			{
				return;
			}
			ModConfig.RaceConfig config = ModConfig.GetConfig(playerRace);
			if (config == null)
			{
				return;
			}
			GameObject val3 = new GameObject("HeadElf_Container_V2");
			val3.transform.SetParent(val, false);
			val3.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.identity;
			Transform transform = val3.transform;
			string text = "";
			if (playerRace == Race.Elf || playerRace == Race.HighElf || playerRace == Race.Drow || playerRace == Race.Halfling)
			{
				text = "TrophyGoblin";
			}
			else
			{
				switch (playerRace)
				{
				case Race.HalfOrc:
					text = "HelmetBerserkerUndead";
					break;
				case Race.Undead:
					text = "TrophySkeleton";
					break;
				}
			}
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Transform val4 = prefab.transform.Find("attach") ?? prefab.transform.Find("Visual") ?? prefab.transform;
			ZNetView.m_forceDisableInit = true;
			GameObject val5 = Object.Instantiate<GameObject>(((Component)val4).gameObject, transform, false);
			ZNetView.m_forceDisableInit = false;
			((Object)val5).name = $"RaceVisual_Hack_{playerRace}";
			Component[] componentsInChildren = val5.GetComponentsInChildren<Component>();
			foreach (Component val6 in componentsInChildren)
			{
				if (!(val6 is Transform) && !(val6 is MeshFilter) && !(val6 is MeshRenderer) && !(val6 is SkinnedMeshRenderer))
				{
					Object.DestroyImmediate((Object)(object)val6);
				}
			}
			int modelIndex = vis.GetModelIndex();
			Vector3 zero = Vector3.zero;
			Vector3 zero2 = Vector3.zero;
			Vector3 one = Vector3.one;
			if (playerRace == Race.HalfOrc)
			{
				if (modelIndex == 1)
				{
					zero = ModConfig.ParseVector3(config.ItemPositionFemale?.Value, Vector3.zero);
					zero2 = ModConfig.ParseVector3(config.ItemRotationFemale?.Value, Vector3.zero);
					one = ModConfig.ParseVector3(config.ItemScaleFemale?.Value, Vector3.one);
				}
				else
				{
					zero = ModConfig.ParseVector3(config.ItemPositionMale?.Value, Vector3.zero);
					zero2 = ModConfig.ParseVector3(config.ItemRotationMale?.Value, Vector3.zero);
					one = ModConfig.ParseVector3(config.ItemScaleMale?.Value, Vector3.one);
				}
			}
			else
			{
				zero = ModConfig.ParseVector3(config.ItemPosition?.Value, Vector3.zero);
				zero2 = ModConfig.ParseVector3(config.ItemRotation?.Value, Vector3.zero);
				one = ModConfig.ParseVector3(config.ItemScale?.Value, Vector3.one);
			}
			val5.transform.localPosition = zero;
			val5.transform.localRotation = Quaternion.Euler(zero2);
			val5.transform.localScale = one;
			if (!(text == "TrophyGoblin"))
			{
				return;
			}
			Color? val7 = null;
			if (config.ItemColor != null)
			{
				val7 = ModConfig.ParseColor(config.ItemColor.Value);
			}
			if (!val7.HasValue)
			{
				Vector3 val8 = Vector3.one;
				ZNetView componentInParent2 = ((Component)vis).GetComponentInParent<ZNetView>();
				if ((Object)(object)componentInParent2 != (Object)null && componentInParent2.GetZDO() != null)
				{
					val8 = componentInParent2.GetZDO().GetVec3(ZDOVars.s_skinColor, Vector3.one);
				}
				val7 = new Color(val8.x, val8.y, val8.z);
			}
			if (!val7.HasValue)
			{
				return;
			}
			Renderer[] componentsInChildren2 = val5.GetComponentsInChildren<Renderer>();
			foreach (Renderer val9 in componentsInChildren2)
			{
				if ((playerRace == Race.HighElf || playerRace == Race.Undead) && (Object)(object)vis.m_bodyModel != (Object)null && ((Renderer)vis.m_bodyModel).materials.Length != 0)
				{
					val9.material = new Material(((Renderer)vis.m_bodyModel).materials[0]);
					val9.material.mainTexture = null;
					val9.material.SetTexture("_MainTex", (Texture)null);
					val9.material.SetTexture("_SkinBumpMap", (Texture)null);
				}
				if ((Object)(object)val9.material != (Object)null)
				{
					val9.material.color = val7.Value;
					val9.material.SetColor("_SkinColor", val7.Value);
				}
			}
		}

		public static void ApplyUndeadFeatures(VisEquipment vis)
		{
			Player componentInParent = ((Component)vis).GetComponentInParent<Player>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				Race playerRace = BoneScaler.GetPlayerRace(componentInParent);
				if (playerRace == Race.Undead)
				{
					SetMeshActive(vis, "m_hairItemInstance", active: false);
					SetMeshActive(vis, "m_beardItemInstance", active: false);
				}
				else
				{
					SetMeshActive(vis, "m_hairItemInstance", active: true);
					SetMeshActive(vis, "m_beardItemInstance", active: true);
				}
			}
		}

		public static void ApplySkinColor(VisEquipment vis)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: 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_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			Player componentInParent = ((Component)vis).GetComponentInParent<Player>();
			if ((Object)(object)componentInParent == (Object)null || (Object)(object)vis.m_bodyModel == (Object)null)
			{
				return;
			}
			Race playerRace = BoneScaler.GetPlayerRace(componentInParent);
			if (playerRace != Race.Undead && originalMaterials.ContainsKey(vis))
			{
				((Renderer)vis.m_bodyModel).materials = originalMaterials[vis];
				originalMaterials.Remove(vis);
				ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.GetZDO() != null)
				{
					Color val = Utils.Vec3ToColor(component.GetZDO().GetVec3(ZDOVars.s_skinColor, Vector3.one));
					Color val2 = Utils.Vec3ToColor(component.GetZDO().GetVec3(ZDOVars.s_hairColor, Vector3.one));
					if (((Renderer)vis.m_bodyModel).materials.Length != 0)
					{
						((Renderer)vis.m_bodyModel).materials[0].SetColor("_SkinColor", val);
					}
					if (((Renderer)vis.m_bodyModel).materials.Length > 1)
					{
						((Renderer)vis.m_bodyModel).materials[1].SetColor("_SkinColor", val2);
					}
				}
			}
			switch (playerRace)
			{
			case Race.Human:
				return;
			case Race.Undead:
			{
				Material val3 = GetUndeadMaterial();
				if ((Object)(object)val3 != (Object)null)
				{
					if (!originalMaterials.ContainsKey(vis))
					{
						originalMaterials[vis] = ((Renderer)vis.m_bodyModel).materials;
					}
					Material[] array = (Material[])(object)new Material[((Renderer)vis.m_bodyModel).materials.Length];
					for (int i = 0; i < array.Length; i++)
					{
						array[i] = val3;
					}
					((Renderer)vis.m_bodyModel).materials = array;
				}
				break;
			}
			}
			ModConfig.RaceConfig config = ModConfig.GetConfig(playerRace);
			if (config != null && config.SkinColor != null && config.SkinColor.Value.ToLower() != "vanilla")
			{
				Color? val4 = ModConfig.ParseColor(config.SkinColor.Value);
				if (val4.HasValue)
				{
					Material[] materials = ((Renderer)vis.m_bodyModel).materials;
					foreach (Material val5 in materials)
					{
						val5.SetColor("_SkinColor", val4.Value);
						val5.color = val4.Value;
					}
				}
			}
			Color? val6 = null;
			if (playerRace == Race.HighElf || playerRace == Race.Elf)
			{
				val6 = Color.white;
			}
			else if (playerRace == Race.HalfOrc)
			{
				val6 = Color.red;
			}
			if (val6.HasValue)
			{
				if (((Renderer)vis.m_bodyModel).materials.Length > 1)
				{
					((Renderer)vis.m_bodyModel).materials[1].SetColor("_SkinColor", val6.Value);
				}
				SetMeshActiveColor(vis, "m_hairItemInstance", val6.Value);
				SetMeshActiveColor(vis, "m_beardItemInstance", val6.Value);
			}
		}

		private static void SetMeshActiveColor(VisEquipment vis, string fieldName, Color color)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo field = ((object)vis).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field != null))
			{
				return;
			}
			object? value = field.GetValue(vis);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				Renderer componentInChildren = val.GetComponentInChildren<Renderer>();
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.material != (Object)null)
				{
					componentInChildren.material.SetColor("_SkinColor", color);
				}
			}
		}

		private static void SetMeshActive(VisEquipment vis, string fieldName, bool active)
		{
			FieldInfo field = ((object)vis).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(vis);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(active);
				}
			}
		}

		private static Material GetUndeadMaterial()
		{
			if ((Object)(object)undeadMaterial != (Object)null)
			{
				return undeadMaterial;
			}
			Material[] array = Resources.FindObjectsOfTypeAll<Material>();
			Material[] array2 = array;
			foreach (Material val in array2)
			{
				if (((Object)val).name.Equals("UndeadMaterial", StringComparison.OrdinalIgnoreCase))
				{
					undeadMaterial = val;
					return undeadMaterial;
				}
			}
			ZNetScene instance = ZNetScene.instance;
			GameObject val2 = ((instance != null) ? instance.GetPrefab("Skeleton") : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Renderer componentInChildren = val2.GetComponentInChildren<Renderer>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					undeadMaterial = componentInChildren.material;
				}
			}
			return undeadMaterial;
		}
	}
	public enum Race
	{
		Human,
		Elf,
		HalfOrc,
		Undead,
		Drow,
		Dwarf,
		Halfling,
		HighElf,
		Child
	}
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public static class ChatPatches
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleOptionsFetcher <>9__0_1;

			internal void <Postfix>b__0_0(ConsoleEventArgs args)
			{
				if ((Object)(object)Console.instance == (Object)null || !((Terminal)Console.instance).IsCheatsEnabled() || !Player.m_debugMode)
				{
					args.Context.AddString("Erro: devcommands e debugmode precisam estar ativados para usar este comando.");
					return;
				}
				if (args.Length < 2)
				{
					args.Context.AddString("Uso: /race [nome_da_raca] [nome_do_jogador]");
					return;
				}
				string text = args[1].Replace("-", "").ToLower();
				Race race = Race.Human;
				bool flag = false;
				foreach (Race value in Enum.GetValues(typeof(Race)))
				{
					if (value.ToString().ToLower().Replace("-", "") == text)
					{
						race = value;
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					args.Context.AddString("Raça '" + args[1] + "' inválida. Opções: Elf, High-Elf, Drow, Dwarf, Halfling, Half-Orc, Child, Undead, Human.");
					return;
				}
				Player val = Player.m_localPlayer;
				if (args.Length >= 3)
				{
					<>c__DisplayClass0_0 CS$<>8__locals1 = new <>c__DisplayClass0_0
					{
						playerName = args[2].ToLower()
					};
					val = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => p.GetPlayerName().ToLower() == CS$<>8__locals1.playerName));
					if ((Object)(object)val == (Object)null)
					{
						args.Context.AddString("Jogador '" + args[2] + "' não encontrado.");
						return;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					BoneScaler.SetPlayerRace(val, race);
					args.Context.AddString($"Raça de {val.GetPlayerName()} alterada para {race}.");
				}
			}

			internal List<string> <Postfix>b__0_1()
			{
				return Enum.GetNames(typeof(Race)).ToList();
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass0_0
		{
			public string playerName;

			internal bool <Postfix>b__2(Player p)
			{
				return p.GetPlayerName().ToLower() == playerName;
			}
		}

		[HarmonyPostfix]
		private static void Postfix()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					if ((Object)(object)Console.instance == (Object)null || !((Terminal)Console.instance).IsCheatsEnabled() || !Player.m_debugMode)
					{
						args.Context.AddString("Erro: devcommands e debugmode precisam estar ativados para usar este comando.");
					}
					else if (args.Length < 2)
					{
						args.Context.AddString("Uso: /race [nome_da_raca] [nome_do_jogador]");
					}
					else
					{
						string text = args[1].Replace("-", "").ToLower();
						Race race = Race.Human;
						bool flag = false;
						foreach (Race value in Enum.GetValues(typeof(Race)))
						{
							if (value.ToString().ToLower().Replace("-", "") == text)
							{
								race = value;
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							args.Context.AddString("Raça '" + args[1] + "' inválida. Opções: Elf, High-Elf, Drow, Dwarf, Halfling, Half-Orc, Child, Undead, Human.");
						}
						else
						{
							Player val3 = Player.m_localPlayer;
							if (args.Length >= 3)
							{
								string playerName = args[2].ToLower();
								val3 = ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => p.GetPlayerName().ToLower() == playerName));
								if ((Object)(object)val3 == (Object)null)
								{
									args.Context.AddString("Jogador '" + args[2] + "' não encontrado.");
									return;
								}
							}
							if ((Object)(object)val3 != (Object)null)
							{
								BoneScaler.SetPlayerRace(val3, race);
								args.Context.AddString($"Raça de {val3.GetPlayerName()} alterada para {race}.");
							}
						}
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleOptionsFetcher val2 = () => Enum.GetNames(typeof(Race)).ToList();
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("race", "[nome_da_raca] [nome_do_jogador] - Altera a raça do jogador.", (ConsoleEvent)obj, false, false, false, false, true, (ConsoleOptionsFetcher)obj2, false, false, false);
		}
	}
	[HarmonyPatch]
	public static class PlayerPatches
	{
		[HarmonyPatch(typeof(Player), "Awake")]
		[HarmonyPostfix]
		private static void PlayerAwakePostfix(Player __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<BoneScaler>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<BoneScaler>();
			}
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<TransformationRitual>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<TransformationRitual>();
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		[HarmonyPostfix]
		private static void PlayerOnSpawnedPostfix(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Race race = Race.Human;
			foreach (string uniqueKey in __instance.GetUniqueKeys())
			{
				Race? race2 = TransformationPatches.ParseRaceFromKey(uniqueKey);
				if (race2.HasValue && race2 != Race.Human)
				{
					race = race2.Value;
					break;
				}
			}
			BoneScaler.SetPlayerRace(__instance, race);
		}

		[HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")]
		[HarmonyPostfix]
		private static void VisEqUpdateEquipmentVisualsPostfix(VisEquipment __instance)
		{
			if (__instance.m_isPlayer)
			{
				VisualsManager.ApplyRacialAttachments(__instance);
				VisualsManager.ApplyUndeadFeatures(__instance);
			}
		}

		[HarmonyPatch(typeof(VisEquipment), "UpdateColors")]
		[HarmonyPostfix]
		private static void VisEqUpdateColorsPostfix(VisEquipment __instance)
		{
			if (__instance.m_isPlayer)
			{
				VisualsManager.ApplySkinColor(__instance);
			}
		}
	}
	[HarmonyPatch]
	public static class TransformationPatches
	{
		public static bool BypassBlock;

		public static Race? ParseRaceFromKey(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return null;
			}
			string text = key.ToLowerInvariant();
			if (text.StartsWith("limiar do elfo"))
			{
				return Race.Elf;
			}
			if (text.StartsWith("limiar do drow"))
			{
				return Race.Drow;
			}
			if (text.StartsWith("limiar do high-elf"))
			{
				return Race.HighElf;
			}
			if (text.StartsWith("limiar do halfling"))
			{
				return Race.Halfling;
			}
			if (text.StartsWith("limiar do dwarf"))
			{
				return Race.Dwarf;
			}
			if (text.StartsWith("limiar do meio-orc"))
			{
				return Race.HalfOrc;
			}
			if (text.StartsWith("limiar da criança"))
			{
				return Race.Child;
			}
			if (text.StartsWith("limiar do morto-vivo"))
			{
				return Race.Undead;
			}
			if (text.StartsWith("limiar do humano"))
			{
				return Race.Human;
			}
			return null;
		}

		public static void RemoveAllRaceKeys(Player player, string excludeKey = "")
		{
			List<string> list = new List<string>();
			foreach (string uniqueKey in player.GetUniqueKeys())
			{
				if (uniqueKey != excludeKey && ParseRaceFromKey(uniqueKey).HasValue)
				{
					list.Add(uniqueKey);
				}
			}
			foreach (string item in list)
			{
				((Humanoid)player).RemoveUniqueKey(item);
			}
		}

		[HarmonyPatch(typeof(Player), "AddUniqueKey")]
		[HarmonyPrefix]
		private static bool AddUniqueKeyPrefix(Player __instance, string name)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			if (BypassBlock)
			{
				return true;
			}
			Race? race = ParseRaceFromKey(name);
			if (race.HasValue)
			{
				Race playerRace = BoneScaler.GetPlayerRace(__instance);
				if (playerRace != race.Value)
				{
					TransformationRitual component = ((Component)__instance).GetComponent<TransformationRitual>();
					if ((Object)(object)component != (Object)null)
					{
						component.StartRitual(race.Value, name);
					}
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Player), "RemoveUniqueKey")]
		[HarmonyPostfix]
		private static void RemoveUniqueKeyPostfix(Player __instance, string name)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || BypassBlock || !ParseRaceFromKey(name).HasValue)
			{
				return;
			}
			bool flag = false;
			foreach (string uniqueKey in __instance.GetUniqueKeys())
			{
				if (ParseRaceFromKey(uniqueKey).HasValue)
				{
					flag = true;
					break;
				}
			}
			if (!flag && BoneScaler.GetPlayerRace(__instance) != Race.Human)
			{
				BoneScaler.SetPlayerRace(__instance, Race.Human);
				((Character)__instance).Message((MessageType)2, "A magia se esvaiu. Você retornou à forma Humana.", 0, (Sprite)null);
			}
		}
	}
	[BepInPlugin("HeadElfPlus.Mod", "HeadElfPlus", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "HeadElfPlus.Mod";

		public const string Name = "HeadElfPlus";

		public const string Version = "1.0.0";

		public static Plugin Instance;

		public static ManualLogSource MLogger;

		private void Awake()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Instance = this;
			MLogger = ((BaseUnityPlugin)this).Logger;
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			Harmony val = new Harmony("HeadElfPlus.Mod");
			val.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HeadElfPlus v1.0.0 initialized successfully.");
		}

		private void Update()
		{
			if (ModConfig.ReloadPending)
			{
				ModConfig.ReloadPending = false;
				((BaseUnityPlugin)this).Config.Reload();
				ModConfig.ForceUpdateAllVisuals();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Configurações recarregadas automaticamente do disco.");
			}
		}
	}
}