Decompiled source of LC Room attribution prediction experiment v1.5.1

BepInEx/plugins/LethalCompanyRegionTag.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalCompanyRegionTag.Analysis;
using LethalCompanyRegionTag.Cache;
using LethalCompanyRegionTag.Config;
using LethalCompanyRegionTag.Patches;
using LethalCompanyRegionTag.UI;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TAIGU")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Lethal Company lobby region identification mod - identifies lobby host country/region")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+f47741a05e197a1cbbf41590b7ae832aee769277")]
[assembly: AssemblyProduct("TAIGU-Room recognition experiment")]
[assembly: AssemblyTitle("LethalCompanyRegionTag")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalCompanyRegionTag
{
	[BepInPlugin("TAIGU.RoomRecognition", "TAIGU-Room recognition experiment", "1.5.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "TAIGU.RoomRecognition";

		public const string PluginName = "TAIGU-Room recognition experiment";

		public const string PluginVersion = "1.5.1";

		public static Plugin Instance { get; private set; }

		internal static ManualLogSource LogSource => ((BaseUnityPlugin)Instance).Logger;

		internal static Harmony HarmonyInstance { get; private set; }

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Instance = this;
			PluginConfig.Init(((BaseUnityPlugin)this).Config);
			HarmonyInstance = new Harmony("TAIGU.RoomRecognition");
			try
			{
				HarmonyInstance.PatchAll(typeof(SteamLobbyManagerPatch));
				LogSource.LogInfo((object)"[TAIGU] Successfully patched: SteamLobbyManagerPatch");
			}
			catch (Exception ex)
			{
				LogSource.LogError((object)("[TAIGU] Failed to apply SteamLobbyManager patches: " + ex.Message));
			}
			try
			{
				HarmonyInstance.PatchAll(typeof(LobbySlotPatch));
				LogSource.LogInfo((object)"[TAIGU] Successfully patched: LobbySlotPatch");
			}
			catch (Exception ex2)
			{
				LogSource.LogError((object)("[TAIGU] Failed to apply LobbySlot patches: " + ex2.Message));
			}
			FontManager.Initialize();
			LogSource.LogInfo((object)"[TAIGU] TAIGU-Room recognition experiment v1.5.1 loaded!");
			LogSource.LogInfo((object)$"[TAIGU] Region detection enabled: Nickname={PluginConfig.EnableNicknameAnalysis.Value}, SteamAPI={!string.IsNullOrEmpty(PluginConfig.SteamWebApiKey.Value)}");
			LogSource.LogInfo((object)$"[TAIGU] CJK font available: {FontManager.CjkFontAvailable}");
			LogSource.LogInfo((object)$"[TAIGU] Community query: {PluginConfig.EnableCommunityQuery.Value}, XML query: {PluginConfig.EnableXmlQuery.Value}");
			if (string.IsNullOrEmpty(PluginConfig.SteamWebApiKey.Value))
			{
				LogSource.LogWarning((object)"[TAIGU] No Steam Web API key configured. Region detection will rely on nickname analysis + community page queries.");
				LogSource.LogWarning((object)"[TAIGU] For best results, get a free API key from: https://steamcommunity.com/dev/apikey");
			}
		}
	}
}
namespace LethalCompanyRegionTag.UI
{
	public static class FontManager
	{
		private static bool _initialized = false;

		private static bool _cjkFontAvailable = false;

		private static TMP_FontAsset _cjkFontAsset = null;

		private static readonly List<TMP_FontAsset> _loadedFonts = new List<TMP_FontAsset>();

		private static readonly string[] KnownCjkFontFiles = new string[15]
		{
			"arialuni_sdf_u2019", "Sinter-Normal", "sinter-normal", "NotoSansSC", "NotoSansCJK", "SourceHanSans", "WenQuanYi", "MicrosoftYaHei", "msyh", "simhei",
			"simsun", "arialunicode", "arialuni", "droidsansfallback", "cjk"
		};

		private static readonly string[] FontExtensions = new string[4] { ".assets", ".unity3d", ".bundle", ".fontsettings" };

		private static readonly string[] TtfExtensions = new string[2] { ".ttf", ".otf" };

		public static bool CjkFontAvailable => _cjkFontAvailable;

		public static TMP_FontAsset CjkFontAsset => _cjkFontAsset;

		public static void Initialize()
		{
			if (!_initialized)
			{
				_initialized = true;
				Plugin.LogSource.LogInfo((object)"[TAIGU] FontManager: Scanning for CJK fonts...");
				TryLoadTtfFromPluginDirectory();
				if (!_cjkFontAvailable)
				{
					TryFindLoadedCjkFonts();
				}
				if (!_cjkFontAvailable)
				{
					TryLoadFontsFromDirectory(Application.dataPath);
				}
				if (!_cjkFontAvailable)
				{
					TryLoadFontsFromDirectory(Path.Combine(Path.GetDirectoryName(Application.dataPath), "BepInEx"));
				}
				if (!_cjkFontAvailable)
				{
					TryLoadFontsFromDirectory(Path.GetDirectoryName(Application.dataPath));
				}
				if (!_cjkFontAvailable)
				{
					TryLoadFromResources();
				}
				if (_cjkFontAvailable)
				{
					Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: CJK font loaded successfully - '" + ((Object)_cjkFontAsset).name + "'"));
					TryAddFallbackToGameFont();
				}
				else
				{
					Plugin.LogSource.LogWarning((object)"[TAIGU] FontManager: No CJK font found. Chinese characters will display as ASCII codes.");
					Plugin.LogSource.LogWarning((object)"[TAIGU] FontManager: Install a Chinese localization mod or place a CJK font file (TTF/OTF) in BepInEx/plugins/LethalCompanyRegionTag/ directory.");
				}
			}
		}

		private static void TryLoadTtfFromPluginDirectory()
		{
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Application.dataPath), "BepInEx", "plugins", "LethalCompanyRegionTag");
				if (!Directory.Exists(text))
				{
					Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Plugin directory not found: " + text));
					return;
				}
				Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Scanning plugin directory for TTF fonts: " + text));
				string[] ttfExtensions = TtfExtensions;
				foreach (string text2 in ttfExtensions)
				{
					string[] files = Directory.GetFiles(text, "*" + text2, SearchOption.TopDirectoryOnly);
					foreach (string text3 in files)
					{
						if (TryLoadTtfFont(text3))
						{
							Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Successfully loaded TTF font from: " + text3));
							return;
						}
					}
				}
				ttfExtensions = KnownCjkFontFiles;
				foreach (string text4 in ttfExtensions)
				{
					string[] files = TtfExtensions;
					foreach (string text5 in files)
					{
						string text6 = Path.Combine(text, text4 + text5);
						if (File.Exists(text6) && TryLoadTtfFont(text6))
						{
							Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Successfully loaded known CJK font: " + text6));
							return;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Error loading TTF from plugin directory: " + ex.Message));
			}
		}

		private static bool TryLoadTtfFont(string filePath)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			try
			{
				if (!File.Exists(filePath))
				{
					return false;
				}
				Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Attempting to load TTF font: " + filePath));
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
				Font val = null;
				try
				{
					val = new Font(filePath);
					if ((Object)(object)val != (Object)null && ((Object)val).name != null)
					{
						Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Loaded font via direct path: " + ((Object)val).name));
					}
					else
					{
						val = null;
					}
				}
				catch
				{
					val = null;
				}
				if ((Object)(object)val == (Object)null)
				{
					try
					{
						val = Font.CreateDynamicFontFromOSFont(fileNameWithoutExtension, 16);
						if ((Object)(object)val != (Object)null)
						{
							Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Loaded font via OS font name: " + fileNameWithoutExtension));
						}
					}
					catch
					{
						val = null;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					string[] array = new string[18]
					{
						"Microsoft YaHei",
						"Microsoft YaHei UI",
						"SimHei",
						"SimSun",
						"NSimSun",
						"KaiTi",
						"Noto Sans SC",
						"Noto Sans CJK SC",
						"Noto Sans",
						"Source Han Sans SC",
						"Source Han Sans CN",
						"WenQuanYi Micro Hei",
						"WenQuanYi Zen Hei",
						"PingFang SC",
						"Hiragino Sans GB",
						fileNameWithoutExtension,
						fileNameWithoutExtension.Replace("_", " "),
						fileNameWithoutExtension.Replace("-", " ")
					};
					foreach (string text in array)
					{
						if (string.IsNullOrEmpty(text))
						{
							continue;
						}
						try
						{
							val = Font.CreateDynamicFontFromOSFont(text, 16);
							if ((Object)(object)val != (Object)null)
							{
								Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Loaded font via known name: " + text));
								break;
							}
						}
						catch
						{
							val = null;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Could not load font from: " + filePath));
					return false;
				}
				TMP_FontAsset val2 = TMP_FontAsset.CreateFontAsset(val);
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Failed to create TMP FontAsset from: " + filePath));
					return false;
				}
				((Object)val2).name = fileNameWithoutExtension;
				_loadedFonts.Add(val2);
				SetCjkFont(val2);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Failed to load TTF font from " + filePath + ": " + ex.Message));
				return false;
			}
		}

		private static void TryFindLoadedCjkFonts()
		{
			try
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				foreach (TMP_FontAsset val in array)
				{
					if (!((Object)(object)val == (Object)null) && ((Object)val).name != null && HasCjkSupport(val))
					{
						SetCjkFont(val);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Error scanning loaded fonts: " + ex.Message));
			}
		}

		private static void TryLoadFontsFromDirectory(string directory)
		{
			if (!Directory.Exists(directory))
			{
				return;
			}
			try
			{
				string[] knownCjkFontFiles = KnownCjkFontFiles;
				foreach (string text in knownCjkFontFiles)
				{
					string[] fontExtensions = FontExtensions;
					foreach (string text2 in fontExtensions)
					{
						string searchPattern = "*" + text + "*" + text2;
						string[] files = Directory.GetFiles(directory, searchPattern, SearchOption.AllDirectories);
						for (int k = 0; k < files.Length; k++)
						{
							if (TryLoadFontFromFile(files[k]))
							{
								return;
							}
						}
					}
				}
				knownCjkFontFiles = TtfExtensions;
				foreach (string text3 in knownCjkFontFiles)
				{
					string[] fontExtensions = Directory.GetFiles(directory, "*" + text3, SearchOption.AllDirectories);
					for (int j = 0; j < fontExtensions.Length; j++)
					{
						if (TryLoadTtfFont(fontExtensions[j]))
						{
							return;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Error scanning directory " + directory + ": " + ex.Message));
			}
		}

		private static bool TryLoadFontFromFile(string filePath)
		{
			try
			{
				if (!File.Exists(filePath))
				{
					return false;
				}
				AssetBundleCreateRequest val = AssetBundle.LoadFromFileAsync(filePath);
				while (!((AsyncOperation)val).isDone)
				{
					Thread.Sleep(10);
				}
				AssetBundle assetBundle = val.assetBundle;
				if ((Object)(object)assetBundle == (Object)null)
				{
					return false;
				}
				TMP_FontAsset[] array = assetBundle.LoadAllAssets<TMP_FontAsset>();
				if (array != null && array.Length != 0)
				{
					TMP_FontAsset[] array2 = array;
					foreach (TMP_FontAsset val2 in array2)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							_loadedFonts.Add(val2);
							if (HasCjkSupport(val2))
							{
								SetCjkFont(val2);
								Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Loaded CJK font from: " + filePath));
								return true;
							}
						}
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Failed to load font from " + filePath + ": " + ex.Message));
				return false;
			}
		}

		private static void TryLoadFromResources()
		{
			try
			{
				string[] array = new string[6] { "Fonts/arialuni_sdf_u2019", "Fonts/Sinter-Normal", "Fonts/NotoSansSC", "Fonts/cjk", "arialuni_sdf_u2019", "Sinter-Normal" };
				foreach (string text in array)
				{
					TMP_FontAsset val = Resources.Load<TMP_FontAsset>(text);
					if ((Object)(object)val != (Object)null && HasCjkSupport(val))
					{
						SetCjkFont(val);
						Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Loaded CJK font from Resources: " + text));
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Error loading from Resources: " + ex.Message));
			}
		}

		private static bool HasCjkSupport(TMP_FontAsset font)
		{
			if ((Object)(object)font == (Object)null || font.characterLookupTable == null)
			{
				return false;
			}
			char[] obj = new char[5] { '中', '国', 'あ', 'ア', '가' };
			int num = 0;
			char[] array = obj;
			foreach (char key in array)
			{
				if (font.characterLookupTable.ContainsKey(key))
				{
					num++;
				}
			}
			return num >= 2;
		}

		private static void SetCjkFont(TMP_FontAsset font)
		{
			_cjkFontAsset = font;
			_cjkFontAvailable = true;
		}

		private static void TryAddFallbackToGameFont()
		{
			if (!_cjkFontAvailable || (Object)(object)_cjkFontAsset == (Object)null)
			{
				return;
			}
			try
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				foreach (TMP_FontAsset val in array)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name != null && ((Object)val).name.Contains("3270"))
					{
						List<TMP_FontAsset> list = new List<TMP_FontAsset>(val.fallbackFontAssetTable ?? new List<TMP_FontAsset>());
						if (!list.Contains(_cjkFontAsset))
						{
							list.Add(_cjkFontAsset);
							val.fallbackFontAssetTable = list;
							Plugin.LogSource.LogInfo((object)("[TAIGU] FontManager: Added CJK font as fallback to game font '" + ((Object)val).name + "'"));
						}
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] FontManager: Error adding fallback font: " + ex.Message));
			}
		}

		public static string GetDisplayLabel(string regionCode)
		{
			if (string.IsNullOrEmpty(regionCode))
			{
				return regionCode;
			}
			if (!_cjkFontAvailable)
			{
				return regionCode;
			}
			switch (regionCode.ToUpper())
			{
			case "CN":
				return "中国";
			case "TW":
				return "台湾";
			case "HK":
				return "香港";
			case "JP":
				return "日本";
			case "KR":
				return "韩国";
			case "RU":
				return "俄罗斯";
			case "VN":
				return "越南";
			case "TH":
				return "泰国";
			case "ID":
				return "印尼";
			case "IE":
				return "爱尔兰";
			case "MY":
				return "马来";
			case "PH":
				return "菲律宾";
			case "KH":
				return "柬埔寨";
			case "LA":
				return "老挝";
			case "MM":
				return "缅甸";
			case "MN":
				return "蒙古";
			case "PL":
				return "波兰";
			case "CZ":
				return "捷克";
			case "SK":
				return "斯洛伐克";
			case "HU":
				return "匈牙利";
			case "RO":
				return "罗马尼亚";
			case "BG":
				return "保加利亚";
			case "UA":
				return "乌克兰";
			case "TR":
				return "土耳其";
			case "SA":
				return "沙特";
			case "IR":
				return "伊朗";
			case "AE":
				return "阿联酋";
			case "EG":
				return "埃及";
			case "MA":
				return "摩洛哥";
			case "DZ":
				return "阿尔及利亚";
			case "NG":
				return "尼日利亚";
			case "ET":
				return "埃塞俄比亚";
			case "ZA":
				return "南非";
			case "US":
				return "美国";
			case "CA":
				return "加拿大";
			case "MX":
				return "墨西哥";
			case "BR":
				return "巴西";
			case "AR":
				return "阿根廷";
			case "CL":
				return "智利";
			case "CO":
				return "哥伦比亚";
			case "PE":
				return "秘鲁";
			case "DE":
				return "德国";
			case "FR":
				return "法国";
			case "ES":
				return "西班牙";
			case "IT":
				return "意大利";
			case "PT":
				return "葡萄牙";
			case "NL":
				return "荷兰";
			case "SE":
				return "瑞典";
			case "NO":
				return "挪威";
			case "DK":
				return "丹麦";
			case "FI":
				return "芬兰";
			case "GB":
				return "英国";
			case "AU":
				return "澳大利亚";
			case "NZ":
				return "新西兰";
			case "IN":
				return "印度";
			case "PK":
				return "巴基斯坦";
			case "BD":
				return "孟加拉";
			case "KZ":
				return "哈萨克斯坦";
			case "UZ":
				return "乌兹别克斯坦";
			case "WEST":
				return "欧美";
			case "EE":
			case "EAST_EU":
				return "东欧";
			case "NORD":
			case "NORDIC":
				return "北欧";
			case "SEA":
				return "东南亚";
			case "LATAM":
				return "拉美";
			case "ME":
			case "MENA":
				return "中东";
			case "SAS":
			case "SAARC":
				return "南亚";
			case "CAS":
			case "CENTRAL_ASIA":
				return "中亚";
			case "NA":
			case "NAF":
				return "北非";
			case "NAM":
				return "北美";
			case "SSA":
				return "撒哈拉以南非洲";
			case "OC":
			case "OCEANIA":
				return "大洋洲";
			case "BLT":
				return "波罗的海";
			case "BALK":
				return "巴尔干";
			case "IB":
				return "伊比利亚";
			case "AFRICA":
				return "非洲";
			case "OTHER":
			case "Other":
				return "其他";
			case "AM":
				return "亚美尼亚";
			case "BY":
				return "白俄罗斯";
			case "CH":
				return "瑞士";
			case "ER":
				return "厄立特里亚";
			case "GE":
				return "格鲁吉亚";
			case "GR":
				return "希腊";
			case "LK":
				return "斯里兰卡";
			case "MD":
				return "摩尔多瓦";
			case "NP":
				return "尼泊尔";
			case "RS":
				return "塞尔维亚";
			case "??":
				return "未知";
			default:
				if (!CjkFontAvailable)
				{
					return regionCode;
				}
				try
				{
					Dictionary<string, string> regionCodeToChinese = LobbySlotPatch.RegionCodeToChinese;
					if (regionCodeToChinese != null && regionCodeToChinese.TryGetValue(regionCode, out var value))
					{
						return value;
					}
				}
				catch
				{
				}
				return regionCode;
			}
		}
	}
	public class RegionTagManager : MonoBehaviour
	{
		private readonly HashSet<ulong> _taggedLobbyIds = new HashSet<ulong>();

		private readonly Dictionary<ulong, RegionResult> _resultCache = new Dictionary<ulong, RegionResult>();

		private readonly HashSet<ulong> _pendingAnalysis = new HashSet<ulong>();

		private Lobby[] _currentLobbyList;

		private float _lastCheckTime;

		private const float CHECK_INTERVAL = 0.5f;

		public static RegionTagManager Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Plugin.LogSource.LogInfo((object)"[TAIGU] RegionTagManager initialized");
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public void OnLobbyListReceived(Lobby[] lobbyList)
		{
			_currentLobbyList = lobbyList;
			Plugin.LogSource.LogInfo((object)$"[TAIGU] Lobby list updated with {((lobbyList != null) ? lobbyList.Length : 0)} entries");
		}

		public void ClearTaggedSlots()
		{
			_taggedLobbyIds.Clear();
			_pendingAnalysis.Clear();
			Plugin.LogSource.LogInfo((object)"[TAIGU] Cleared tagged slots tracking");
		}

		private void Update()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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)
			if (Time.time - _lastCheckTime < 0.5f)
			{
				return;
			}
			_lastCheckTime = Time.time;
			try
			{
				LobbySlot[] array = Object.FindObjectsOfType<LobbySlot>();
				if (array == null || array.Length == 0)
				{
					return;
				}
				LobbySlot[] array2 = array;
				foreach (LobbySlot val in array2)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					ulong value = val.lobbyId.Value;
					if (!_taggedLobbyIds.Contains(value))
					{
						Lobby thisLobby = val.thisLobby;
						if (((Lobby)(ref thisLobby)).Id.Value != 0L && !_pendingAnalysis.Contains(value))
						{
							_pendingAnalysis.Add(value);
							((MonoBehaviour)this).StartCoroutine(AnalyzeAndTagLobby(val, thisLobby));
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error in RegionTagManager.Update: " + ex.Message));
			}
		}

		private IEnumerator AnalyzeAndTagLobby(LobbySlot slot, Lobby lobby)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ulong lobbyIdValue = ((Lobby)(ref lobby)).Id.Value;
			if (_resultCache.TryGetValue(lobbyIdValue, out var value))
			{
				ApplyTagToSlot(slot, value);
				_taggedLobbyIds.Add(lobbyIdValue);
				_pendingAnalysis.Remove(lobbyIdValue);
				yield break;
			}
			Friend owner = ((Lobby)(ref lobby)).Owner;
			string ownerName = ((Friend)(ref owner)).Name ?? "Unknown";
			ulong value2 = owner.Id.Value;
			Plugin.LogSource.LogInfo((object)$"[TAIGU] Analyzing lobby {lobbyIdValue}, owner: {ownerName} (SteamID: {value2})");
			Task<RegionResult> analysisTask = RegionAnalyzer.AnalyzeRegion(ownerName, value2);
			float timeout = 5f;
			float elapsed = 0f;
			while (!analysisTask.IsCompleted && elapsed < timeout)
			{
				yield return null;
				elapsed += Time.deltaTime;
			}
			RegionResult regionResult;
			if (analysisTask.IsCompleted)
			{
				regionResult = analysisTask.Result;
			}
			else
			{
				regionResult = RegionAnalyzer.GetQuickAnalysis(ownerName);
				Plugin.LogSource.LogWarning((object)$"[TAIGU] Analysis timeout for lobby {lobbyIdValue}, using quick analysis");
			}
			_resultCache[lobbyIdValue] = regionResult;
			ApplyTagToSlot(slot, regionResult);
			_taggedLobbyIds.Add(lobbyIdValue);
			_pendingAnalysis.Remove(lobbyIdValue);
		}

		private void ApplyTagToSlot(LobbySlot slot, RegionResult result)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)slot == (Object)null || (Object)(object)slot.LobbyName == (Object)null)
			{
				return;
			}
			try
			{
				string text = ((TMP_Text)slot.LobbyName).text ?? "";
				text = RemoveExistingTag(text);
				if (result == null || result.PrimaryRegion == "Unknown" || result.Confidence < 20f)
				{
					if (PluginConfig.ShowLowConfidenceTags.Value)
					{
						string text2 = FormatTag("??", 0f);
						((TMP_Text)slot.LobbyName).text = text2 + " " + text;
					}
					return;
				}
				string regionCode = GetRegionCode(result.PrimaryRegion);
				float confidence = result.Confidence;
				if (confidence >= PluginConfig.MinConfidenceThreshold.Value)
				{
					string text3 = FormatTag(regionCode, confidence);
					((TMP_Text)slot.LobbyName).text = text3 + " " + text;
					Color confidenceColor = GetConfidenceColor(confidence);
					((Graphic)slot.LobbyName).color = confidenceColor;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error applying tag to slot: " + ex.Message));
			}
		}

		private string FormatTag(string regionCode, float confidence)
		{
			if (PluginConfig.ShowProbability.Value && confidence > 0f)
			{
				return $"[{regionCode} {confidence:F0}%]";
			}
			return "[" + regionCode + "]";
		}

		private string GetRegionCode(string region)
		{
			if (string.IsNullOrEmpty(region))
			{
				return "??";
			}
			if (region.Contains("China"))
			{
				return "CN";
			}
			if (region.Contains("Japan"))
			{
				return "JP";
			}
			if (region.Contains("Korea"))
			{
				return "KR";
			}
			if (region.Contains("Russia"))
			{
				return "RU";
			}
			if (region.Contains("Ukraine"))
			{
				return "UA";
			}
			if (region.Contains("North America"))
			{
				return "NAM";
			}
			if (region.Contains("UK") || region.Contains("Ireland"))
			{
				return "GB";
			}
			if (region.Contains("Germany"))
			{
				return "DE";
			}
			if (region.Contains("France"))
			{
				return "FR";
			}
			if (region.Contains("Italy"))
			{
				return "IT";
			}
			if (region.Contains("Iberia") || region.Contains("Spain") || region.Contains("Portugal"))
			{
				return "ES";
			}
			if (region.Contains("Brazil"))
			{
				return "BR";
			}
			if (region.Contains("Oceania") || region.Contains("Australia"))
			{
				return "OC";
			}
			if (region.Contains("India"))
			{
				return "IN";
			}
			if (region.Contains("Thailand"))
			{
				return "TH";
			}
			if (region.Contains("Southeast Asia"))
			{
				return "SEA";
			}
			if (region.Contains("Turkey"))
			{
				return "TR";
			}
			if (region.Contains("Middle East"))
			{
				return "ME";
			}
			if (region.Contains("Latin America"))
			{
				return "LATAM";
			}
			if (region.Contains("Nordic"))
			{
				return "NORD";
			}
			if (region.Contains("Benelux"))
			{
				return "BEN";
			}
			if (region.Contains("Eastern Europe"))
			{
				return "EE";
			}
			if (region.Contains("CIS"))
			{
				return "EE";
			}
			if (region.Contains("Greece"))
			{
				return "GR";
			}
			if (region.Contains("Israel"))
			{
				return "IL";
			}
			if (region.Contains("Poland"))
			{
				return "PL";
			}
			if (region.Contains("Western"))
			{
				return "WEST";
			}
			if (region.Contains("Americas"))
			{
				return "AM";
			}
			if (region.Length > 4)
			{
				return region.Substring(0, 3).ToUpper();
			}
			return region.ToUpper();
		}

		private Color GetConfidenceColor(float confidence)
		{
			//IL_0017: 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_0051: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			if (confidence >= 80f)
			{
				return new Color(0.2f, 1f, 0.2f);
			}
			if (confidence >= 60f)
			{
				return new Color(0.8f, 1f, 0.2f);
			}
			if (confidence >= 40f)
			{
				return new Color(1f, 0.8f, 0.2f);
			}
			if (confidence >= 20f)
			{
				return new Color(1f, 0.5f, 0.2f);
			}
			return new Color(0.7f, 0.7f, 0.7f);
		}

		private string RemoveExistingTag(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			int num = text.IndexOf(']');
			if (num > 0 && text.StartsWith("["))
			{
				string text2 = text.Substring(1, num - 1).Trim();
				if (text2.Length <= 10 && Regex.IsMatch(text2, "^[A-Z]{2,4}(\\s+\\d+%)?$"))
				{
					text = text.Substring(num + 1).TrimStart();
				}
			}
			return text;
		}
	}
}
namespace LethalCompanyRegionTag.Patches
{
	[HarmonyPatch(typeof(LobbySlot))]
	public static class LobbySlotPatch
	{
		private struct PendingUpdate
		{
			public int InstanceHash;

			public LobbySlot Slot;

			public RegionResult Result;

			public string DisplayedName;
		}

		private static HashSet<int> _taggedSlots = new HashSet<int>();

		private static HashSet<int> _webQueryDoneSlots = new HashSet<int>();

		private static Dictionary<ulong, RegionResult> _resultCache = new Dictionary<ulong, RegionResult>();

		private static HashSet<int> _pendingWebQueries = new HashSet<int>();

		private static Queue<PendingUpdate> _pendingUpdateQueue = new Queue<PendingUpdate>();

		private static volatile bool _hasPendingUpdate = false;

		private static Dictionary<string, string> _regionCodeToChinese;

		public static Dictionary<string, string> RegionCodeToChinese
		{
			get
			{
				if (_regionCodeToChinese == null)
				{
					try
					{
						_regionCodeToChinese = BuildRegionCodeMap();
					}
					catch (Exception ex)
					{
						ManualLogSource logSource = Plugin.LogSource;
						if (logSource != null)
						{
							logSource.LogError((object)("[TAIGU] Failed to build RegionCodeToChinese: " + ex.Message));
						}
						_regionCodeToChinese = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
					}
				}
				return _regionCodeToChinese;
			}
		}

		public static void ResetTaggedSlots()
		{
			_taggedSlots.Clear();
			_webQueryDoneSlots.Clear();
			_pendingWebQueries.Clear();
			_resultCache.Clear();
			Plugin.LogSource.LogInfo((object)"[TAIGU] Reset tagged slots tracking");
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void PostfixUpdate(LobbySlot __instance)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				ProcessPendingUpdates();
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				int hashCode = ((object)__instance).GetHashCode();
				TextMeshProUGUI lobbyName = __instance.LobbyName;
				if ((Object)(object)lobbyName == (Object)null)
				{
					return;
				}
				string text = ((TMP_Text)lobbyName).text;
				if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text))
				{
					return;
				}
				Lobby thisLobby = __instance.thisLobby;
				ulong num = 0uL;
				ulong num2 = 0uL;
				try
				{
					num = ((Lobby)(ref thisLobby)).Id.Value;
				}
				catch
				{
				}
				try
				{
					num2 = ((Lobby)(ref thisLobby)).Owner.Id.Value;
				}
				catch
				{
				}
				if (_taggedSlots.Contains(hashCode))
				{
					return;
				}
				if (num != 0L && _resultCache.TryGetValue(num, out var value))
				{
					ApplyTag(__instance, value, text);
					_taggedSlots.Add(hashCode);
					if (value.Source == "Steam Community" || value.Source == "Steam XML" || value.Source == "Steam Web API")
					{
						_webQueryDoneSlots.Add(hashCode);
					}
					return;
				}
				RegionResult quickAnalysis = RegionAnalyzer.GetQuickAnalysis(text);
				Plugin.LogSource.LogInfo((object)$"[TAIGU] Phase 1 (nickname): displayedName='{text}', primary={quickAnalysis.PrimaryRegion}, confidence={quickAnalysis.Confidence:F0}%");
				ApplyTag(__instance, quickAnalysis, text);
				_taggedSlots.Add(hashCode);
				if (num != 0L)
				{
					_resultCache[num] = quickAnalysis;
				}
				if (num2 != 0L && !_webQueryDoneSlots.Contains(hashCode) && !_pendingWebQueries.Contains(hashCode))
				{
					_pendingWebQueries.Add(hashCode);
					Plugin.LogSource.LogInfo((object)$"[TAIGU] Phase 2: Starting Steam web query for ownerSteamId={num2}");
					StartWebQueryAsync(__instance, hashCode, num, num2, text);
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error in LobbySlot.Update postfix: " + ex.Message + "\n" + ex.StackTrace));
				if ((Object)(object)__instance != (Object)null)
				{
					_pendingWebQueries.Remove(((object)__instance).GetHashCode());
				}
			}
		}

		private static void StartWebQueryAsync(LobbySlot slot, int instanceHash, ulong lobbyId, ulong ownerSteamId, string displayedName)
		{
			ThreadPool.QueueUserWorkItem(delegate
			{
				try
				{
					SteamWebQuery.WebQueryResult result = SteamWebQuery.QueryAllSources(ownerSteamId.ToString()).GetAwaiter().GetResult();
					if (result != null && !string.IsNullOrEmpty(result.CountryCode))
					{
						RegionResult regionResult = new RegionResult
						{
							Source = result.Source,
							CountryCode = result.CountryCode,
							DisplayCode = result.CountryCode,
							PrimaryRegion = RegionAnalyzer.CountryCodeToRegion(result.CountryCode),
							Confidence = result.Confidence,
							Probabilities = BuildWebQueryProbabilityMap(result.CountryCode, result.Confidence)
						};
						Plugin.LogSource.LogInfo((object)$"[TAIGU] Phase 2 complete: countryCode={result.CountryCode}, region={regionResult.PrimaryRegion}, confidence={regionResult.Confidence:F0}%, source={result.Source}");
						if (lobbyId != 0L)
						{
							_resultCache[lobbyId] = regionResult;
						}
						_pendingUpdateQueue.Enqueue(new PendingUpdate
						{
							InstanceHash = instanceHash,
							Slot = slot,
							Result = regionResult,
							DisplayedName = displayedName
						});
						_hasPendingUpdate = true;
					}
					else
					{
						Plugin.LogSource.LogInfo((object)$"[TAIGU] Phase 2: No country code found for ownerSteamId={ownerSteamId}");
					}
				}
				catch (Exception ex)
				{
					Plugin.LogSource.LogWarning((object)("[TAIGU] Phase 2 error: " + ex.Message));
				}
				finally
				{
					_pendingWebQueries.Remove(instanceHash);
					_webQueryDoneSlots.Add(instanceHash);
				}
			});
		}

		public static void ProcessPendingUpdates()
		{
			if (!_hasPendingUpdate)
			{
				return;
			}
			lock (_pendingUpdateQueue)
			{
				while (_pendingUpdateQueue.Count > 0)
				{
					PendingUpdate pendingUpdate = _pendingUpdateQueue.Dequeue();
					try
					{
						if ((Object)(object)pendingUpdate.Slot != (Object)null && (Object)(object)pendingUpdate.Slot.LobbyName != (Object)null)
						{
							ApplyTag(pendingUpdate.Slot, pendingUpdate.Result, pendingUpdate.DisplayedName);
							Plugin.LogSource.LogInfo((object)$"[TAIGU] Updated tag from web query: {pendingUpdate.Result.PrimaryRegion} ({pendingUpdate.Result.Confidence:F0}%)");
						}
					}
					catch (Exception ex)
					{
						Plugin.LogSource.LogWarning((object)("[TAIGU] Error processing pending update: " + ex.Message));
					}
				}
				_hasPendingUpdate = false;
			}
		}

		private static void ApplyTag(LobbySlot slot, RegionResult result, string originalText)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)slot.LobbyName == (Object)null)
				{
					Plugin.LogSource.LogWarning((object)"[TAIGU] LobbyName is null, cannot apply tag");
					return;
				}
				string text = BuildTag(result);
				if (string.IsNullOrEmpty(text))
				{
					Plugin.LogSource.LogInfo((object)"[TAIGU] No tag to apply (unknown region)");
					return;
				}
				string text2 = originalText + "  " + text;
				_ = ((Graphic)slot.LobbyName).color;
				((TMP_Text)slot.LobbyName).text = text2;
				((Graphic)slot.LobbyName).color = GetTagColor(result.Confidence);
				Plugin.LogSource.LogInfo((object)$"[TAIGU] Applied tag: '{text}' to slot (confidence: {result.Confidence:F0}%)");
				EnsureCjkFallback(slot.LobbyName);
				if (((TMP_Text)slot.LobbyName).richText)
				{
					string text3 = ColorToHex(GetTagColor(result.Confidence));
					((TMP_Text)slot.LobbyName).text = originalText + "  <color=#" + text3 + ">" + text + "</color>";
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error applying tag: " + ex.Message));
			}
		}

		private static Dictionary<string, float> BuildWebQueryProbabilityMap(string countryCode, float confidence)
		{
			Dictionary<string, float> obj = new Dictionary<string, float> { [RegionAnalyzer.CountryCodeToRegion(countryCode)] = confidence };
			float value = 100f - confidence;
			obj["Other"] = value;
			return obj;
		}

		private static string BuildTag(RegionResult result)
		{
			if (result == null || result.PrimaryRegion == "Unknown" || result.Confidence < 10f)
			{
				return "";
			}
			string text = result.DisplayCode;
			if (string.IsNullOrEmpty(text))
			{
				text = GetRegionCode(result.PrimaryRegion);
			}
			string displayLabel = GetDisplayLabel(text);
			string arg = "";
			if (result.Source == "Steam Community" || result.Source == "Steam XML" || result.Source == "Steam Web API")
			{
				arg = "*";
			}
			List<string> list = new List<string>();
			list.Add($"[{displayLabel}]{arg} {result.Confidence:F0}%");
			if (result.Probabilities != null)
			{
				List<KeyValuePair<string, float>> list2 = new List<KeyValuePair<string, float>>(result.Probabilities);
				list2.Sort((KeyValuePair<string, float> a, KeyValuePair<string, float> b) => b.Value.CompareTo(a.Value));
				foreach (KeyValuePair<string, float> item in list2)
				{
					if (!(item.Value < 3f) && !(item.Key == result.PrimaryRegion))
					{
						string displayLabel2 = GetDisplayLabel(GetRegionCode(item.Key));
						list.Add($"{displayLabel2} {item.Value:F0}%");
						if (list.Count >= 4)
						{
							break;
						}
					}
				}
			}
			return string.Join(" | ", list);
		}

		private static string GetRegionCode(string region)
		{
			if (string.IsNullOrEmpty(region))
			{
				return "??";
			}
			string text = RegionAnalyzer.RegionToCountryCode(region);
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			switch (region.ToLower())
			{
			case "china":
				return "CN";
			case "japan":
				return "JP";
			case "korea":
				return "KR";
			case "russia":
				return "RU";
			case "vietnam":
				return "VN";
			case "thailand":
				return "TH";
			case "western":
				return "WEST";
			case "western europe":
				return "WEST";
			case "eastern europe":
				return "EE";
			case "southeast asia":
				return "SEA";
			case "south asia":
				return "SAS";
			case "central asia":
				return "CAS";
			case "middle east":
				return "ME";
			case "south america":
				return "LATAM";
			case "central america":
				return "LATAM";
			case "north america":
				return "NAM";
			case "latin america":
				return "LATAM";
			case "north africa":
				return "NAF";
			case "sub-saharan africa":
				return "SSA";
			case "oceania":
				return "OC";
			case "baltic":
				return "BLT";
			case "balkans":
				return "BALK";
			case "nordic":
				return "NORD";
			case "iberia":
				return "IB";
			case "other":
				return "OTHER";
			case "other cis":
				return "EE";
			case "unknown":
				return "OTHER";
			case "nepal":
				return "SAS";
			case "cyprus":
				return "ME";
			case "eritrea":
				return "SSA";
			case "moldova":
				return "EE";
			case "portugal":
				return "IB";
			case "spain":
				return "IB";
			case "slovakia":
				return "EE";
			case "netherlands":
				return "WEST";
			case "belgium":
				return "WEST";
			case "austria":
				return "WEST";
			default:
				if (region.Length <= 4)
				{
					return region.ToUpper();
				}
				return region.Substring(0, 4).ToUpper();
			}
		}

		private static Dictionary<string, string> BuildRegionCodeMap()
		{
			return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				{ "CN", "中国" },
				{ "TW", "台湾" },
				{ "HK", "香港" },
				{ "JP", "日本" },
				{ "KR", "韩国" },
				{ "VN", "越南" },
				{ "TH", "泰国" },
				{ "ID", "印尼" },
				{ "MY", "马来" },
				{ "PH", "菲律宾" },
				{ "SG", "新加坡" },
				{ "KH", "柬埔寨" },
				{ "LA", "老挝" },
				{ "MM", "缅甸" },
				{ "IN", "印度" },
				{ "PK", "巴基斯坦" },
				{ "BD", "孟加拉" },
				{ "KZ", "哈萨克" },
				{ "UZ", "乌兹别克" },
				{ "TR", "土耳其" },
				{ "SA", "沙特" },
				{ "AE", "阿联酋" },
				{ "IR", "伊朗" },
				{ "IQ", "伊拉克" },
				{ "IL", "以色列" },
				{ "IE", "爱尔兰" },
				{ "RU", "俄罗斯" },
				{ "PL", "波兰" },
				{ "UA", "乌克兰" },
				{ "CZ", "捷克" },
				{ "SK", "斯洛伐克" },
				{ "HU", "匈牙利" },
				{ "RO", "罗马尼亚" },
				{ "BG", "保加利亚" },
				{ "SE", "瑞典" },
				{ "FI", "芬兰" },
				{ "DK", "丹麦" },
				{ "GB", "英国" },
				{ "FR", "法国" },
				{ "DE", "德国" },
				{ "IT", "意大利" },
				{ "ES", "西班牙" },
				{ "PT", "葡萄牙" },
				{ "NL", "荷兰" },
				{ "NO", "挪威" },
				{ "BE", "比利时" },
				{ "AT", "奥地利" },
				{ "US", "美国" },
				{ "CA", "加拿大" },
				{ "MX", "墨西哥" },
				{ "BR", "巴西" },
				{ "AR", "阿根廷" },
				{ "CL", "智利" },
				{ "CO", "哥伦比亚" },
				{ "PE", "秘鲁" },
				{ "ZA", "南非" },
				{ "EG", "埃及" },
				{ "MA", "摩洛哥" },
				{ "DZ", "阿尔及利亚" },
				{ "ET", "埃塞俄比亚" },
				{ "NG", "尼日利亚" },
				{ "AU", "澳洲" },
				{ "NZ", "新西兰" },
				{ "MN", "蒙古" },
				{ "AM", "亚美尼亚" },
				{ "BY", "白俄罗斯" },
				{ "CH", "瑞士" },
				{ "ER", "厄立特里亚" },
				{ "GE", "格鲁吉亚" },
				{ "GR", "希腊" },
				{ "LK", "斯里兰卡" },
				{ "MD", "摩尔多瓦" },
				{ "NP", "尼泊尔" },
				{ "RS", "塞尔维亚" },
				{ "WEST", "欧美" },
				{ "EE", "东欧" },
				{ "NORD", "北欧" },
				{ "SAS", "南亚" },
				{ "CAS", "中亚" },
				{ "ME", "中东" },
				{ "SEA", "东南亚" },
				{ "LATAM", "拉美" },
				{ "NAF", "北非" },
				{ "NAM", "北美" },
				{ "NA", "北非" },
				{ "SSA", "撒哈拉以南非洲" },
				{ "OC", "大洋洲" },
				{ "BLT", "波罗的海" },
				{ "BALK", "巴尔干" },
				{ "IB", "伊比利亚" },
				{ "OTHER", "其他" },
				{ "??", "未知" }
			};
		}

		private static string GetDisplayLabel(string regionCode)
		{
			if (string.IsNullOrEmpty(regionCode))
			{
				return "??";
			}
			if (PluginConfig.UseChineseDisplay.Value && FontManager.CjkFontAvailable)
			{
				return FontManager.GetDisplayLabel(regionCode);
			}
			return regionCode;
		}

		private static void EnsureCjkFallback(TextMeshProUGUI label)
		{
			if (!FontManager.CjkFontAvailable || (Object)(object)label == (Object)null || (Object)(object)((TMP_Text)label).font == (Object)null)
			{
				return;
			}
			try
			{
				TMP_FontAsset font = ((TMP_Text)label).font;
				List<TMP_FontAsset> list = font.fallbackFontAssetTable;
				if (list == null)
				{
					list = (font.fallbackFontAssetTable = new List<TMP_FontAsset>());
				}
				bool flag = false;
				foreach (TMP_FontAsset item in list)
				{
					if ((Object)(object)item == (Object)(object)FontManager.CjkFontAsset)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					list.Add(FontManager.CjkFontAsset);
					font.fallbackFontAssetTable = list;
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error applying CJK font fallback: " + ex.Message));
			}
		}

		private static Color GetTagColor(float confidence)
		{
			//IL_0017: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (confidence >= 85f)
			{
				return new Color(0.2f, 1f, 0.2f);
			}
			if (confidence >= 60f)
			{
				return new Color(0.4f, 0.9f, 0.4f);
			}
			if (confidence >= 40f)
			{
				return new Color(1f, 0.9f, 0.3f);
			}
			return new Color(0.7f, 0.7f, 0.7f);
		}

		private static string ColorToHex(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			int num = (int)(color.r * 255f);
			int num2 = (int)(color.g * 255f);
			int num3 = (int)(color.b * 255f);
			return $"{num:X2}{num2:X2}{num3:X2}";
		}
	}
	[HarmonyPatch(typeof(SteamLobbyManager))]
	public static class SteamLobbyManagerPatch
	{
		public static Lobby[] CurrentLobbyList { get; private set; }

		[HarmonyPostfix]
		[HarmonyPatch("loadLobbyListAndFilter")]
		private static void PostfixLoadLobbyList(Lobby[] lobbyList)
		{
			try
			{
				if (lobbyList != null && lobbyList.Length != 0)
				{
					CurrentLobbyList = lobbyList;
					Plugin.LogSource.LogInfo((object)$"[TAIGU] Captured {lobbyList.Length} lobbies from server list");
					LobbySlotPatch.ResetTaggedSlots();
				}
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error in SteamLobbyManagerPatch: " + ex.Message));
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("LoadServerList")]
		private static void PostfixLoadServerList()
		{
			try
			{
				Plugin.LogSource.LogInfo((object)"[TAIGU] Server list refresh requested");
				LobbySlotPatch.ResetTaggedSlots();
			}
			catch (Exception ex)
			{
				Plugin.LogSource.LogWarning((object)("[TAIGU] Error in LoadServerList postfix: " + ex.Message));
			}
		}
	}
}
namespace LethalCompanyRegionTag.Config
{
	public static class PluginConfig
	{
		public static ConfigEntry<bool> EnableNicknameAnalysis { get; private set; }

