Decompiled source of Namify v0.2.3

plugins/Namify.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Lamb.UI;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Newtonsoft.Json;
using Shared;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("p1xel8ted")]
[assembly: AssemblyConfiguration("Release-Thunderstore")]
[assembly: AssemblyDescription("Namify")]
[assembly: AssemblyFileVersion("0.2.3.0")]
[assembly: AssemblyInformationalVersion("0.2.3+05fe0568a48e1f90139e200bb2cd085fa2e2d6c2")]
[assembly: AssemblyProduct("Namify")]
[assembly: AssemblyTitle("Namify")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace Namify
{
	public static class Data
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass16_0
		{
			public Action onFail;

			public Action onComplete;

			public Action<UnityWebRequest> <>9__0;

			internal void <GetNamifyNamesBackupRequest>b__0(UnityWebRequest req)
			{
				//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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Invalid comparison between Unknown and I4
				Result result = req.result;
				if (result - 2 <= 2)
				{
					Plugin.Log.LogError((object)(req.error + ": " + req.downloadHandler.text));
					NotificationCentre.Instance.PlayGenericNotification(Localization.ApiBackupError, (Flair)0);
					onFail?.Invoke();
					return;
				}
				string[] array = JsonConvert.DeserializeObject<string[]>(req.downloadHandler.text);
				foreach (string item in array)
				{
					NamifyNames.Add(item);
				}
				SaveData();
				NotificationCentre.Instance.PlayGenericNotification(Localization.NamesRetrievedBackup, (Flair)0);
				onComplete?.Invoke();
			}
		}

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

			private object <>2__current;

			public Action onFail;

			public Action onComplete;

			private <>c__DisplayClass16_0 <>8__1;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass16_0();
					<>8__1.onFail = onFail;
					<>8__1.onComplete = onComplete;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 10)
				{
					<>2__current = ((MonoBehaviour)GameManager.GetInstance()).StartCoroutine(NamifyNamesGetRequest("https://namey.muffinlabs.com/name.json?count=10&with_surname=true&frequency=all", apiKey: false, delegate(UnityWebRequest req)
					{
						//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_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_0009: Unknown result type (might be due to invalid IL or missing references)
						//IL_000b: Invalid comparison between Unknown and I4
						Result result = req.result;
						if (result - 2 <= 2)
						{
							Plugin.Log.LogError((object)(req.error + ": " + req.downloadHandler.text));
							NotificationCentre.Instance.PlayGenericNotification(Localization.ApiBackupError, (Flair)0);
							<>8__1.onFail?.Invoke();
						}
						else
						{
							string[] array = JsonConvert.DeserializeObject<string[]>(req.downloadHandler.text);
							foreach (string item in array)
							{
								NamifyNames.Add(item);
							}
							SaveData();
							NotificationCentre.Instance.PlayGenericNotification(Localization.NamesRetrievedBackup, (Flair)0);
							<>8__1.onComplete?.Invoke();
						}
					}));
					<>1__state = 1;
					return true;
				}
				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 <NamifyNamesGetRequest>d__17 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public string endpoint;

			public bool apiKey;

			public Action<UnityWebRequest> callback;

			private UnityWebRequest <request>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<request>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<request>5__2 = UnityWebRequest.Get(endpoint);
						<>1__state = -3;
						if (apiKey)
						{
							<request>5__2.SetRequestHeader("X-Api-Key", Plugin.PersonalApiKey.Value);
						}
						<>2__current = <request>5__2.SendWebRequest();
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -3;
						callback(<request>5__2);
						<>m__Finally1();
						return false;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				UnityWebRequest obj = <request>5__2;
				if (obj != null)
				{
					obj.Dispose();
				}
			}

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

		internal const string NamifyDataPath = "namify_names.json";

		internal const string UserDataPath = "user_names.json";

		public static SortedSet<string> NamifyNames = new SortedSet<string>();

		public static SortedSet<string> UserNames = new SortedSet<string>();

		private static string SavesDirectory => Path.Combine(Application.persistentDataPath, "saves");

		internal static string NamifyNamesFilePath => Path.Combine(SavesDirectory, "namify_names.json");

		internal static string UserNamesFilePath => Path.Combine(SavesDirectory, "user_names.json");

		private static void RemoveFollowerNames()
		{
			if (Follower.Followers == null)
			{
				return;
			}
			foreach (string name in NamifyNames)
			{
				Follower.Followers.RemoveAll(delegate(Follower a)
				{
					object obj2;
					if (a == null)
					{
						obj2 = null;
					}
					else
					{
						FollowerBrain brain2 = a.Brain;
						if (brain2 == null)
						{
							obj2 = null;
						}
						else
						{
							FollowerBrainInfo info2 = brain2.Info;
							obj2 = ((info2 != null) ? info2.Name : null);
						}
					}
					return (string?)obj2 == name;
				});
			}
			foreach (string name2 in UserNames)
			{
				Follower.Followers.RemoveAll(delegate(Follower a)
				{
					object obj;
					if (a == null)
					{
						obj = null;
					}
					else
					{
						FollowerBrain brain = a.Brain;
						if (brain == null)
						{
							obj = null;
						}
						else
						{
							FollowerBrainInfo info = brain.Info;
							obj = ((info != null) ? info.Name : null);
						}
					}
					return (string?)obj == name2;
				});
			}
		}

		internal static void LoadData()
		{
			Directory.CreateDirectory(SavesDirectory);
			NamifyNames = LoadNamesFromFile(NamifyNamesFilePath);
			if (NamifyNames.Count > 0)
			{
				Plugin.Log.LogInfo((object)$"Loaded {NamifyNames.Count} Namify generated names.");
			}
			UserNames = LoadNamesFromFile(UserNamesFilePath);
			if (UserNames.Count > 0)
			{
				Plugin.Log.LogInfo((object)$"Loaded {UserNames.Count} user-generated names.");
			}
			RemoveFollowerNames();
		}

		private static SortedSet<string> LoadNamesFromFile(string jsonPath)
		{
			if (File.Exists(jsonPath))
			{
				try
				{
					List<string> list = JsonConvert.DeserializeObject<List<string>>(File.ReadAllText(jsonPath));
					return (list != null) ? new SortedSet<string>(list) : new SortedSet<string>();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Failed to load " + jsonPath + ": " + ex.Message));
				}
			}
			string path = Path.ChangeExtension(jsonPath, ".mp");
			if (File.Exists(path))
			{
				Plugin.Log.LogWarning((object)("Found old format file: " + Path.GetFileName(path)));
				Plugin.Log.LogWarning((object)"This file was created by the game's old save system and cannot be read.");
				Plugin.Log.LogWarning((object)"Please delete it and the mod will regenerate names from the API.");
			}
			return new SortedSet<string>();
		}

		internal static void SaveData()
		{
			Directory.CreateDirectory(SavesDirectory);
			SaveNamesToFile(NamifyNamesFilePath, NamifyNames);
			SaveNamesToFile(UserNamesFilePath, UserNames);
		}

		private static void SaveNamesToFile(string path, SortedSet<string> names)
		{
			try
			{
				string contents = JsonConvert.SerializeObject((object)names.ToList(), (Formatting)1);
				File.WriteAllText(path, contents);
				Plugin.Log.LogInfo((object)$"Saved {names.Count} names to {Path.GetFileName(path)}");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to save " + path + ": " + ex.Message));
			}
		}

		internal static void GetNamifyNames(Action onFail = null, Action onComplete = null)
		{
			if (NamifyNames.Count > 0)
			{
				return;
			}
			GameManager instance = GameManager.GetInstance();
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.Log.LogInfo((object)"GameManager not ready, cannot fetch names");
				onFail?.Invoke();
				return;
			}
			((MonoBehaviour)instance).StartCoroutine(NamifyNamesGetRequest("https://randommer.io/api/Name?nameType=fullname&quantity=1000", apiKey: true, delegate(UnityWebRequest req)
			{
				//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_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Invalid comparison between Unknown and I4
				Result result = req.result;
				if (result - 2 <= 2)
				{
					Plugin.Log.LogError((object)(req.error + ": " + req.downloadHandler.text));
					NotificationCentre.Instance.PlayGenericNotification(Localization.ApiError, (Flair)0);
					GameManager instance2 = GameManager.GetInstance();
					if ((Object)(object)instance2 != (Object)null)
					{
						((MonoBehaviour)instance2).StartCoroutine(GetNamifyNamesBackupRequest(onFail, onComplete));
					}
					else
					{
						onFail?.Invoke();
					}
				}
				else
				{
					string[] array = JsonConvert.DeserializeObject<string[]>(req.downloadHandler.text);
					foreach (string text in array)
					{
						NamifyNames.AddRange(text.Split());
					}
					SaveData();
					NotificationCentre.Instance.PlayGenericNotification(Localization.NamesRetrieved, (Flair)0);
					onComplete?.Invoke();
				}
			}));
		}

		[IteratorStateMachine(typeof(<GetNamifyNamesBackupRequest>d__16))]
		private static IEnumerator GetNamifyNamesBackupRequest(Action onFail = null, Action onComplete = null)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GetNamifyNamesBackupRequest>d__16(0)
			{
				onFail = onFail,
				onComplete = onComplete
			};
		}

		[IteratorStateMachine(typeof(<NamifyNamesGetRequest>d__17))]
		private static IEnumerator NamifyNamesGetRequest(string endpoint, bool apiKey, Action<UnityWebRequest> callback)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <NamifyNamesGetRequest>d__17(0)
			{
				endpoint = endpoint,
				apiKey = apiKey,
				callback = callback
			};
		}
	}
	internal static class Localization
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Strings = new Dictionary<string, Dictionary<string, string>>
		{
			{
				"English",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Add Name" },
					{ "OpenNamifyList", "Open Namify List" },
					{ "OpenUserList", "Open User List" },
					{ "GenerateNewNames", "Generate New Names" },
					{ "ReloadNamesFromFile", "Reload Names From File" },
					{ "Yes", "Yes" },
					{ "No", "No" },
					{ "ConfirmGenerateNew", "Are you sure you want to generate new names?" },
					{ "ConfirmReload", "Are you sure you want to reload names from file?" },
					{ "NamesReloaded", "Names reloaded from file!" },
					{ "ErrorReloading", "Error reloading names. Check log for details." },
					{ "NewNamesGenerated", "New names generated!" },
					{ "ErrorGenerating", "Error generating new names!" },
					{ "NameAdded", "Added '{0}' to available names!" },
					{ "NameExists", "'{0}' already exists!" },
					{ "NoNameEntered", "You haven't entered a name to add?" },
					{ "FileNotFound", "File not found: {0}" },
					{ "ApiError", "Error retrieving names! Trying backup source..." },
					{ "ApiBackupError", "Error retrieving names from backup source!" },
					{ "NamesRetrieved", "Names retrieved for Namify!" },
					{ "NamesRetrievedBackup", "Names retrieved from backup source!" },
					{ "DescAsteriskNames", "Show an asterisk next to Namify-generated names in the indoctrination UI." },
					{ "DescAddName", "Enter a custom name to add to your personal name list." },
					{ "DescAddNameButton", "Add the name entered above to your personal list." },
					{ "DescOpenNamifyFile", "Opens the API-generated names file for viewing/editing." },
					{ "DescOpenUserFile", "Opens your personal names file for viewing/editing." },
					{ "DescGenerateNew", "Fetches a fresh batch of names from the API. Your personal names are preserved." },
					{ "DescReloadNames", "Reloads names from file (useful after manual edits)." },
					{ "DescApiKey", "The default key is shared and limited to 1000 requests/day. Get your own free key at https://randommer.io/" }
				}
			},
			{
				"French",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Ajouter un nom" },
					{ "OpenNamifyList", "Ouvrir la liste Namify" },
					{ "OpenUserList", "Ouvrir ma liste" },
					{ "GenerateNewNames", "Générer de nouveaux noms" },
					{ "ReloadNamesFromFile", "Recharger depuis le fichier" },
					{ "Yes", "Oui" },
					{ "No", "Non" },
					{ "ConfirmGenerateNew", "Voulez-vous vraiment générer de nouveaux noms?" },
					{ "ConfirmReload", "Voulez-vous vraiment recharger les noms depuis le fichier?" },
					{ "NamesReloaded", "Noms rechargés depuis le fichier!" },
					{ "ErrorReloading", "Erreur lors du rechargement. Consultez le journal." },
					{ "NewNamesGenerated", "Nouveaux noms générés!" },
					{ "ErrorGenerating", "Erreur lors de la génération!" },
					{ "NameAdded", "'{0}' ajouté aux noms disponibles!" },
					{ "NameExists", "'{0}' existe déjà!" },
					{ "NoNameEntered", "Vous n'avez pas entré de nom?" },
					{ "FileNotFound", "Fichier non trouvé: {0}" },
					{ "ApiError", "Erreur de récupération! Essai de la source de secours..." },
					{ "ApiBackupError", "Erreur de récupération depuis la source de secours!" },
					{ "NamesRetrieved", "Noms récupérés pour Namify!" },
					{ "NamesRetrievedBackup", "Noms récupérés depuis la source de secours!" },
					{ "DescAsteriskNames", "Afficher un astérisque à côté des noms générés par Namify." },
					{ "DescAddName", "Entrez un nom personnalisé à ajouter à votre liste." },
					{ "DescAddNameButton", "Ajouter le nom ci-dessus à votre liste personnelle." },
					{ "DescOpenNamifyFile", "Ouvre le fichier des noms générés par l'API." },
					{ "DescOpenUserFile", "Ouvre votre fichier de noms personnels." },
					{ "DescGenerateNew", "Récupère de nouveaux noms depuis l'API. Vos noms personnels sont conservés." },
					{ "DescReloadNames", "Recharge les noms depuis le fichier (utile après modification manuelle)." },
					{ "DescApiKey", "La clé par défaut est partagée et limitée à 1000 requêtes/jour. Obtenez votre clé gratuite sur https://randommer.io/" }
				}
			},
			{
				"German",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Name hinzufügen" },
					{ "OpenNamifyList", "Namify-Liste öffnen" },
					{ "OpenUserList", "Benutzerliste öffnen" },
					{ "GenerateNewNames", "Neue Namen generieren" },
					{ "ReloadNamesFromFile", "Namen aus Datei laden" },
					{ "Yes", "Ja" },
					{ "No", "Nein" },
					{ "ConfirmGenerateNew", "Möchten Sie wirklich neue Namen generieren?" },
					{ "ConfirmReload", "Möchten Sie wirklich Namen aus der Datei laden?" },
					{ "NamesReloaded", "Namen aus Datei geladen!" },
					{ "ErrorReloading", "Fehler beim Laden. Siehe Protokoll." },
					{ "NewNamesGenerated", "Neue Namen generiert!" },
					{ "ErrorGenerating", "Fehler beim Generieren!" },
					{ "NameAdded", "'{0}' zu verfügbaren Namen hinzugefügt!" },
					{ "NameExists", "'{0}' existiert bereits!" },
					{ "NoNameEntered", "Sie haben keinen Namen eingegeben?" },
					{ "FileNotFound", "Datei nicht gefunden: {0}" },
					{ "ApiError", "Abruffehler! Versuche Backup-Quelle..." },
					{ "ApiBackupError", "Fehler beim Abruf von Backup-Quelle!" },
					{ "NamesRetrieved", "Namen für Namify abgerufen!" },
					{ "NamesRetrievedBackup", "Namen von Backup-Quelle abgerufen!" },
					{ "DescAsteriskNames", "Zeigt ein Sternchen neben Namify-generierten Namen an." },
					{ "DescAddName", "Geben Sie einen benutzerdefinierten Namen ein." },
					{ "DescAddNameButton", "Fügt den obigen Namen zu Ihrer Liste hinzu." },
					{ "DescOpenNamifyFile", "Öffnet die API-generierte Namensdatei." },
					{ "DescOpenUserFile", "Öffnet Ihre persönliche Namensdatei." },
					{ "DescGenerateNew", "Ruft neue Namen von der API ab. Ihre Namen bleiben erhalten." },
					{ "DescReloadNames", "Lädt Namen aus Datei neu (nützlich nach manueller Bearbeitung)." },
					{ "DescApiKey", "Der Standardschlüssel ist geteilt und auf 1000 Anfragen/Tag begrenzt. Holen Sie sich Ihren kostenlosen Schlüssel auf https://randommer.io/" }
				}
			},
			{
				"Spanish",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Añadir nombre" },
					{ "OpenNamifyList", "Abrir lista Namify" },
					{ "OpenUserList", "Abrir mi lista" },
					{ "GenerateNewNames", "Generar nuevos nombres" },
					{ "ReloadNamesFromFile", "Recargar desde archivo" },
					{ "Yes", "Sí" },
					{ "No", "No" },
					{ "ConfirmGenerateNew", "¿Seguro que quieres generar nuevos nombres?" },
					{ "ConfirmReload", "¿Seguro que quieres recargar los nombres desde el archivo?" },
					{ "NamesReloaded", "¡Nombres recargados desde el archivo!" },
					{ "ErrorReloading", "Error al recargar. Consulta el registro." },
					{ "NewNamesGenerated", "¡Nuevos nombres generados!" },
					{ "ErrorGenerating", "¡Error al generar!" },
					{ "NameAdded", "¡'{0}' añadido a los nombres disponibles!" },
					{ "NameExists", "¡'{0}' ya existe!" },
					{ "NoNameEntered", "¿No has introducido un nombre?" },
					{ "FileNotFound", "Archivo no encontrado: {0}" },
					{ "ApiError", "¡Error de recuperación! Probando fuente de respaldo..." },
					{ "ApiBackupError", "¡Error de recuperación desde fuente de respaldo!" },
					{ "NamesRetrieved", "¡Nombres recuperados para Namify!" },
					{ "NamesRetrievedBackup", "¡Nombres recuperados desde fuente de respaldo!" },
					{ "DescAsteriskNames", "Muestra un asterisco junto a los nombres generados por Namify." },
					{ "DescAddName", "Introduce un nombre personalizado para añadir a tu lista." },
					{ "DescAddNameButton", "Añade el nombre de arriba a tu lista personal." },
					{ "DescOpenNamifyFile", "Abre el archivo de nombres generados por la API." },
					{ "DescOpenUserFile", "Abre tu archivo de nombres personales." },
					{ "DescGenerateNew", "Obtiene nuevos nombres de la API. Tus nombres se conservan." },
					{ "DescReloadNames", "Recarga nombres desde el archivo (útil después de editar manualmente)." },
					{ "DescApiKey", "La clave predeterminada es compartida y limitada a 1000 solicitudes/día. Obtén tu clave gratuita en https://randommer.io/" }
				}
			},
			{
				"Japanese",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "名前を追加" },
					{ "OpenNamifyList", "Namifyリストを開く" },
					{ "OpenUserList", "ユーザーリストを開く" },
					{ "GenerateNewNames", "新しい名前を生成" },
					{ "ReloadNamesFromFile", "ファイルから再読み込み" },
					{ "Yes", "はい" },
					{ "No", "いいえ" },
					{ "ConfirmGenerateNew", "新しい名前を生成してもよろしいですか?" },
					{ "ConfirmReload", "ファイルから名前を再読み込みしてもよろしいですか?" },
					{ "NamesReloaded", "ファイルから名前を再読み込みしました!" },
					{ "ErrorReloading", "再読み込みエラー。ログを確認してください。" },
					{ "NewNamesGenerated", "新しい名前を生成しました!" },
					{ "ErrorGenerating", "生成エラー!" },
					{ "NameAdded", "'{0}'を利用可能な名前に追加しました!" },
					{ "NameExists", "'{0}'は既に存在します!" },
					{ "NoNameEntered", "名前が入力されていません?" },
					{ "FileNotFound", "ファイルが見つかりません: {0}" },
					{ "ApiError", "取得エラー!バックアップソースを試しています..." },
					{ "ApiBackupError", "バックアップソースからの取得エラー!" },
					{ "NamesRetrieved", "Namify用の名前を取得しました!" },
					{ "NamesRetrievedBackup", "バックアップソースから名前を取得しました!" },
					{ "DescAsteriskNames", "Namifyで生成された名前の横にアスタリスクを表示します。" },
					{ "DescAddName", "リストに追加するカスタム名を入力してください。" },
					{ "DescAddNameButton", "上記の名前を個人リストに追加します。" },
					{ "DescOpenNamifyFile", "API生成の名前ファイルを開きます。" },
					{ "DescOpenUserFile", "個人の名前ファイルを開きます。" },
					{ "DescGenerateNew", "APIから新しい名前を取得します。個人の名前は保持されます。" },
					{ "DescReloadNames", "ファイルから名前を再読み込みします(手動編集後に便利)。" },
					{ "DescApiKey", "デフォルトキーは共有され、1日1000リクエストに制限されています。https://randommer.io/で無料キーを取得してください。" }
				}
			},
			{
				"Russian",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Добавить имя" },
					{ "OpenNamifyList", "Открыть список Namify" },
					{ "OpenUserList", "Открыть мой список" },
					{ "GenerateNewNames", "Создать новые имена" },
					{ "ReloadNamesFromFile", "Перезагрузить из файла" },
					{ "Yes", "Да" },
					{ "No", "Нет" },
					{ "ConfirmGenerateNew", "Вы уверены, что хотите создать новые имена?" },
					{ "ConfirmReload", "Вы уверены, что хотите перезагрузить имена из файла?" },
					{ "NamesReloaded", "Имена перезагружены из файла!" },
					{ "ErrorReloading", "Ошибка перезагрузки. Проверьте журнал." },
					{ "NewNamesGenerated", "Новые имена созданы!" },
					{ "ErrorGenerating", "Ошибка создания!" },
					{ "NameAdded", "'{0}' добавлено в доступные имена!" },
					{ "NameExists", "'{0}' уже существует!" },
					{ "NoNameEntered", "Вы не ввели имя?" },
					{ "FileNotFound", "Файл не найден: {0}" },
					{ "ApiError", "Ошибка получения! Пробуем резервный источник..." },
					{ "ApiBackupError", "Ошибка получения из резервного источника!" },
					{ "NamesRetrieved", "Имена получены для Namify!" },
					{ "NamesRetrievedBackup", "Имена получены из резервного источника!" },
					{ "DescAsteriskNames", "Показывать звёздочку рядом с именами, созданными Namify." },
					{ "DescAddName", "Введите пользовательское имя для добавления в ваш список." },
					{ "DescAddNameButton", "Добавляет вышеуказанное имя в ваш личный список." },
					{ "DescOpenNamifyFile", "Открывает файл имён, созданных API." },
					{ "DescOpenUserFile", "Открывает ваш личный файл имён." },
					{ "DescGenerateNew", "Получает новые имена из API. Ваши имена сохраняются." },
					{ "DescReloadNames", "Перезагружает имена из файла (полезно после ручного редактирования)." },
					{ "DescApiKey", "Ключ по умолчанию общий и ограничен 1000 запросами в день. Получите бесплатный ключ на https://randommer.io/" }
				}
			},
			{
				"Portuguese (Brazil)",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Adicionar nome" },
					{ "OpenNamifyList", "Abrir lista Namify" },
					{ "OpenUserList", "Abrir minha lista" },
					{ "GenerateNewNames", "Gerar novos nomes" },
					{ "ReloadNamesFromFile", "Recarregar do arquivo" },
					{ "Yes", "Sim" },
					{ "No", "Não" },
					{ "ConfirmGenerateNew", "Tem certeza que deseja gerar novos nomes?" },
					{ "ConfirmReload", "Tem certeza que deseja recarregar os nomes do arquivo?" },
					{ "NamesReloaded", "Nomes recarregados do arquivo!" },
					{ "ErrorReloading", "Erro ao recarregar. Verifique o log." },
					{ "NewNamesGenerated", "Novos nomes gerados!" },
					{ "ErrorGenerating", "Erro ao gerar!" },
					{ "NameAdded", "'{0}' adicionado aos nomes disponíveis!" },
					{ "NameExists", "'{0}' já existe!" },
					{ "NoNameEntered", "Você não digitou um nome?" },
					{ "FileNotFound", "Arquivo não encontrado: {0}" },
					{ "ApiError", "Erro de recuperação! Tentando fonte de backup..." },
					{ "ApiBackupError", "Erro de recuperação da fonte de backup!" },
					{ "NamesRetrieved", "Nomes recuperados para Namify!" },
					{ "NamesRetrievedBackup", "Nomes recuperados da fonte de backup!" },
					{ "DescAsteriskNames", "Mostra um asterisco ao lado dos nomes gerados pelo Namify." },
					{ "DescAddName", "Digite um nome personalizado para adicionar à sua lista." },
					{ "DescAddNameButton", "Adiciona o nome acima à sua lista pessoal." },
					{ "DescOpenNamifyFile", "Abre o arquivo de nomes gerados pela API." },
					{ "DescOpenUserFile", "Abre seu arquivo de nomes pessoais." },
					{ "DescGenerateNew", "Obtém novos nomes da API. Seus nomes são preservados." },
					{ "DescReloadNames", "Recarrega nomes do arquivo (útil após edição manual)." },
					{ "DescApiKey", "A chave padrão é compartilhada e limitada a 1000 solicitações/dia. Obtenha sua chave gratuita em https://randommer.io/" }
				}
			},
			{
				"Chinese (Simplified)",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "添加名字" },
					{ "OpenNamifyList", "打开Namify列表" },
					{ "OpenUserList", "打开用户列表" },
					{ "GenerateNewNames", "生成新名字" },
					{ "ReloadNamesFromFile", "从文件重新加载" },
					{ "Yes", "是" },
					{ "No", "否" },
					{ "ConfirmGenerateNew", "确定要生成新名字吗?" },
					{ "ConfirmReload", "确定要从文件重新加载名字吗?" },
					{ "NamesReloaded", "已从文件重新加载名字!" },
					{ "ErrorReloading", "重新加载错误。请检查日志。" },
					{ "NewNamesGenerated", "已生成新名字!" },
					{ "ErrorGenerating", "生成错误!" },
					{ "NameAdded", "已将'{0}'添加到可用名字!" },
					{ "NameExists", "'{0}'已存在!" },
					{ "NoNameEntered", "您没有输入名字?" },
					{ "FileNotFound", "找不到文件:{0}" },
					{ "ApiError", "获取错误!正在尝试备用源..." },
					{ "ApiBackupError", "从备用源获取错误!" },
					{ "NamesRetrieved", "已为Namify获取名字!" },
					{ "NamesRetrievedBackup", "已从备用源获取名字!" },
					{ "DescAsteriskNames", "在Namify生成的名字旁边显示星号。" },
					{ "DescAddName", "输入要添加到列表的自定义名字。" },
					{ "DescAddNameButton", "将上面的名字添加到您的个人列表。" },
					{ "DescOpenNamifyFile", "打开API生成的名字文件。" },
					{ "DescOpenUserFile", "打开您的个人名字文件。" },
					{ "DescGenerateNew", "从API获取新名字。您的名字将被保留。" },
					{ "DescReloadNames", "从文件重新加载名字(手动编辑后有用)。" },
					{ "DescApiKey", "默认密钥是共享的,每天限制1000个请求。在https://randommer.io/获取免费密钥。" }
				}
			},
			{
				"Chinese (Traditional)",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "新增名字" },
					{ "OpenNamifyList", "開啟Namify清單" },
					{ "OpenUserList", "開啟使用者清單" },
					{ "GenerateNewNames", "產生新名字" },
					{ "ReloadNamesFromFile", "從檔案重新載入" },
					{ "Yes", "是" },
					{ "No", "否" },
					{ "ConfirmGenerateNew", "確定要產生新名字嗎?" },
					{ "ConfirmReload", "確定要從檔案重新載入名字嗎?" },
					{ "NamesReloaded", "已從檔案重新載入名字!" },
					{ "ErrorReloading", "重新載入錯誤。請檢查日誌。" },
					{ "NewNamesGenerated", "已產生新名字!" },
					{ "ErrorGenerating", "產生錯誤!" },
					{ "NameAdded", "已將'{0}'新增至可用名字!" },
					{ "NameExists", "'{0}'已存在!" },
					{ "NoNameEntered", "您沒有輸入名字?" },
					{ "FileNotFound", "找不到檔案:{0}" },
					{ "ApiError", "取得錯誤!正在嘗試備用來源..." },
					{ "ApiBackupError", "從備用來源取得錯誤!" },
					{ "NamesRetrieved", "已為Namify取得名字!" },
					{ "NamesRetrievedBackup", "已從備用來源取得名字!" },
					{ "DescAsteriskNames", "在Namify產生的名字旁邊顯示星號。" },
					{ "DescAddName", "輸入要新增至清單的自訂名字。" },
					{ "DescAddNameButton", "將上面的名字新增至您的個人清單。" },
					{ "DescOpenNamifyFile", "開啟API產生的名字檔案。" },
					{ "DescOpenUserFile", "開啟您的個人名字檔案。" },
					{ "DescGenerateNew", "從API取得新名字。您的名字將被保留。" },
					{ "DescReloadNames", "從檔案重新載入名字(手動編輯後有用)。" },
					{ "DescApiKey", "預設金鑰是共用的,每天限制1000個請求。在https://randommer.io/取得免費金鑰。" }
				}
			},
			{
				"Korean",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "이름 추가" },
					{ "OpenNamifyList", "Namify 목록 열기" },
					{ "OpenUserList", "사용자 목록 열기" },
					{ "GenerateNewNames", "새 이름 생성" },
					{ "ReloadNamesFromFile", "파일에서 다시 로드" },
					{ "Yes", "예" },
					{ "No", "아니오" },
					{ "ConfirmGenerateNew", "새 이름을 생성하시겠습니까?" },
					{ "ConfirmReload", "파일에서 이름을 다시 로드하시겠습니까?" },
					{ "NamesReloaded", "파일에서 이름을 다시 로드했습니다!" },
					{ "ErrorReloading", "다시 로드 오류. 로그를 확인하세요." },
					{ "NewNamesGenerated", "새 이름이 생성되었습니다!" },
					{ "ErrorGenerating", "생성 오류!" },
					{ "NameAdded", "'{0}'이(가) 사용 가능한 이름에 추가되었습니다!" },
					{ "NameExists", "'{0}'이(가) 이미 존재합니다!" },
					{ "NoNameEntered", "이름을 입력하지 않았습니까?" },
					{ "FileNotFound", "파일을 찾을 수 없음: {0}" },
					{ "ApiError", "검색 오류! 백업 소스 시도 중..." },
					{ "ApiBackupError", "백업 소스에서 검색 오류!" },
					{ "NamesRetrieved", "Namify용 이름을 검색했습니다!" },
					{ "NamesRetrievedBackup", "백업 소스에서 이름을 검색했습니다!" },
					{ "DescAsteriskNames", "Namify에서 생성한 이름 옆에 별표를 표시합니다." },
					{ "DescAddName", "목록에 추가할 사용자 정의 이름을 입력하세요." },
					{ "DescAddNameButton", "위의 이름을 개인 목록에 추가합니다." },
					{ "DescOpenNamifyFile", "API에서 생성한 이름 파일을 엽니다." },
					{ "DescOpenUserFile", "개인 이름 파일을 엽니다." },
					{ "DescGenerateNew", "API에서 새 이름을 가져옵니다. 기존 이름은 유지됩니다." },
					{ "DescReloadNames", "파일에서 이름을 다시 로드합니다 (수동 편집 후 유용)." },
					{ "DescApiKey", "기본 키는 공유되며 하루 1000개 요청으로 제한됩니다. https://randommer.io/에서 무료 키를 받으세요." }
				}
			},
			{
				"Italian",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Aggiungi nome" },
					{ "OpenNamifyList", "Apri lista Namify" },
					{ "OpenUserList", "Apri la mia lista" },
					{ "GenerateNewNames", "Genera nuovi nomi" },
					{ "ReloadNamesFromFile", "Ricarica da file" },
					{ "Yes", "Sì" },
					{ "No", "No" },
					{ "ConfirmGenerateNew", "Sei sicuro di voler generare nuovi nomi?" },
					{ "ConfirmReload", "Sei sicuro di voler ricaricare i nomi dal file?" },
					{ "NamesReloaded", "Nomi ricaricati dal file!" },
					{ "ErrorReloading", "Errore nel ricaricamento. Controlla il log." },
					{ "NewNamesGenerated", "Nuovi nomi generati!" },
					{ "ErrorGenerating", "Errore nella generazione!" },
					{ "NameAdded", "'{0}' aggiunto ai nomi disponibili!" },
					{ "NameExists", "'{0}' esiste già!" },
					{ "NoNameEntered", "Non hai inserito un nome?" },
					{ "FileNotFound", "File non trovato: {0}" },
					{ "ApiError", "Errore di recupero! Tentativo con fonte di backup..." },
					{ "ApiBackupError", "Errore di recupero dalla fonte di backup!" },
					{ "NamesRetrieved", "Nomi recuperati per Namify!" },
					{ "NamesRetrievedBackup", "Nomi recuperati dalla fonte di backup!" },
					{ "DescAsteriskNames", "Mostra un asterisco accanto ai nomi generati da Namify." },
					{ "DescAddName", "Inserisci un nome personalizzato da aggiungere alla tua lista." },
					{ "DescAddNameButton", "Aggiunge il nome sopra alla tua lista personale." },
					{ "DescOpenNamifyFile", "Apre il file dei nomi generati dall'API." },
					{ "DescOpenUserFile", "Apre il tuo file dei nomi personali." },
					{ "DescGenerateNew", "Recupera nuovi nomi dall'API. I tuoi nomi vengono preservati." },
					{ "DescReloadNames", "Ricarica i nomi dal file (utile dopo modifiche manuali)." },
					{ "DescApiKey", "La chiave predefinita è condivisa e limitata a 1000 richieste/giorno. Ottieni la tua chiave gratuita su https://randommer.io/" }
				}
			},
			{
				"Dutch",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Naam toevoegen" },
					{ "OpenNamifyList", "Namify-lijst openen" },
					{ "OpenUserList", "Mijn lijst openen" },
					{ "GenerateNewNames", "Nieuwe namen genereren" },
					{ "ReloadNamesFromFile", "Herladen uit bestand" },
					{ "Yes", "Ja" },
					{ "No", "Nee" },
					{ "ConfirmGenerateNew", "Weet je zeker dat je nieuwe namen wilt genereren?" },
					{ "ConfirmReload", "Weet je zeker dat je de namen wilt herladen uit het bestand?" },
					{ "NamesReloaded", "Namen herladen uit bestand!" },
					{ "ErrorReloading", "Fout bij herladen. Controleer het logboek." },
					{ "NewNamesGenerated", "Nieuwe namen gegenereerd!" },
					{ "ErrorGenerating", "Fout bij genereren!" },
					{ "NameAdded", "'{0}' toegevoegd aan beschikbare namen!" },
					{ "NameExists", "'{0}' bestaat al!" },
					{ "NoNameEntered", "Je hebt geen naam ingevoerd?" },
					{ "FileNotFound", "Bestand niet gevonden: {0}" },
					{ "ApiError", "Ophaalfout! Back-upbron proberen..." },
					{ "ApiBackupError", "Fout bij ophalen van back-upbron!" },
					{ "NamesRetrieved", "Namen opgehaald voor Namify!" },
					{ "NamesRetrievedBackup", "Namen opgehaald van back-upbron!" },
					{ "DescAsteriskNames", "Toont een asterisk naast door Namify gegenereerde namen." },
					{ "DescAddName", "Voer een aangepaste naam in om aan je lijst toe te voegen." },
					{ "DescAddNameButton", "Voegt de bovenstaande naam toe aan je persoonlijke lijst." },
					{ "DescOpenNamifyFile", "Opent het API-gegenereerde namenbestand." },
					{ "DescOpenUserFile", "Opent je persoonlijke namenbestand." },
					{ "DescGenerateNew", "Haalt nieuwe namen op van de API. Je namen blijven behouden." },
					{ "DescReloadNames", "Herlaadt namen uit bestand (handig na handmatige bewerking)." },
					{ "DescApiKey", "De standaardsleutel is gedeeld en beperkt tot 1000 verzoeken/dag. Haal je gratis sleutel op https://randommer.io/" }
				}
			},
			{
				"Turkish",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "İsim Ekle" },
					{ "OpenNamifyList", "Namify Listesini Aç" },
					{ "OpenUserList", "Kullanıcı Listesini Aç" },
					{ "GenerateNewNames", "Yeni İsimler Oluştur" },
					{ "ReloadNamesFromFile", "Dosyadan Yeniden Yükle" },
					{ "Yes", "Evet" },
					{ "No", "Hayır" },
					{ "ConfirmGenerateNew", "Yeni isimler oluşturmak istediğinizden emin misiniz?" },
					{ "ConfirmReload", "İsimleri dosyadan yeniden yüklemek istediğinizden emin misiniz?" },
					{ "NamesReloaded", "İsimler dosyadan yeniden yüklendi!" },
					{ "ErrorReloading", "Yeniden yükleme hatası. Günlüğü kontrol edin." },
					{ "NewNamesGenerated", "Yeni isimler oluşturuldu!" },
					{ "ErrorGenerating", "Oluşturma hatası!" },
					{ "NameAdded", "'{0}' mevcut isimlere eklendi!" },
					{ "NameExists", "'{0}' zaten mevcut!" },
					{ "NoNameEntered", "Bir isim girmediniz mi?" },
					{ "FileNotFound", "Dosya bulunamadı: {0}" },
					{ "ApiError", "Alma hatası! Yedek kaynak deneniyor..." },
					{ "ApiBackupError", "Yedek kaynaktan alma hatası!" },
					{ "NamesRetrieved", "Namify için isimler alındı!" },
					{ "NamesRetrievedBackup", "Yedek kaynaktan isimler alındı!" },
					{ "DescAsteriskNames", "Namify tarafından oluşturulan isimlerin yanında yıldız gösterir." },
					{ "DescAddName", "Listenize eklemek için özel bir isim girin." },
					{ "DescAddNameButton", "Yukarıdaki ismi kişisel listenize ekler." },
					{ "DescOpenNamifyFile", "API tarafından oluşturulan isimler dosyasını açar." },
					{ "DescOpenUserFile", "Kişisel isimler dosyanızı açar." },
					{ "DescGenerateNew", "API'den yeni isimler alır. İsimleriniz korunur." },
					{ "DescReloadNames", "Dosyadan isimleri yeniden yükler (manuel düzenlemeden sonra yararlı)." },
					{ "DescApiKey", "Varsayılan anahtar paylaşılır ve günde 1000 istekle sınırlıdır. https://randommer.io/ adresinden ücretsiz anahtarınızı alın." }
				}
			},
			{
				"French (Canada)",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "Ajouter un nom" },
					{ "OpenNamifyList", "Ouvrir la liste Namify" },
					{ "OpenUserList", "Ouvrir ma liste" },
					{ "GenerateNewNames", "Générer de nouveaux noms" },
					{ "ReloadNamesFromFile", "Recharger du fichier" },
					{ "Yes", "Oui" },
					{ "No", "Non" },
					{ "ConfirmGenerateNew", "Êtes-vous certain de vouloir générer de nouveaux noms?" },
					{ "ConfirmReload", "Êtes-vous certain de vouloir recharger les noms du fichier?" },
					{ "NamesReloaded", "Noms rechargés du fichier!" },
					{ "ErrorReloading", "Erreur de rechargement. Vérifiez le journal." },
					{ "NewNamesGenerated", "Nouveaux noms générés!" },
					{ "ErrorGenerating", "Erreur de génération!" },
					{ "NameAdded", "'{0}' ajouté aux noms disponibles!" },
					{ "NameExists", "'{0}' existe déjà!" },
					{ "NoNameEntered", "Vous n'avez pas entré de nom?" },
					{ "FileNotFound", "Fichier non trouvé: {0}" },
					{ "ApiError", "Erreur de récupération! Essai de la source de secours..." },
					{ "ApiBackupError", "Erreur de récupération de la source de secours!" },
					{ "NamesRetrieved", "Noms récupérés pour Namify!" },
					{ "NamesRetrievedBackup", "Noms récupérés de la source de secours!" },
					{ "DescAsteriskNames", "Affiche un astérisque à côté des noms générés par Namify." },
					{ "DescAddName", "Entrez un nom personnalisé à ajouter à votre liste." },
					{ "DescAddNameButton", "Ajoute le nom ci-dessus à votre liste personnelle." },
					{ "DescOpenNamifyFile", "Ouvre le fichier de noms générés par l'API." },
					{ "DescOpenUserFile", "Ouvre votre fichier de noms personnels." },
					{ "DescGenerateNew", "Récupère de nouveaux noms de l'API. Vos noms sont préservés." },
					{ "DescReloadNames", "Recharge les noms du fichier (utile après modification manuelle)." },
					{ "DescApiKey", "La clé par défaut est partagée et limitée à 1000 requêtes/jour. Obtenez votre clé gratuite sur https://randommer.io/" }
				}
			},
			{
				"Arabic",
				new Dictionary<string, string>
				{
					{ "AddNameButton", "إضافة اسم" },
					{ "OpenNamifyList", "فتح قائمة Namify" },
					{ "OpenUserList", "فتح قائمتي" },
					{ "GenerateNewNames", "إنشاء أسماء جديدة" },
					{ "ReloadNamesFromFile", "إعادة التحميل من الملف" },
					{ "Yes", "نعم" },
					{ "No", "لا" },
					{ "ConfirmGenerateNew", "هل أنت متأكد من أنك تريد إنشاء أسماء جديدة؟" },
					{ "ConfirmReload", "هل أنت متأكد من أنك تريد إعادة تحميل الأسماء من الملف؟" },
					{ "NamesReloaded", "تم إعادة تحميل الأسماء من الملف!" },
					{ "ErrorReloading", "خطأ في إعادة التحميل. تحقق من السجل." },
					{ "NewNamesGenerated", "تم إنشاء أسماء جديدة!" },
					{ "ErrorGenerating", "خطأ في الإنشاء!" },
					{ "NameAdded", "تمت إضافة '{0}' إلى الأسماء المتاحة!" },
					{ "NameExists", "'{0}' موجود بالفعل!" },
					{ "NoNameEntered", "لم تقم بإدخال اسم؟" },
					{ "FileNotFound", "الملف غير موجود: {0}" },
					{ "ApiError", "خطأ في الاسترجاع! جار\u064d تجربة المصدر الاحتياطي..." },
					{ "ApiBackupError", "خطأ في الاسترجاع من المصدر الاحتياطي!" },
					{ "NamesRetrieved", "تم استرجاع الأسماء لـ Namify!" },
					{ "NamesRetrievedBackup", "تم استرجاع الأسماء من المصدر الاحتياطي!" },
					{ "DescAsteriskNames", "إظهار علامة النجمة بجانب الأسماء التي أنشأها Namify." },
					{ "DescAddName", "أدخل اسم\u064bا مخصص\u064bا لإضافته إلى قائمتك." },
					{ "DescAddNameButton", "يضيف الاسم أعلاه إلى قائمتك الشخصية." },
					{ "DescOpenNamifyFile", "يفتح ملف الأسماء الذي أنشأته واجهة برمجة التطبيقات." },
					{ "DescOpenUserFile", "يفتح ملف أسمائك الشخصية." },
					{ "DescGenerateNew", "يجلب أسماء جديدة من واجهة برمجة التطبيقات. يتم الحفاظ على أسمائك." },
					{ "DescReloadNames", "يعيد تحميل الأسماء من الملف (مفيد بعد التحرير اليدوي)." },
					{ "DescApiKey", "المفتاح الافتراضي مشترك ومحدود بـ 1000 طلب/يوم. احصل على مفتاحك المجاني من https://randommer.io/" }
				}
			}
		};

		internal static string AddNameButton => Get("AddNameButton");

		internal static string OpenNamifyList => Get("OpenNamifyList");

		internal static string OpenUserList => Get("OpenUserList");

		internal static string GenerateNewNames => Get("GenerateNewNames");

		internal static string ReloadNamesFromFile => Get("ReloadNamesFromFile");

		internal static string Yes => Get("Yes");

		internal static string No => Get("No");

		internal static string ConfirmGenerateNew => Get("ConfirmGenerateNew");

		internal static string ConfirmReload => Get("ConfirmReload");

		internal static string NamesReloaded => Get("NamesReloaded");

		internal static string ErrorReloading => Get("ErrorReloading");

		internal static string NewNamesGenerated => Get("NewNamesGenerated");

		internal static string ErrorGenerating => Get("ErrorGenerating");

		internal static string NameAdded => Get("NameAdded");

		internal static string NameExists => Get("NameExists");

		internal static string NoNameEntered => Get("NoNameEntered");

		internal static string FileNotFound => Get("FileNotFound");

		internal static string ApiError => Get("ApiError");

		internal static string ApiBackupError => Get("ApiBackupError");

		internal static string NamesRetrieved => Get("NamesRetrieved");

		internal static string NamesRetrievedBackup => Get("NamesRetrievedBackup");

		internal static string DescAsteriskNames => Get("DescAsteriskNames");

		internal static string DescAddName => Get("DescAddName");

		internal static string DescAddNameButton => Get("DescAddNameButton");

		internal static string DescOpenNamifyFile => Get("DescOpenNamifyFile");

		internal static string DescOpenUserFile => Get("DescOpenUserFile");

		internal static string DescGenerateNew => Get("DescGenerateNew");

		internal static string DescReloadNames => Get("DescReloadNames");

		internal static string DescApiKey => Get("DescApiKey");

		private static string Get(string key)
		{
			string key2 = LocalizationManager.CurrentLanguage ?? "English";
			if (Strings.TryGetValue(key2, out var value) && value.TryGetValue(key, out var value2))
			{
				return value2;
			}
			if (!Strings["English"].TryGetValue(key, out var value3))
			{
				return key;
			}
			return value3;
		}
	}
	[Harmony]
	public static class Patches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveAndLoad), "Save", new Type[] { })]
		private static void SaveAndLoad_Save()
		{
			if (DataManager.Instance.AllowSaving && !CheatConsole.IN_DEMO)
			{
				Data.SaveData();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SaveAndLoad), "Load")]
		private static void SaveAndLoad_Load(int saveSlot)
		{
			if (CheatConsole.IN_DEMO)
			{
				return;
			}
			Data.LoadData();
			foreach (FollowerInfo follower in DataManager.Instance.Followers)
			{
				if (follower.Name.Contains("*"))
				{
					follower.Name = follower.Name.Replace("*", string.Empty);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIFollowerIndoctrinationMenuController), "Show", new Type[]
		{
			typeof(Follower),
			typeof(OriginalFollowerLookData),
			typeof(bool)
		})]
		private static void UIFollowerIndoctrinationMenuController_Show(UIFollowerIndoctrinationMenuController __instance)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			UIFollowerIndoctrinationMenuController instance = __instance;
			if (Plugin.AsterixNames.Value)
			{
				string name = instance._targetFollower.Brain.Info.Name;
				if (Data.NamifyNames.Contains(name) || Data.UserNames.Contains(name))
				{
					((TMP_InputField)instance._nameInputField).text = ((TMP_InputField)instance._nameInputField).text + "*";
				}
			}
			((UnityEventBase)((Button)__instance._acceptButton).onClick).RemoveAllListeners();
			((UnityEvent)((Button)__instance._acceptButton).onClick).AddListener((UnityAction)delegate
			{
				string text = ((TMP_InputField)instance._nameInputField).text.Replace("*", string.Empty);
				((TMP_InputField)instance._nameInputField).text = text;
				instance._targetFollower.Brain.Info.Name = LocalizeIntegration.Arabic_ReverseNonRTL(((TMP_InputField)instance._nameInputField).text, false);
				if (!string.IsNullOrEmpty(instance.twitchFollowerViewerID))
				{
					DataManager.Instance.TwitchFollowerViewerIDs.Insert(0, instance.twitchFollowerViewerID);
					DataManager.Instance.TwitchFollowerIDs.Insert(0, instance.twitchFollowerID);
					instance.twitchFollowerViewerID = "";
					instance.twitchFollowerID = "";
				}
				Plugin.Log.LogInfo((object)("Follower name " + text + " confirmed! Removing name from saved name list."));
				Data.NamifyNames.Remove(text);
				Data.UserNames.Remove(text);
				instance.SwapOutfit();
				((UIMenuBase)instance).Hide(false);
			});
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UIFollowerIndoctrinationMenuController), "RandomiseName")]
		private static void UIFollowerIndoctrinationMenuController_RandomiseName(UIFollowerIndoctrinationMenuController __instance)
		{
			if (Plugin.AsterixNames.Value)
			{
				string text = ((TMP_InputField)__instance._nameInputField).text;
				if (Data.NamifyNames.Contains(text) || Data.UserNames.Contains(text))
				{
					((TMP_InputField)__instance._nameInputField).text = text + "*";
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FollowerInfo), "GenerateName")]
		public static void FollowerInfo_GenerateName(ref string __result)
		{
			if (GameManager.GetInstance() == null || DataManager.Instance == null)
			{
				return;
			}
			if (Data.NamifyNames.Count <= 0 && Data.UserNames.Count <= 0)
			{
				try
				{
					Data.LoadData();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Failed to load names during generation: " + ex.Message));
				}
			}
			if (Data.NamifyNames.Count <= 0 && Data.UserNames.Count <= 0)
			{
				Plugin.Log.LogInfo((object)"No names available yet, using game's default. Triggering background fetch...");
				Data.GetNamifyNames();
			}
			else
			{
				List<string> list = Data.NamifyNames.Concat(Data.UserNames).Distinct().ToList();
				__result = ListExtensions.RandomElement<string>(list);
			}
		}
	}
	[BepInPlugin("p1xel8ted.cotl.namify", "Namify", "0.2.3")]
	[BepInDependency("com.bepis.bepinex.configurationmanager", "18.4.1")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <PreloadNamesCoroutine>d__39 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 10)
				{
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				bool num = File.Exists(NamifyNamesFilePath);
				bool flag = File.Exists(Path.ChangeExtension(NamifyNamesFilePath, ".mp"));
				bool flag2 = File.Exists(UserNameFilePath);
				bool flag3 = File.Exists(Path.ChangeExtension(UserNameFilePath, ".mp"));
				if (num || flag || flag2 || flag3)
				{
					Log.LogInfo((object)"Loading existing names from file...");
					Data.LoadData();
				}
				if (Data.NamifyNames.Count == 0 && Data.UserNames.Count == 0)
				{
					Log.LogInfo((object)"No existing names found, fetching from API...");
					Data.GetNamifyNames(delegate
					{
						Log.LogInfo((object)"Failed to fetch names during initialization");
					}, delegate
					{
						Log.LogInfo((object)"Successfully pre-loaded names from API");
					});
				}
				else
				{
					Log.LogInfo((object)$"Pre-loaded {Data.NamifyNames.Count} Namify names and {Data.UserNames.Count} user names.");
				}
				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 PluginGuid = "p1xel8ted.cotl.namify";

		internal const string PluginName = "Namify";

		private const string PluginVer = "0.2.3";

		private const string NamesSection = "── Names ──";

		private const string ApiSection = "── API ──";

		public static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<string> PersonalApiKey { get; private set; }

		internal static ConfigEntry<string> AddName { get; private set; }

		internal static ConfigEntry<bool> AsterixNames { get; private set; }

		private static bool ShowGetNewConfirmationDialog { get; set; }

		private static bool ShowReloadConfirmationDialog { get; set; }

		private static string NamifyNamesFilePath => Data.NamifyNamesFilePath;

		private static string UserNameFilePath => Data.UserNamesFilePath;

		private static PopupManager PopupManagerInstance { get; set; }

		private void Awake()
		{
			InitializeLogger();
			InitializeConfigurations();
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.namify");
			Helpers.PrintModLoaded("Namify", ((BaseUnityPlugin)this).Logger);
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(PreloadNamesCoroutine());
		}

		[IteratorStateMachine(typeof(<PreloadNamesCoroutine>d__39))]
		private static IEnumerator PreloadNamesCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PreloadNamesCoroutine>d__39(0);
		}

		private void InitializeLogger()
		{
			Log = ((BaseUnityPlugin)this).Logger;
		}

		private void InitializeConfigurations()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected O, but got Unknown
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			PopupManagerInstance = ((Component)this).gameObject.AddComponent<PopupManager>();
			AsterixNames = ((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Asterisk Names", false, new ConfigDescription(Localization.DescAsteriskNames, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7
				}
			}));
			AddName = ((BaseUnityPlugin)this).Config.Bind<string>("── Names ──", "Add Name", "", new ConfigDescription(Localization.DescAddName, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 6
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Add Name Button", true, new ConfigDescription(Localization.DescAddNameButton, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5,
					DispName = "    └ Add Name",
					HideDefaultButton = true,
					CustomDrawer = AddNameButton
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Open Namify Names File", true, new ConfigDescription(Localization.DescOpenNamifyFile, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4,
					DispName = string.Empty,
					HideDefaultButton = true,
					CustomDrawer = OpenNamifyNamesFile
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Open User Names File", true, new ConfigDescription(Localization.DescOpenUserFile, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3,
					DispName = string.Empty,
					HideDefaultButton = true,
					CustomDrawer = OpenUserGeneratedNamesFile
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Generate New Names", true, new ConfigDescription(Localization.DescGenerateNew, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2,
					DispName = string.Empty,
					HideDefaultButton = true,
					CustomDrawer = GenerateNewNamesButton
				}
			}));
			((BaseUnityPlugin)this).Config.Bind<bool>("── Names ──", "Reload Names", true, new ConfigDescription(Localization.DescReloadNames, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1,
					DispName = string.Empty,
					HideDefaultButton = true,
					CustomDrawer = ReloadNames
				}
			}));
			PersonalApiKey = ((BaseUnityPlugin)this).Config.Bind<string>("── API ──", "Personal API Key", "ee5f806e1c1d458b99c934c0eb3de5b8", new ConfigDescription(Localization.DescApiKey, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1
				}
			}));
		}

		private static void OpenNamifyNamesFile(ConfigEntryBase entry)
		{
			if (GUILayout.Button(Localization.OpenNamifyList, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				TryOpenNamifyNamesFile();
			}
		}

		private static void OpenUserGeneratedNamesFile(ConfigEntryBase entry)
		{
			if (GUILayout.Button(Localization.OpenUserList, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				TryOpenUserNamesFile();
			}
		}

		private static void TryOpenNamifyNamesFile()
		{
			if (File.Exists(NamifyNamesFilePath))
			{
				Application.OpenURL(NamifyNamesFilePath);
			}
			else
			{
				PopupManagerInstance.ShowPopup(string.Format(Localization.FileNotFound, NamifyNamesFilePath));
			}
		}

		private static void TryOpenUserNamesFile()
		{
			if (File.Exists(UserNameFilePath))
			{
				Application.OpenURL(UserNameFilePath);
			}
			else
			{
				PopupManagerInstance.ShowPopup(string.Format(Localization.FileNotFound, UserNameFilePath));
			}
		}

		private static void DisplayGetNewConfirmationDialog()
		{
			GUILayout.Label(Localization.ConfirmGenerateNew, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(Localization.Yes, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				GenerateNewNamesAction();
				ShowGetNewConfirmationDialog = false;
			}
			if (GUILayout.Button(Localization.No, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ShowGetNewConfirmationDialog = false;
			}
			GUILayout.EndHorizontal();
		}

		private static void DisplayReloadConfirmationDialog()
		{
			GUILayout.Label(Localization.ConfirmReload, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(Localization.Yes, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				try
				{
					Data.LoadData();
					PopupManagerInstance.ShowPopup(Localization.NamesReloaded);
				}
				catch (Exception ex)
				{
					PopupManagerInstance.ShowPopup(Localization.ErrorReloading);
					Log.LogError((object)("Error in reloading names: " + ex.Message));
				}
				ShowReloadConfirmationDialog = false;
			}
			if (GUILayout.Button(Localization.No, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ShowReloadConfirmationDialog = false;
			}
			GUILayout.EndHorizontal();
		}

		private static void GenerateNewNamesAction()
		{
			try
			{
				File.Delete(NamifyNamesFilePath);
				Data.NamifyNames.Clear();
				Data.GetNamifyNames(delegate
				{
					PopupManagerInstance.ShowPopup(Localization.ErrorGenerating);
				}, delegate
				{
					PopupManagerInstance.ShowPopup(Localization.NewNamesGenerated);
				});
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Error in generating new names: " + ex.Message));
			}
		}

		private static void AddNameButton(ConfigEntryBase entry)
		{
			if (GUILayout.Button(Localization.AddNameButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				if (string.IsNullOrWhiteSpace(AddName.Value))
				{
					PopupManagerInstance.ShowPopup(Localization.NoNameEntered);
					return;
				}
				if (!Data.UserNames.Add(AddName.Value))
				{
					PopupManagerInstance.ShowPopup(string.Format(Localization.NameExists, AddName.Value));
					return;
				}
				Data.SaveData();
				PopupManagerInstance.ShowPopup(string.Format(Localization.NameAdded, AddName.Value));
			}
		}

		private static void ReloadNames(ConfigEntryBase entry)
		{
			if (ShowReloadConfirmationDialog)
			{
				DisplayReloadConfirmationDialog();
			}
			else if (GUILayout.Button(Localization.ReloadNamesFromFile, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ShowReloadConfirmationDialog = true;
			}
		}

		private static void GenerateNewNamesButton(ConfigEntryBase entry)
		{
			if (ShowGetNewConfirmationDialog)
			{
				DisplayGetNewConfirmationDialog();
			}
			else if (GUILayout.Button(Localization.GenerateNewNames, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ShowGetNewConfirmationDialog = true;
			}
		}
	}
	internal class PopupManager : MonoBehaviour
	{
		private bool showPopup;

		private string popupMessage = "";

		private Rect popupRect = new Rect((float)Screen.width / 2f - 150f, (float)Screen.height / 2f - 75f, 300f, 100f);

		private GUIStyle messageStyle;

		private void Start()
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GUIStyle val = new GUIStyle
			{
				alignment = (TextAnchor)4,
				wordWrap = true,
				fontSize = 20
			};
			val.normal.textColor = Color.white;
			messageStyle = val;
		}

		private void OnGUI()
		{
			//IL_000b: 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_002b: Expected O, but got Unknown
			//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)
			if (showPopup)
			{
				popupRect = GUILayout.Window(0, popupRect, new WindowFunction(DrawPopup), "Namify", Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawPopup(int windowID)
		{
			GUILayout.FlexibleSpace();
			GUILayout.Label(popupMessage, messageStyle, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(100f) }))
			{
				Plugin.AddName.Value = string.Empty;
				showPopup = false;
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.FlexibleSpace();
		}

		public void ShowPopup(string message)
		{
			popupMessage = message;
			showPopup = true;
		}
	}
}
namespace Shared
{
	public static class Helpers
	{
		private static class StorefrontDetector
		{
			private static readonly string[] PiracyFiles = new string[65]
			{
				"SmartSteamEmu.ini", "codex.ini", "steam_emu.ini", "goldberg_emulator.dll", "steamclient_loader.dll", "steam_api64_o.dll", "steam_api.cdx", "steam_api64.cdx.dll", "steam_interfaces.txt", "local_save.txt",
				"valve.ini", "codex64.dll", "coldclient.dll", "ColdClientLoader.ini", "steamless.dll", "GreenLuma", "CreamAPI.dll", "cream_api.ini", "ScreamAPI.dll", "OnlineFix.dll",
				"OnlineFix.url", "online-fix.me", "CODEX", "SKIDROW", "CPY", "PLAZA", "HOODLUM", "EMPRESS", "TENOKE", "PROPHET",
				"REVOLT", "DARKSiDERS", "RAZOR1911", "FLT", "FLT.dll", "RUNE", "RUNE.ini", "TiNYiSO", "RELOADED", "RLD!",
				"DOGE", "BAT", "P2P", "ElAmigos", "FitGirl", "DODI", "xatab", "KaOs", "IGG", "Masquerade",
				"3dmgame.dll", "ALI213.dll", "crack", "crack.exe", "Crack.nfo", "crackfix", "CrackOnly", "fix.exe", "gamefix.dll", "SKIDROW.ini",
				"nosTEAM", "NoSteam", "FCKDRM", "Goldberg", "VALVEEMPRESS"
			};

			public static string DetectStorefront()
			{
				string dir = Directory.GetCurrentDirectory();
				string text = "Unknown";
				if (File.Exists(Path.Combine(dir, "steam_api.dll")) || File.Exists(Path.Combine(dir, "steam_api64.dll")) || File.Exists(Path.Combine(dir, "steam_appid.txt")) || Directory.Exists(Path.Combine(dir, "steam_settings")))
				{
					text = "Steam";
				}
				else if (Directory.GetFiles(dir, "goggame-*.info").Any() || File.Exists(Path.Combine(dir, "galaxy.dll")))
				{
					text = "GOG";
				}
				else if (File.Exists(Path.Combine(dir, "EOSSDK-Win64-Shipping.dll")) || File.Exists(Path.Combine(dir, "EpicOnlineServices.dll")) || Directory.Exists(Path.Combine(dir, ".egstore")))
				{
					text = "Epic";
				}
				else if (IsProcessRunning("steam"))
				{
					text = "Steam (process only)";
				}
				else if (IsProcessRunning("GalaxyClient"))
				{
					text = "GOG (process only)";
				}
				else if (IsProcessRunning("EpicGamesLauncher"))
				{
					text = "Epic (process only)";
				}
				if (PiracyFiles.Any((string pirate) => File.Exists(Path.Combine(dir, pirate)) || Directory.Exists(Path.Combine(dir, pirate))))
				{
					text += " + Possible Pirated/Cracked Files Found!";
				}
				return text;
			}

			private static bool IsProcessRunning(string name)
			{
				return Process.GetProcessesByName(name).Length != 0;
			}
		}

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

			private object <>2__current;

			public IEnumerator original;

			public Type[] typesToRemove;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				while (original.MoveNext())
				{
					object current = original.Current;
					if (current != null && !ArrayExtensions.Contains<Type>(typesToRemove, current.GetType()))
					{
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
				}
				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();
			}
		}

		internal static List<Follower> AllFollowers => FollowerManager.Followers.SelectMany((KeyValuePair<FollowerLocation, List<Follower>> followerList) => followerList.Value).ToList();

		private static bool ContainsIgnoreCase(this string source, string value)
		{
			if (source == null)
			{
				return false;
			}
			return source.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
		}

		public static void PrintModLoaded(string plugin, ManualLogSource logger)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			string text = Application.version.Replace("\r", "").Replace("\n", "");
			string buildGUID = Application.buildGUID;
			Platform current = PlatformHelper.Current;
			string text2 = StorefrontDetector.DetectStorefront();
			logger.LogInfo((object)"==========================================");
			logger.LogInfo((object)("  Plugin Loaded: " + plugin));
			logger.LogInfo((object)("  Version   : " + text + " (BuildGUID: " + buildGUID + ")"));
			logger.LogInfo((object)$"  Platform  : {current}");
			logger.LogInfo((object)("  Storefront: " + text2));
			logger.LogInfo((object)"==========================================");
		}

		public static bool IsMultiplierActive(float value)
		{
			return !Mathf.Approximately(value, 1f);
		}

		[IteratorStateMachine(typeof(<FilterEnumerator>d__6))]
		public static IEnumerator FilterEnumerator(IEnumerator original, Type[] typesToRemove)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FilterEnumerator>d__6(0)
			{
				original = original,
				typesToRemove = typesToRemove
			};
		}

		public static void LogCallStack(ManualLogSource logger, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
				logger.LogWarning((object)string.Format(arg1: (methodBase?.DeclaringType)?.FullName, format: "[Frame {0}] {1}.{2}", arg0: i, arg2: methodBase?.Name));
			}
		}

		public static Type GetCallingType(ICollection<Type> targetTypes, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				Type type = stackTrace.GetFrame(i)?.GetMethod()?.DeclaringType;
				if (type != null && targetTypes.Contains(type))
				{
					return type;
				}
			}
			return null;
		}

		public static bool IsCalledFrom(string typeNameContains, string methodNameContains = null, int skipFrames = 3, int maxFrames = 10)
		{
			StackTrace stackTrace = new StackTrace(fNeedFileInfo: false);
			int frameCount = stackTrace.FrameCount;
			for (int i = skipFrames; i < frameCount && i < maxFrames; i++)
			{
				MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod();
				Type type = methodBase?.DeclaringType;
				if (!(type == null))
				{
					bool num = type.FullName.ContainsIgnoreCase(typeNameContains);
					bool flag = methodNameContains == null || methodBase.Name.ContainsIgnoreCase(methodNameContains);
					if (num && flag)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	public static class Extensions
	{
		[SpecialName]
		public sealed class <G>$C3955E4562CB1DA95F117E77C88727F9
		{
			[SpecialName]
			public static class <M>$A7FEE9A02FBDD7AF3540A93B5A9996F2
			{
			}

			[ExtensionMarker("<M>$A7FEE9A02FBDD7AF3540A93B5A9996F2")]
			public bool IsMealWithMeat()
			{
				throw null;
			}

			[ExtensionMarker("<M>$A7FEE9A02FBDD7AF3540A93B5A9996F2")]
			public bool IsMixedMeal()
			{
				throw null;
			}
		}

		public static bool TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
		{
			if (dictionary.ContainsKey(key))
			{
				return false;
			}
			dictionary.Add(key, value);
			return true;
		}

		public static bool IsMealWithMeat(this ITEM_TYPE itemType)
		{
			string[] source = new string[3] { "meat", "fish", "mixed" };
			string itemName = ((object)(ITEM_TYPE)(ref itemType)).ToString().ToLower();
			return source.Any((string check) => itemName.Contains(check));
		}

		public static bool IsMixedMeal(this ITEM_TYPE itemType)
		{
			string[] source = new string[1] { "mixed" };
			string itemName = ((object)(ITEM_TYPE)(ref itemType)).ToString().ToLower();
			return source.Any((string check) => itemName.Contains(check));
		}

		public static void AddRange<T>(this SortedSet<T> set, IEnumerable<T> elements)
		{
			foreach (T element in elements)
			{
				set.Add(element);
			}
		}

		public static bool TryReplace(this string source, string oldValue, string newValue, out string result)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (oldValue == null)
			{
				throw new ArgumentNullException("oldValue");
			}
			result = source.Replace(oldValue, newValue);
			return (object)source != result;
		}

		public static string GetPath(this GameObject obj)
		{
			if (!((Object)(object)obj.transform.parent == (Object)null))
			{
				return ((Component)obj.transform.parent).gameObject.GetPath() + "/" + ((Object)obj).name;
			}
			return ((Object)obj).name;
		}

		public static bool Contains(this string source, string toCheck, StringComparison comparison)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			if (toCheck == null)
			{
				throw new ArgumentNullException("toCheck");
			}
			return source.IndexOf(toCheck, comparison) >= 0;
		}
	}
}