Decompiled source of SullysAutoPinner v1.4.0

BepInEx/plugins/SullysAutoPinner.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using SimpleJSON;
using Splatform;
using SullysAutoPinner;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SullysAutoPinner")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SullysAutoPinner")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("53eb7460-cf9b-4412-b6f9-0c7191329f58")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.2.0.0")]
public class LocalizationManager
{
	private readonly Dictionary<string, string> _translations = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

	private readonly HashSet<string> _missingKeys = new HashSet<string>();

	private readonly ManualLogSource _logger;

	private readonly string _langCode;

	private readonly string _translationsFolder;

	private const string FallbackLang = "en";

	private string _currentLanguage = "";

	public LocalizationManager(ManualLogSource logger, string langCode)
	{
		_logger = logger;
		_langCode = (string.IsNullOrWhiteSpace(langCode) ? "en" : langCode.ToLowerInvariant());
		_translationsFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles", "Translations");
		LoadTranslations("en");
		if (_langCode != "en")
		{
			LoadTranslations(_langCode);
		}
	}

	public void Reload(string newLanguageCode)
	{
		if (!_currentLanguage.Equals(newLanguageCode, StringComparison.OrdinalIgnoreCase))
		{
			_currentLanguage = newLanguageCode;
			LoadTranslations(newLanguageCode);
		}
	}