		public static ConfigEntry<bool> EnableCommunityQuery { get; private set; }

		public static ConfigEntry<bool> EnableXmlQuery { get; private set; }

		public static ConfigEntry<string> SteamWebApiKey { get; private set; }

		public static ConfigEntry<float> MinConfidenceThreshold { get; private set; }

		public static ConfigEntry<bool> ShowLowConfidenceTags { get; private set; }

		public static ConfigEntry<bool> ShowProbability { get; private set; }

		public static ConfigEntry<bool> UseChineseDisplay { get; private set; }

		public static void Init(ConfigFile configFile)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			EnableNicknameAnalysis = configFile.Bind<bool>("Analysis Sources", "EnableNicknameAnalysis", true, "Enable nickname language analysis (always works, no network needed). Analyzes Unicode character sets in lobby host names to detect language/region.");
			EnableCommunityQuery = configFile.Bind<bool>("Analysis Sources", "EnableCommunityQuery", true, "Enable Steam Community page query (no API key needed). Fetches the host's Steam profile page to extract country flag. May be slow or rate-limited.");
			EnableXmlQuery = configFile.Bind<bool>("Analysis Sources", "EnableXmlQuery", true, "Enable Steam XML profile query (fallback). Fetches the host's Steam profile in XML format to extract location info.");
			SteamWebApiKey = configFile.Bind<string>("Analysis Sources", "SteamWebApiKey", "", "Steam Web API key for most accurate region detection. Get a free key from: https://steamcommunity.com/dev/apikey (requires Steam account). Leave empty to use other methods only.");
			MinConfidenceThreshold = configFile.Bind<float>("Display Settings", "MinConfidenceThreshold", 20f, new ConfigDescription("Minimum confidence percentage (0-100) required to show a region tag. Tags below this threshold are hidden.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			ShowLowConfidenceTags = configFile.Bind<bool>("Display Settings", "ShowLowConfidenceTags", false, "Show [??] tag for lobbies where no region could be determined at all.");
			ShowProbability = configFile.Bind<bool>("Display Settings", "ShowProbability", true, "Show probability percentage next to the region code (e.g. [CN 78%] instead of just [CN]).");
			UseChineseDisplay = configFile.Bind<bool>("Display Settings", "UseChineseDisplay", true, "Use Chinese names for region display (e.g. [中国] instead of [CN]). Note: requires game font to support CJK characters. If you see garbled text, set this to false.");
		}
	}
}
namespace LethalCompanyRegionTag.Cache
{
	public class RegionCache
	{
		private struct CacheEntry
		{
			public RegionResult Result;

