Decompiled source of GlitnirRacesKingdom v0.0.5

GlitnirRaces.dll

Decompiled 2 weeks 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 HarmonyLib;
using Jotunn.Managers;
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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("GlitnirRaces")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GlitnirRaces")]
[assembly: AssemblyTitle("GlitnirRaces")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("glitnir.races", "Glitnir Races", "2.1.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class GlitnirRacesPlugin : BaseUnityPlugin
{
	public class RaceConfig
	{
		public string RaceId;

		public string DisplayName;

		public ConfigEntry<bool> Enabled;

		public ConfigEntry<string> Scale;

		public ConfigEntry<string> SkinColor;

		public ConfigEntry<string> EarColor;

		public ConfigEntry<string> EyeColor;

		public ConfigEntry<string> SecretCode;

		public ConfigEntry<string> Players;
	}

	[HarmonyPatch(typeof(Player), "OnSpawned")]
	private static class PlayerSpawnedPatch
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Instance == (Object)null))
			{
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					Instance.RestoreLocalSavedRaceIfNeeded();
				}
				if (HasPlayer(LockedPlayers, __instance) || IsPlayerLocked(__instance))
				{
					SetZdoLocked(__instance, locked: true);
				}
				Instance.ApplyRaceWithDelays(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Player), "OnDeath")]
	private static class PlayerDeathPatch
	{
		private static void Prefix(Player __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Instance == (Object)null))
			{
				Instance.RemovePlayerAttachment(__instance, "JotunFreeze");
			}
		}
	}

	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	private static class ZNetShutdownPatch
	{
		private static void Prefix()
		{
			NetworkRaces.Clear();
			LastAppliedRace.Clear();
			OriginalSkinColors.Clear();
			LastSkinRefreshRequest.Clear();
			OrcHelmetOriginalScale.Clear();
			OrcHelmetOriginalPosition.Clear();
			RegisteredSecretCodes.Clear();
			RpcRegistered = false;
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.lastBroadcastRace = null;
			}
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetSkinColor")]
	private static class PreventForcedRaceSkinOverridePatch
	{
		private static bool Prefix(VisEquipment __instance, Vector3 __0)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || IsApplyingRace)
			{
				return true;
			}
			Player component = ((Component)__instance).GetComponent<Player>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			string race = GetRace(component);
			if (!RaceUsesForcedSkin(race))
			{
				return true;
			}
			CacheOriginalSkinValue(component, __0);
			if ((Object)(object)Instance != (Object)null)
			{
				Instance.ForceSkinAfterVanilla(component, race);
			}
			return false;
		}
	}

	[HarmonyPatch]
	private static class VisEquipmentOnlineRefreshPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private string[] <names>5__1;

			private string[] <>s__2;

			private int <>s__3;

			private string <name>5__4;

			private MethodInfo <method>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<names>5__1 = null;
				<>s__2 = null;
				<name>5__4 = null;
				<method>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_00eb;
				}
				<>1__state = -1;
				<names>5__1 = new string[9] { "UpdateEquipmentVisuals", "UpdateVisuals", "SetChestItem", "SetLegItem", "SetHelmetItem", "SetShoulderItem", "SetUtilityItem", "SetLeftItem", "SetRightItem" };
				<>s__2 = <names>5__1;
				<>s__3 = 0;
				goto IL_0108;
				IL_00eb:
				<method>5__5 = null;
				<name>5__4 = null;
				<>s__3++;
				goto IL_0108;
				IL_0108:
				if (<>s__3 < <>s__2.Length)
				{
					<name>5__4 = <>s__2[<>s__3];
					<method>5__5 = AccessTools.Method(typeof(VisEquipment), <name>5__4, (Type[])null, (Type[])null);
					if (<method>5__5 != null)
					{
						<>2__current = <method>5__5;
						<>1__state = 1;
						return true;
					}
					goto IL_00eb;
				}
				<>s__2 = null;
				return false;
			}

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

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

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

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

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

		private static void Postfix(VisEquipment __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Instance == (Object)null) && !IsApplyingRace)
			{
				Instance.ForceSkinAfterVanilla(__instance);
			}
		}
	}

	[HarmonyPatch]
	private static class PlayerOnlineRefreshPatch
	{
		[CompilerGenerated]
		private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private string[] <names>5__1;

			private string[] <>s__2;

			private int <>s__3;

			private string <name>5__4;

			private MethodInfo <method>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<names>5__1 = null;
				<>s__2 = null;
				<name>5__4 = null;
				<method>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					goto IL_00ba;
				}
				<>1__state = -1;
				<names>5__1 = new string[3] { "UpdateEquipment", "OnInventoryChanged", "UpdateVisual" };
				<>s__2 = <names>5__1;
				<>s__3 = 0;
				goto IL_00d7;
				IL_00ba:
				<method>5__5 = null;
				<name>5__4 = null;
				<>s__3++;
				goto IL_00d7;
				IL_00d7:
				if (<>s__3 < <>s__2.Length)
				{
					<name>5__4 = <>s__2[<>s__3];
					<method>5__5 = AccessTools.Method(typeof(Player), <name>5__4, (Type[])null, (Type[])null);
					if (<method>5__5 != null)
					{
						<>2__current = <method>5__5;
						<>1__state = 1;
						return true;
					}
					goto IL_00ba;
				}
				<>s__2 = null;
				return false;
			}

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

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

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

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

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

		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)Instance == (Object)null) && !IsApplyingRace)
			{
				Instance.RequestOnlineVisualRefresh(__instance);
			}
		}
	}

	[HarmonyPatch(typeof(Chat), "InputText")]
	private static class ChatPatch
	{
		private static bool Prefix(Chat __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			string text = "";
			try
			{
				FieldInfo field = typeof(Chat).GetField("m_input", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field == null)
				{
					return true;
				}
				object value = field.GetValue(__instance);
				if (value == null)
				{
					return true;
				}
				text = (value.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public)?.GetValue(value) as string)?.Trim() ?? "";
			}
			catch
			{
				return true;
			}
			string raceFromSecretCode = GetRaceFromSecretCode(text);
			if (raceFromSecretCode == null)
			{
				return true;
			}
			TransformLocalPlayerFromMarketplace(raceFromSecretCode);
			try
			{
				object obj2 = typeof(Chat).GetField("m_input", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(__instance);
				PropertyInfo propertyInfo = obj2?.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				if (propertyInfo != null && propertyInfo.CanWrite)
				{
					propertyInfo.SetValue(obj2, "");
				}
			}
			catch
			{
			}
			return false;
		}
	}

	[CompilerGenerated]
	private sealed class <ApplyRaceDelayed>d__78 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player p;

		public float delay;

		public GlitnirRacesPlugin <>4__this;

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

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

		[DebuggerHidden]
		public <ApplyRaceDelayed>d__78(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

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

		private bool MoveNext()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(delay);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if ((Object)(object)p != (Object)null)
				{
					<>4__this.ApplyRace(p);
				}
				return false;
			}
		}

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

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

	[CompilerGenerated]
	private sealed class <ForceSkinRefresh>d__80 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player p;

		public string race;

		public GlitnirRacesPlugin <>4__this;

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

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

		[DebuggerHidden]
		public <ForceSkinRefresh>d__80(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

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

		private bool MoveNext()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<>4__this.ForceSkinNow(p, race);
				<>2__current = (object)new WaitForSeconds(0.05f);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				<>4__this.ForceSkinNow(p, race);
				<>2__current = (object)new WaitForSeconds(0.2f);
				<>1__state = 3;
				return true;
			case 3:
				<>1__state = -1;
				<>4__this.ForceSkinNow(p, race);
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 4;
				return true;
			case 4:
				<>1__state = -1;
				<>4__this.ForceSkinNow(p, race);
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 5;
				return true;
			case 5:
				<>1__state = -1;
				<>4__this.ForceSkinNow(p, race);
				return false;
			}
		}

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

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

	private const string ModGUID = "glitnir.races";

	private const string ModName = "Glitnir Races";

	private const string ModVersion = "2.1.4";

	private const string RaceOrc = "orc";

	private const string RaceElf = "elfo";

	private const string RaceDarkElf = "elfonegro";

	private const string RaceDwarf = "anao";

	private const string RaceHalfling = "halfling";

	private const string RaceHuman = "humano";

	private const string RaceJotun = "jotun";

	private const string ZdoRaceKey = "GlitnirRace";

	private const string ZdoLockedKey = "GlitnirRaceLocked";

	private const string ZdoEarColorKey = "GlitnirRaceEarColor";

	private const string ZdoSkinColorKey = "GlitnirRaceSkinColor";

	private const string RpcSetRace = "GlitnirRaces_SetRace";

	private const int FindHeadMaxDepth = 12;

	private const float RaceApplyMaxDistance = 60f;

	private readonly Harmony harmony = new Harmony("glitnir.races");

	public static GlitnirRacesPlugin Instance;

	public static readonly Dictionary<string, RaceConfig> Races = new Dictionary<string, RaceConfig>();

	public static ConfigEntry<string> LockedPlayers;

	private static GameObject ElfEarsPrefab;

	private static GameObject OrcEarsPrefab;

	private static GameObject HighElfEyesPrefab;

	private static GameObject OrcTuskPrefab;

	private static GameObject HalflingEarsPrefab;

	private static bool IsApplyingRace = false;

	private static bool RpcRegistered = false;

	private static readonly Dictionary<long, string> NetworkRaces = new Dictionary<long, string>();

	private static readonly Dictionary<string, string> LastAppliedRace = new Dictionary<string, string>();

	private static readonly Dictionary<string, Vector3> OriginalSkinColors = new Dictionary<string, Vector3>();

	private static readonly Dictionary<string, float> LastSkinRefreshRequest = new Dictionary<string, float>();

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

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

	private float timer = 0f;

	private float syncTimer = 0f;

	private float localSaveTimer = 0f;

	private string lastBroadcastRace = null;

	private static readonly Vector3 HumanScale = Vector3.one;

	private static readonly Vector3 OrcHelmetScaleMult = new Vector3(1.18f, 1.18f, 1.18f);

	private static readonly Vector3 OrcHelmetOffset = new Vector3(0f, 0.015f, 0f);

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

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

	private static readonly Vector3 ElfEarScale = new Vector3(1f, 1f, 1f);

	private static readonly Vector3 OrcEarPosition = new Vector3(0.00024f, 0.001475f, 0.001121f);

	private static readonly Vector3 OrcEarRotation = new Vector3(24.5f, 81.89f, -2.969f);

	private static readonly Vector3 OrcEarScale = new Vector3(1.137024f, 1.637663f, 1.083586f);

	private static readonly Vector3 HighElfEyesPosition = new Vector3(-0.0063f, -0.0194f, -0.00017f);

	private static readonly Vector3 HighElfEyesRotation = new Vector3(-18.776f, -89.449f, -0.691f);

	private static readonly Vector3 HighElfEyesScale = new Vector3(0.00993f, 0.011539f, 0.01272f);

	private static readonly Vector3 OrcTuskPosition = new Vector3(-0.00137f, 0.00114f, -0.00014f);

	private static readonly Vector3 OrcTuskRotation = new Vector3(-16.932f, -110.817f, 8.571f);

	private static readonly Vector3 OrcTuskScale = new Vector3(0.00494f, 0.005076f, 0.00559f);

	private static readonly HashSet<string> RegisteredSecretCodes = new HashSet<string>(StringComparer.Ordinal);

	private void Awake()
	{
		Instance = this;
		CreateRaceConfigs();
		LockedPlayers = SyncedConfig("Geral", "PlayersBloqueados", "", "Players que já escolheram raça. Use ID ou nome separado por vírgula.");
		SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
		LoadAssets();
		RegisterCommands();
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Glitnir Races 2.1.4 carregado!");
	}

	private void OnDestroy()
	{
		SynchronizationManager.OnConfigurationSynchronized -= OnConfigurationSynchronized;
		harmony.UnpatchSelf();
	}

	private void CreateRaceConfigs()
	{
		Races.Clear();
		CreateRaceConfig("orc", "Orc", enabled: true, "1,1,1", "#448512", "#448512", "#FF0000", "orc");
		CreateRaceConfig("elfo", "Alto Elfo", enabled: true, "1,1,1", "-1", "-1", "#00FF00", "altoelfo");
		CreateRaceConfig("elfonegro", "Elfo Negro", enabled: true, "1,1,1", "#0779c5", "#0779c5", "#FFFF00", "elfonegro");
		CreateRaceConfig("anao", "Anão", enabled: true, "1,0.8,0.8", "-1", "-1", "#E0B0FF", "anao");
		CreateRaceConfig("halfling", "Halfling", enabled: true, "1,0.8,0.8", "-1", "-1", "#FF7518", "halfling");
		CreateRaceConfig("jotun", "Jotun", enabled: true, "1.2,1.2,1.2", "#4cc0dd", "#4cc0dd", "#6dceee", "jotun");
		CreateRaceConfig("humano", "Humano", enabled: true, "1,1,1", "-1", "-1", "#00F0FF", "humano");
	}

	private void CreateRaceConfig(string raceId, string displayName, bool enabled, string scale, string skinColor, string earColor, string eyeColor, string secretCode)
	{
		string group = "Raca - " + displayName;
		RaceConfig value = new RaceConfig
		{
			RaceId = raceId,
			DisplayName = displayName,
			Enabled = SyncedConfig(group, "Usar", enabled, "Ativa ou desativa a raça " + displayName + "."),
			Scale = SyncedConfig(group, "Tamanho", scale, "Tamanho da raça no formato X,Y,Z."),
			SkinColor = SyncedConfig(group, "Cor", skinColor, "Cor da pele em HEX. Use -1 para não alterar."),
			EarColor = SyncedConfig(group, "CorOrelha", earColor, "Cor da orelha em HEX. Use -1 para usar a cor da pele."),
			EyeColor = SyncedConfig(group, "CorOlho", eyeColor, "Cor dos olhos em HEX."),
			SecretCode = SyncedConfig(group, "CodigoSecreto", secretCode, "Código secreto digitado no chat para escolher a raça."),
			Players = SyncedConfig(group, "Players", "", "Players definidos como " + displayName + ". Use ID ou nome separado por vírgula.")
		};
		Races[raceId] = value;
	}

	private ConfigEntry<T> SyncedConfig<T>(string group, string name, T value, string description)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Expected O, but got Unknown
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		ConfigDescription val2 = new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { val });
		return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, val2);
	}

	private void OnConfigurationSynchronized(object sender, EventArgs args)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Configuração sincronizada pelo Jotunn.");
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		ReRegisterSecretCodeCommands();
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			ApplyRaceWithDelays(allPlayer);
		}
	}

	private void LoadAssets()
	{
		ElfEarsPrefab = LoadPrefabFromEmbedded("elf_ears");
		OrcEarsPrefab = LoadPrefabFromEmbedded("orc_ears");
		HighElfEyesPrefab = LoadPrefabFromEmbedded("high_elf_eyes");
		OrcTuskPrefab = LoadPrefabFromEmbedded("orc_tusk");
		HalflingEarsPrefab = LoadPrefabFromEmbedded("halfling_ears");
	}

	private GameObject LoadPrefabFromEmbedded(string assetName)
	{
		try
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string x) => x.EndsWith(assetName));
			if (text == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Asset embutido '" + assetName + "' não encontrado na DLL."));
				string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
				foreach (string text2 in manifestResourceNames)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("RESOURCE: " + text2));
				}
				return null;
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Stream do asset '" + assetName + "' retornou nulo."));
				return null;
			}
			byte[] array;
			using (MemoryStream memoryStream = new MemoryStream())
			{
				stream.CopyTo(memoryStream);
				array = memoryStream.ToArray();
			}
			AssetBundle val = AssetBundle.LoadFromMemory(array);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Falha ao carregar AssetBundle '" + assetName + "'."));
				return null;
			}
			GameObject val2 = val.LoadAsset<GameObject>(assetName) ?? val.LoadAllAssets<GameObject>().FirstOrDefault();
			if ((Object)(object)val2 == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Nenhum prefab encontrado dentro do AssetBundle '" + assetName + "'."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Prefab '" + assetName + "' carregado com sucesso."));
			}
			return val2;
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"Erro ao carregar asset '{assetName}': {arg}");
			return null;
		}
	}

	private void RegisterCommands()
	{
		RegisterRaceCommand("orc");
		RegisterRaceCommand("elfo");
		RegisterRaceCommand("elfonegro");
		RegisterRaceCommand("anao");
		RegisterRaceCommand("halfling");
		RegisterRaceCommand("humano");
		RegisterRaceCommand("jotun");
		RegisterResetRaceCommand();
		ReRegisterSecretCodeCommands();
	}

	private void ReRegisterSecretCodeCommands()
	{
		foreach (KeyValuePair<string, RaceConfig> race in Races)
		{
			string value = race.Value.SecretCode.Value;
			string key = race.Key;
			if (!string.IsNullOrWhiteSpace(value) && !RegisteredSecretCodes.Contains(value))
			{
				RegisterSecretCodeCommand(value, key);
				RegisteredSecretCodes.Add(value);
			}
		}
	}

	private void RegisterSecretCodeCommand(string code, string race)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		new ConsoleCommand(code, "", (ConsoleEventFailable)delegate
		{
			TransformLocalPlayerFromMarketplace(race);
			return true;
		}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
	}

	private void RegisterRaceCommand(string race)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		new ConsoleCommand(race, race + " me  ou  " + race + " NomeDoPlayer", (ConsoleEventFailable)delegate(ConsoleEventArgs args)
		{
			if (!HasDevCommands())
			{
				args.Context.AddString("Ops! você não pode fazer isso!");
				return false;
			}
			if (!IsRaceEnabled(race))
			{
				args.Context.AddString("A raça " + GetRaceName(race) + " está desativada na config.");
				return false;
			}
			if (args.Args.Length < 2)
			{
				args.Context.AddString("Uso: " + race + " me  ou  " + race + " NomeDoPlayer");
				return false;
			}
			Player targetPlayer = GetTargetPlayer(args);
			if ((Object)(object)targetPlayer == (Object)null)
			{
				args.Context.AddString("Player não encontrado.");
				return false;
			}
			SetRace(targetPlayer, race, lockPlayer: false, broadcast: true);
			ApplyRaceWithDelays(targetPlayer);
			SpawnEffect(targetPlayer);
			args.Context.AddString(targetPlayer.GetPlayerName() + " agora é " + GetRaceName(race) + ".");
			return true;
		}, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
	}

	private void RegisterResetRaceCommand()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Expected O, but got Unknown
		//IL_0022: 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)
		ConsoleEventFailable val = (ConsoleEventFailable)delegate(ConsoleEventArgs args)
		{
			if (!HasDevCommands())
			{
				args.Context.AddString("Ops! você não pode fazer isso!");
				return false;
			}
			if (args.Args.Length < 2)
			{
				args.Context.AddString("Uso: " + args.Args[0] + " me  ou  " + args.Args[0] + " NomeDoPlayer");
				return false;
			}
			Player targetPlayer = GetTargetPlayer(args);
			if ((Object)(object)targetPlayer == (Object)null)
			{
				args.Context.AddString("Player não encontrado.");
				return false;
			}
			ResetRace(targetPlayer, broadcast: true);
			args.Context.AddString("Raça de " + targetPlayer.GetPlayerName() + " removida.");
			return true;
		};
		new ConsoleCommand("racareset", "racareset me  ou  racareset NomeDoPlayer", val, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		new ConsoleCommand("racadesfazer", "racadesfazer me  ou  racadesfazer NomeDoPlayer", val, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
	}

	private Player GetTargetPlayer(ConsoleEventArgs args)
	{
		string typedName = string.Join(" ", args.Args.Skip(1)).Trim();
		if (typedName.Equals("me", StringComparison.OrdinalIgnoreCase))
		{
			return Player.m_localPlayer;
		}
		return ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && p.GetPlayerName().Equals(typedName, StringComparison.OrdinalIgnoreCase)));
	}

	private void Update()
	{
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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)
		RegisterRpcIfNeeded();
		syncTimer += Time.deltaTime;
		if (syncTimer >= 2f)
		{
			syncTimer = 0f;
			SyncLocalRace();
		}
		localSaveTimer += Time.deltaTime;
		if (localSaveTimer >= 3f)
		{
			localSaveTimer = 0f;
			RestoreLocalSavedRaceIfNeeded();
		}
		timer += Time.deltaTime;
		if (timer < 0.6f)
		{
			return;
		}
		timer = 0f;
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		Vector3 position = ((Component)Player.m_localPlayer).transform.position;
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			if (!((Object)(object)allPlayer == (Object)null) && (!((Object)(object)allPlayer != (Object)(object)Player.m_localPlayer) || !(Vector3.SqrMagnitude(((Component)allPlayer).transform.position - position) > 3600f)))
			{
				ApplyRace(allPlayer);
			}
		}
	}

	private void RestoreLocalSavedRaceIfNeeded()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		string savedLocalRace = GetSavedLocalRace();
		if (string.IsNullOrWhiteSpace(savedLocalRace) || !IsRaceEnabled(savedLocalRace))
		{
			return;
		}
		string race = GetRace(localPlayer);
		if (string.IsNullOrWhiteSpace(race))
		{
			long playerIdLong = GetPlayerIdLong(localPlayer);
			if (playerIdLong != 0)
			{
				NetworkRaces[playerIdLong] = savedLocalRace;
			}
			SetZdoRace(localPlayer, savedLocalRace);
			SetRaceVisualZdo(localPlayer, savedLocalRace);
			SetZdoLocked(localPlayer, locked: true);
			BroadcastRace(localPlayer, savedLocalRace);
			ApplyRaceWithDelays(localPlayer);
		}
		else
		{
			SetZdoLocked(localPlayer, locked: true);
		}
	}

	private void RegisterRpcIfNeeded()
	{
		if (!RpcRegistered && ZRoutedRpc.instance != null)
		{
			ZRoutedRpc.instance.Register<long, string>("GlitnirRaces_SetRace", (Action<long, long, string>)RPC_SetRace);
			RpcRegistered = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"RPC multiplayer do Glitnir Races registrado.");
		}
	}

	private static void RPC_SetRace(long sender, long playerId, string race)
	{
		if (playerId == 0)
		{
			return;
		}
		if (!IsRpcSenderAuthorized(sender, playerId))
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"RPC_SetRace rejeitado: sender={sender} tentou alterar playerId={playerId}");
			}
			return;
		}
		Player val = FindPlayerById(playerId);
		if (string.IsNullOrWhiteSpace(race))
		{
			NetworkRaces.Remove(playerId);
			if ((Object)(object)val != (Object)null && (Object)(object)Instance != (Object)null)
			{
				Instance.ResetRace(val, broadcast: false);
			}
			return;
		}
		NetworkRaces[playerId] = race;
		if ((Object)(object)val != (Object)null && (Object)(object)Instance != (Object)null)
		{
			SetZdoRace(val, race);
			SetRaceVisualZdo(val, race);
			if ((Object)(object)val == (Object)(object)Player.m_localPlayer)
			{
				SaveLocalRace(race, locked: true);
			}
			Instance.ApplyRaceWithDelays(val);
		}
	}

	private static bool IsRpcSenderAuthorized(long sender, long playerId)
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (ZRoutedRpc.instance == null)
		{
			return true;
		}
		try
		{
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
				{
					ZDOID characterID = player.m_characterID;
					if (((ZDOID)(ref characterID)).UserID == playerId)
					{
						return true;
					}
				}
			}
		}
		catch
		{
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer != (Object)null && GetPlayerIdLong(localPlayer) == playerId)
		{
			return true;
		}
		return false;
	}

	private static void BroadcastRace(Player player, string race)
	{
		//IL_0073: 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)
		if ((Object)(object)player == (Object)null || ZRoutedRpc.instance == null)
		{
			return;
		}
		long playerIdLong = GetPlayerIdLong(player);
		if (playerIdLong != 0)
		{
			if (string.IsNullOrWhiteSpace(race))
			{
				NetworkRaces.Remove(playerIdLong);
				SetZdoRace(player, "");
				SetZdoLocked(player, locked: false);
				SetZdoVector(player, "GlitnirRaceEarColor", new Vector3(-1f, -1f, -1f));
				SetZdoVector(player, "GlitnirRaceSkinColor", new Vector3(-1f, -1f, -1f));
			}
			else
			{
				NetworkRaces[playerIdLong] = race;
				SetZdoRace(player, race);
				SetRaceVisualZdo(player, race);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "GlitnirRaces_SetRace", new object[2]
			{
				playerIdLong,
				race ?? ""
			});
		}
	}

	private void SyncLocalRace()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && !IsClientConnectedToRemoteServer())
		{
			string race = GetRace(localPlayer);
			if (!string.IsNullOrWhiteSpace(race) && !(race == lastBroadcastRace))
			{
				lastBroadcastRace = race;
				BroadcastRace(localPlayer, race);
			}
		}
	}

	private static Player FindPlayerById(long playerId)
	{
		if (playerId == 0)
		{
			return null;
		}
		return ((IEnumerable<Player>)Player.GetAllPlayers()).FirstOrDefault((Func<Player, bool>)((Player p) => (Object)(object)p != (Object)null && GetPlayerIdLong(p) == playerId));
	}

	private void ApplyRaceWithDelays(Player p)
	{
		if (!((Object)(object)p == (Object)null))
		{
			ApplyRace(p);
			((MonoBehaviour)this).StartCoroutine(ApplyRaceDelayed(p, 0.1f));
			((MonoBehaviour)this).StartCoroutine(ApplyRaceDelayed(p, 0.5f));
			((MonoBehaviour)this).StartCoroutine(ApplyRaceDelayed(p, 1f));
			((MonoBehaviour)this).StartCoroutine(ApplyRaceDelayed(p, 2f));
		}
	}

	[IteratorStateMachine(typeof(<ApplyRaceDelayed>d__78))]
	private IEnumerator ApplyRaceDelayed(Player p, float delay)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ApplyRaceDelayed>d__78(0)
		{
			<>4__this = this,
			p = p,
			delay = delay
		};
	}

	private void QueueSkinRefresh(Player p, string race)
	{
		if (!((Object)(object)p == (Object)null) && !string.IsNullOrWhiteSpace(race))
		{
			string text = GetVisualKey(p);
			if (string.IsNullOrWhiteSpace(text))
			{
				text = ((Object)p).GetInstanceID().ToString();
			}
			float time = Time.time;
			if (!LastSkinRefreshRequest.TryGetValue(text, out var value) || !(time - value < 1.25f))
			{
				LastSkinRefreshRequest[text] = time;
				((MonoBehaviour)this).StartCoroutine(ForceSkinRefresh(p, race));
			}
		}
	}

	[IteratorStateMachine(typeof(<ForceSkinRefresh>d__80))]
	private IEnumerator ForceSkinRefresh(Player p, string race)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ForceSkinRefresh>d__80(0)
		{
			<>4__this = this,
			p = p,
			race = race
		};
	}

	private void ForceSkinNow(Player p, string race)
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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_00c2: 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)
		if ((Object)(object)p == (Object)null || string.IsNullOrWhiteSpace(race) || GetRace(p) != race)
		{
			return;
		}
		bool isApplyingRace = IsApplyingRace;
		IsApplyingRace = true;
		try
		{
			if (RaceUsesForcedSkin(race))
			{
				ApplySkin(p, GetNetworkSkinColor(p, race));
			}
			Color color = ToColor(GetRaceEarColor(p, race));
			if (race == "orc" || race == "jotun")
			{
				ApplyOrcEars(p, color);
			}
			else if (race == "elfonegro" || race == "elfo" || race == "halfling")
			{
				ApplyEars(p, color);
			}
			Transform obj = FindHead(((Component)p).transform, 0);
			Transform val = ((obj != null) ? obj.Find("HighElfEyes") : null);
			if ((Object)(object)val != (Object)null)
			{
				ApplyEyeColor(val, GetRaceEyeColor(race));
			}
		}
		finally
		{
			IsApplyingRace = isApplyingRace;
		}
	}

	public void RequestOnlineVisualRefresh(Player p)
	{
		if ((Object)(object)p == (Object)null)
		{
			return;
		}
		string race = GetRace(p);
		if (!string.IsNullOrWhiteSpace(race))
		{
			ApplyRaceWithDelays(p);
			if (RaceUsesForcedSkin(race) || race == "elfo" || race == "halfling")
			{
				QueueSkinRefresh(p, race);
			}
		}
	}

	public void RequestOnlineVisualRefresh(VisEquipment vis)
	{
		if (!((Object)(object)vis == (Object)null))
		{
			Player val = ((Component)vis).GetComponent<Player>() ?? ((Component)vis).GetComponentInParent<Player>();
			if ((Object)(object)val != (Object)null)
			{
				RequestOnlineVisualRefresh(val);
			}
		}
	}

	public void ForceSkinAfterVanilla(Player p, string race)
	{
		if (!((Object)(object)p == (Object)null) && !string.IsNullOrWhiteSpace(race))
		{
			QueueSkinRefresh(p, race);
		}
	}

	public void ForceSkinAfterVanilla(VisEquipment vis)
	{
		if ((Object)(object)vis == (Object)null)
		{
			return;
		}
		Player val = ((Component)vis).GetComponent<Player>() ?? ((Component)vis).GetComponentInParent<Player>();
		if (!((Object)(object)val == (Object)null))
		{
			string race = GetRace(val);
			if (RaceUsesForcedSkin(race) || race == "elfo" || race == "halfling")
			{
				QueueSkinRefresh(val, race);
			}
		}
	}

	public void ApplyRace(Player p)
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: 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_0338: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_030c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || IsApplyingRace)
		{
			return;
		}
		string race = GetRace(p);
		string visualKey = GetVisualKey(p);
		string value = "";
		if (!string.IsNullOrWhiteSpace(visualKey))
		{
			LastAppliedRace.TryGetValue(visualKey, out value);
		}
		bool flag = value != race;
		IsApplyingRace = true;
		try
		{
			if (flag)
			{
				if (value == "orc")
				{
					ResetOrcHelmet(p);
				}
				((Component)p).transform.localScale = HumanScale;
				if (RaceUsesForcedSkin(value))
				{
					ResetSkin(p);
				}
				RemoveHeadAttachment(p, "Ears");
				RemoveHeadAttachment(p, "OrcEars");
				RemoveHeadAttachment(p, "HighElfEyes");
				RemoveHeadAttachment(p, "OrcTusk");
				RemovePlayerAttachment(p, "JotunFreeze");
				if (!string.IsNullOrWhiteSpace(visualKey))
				{
					LastAppliedRace[visualKey] = race;
				}
			}
			if (string.IsNullOrWhiteSpace(race) || !IsRaceEnabled(race))
			{
				((Component)p).transform.localScale = HumanScale;
				return;
			}
			((Component)p).transform.localScale = GetRaceScale(race);
			if (RaceUsesForcedSkin(race))
			{
				CacheOriginalSkinIfNeeded(p);
				ApplySkin(p, GetNetworkSkinColor(p, race));
				QueueSkinRefresh(p, race);
			}
			switch (race)
			{
			case "orc":
				ApplyOrcEars(p, ToColor(GetRaceEarColor(p, race)));
				ApplyHighElfEyes(p);
				ApplyOrcTusk(p);
				ScaleOrcHelmet(p);
				break;
			case "elfonegro":
				ApplyEars(p, ToColor(GetRaceEarColor(p, race)));
				ApplyHighElfEyes(p);
				break;
			case "elfo":
				ApplyEars(p, ToColor(GetRaceEarColor(p, race)));
				QueueSkinRefresh(p, race);
				ApplyHighElfEyes(p);
				break;
			case "halfling":
				ApplyHalflingEars(p, ToColor(GetRaceEarColor(p, race)));
				QueueSkinRefresh(p, race);
				ApplyHighElfEyes(p);
				break;
			case "anao":
			case "humano":
				ApplyHighElfEyes(p);
				break;
			case "jotun":
				ApplyOrcEars(p, ToColor(GetRaceEarColor(p, race)));
				ApplyHighElfEyes(p);
				ApplyFreezingEffect(p);
				break;
			}
		}
		finally
		{
			IsApplyingRace = false;
		}
	}

	private static bool IsZdoOwner(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return false;
			}
			return component.IsOwner();
		}
		catch
		{
			return false;
		}
	}

	private static void SetRaceVisualZdo(Player player, string race)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)player == (Object)null) && !string.IsNullOrWhiteSpace(race) && IsZdoOwner(player))
		{
			SetZdoVector(player, "GlitnirRaceEarColor", GetCalculatedRaceEarColor(player, race));
			if (RaceUsesForcedSkin(race))
			{
				SetZdoVector(player, "GlitnirRaceSkinColor", GetRaceSkinColor(race));
			}
		}
	}

	private static void SetZdoRace(Player player, string race)
	{
		if ((Object)(object)player == (Object)null || !IsZdoOwner(player))
		{
			return;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.GetZDO() != null)
			{
				component.GetZDO().Set("GlitnirRace", race);
			}
		}
		catch
		{
		}
	}

	private static string GetZdoRace(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return "";
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return "";
			}
			return component.GetZDO().GetString("GlitnirRace", "");
		}
		catch
		{
			return "";
		}
	}

	private static void SetZdoLocked(Player player, bool locked)
	{
		if ((Object)(object)player == (Object)null || !IsZdoOwner(player))
		{
			return;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.GetZDO() != null)
			{
				component.GetZDO().Set("GlitnirRaceLocked", locked);
			}
		}
		catch
		{
		}
	}

	private static bool GetZdoLocked(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return false;
			}
			return component.GetZDO().GetBool("GlitnirRaceLocked", false);
		}
		catch
		{
			return false;
		}
	}

	private static void SetZdoVector(Player player, string key, Vector3 value)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || string.IsNullOrWhiteSpace(key) || !IsZdoOwner(player))
		{
			return;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.GetZDO() != null)
			{
				component.GetZDO().Set(key + "_x", value.x);
				component.GetZDO().Set(key + "_y", value.y);
				component.GetZDO().Set(key + "_z", value.z);
			}
		}
		catch
		{
		}
	}

	private static Vector3 GetZdoVector(Player player, string key, Vector3 fallback)
	{
		//IL_00ae: 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_00b2: 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_0018: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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)
		//IL_00a9: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null || string.IsNullOrWhiteSpace(key))
		{
			return fallback;
		}
		try
		{
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return fallback;
			}
			float @float = component.GetZDO().GetFloat(key + "_x", fallback.x);
			float float2 = component.GetZDO().GetFloat(key + "_y", fallback.y);
			float float3 = component.GetZDO().GetFloat(key + "_z", fallback.z);
			return new Vector3(@float, float2, float3);
		}
		catch
		{
			return fallback;
		}
	}

	private static string GetRace(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return "";
		}
		long playerIdLong = GetPlayerIdLong(player);
		string zdoRace = GetZdoRace(player);
		if (!string.IsNullOrWhiteSpace(zdoRace))
		{
			if (playerIdLong != 0)
			{
				NetworkRaces[playerIdLong] = zdoRace;
			}
			return zdoRace;
		}
		foreach (KeyValuePair<string, RaceConfig> race in Races)
		{
			if (race.Key == "humano" || !HasPlayer(race.Value.Players, player))
			{
				continue;
			}
			SetZdoRace(player, race.Key);
			if (playerIdLong != 0)
			{
				NetworkRaces[playerIdLong] = race.Key;
			}
			return race.Key;
		}
		if (playerIdLong != 0L && NetworkRaces.TryGetValue(playerIdLong, out var value) && !string.IsNullOrWhiteSpace(value))
		{
			return value;
		}
		return "";
	}

	private bool SetRace(Player player, string race, bool lockPlayer, bool broadcast)
	{
		if ((Object)(object)player == (Object)null || !IsRaceEnabled(race))
		{
			return false;
		}
		if (RaceUsesForcedSkin(race))
		{
			CacheOriginalSkinIfNeeded(player);
		}
		string playerId = GetPlayerId(player);
		string playerName = player.GetPlayerName();
		long playerIdLong = GetPlayerIdLong(player);
		ClearRace(playerId, playerName);
		if (race != "humano" && Races.TryGetValue(race, out var value))
		{
			Add(value.Players, playerId);
		}
		if (playerIdLong != 0)
		{
			NetworkRaces[playerIdLong] = race;
		}
		SetZdoRace(player, race);
		SetRaceVisualZdo(player, race);
		if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
		{
			SaveLocalRace(race, lockPlayer || IsPlayerLocked(player));
		}
		if (broadcast)
		{
			BroadcastRace(player, race);
		}
		if (lockPlayer)
		{
			Add(LockedPlayers, playerId);
			Add(LockedPlayers, playerName);
			SetZdoLocked(player, locked: true);
		}
		return true;
	}

	private void ResetRace(Player player, bool broadcast)
	{
		//IL_00af: 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_0110: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)player == (Object)null))
		{
			string playerId = GetPlayerId(player);
			string playerName = player.GetPlayerName();
			long playerIdLong = GetPlayerIdLong(player);
			string visualKey = GetVisualKey(player);
			ClearRace(playerId, playerName);
			Remove(LockedPlayers, playerId);
			Remove(LockedPlayers, playerName);
			if (playerIdLong != 0)
			{
				NetworkRaces.Remove(playerIdLong);
			}
			if (!string.IsNullOrWhiteSpace(visualKey))
			{
				LastAppliedRace[visualKey] = "";
			}
			SetZdoRace(player, "");
			SetZdoLocked(player, locked: false);
			SetZdoVector(player, "GlitnirRaceEarColor", new Vector3(-1f, -1f, -1f));
			SetZdoVector(player, "GlitnirRaceSkinColor", new Vector3(-1f, -1f, -1f));
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				ClearLocalSavedRace();
				lastBroadcastRace = null;
			}
			ResetOrcHelmet(player);
			ResetSkin(player);
			((Component)player).transform.localScale = HumanScale;
			RemoveHeadAttachment(player, "Ears");
			RemoveHeadAttachment(player, "OrcEars");
			RemoveHeadAttachment(player, "HighElfEyes");
			RemoveHeadAttachment(player, "OrcTusk");
			RemovePlayerAttachment(player, "JotunFreeze");
			ApplyRaceWithDelays(player);
			if (broadcast)
			{
				BroadcastRace(player, "");
			}
		}
	}

	private static bool IsPlayerLocked(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		if (GetZdoLocked(player))
		{
			return true;
		}
		if ((Object)(object)player == (Object)(object)Player.m_localPlayer && !IsClientConnectedToRemoteServer() && HasSavedLocalRaceLocked())
		{
			return true;
		}
		if (HasPlayer(LockedPlayers, player))
		{
			return true;
		}
		return false;
	}

	private static string GetLocalSavePrefix()
	{
		string text = "unknown";
		try
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				long playerID = Player.m_localPlayer.GetPlayerID();
				if (playerID != 0)
				{
					text = playerID.ToString();
				}
			}
		}
		catch
		{
		}
		string value = "local";
		try
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				if (!ZNet.instance.IsServer())
				{
					string text2 = "";
					int result = 0;
					FieldInfo fieldInfo = AccessTools.Field(typeof(ZNet), "m_serverHost");
					FieldInfo fieldInfo2 = AccessTools.Field(typeof(ZNet), "m_serverPort");
					if (fieldInfo != null)
					{
						text2 = fieldInfo.GetValue(ZNet.instance)?.ToString() ?? "";
					}
					if (fieldInfo2 != null)
					{
						int.TryParse(fieldInfo2.GetValue(ZNet.instance)?.ToString() ?? "", out result);
					}
					if (!string.IsNullOrWhiteSpace(text2))
					{
						value = text2 + ((result > 0) ? ("_" + result) : "");
					}
				}
				else
				{
					MethodInfo methodInfo = AccessTools.Method(typeof(ZNet), "GetWorldName", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						value = methodInfo.Invoke(ZNet.instance, null)?.ToString() ?? "local";
					}
				}
			}
		}
		catch
		{
		}
		value = SanitizeKey(value);
		return "GlitnirRaces_c" + text + "_s" + value + "_";
	}

	private static string SanitizeKey(string value)
	{
		if (string.IsNullOrWhiteSpace(value))
		{
			return "unknown";
		}
		char[] array = value.ToCharArray();
		for (int i = 0; i < array.Length; i++)
		{
			if (!char.IsLetterOrDigit(array[i]) && array[i] != '-')
			{
				array[i] = '_';
			}
		}
		return new string(array);
	}

	private static string GetSavedLocalRace()
	{
		try
		{
			return PlayerPrefs.GetString(GetLocalSavePrefix() + "Race", "");
		}
		catch
		{
			return "";
		}
	}

	private static bool HasSavedLocalRaceLocked()
	{
		try
		{
			return PlayerPrefs.GetInt(GetLocalSavePrefix() + "Locked", 0) == 1;
		}
		catch
		{
			return false;
		}
	}

	private static void SaveLocalRace(string race, bool locked)
	{
		if (string.IsNullOrWhiteSpace(race))
		{
			return;
		}
		try
		{
			PlayerPrefs.SetString(GetLocalSavePrefix() + "Race", race);
			if (locked)
			{
				PlayerPrefs.SetInt(GetLocalSavePrefix() + "Locked", 1);
			}
			PlayerPrefs.Save();
		}
		catch
		{
		}
	}

	private static void ClearLocalSavedRace()
	{
		try
		{
			PlayerPrefs.DeleteKey(GetLocalSavePrefix() + "Race");
			PlayerPrefs.DeleteKey(GetLocalSavePrefix() + "Locked");
			PlayerPrefs.Save();
		}
		catch
		{
		}
	}

	public static bool HasDevCommands()
	{
		try
		{
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return true;
			}
		}
		catch
		{
		}
		return GetStaticBool("Terminal", "m_cheat") || GetStaticBool("Console", "m_cheat") || GetStaticBool("Terminal", "m_devcommands") || GetStaticBool("Console", "m_devcommands");
	}

	private static bool GetStaticBool(string typeName, string fieldName)
	{
		try
		{
			Type type = AccessTools.TypeByName(typeName);
			if (type == null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, fieldName);
			if (fieldInfo == null)
			{
				return false;
			}
			object value = fieldInfo.GetValue(null);
			bool flag = default(bool);
			int num;
			if (value is bool)
			{
				flag = (bool)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}
		catch
		{
			return false;
		}
	}

	private static Vector3 GetRaceEarColor(Player p, string race)
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_0043: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		if (!string.IsNullOrWhiteSpace(race) && Races.TryGetValue(race, out var value))
		{
			Vector3 val = ParseColorConfig(value.EarColor.Value, new Vector3(-1f, -1f, -1f));
			if (val.x >= 0f)
			{
				return val;
			}
		}
		Vector3 zdoVector = GetZdoVector(p, "GlitnirRaceEarColor", new Vector3(-1f, -1f, -1f));
		if (zdoVector.x >= 0f)
		{
			return zdoVector;
		}
		if (RaceUsesForcedSkin(race))
		{
			return GetNetworkSkinColor(p, race);
		}
		return ((Object)(object)Instance != (Object)null) ? Instance.GetCurrentSkinVector(p) : Vector3.one;
	}

	private static Vector3 GetCalculatedRaceEarColor(Player p, string race)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		if (!string.IsNullOrWhiteSpace(race) && Races.TryGetValue(race, out var value))
		{
			Vector3 val = ParseColorConfig(value.EarColor.Value, new Vector3(-1f, -1f, -1f));
			if (val.x >= 0f)
			{
				return val;
			}
		}
		if (RaceUsesForcedSkin(race))
		{
			return GetRaceSkinColor(race);
		}
		return ((Object)(object)Instance != (Object)null) ? Instance.GetCurrentSkinVector(p) : Vector3.one;
	}

	private static Vector3 GetNetworkSkinColor(Player p, string race)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (RaceUsesForcedSkin(race))
		{
			return GetRaceSkinColor(race);
		}
		Vector3 zdoVector = GetZdoVector(p, "GlitnirRaceSkinColor", new Vector3(-1f, -1f, -1f));
		if (zdoVector.x >= 0f)
		{
			return zdoVector;
		}
		return GetRaceSkinColor(race);
	}

	private static Color GetRaceEyeColor(string race)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (!Races.TryGetValue(race, out var value))
		{
			return Color.cyan;
		}
		Vector3 val = ParseColorConfig(value.EyeColor.Value, new Vector3(0f, 1f, 1f));
		if (val.x < 0f)
		{
			return Color.cyan;
		}
		return new Color(val.x, val.y, val.z, 1f);
	}

	private static bool IsRaceEnabled(string race)
	{
		if (string.IsNullOrWhiteSpace(race))
		{
			return false;
		}
		RaceConfig value;
		return Races.TryGetValue(race, out value) && value.Enabled.Value;
	}

	private static bool RaceUsesForcedSkin(string race)
	{
		//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_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrWhiteSpace(race))
		{
			return false;
		}
		if (!Races.TryGetValue(race, out var value))
		{
			return false;
		}
		Vector3 val = ParseColorConfig(value.SkinColor.Value, new Vector3(-1f, -1f, -1f));
		return val.x >= 0f && val.y >= 0f && val.z >= 0f;
	}

	private static Vector3 GetRaceScale(string race)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (!Races.TryGetValue(race, out var value))
		{
			return HumanScale;
		}
		return ParseVector(value.Scale.Value, HumanScale);
	}

	private static Vector3 GetRaceSkinColor(string race)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (!Races.TryGetValue(race, out var value))
		{
			return Vector3.one;
		}
		return ParseColorConfig(value.SkinColor.Value, Vector3.one);
	}

	private static Vector3 ParseVector(string value, Vector3 fallback)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			string[] array = value.Split(new char[1] { ',' });
			if (array.Length != 3)
			{
				return fallback;
			}
			return new Vector3(float.Parse(array[0].Trim(), CultureInfo.InvariantCulture), float.Parse(array[1].Trim(), CultureInfo.InvariantCulture), float.Parse(array[2].Trim(), CultureInfo.InvariantCulture));
		}
		catch
		{
			return fallback;
		}
	}

	private static Vector3 ParseColorConfig(string value, Vector3 fallback)
	{
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			value = value.Trim();
			if (value == "-1" || value.Equals("none", StringComparison.OrdinalIgnoreCase) || value.Equals("nao", StringComparison.OrdinalIgnoreCase) || value.Equals("não", StringComparison.OrdinalIgnoreCase) || value == "-1,-1,-1")
			{
				return new Vector3(-1f, -1f, -1f);
			}
			if (value.StartsWith("#"))
			{
				Color val = default(Color);
				if (ColorUtility.TryParseHtmlString(value, ref val))
				{
					return new Vector3(val.r, val.g, val.b);
				}
				return fallback;
			}
			return ParseVector(value, fallback);
		}
		catch
		{
			return fallback;
		}
	}

	private static string GetRaceFromSecretCode(string text)
	{
		if (string.IsNullOrWhiteSpace(text))
		{
			return null;
		}
		foreach (KeyValuePair<string, RaceConfig> race in Races)
		{
			RaceConfig value = race.Value;
			if (value?.SecretCode == null || !value.Enabled.Value || !text.Equals(value.SecretCode.Value, StringComparison.Ordinal))
			{
				continue;
			}
			return race.Key;
		}
		return null;
	}

	private static void TransformLocalPlayerFromMarketplace(string race)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || (Object)(object)Instance == (Object)null)
		{
			return;
		}
		if (!IsRaceEnabled(race))
		{
			((Character)localPlayer).Message((MessageType)2, "Essa raça está desativada.", 0, (Sprite)null);
			return;
		}
		if (RaceUsesForcedSkin(race))
		{
			Instance.CacheOriginalSkinIfNeeded(localPlayer);
		}
		if (IsPlayerLocked(localPlayer) || (!IsClientConnectedToRemoteServer() && HasSavedLocalRaceLocked()))
		{
			Instance.RestoreLocalSavedRaceIfNeeded();
			((Character)localPlayer).Message((MessageType)2, "Você ja faz parte de uma raça!", 0, (Sprite)null);
			return;
		}
		Instance.SetRace(localPlayer, race, lockPlayer: true, broadcast: true);
		Instance.ApplyRaceWithDelays(localPlayer);
		Instance.SpawnEffect(localPlayer);
		((Character)localPlayer).Message((MessageType)2, "Agora eu sou: " + Instance.GetRaceName(race), 0, (Sprite)null);
	}

	public void SpawnEffect(Player p)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: 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)
		if (!((Object)(object)p == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null))
		{
			Vector3 val = ((Component)p).transform.position + Vector3.up;
			Quaternion rotation = ((Component)p).transform.rotation;
			GameObject prefab = ZNetScene.instance.GetPrefab("vfx_spawn_large");
			GameObject prefab2 = ZNetScene.instance.GetPrefab("fx_Fader_Roar_Projectile_Hit");
			if ((Object)(object)prefab != (Object)null)
			{
				Object.Instantiate<GameObject>(prefab, val, rotation);
			}
			if ((Object)(object)prefab2 != (Object)null)
			{
				Object.Instantiate<GameObject>(prefab2, val, rotation);
			}
		}
	}

	private void ApplyFreezingEffect(Player p)
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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)
		if (!((Object)(object)p == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)((Component)p).transform.Find("JotunFreeze") != (Object)null))
		{
			GameObject prefab = ZNetScene.instance.GetPrefab("vfx_Freezing");
			if ((Object)(object)prefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"vfx_Freezing não encontrado.");
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)p).transform);
			((Object)val).name = "JotunFreeze";
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
		}
	}

	private void RemovePlayerAttachment(Player p, string objectName)
	{
		if (!((Object)(object)p == (Object)null))
		{
			Transform val = ((Component)p).transform.Find(objectName);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
	}

	private void ScaleOrcHelmet(Player p)
	{
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || GetRace(p) != "orc")
		{
			return;
		}
		HashSet<Transform> hashSet = new HashSet<Transform>();
		Renderer[] componentsInChildren = ((Component)p).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform == (Object)null))
			{
				Transform transform = ((Component)val).transform;
				string text = GetTransformPath(transform).ToLowerInvariant();
				bool flag = text.Contains("helmet") || text.Contains("helm") || text.Contains("headgear");
				bool flag2 = text.Contains("hair") || text.Contains("beard") || text.Contains("ear") || text.Contains("orc") || text.Contains("tusk") || text.Contains("eye") || text.Contains("high");
				if (flag && !flag2)
				{
					hashSet.Add(transform);
				}
			}
		}
		foreach (Transform item in hashSet)
		{
			int instanceID = ((Object)item).GetInstanceID();
			if (!OrcHelmetOriginalScale.ContainsKey(instanceID))
			{
				OrcHelmetOriginalScale[instanceID] = item.localScale;
			}
			if (!OrcHelmetOriginalPosition.ContainsKey(instanceID))
			{
				OrcHelmetOriginalPosition[instanceID] = item.localPosition;
			}
			Vector3 val2 = OrcHelmetOriginalScale[instanceID];
			Vector3 val3 = OrcHelmetOriginalPosition[instanceID];
			item.localScale = Vector3.Scale(val2, OrcHelmetScaleMult);
			item.localPosition = val3 + OrcHelmetOffset;
		}
	}

	private void ResetOrcHelmet(Player p)
	{
		//IL_004c: 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)
		if ((Object)(object)p == (Object)null)
		{
			return;
		}
		Transform[] componentsInChildren = ((Component)p).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null))
			{
				int instanceID = ((Object)val).GetInstanceID();
				if (OrcHelmetOriginalScale.TryGetValue(instanceID, out var value))
				{
					val.localScale = value;
				}
				if (OrcHelmetOriginalPosition.TryGetValue(instanceID, out var value2))
				{
					val.localPosition = value2;
				}
			}
		}
	}

	private string GetTransformPath(Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder(((Object)t).name);
		Transform parent = t.parent;
		while ((Object)(object)parent != (Object)null)
		{
			stringBuilder.Insert(0, ((Object)parent).name + "/");
			parent = parent.parent;
		}
		return stringBuilder.ToString();
	}

	private void ApplySkin(Player p, Vector3 color)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		VisEquipment component = ((Component)p).GetComponent<VisEquipment>();
		if (!((Object)(object)component == (Object)null))
		{
			typeof(VisEquipment).GetMethod("SetSkinColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(component, new object[1] { color });
		}
	}

	private void CacheOriginalSkinIfNeeded(Player p)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)p == (Object)null))
		{
			string visualKey = GetVisualKey(p);
			if (!string.IsNullOrWhiteSpace(visualKey) && !OriginalSkinColors.ContainsKey(visualKey))
			{
				OriginalSkinColors[visualKey] = GetCurrentSkinVector(p);
			}
		}
	}

	private static void CacheOriginalSkinValue(Player p, Vector3 skin)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)p == (Object)null))
		{
			string visualKey = GetVisualKey(p);
			if (!string.IsNullOrWhiteSpace(visualKey) && !OriginalSkinColors.ContainsKey(visualKey))
			{
				OriginalSkinColors[visualKey] = skin;
			}
		}
	}

	private void ResetSkin(Player p)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)p == (Object)null))
		{
			string visualKey = GetVisualKey(p);
			if (!string.IsNullOrWhiteSpace(visualKey) && OriginalSkinColors.TryGetValue(visualKey, out var value))
			{
				ApplySkin(p, value);
			}
		}
	}

	private Vector3 GetCurrentSkinVector(Player p)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: 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_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null)
		{
			return Vector3.one;
		}
		VisEquipment component = ((Component)p).GetComponent<VisEquipment>();
		if ((Object)(object)component == (Object)null)
		{
			return Vector3.one;
		}
		try
		{
			FieldInfo field = typeof(VisEquipment).GetField("m_skinColor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(component);
				if (value is Vector3)
				{
					Vector3 result = (Vector3)value;
					if (true)
					{
						return result;
					}
				}
			}
		}
		catch
		{
		}
		return Vector3.one;
	}

	private void ApplyEyeColor(Transform t, Color color)
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)t == (Object)null)
		{
			return;
		}
		Renderer[] componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Material[] materials = val.materials;
			foreach (Material val2 in materials)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					if (val2.HasProperty("_EmissionColor"))
					{
						val2.EnableKeyword("_EMISSION");
						val2.SetColor("_EmissionColor", color * 3.5f);
					}
					if (val2.HasProperty("_Color"))
					{
						val2.SetColor("_Color", color);
					}
					if (val2.HasProperty("_BaseColor"))
					{
						val2.SetColor("_BaseColor", color);
					}
					if (val2.HasProperty("_TintColor"))
					{
						val2.SetColor("_TintColor", color);
					}
				}
			}
		}
	}

	private void ApplyEars(Player p, Color color)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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_00a3: 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)
		if ((Object)(object)p == (Object)null || (Object)(object)ElfEarsPrefab == (Object)null)
		{
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find("Ears");
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(ElfEarsPrefab, val);
				((Object)val3).name = "Ears";
				StripItemComponents(val3);
				val2 = val3.transform;
			}
			val2.localPosition = ElfEarPosition;
			val2.localRotation = Quaternion.Euler(ElfEarRotation);
			val2.localScale = ElfEarScale;
			FixEarMaterials(val2);
			ApplyColor(val2, color);
		}
	}

	private void ApplyHalflingEars(Player p, Color color)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || (Object)(object)HalflingEarsPrefab == (Object)null)
		{
			if ((Object)(object)HalflingEarsPrefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Prefab halfling_ears não encontrado.");
			}
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find("Ears");
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(HalflingEarsPrefab, val);
				((Object)val3).name = "Ears";
				StripItemComponents(val3);
				val2 = val3.transform;
			}
			val2.localPosition = ElfEarPosition;
			val2.localRotation = Quaternion.Euler(ElfEarRotation);
			val2.localScale = ElfEarScale;
			FixEarMaterials(val2);
			ApplyColor(val2, color);
		}
	}

	private void ApplyOrcEars(Player p, Color color)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || (Object)(object)OrcEarsPrefab == (Object)null)
		{
			if ((Object)(object)OrcEarsPrefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Prefab orc_ears não encontrado.");
			}
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find("OrcEars");
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(OrcEarsPrefab, val);
				((Object)val3).name = "OrcEars";
				StripItemComponents(val3);
				val2 = val3.transform;
			}
			val2.localPosition = OrcEarPosition;
			val2.localRotation = Quaternion.Euler(OrcEarRotation);
			val2.localScale = OrcEarScale;
			FixEarMaterials(val2);
			ApplyColor(val2, color);
		}
	}

	private void ApplyHighElfEyes(Player p)
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || (Object)(object)HighElfEyesPrefab == (Object)null)
		{
			if ((Object)(object)HighElfEyesPrefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Prefab high_elf_eyes não encontrado.");
			}
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find("HighElfEyes");
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(HighElfEyesPrefab, val);
				((Object)val3).name = "HighElfEyes";
				StripItemComponents(val3);
				val2 = val3.transform;
			}
			val2.localPosition = HighElfEyesPosition;
			val2.localRotation = Quaternion.Euler(HighElfEyesRotation);
			val2.localScale = HighElfEyesScale;
			ApplyEyeColor(val2, GetRaceEyeColor(GetRace(p)));
		}
	}

	private void ApplyOrcTusk(Player p)
	{
		//IL_00b7: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)p == (Object)null || (Object)(object)OrcTuskPrefab == (Object)null)
		{
			if ((Object)(object)OrcTuskPrefab == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Prefab orc_tusk não encontrado.");
			}
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find("OrcTusk");
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = Object.Instantiate<GameObject>(OrcTuskPrefab, val);
				((Object)val3).name = "OrcTusk";
				StripItemComponents(val3);
				FixEarMaterials(val3.transform);
				val2 = val3.transform;
			}
			val2.localPosition = OrcTuskPosition;
			val2.localRotation = Quaternion.Euler(OrcTuskRotation);
			val2.localScale = OrcTuskScale;
			FixEarMaterials(val2);
		}
	}

	private void RemoveHeadAttachment(Player p, string objectName)
	{
		if ((Object)(object)p == (Object)null)
		{
			return;
		}
		Transform val = FindHead(((Component)p).transform, 0);
		if (!((Object)(object)val == (Object)null))
		{
			Transform val2 = val.Find(objectName);
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val2).gameObject);
			}
		}
	}

	private void FixEarMaterials(Transform t)
	{
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)t == (Object)null)
		{
			return;
		}
		Shader val = Shader.Find("Standard");
		Renderer[] componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Material[] materials = val2.materials;
			foreach (Material val3 in materials)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					if (val3.IsKeywordEnabled("_EMISSION"))
					{
						val3.DisableKeyword("_EMISSION");
					}
					if (val3.HasProperty("_EmissionColor"))
					{
						val3.SetColor("_EmissionColor", Color.black);
					}
					if ((Object)(object)val != (Object)null)
					{
						val3.shader = val;
					}
				}
			}
		}
	}

	private void ApplyColor(Transform t, Color c)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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)
		if ((Object)(object)t == (Object)null)
		{
			return;
		}
		Renderer[] componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Material[] materials = val.materials;
			foreach (Material val2 in materials)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.color = c;
					if (val2.HasProperty("_Color"))
					{
						val2.SetColor("_Color", c);
					}
					if (val2.HasProperty("_BaseColor"))
					{
						val2.SetColor("_BaseColor", c);
					}
					if (val2.HasProperty("_TintColor"))
					{
						val2.SetColor("_TintColor", c);
					}
				}
			}
		}
	}

	private Transform FindHead(Transform t, int depth)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		if ((Object)(object)t == (Object)null || depth > 12)
		{
			return null;
		}
		string text = ((Object)t).name.ToLowerInvariant();
		if (text == "head" || text.Contains("head") || text.Contains("bip001 head") || text.Contains("helmet_attach") || text.Contains("head_attach"))
		{
			return t;
		}
		foreach (Transform item in t)
		{
			Transform t2 = item;
			Transform val = FindHead(t2, depth + 1);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		return null;
	}

	private void StripItemComponents(GameObject obj)
	{
		if (!((Object)(object)obj == (Object)null))
		{
			Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				Object.Destroy((Object)(object)val);
			}
			Rigidbody[] componentsInChildren2 = obj.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val2 in componentsInChildren2)
			{
				Object.Destroy((Object)(object)val2);
			}
			ItemDrop[] componentsInChildren3 = obj.GetComponentsInChildren<ItemDrop>(true);
			foreach (ItemDrop val3 in componentsInChildren3)
			{
				Object.Destroy((Object)(object)val3);
			}
			ZNetView[] componentsInChildren4 = obj.GetComponentsInChildren<ZNetView>(true);
			foreach (ZNetView val4 in componentsInChildren4)
			{
				Object.Destroy((Object)(object)val4);
			}
		}
	}

	private static Color ToColor(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: 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)
		return new Color(v.x, v.y, v.z, 1f);
	}

	private static string GetPlayerId(Player player)
	{
		long playerIdLong = GetPlayerIdLong(player);
		if (playerIdLong != 0)
		{
			return playerIdLong.ToString();
		}
		return ((Object)(object)player != (Object)null) ? player.GetPlayerName() : "";
	}

	private static string GetVisualKey(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return "";
		}
		long playerIdLong = GetPlayerIdLong(player);
		if (playerIdLong != 0)
		{
			return playerIdLong.ToString();
		}
		return player.GetPlayerName();
	}

	private static long GetPlayerIdLong(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return 0L;
		}
		try
		{
			long playerID = player.GetPlayerID();
			if (playerID != 0)
			{
				return playerID;
			}
		}
		catch
		{
		}
		return 0L;
	}

	private string GetRaceName(string race)
	{
		RaceConfig value;
		return Races.TryGetValue(race, out value) ? value.DisplayName : race;
	}

	private static bool IsClientConnectedToRemoteServer()
	{
		try
		{
			return (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer();
		}
		catch
		{
			return false;
		}
	}

	private static List<string> GetList(ConfigEntry<string> entry)
	{
		if (entry == null)
		{
			return new List<string>();
		}
		return (from x in entry.Value.Split(new char[1] { ',' })
			select x.Trim() into x
			where !string.IsNullOrEmpty(x)
			select x).ToList();
	}

	private static bool Has(ConfigEntry<string> entry, string value)
	{
		if (entry == null || string.IsNullOrWhiteSpace(value))
		{
			return false;
		}
		return GetList(entry).Any((string x) => x.Equals(value, StringComparison.OrdinalIgnoreCase));
	}

	private static bool HasPlayer(ConfigEntry<string> entry, Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		return Has(entry, GetPlayerId(player)) || Has(entry, player.GetPlayerName());
	}

	private static void Add(ConfigEntry<string> entry, string value)
	{
		if (entry != null && !string.IsNullOrWhiteSpace(value))
		{
			List<string> list = GetList(entry);
			if (!list.Any((string x) => x.Equals(value, StringComparison.OrdinalIgnoreCase)))
			{
				list.Add(value);
			}
			entry.Value = string.Join(",", list);
		}
	}

	private static void Remove(ConfigEntry<string> entry, string value)
	{
		if (entry != null && !string.IsNullOrWhiteSpace(value))
		{
			entry.Value = string.Join(",", from x in GetList(entry)
				where !x.Equals(value, StringComparison.OrdinalIgnoreCase)
				select x);
		}
	}

	private static void ClearRace(string playerId, string playerName)
	{
		foreach (KeyValuePair<string, RaceConfig> race in Races)
		{
			Remove(race.Value.Players, playerId);
			Remove(race.Value.Players, playerName);
		}
	}
}