	private void LoadTranslations(string lang)
	{
		try
		{
			string text = Path.Combine(_translationsFolder, lang + ".json");
			if (!File.Exists(text))
			{
				_logger.LogWarning((object)("[LocalizationManager] Translation file not found: " + text));
				return;
			}
			JSONNode jSONNode = JSON.Parse(File.ReadAllText(text));
			if (jSONNode == null || !jSONNode.IsObject)
			{
				_logger.LogWarning((object)("[LocalizationManager] Failed to parse " + text));
				return;
			}
			JSONNode.Enumerator enumerator = jSONNode.AsObject.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<string, JSONNode> current = enumerator.Current;
				_translations[current.Key.ToUpperInvariant()] = current.Value.Value;
			}
			_logger.LogWarning((object)$"[LocalizationManager] Loaded {jSONNode.Count} entries from {lang}.json");
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("[LocalizationManager] Error loading " + lang + ".json: " + ex.Message));
		}
	}

	public string GetLabel(string key)
	{
		if (string.IsNullOrWhiteSpace(key))
		{
			return key;
		}
		if (_translations.TryGetValue(key.ToUpperInvariant(), out var value))
		{
			return value;
		}
		if (_missingKeys.Add(key))
		{
			_logger.LogWarning((object)("[LocalizationManager] Missing translation for label: " + key));
		}
		return key;
	}

	public static void EnsureBaseLanguageFiles(ManualLogSource logger)
	{
		string text = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles", "Translations");
		Directory.CreateDirectory(text);
		foreach (KeyValuePair<string, Dictionary<string, string>> defaultTranslation in GetDefaultTranslations())
		{
			string key = defaultTranslation.Key;
			string path = Path.Combine(text, key + ".json");
			if (File.Exists(path))
			{
				continue;
			}
			try
			{
				JSONObject jSONObject = new JSONObject();
				foreach (KeyValuePair<string, string> item in defaultTranslation.Value)
				{
					jSONObject[item.Key] = item.Value;
				}
				File.WriteAllText(path, jSONObject.ToString(2));
				logger.LogWarning((object)("[LocalizationManager] Created default translation file: " + key + ".json"));
			}
			catch (Exception ex)
			{
				logger.LogWarning((object)("[LocalizationManager] Failed to write " + key + ".json: " + ex.Message));
			}
		}
	}

	private static Dictionary<string, Dictionary<string, string>> GetDefaultTranslations()
	{
		return new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			["en"] = LocalizationTranslations.EN,
			["ru"] = LocalizationTranslations.RU,
			["fr"] = LocalizationTranslations.FR,
			["de"] = LocalizationTranslations.DE,
			["es"] = LocalizationTranslations.ES,
			["pl"] = LocalizationTranslations.PL,
			["zh"] = LocalizationTranslations.ZH,
			["pt"] = LocalizationTranslations.PT
		};
	}
}
public static class LocalizationTranslations
{
	public static readonly Dictionary<string, string> EN = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abomination",
		["CRYPT"] = "Crypt",
		["DRAUGRSPAWNER"] = "Draugr Spawner",
		["DVERGERTHINGS"] = "Dvergr Remains",
		["DWARFSPAWNER"] = "Greydwarf Nest",
		["FIRE"] = "Campfire",
		["FLAX"] = "Flax",
		["IRON"] = "Iron",
		["MUDPILE"] = "Mudpile",
		["METEORITE"] = "Meteorite",
		["MAGECAPS"] = "Magecaps",
		["MARKER"] = "Marker",
		["MUSHROOMS"] = "Mushrooms",
		["OBSIDIAN"] = "Obsidian",
		["SEEDS"] = "Seeds",
		["SILVER"] = "Silver",
		["SKELETON"] = "Skeleton",
		["SMOKEPUFFS"] = "Smoke Puffs",
		["TAR"] = "Tar Pit",
		["THISTLE"] = "Thistle",
		["TOTEM"] = "Fuling Totem",
		["TROLLCAVE"] = "Troll Cave",
		["TREASURE"] = "Buried Treasure",
		["VOLTUREEGG"] = "Vulture Egg",
		["YPCONES"] = "Yggdrasil Pine Cones",
		["JOTUNNPUFFS"] = "Jotunn Puffs",
		["RASPBERRIES"] = "Raspberries",
		["BLUEBERRIES"] = "Blueberries",
		["CLOUDBERRIES"] = "Cloudberries",
		["BARLEY"] = "Barley",
		["CLOTH"] = "Cloth",
		["SHIPWRECKCHEST"] = "Shipwreck Chest",
		["GIANTSWORD"] = "Giant Sword",
		["GIANTRIBS"] = "Giant Ribs",
		["GIANTSKULL"] = "Giant Skull",
		["GIANTBRAIN"] = "Giant Brain",
		["EXCAVATION"] = "Excavation Site",
		["LANTERN"] = "Lantern",
		["ASHLANDPOTGREEN"] = "Ashland Pot (Green)",
		["ASHLANDPOTRED"] = "Ashland Pot (Red)",
		["SEEKERBRUTE"] = "Seeker Brute",
		["BONEMAWSERPENT"] = "Bonemaw Serpent",
		["COPPER"] = "Copper",
		["DRAGONEGG"] = "Dragon Egg"
	};

	public static readonly Dictionary<string, string> RU = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Мерзость",
		["CRYPT"] = "Крипта",
		["DRAUGRSPAWNER"] = "Портал драугров",
		["DVERGERTHINGS"] = "Останки двергров",
		["DWARFSPAWNER"] = "Гнездо серого карлика",
		["FIRE"] = "Костер",
		["FLAX"] = "Лён",
		["IRON"] = "Железо",
		["MUDPILE"] = "Грязевая куча",
		["METEORITE"] = "Метеорит",
		["MAGECAPS"] = "Волшебные шляпки",
		["MARKER"] = "Маркер",
		["MUSHROOMS"] = "Грибы",
		["OBSIDIAN"] = "Обсидиан",
		["SEEDS"] = "Семена",
		["SILVER"] = "Серебро",
		["SKELETON"] = "Скелет",
		["SMOKEPUFFS"] = "Клубы дыма",
		["TAR"] = "Смоляная яма",
		["THISTLE"] = "Чертополох",
		["TOTEM"] = "Тотем фулингов",
		["TROLLCAVE"] = "Пещера тролля",
		["TREASURE"] = "Сокровище",
		["VOLTUREEGG"] = "Яйцо стервятника",
		["YPCONES"] = "Шишки Иггдрасиля",
		["JOTUNNPUFFS"] = "Пух Йотуна",
		["RASPBERRIES"] = "Малина",
		["BLUEBERRIES"] = "Черника",
		["CLOUDBERRIES"] = "Морошка",
		["BARLEY"] = "Ячмень",
		["CLOTH"] = "Ткань",
		["SHIPWRECKCHEST"] = "Сундук кораблекрушения",
		["GIANTSWORD"] = "Меч великана",
		["GIANTRIBS"] = "Рёбра великана",
		["GIANTSKULL"] = "Череп великана",
		["GIANTBRAIN"] = "Мозг великана",
		["EXCAVATION"] = "Место раскопок",
		["LANTERN"] = "Фонарь",
		["ASHLANDPOTGREEN"] = "Пот Зелёный",
		["ASHLANDPOTRED"] = "Пот Красный",
		["SEEKERBRUTE"] = "Ищущий Враг",
		["BONEMAWSERPENT"] = "Костеглот",
		["COPPER"] = "Медь",
		["DRAGONEGG"] = "Яйцо дракона"
	};

	public static readonly Dictionary<string, string> FR = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abomination",
		["CRYPT"] = "Crypte",
		["DRAUGRSPAWNER"] = "Portail Draugr",
		["DVERGERTHINGS"] = "Restes de Dvergr",
		["DWARFSPAWNER"] = "Nid de nain gris",
		["FIRE"] = "Feu de camp",
		["FLAX"] = "Lin",
		["IRON"] = "Fer",
		["MUDPILE"] = "Tas de boue",
		["METEORITE"] = "Météorite",
		["MAGECAPS"] = "Chapeaux de mage",
		["MARKER"] = "Marqueur",
		["MUSHROOMS"] = "Champignons",
		["OBSIDIAN"] = "Obsidienne",
		["SEEDS"] = "Graines",
		["SILVER"] = "Argent",
		["SKELETON"] = "Squelette",
		["SMOKEPUFFS"] = "Nuages de fumée",
		["TAR"] = "Fosse à goudron",
		["THISTLE"] = "Chardon",
		["TOTEM"] = "Totem de Fuling",
		["TROLLCAVE"] = "Grotte du troll",
		["TREASURE"] = "Trésor",
		["VOLTUREEGG"] = "Œuf de vautour",
		["YPCONES"] = "Cônes d’Yggdrasil",
		["JOTUNNPUFFS"] = "Poussières de Jotunn",
		["RASPBERRIES"] = "Framboises",
		["BLUEBERRIES"] = "Myrtilles",
		["CLOUDBERRIES"] = "Plaquebières",
		["BARLEY"] = "Orge",
		["CLOTH"] = "Tissu",
		["SHIPWRECKCHEST"] = "Coffre d'épave",
		["GIANTSWORD"] = "Épée de géant",
		["GIANTRIBS"] = "Côtes de géant",
		["GIANTSKULL"] = "Crâne de géant",
		["GIANTBRAIN"] = "Cerveau de géant",
		["EXCAVATION"] = "Site d’excavation",
		["LANTERN"] = "Lanterne",
		["ASHLANDPOTGREEN"] = "Pot des cendres (vert)",
		["ASHLANDPOTRED"] = "Pot des cendres (rouge)",
		["SEEKERBRUTE"] = "Brute Chercheuse",
		["BONEMAWSERPENT"] = "Serpent Mâchoires d’Os",
		["COPPER"] = "Cuivre",
		["DRAGONEGG"] = "Œuf de dragon"
	};

	public static readonly Dictionary<string, string> DE = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abscheulichkeit",
		["CRYPT"] = "Gruft",
		["DRAUGRSPAWNER"] = "Draugr-Portal",
		["DVERGERTHINGS"] = "Dvergr-Überreste",
		["DWARFSPAWNER"] = "Grauzwergen-Nest",
		["FIRE"] = "Lagerfeuer",
		["FLAX"] = "Flachs",
		["IRON"] = "Eisen",
		["MUDPILE"] = "Schlammhaufen",
		["METEORITE"] = "Meteorit",
		["MAGECAPS"] = "Magierkappen",
		["MARKER"] = "Markierung",
		["MUSHROOMS"] = "Pilze",
		["OBSIDIAN"] = "Obsidian",
		["SEEDS"] = "Samen",
		["SILVER"] = "Silber",
		["SKELETON"] = "Skelett",
		["SMOKEPUFFS"] = "Rauchwolken",
		["TAR"] = "Teergrube",
		["THISTLE"] = "Distel",
		["TOTEM"] = "Fuling-Totem",
		["TROLLCAVE"] = "Trollhöhle",
		["TREASURE"] = "Schatz",
		["VOLTUREEGG"] = "Geier-Ei",
		["YPCONES"] = "Yggdrasil-Zapfen",
		["JOTUNNPUFFS"] = "Jotunnflusen",
		["RASPBERRIES"] = "Himbeeren",
		["BLUEBERRIES"] = "Blaubeeren",
		["CLOUDBERRIES"] = "Moltebeeren",
		["BARLEY"] = "Gerste",
		["CLOTH"] = "Stoff",
		["SHIPWRECKCHEST"] = "Schiffswracktruhe",
		["GIANTSWORD"] = "Schwert des Riesen",
		["GIANTRIBS"] = "Rippen des Riesen",
		["GIANTSKULL"] = "Schädel des Riesen",
		["GIANTBRAIN"] = "Gehirn des Riesen",
		["EXCAVATION"] = "Ausgrabungsstätte",
		["LANTERN"] = "Laterne",
		["ASHLANDPOTGREEN"] = "Aschenkrug (Grün)",
		["ASHLANDPOTRED"] = "Aschenkrug (Rot)",
		["SEEKERBRUTE"] = "Sucher-Brutalo",
		["BONEMAWSERPENT"] = "Knochenrachen-Schlange",
		["COPPER"] = "Kupfer",
		["DRAGONEGG"] = "Drachenei"
	};

	public static readonly Dictionary<string, string> ES = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abominación",
		["CRYPT"] = "Cripta",
		["DRAUGRSPAWNER"] = "Generador de Draugr",
		["DVERGERTHINGS"] = "Restos de Dvergr",
		["DWARFSPAWNER"] = "Nido de enano gris",
		["FIRE"] = "Hoguera",
		["FLAX"] = "Lino",
		["IRON"] = "Hierro",
		["MUDPILE"] = "Montón de barro",
		["METEORITE"] = "Meteorito",
		["MAGECAPS"] = "Sombreros de mago",
		["MARKER"] = "Marcador",
		["MUSHROOMS"] = "Hongos",
		["OBSIDIAN"] = "Obsidiana",
		["SEEDS"] = "Semillas",
		["SILVER"] = "Plata",
		["SKELETON"] = "Esqueleto",
		["SMOKEPUFFS"] = "Nubes de humo",
		["TAR"] = "Pozo de alquitrán",
		["THISTLE"] = "Cardo",
		["TOTEM"] = "Tótem de Fuling",
		["TROLLCAVE"] = "Cueva del troll",
		["TREASURE"] = "Tesoro enterrado",
		["VOLTUREEGG"] = "Huevo de buitre",
		["YPCONES"] = "Conos de Yggdrasil",
		["JOTUNNPUFFS"] = "Pelusas de Jotunn",
		["RASPBERRIES"] = "Frambuesas",
		["BLUEBERRIES"] = "Arándanos",
		["CLOUDBERRIES"] = "Moras árticas",
		["BARLEY"] = "Cebada",
		["CLOTH"] = "Tela",
		["SHIPWRECKCHEST"] = "Cofre del naufragio",
		["GIANTSWORD"] = "Espada gigante",
		["GIANTRIBS"] = "Costillas de gigante",
		["GIANTSKULL"] = "Cráneo de gigante",
		["GIANTBRAIN"] = "Cerebro de gigante",
		["EXCAVATION"] = "Sitio de excavación",
		["LANTERN"] = "Linterna",
		["ASHLANDPOTGREEN"] = "Tintero de ceniza (verde)",
		["ASHLANDPOTRED"] = "Tintero de ceniza (rojo)",
		["SEEKERBRUTE"] = "Bruto Buscador",
		["BONEMAWSERPENT"] = "Serpiente Mandíbulas de Hueso",
		["COPPER"] = "Cobre",
		["DRAGONEGG"] = "Huevo de dragón"
	};

	public static readonly Dictionary<string, string> PL = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abominacja",
		["CRYPT"] = "Krypta",
		["DRAUGRSPAWNER"] = "Pojawiacz Draugrów",
		["DVERGERTHINGS"] = "Szczątki Dvergrów",
		["DWARFSPAWNER"] = "Gniazdo szarego krasnoluda",
		["FIRE"] = "Ognisko",
		["FLAX"] = "Len",
		["IRON"] = "Żelazo",
		["MUDPILE"] = "Stos błota",
		["METEORITE"] = "Meteoryt",
		["MAGECAPS"] = "Kapelusze maga",
		["MARKER"] = "Znacznik",
		["MUSHROOMS"] = "Grzyby",
		["OBSIDIAN"] = "Obsydian",
		["SEEDS"] = "Nasiona",
		["SILVER"] = "Srebro",
		["SKELETON"] = "Szkielet",
		["SMOKEPUFFS"] = "Kłęby dymu",
		["TAR"] = "Dół smoły",
		["THISTLE"] = "Oset",
		["TOTEM"] = "Totem Fulingów",
		["TROLLCAVE"] = "Jaskinia trolla",
		["TREASURE"] = "Zakopany skarb",
		["VOLTUREEGG"] = "Jajo sępa",
		["YPCONES"] = "Szyszki Yggdrasila",
		["JOTUNNPUFFS"] = "Puch Jotunna",
		["RASPBERRIES"] = "Maliny",
		["BLUEBERRIES"] = "Jagody",
		["CLOUDBERRIES"] = "Maliny moroszki",
		["BARLEY"] = "Jęczmień",
		["CLOTH"] = "Tkanina",
		["SHIPWRECKCHEST"] = "Skrzynia z wraku statku",
		["GIANTSWORD"] = "Miecz olbrzyma",
		["GIANTRIBS"] = "Żebra olbrzyma",
		["GIANTSKULL"] = "Czaszka olbrzyma",
		["GIANTBRAIN"] = "Mózg olbrzyma",
		["EXCAVATION"] = "Miejsce wykopalisk",
		["LANTERN"] = "Latarnia",
		["ASHLANDPOTGREEN"] = "Popielniczka (zielona)",
		["ASHLANDPOTRED"] = "Popielniczka (czerwona)",
		["SEEKERBRUTE"] = "Brutalny Poszukiwacz",
		["BONEMAWSERPENT"] = "Wąż Kościany",
		["COPPER"] = "Miedź",
		["DRAGONEGG"] = "Jajo smoka"
	};

	public static readonly Dictionary<string, string> ZH = new Dictionary<string, string>
	{
		["ABOMINATION"] = "憎恶",
		["CRYPT"] = "地穴",
		["DRAUGRSPAWNER"] = "尸鬼刷怪点",
		["DVERGERTHINGS"] = "矮人遗骸",
		["DWARFSPAWNER"] = "灰矮人巢穴",
		["FIRE"] = "篝火",
		["FLAX"] = "亚麻",
		["IRON"] = "铁",
		["MUDPILE"] = "泥堆",
		["METEORITE"] = "陨石",
		["MAGECAPS"] = "法师帽",
		["MARKER"] = "标记",
		["MUSHROOMS"] = "蘑菇",
		["OBSIDIAN"] = "黑曜石",
		["SEEDS"] = "种子",
		["SILVER"] = "银",
		["SKELETON"] = "骷髅",
		["SMOKEPUFFS"] = "烟雾",
		["TAR"] = "焦油坑",
		["THISTLE"] = "蓟",
		["TOTEM"] = "伏林图腾",
		["TROLLCAVE"] = "巨魔洞穴",
		["TREASURE"] = "埋藏宝藏",
		["VOLTUREEGG"] = "秃鹫蛋",
		["YPCONES"] = "世界树松果",
		["JOTUNNPUFFS"] = "尤顿之绒",
		["RASPBERRIES"] = "覆盆子",
		["BLUEBERRIES"] = "蓝莓",
		["CLOUDBERRIES"] = "云莓",
		["BARLEY"] = "大麦",
		["CLOTH"] = "布料",
		["SHIPWRECKCHEST"] = "沉船宝箱",
		["GIANTSWORD"] = "巨人之剑",
		["GIANTRIBS"] = "巨人肋骨",
		["GIANTSKULL"] = "巨人头骨",
		["GIANTBRAIN"] = "巨人脑",
		["EXCAVATION"] = "挖掘现场",
		["LANTERN"] = "灯笼",
		["ASHLANDPOTGREEN"] = "灰烬罐(绿色)",
		["ASHLANDPOTRED"] = "灰烬罐(红色)",
		["SEEKERBRUTE"] = "搜寻者蛮兵",
		["BONEMAWSERPENT"] = "骨颚巨蛇",
		["COPPER"] = "铜",
		["DRAGONEGG"] = "龙蛋"
	};

	public static readonly Dictionary<string, string> PT = new Dictionary<string, string>
	{
		["ABOMINATION"] = "Abominação",
		["CRYPT"] = "Cripta",
		["DRAUGRSPAWNER"] = "Gerador de Draugr",
		["DVERGERTHINGS"] = "Restos de Dvergr",
		["DWARFSPAWNER"] = "Ninho de Anão Cinzento",
		["FIRE"] = "Fogueira",
		["FLAX"] = "Linho",
		["IRON"] = "Ferro",
		["MUDPILE"] = "Monturo de lama",
		["METEORITE"] = "Meteorito",
		["MAGECAPS"] = "Chapéus de mago",
		["MARKER"] = "Marcador",
		["MUSHROOMS"] = "Cogumelos",
		["OBSIDIAN"] = "Obsidiana",
		["SEEDS"] = "Sementes",
		["SILVER"] = "Prata",
		["SKELETON"] = "Esqueleto",
		["SMOKEPUFFS"] = "Fumaça",
		["TAR"] = "Poça de piche",
		["THISTLE"] = "Cardo",
		["TOTEM"] = "Totem de Fuling",
		["TROLLCAVE"] = "Caverna do troll",
		["TREASURE"] = "Tesouro enterrado",
		["VOLTUREEGG"] = "Ovo de abutre",
		["YPCONES"] = "Pinhas de Yggdrasil",
		["JOTUNNPUFFS"] = "Pufs de Jotunn",
		["RASPBERRIES"] = "Framboesas",
		["BLUEBERRIES"] = "Mirtilos",
		["CLOUDBERRIES"] = "Amoras árticas",
		["BARLEY"] = "Cevada",
		["CLOTH"] = "Tecido",
		["SHIPWRECKCHEST"] = "Baú de naufrágio",
		["GIANTSWORD"] = "Espada gigante",
		["GIANTRIBS"] = "Costelas gigantes",
		["GIANTSKULL"] = "Crânio gigante",
		["GIANTBRAIN"] = "Cérebro gigante",
		["EXCAVATION"] = "Local de escavação",
		["LANTERN"] = "Lanterna",
		["ASHLANDPOTGREEN"] = "Pote das Cinzas (Verde)",
		["ASHLANDPOTRED"] = "Pote das Cinzas (Vermelho)",
		["SEEKERBRUTE"] = "Bruto Buscador",
		["BONEMAWSERPENT"] = "Serpente Mandíbula Óssea",
		["COPPER"] = "Cobre",
		["DRAGONEGG"] = "Ovo de dragão"
	};
}
public class PinManager
{
	private const int PinFlushThreshold = 50;