			public DateTime ExpiresAt;
		}

		private static readonly Dictionary<ulong, CacheEntry> _cache = new Dictionary<ulong, CacheEntry>();

		private static readonly object _lock = new object();

		private static readonly TimeSpan DefaultTTL = TimeSpan.FromMinutes(10.0);

		public static bool TryGet(ulong steamId, out RegionResult result)
		{
			lock (_lock)
			{
				if (_cache.TryGetValue(steamId, out var value))
				{
					if (DateTime.UtcNow < value.ExpiresAt)
					{
						result = value.Result;
						return true;
					}
					_cache.Remove(steamId);
				}
			}
			result = null;
			return false;
		}

		public static void Set(ulong steamId, RegionResult result)
		{
			if (steamId == 0L || result == null)
			{
				return;
			}
			lock (_lock)
			{
				_cache[steamId] = new CacheEntry
				{
					Result = result,
					ExpiresAt = DateTime.UtcNow + DefaultTTL
				};
			}
		}

		public static void Clear()
		{
			lock (_lock)
			{
				_cache.Clear();
			}
		}

		public static void Cleanup()
		{
			lock (_lock)
			{
				DateTime utcNow = DateTime.UtcNow;
				List<ulong> list = new List<ulong>();
				foreach (KeyValuePair<ulong, CacheEntry> item in _cache)
				{
					if (utcNow >= item.Value.ExpiresAt)
					{
						list.Add(item.Key);
					}
				}
				foreach (ulong item2 in list)
				{
					_cache.Remove(item2);
				}
			}
		}
	}
}
namespace LethalCompanyRegionTag.Analysis
{
	public static class NicknameAnalyzer
	{
		private static readonly Regex CJKUnified = new Regex("[\\u4E00-\\u9FFF\\u3400-\\u4DBF]");

		private static readonly Regex Hiragana = new Regex("[\\u3040-\\u309F]");

		private static readonly Regex Katakana = new Regex("[\\u30A0-\\u30FF\\u31F0-\\u31FF]");

		private static readonly Regex HangulSyllables = new Regex("[\\uAC00-\\uD7AF]");

		private static readonly Regex HangulJamo = new Regex("[\\u1100-\\u11FF\\u3130-\\u318F\\uA960-\\uA97F\\uD7B0-\\uD7FF]");

		private static readonly Regex Cyrillic = new Regex("[\\u0400-\\u04FF\\u0500-\\u052F\\u2DE0-\\u2DFF\\uA640-\\uA69F]");

		private static readonly Regex Arabic = new Regex("[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]");

		private static readonly Regex Thai = new Regex("[\\u0E00-\\u0E7F]");

		private static readonly Regex Lao = new Regex("[\\u0E80-\\u0EFF]");

		private static readonly Regex Khmer = new Regex("[\\u1780-\\u17FF\\u19E0-\\u19FF]");

		private static readonly Regex Myanmar = new Regex("[\\u1000-\\u109F\\uAA60-\\uAA7F]");

		private static readonly Regex Tibetan = new Regex("[\\u0F00-\\u0FFF]");

		private static readonly Regex Devanagari = new Regex("[\\u0900-\\u097F]");

		private static readonly Regex Bengali = new Regex("[\\u0980-\\u09FF]");

		private static readonly Regex Greek = new Regex("[\\u0370-\\u03FF\\u1F00-\\u1FFF]");

		private static readonly Regex Hebrew = new Regex("[\\u0590-\\u05FF\\uFB1D-\\uFB4F]");

		private static readonly Regex Armenian = new Regex("[\\u0530-\\u058F\\uFB00-\\uFB17]");

		private static readonly Regex Georgian = new Regex("[\\u10A0-\\u10FF\\u2D00-\\u2D2F]");

		private static readonly Regex Latin = new Regex("[A-Za-z\\u00C0-\\u024F]");

		private static readonly Regex LatinExtended = new Regex("[\\u0100-\\u024F\\u1E00-\\u1EFF]");

		private static readonly Regex Ethiopic = new Regex("[\\u1200-\\u137F\\u1380-\\u139F\\u2D80-\\u2DDF\\uAB00-\\uAB2F]");

		private static readonly Regex Sinhala = new Regex("[\\u0D80-\\u0DFF]");

		private static readonly Regex Tamil = new Regex("[\\u0B80-\\u0BFF]");

		private static readonly Regex Telugu = new Regex("[\\u0C00-\\u0C7F]");

		private static readonly Dictionary<string, string[]> CountryKeywords = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
		{
			["CN"] = new string[16]
			{
				"china", " cn ", "[cn]", "chinese", "国服", "中国", "中文", "国人", "no foreigner", "不要外国人",
				"华人", "汉语", "简体", "繁体", "cn服", "国际服禁止"
			},
			["TW"] = new string[6] { " taiwan", " tw ", "[tw]", "台湾", "繁体", "正體字" },
			["HK"] = new string[5] { " hong kong", " hk ", "[hk]", "香港", "cantonese" },
			["JP"] = new string[6] { "japan", " japanese", " jp ", "[jp]", "日本語", "日本人" },
			["KR"] = new string[6] { "korea", " korean", " kr ", "[kr]", "한국어", "한국인" },
			["VN"] = new string[5] { "vietnam", " vietnamese", " vn ", "[vn]", "tieng viet" },
			["TH"] = new string[5] { "thailand", " thai ", " th ", "[th]", "ไทย" },
			["ID"] = new string[7] { "indonesia", " indonesian", " id ", "[id]", " indo ", "wibu", "orang indonesia" },
			["PH"] = new string[7] { "philippines", " filipino", " ph ", "[ph]", " pinoy", " pinay", "tagalog" },
			["MY"] = new string[5] { "malaysia", " malaysian", " my ", "[my]", "malaysian" },
			["SG"] = new string[3] { "singapore", " sg ", "[sg]" },
			["IN"] = new string[7] { "india", " indian", " in ", "[in]", "hindi", "ह\u093fन\u094dद\u0940", "bharat" },
			["PK"] = new string[5] { "pakistan", " pakistani", " pk ", "[pk]", "urdu" },
			["BD"] = new string[4] { "bangladesh", " bangla", " bd ", "[bd]" },
			["SA"] = new string[4] { "saudi", " sa ", "[sa]", "العربية" },
			["AE"] = new string[5] { "uae", " emirates", " ae ", "[ae]", "dubai" },
			["IR"] = new string[7] { "iran", " iranian", " ir ", "[ir]", "farsi", "فارسی", "persian" },
			["TR"] = new string[7] { "turkey", " turkish", " tr ", "[tr]", "türkçe", "türk", "tr备" },
			["RU"] = new string[8] { "russia", " russian", " ru ", "[ru]", "cis", "рус", "россия", "русский" },
			["UA"] = new string[6] { "ukraine", " ukrainian", " ua ", "[ua]", "укр", "україн" },
			["BY"] = new string[5] { "belarus", " belarusian", " by ", "[by]", "беларус" },
			["KZ"] = new string[4] { "kazakhstan", " kazakh", " kz ", "[kz]" },
			["PL"] = new string[9] { "poland", " polish", " pl ", "[pl]", "polska", "polski", "polacy", "tylko polacy", "no foreigner pl" },
			["DE"] = new string[7] { "germany", " german", " de ", "[de]", "deutsch", "deutsche", "nur deutsch" },
			["FR"] = new string[6] { "france", " french", " fr ", "[fr]", "français", "francophone" },
			["IT"] = new string[5] { "italy", " italian", " it ", "[it]", "italiano" },
			["ES"] = new string[7] { "spain", " spanish", " es ", "[es]", "español", "españa", "hispano" },
			["PT"] = new string[7] { "portugal", " portuguese", " pt ", "[pt]", "português", "brasil", "brazil" },
			["NL"] = new string[6] { "netherlands", " dutch", " nl ", "[nl]", "nederlands", "holland" },
			["SE"] = new string[6] { "sweden", " swedish", " se ", "[se]", "svenska", "sverige" },
			["NO"] = new string[6] { "norway", " norwegian", " no ", "[no]", "norsk", "norge" },
			["DK"] = new string[6] { "denmark", " danish", " dk ", "[dk]", "dansk", "danmark" },
			["FI"] = new string[6] { "finland", " finnish", " fi ", "[fi]", "suomi", "suomalainen" },
			["CZ"] = new string[5] { "czech", " cz ", "[cz]", "čeština", "český" },
			["SK"] = new string[5] { "slovakia", " slovak", " sk ", "[sk]", "slovenčina" },
			["HU"] = new string[5] { "hungary", " hungarian", " hu ", "[hu]", "magyar" },
			["RO"] = new string[5] { "romania", " romanian", " ro ", "[ro]", "română" },
			["BG"] = new string[5] { "bulgaria", " bulgarian", " bg ", "[bg]", "българ" },
			["HR"] = new string[5] { "croatia", " croatian", " hr ", "[hr]", "hrvatski" },
			["RS"] = new string[6] { "serbia", " serbian", " rs ", "[rs]", "srpski", "српски" },
			["GR"] = new string[5] { "greece", " greek", " gr ", "[gr]", "ελληνικά" },
			["US"] = new string[8] { "usa", " us ", "[us]", "america", "american", "english only", "en only", "north america" },
			["CA"] = new string[4] { "canada", " canadian", " ca ", "[ca]" },
			["BR"] = new string[6] { "brazil", " brazilian", " br ", "[br]", "português", "brasileiro" },
			["MX"] = new string[6] { "mexico", " mexican", " mx ", "[mx]", "méxico", "latino" },
			["AR"] = new string[4] { "argentina", " argentinian", " ar ", "[ar]" },
			["CL"] = new string[4] { "chile", " chilean", " cl ", "[cl]" },
			["CO"] = new string[4] { "colombia", " colombian", " co ", "[co]" },
			["AU"] = new string[5] { "australia", " aussie", " au ", "[au]", "aussi" },
			["NZ"] = new string[4] { "new zealand", " nz ", "[nz]", "kiwi" },
			["EG"] = new string[5] { "egypt", " egyptian", " eg ", "[eg]", "مصر" },
			["ZA"] = new string[3] { "south africa", " za ", "[za]" },
			["MA"] = new string[5] { "morocco", " moroccan", " ma ", "[ma]", "maroc" },
			["DZ"] = new string[5] { "algeria", " algerian", " dz ", "[dz]", "algérie" }
		};