	private readonly HashSet<string> _pinHashes = new HashSet<string>();

	private readonly ModConfig _config;

	private readonly ManualLogSource _logger;

	private readonly LocalizationManager _localizationManager;

	private readonly List<Tuple<Vector3, string>> _currentPins = new List<Tuple<Vector3, string>>();

	private readonly List<Tuple<Vector3, string>> _newPins = new List<Tuple<Vector3, string>>();

	private float _lastSaveTime;

	private static readonly string SaveFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles");

	private static readonly string PinsFilePath = Path.Combine(SaveFolder, "Pins.txt");

	public PinManager(ModConfig config, ManualLogSource logger, LocalizationManager localizationManager)
	{
		_config = config;
		_logger = logger;
		_localizationManager = localizationManager;
		Directory.CreateDirectory(Path.GetDirectoryName(PinsFilePath));
		LoadPinsFromFile();
	}

	public void ReloadConfig()
	{
	}

	public void TryAddPin(Vector3 pos, string label, PinType icon)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Minimap.instance == (Object)null)
		{
			return;
		}
		Vector3 val = RoundTo0_1(pos);
		string text = label.ToUpperInvariant();
		string pinHash = GetPinHash(val, text);
		if (_pinHashes.Contains(pinHash))
		{
			return;
		}
		foreach (Tuple<Vector3, string> currentPin in _currentPins)
		{
			if (Vector3.Distance(currentPin.Item1, val) < _config.PinMergeDistance.Value && string.Equals(currentPin.Item2, text, StringComparison.OrdinalIgnoreCase))
			{
				return;
			}
		}
		string label2 = _localizationManager.GetLabel(text);
		Minimap.instance.AddPin(val, icon, label2, true, false, 0L, default(PlatformUserID));
		_newPins.Add(new Tuple<Vector3, string>(val, text));
		_currentPins.Add(new Tuple<Vector3, string>(val, text));
		_pinHashes.Add(pinHash);
		if (_config.EnablePinSaving.Value && _newPins.Count >= 50)
		{
			SavePinsToFile();
		}
	}

	public void TryPeriodicSave()
	{
		if (_config.EnablePinSaving.Value && _newPins.Count != 0 && (_newPins.Count >= 50 || Time.time - _lastSaveTime > _config.SaveInterval.Value))
		{
			SavePinsToFile();
		}
	}

	public void SaveImmediate()
	{
		if (_config.EnablePinSaving.Value)
		{
			SavePinsToFile();
		}
	}

	public void RemoveAllPins()
	{
		if ((Object)(object)Minimap.instance == (Object)null)
		{
			return;
		}
		_pinHashes.Clear();
		try
		{
			File.WriteAllText(PinsFilePath, string.Empty);
			_logger.LogWarning((object)"SullysAutoPinner >>> All Map Pins Removed - Pin history file emptied.");
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullysAutoPinner >>> Failed to clear Pins.txt: " + ex.Message));
			return;
		}
		if (!(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		foreach (PinData item in list.ToList())
		{
			Minimap.instance.RemovePin(item);
		}
		_currentPins.Clear();
		_newPins.Clear();
		_pinHashes.Clear();
		_logger.LogWarning((object)$"SullysAutoPinner >>> All Map Pins Removed: {list.Count} pins removed from the map.");
	}

	public void RemoveUnwantedPins(ModConfig config)
	{
		if ((Object)(object)Minimap.instance == (Object)null || !(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		foreach (KeyValuePair<string, (string, PinType)> item2 in PinScanner.PinLabelMap.LabelToSettingInfo)
		{
			string item = item2.Value.Item1;
			FieldInfo field = typeof(ModConfig).GetField(item);
			if (!(field == null) && !(field.FieldType != typeof(ConfigEntry<bool>)))
			{
				ConfigEntry<bool> val = (ConfigEntry<bool>)field.GetValue(config);
				if (val != null && val.Value)
				{
					string label = _localizationManager.GetLabel(item.ToUpperInvariant());
					hashSet.Add(label);
				}
			}
		}
		List<PinData> list2 = new List<PinData>();
		foreach (PinData item3 in list)
		{
			if (!hashSet.Contains(item3.m_name))
			{
				list2.Add(item3);
			}
		}
		foreach (PinData item4 in list2)
		{
			Minimap.instance.RemovePin(item4);
		}
		_logger.LogWarning((object)$"Removed {list2.Count} unwanted pins from the map.");
	}

	private bool IsLabelEnabled(string label, ModConfig config)
	{
		if (!PinScanner.PinLabelMap.LabelToSettingInfo.TryGetValue(label, out (string, PinType) value))
		{
			return true;
		}
		FieldInfo field = typeof(ModConfig).GetField(value.Item1);
		if (field == null || field.FieldType != typeof(ConfigEntry<bool>))
		{
			return true;
		}
		return ((ConfigEntry<bool>)field.GetValue(config)).Value;
	}

	private void SavePinsToFile()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			using StreamWriter streamWriter = File.AppendText(PinsFilePath);
			foreach (Tuple<Vector3, string> newPin in _newPins)
			{
				streamWriter.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0:F1}|{1:F1}|{2:F1}|{3}", newPin.Item1.x, newPin.Item1.y, newPin.Item1.z, newPin.Item2));
			}
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullyAutoPinner >>> Error saving pins: " + ex.Message));
		}
		_newPins.Clear();
		_lastSaveTime = Time.time;
	}

	private void LoadPinsFromFile()
	{
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!File.Exists(PinsFilePath))
			{
				return;
			}
			string[] array = File.ReadAllLines(PinsFilePath);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { '|' });
				if (array2.Length == 4 && float.TryParse(array2[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
				{
					string text = array2[3].Trim().ToUpperInvariant();
					Vector3 val = RoundTo0_1(new Vector3(result, result2, result3));
					string pinHash = GetPinHash(val, text);
					_pinHashes.Add(pinHash);
					_currentPins.Add(new Tuple<Vector3, string>(val, text));
				}
			}
		}
		catch (Exception ex)
		{
			_logger.LogWarning((object)("SullyAutoPinner >>> Error loading pins: " + ex.Message));
		}
	}

	private string GetPinHash(Vector3 pos, string label)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = RoundTo0_1(pos);
		return string.Format(CultureInfo.InvariantCulture, "{0}:{1:F1},{2:F1},{3:F1}", label.ToUpperInvariant(), val.x, val.y, val.z);
	}

	private Vector3 RoundTo0_1(Vector3 v)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(Mathf.Round(v.x * 10f) / 10f, Mathf.Round(v.y * 10f) / 10f, Mathf.Round(v.z * 10f) / 10f);
	}

	public void RemoveNearbyFallbackPins(Vector3 center, float radius)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Minimap.instance == (Object)null || !(AccessTools.Field(typeof(Minimap), "m_pins").GetValue(Minimap.instance) is List<PinData> list))
		{
			return;
		}
		List<PinData> list2 = new List<PinData>();
		foreach (PinData item in list)
		{
			if (!(Vector3.Distance(center, item.m_pos) > radius))
			{
				string name = item.m_name;
				if (!PinScanner.PinLabelMap.LabelToSettingInfo.ContainsKey(name))
				{
					list2.Add(item);
				}
			}
		}
		foreach (PinData item2 in list2)
		{
			Minimap.instance.RemovePin(item2);
		}
		_logger.LogWarning((object)$"Removed {list2.Count} fallback pins within {radius}m.");
	}
}
namespace SimpleJSON
{
	public enum JSONNodeType
	{
		Array = 1,
		Object = 2,
		String = 3,
		Number = 4,
		NullValue = 5,
		Boolean = 6,
		None = 7,
		Custom = 255
	}
	public enum JSONTextMode
	{
		Compact,
		Indent
	}
	public abstract class JSONNode
	{
		public struct Enumerator
		{
			private enum Type
			{
				None,
				Array,
				Object
			}

			private Type type;

			private Dictionary<string, JSONNode>.Enumerator m_Object;

			private List<JSONNode>.Enumerator m_Array;

			public bool IsValid => type != Type.None;

			public KeyValuePair<string, JSONNode> Current
			{
				get
				{
					if (type == Type.Array)
					{
						return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current);
					}
					if (type == Type.Object)
					{
						return m_Object.Current;
					}
					return new KeyValuePair<string, JSONNode>(string.Empty, null);
				}
			}

			public Enumerator(List<JSONNode>.Enumerator aArrayEnum)
			{
				type = Type.Array;
				m_Object = default(Dictionary<string, JSONNode>.Enumerator);
				m_Array = aArrayEnum;
			}

			public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
			{
				type = Type.Object;
				m_Object = aDictEnum;
				m_Array = default(List<JSONNode>.Enumerator);
			}

			public bool MoveNext()
			{
				if (type == Type.Array)
				{
					return m_Array.MoveNext();
				}
				if (type == Type.Object)
				{
					return m_Object.MoveNext();
				}
				return false;
			}
		}

		public struct ValueEnumerator
		{
			private Enumerator m_Enumerator;

			public JSONNode Current => m_Enumerator.Current.Value;

			public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public ValueEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public ValueEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public struct KeyEnumerator
		{
			private Enumerator m_Enumerator;

			public string Current => m_Enumerator.Current.Key;

			public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum)
				: this(new Enumerator(aArrayEnum))
			{
			}

			public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum)
				: this(new Enumerator(aDictEnum))
			{
			}

			public KeyEnumerator(Enumerator aEnumerator)
			{
				m_Enumerator = aEnumerator;
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public KeyEnumerator GetEnumerator()
			{
				return this;
			}
		}

		public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IDisposable, IEnumerator, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable
		{
			private JSONNode m_Node;

			private Enumerator m_Enumerator;

			public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current;

			object IEnumerator.Current => m_Enumerator.Current;

			internal LinqEnumerator(JSONNode aNode)
			{
				m_Node = aNode;
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			public bool MoveNext()
			{
				return m_Enumerator.MoveNext();
			}

			public void Dispose()
			{
				m_Node = null;
				m_Enumerator = default(Enumerator);
			}

			public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}

			public void Reset()
			{
				if (m_Node != null)
				{
					m_Enumerator = m_Node.GetEnumerator();
				}
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return new LinqEnumerator(m_Node);
			}
		}