		private static readonly Regex SpanishPattern = new Regex("\\b(juan|maria|jose|carlos|luis|pedro|pablo|diego|fernando|alejandro|antonio|manuel|francisco|rafael|sergio|miguel|angel|enrique|roberto|alberto|eduardo|andres|ricardo|jorge|oscar|ramon|victor|hernandez|garcia|rodriguez|martinez|lopez|gonzalez|perez|sanchez|ramirez|torres|flores|rivera|gomez|diaz|cruz|morales|reyes|gutierrez|ortiz|moreno|romero|alvarez|ruiz|jimenez|dominguez|fernandez|vasquez|mendez|herrera|vargas|castro|campos|medina|pena|delgado|vega|silva|espinoza|valdez|aguilar|santos|acosta|figueroa|cabrera|enriquez|miranda|maldonado|estrada|rojas|abreu|cervantes|santiago|velasquez|montoya|peralta|soler|camacho|pimentel|de\\s+la\\s+cruz|de\\s+jesus)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex GermanPattern = new Regex("\\b(hans|klaus|peter|stefan|thomas|andreas|michael|markus|martin|bernd|jurgen|wolfgang|dieter|ulf|sven|lars|bjorn|fischer|muller|schmidt|schneider|wagner|weber|becker|hoffmann|schwarz|wolf|klein|neumann|hartmann|kruger|ludwig|lang|graf|heinrich)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex FrenchPattern = new Regex("\\b(jean|pierre|jacques|philippe|alain|michel|louis|christophe|nicolas|julien|thomas|alexandre|olivier|laurent|stephane|frederic|dupont|bernard|robert|petit|richard|durand|leroy|moreau|simon|lefebvre|bertrand|roux|vincent|fournier|morel|girard|lemercier|blanc|robin|clement|bonnet|picard|garnier|marie|renaud|chevalier|francois|faure|perrin|merceron)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex VietnamesePattern = new Regex("\\b(nguyen|tran|le\\s|pham|hoang|huynh|phan|vu\\s|vo\\s|dang|bui|do\\s|ho\\s|ngo\\s|duong|ly\\s|thi\\s|van\\s|dung\\s|hung\\s|cuong|minh\\s|tuan\\s|hai\\s|phong\\s|linh\\s|hoa\\s|thanh\\s|trang\\s|lan\\s|hien\\s|mai\\s|anh\\s|duc\\s|nhan\\s|tam\\s|tin\\s|khoa\\s|bao\\s|chau\\s|quoc\\s|phu\\s|thao\\s|my\\s|ngoc\\s|trinh\\s|an\\s|binh\\s|cong\\s|dat\\s|dien\\s|gia\\s|hanh\\s|khanh\\s|long\\s|nam\\s|quan\\s|son\\s|tai\\s|uyen\\s|xuan\\s|yen\\s)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex IndonesianPattern = new Regex("\\b(surya|budi|andi|dewi|siti|agus|eko|rizky|fitri|novi|yuni|ari|dimas|fajar|galih|heru|irfan|joko|kurnia|lutfi|maya|nanda|oki|putri|rani|sari|tomi|udin|wawan|yoga|zaki|putra|permata|nurul|indah|ratu|cipta|bagus|wicaksono|prasetyo)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex TurkishPattern = new Regex("\\b(mehmet|mustafa|ahmet|ali|huseyin|hasan|ibrahim|ismail|yusuf|osman|murat|emre|fatma|ayse|elif|zeynep|selin|deniz|cem|kaan|baris|onur|serkan|tolga|volkan|yilmaz|kaya|demir|celik|yildiz|aydin|ozturk|arslan|dogan|kilic)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex PolishPattern = new Regex("\\b(jan|andrzej|piotr|krzysztof|tomasz|marek|michal|pawel|marcin|grzegorz|jakub|mateusz|katarzyna|anna|malgorzata|agnieszka|magdalena|joanna|barbara|ewal|kowalski|nowak|wisniewski|wójcik|kaminski|lewandowski|szymanski|wojciech|zielinski)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex RussianNamePattern = new Regex("\\b(alexander|dmitry|sergei|ivan|andrei|nikolai|vladimir|mikhail|artem|maxim|anastasia|elena|olga|natalia|tatiana|ekaterina|maria|svetlana|irina|yulia|ivanov|petrov|sidorov|smirnov|kuznetsov|popov)\\b", RegexOptions.IgnoreCase);

		private static readonly Regex ArabicNamePattern = new Regex("\\b(mohammed|ahmed|ali|hassan|hussein|omar|khalid|faisal|abdullah|ibrahim|fatima|aisha|khadija|maryam|al\\s|bin\\s|abu\\s|el\\s)\\b", RegexOptions.IgnoreCase);

		public static NicknameAnalysisResult Analyze(string nickname)
		{
			NicknameAnalysisResult nicknameAnalysisResult = new NicknameAnalysisResult();
			if (string.IsNullOrWhiteSpace(nickname))
			{
				nicknameAnalysisResult.Probabilities["Unknown"] = 100f;
				nicknameAnalysisResult.PrimaryRegion = "Unknown";
				nicknameAnalysisResult.Confidence = 0f;
				nicknameAnalysisResult.AnalysisMethod = "Empty";
				return nicknameAnalysisResult;
			}
			string text = nickname.ToLowerInvariant();
			Dictionary<string, float> dictionary = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);
			foreach (KeyValuePair<string, string[]> countryKeyword in CountryKeywords)
			{
				string key = countryKeyword.Key;
				string[] value = countryKeyword.Value;
				foreach (string text2 in value)
				{
					if (text.Contains(text2.ToLowerInvariant()))
					{
						float num = 85f + Math.Min((float)text2.Length * 1.5f, 10f);
						if (!dictionary.ContainsKey(key) || dictionary[key] < num)
						{
							dictionary[key] = num;
						}
					}
				}
			}
			if (dictionary.Count > 0)
			{
				KeyValuePair<string, float> keyValuePair = dictionary.OrderByDescending((KeyValuePair<string, float> x) => x.Value).First();
				string key2 = keyValuePair.Key;
				float num2 = Math.Min(keyValuePair.Value, 97f);
				nicknameAnalysisResult.PrimaryRegion = RegionAnalyzer.CountryCodeToRegion(key2);
				nicknameAnalysisResult.Confidence = num2;
				nicknameAnalysisResult.CountryCode = key2;
				nicknameAnalysisResult.AnalysisMethod = "Keyword: " + key2;
				nicknameAnalysisResult.Probabilities[nicknameAnalysisResult.PrimaryRegion] = num2;
				float num3 = 100f - num2;
				if (dictionary.Count > 1)
				{
					string text3 = RegionAnalyzer.CountryCodeToRegion(dictionary.OrderByDescending((KeyValuePair<string, float> x) => x.Value).Skip(1).First()
						.Key);
						if (text3 != nicknameAnalysisResult.PrimaryRegion)
						{
							float num4 = num3 * 0.6f;
							nicknameAnalysisResult.Probabilities[text3] = num4;
							num3 -= num4;
						}
					}
					if (num3 > 2f)
					{
						nicknameAnalysisResult.Probabilities["Other"] = num3;
					}
					return nicknameAnalysisResult;
				}
				bool flag = CJKUnified.IsMatch(nickname);
				bool flag2 = Hiragana.IsMatch(nickname);
				bool flag3 = Katakana.IsMatch(nickname);
				bool flag4 = HangulSyllables.IsMatch(nickname) || HangulJamo.IsMatch(nickname);
				bool flag5 = Cyrillic.IsMatch(nickname);
				bool flag6 = Arabic.IsMatch(nickname);
				bool flag7 = Thai.IsMatch(nickname);
				bool flag8 = Lao.IsMatch(nickname);
				bool flag9 = Khmer.IsMatch(nickname);
				bool flag10 = Myanmar.IsMatch(nickname);
				bool flag11 = Tibetan.IsMatch(nickname);
				bool flag12 = Devanagari.IsMatch(nickname);
				bool flag13 = Bengali.IsMatch(nickname);
				bool flag14 = Greek.IsMatch(nickname);
				bool flag15 = Hebrew.IsMatch(nickname);
				bool flag16 = Armenian.IsMatch(nickname);
				bool flag17 = Georgian.IsMatch(nickname);
				bool flag18 = Ethiopic.IsMatch(nickname);
				bool flag19 = Sinhala.IsMatch(nickname);
				bool flag20 = Tamil.IsMatch(nickname);
				bool flag21 = Telugu.IsMatch(nickname);
				bool flag22 = Latin.IsMatch(nickname);
				if (flag2 || flag3)
				{
					nicknameAnalysisResult.Probabilities["Japan"] = 94f;
					nicknameAnalysisResult.Probabilities["Other"] = 6f;
					nicknameAnalysisResult.PrimaryRegion = "Japan";
					nicknameAnalysisResult.Confidence = 94f;
					nicknameAnalysisResult.AnalysisMethod = "Kana detected";
					nicknameAnalysisResult.CountryCode = "JP";
					return nicknameAnalysisResult;
				}
				if (flag4)
				{
					nicknameAnalysisResult.Probabilities["Korea"] = 94f;
					nicknameAnalysisResult.Probabilities["Other"] = 6f;
					nicknameAnalysisResult.PrimaryRegion = "Korea";
					nicknameAnalysisResult.Confidence = 94f;
					nicknameAnalysisResult.AnalysisMethod = "Hangul detected";
					nicknameAnalysisResult.CountryCode = "KR";
					return nicknameAnalysisResult;
				}
				if (flag && !flag2 && !flag3 && !flag4)
				{
					nicknameAnalysisResult.Probabilities["China"] = 78f;
					nicknameAnalysisResult.Probabilities["Japan"] = 7f;
					nicknameAnalysisResult.Probabilities["Korea"] = 6f;
					nicknameAnalysisResult.Probabilities["Vietnam"] = 4f;
					nicknameAnalysisResult.Probabilities["Other"] = 5f;
					nicknameAnalysisResult.PrimaryRegion = "China";
					nicknameAnalysisResult.Confidence = 78f;
					nicknameAnalysisResult.AnalysisMethod = "CJK Hanzi detected";
					nicknameAnalysisResult.CountryCode = "CN";
					return nicknameAnalysisResult;
				}
				if (flag7)
				{
					nicknameAnalysisResult.Probabilities["Thailand"] = 90f;
					nicknameAnalysisResult.Probabilities["Other"] = 10f;
					nicknameAnalysisResult.PrimaryRegion = "Thailand";
					nicknameAnalysisResult.Confidence = 90f;
					nicknameAnalysisResult.AnalysisMethod = "Thai script detected";
					nicknameAnalysisResult.CountryCode = "TH";
					return nicknameAnalysisResult;
				}
				if (flag8)
				{
					nicknameAnalysisResult.Probabilities["Laos"] = 85f;
					nicknameAnalysisResult.Probabilities["Thailand"] = 10f;
					nicknameAnalysisResult.Probabilities["Other"] = 5f;
					nicknameAnalysisResult.PrimaryRegion = "Laos";
					nicknameAnalysisResult.Confidence = 85f;
					nicknameAnalysisResult.AnalysisMethod = "Lao script detected";
					nicknameAnalysisResult.CountryCode = "LA";
					return nicknameAnalysisResult;
				}
				if (flag9)
				{
					nicknameAnalysisResult.Probabilities["Cambodia"] = 88f;
					nicknameAnalysisResult.Probabilities["Other"] = 12f;
					nicknameAnalysisResult.PrimaryRegion = "Cambodia";
					nicknameAnalysisResult.Confidence = 88f;
					nicknameAnalysisResult.AnalysisMethod = "Khmer script detected";
					nicknameAnalysisResult.CountryCode = "KH";
					return nicknameAnalysisResult;
				}
				if (flag10)
				{
					nicknameAnalysisResult.Probabilities["Myanmar"] = 88f;
					nicknameAnalysisResult.Probabilities["Other"] = 12f;
					nicknameAnalysisResult.PrimaryRegion = "Myanmar";
					nicknameAnalysisResult.Confidence = 88f;
					nicknameAnalysisResult.AnalysisMethod = "Myanmar script detected";
					nicknameAnalysisResult.CountryCode = "MM";
					return nicknameAnalysisResult;
				}
				if (flag11)
				{
					nicknameAnalysisResult.Probabilities["China"] = 60f;
					nicknameAnalysisResult.Probabilities["Other"] = 40f;
					nicknameAnalysisResult.PrimaryRegion = "China";
					nicknameAnalysisResult.Confidence = 60f;
					nicknameAnalysisResult.AnalysisMethod = "Tibetan script detected";
					nicknameAnalysisResult.CountryCode = "CN";
					return nicknameAnalysisResult;
				}
				if (flag12)
				{
					nicknameAnalysisResult.Probabilities["India"] = 80f;
					nicknameAnalysisResult.Probabilities["Nepal"] = 12f;
					nicknameAnalysisResult.Probabilities["Other"] = 8f;
					nicknameAnalysisResult.PrimaryRegion = "India";
					nicknameAnalysisResult.Confidence = 80f;
					nicknameAnalysisResult.AnalysisMethod = "Devanagari detected";
					nicknameAnalysisResult.CountryCode = "IN";
					return nicknameAnalysisResult;
				}
				if (flag13)
				{
					nicknameAnalysisResult.Probabilities["Bangladesh"] = 45f;
					nicknameAnalysisResult.Probabilities["India"] = 45f;
					nicknameAnalysisResult.Probabilities["Other"] = 10f;
					nicknameAnalysisResult.PrimaryRegion = "Bangladesh";
					nicknameAnalysisResult.Confidence = 45f;
					nicknameAnalysisResult.AnalysisMethod = "Bengali detected";
					nicknameAnalysisResult.CountryCode = "BD";
					return nicknameAnalysisResult;
				}
				if (flag20)
				{
					nicknameAnalysisResult.Probabilities["India"] = 60f;
					nicknameAnalysisResult.Probabilities["Sri Lanka"] = 25f;
					nicknameAnalysisResult.Probabilities["Other"] = 15f;
					nicknameAnalysisResult.PrimaryRegion = "India";
					nicknameAnalysisResult.Confidence = 60f;
					nicknameAnalysisResult.AnalysisMethod = "Tamil detected";
					nicknameAnalysisResult.CountryCode = "IN";
					return nicknameAnalysisResult;
				}
				if (flag21)
				{
					nicknameAnalysisResult.Probabilities["India"] = 85f;
					nicknameAnalysisResult.Probabilities["Other"] = 15f;
					nicknameAnalysisResult.PrimaryRegion = "India";
					nicknameAnalysisResult.Confidence = 85f;
					nicknameAnalysisResult.AnalysisMethod = "Telugu detected";
					nicknameAnalysisResult.CountryCode = "IN";
					return nicknameAnalysisResult;
				}
				if (flag19)
				{
					nicknameAnalysisResult.Probabilities["Sri Lanka"] = 88f;
					nicknameAnalysisResult.Probabilities["Other"] = 12f;
					nicknameAnalysisResult.PrimaryRegion = "Sri Lanka";
					nicknameAnalysisResult.Confidence = 88f;
					nicknameAnalysisResult.AnalysisMethod = "Sinhala detected";
					nicknameAnalysisResult.CountryCode = "LK";
					return nicknameAnalysisResult;
				}
				if (flag18)
				{
					nicknameAnalysisResult.Probabilities["Ethiopia"] = 70f;
					nicknameAnalysisResult.Probabilities["Eritrea"] = 20f;
					nicknameAnalysisResult.Probabilities["Other"] = 10f;
					nicknameAnalysisResult.PrimaryRegion = "Ethiopia";
					nicknameAnalysisResult.Confidence = 70f;
					nicknameAnalysisResult.AnalysisMethod = "Ethiopic detected";
					nicknameAnalysisResult.CountryCode = "ET";
					return nicknameAnalysisResult;
				}
				if (flag5)
				{
					RussianNamePattern.IsMatch(nickname);
					bool num5 = text.Contains("укр") || text.Contains("ua ") || text.Contains("[ua]");
					bool flag23 = text.Contains("беларус") || text.Contains("by ") || text.Contains("[by]");
					if (num5)
					{
						nicknameAnalysisResult.Probabilities["Ukraine"] = 75f;
						nicknameAnalysisResult.Probabilities["Russia"] = 10f;
						nicknameAnalysisResult.Probabilities["Other"] = 15f;
						nicknameAnalysisResult.PrimaryRegion = "Ukraine";
						nicknameAnalysisResult.Confidence = 75f;
						nicknameAnalysisResult.AnalysisMethod = "Cyrillic + UA keywords";
						nicknameAnalysisResult.CountryCode = "UA";
					}
					else if (flag23)
					{
						nicknameAnalysisResult.Probabilities["Belarus"] = 75f;
						nicknameAnalysisResult.Probabilities["Russia"] = 10f;
						nicknameAnalysisResult.Probabilities["Other"] = 15f;
						nicknameAnalysisResult.PrimaryRegion = "Belarus";
						nicknameAnalysisResult.Confidence = 75f;
						nicknameAnalysisResult.AnalysisMethod = "Cyrillic + BY keywords";
						nicknameAnalysisResult.CountryCode = "BY";
					}
					else
					{
						nicknameAnalysisResult.Probabilities["Russia"] = 55f;
						nicknameAnalysisResult.Probabilities["Ukraine"] = 12f;
						nicknameAnalysisResult.Probabilities["Belarus"] = 8f;
						nicknameAnalysisResult.Probabilities["Other CIS"] = 10f;
						nicknameAnalysisResult.Probabilities["Balkans"] = 5f;
						nicknameAnalysisResult.Probabilities["Other"] = 10f;
						nicknameAnalysisResult.PrimaryRegion = "Russia";
						nicknameAnalysisResult.Confidence = 55f;
						nicknameAnalysisResult.AnalysisMethod = "Cyrillic detected";
						nicknameAnalysisResult.CountryCode = "RU";
					}
					return nicknameAnalysisResult;
				}
				if (flag6)
				{
					ArabicNamePattern.IsMatch(nickname);
					if (text.Contains("egypt") || text.Contains("مصر"))
					{
						nicknameAnalysisResult.Probabilities["Egypt"] = 65f;
						nicknameAnalysisResult.Probabilities["Middle East"] = 15f;
						nicknameAnalysisResult.Probabilities["Other"] = 20f;
						nicknameAnalysisResult.PrimaryRegion = "Egypt";
						nicknameAnalysisResult.Confidence = 65f;
						nicknameAnalysisResult.AnalysisMethod = "Arabic + EG keywords";
						nicknameAnalysisResult.CountryCode = "EG";
					}
					else
					{
						nicknameAnalysisResult.Probabilities["Middle East"] = 50f;
						nicknameAnalysisResult.Probabilities["North Africa"] = 20f;
						nicknameAnalysisResult.Probabilities["Central Asia"] = 10f;
						nicknameAnalysisResult.Probabilities["Other"] = 20f;
						nicknameAnalysisResult.PrimaryRegion = "Middle East";
						nicknameAnalysisResult.Confidence = 50f;
						nicknameAnalysisResult.AnalysisMethod = "Arabic script detected";
						nicknameAnalysisResult.CountryCode = "SA";
					}
					return nicknameAnalysisResult;
				}
				if (flag14)
				{
					nicknameAnalysisResult.Probabilities["Greece"] = 82f;
					nicknameAnalysisResult.Probabilities["Cyprus"] = 8f;
					nicknameAnalysisResult.Probabilities["Other"] = 10f;
					nicknameAnalysisResult.PrimaryRegion = "Greece";
					nicknameAnalysisResult.Confidence = 82f;
					nicknameAnalysisResult.AnalysisMethod = "Greek script detected";
					nicknameAnalysisResult.CountryCode = "GR";
					return nicknameAnalysisResult;
				}
				if (flag15)
				{
					nicknameAnalysisResult.Probabilities["Israel"] = 85f;
					nicknameAnalysisResult.Probabilities["Other"] = 15f;
					nicknameAnalysisResult.PrimaryRegion = "Israel";
					nicknameAnalysisResult.Confidence = 85f;
					nicknameAnalysisResult.AnalysisMethod = "Hebrew script detected";
					nicknameAnalysisResult.CountryCode = "IL";
					return nicknameAnalysisResult;
				}
				if (flag16)
				{
					nicknameAnalysisResult.Probabilities["Armenia"] = 80f;
					nicknameAnalysisResult.Probabilities["Other"] = 20f;
					nicknameAnalysisResult.PrimaryRegion = "Armenia";
					nicknameAnalysisResult.Confidence = 80f;
					nicknameAnalysisResult.AnalysisMethod = "Armenian script detected";
					nicknameAnalysisResult.CountryCode = "AM";
					return nicknameAnalysisResult;
				}
				if (flag17)
				{
					nicknameAnalysisResult.Probabilities["Georgia"] = 82f;
					nicknameAnalysisResult.Probabilities["Other"] = 18f;
					nicknameAnalysisResult.PrimaryRegion = "Georgia";
					nicknameAnalysisResult.Confidence = 82f;
					nicknameAnalysisResult.AnalysisMethod = "Georgian script detected";
					nicknameAnalysisResult.CountryCode = "GE";
					return nicknameAnalysisResult;
				}
				if (flag22)
				{
					bool flag24 = Regex.IsMatch(nickname, "[\\u0103\\u00E2\\u00EA\\u00F4\\u01A1\\u01B0\\u0111\\u00E0\\u00E1\\u00E3\\u00E8\\u00E9\\u00EC\\u00ED\\u00F2\\u00F3\\u00F9\\u00FA\\u00FD\\u1EA3\\u1EA1\\u1EB9\\u1EC7\\u1ECF\\u1ED3\\u1EDD\\u1EE5\\u1EEF]");
					bool flag25 = Regex.IsMatch(nickname, "[\\u00E7\\u011F\\u0131\\u00F6\\u015F\\u00FC]", RegexOptions.IgnoreCase);
					bool flag26 = Regex.IsMatch(nickname, "[\\u0105\\u0107\\u0119\\u0142\\u0144\\u00F3\\u015B\\u017A\\u017C]", RegexOptions.IgnoreCase);
					bool flag27 = Regex.IsMatch(nickname, "[\\u00E4\\u00E5\\u00F6\\u00E6\\u00F8]", RegexOptions.IgnoreCase);
					bool flag28 = Regex.IsMatch(nickname, "[\\u010D\\u011B\\u0148\\u0159\\u0161\\u0165\\u016F\\u017E]", RegexOptions.IgnoreCase);
					bool flag29 = Regex.IsMatch(nickname, "[\\u0103\\u00E2\\u00EE\\u0219\\u021B]", RegexOptions.IgnoreCase);
					bool flag30 = Regex.IsMatch(nickname, "[\\u00E1\\u00E9\\u00ED\\u00F3\\u00F6\\u0151\\u00FA\\u00FC\\u0171]", RegexOptions.IgnoreCase);
					bool flag31 = SpanishPattern.IsMatch(nickname);
					bool flag32 = GermanPattern.IsMatch(nickname);
					bool flag33 = FrenchPattern.IsMatch(nickname);
					bool num6 = VietnamesePattern.IsMatch(nickname);
					bool flag34 = IndonesianPattern.IsMatch(nickname);
					bool flag35 = TurkishPattern.IsMatch(nickname);
					bool flag36 = PolishPattern.IsMatch(nickname);
					bool flag37 = RussianNamePattern.IsMatch(nickname);
					bool flag38 = ArabicNamePattern.IsMatch(nickname);
					if (num6 || flag24)
					{
						nicknameAnalysisResult.Probabilities["Vietnam"] = 78f;
						nicknameAnalysisResult.Probabilities["Other"] = 22f;
						nicknameAnalysisResult.PrimaryRegion = "Vietnam";
						nicknameAnalysisResult.Confidence = 78f;
						nicknameAnalysisResult.AnalysisMethod = "Vietnamese pattern/diacritics";
						nicknameAnalysisResult.CountryCode = "VN";
						return nicknameAnalysisResult;
					}
					if (flag25 || flag35)
					{
						float num7 = ((flag25 && flag35) ? 80f : 72f);
						nicknameAnalysisResult.Probabilities["Turkey"] = num7;
						nicknameAnalysisResult.Probabilities["Other"] = 100f - num7;
						nicknameAnalysisResult.PrimaryRegion = "Turkey";
						nicknameAnalysisResult.Confidence = num7;
						nicknameAnalysisResult.AnalysisMethod = "Turkish pattern/chars";
						nicknameAnalysisResult.CountryCode = "TR";
						return nicknameAnalysisResult;
					}
					if (flag26 || flag36)
					{
						float num8 = ((flag26 && flag36) ? 78f : 65f);
						nicknameAnalysisResult.Probabilities["Poland"] = num8;
						nicknameAnalysisResult.Probabilities["Czech"] = 5f;
						nicknameAnalysisResult.Probabilities["Other"] = 100f - num8 - 5f;
						nicknameAnalysisResult.PrimaryRegion = "Poland";
						nicknameAnalysisResult.Confidence = num8;
						nicknameAnalysisResult.AnalysisMethod = "Polish pattern/chars";
						nicknameAnalysisResult.CountryCode = "PL";
						return nicknameAnalysisResult;
					}
					if (flag28)
					{
						nicknameAnalysisResult.Probabilities["Czech"] = 70f;
						nicknameAnalysisResult.Probabilities["Slovakia"] = 12f;
						nicknameAnalysisResult.Probabilities["Other"] = 18f;
						nicknameAnalysisResult.PrimaryRegion = "Czech";
						nicknameAnalysisResult.Confidence = 70f;
						nicknameAnalysisResult.AnalysisMethod = "Czech characters";
						nicknameAnalysisResult.CountryCode = "CZ";
						return nicknameAnalysisResult;
					}
					if (flag29)
					{
						nicknameAnalysisResult.Probabilities["Romania"] = 70f;
						nicknameAnalysisResult.Probabilities["Moldova"] = 8f;
						nicknameAnalysisResult.Probabilities["Other"] = 22f;
						nicknameAnalysisResult.PrimaryRegion = "Romania";
						nicknameAnalysisResult.Confidence = 70f;
						nicknameAnalysisResult.AnalysisMethod = "Romanian characters";
						nicknameAnalysisResult.CountryCode = "RO";
						return nicknameAnalysisResult;
					}
					if (flag30 && !flag32)
					{
						nicknameAnalysisResult.Probabilities["Hungary"] = 60f;
						nicknameAnalysisResult.Probabilities["Germany"] = 10f;
						nicknameAnalysisResult.Probabilities["Other"] = 30f;
						nicknameAnalysisResult.PrimaryRegion = "Hungary";
						nicknameAnalysisResult.Confidence = 60f;
						nicknameAnalysisResult.AnalysisMethod = "Hungarian characters";
						nicknameAnalysisResult.CountryCode = "HU";
						return nicknameAnalysisResult;
					}
					if (flag27)
					{
						nicknameAnalysisResult.Probabilities["Nordic"] = 55f;
						nicknameAnalysisResult.Probabilities["Germany"] = 15f;
						nicknameAnalysisResult.Probabilities["Other"] = 30f;
						nicknameAnalysisResult.PrimaryRegion = "Nordic";
						nicknameAnalysisResult.Confidence = 55f;
						nicknameAnalysisResult.AnalysisMethod = "Scandinavian characters";
						nicknameAnalysisResult.CountryCode = "SE";
						return nicknameAnalysisResult;
					}
					if (flag34)
					{
						nicknameAnalysisResult.Probabilities["Indonesia"] = 65f;
						nicknameAnalysisResult.Probabilities["Malaysia"] = 10f;
						nicknameAnalysisResult.Probabilities["Other"] = 25f;
						nicknameAnalysisResult.PrimaryRegion = "Indonesia";
						nicknameAnalysisResult.Confidence = 65f;
						nicknameAnalysisResult.AnalysisMethod = "Indonesian name pattern";
						nicknameAnalysisResult.CountryCode = "ID";
						return nicknameAnalysisResult;
					}
					if (flag38)
					{
						nicknameAnalysisResult.Probabilities["Middle East"] = 50f;
						nicknameAnalysisResult.Probabilities["North Africa"] = 20f;
						nicknameAnalysisResult.Probabilities["Other"] = 30f;
						nicknameAnalysisResult.PrimaryRegion = "Middle East";
						nicknameAnalysisResult.Confidence = 50f;
						nicknameAnalysisResult.AnalysisMethod = "Arabic name (Latin)";
						nicknameAnalysisResult.CountryCode = "SA";
						return nicknameAnalysisResult;
					}
					if (flag37)
					{
						nicknameAnalysisResult.Probabilities["Russia"] = 45f;
						nicknameAnalysisResult.Probabilities["Other CIS"] = 15f;
						nicknameAnalysisResult.Probabilities["Other"] = 40f;
						nicknameAnalysisResult.PrimaryRegion = "Russia";
						nicknameAnalysisResult.Confidence = 45f;
						nicknameAnalysisResult.AnalysisMethod = "Russian name (Latin)";
						nicknameAnalysisResult.CountryCode = "RU";
						return nicknameAnalysisResult;
					}
					if (flag31)
					{
						nicknameAnalysisResult.Probabilities["Latin America"] = 35f;
						nicknameAnalysisResult.Probabilities["Spain"] = 25f;
						nicknameAnalysisResult.Probabilities["Other"] = 40f;
						nicknameAnalysisResult.PrimaryRegion = "Latin America";
						nicknameAnalysisResult.Confidence = 35f;
						nicknameAnalysisResult.AnalysisMethod = "Spanish pattern";
						nicknameAnalysisResult.CountryCode = "MX";
						return nicknameAnalysisResult;
					}
					if (flag32)
					{
						nicknameAnalysisResult.Probabilities["Germany"] = 45f;
						nicknameAnalysisResult.Probabilities["Austria"] = 12f;
						nicknameAnalysisResult.Probabilities["Nordic"] = 8f;
						nicknameAnalysisResult.Probabilities["Other"] = 35f;
						nicknameAnalysisResult.PrimaryRegion = "Germany";
						nicknameAnalysisResult.Confidence = 45f;
						nicknameAnalysisResult.AnalysisMethod = "German pattern";
						nicknameAnalysisResult.CountryCode = "DE";
						return nicknameAnalysisResult;
					}
					if (flag33)
					{
						nicknameAnalysisResult.Probabilities["France"] = 40f;
						nicknameAnalysisResult.Probabilities["Belgium"] = 8f;
						nicknameAnalysisResult.Probabilities["Other"] = 52f;
						nicknameAnalysisResult.PrimaryRegion = "France";
						nicknameAnalysisResult.Confidence = 40f;
						nicknameAnalysisResult.AnalysisMethod = "French pattern";
						nicknameAnalysisResult.CountryCode = "FR";
						return nicknameAnalysisResult;
					}
					if (Regex.IsMatch(nickname, "[\\u00E3\\u00F5\\u00E7\\u00E1\\u00E9\\u00ED\\u00F3\\u00FA]", RegexOptions.IgnoreCase))
					{
						if (text.Contains("br") || text.Contains("brasil"))
						{
							nicknameAnalysisResult.Probabilities["Brazil"] = 70f;
							nicknameAnalysisResult.Probabilities["Portugal"] = 10f;
							nicknameAnalysisResult.Probabilities["Other"] = 20f;
							nicknameAnalysisResult.PrimaryRegion = "Brazil";
							nicknameAnalysisResult.Confidence = 70f;
							nicknameAnalysisResult.AnalysisMethod = "Portuguese + BR hint";
							nicknameAnalysisResult.CountryCode = "BR";
						}
						else
						{
							nicknameAnalysisResult.Probabilities["Brazil"] = 45f;
							nicknameAnalysisResult.Probabilities["Portugal"] = 20f;
							nicknameAnalysisResult.Probabilities["Other"] = 35f;
							nicknameAnalysisResult.PrimaryRegion = "Brazil";
							nicknameAnalysisResult.Confidence = 45f;
							nicknameAnalysisResult.AnalysisMethod = "Portuguese characters";
							nicknameAnalysisResult.CountryCode = "BR";
						}
						return nicknameAnalysisResult;
					}
					nicknameAnalysisResult.Probabilities["Western Europe"] = 18f;
					nicknameAnalysisResult.Probabilities["North America"] = 18f;
					nicknameAnalysisResult.Probabilities["Latin America"] = 12f;
					nicknameAnalysisResult.Probabilities["Southeast Asia"] = 10f;
					nicknameAnalysisResult.Probabilities["Eastern Europe"] = 8f;
					nicknameAnalysisResult.Probabilities["Other"] = 34f;
					nicknameAnalysisResult.PrimaryRegion = "Western Europe";
					nicknameAnalysisResult.Confidence = 18f;
					nicknameAnalysisResult.AnalysisMethod = "Latin script (generic)";
					nicknameAnalysisResult.CountryCode = null;
					return nicknameAnalysisResult;
				}
				nicknameAnalysisResult.Probabilities["Unknown"] = 100f;
				nicknameAnalysisResult.PrimaryRegion = "Unknown";
				nicknameAnalysisResult.Confidence = 0f;
				nicknameAnalysisResult.AnalysisMethod = "Unrecognizable";
				return nicknameAnalysisResult;
			}
		}
		public class NicknameAnalysisResult
		{
			public Dictionary<string, float> Probabilities { get; set; } = new Dictionary<string, float>();

			public string PrimaryRegion { get; set; } = "Unknown";

			public float Confidence { get; set; }

			public string AnalysisMethod { get; set; }

			public string CountryCode { get; set; }
		}
		public static class RegionAnalyzer
		{
			public static async Task<RegionResult> AnalyzeRegion(string ownerName, ulong ownerSteamId)
			{
				RegionResult result = new RegionResult();
				if (string.IsNullOrEmpty(ownerName) && ownerSteamId == 0L)
				{
					result.PrimaryRegion = "Unknown";
					result.Confidence = 0f;
					result.Source = "No data";
					return result;
				}
				string value = PluginConfig.SteamWebApiKey.Value;
				if (!string.IsNullOrEmpty(value) && ownerSteamId != 0L)
				{
					try
					{
						string text = await SteamWebQuery.GetCountryFromWebApi(ownerSteamId.ToString(), value);
						if (!string.IsNullOrEmpty(text))
						{
							result.Source = "Steam Web API";
							result.CountryCode = text;
							result.DisplayCode = text;
							result.PrimaryRegion = CountryCodeToRegion(text);
							result.Confidence = 95f;
							result.Probabilities = BuildProbabilityMap(result.PrimaryRegion, 95f);
							RegionCache.Set(ownerSteamId, result);
							return result;
						}
					}
					catch (Exception ex)
					{
						Plugin.LogSource.LogWarning((object)("[TAIGU] Steam Web API error: " + ex.Message));
					}
				}
				if (PluginConfig.EnableCommunityQuery.Value && ownerSteamId != 0L)
				{
					try
					{
						string text = await SteamWebQuery.GetCountryFromCommunityPage(ownerSteamId.ToString());
						if (!string.IsNullOrEmpty(text))
						{
							result.Source = "Steam Community";
							result.CountryCode = text;
							result.DisplayCode = text;
							result.PrimaryRegion = CountryCodeToRegion(text);
							result.Confidence = 88f;
							result.Probabilities = BuildProbabilityMap(result.PrimaryRegion, 88f);
							RegionCache.Set(ownerSteamId, result);
							return result;
						}
					}
					catch (Exception ex2)
					{
						Plugin.LogSource.LogWarning((object)("[TAIGU] Steam Community query error: " + ex2.Message));
					}
				}
				if (PluginConfig.EnableXmlQuery.Value && ownerSteamId != 0L)
				{
					try
					{
						string text = await SteamWebQuery.GetCountryFromXml(ownerSteamId.ToString());
						if (!string.IsNullOrEmpty(text))
						{
							result.Source = "Steam XML";
							result.CountryCode = text;
							result.DisplayCode = text;
							result.PrimaryRegion = CountryCodeToRegion(text);
							result.Confidence = 85f;
							result.Probabilities = BuildProbabilityMap(result.PrimaryRegion, 85f);
							RegionCache.Set(ownerSteamId, result);
							return result;
						}
					}
					catch (Exception ex3)
					{
						Plugin.LogSource.LogWarning((object)("[TAIGU] Steam XML query error: " + ex3.Message));
					}
				}
				if (PluginConfig.EnableNicknameAnalysis.Value && !string.IsNullOrEmpty(ownerName))
				{
					NicknameAnalysisResult nicknameAnalysisResult = NicknameAnalyzer.Analyze(ownerName);
					if (nicknameAnalysisResult.Probabilities.Count > 0)
					{
						result.PrimaryRegion = nicknameAnalysisResult.PrimaryRegion;
						result.Confidence = nicknameAnalysisResult.Confidence;
						result.Probabilities = nicknameAnalysisResult.Probabilities;
						result.Source = "Nickname Analysis";
						result.CountryCode = nicknameAnalysisResult.CountryCode ?? RegionToCountryCode(nicknameAnalysisResult.PrimaryRegion);
						result.DisplayCode = nicknameAnalysisResult.CountryCode;
						RegionCache.Set(ownerSteamId, result);
						return result;
					}
				}
				result.PrimaryRegion = "Unknown";
				result.Confidence = 0f;
				result.Source = "No data";
				result.Probabilities = new Dictionary<string, float> { { "Unknown", 100f } };
				return result;
			}

			public static RegionResult GetQuickAnalysis(string ownerName)
			{
				RegionResult regionResult = new RegionResult();
				if (!string.IsNullOrEmpty(ownerName))
				{
					NicknameAnalysisResult nicknameAnalysisResult = NicknameAnalyzer.Analyze(ownerName);
					if (nicknameAnalysisResult.Probabilities.Count > 0)
					{
						regionResult.PrimaryRegion = nicknameAnalysisResult.PrimaryRegion;
						regionResult.Confidence = nicknameAnalysisResult.Confidence;
						regionResult.Probabilities = nicknameAnalysisResult.Probabilities;
						regionResult.Source = "Nickname Analysis (Quick)";
						regionResult.CountryCode = nicknameAnalysisResult.CountryCode ?? RegionToCountryCode(nicknameAnalysisResult.PrimaryRegion);
						regionResult.DisplayCode = nicknameAnalysisResult.CountryCode;
						return regionResult;
					}
				}
				regionResult.PrimaryRegion = "Unknown";
				regionResult.Confidence = 0f;
				regionResult.Source = "No data";
				regionResult.Probabilities = new Dictionary<string, float> { { "Unknown", 100f } };
				return regionResult;
			}

			public static string CountryCodeToRegion(string code)
			{
				if (string.IsNullOrEmpty(code))
				{
					return "Unknown";
				}
				code = code.ToUpper();
				switch (code)
				{
				case "CN":
					return "China";
				case "TW":
				case "HK":
				case "MO":
					return "China (TW/HK/MO)";
				case "JP":
					return "Japan";
				case "KR":
				case "KP":
					return "Korea";
				case "MN":
					return "Mongolia";
				case "VN":
					return "Vietnam";
				case "TH":
					return "Thailand";
				case "ID":
					return "Indonesia";
				case "PH":
					return "Philippines";
				case "MY":
					return "Malaysia";
				case "SG":
					return "Singapore";
				case "KH":
					return "Cambodia";
				case "LA":
					return "Laos";
				case "MM":
					return "Myanmar";
				case "BN":
					return "Brunei";
				case "TL":
					return "Timor-Leste";
				case "IN":
					return "India";
				case "PK":
					return "Pakistan";
				case "BD":
					return "Bangladesh";
				case "LK":
					return "Sri Lanka";
				case "NP":
					return "Nepal";
				case "BT":
					return "Bhutan";
				case "MV":
					return "Maldives";
				case "KZ":
					return "Kazakhstan";
				case "UZ":
					return "Uzbekistan";
				case "TM":
					return "Turkmenistan";
				case "KG":
					return "Kyrgyzstan";
				case "TJ":
					return "Tajikistan";
				case "TR":
					return "Turkey";
				case "SA":
					return "Saudi Arabia";
				case "AE":
					return "UAE";
				case "IR":
					return "Iran";
				case "IQ":
					return "Iraq";
				case "IL":
					return "Israel";
				case "JO":
					return "Jordan";
				case "LB":
					return "Lebanon";
				case "SY":
					return "Syria";
				case "YE":
					return "Yemen";
				case "OM":
					return "Oman";
				case "QA":
					return "Qatar";
				case "KW":
					return "Kuwait";
				case "BH":
					return "Bahrain";
				case "CY":
					return "Cyprus";
				case "GE":
					return "Georgia";
				case "AM":
					return "Armenia";
				case "AZ":
					return "Azerbaijan";
				case "EG":
					return "Egypt";
				case "MA":
					return "Morocco";
				case "DZ":
					return "Algeria";
				case "TN":
					return "Tunisia";
				case "LY":
					return "Libya";
				case "SD":
					return "Sudan";
				case "ZA":
					return "South Africa";
				case "NG":
					return "Nigeria";
				case "KE":
					return "Kenya";
				case "ET":
					return "Ethiopia";
				case "GH":
					return "Ghana";
				case "TZ":
					return "Tanzania";
				case "UG":
					return "Uganda";
				case "ER":
					return "Eritrea";
				case "RU":
					return "Russia";
				case "UA":
					return "Ukraine";
				case "BY":
					return "Belarus";
				case "MD":
					return "Moldova";
				case "PL":
					return "Poland";
				case "CZ":
					return "Czech";
				case "SK":
					return "Slovakia";
				case "HU":
					return "Hungary";
				case "RO":
					return "Romania";
				case "BG":
					return "Bulgaria";
				case "HR":
					return "Croatia";
				case "RS":
					return "Serbia";
				case "BA":
					return "Bosnia";
				case "SI":
					return "Slovenia";
				case "MK":
					return "North Macedonia";
				case "AL":
					return "Albania";
				case "ME":
					return "Montenegro";
				case "XK":
					return "Kosovo";
				case "LT":
				case "LV":
				case "EE":
					return "Baltics";
				case "DE":
					return "Germany";
				case "AT":
					return "Austria";
				case "CH":
					return "Switzerland";
				case "FR":
					return "France";
				case "IT":
					return "Italy";
				case "ES":
				case "PT":
					return "Iberia";
				case "NL":
				case "BE":
					return "Benelux";
				case "GB":
				case "IE":
					return "UK/Ireland";
				case "LU":
					return "Luxembourg";
				case "MC":
					return "Monaco";
				case "SE":
					return "Sweden";
				case "NO":
					return "Norway";
				case "DK":
					return "Denmark";
				case "FI":
					return "Finland";
				case "IS":
					return "Iceland";
				case "GR":
					return "Greece";
				case "MT":
					return "Malta";
				case "US":
				case "CA":
					return "North America";
				case "MX":
					return "Mexico";
				case "BR":
					return "Brazil";
				case "AR":
					return "Argentina";
				case "CL":
					return "Chile";
				case "CO":
					return "Colombia";
				case "PE":
					return "Peru";
				case "VE":
					return "Venezuela";
				case "EC":
					return "Ecuador";
				case "BO":
					return "Bolivia";
				case "PY":
					return "Paraguay";
				case "UY":
					return "Uruguay";
				case "PA":
					return "Panama";
				case "CR":
					return "Costa Rica";
				case "GT":
					return "Guatemala";
				case "HN":
					return "Honduras";
				case "SV":
					return "El Salvador";
				case "NI":
					return "Nicaragua";
				case "CU":
					return "Cuba";
				case "DO":
					return "Dominican Republic";
				case "PR":
					return "Puerto Rico";
				case "JM":
					return "Jamaica";
				case "TT":
					return "Trinidad";
				case "AU":
				case "NZ":
					return "Oceania";
				case "FJ":
					return "Fiji";
				case "PG":
					return "Papua New Guinea";
				default:
					return code;
				}
			}

			public static string RegionToCountryCode(string region)
			{
				if (string.IsNullOrEmpty(region))
				{
					return null;
				}
				return region switch
				{
					"China" => "CN", 
					"China (TW/HK/MO)" => "TW", 
					"Japan" => "JP", 
					"Korea" => "KR", 
					"Vietnam" => "VN", 
					"Thailand" => "TH", 
					"Indonesia" => "ID", 
					"Philippines" => "PH", 
					"Malaysia" => "MY", 
					"Singapore" => "SG", 
					"Cambodia" => "KH", 
					"Laos" => "LA", 
					"Myanmar" => "MM", 
					"India" => "IN", 
					"Pakistan" => "PK", 
					"Bangladesh" => "BD", 
					"Sri Lanka" => "LK", 
					"Russia" => "RU", 
					"Ukraine" => "UA", 
					"Belarus" => "BY", 
					"Kazakhstan" => "KZ", 
					"Turkey" => "TR", 
					"Saudi Arabia" => "SA", 
					"UAE" => "AE", 
					"Iran" => "IR", 
					"Egypt" => "EG", 
					"Israel" => "IL", 
					"Middle East" => "SA", 
					"North Africa" => "EG", 
					"Poland" => "PL", 
					"Czech" => "CZ", 
					"Slovakia" => "SK", 
					"Hungary" => "HU", 
					"Romania" => "RO", 
					"Bulgaria" => "BG", 
					"Croatia" => "HR", 
					"Serbia" => "RS", 
					"Greece" => "GR", 
					"Germany" => "DE", 
					"France" => "FR", 
					"Italy" => "IT", 
					"Iberia" => "ES", 
					"Benelux" => "NL", 
					"UK/Ireland" => "GB", 
					"Nordic" => "SE", 
					"Sweden" => "SE", 
					"Norway" => "NO", 
					"Denmark" => "DK", 
					"Finland" => "FI", 
					"North America" => "US", 
					"Brazil" => "BR", 
					"Mexico" => "MX", 
					"Argentina" => "AR", 
					"Latin America" => "MX", 
					"Oceania" => "AU", 
					"South Africa" => "ZA", 
					"Ethiopia" => "ET", 
					"Mongolia" => "MN", 
					"Georgia" => "GE", 
					"Armenia" => "AM", 
					_ => null, 
				};
			}

			public static Dictionary<string, float> BuildProbabilityMap(string primaryRegion, float confidence)
			{
				Dictionary<string, float> dictionary = new Dictionary<string, float>();
				dictionary[primaryRegion] = confidence;
				float num = 100f - confidence;
				if (num > 0f)
				{
					dictionary["Other"] = num;
				}
				return dictionary;
			}
		}
		public class RegionResult
		{
			private string _displayCode;

			public string PrimaryRegion { get; set; } = "Unknown";

			public float Confidence { get; set; }

			public Dictionary<string, float> Probabilities { get; set; } = new Dictionary<string, float>();

			public string CountryCode { get; set; }

			public string DisplayCode
			{
				get
				{
					if (!string.IsNullOrEmpty(_displayCode))
					{
						return _displayCode;
					}
					if (!string.IsNullOrEmpty(CountryCode))
					{
						return CountryCode;
					}
					return GetRegionCode(PrimaryRegion);
				}
				set
				{
					_displayCode = value;
				}
			}

			public string Source { get; set; } = "None";

			public string DisplayName { get; set; }

			public ulong SteamId64 { get; set; }

			public DateTime Timestamp { get; set; } = DateTime.UtcNow;

			public bool IsPending { get; set; }

			public string DisplayTag
			{
				get
				{
					if (IsPending)
					{
						return "[...] Analyzing...";
					}
					if (string.IsNullOrEmpty(PrimaryRegion) || PrimaryRegion == "Unknown")
					{
						return "[?] Unknown";
					}
					string arg = ((!string.IsNullOrEmpty(CountryCode)) ? CountryCode : GetRegionCode(PrimaryRegion));
					return $"[{arg}] {PrimaryRegion} {Confidence:F0}%";
				}
			}

			public string DetailText
			{
				get
				{
					if (Probabilities == null || Probabilities.Count == 0)
					{
						return "No data available";
					}
					IEnumerable<string> values = from x in Probabilities.OrderByDescending((KeyValuePair<string, float> x) => x.Value).Take(5)
						select $"  {x.Key}: {x.Value:F1}%";
					return "Region Analysis (" + Source + "):\n" + string.Join("\n", values);
				}
			}

			private static string GetRegionCode(string region)
			{
				return region switch
				{
					"China" => "CN", 
					"Japan" => "JP", 
					"Korea" => "KR", 
					"Russia" => "RU", 
					"Ukraine" => "UA", 
					"Thailand" => "TH", 
					"India" => "IN", 
					"Vietnam" => "VN", 
					"Turkey" => "TR", 
					"Brazil" => "BR", 
					"Germany" => "DE", 
					"France" => "FR", 
					"Greece" => "GR", 
					"Israel" => "IL", 
					"Armenia" => "AM", 
					"Georgia" => "GE", 
					"Poland" => "PL", 
					"Nordic" => "NORD", 
					"Middle East" => "ME", 
					"North Africa" => "NAF", 
					"Latin America" => "LATAM", 
					"North America" => "NAM", 
					"Western Europe" => "WEST", 
					"Southeast Asia" => "SEA", 
					"Eastern Europe" => "EE", 
					"Oceania" => "OC", 
					"Other CIS" => "EE", 
					"Balkans" => "BALK", 
					"Spain" => "ES", 
					"Italy" => "IT", 
					"Portugal" => "PT", 
					"Austria" => "AT", 
					"Belgium" => "BE", 
					"Cyprus" => "CY", 
					"Nepal" => "NP", 
					"Central Asia" => "CAS", 
					_ => "?", 
				};
			}
		}
		public static class SteamWebQuery
		{
			public class WebQueryResult
			{
				public string CountryCode;

				public string Source;

				public float Confidence;
			}

			private static HttpClient _httpClient;

			private static HttpClient GetClient()
			{
				if (_httpClient == null)
				{
					_httpClient = new HttpClient();
					_httpClient.Timeout = TimeSpan.FromSeconds(8.0);
					_httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) LethalCompanyRegionTag/1.0");
				}
				return _httpClient;
			}

			public static async Task<string> GetCountryFromWebApi(string steamId64, string apiKey)
			{
				if (string.IsNullOrEmpty(apiKey) || string.IsNullOrEmpty(steamId64))
				{
					return null;
				}
				try
				{
					string requestUri = "https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=" + apiKey + "&steamids=" + steamId64;
					Match match = Regex.Match(await GetClient().GetStringAsync(requestUri), "\"loccountrycode\"\\s*:\\s*\"([^\"]+)\"");
					if (match.Success)
					{
						return match.Groups[1].Value.ToUpper();
					}
				}
				catch (Exception ex)
				{
					Plugin.LogSource.LogWarning((object)("[TAIGU] Steam Web API query failed: " + ex.Message));
				}
				return null;
			}

			public static async Task<string> GetCountryFromCommunityPage(string steamId64)
			{
				if (string.IsNullOrEmpty(steamId64))
				{
					return null;
				}
				try
				{
					string requestUri = "https://steamcommunity.com/profiles/" + steamId64 + "/";
					string input = await GetClient().GetStringAsync(requestUri);
					Match match = Regex.Match(input, "flags/(\\w{2})\\.png");
					if (match.Success)
					{
						return match.Groups[1].Value.ToUpper();
					}
					match = Regex.Match(input, "\"locationcountrycode\"\\s*:\\s*\"([^\"]+)\"");
					if (match.Success)