		[CompilerGenerated]
		private sealed class <get_Children>d__43 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

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

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

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

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

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				return false;
			}

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

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

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

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

		[CompilerGenerated]
		private sealed class <get_DeepChildren>d__45 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONNode <>4__this;

			private IEnumerator<JSONNode> <>7__wrap1;

			private IEnumerator<JSONNode> <>7__wrap2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if ((uint)(num - -4) <= 1u || num == 1)
				{
					try
					{
						if (num == -4 || num == 1)
						{
							try
							{
							}
							finally
							{
								<>m__Finally2();
							}
						}
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					JSONNode jSONNode = <>4__this;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -4;
						goto IL_008d;
					}
					<>1__state = -1;
					<>7__wrap1 = jSONNode.Children.GetEnumerator();
					<>1__state = -3;
					goto IL_00a7;
					IL_008d:
					if (<>7__wrap2.MoveNext())
					{
						JSONNode current = <>7__wrap2.Current;
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
					<>m__Finally2();
					<>7__wrap2 = null;
					goto IL_00a7;
					IL_00a7:
					if (<>7__wrap1.MoveNext())
					{
						JSONNode current2 = <>7__wrap1.Current;
						<>7__wrap2 = current2.DeepChildren.GetEnumerator();
						<>1__state = -4;
						goto IL_008d;
					}
					<>m__Finally1();
					<>7__wrap1 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap1 != null)
				{
					<>7__wrap1.Dispose();
				}
			}

			private void <>m__Finally2()
			{
				<>1__state = -3;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_DeepChildren>d__45 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_DeepChildren>d__45(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		public static bool forceASCII = false;

		public static bool longAsString = false;

		public static bool allowLineComments = true;

		[ThreadStatic]
		private static StringBuilder m_EscapeBuilder;

		public abstract JSONNodeType Tag { get; }

		public virtual JSONNode this[int aIndex]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual JSONNode this[string aKey]
		{
			get
			{
				return null;
			}
			set
			{
			}
		}

		public virtual string Value
		{
			get
			{
				return "";
			}
			set
			{
			}
		}

		public virtual int Count => 0;

		public virtual bool IsNumber => false;

		public virtual bool IsString => false;

		public virtual bool IsBoolean => false;

		public virtual bool IsNull => false;

		public virtual bool IsArray => false;

		public virtual bool IsObject => false;

		public virtual bool Inline
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public virtual IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__43))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Children>d__43(-2);
			}
		}

		public IEnumerable<JSONNode> DeepChildren
		{
			[IteratorStateMachine(typeof(<get_DeepChildren>d__45))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_DeepChildren>d__45(-2)
				{
					<>4__this = this
				};
			}
		}

		public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this);

		public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator());

		public ValueEnumerator Values => new ValueEnumerator(GetEnumerator());

		public virtual double AsDouble
		{
			get
			{
				double result = 0.0;
				if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0.0;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual int AsInt
		{
			get
			{
				return (int)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual float AsFloat
		{
			get
			{
				return (float)AsDouble;
			}
			set
			{
				AsDouble = value;
			}
		}

		public virtual bool AsBool
		{
			get
			{
				bool result = false;
				if (bool.TryParse(Value, out result))
				{
					return result;
				}
				return !string.IsNullOrEmpty(Value);
			}
			set
			{
				Value = (value ? "true" : "false");
			}
		}

		public virtual long AsLong
		{
			get
			{
				long result = 0L;
				if (long.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0L;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual ulong AsULong
		{
			get
			{
				ulong result = 0uL;
				if (ulong.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
				{
					return result;
				}
				return 0uL;
			}
			set
			{
				Value = value.ToString(CultureInfo.InvariantCulture);
			}
		}

		public virtual JSONArray AsArray => this as JSONArray;

		public virtual JSONObject AsObject => this as JSONObject;

		internal static StringBuilder EscapeBuilder
		{
			get
			{
				if (m_EscapeBuilder == null)
				{
					m_EscapeBuilder = new StringBuilder();
				}
				return m_EscapeBuilder;
			}
		}

		public virtual void Add(string aKey, JSONNode aItem)
		{
		}

		public virtual void Add(JSONNode aItem)
		{
			Add("", aItem);
		}

		public virtual JSONNode Remove(string aKey)
		{
			return null;
		}

		public virtual JSONNode Remove(int aIndex)
		{
			return null;
		}

		public virtual JSONNode Remove(JSONNode aNode)
		{
			return aNode;
		}

		public virtual void Clear()
		{
		}

		public virtual JSONNode Clone()
		{
			return null;
		}

		public virtual bool HasKey(string aKey)
		{
			return false;
		}

		public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
		{
			return aDefault;
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact);
			return stringBuilder.ToString();
		}

		public virtual string ToString(int aIndent)
		{
			StringBuilder stringBuilder = new StringBuilder();
			WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent);
			return stringBuilder.ToString();
		}

		internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode);

		public abstract Enumerator GetEnumerator();

		public static implicit operator JSONNode(string s)
		{
			if (s != null)
			{
				return new JSONString(s);
			}
			return JSONNull.CreateOrGet();
		}

		public static implicit operator string(JSONNode d)
		{
			if (!(d == null))
			{
				return d.Value;
			}
			return null;
		}

		public static implicit operator JSONNode(double n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator double(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsDouble;
			}
			return 0.0;
		}

		public static implicit operator JSONNode(float n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator float(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsFloat;
			}
			return 0f;
		}

		public static implicit operator JSONNode(int n)
		{
			return new JSONNumber(n);
		}

		public static implicit operator int(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsInt;
			}
			return 0;
		}

		public static implicit operator JSONNode(long n)
		{
			if (longAsString)
			{
				return new JSONString(n.ToString(CultureInfo.InvariantCulture));
			}
			return new JSONNumber(n);
		}

		public static implicit operator long(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsLong;
			}
			return 0L;
		}

		public static implicit operator JSONNode(ulong n)
		{
			if (longAsString)
			{
				return new JSONString(n.ToString(CultureInfo.InvariantCulture));
			}
			return new JSONNumber(n);
		}

		public static implicit operator ulong(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsULong;
			}
			return 0uL;
		}

		public static implicit operator JSONNode(bool b)
		{
			return new JSONBool(b);
		}

		public static implicit operator bool(JSONNode d)
		{
			if (!(d == null))
			{
				return d.AsBool;
			}
			return false;
		}

		public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue)
		{
			return aKeyValue.Value;
		}

		public static bool operator ==(JSONNode a, object b)
		{
			if ((object)a == b)
			{
				return true;
			}
			bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator;
			bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator;
			if (flag && flag2)
			{
				return true;
			}
			if (!flag)
			{
				return a.Equals(b);
			}
			return false;
		}

		public static bool operator !=(JSONNode a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		internal static string Escape(string aText)
		{
			StringBuilder escapeBuilder = EscapeBuilder;
			escapeBuilder.Length = 0;
			if (escapeBuilder.Capacity < aText.Length + aText.Length / 10)
			{
				escapeBuilder.Capacity = aText.Length + aText.Length / 10;
			}
			foreach (char c in aText)
			{
				switch (c)
				{
				case '\\':
					escapeBuilder.Append("\\\\");
					continue;
				case '"':
					escapeBuilder.Append("\\\"");
					continue;
				case '\n':
					escapeBuilder.Append("\\n");
					continue;
				case '\r':
					escapeBuilder.Append("\\r");
					continue;
				case '\t':
					escapeBuilder.Append("\\t");
					continue;
				case '\b':
					escapeBuilder.Append("\\b");
					continue;
				case '\f':
					escapeBuilder.Append("\\f");
					continue;
				}
				if (c < ' ' || (forceASCII && c > '\u007f'))
				{
					ushort num = c;
					escapeBuilder.Append("\\u").Append(num.ToString("X4"));
				}
				else
				{
					escapeBuilder.Append(c);
				}
			}
			string result = escapeBuilder.ToString();
			escapeBuilder.Length = 0;
			return result;
		}

		private static JSONNode ParseElement(string token, bool quoted)
		{
			if (quoted)
			{
				return token;
			}
			if (token.Length <= 5)
			{
				string text = token.ToLower();
				switch (text)
				{
				case "false":
				case "true":
					return text == "true";
				case "null":
					return JSONNull.CreateOrGet();
				}
			}
			if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				return result;
			}
			return token;
		}

		public static JSONNode Parse(string aJSON)
		{
			Stack<JSONNode> stack = new Stack<JSONNode>();
			JSONNode jSONNode = null;
			int i = 0;
			StringBuilder stringBuilder = new StringBuilder();
			string aKey = "";
			bool flag = false;
			bool flag2 = false;
			bool flag3 = false;
			for (; i < aJSON.Length; i++)
			{
				switch (aJSON[i])
				{
				case '{':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONObject());
					if (jSONNode != null)
					{
						jSONNode.Add(aKey, stack.Peek());
					}
					aKey = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					flag3 = false;
					break;
				case '[':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					stack.Push(new JSONArray());
					if (jSONNode != null)
					{
						jSONNode.Add(aKey, stack.Peek());
					}
					aKey = "";
					stringBuilder.Length = 0;
					jSONNode = stack.Peek();
					flag3 = false;
					break;
				case ']':
				case '}':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stack.Count == 0)
					{
						throw new Exception("JSON Parse: Too many closing brackets");
					}
					stack.Pop();
					if (stringBuilder.Length > 0 || flag2)
					{
						jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2));
					}
					if (jSONNode != null)
					{
						jSONNode.Inline = !flag3;
					}
					flag2 = false;
					aKey = "";
					stringBuilder.Length = 0;
					if (stack.Count > 0)
					{
						jSONNode = stack.Peek();
					}
					break;
				case ':':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					aKey = stringBuilder.ToString();
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '"':
					flag = !flag;
					flag2 = flag2 || flag;
					break;
				case ',':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
						break;
					}
					if (stringBuilder.Length > 0 || flag2)
					{
						jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2));
					}
					flag2 = false;
					aKey = "";
					stringBuilder.Length = 0;
					flag2 = false;
					break;
				case '\n':
				case '\r':
					flag3 = true;
					break;
				case '\t':
				case ' ':
					if (flag)
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				case '\\':
					i++;
					if (flag)
					{
						char c = aJSON[i];
						switch (c)
						{
						case 't':
							stringBuilder.Append('\t');
							break;
						case 'r':
							stringBuilder.Append('\r');
							break;
						case 'n':
							stringBuilder.Append('\n');
							break;
						case 'b':
							stringBuilder.Append('\b');
							break;
						case 'f':
							stringBuilder.Append('\f');
							break;
						case 'u':
						{
							string s = aJSON.Substring(i + 1, 4);
							stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier));
							i += 4;
							break;
						}
						default:
							stringBuilder.Append(c);
							break;
						}
					}
					break;
				case '/':
					if (allowLineComments && !flag && i + 1 < aJSON.Length && aJSON[i + 1] == '/')
					{
						while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r')
						{
						}
					}
					else
					{
						stringBuilder.Append(aJSON[i]);
					}
					break;
				default:
					stringBuilder.Append(aJSON[i]);
					break;
				case '\ufeff':
					break;
				}
			}
			if (flag)
			{
				throw new Exception("JSON Parse: Quotation marks seems to be messed up.");
			}
			if (jSONNode == null)
			{
				return ParseElement(stringBuilder.ToString(), flag2);
			}
			return jSONNode;
		}
	}
	public class JSONArray : JSONNode
	{
		[CompilerGenerated]
		private sealed class <get_Children>d__24 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONArray <>4__this;

			private List<JSONNode>.Enumerator <>7__wrap1;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(List<JSONNode>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					JSONArray jSONArray = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = jSONArray.m_List.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						JSONNode current = <>7__wrap1.Current;
						<>2__current = current;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = default(List<JSONNode>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_Children>d__24 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Children>d__24(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		private List<JSONNode> m_List = new List<JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Array;

		public override bool IsArray => true;

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					return new JSONLazyCreator(this);
				}
				return m_List[aIndex];
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex < 0 || aIndex >= m_List.Count)
				{
					m_List.Add(value);
				}
				else
				{
					m_List[aIndex] = value;
				}
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				m_List.Add(value);
			}
		}

		public override int Count => m_List.Count;

		public override IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__24))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Children>d__24(-2)
				{
					<>4__this = this
				};
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_List.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			m_List.Add(aItem);
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_List.Count)
			{
				return null;
			}
			JSONNode result = m_List[aIndex];
			m_List.RemoveAt(aIndex);
			return result;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			m_List.Remove(aNode);
			return aNode;
		}

		public override void Clear()
		{
			m_List.Clear();
		}

		public override JSONNode Clone()
		{
			JSONArray jSONArray = new JSONArray();
			jSONArray.m_List.Capacity = m_List.Capacity;
			foreach (JSONNode item in m_List)
			{
				if (item != null)
				{
					jSONArray.Add(item.Clone());
				}
				else
				{
					jSONArray.Add(null);
				}
			}
			return jSONArray;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('[');
			int count = m_List.Count;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			for (int i = 0; i < count; i++)
			{
				if (i > 0)
				{
					aSB.Append(',');
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append(']');
		}
	}
	public class JSONObject : JSONNode
	{
		[CompilerGenerated]
		private sealed class <get_Children>d__27 : IEnumerable<JSONNode>, IEnumerable, IEnumerator<JSONNode>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private JSONNode <>2__current;

			private int <>l__initialThreadId;

			public JSONObject <>4__this;

			private Dictionary<string, JSONNode>.Enumerator <>7__wrap1;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = default(Dictionary<string, JSONNode>.Enumerator);
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					JSONObject jSONObject = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = jSONObject.m_Dict.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					if (<>7__wrap1.MoveNext())
					{
						<>2__current = <>7__wrap1.Current.Value;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>7__wrap1 = default(Dictionary<string, JSONNode>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

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

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>7__wrap1).Dispose();
			}

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

			[DebuggerHidden]
			IEnumerator<JSONNode> IEnumerable<JSONNode>.GetEnumerator()
			{
				<get_Children>d__27 result;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					result = this;
				}
				else
				{
					result = new <get_Children>d__27(0)
					{
						<>4__this = <>4__this
					};
				}
				return result;
			}

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

		private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>();

		private bool inline;

		public override bool Inline
		{
			get
			{
				return inline;
			}
			set
			{
				inline = value;
			}
		}

		public override JSONNodeType Tag => JSONNodeType.Object;

		public override bool IsObject => true;

		public override JSONNode this[string aKey]
		{
			get
			{
				if (m_Dict.TryGetValue(aKey, out var value))
				{
					return value;
				}
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = value;
				}
				else
				{
					m_Dict.Add(aKey, value);
				}
			}
		}

		public override JSONNode this[int aIndex]
		{
			get
			{
				if (aIndex < 0 || aIndex >= m_Dict.Count)
				{
					return null;
				}
				return m_Dict.ElementAt(aIndex).Value;
			}
			set
			{
				if (value == null)
				{
					value = JSONNull.CreateOrGet();
				}
				if (aIndex >= 0 && aIndex < m_Dict.Count)
				{
					string key = m_Dict.ElementAt(aIndex).Key;
					m_Dict[key] = value;
				}
			}
		}

		public override int Count => m_Dict.Count;

		public override IEnumerable<JSONNode> Children
		{
			[IteratorStateMachine(typeof(<get_Children>d__27))]
			get
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <get_Children>d__27(-2)
				{
					<>4__this = this
				};
			}
		}

		public override Enumerator GetEnumerator()
		{
			return new Enumerator(m_Dict.GetEnumerator());
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			if (aItem == null)
			{
				aItem = JSONNull.CreateOrGet();
			}
			if (aKey != null)
			{
				if (m_Dict.ContainsKey(aKey))
				{
					m_Dict[aKey] = aItem;
				}
				else
				{
					m_Dict.Add(aKey, aItem);
				}
			}
			else
			{
				m_Dict.Add(Guid.NewGuid().ToString(), aItem);
			}
		}

		public override JSONNode Remove(string aKey)
		{
			if (!m_Dict.ContainsKey(aKey))
			{
				return null;
			}
			JSONNode result = m_Dict[aKey];
			m_Dict.Remove(aKey);
			return result;
		}

		public override JSONNode Remove(int aIndex)
		{
			if (aIndex < 0 || aIndex >= m_Dict.Count)
			{
				return null;
			}
			KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex);
			m_Dict.Remove(keyValuePair.Key);
			return keyValuePair.Value;
		}

		public override JSONNode Remove(JSONNode aNode)
		{
			try
			{
				KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First();
				m_Dict.Remove(keyValuePair.Key);
				return aNode;
			}
			catch
			{
				return null;
			}
		}

		public override void Clear()
		{
			m_Dict.Clear();
		}

		public override JSONNode Clone()
		{
			JSONObject jSONObject = new JSONObject();
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				jSONObject.Add(item.Key, item.Value.Clone());
			}
			return jSONObject;
		}

		public override bool HasKey(string aKey)
		{
			return m_Dict.ContainsKey(aKey);
		}

		public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault)
		{
			if (m_Dict.TryGetValue(aKey, out var value))
			{
				return value;
			}
			return aDefault;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('{');
			bool flag = true;
			if (inline)
			{
				aMode = JSONTextMode.Compact;
			}
			foreach (KeyValuePair<string, JSONNode> item in m_Dict)
			{
				if (!flag)
				{
					aSB.Append(',');
				}
				flag = false;
				if (aMode == JSONTextMode.Indent)
				{
					aSB.AppendLine();
				}
				if (aMode == JSONTextMode.Indent)
				{
					aSB.Append(' ', aIndent + aIndentInc);
				}
				aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"');
				if (aMode == JSONTextMode.Compact)
				{
					aSB.Append(':');
				}
				else
				{
					aSB.Append(" : ");
				}
				item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode);
			}
			if (aMode == JSONTextMode.Indent)
			{
				aSB.AppendLine().Append(' ', aIndent);
			}
			aSB.Append('}');
		}
	}
	public class JSONString : JSONNode
	{
		private string m_Data;

		public override JSONNodeType Tag => JSONNodeType.String;

		public override bool IsString => true;

		public override string Value
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONString(string aData)
		{
			m_Data = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONString(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"');
		}

		public override bool Equals(object obj)
		{
			if (base.Equals(obj))
			{
				return true;
			}
			if (obj is string text)
			{
				return m_Data == text;
			}
			JSONString jSONString = obj as JSONString;
			if (jSONString != null)
			{
				return m_Data == jSONString.m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = "";
		}
	}
	public class JSONNumber : JSONNode
	{
		private double m_Data;

		public override JSONNodeType Tag => JSONNodeType.Number;

		public override bool IsNumber => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString(CultureInfo.InvariantCulture);
			}
			set
			{
				if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override double AsDouble
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override long AsLong
		{
			get
			{
				return (long)m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override ulong AsULong
		{
			get
			{
				return (ulong)m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONNumber(double aData)
		{
			m_Data = aData;
		}

		public JSONNumber(string aData)
		{
			Value = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONNumber(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(Value.ToString(CultureInfo.InvariantCulture));
		}

		private static bool IsNumeric(object value)
		{
			if (!(value is int) && !(value is uint) && !(value is float) && !(value is double) && !(value is decimal) && !(value is long) && !(value is ulong) && !(value is short) && !(value is ushort) && !(value is sbyte))
			{
				return value is byte;
			}
			return true;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (base.Equals(obj))
			{
				return true;
			}
			JSONNumber jSONNumber = obj as JSONNumber;
			if (jSONNumber != null)
			{
				return m_Data == jSONNumber.m_Data;
			}
			if (IsNumeric(obj))
			{
				return Convert.ToDouble(obj) == m_Data;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = 0.0;
		}
	}
	public class JSONBool : JSONNode
	{
		private bool m_Data;

		public override JSONNodeType Tag => JSONNodeType.Boolean;

		public override bool IsBoolean => true;

		public override string Value
		{
			get
			{
				return m_Data.ToString();
			}
			set
			{
				if (bool.TryParse(value, out var result))
				{
					m_Data = result;
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				return m_Data;
			}
			set
			{
				m_Data = value;
			}
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONBool(bool aData)
		{
			m_Data = aData;
		}

		public JSONBool(string aData)
		{
			Value = aData;
		}

		public override JSONNode Clone()
		{
			return new JSONBool(m_Data);
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append(m_Data ? "true" : "false");
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (obj is bool)
			{
				return m_Data == (bool)obj;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return m_Data.GetHashCode();
		}

		public override void Clear()
		{
			m_Data = false;
		}
	}
	public class JSONNull : JSONNode
	{
		private static JSONNull m_StaticInstance = new JSONNull();

		public static bool reuseSameInstance = true;

		public override JSONNodeType Tag => JSONNodeType.NullValue;

		public override bool IsNull => true;

		public override string Value
		{
			get
			{
				return "null";
			}
			set
			{
			}
		}

		public override bool AsBool
		{
			get
			{
				return false;
			}
			set
			{
			}
		}

		public static JSONNull CreateOrGet()
		{
			if (reuseSameInstance)
			{
				return m_StaticInstance;
			}
			return new JSONNull();
		}

		private JSONNull()
		{
		}

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public override JSONNode Clone()
		{
			return CreateOrGet();
		}

		public override bool Equals(object obj)
		{
			if ((object)this == obj)
			{
				return true;
			}
			return obj is JSONNull;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	internal class JSONLazyCreator : JSONNode
	{
		private JSONNode m_Node;

		private string m_Key;

		public override JSONNodeType Tag => JSONNodeType.None;

		public override JSONNode this[int aIndex]
		{
			get
			{
				return new JSONLazyCreator(this);
			}
			set
			{
				Set(new JSONArray()).Add(value);
			}
		}

		public override JSONNode this[string aKey]
		{
			get
			{
				return new JSONLazyCreator(this, aKey);
			}
			set
			{
				Set(new JSONObject()).Add(aKey, value);
			}
		}

		public override int AsInt
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override float AsFloat
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0f;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override double AsDouble
		{
			get
			{
				Set(new JSONNumber(0.0));
				return 0.0;
			}
			set
			{
				Set(new JSONNumber(value));
			}
		}

		public override long AsLong
		{
			get
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString("0"));
				}
				else
				{
					Set(new JSONNumber(0.0));
				}
				return 0L;
			}
			set
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString(value.ToString(CultureInfo.InvariantCulture)));
				}
				else
				{
					Set(new JSONNumber(value));
				}
			}
		}

		public override ulong AsULong
		{
			get
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString("0"));
				}
				else
				{
					Set(new JSONNumber(0.0));
				}
				return 0uL;
			}
			set
			{
				if (JSONNode.longAsString)
				{
					Set(new JSONString(value.ToString(CultureInfo.InvariantCulture)));
				}
				else
				{
					Set(new JSONNumber(value));
				}
			}
		}

		public override bool AsBool
		{
			get
			{
				Set(new JSONBool(aData: false));
				return false;
			}
			set
			{
				Set(new JSONBool(value));
			}
		}

		public override JSONArray AsArray => Set(new JSONArray());

		public override JSONObject AsObject => Set(new JSONObject());

		public override Enumerator GetEnumerator()
		{
			return default(Enumerator);
		}

		public JSONLazyCreator(JSONNode aNode)
		{
			m_Node = aNode;
			m_Key = null;
		}

		public JSONLazyCreator(JSONNode aNode, string aKey)
		{
			m_Node = aNode;
			m_Key = aKey;
		}

		private T Set<T>(T aVal) where T : JSONNode
		{
			if (m_Key == null)
			{
				m_Node.Add(aVal);
			}
			else
			{
				m_Node.Add(m_Key, aVal);
			}
			m_Node = null;
			return aVal;
		}

		public override void Add(JSONNode aItem)
		{
			Set(new JSONArray()).Add(aItem);
		}

		public override void Add(string aKey, JSONNode aItem)
		{
			Set(new JSONObject()).Add(aKey, aItem);
		}

		public static bool operator ==(JSONLazyCreator a, object b)
		{
			if (b == null)
			{
				return true;
			}
			return (object)a == b;
		}

		public static bool operator !=(JSONLazyCreator a, object b)
		{
			return !(a == b);
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return true;
			}
			return (object)this == obj;
		}

		public override int GetHashCode()
		{
			return 0;
		}

		internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode)
		{
			aSB.Append("null");
		}
	}
	public static class JSON
	{
		public static JSONNode Parse(string aJSON)
		{
			return JSONNode.Parse(aJSON);
		}
	}
}
namespace SullysAutoPinner
{
	public class ConfigWatcher : IDisposable
	{
		private readonly string _filePath;

		private readonly ManualLogSource _logger;

		private readonly Action _onConfigChanged;

		private FileSystemWatcher _watcher;

		private Timer _debounceTimer;

		public ConfigWatcher(string filePath, Action onConfigChanged, ManualLogSource logger)
		{
			_filePath = filePath;
			_onConfigChanged = onConfigChanged;
			_logger = logger;
			if (!File.Exists(filePath))
			{
				_logger.LogWarning((object)("[ConfigWatcher] File does not exist yet: " + filePath));
				return;
			}
			string directoryName = Path.GetDirectoryName(filePath);
			string fileName = Path.GetFileName(filePath);
			_watcher = new FileSystemWatcher(directoryName, fileName)
			{
				NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite),
				EnableRaisingEvents = true
			};
			_watcher.Changed += OnChanged;
			_watcher.Renamed += OnChanged;
			_logger.LogInfo((object)("[ConfigWatcher] Watching for changes: " + filePath));
		}

		private void OnChanged(object sender, FileSystemEventArgs e)
		{
			_debounceTimer?.Dispose();
			_debounceTimer = new Timer(delegate
			{
				try
				{
					_logger.LogInfo((object)("[ConfigWatcher] Detected config change: " + _filePath));
					_onConfigChanged?.Invoke();
				}
				catch (Exception ex)
				{
					_logger.LogWarning((object)("[ConfigWatcher] Reload failed: " + ex.Message));
				}
			}, null, 300, -1);
		}

		public void Dispose()
		{
			_watcher?.Dispose();
			_debounceTimer?.Dispose();
		}
	}
	[BepInPlugin("sullys.autopinner", "Sullys Auto Pinner", "1.4.0")]
	public class SullysAutoPinner : BaseUnityPlugin
	{
		private PinManager _pinManager;

		private ModConfig _config;

		private PinScanner _scanner;

		private PrefabTracker _prefabTracker;

		private float _lastScanTime;

		private LocalizationManager _localizationManager;

		private ConfigWatcher _configWatcher;

		private void Awake()
		{
			_config = new ModConfig(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
			string filePath = Path.Combine(Paths.ConfigPath, "sullys.autopinner.cfg");
			_configWatcher = new ConfigWatcher(filePath, OnConfigReloaded, ((BaseUnityPlugin)this).Logger);
			LocalizationManager.EnsureBaseLanguageFiles(((BaseUnityPlugin)this).Logger);
			_localizationManager = new LocalizationManager(((BaseUnityPlugin)this).Logger, _config.PreferredLanguage.Value);
			_pinManager = new PinManager(_config, ((BaseUnityPlugin)this).Logger, _localizationManager);
			_prefabTracker = new PrefabTracker(((BaseUnityPlugin)this).Logger, _config);
			_scanner = new PinScanner(_config, _pinManager, _prefabTracker);
			((BaseUnityPlugin)this).Logger.LogWarning((object)"SullysAutoPinner Initialized");
		}

		private void OnConfigReloaded()
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Reloading config from file...");
			((BaseUnityPlugin)this).Config.Reload();
			_localizationManager.Reload(_config.PreferredLanguage.Value);
			_pinManager.ReloadConfig();
			if (_config.ClearAllUnwantedPins.Value)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Remove Unwanted Pins Triggered");
				_pinManager.RemoveUnwantedPins(_config);
				_config.ClearAllUnwantedPins.Value = false;
			}
			if (_config.ClearAllMapPinsAndHistory.Value)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Remove All Pins and History Triggered");
				_pinManager.RemoveAllPins();
				_config.ClearAllMapPinsAndHistory.Value = false;
			}
		}

		private void Update()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				if (Time.time - _lastScanTime > _config.ScanInterval.Value)
				{
					_lastScanTime = Time.time;
					_scanner.RunScan(((Component)Player.m_localPlayer).transform.position);
				}
				_pinManager.TryPeriodicSave();
				_prefabTracker.TryPeriodicSave();
			}
		}

		private void OnApplicationQuit()
		{
			_pinManager.SaveImmediate();
			_prefabTracker.SaveImmediate();
		}
	}
	public class PrefabTracker
	{
		private readonly HashSet<string> _seenPrefabs = new HashSet<string>();

		private readonly ManualLogSource _logger;

		private readonly ModConfig _config;

		private float _lastPrefabDumpTime;

		private const float DumpInterval = 300f;

		private const int PrefabFlushThreshold = 1000;

		private const string PrefabsFilePath = "BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt";

		private static readonly HashSet<string> IgnoredPrefabs = new HashSet<string> { "tree", "bush", "log", "stone", "branch" };

		public PrefabTracker(ManualLogSource logger, ModConfig config)
		{
			_logger = logger;
			_config = config;
			Directory.CreateDirectory(Path.GetDirectoryName("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt"));
		}

		public void LogPrefabHierarchy(GameObject rootGO)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			if (!_config.EnablePrefabLogging.Value || (Object)(object)rootGO == (Object)null)
			{
				return;
			}
			string text = ((Object)rootGO).name.ToLowerInvariant();
			foreach (string ignoredPrefab in IgnoredPrefabs)
			{
				if (text.Contains(ignoredPrefab))
				{
					return;
				}
			}
			List<string> list = new List<string>();
			foreach (Transform item2 in rootGO.transform)
			{
				Transform val = item2;
				if ((Object)(object)val != (Object)null)
				{
					list.Add(((Object)val).name);
				}
			}
			list.Sort();
			string item = ((Object)rootGO).name + " | " + string.Join(",", list);
			if (_seenPrefabs.Add(item) && _seenPrefabs.Count >= 1000)
			{
				SaveImmediate();
			}
		}

		public void TryPeriodicSave()
		{
			if (_config.EnablePrefabLogging.Value && Time.time - _lastPrefabDumpTime > 300f)
			{
				SaveImmediate();
			}
		}

		public void SaveImmediate()
		{
			_lastPrefabDumpTime = Time.time;
			try
			{
				HashSet<string> hashSet = new HashSet<string>();
				if (File.Exists("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt"))
				{
					string[] array = File.ReadAllLines("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt");
					foreach (string item in array)
					{
						hashSet.Add(item);
					}
				}
				using StreamWriter streamWriter = File.AppendText("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt");
				foreach (string seenPrefab in _seenPrefabs)
				{
					if (!hashSet.Contains(seenPrefab))
					{
						streamWriter.WriteLine(seenPrefab);
					}
				}
			}
			catch (Exception ex)
			{
				_logger.LogWarning((object)("SullyAutoPinner >>> Error saving prefab list: " + ex.Message));
			}
		}
	}
	public class PinScanner
	{
		public static class PinLabelMap
		{
			public static readonly Dictionary<string, (string SettingKey, PinType Icon)> LabelToSettingInfo = new Dictionary<string, (string, PinType)>(StringComparer.OrdinalIgnoreCase)
			{
				{
					"abomination",
					("Abomination", (PinType)3)
				},
				{
					"crypt2",
					("Crypt", (PinType)3)
				},
				{
					"crypt3",
					("Crypt", (PinType)3)
				},
				{
					"crypt4",
					("Crypt", (PinType)3)
				},
				{
					"trollcave",
					("TrollCave", (PinType)3)
				},
				{
					"dwarfspawner",
					("DwarfSpawner", (PinType)2)
				},
				{
					"draugrspawner",
					("DraugrSpawner", (PinType)2)
				},
				{
					"totem",
					("Totem", (PinType)2)
				},
				{
					"skel",
					("Skeleton", (PinType)3)
				},
				{
					"seekerbrute",
					("SeekerBrute", (PinType)3)
				},
				{
					"bonemawserpent",
					("BonemawSerpent", (PinType)3)
				},
				{
					"rock4_copper",
					("Copper", (PinType)3)
				},
				{
					"iron_deposit",
					("Iron", (PinType)3)
				},
				{
					"mudpile",
					("Mudpile", (PinType)3)
				},
				{
					"obsidian",
					("Obsidian", (PinType)3)
				},
				{
					"rock3_silver",
					("Silver", (PinType)3)
				},
				{
					"silvervein",
					("Silver", (PinType)3)
				},
				{
					"meteor",
					("Meteorite", (PinType)3)
				},
				{
					"pickable_tar",
					("Tar", (PinType)2)
				},
				{
					"pickable_flax_wild",
					("Flax", (PinType)3)
				},
				{
					"flax",
					("Flax", (PinType)3)
				},
				{
					"barley",
					("Barley", (PinType)3)
				},
				{
					"blueberry",
					("BlueBerries", (PinType)3)
				},
				{
					"raspberry",
					("RaspBerries", (PinType)3)
				},
				{
					"shroom",
					("Mushrooms", (PinType)3)
				},
				{
					"cloud",
					("CloudBerries", (PinType)3)
				},
				{
					"thistle",
					("Thistle", (PinType)3)
				},
				{
					"carrot",
					("Seeds", (PinType)3)
				},
				{
					"onion",
					("Seeds", (PinType)3)
				},
				{
					"turnip",
					("Seeds", (PinType)3)
				},
				{
					"magecap",
					("MageCaps", (PinType)3)
				},
				{
					"y-pcone",
					("YPCones", (PinType)3)
				},
				{
					"j-puff",
					("JotunPuffs", (PinType)3)
				},
				{
					"v-egg",
					("VoltureEgg", (PinType)3)
				},
				{
					"dragonegg",
					("DragonEgg", (PinType)3)
				},
				{
					"pickable_smokepuff",
					("SmokePuffs", (PinType)3)
				},
				{
					"thing",
					("DvergerThings", (PinType)3)
				},
				{
					"giant_sword1",
					("GiantSword", (PinType)3)
				},
				{
					"giant_ribs",
					("GiantRibs", (PinType)3)
				},
				{
					"giant_skull",
					("GiantSkull", (PinType)3)
				},
				{
					"giant_brain",
					("GiantBrain", (PinType)3)
				},
				{
					"marker",
					("Marker", (PinType)2)
				},
				{
					"campfire",
					("Fire", (PinType)0)
				},
				{
					"firepit",
					("Fire", (PinType)0)
				},
				{
					"treasurechest",
					("Treasure", (PinType)3)
				},
				{
					"shipwreck_karve_chest",
					("ShipwreckChest", (PinType)3)
				},
				{
					"pickable_dvergrlantern",
					("Lantern", (PinType)3)
				},
				{
					"mistlands_excavation2",
					("Excavation", (PinType)3)
				},
				{
					"ashland_pot1_green",
					("AshlandPotGreen", (PinType)3)
				},
				{
					"ashland_pot2_red",
					("AshlandPotRed", (PinType)3)
				},
				{
					"ashland_pot3_red",
					("AshlandPotRed", (PinType)3)
				}
			};
		}

		private readonly ModConfig _config;

		private readonly PinManager _pinManager;

		private readonly PrefabTracker _prefabTracker;

		public PinScanner(ModConfig config, PinManager pinManager, PrefabTracker prefabTracker)
		{
			_config = config;
			_pinManager = pinManager;
			_prefabTracker = prefabTracker;
		}

		public void RunScan(Vector3 playerPosition)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			if (_config.ClearNearbyFallbackPinsOnNextScan.Value)
			{
				_pinManager.RemoveNearbyFallbackPins(playerPosition, _config.ScanRadius.Value);
				_config.ClearNearbyFallbackPinsOnNextScan.Value = false;
			}
			if (playerPosition.y > 1000f)
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(playerPosition, _config.ScanRadius.Value, -1, (QueryTriggerInteraction)2);
			List<Vector3> list = new List<Vector3>();
			List<(Vector3, Transform)> list2 = new List<(Vector3, Transform)>();
			Collider[] array2 = array;
			foreach (Collider obj in array2)
			{
				GameObject gameObject = ((Component)((Component)obj).transform.root).gameObject;
				if ((Object)(object)gameObject == (Object)null)
				{
					continue;
				}
				_prefabTracker.LogPrefabHierarchy(gameObject);
				string text = ((Object)gameObject).name.ToLowerInvariant();
				Vector3 pinPos2 = gameObject.transform.position;
				string matchedLabel;
				PinType icon;
				if (text.Contains("locationproxy"))
				{
					list2.Add((pinPos2, gameObject.transform));
				}
				else if (TryMatchPrefab(text, out matchedLabel, out icon))
				{
					if (matchedLabel == "TROLLCAVE")
					{
						list.Add(pinPos2);
					}
					if (!(matchedLabel == "CRYPT") || !list.Any((Vector3 tc) => Vector3.Distance(tc, pinPos2) < 40f))
					{
						_pinManager.TryAddPin(pinPos2, matchedLabel, icon);
					}
				}
			}
			foreach (var item in list2)
			{
				var (val, _) = item;
				foreach (Transform item2 in item.Item2)
				{
					string text2 = ((Object)item2).name.ToLowerInvariant();
					if (!text2.Contains("runestone") && TryMatchPrefab(text2, out var matchedLabel2, out var icon2))
					{
						if (matchedLabel2 == "TROLLCAVE")
						{
							list.Add(val);
							_pinManager.TryAddPin(val, matchedLabel2, icon2);
						}
						break;
					}
				}
			}
			foreach (var item3 in list2)
			{
				var (pinPos, _) = item3;
				foreach (Transform item4 in item3.Item2)
				{
					string text3 = ((Object)item4).name.ToLowerInvariant();
					if (!text3.Contains("runestone") && TryMatchPrefab(text3, out var matchedLabel3, out var icon3))
					{
						if (!(matchedLabel3 == "TROLLCAVE") && (!(matchedLabel3 == "CRYPT") || !list.Any((Vector3 tc) => Vector3.Distance(tc, pinPos) < 40f)))
						{
							_pinManager.TryAddPin(pinPos, matchedLabel3, icon3);
						}
						break;
					}
				}
			}
		}

		private string CleanLabel(string rawName)
		{
			return Regex.Replace(rawName.Replace("(Clone)", ""), "\\d", "").ToUpperInvariant();
		}

		private bool TryMatchPrefab(string prefabName, out string matchedLabel, out PinType icon)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected I4, but got Unknown
			matchedLabel = null;
			icon = (PinType)3;
			foreach (KeyValuePair<string, (string, PinType)> item2 in PinLabelMap.LabelToSettingInfo)
			{
				if (prefabName.IndexOf(item2.Key, StringComparison.OrdinalIgnoreCase) < 0)
				{
					continue;
				}
				string item = item2.Value.Item1;
				FieldInfo field = typeof(ModConfig).GetField(item, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);
				if (!(field == null) && !(field.FieldType != typeof(ConfigEntry<bool>)))
				{
					ConfigEntry<bool> val = (ConfigEntry<bool>)field.GetValue(_config);
					if (val != null && val.Value)
					{
						matchedLabel = item.ToUpperInvariant();
						icon = (PinType)(int)item2.Value.Item2;
						return true;
					}
				}
			}
			if (_config.ShowUnmappedPrefabs.Value)
			{
				string[] array = new string[85]
				{
					"beech", "berry", "birch", "boar", "branch", "bush", "dandelion", "deer", "feathers", "fish",
					"firtree", "fur", "goblin", "goblin_archer", "goblin_banner", "goblin_bed", "goblin_fence", "goblin_pole", "goblin_roof", "goblin_roof_cap",
					"goblin_shaman", "goblin_stepladder", "greyling", "greydwarf", "mushroom", "neck", "oak1", "pickable_dolmentreasure", "pickable_forestcryptremains", "pickable_flint",
					"pickable_stone", "player", "pine", "piece_sharpstakes", "piece_workbench", "berries", "resin", "seagal", "shrub", "stone",
					"stone_wall", "stubbe", "vines", "wood", "zone", "pillar", "carrot", "turnip", "onion", "thistle",
					"minerock_tin", "crow", "odin", "pickable_tar", "tarliquid", "skeleton", "deathsquito", "forestcrypt", "swamptree", "wraith",
					"statue", "leech", "table", "draugr", "blob", "oak", "leather", "log", "meat", "seed",
					"bonefragments", "honey", "forge", "entrails", "bonepile", "castlekit", "trophy", "sunken", "root", "guck",
					"swamp", "grave", "piece", "rock_3", "rock_4"
				};
				foreach (string value in array)
				{
					if (prefabName.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return false;
					}
				}
				matchedLabel = prefabName.Replace("(clone)", "");
				icon = (PinType)2;
				return true;
			}
			return false;
		}
	}
	public class ModConfig
	{
		private readonly ManualLogSource _logger;

		public ConfigEntry<string> PreferredLanguage;

		public ConfigEntry<float> ScanRadius;

		public ConfigEntry<float> ScanInterval;

		public ConfigEntry<float> SaveInterval;

		public ConfigEntry<float> PinMergeDistance;

		public ConfigEntry<bool> EnablePinSaving;

		public ConfigEntry<bool> EnablePrefabLogging;

		public ConfigEntry<bool> ClearAllMapPinsAndHistory;

		public ConfigEntry<bool> ClearAllUnwantedPins;

		public ConfigEntry<bool> ClearNearbyFallbackPinsOnNextScan;

		public ConfigEntry<bool> ShowUnmappedPrefabs;

		public ConfigEntry<bool> Abomination;

		public ConfigEntry<bool> AshlandPotGreen;

		public ConfigEntry<bool> AshlandPotRed;

		public ConfigEntry<bool> Barley;

		public ConfigEntry<bool> BlueBerries;

		public ConfigEntry<bool> BonemawSerpent;

		public ConfigEntry<bool> CloudBerries;

		public ConfigEntry<bool> Copper;

		public ConfigEntry<bool> Crypt;

		public ConfigEntry<bool> DragonEgg;

		public ConfigEntry<bool> DraugrSpawner;

		public ConfigEntry<bool> DvergerThings;

		public ConfigEntry<bool> DwarfSpawner;

		public ConfigEntry<bool> Excavation;

		public ConfigEntry<bool> Fire;

		public ConfigEntry<bool> Flax;

		public ConfigEntry<bool> GiantBrain;

		public ConfigEntry<bool> GiantRibs;

		public ConfigEntry<bool> GiantSkull;

		public ConfigEntry<bool> GiantSword;

		public ConfigEntry<bool> Iron;

		public ConfigEntry<bool> JotunPuffs;

		public ConfigEntry<bool> Lantern;

		public ConfigEntry<bool> MageCaps;

		public ConfigEntry<bool> Marker;

		public ConfigEntry<bool> Meteorite;

		public ConfigEntry<bool> MistlandsGiants;

		public ConfigEntry<bool> MistlandsSwords;

		public ConfigEntry<bool> Mudpile;

		public ConfigEntry<bool> Mushrooms;

		public ConfigEntry<bool> Obsidian;

		public ConfigEntry<bool> Onion;

		public ConfigEntry<bool> PickableSmokePuff;

		public ConfigEntry<bool> RaspBerries;

		public ConfigEntry<bool> Seeds;

		public ConfigEntry<bool> SeekerBrute;

		public ConfigEntry<bool> ShipwreckChest;

		public ConfigEntry<bool> Silver;

		public ConfigEntry<bool> Skeleton;

		public ConfigEntry<bool> SmokePuffs;

		public ConfigEntry<bool> Tar;

		public ConfigEntry<bool> Thistle;

		public ConfigEntry<bool> Tin;

		public ConfigEntry<bool> Totem;

		public ConfigEntry<bool> Treasure;

		public ConfigEntry<bool> TrollCave;

		public ConfigEntry<bool> Turnip;

		public ConfigEntry<bool> VoltureEgg;

		public ConfigEntry<bool> YPCones;

		public ModConfig(ConfigFile config, ManualLogSource logger)
		{
			_logger = logger;
			PreferredLanguage = config.Bind<string>("Localization", "LanguageCode", "en", "Language code for localization (en, fr, ru, etc).");
			ScanRadius = config.Bind<float>("Scanning", "ScanRadius", 300f, "Radius (in meters) to scan for prefabs.");
			ScanInterval = config.Bind<float>("Scanning", "ScanInterval", 12f, "Time (in seconds) between environment scans.");
			SaveInterval = config.Bind<float>("Persistence", "SaveInterval", 120f, "How often to save pins to disk (in seconds).");
			PinMergeDistance = config.Bind<float>("Pins", "PinMergeDistance", 50f, "Distance (in meters) at which duplicate pins are merged.");
			EnablePinSaving = config.Bind<bool>("Persistence", "EnablePinSaving", true, "Enable saving of detected pins.");
			EnablePrefabLogging = config.Bind<bool>("Debug", "EnablePrefabLogging", false, "Enable logging of prefab names and hierarchy for debugging.");
			ClearAllMapPinsAndHistory = config.Bind<bool>("Admin", "ClearAllMapPinsAndHistory", false, "Clear all pins and reset history file on next run.");
			ClearAllUnwantedPins = config.Bind<bool>("Admin", "ClearAllUnwantedPins", false, "Clear only pins that do not match active settings.");
			ClearNearbyFallbackPinsOnNextScan = config.Bind<bool>("Admin", "ClearNearbyFallbackPinsOnNextScan", false, "Remove fallback pins near the player on next scan.");
			ShowUnmappedPrefabs = config.Bind<bool>("Fallback", "ShowUnmappedPrefabs", false, "Create pins for unknown prefabs using prefab name.");
			Mushrooms = config.Bind<bool>("Pins", "Mushrooms", false, "");
			RaspBerries = config.Bind<bool>("Pins", "RaspBerries", false, "");
			BlueBerries = config.Bind<bool>("Pins", "BlueBerries", false, "");
			Seeds = config.Bind<bool>("Pins", "Seeds", false, "");
			Thistle = config.Bind<bool>("Pins", "Thistle", false, "");
			CloudBerries = config.Bind<bool>("Pins", "CloudBerries", false, "");
			Copper = config.Bind<bool>("Pins", "Copper", true, "");
			Tin = config.Bind<bool>("Pins", "Tin", false, "");
			Skeleton = config.Bind<bool>("Pins", "Skeleton", false, "");
			DwarfSpawner = config.Bind<bool>("Pins", "DwarfSpawner", true, "");
			TrollCave = config.Bind<bool>("Pins", "TrollCave", true, "");
			Crypt = config.Bind<bool>("Pins", "Crypt", true, "");
			Totem = config.Bind<bool>("Pins", "Totem", true, "");
			Fire = config.Bind<bool>("Pins", "Fire", true, "");
			DraugrSpawner = config.Bind<bool>("Pins", "DraugrSpawner", false, "");
			Treasure = config.Bind<bool>("Pins", "Treasure", false, "");
			Barley = config.Bind<bool>("Pins", "Barley", false, "");
			Flax = config.Bind<bool>("Pins", "Flax", false, "");
			Tar = config.Bind<bool>("Pins", "Tar", true, "");
			DragonEgg = config.Bind<bool>("Pins", "DragonEgg", true, "");
			VoltureEgg = config.Bind<bool>("Pins", "VoltureEgg", true, "");
			SmokePuffs = config.Bind<bool>("Pins", "SmokePuffs", false, "");
			MageCaps = config.Bind<bool>("Pins", "MageCaps", true, "");
			YPCones = config.Bind<bool>("Pins", "YPCones", true, "");
			JotunPuffs = config.Bind<bool>("Pins", "JotunPuffs", true, "");
			Iron = config.Bind<bool>("Pins", "Iron", true, "");
			Mudpile = config.Bind<bool>("Pins", "Mudpile", true, "");
			Abomination = config.Bind<bool>("Pins", "Abomination", true, "");
			Meteorite = config.Bind<bool>("Pins", "Meteorite", true, "");
			Obsidian = config.Bind<bool>("Pins", "Obsidian", true, "");
			Silver = config.Bind<bool>("Pins", "Silver", true, "");
			MistlandsGiants = config.Bind<bool>("Pins", "MistlandsGiants", true, "");
			MistlandsSwords = config.Bind<bool>("Pins", "MistlandsSwords", true, "");
			DvergerThings = config.Bind<bool>("Pins", "DvergerThings", true, "");
			BonemawSerpent = config.Bind<bool>("Pins", "BonemawSerpent", true, "");
			GiantSword = config.Bind<bool>("Pins", "GiantSword", true, "");
			GiantRibs = config.Bind<bool>("Pins", "GiantRibs", true, "");
			GiantSkull = config.Bind<bool>("Pins", "GiantSkull", true, "");
			GiantBrain = config.Bind<bool>("Pins", "GiantBrain", true, "");
			Lantern = config.Bind<bool>("Pins", "Lantern", true, "");
			Excavation = config.Bind<bool>("Pins", "Excavation", true, "");
			AshlandPotGreen = config.Bind<bool>("Pins", "AshlandPotGreen", true, "");
			AshlandPotRed = config.Bind<bool>("Pins", "AshlandPotRed", true, "");
			ShipwreckChest = config.Bind<bool>("Pins", "ShipwreckChest", true, "");
			SeekerBrute = config.Bind<bool>("Pins", "SeekerBrute", true, "");
			Marker = config.Bind<bool>("Pins", "Marker", true, "");
		}
	}
}