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.Logging;
using HarmonyLib;
using SimpleJSON;
using Splatform;
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")]
[BepInPlugin("sullys.autopinner", "Sullys Auto Pinner", "1.3.1")]
public class SullysAutoPinner : BaseUnityPlugin
{
private PinSettings _settings;
private PinManager _pinManager;
private ConfigLoader _configLoader;
private PinScanner _scanner;
private PrefabTracker _prefabTracker;
private float _lastScanTime;
private LocalizationManager _localizationManager;
private void Awake()
{
_configLoader = new ConfigLoader(((BaseUnityPlugin)this).Logger);
_settings = _configLoader.Load();
LocalizationManager.EnsureBaseLanguageFiles(((BaseUnityPlugin)this).Logger);
_localizationManager = new LocalizationManager(((BaseUnityPlugin)this).Logger, _settings.LanguageCode);
_pinManager = new PinManager(_settings, ((BaseUnityPlugin)this).Logger, _localizationManager);
_prefabTracker = new PrefabTracker(((BaseUnityPlugin)this).Logger, _settings);
_scanner = new PinScanner(_settings, _pinManager, _prefabTracker);
_configLoader.EnableHotReload(delegate
{
_settings = _configLoader.Load();
_localizationManager = new LocalizationManager(((BaseUnityPlugin)this).Logger, _settings.LanguageCode);
_pinManager = new PinManager(_settings, ((BaseUnityPlugin)this).Logger, _localizationManager);
_scanner = new PinScanner(_settings, _pinManager, _prefabTracker);
_lastScanTime = 0f;
if (_settings.ClearAllMapPinsAndHistory)
{
_pinManager.RemoveAllPins();
_settings.ClearAllMapPinsAndHistory = false;
_configLoader.SaveDefault(_settings);
((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] All map pins cleared and config flag reset.");
}
if (_settings.ClearAllUnwantedPins)
{
_pinManager.RemoveUnwantedPins(_settings);
_settings.ClearAllUnwantedPins = false;
_configLoader.SaveDefault(_settings);
((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Unwanted pins cleared and config flag reset.");
}
((BaseUnityPlugin)this).Logger.LogWarning((object)"[SullysAutoPinner] Config hot-reloaded — scanner and localization reloaded.");
});
((BaseUnityPlugin)this).Logger.LogWarning((object)"SullysAutoPinner Initialized");
}
private void Update()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Player.m_localPlayer == (Object)null))
{
if (Time.time - _lastScanTime > _settings.ScanInterval)
{
_lastScanTime = Time.time;
_scanner.RunScan(((Component)Player.m_localPlayer).transform.position);
}
_pinManager.TryPeriodicSave();
_prefabTracker.TryPeriodicSave();
}
}
private void OnApplicationQuit()
{
_pinManager.SaveImmediate();
_prefabTracker.SaveImmediate();
}
}
public class ConfigLoader
{
private static readonly string SaveFolder = Path.Combine(Paths.ConfigPath, "SullysAutoPinnerFiles");
private static readonly string ConfigFilePath = Path.Combine(SaveFolder, "SullysAutoPinner.cfg");
private readonly ManualLogSource _logger;
private FileSystemWatcher _watcher;
private Timer _debounceTimer;
private Action _onReload;
public ConfigLoader(ManualLogSource logger)
{
_logger = logger;
Directory.CreateDirectory(SaveFolder);
}
public void EnableHotReload(Action onReload)
{
_onReload = onReload;
_watcher = new FileSystemWatcher(SaveFolder, "SullysAutoPinner.cfg")
{
NotifyFilter = (NotifyFilters.Size | NotifyFilters.LastWrite)
};
_watcher.Changed += OnConfigChanged;
_watcher.Renamed += OnConfigChanged;
_watcher.EnableRaisingEvents = true;
_logger.LogWarning((object)"[ConfigLoader] Hot config reload enabled.");
}
private void OnConfigChanged(object sender, FileSystemEventArgs e)
{
_debounceTimer?.Dispose();
_debounceTimer = new Timer(delegate
{
try
{
_logger.LogWarning((object)"[ConfigLoader] Config file updated — reloading.");
_onReload?.Invoke();
}
catch (Exception ex)
{
_logger.LogWarning((object)("[ConfigLoader] Reload failed: " + ex.Message));
}
}, null, 200, -1);
}
public PinSettings Load()
{
PinSettings pinSettings = new PinSettings();
Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
if (File.Exists(ConfigFilePath))
{
string[] array = File.ReadAllLines(ConfigFilePath);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (!text.StartsWith("#") && text.Contains("="))
{
string[] array2 = text.Split(new char[1] { '=' }, 2);
dictionary[array2[0].Trim().ToLowerInvariant()] = array2[1].Trim().ToLowerInvariant();
}
}
foreach (KeyValuePair<string, string> item in dictionary)
{
ApplyKeyValue(pinSettings, item.Key, item.Value);
}
List<string> list = (from f in typeof(PinSettings).GetFields()
where f.FieldType == typeof(bool)
select f.Name.ToLowerInvariant()).ToHashSet().Except(dictionary.Keys).ToList();
array = new string[2] { "clearallmappinsandhistory", "clearallunwantedpins" };
foreach (string text2 in array)
{
if (!dictionary.ContainsKey(text2) && !list.Contains(text2))
{
list.Add(text2);
}
}
if (list.Any())
{
AppendMissingDefaults(pinSettings, list);
}
}
else
{
SaveDefault(pinSettings);
}
return pinSettings;
}
private void ApplyKeyValue(PinSettings settings, string key, string value)
{
bool flag = value.Equals("true", StringComparison.OrdinalIgnoreCase);
float result;
switch (key)
{
case "scanradius":
if (float.TryParse(value, out result))
{
settings.ScanRadius = result;
}
return;
case "scaninterval":
if (float.TryParse(value, out result))
{
settings.ScanInterval = result;
}
return;
case "saveinterval":
if (float.TryParse(value, out result))
{
settings.SaveInterval = result;
}
return;
case "pinmergedistance":
if (float.TryParse(value, out result))
{
settings.PinMergeDistance = result;
}
return;
}
FieldInfo fieldInfo = typeof(PinSettings).GetFields().FirstOrDefault((FieldInfo f) => f.Name.Equals(key, StringComparison.OrdinalIgnoreCase));
if (fieldInfo != null && fieldInfo.FieldType == typeof(bool))
{
fieldInfo.SetValue(settings, flag);
}
}
private void AppendMissingDefaults(PinSettings settings, IEnumerable<string> missingKeys)
{
try
{
using (StreamWriter streamWriter = File.AppendText(ConfigFilePath))
{
foreach (string key in missingKeys)
{
bool flag = (bool)typeof(PinSettings).GetFields().First((FieldInfo f) => f.Name.Equals(key, StringComparison.InvariantCultureIgnoreCase)).GetValue(settings);
streamWriter.WriteLine(key + "=" + flag.ToString().ToLowerInvariant());
}
}
_logger.LogWarning((object)("Appended missing config keys to: " + ConfigFilePath));
}
catch (Exception ex)
{
_logger.LogWarning((object)("Error appending missing defaults: " + ex.Message));
}
}
public void SaveDefault(PinSettings settings)
{
try
{
using (StreamWriter streamWriter = new StreamWriter(ConfigFilePath))
{
streamWriter.WriteLine("# SullysAutoPinner config");
streamWriter.WriteLine("scanradius=" + settings.ScanRadius);
streamWriter.WriteLine("scaninterval=" + settings.ScanInterval);
streamWriter.WriteLine("saveinterval=" + settings.SaveInterval);
streamWriter.WriteLine("pinmergedistance=" + settings.PinMergeDistance);
FieldInfo[] fields = typeof(PinSettings).GetFields();
foreach (FieldInfo fieldInfo in fields)
{
if (fieldInfo.FieldType == typeof(bool))
{
string text = fieldInfo.Name.ToLowerInvariant();
streamWriter.WriteLine(text + "=" + ((bool)fieldInfo.GetValue(settings)).ToString().ToLowerInvariant());
}
}
}
_logger.LogWarning((object)("Default config created at: " + ConfigFilePath));
}
catch (Exception ex)
{
_logger.LogWarning((object)("Error saving default config: " + ex.Message));
}
}
}
public class PinSettings
{
public string LanguageCode = "en";
public bool ClearNearbyFallbackPinsOnNextScan;
public bool ShowUnmappedPrefabs;
public float ScanRadius = 300f;
public float ScanInterval = 12f;
public float SaveInterval = 120f;
public float PinMergeDistance = 50f;
public bool EnablePinSaving = true;
public bool EnablePrefabLogging;
public bool Mushrooms;
public bool RaspBerries;
public bool BlueBerries;
public bool Seeds;
public bool Thistle;
public bool CloudBerries;
public bool Copper = true;
public bool Tin;
public bool Skeleton;
public bool DwarfSpawner = true;
public bool TrollCave = true;
public bool Crypt = true;
public bool Totem = true;
public bool Fire = true;
public bool DraugrSpawner;
public bool Treasure;
public bool Barley;
public bool Flax;
public bool Tar = true;
public bool DragonEgg = true;
public bool VoltureEgg = true;
public bool SmokePuffs;
public bool MageCaps = true;
public bool YPCones = true;
public bool JotunPuffs = true;
public bool Iron = true;
public bool Mudpile = true;
public bool Abomination = true;
public bool Meteorite = true;
public bool Obsidian = true;
public bool Silver = true;
public bool MistlandsGiants = true;
public bool MistlandsSwords = true;
public bool DvergerThings = true;
public bool ClearAllMapPinsAndHistory;
public bool ClearAllUnwantedPins;
}
public class PrefabTracker
{
private readonly HashSet<string> _seenPrefabs = new HashSet<string>();
private readonly ManualLogSource _logger;
private readonly PinSettings _settings;
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, PinSettings settings)
{
_logger = logger;
_settings = settings;
Directory.CreateDirectory(Path.GetDirectoryName("BepInEx/config/SullysAutoPinnerFiles/SeenPrefabs.txt"));
}
public void LogPrefabHierarchy(GameObject rootGO)
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
if (!_settings.EnablePrefabLogging || (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 (_settings.EnablePrefabLogging && 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)
},
{
"rock4_copper",
("Copper", (PinType)3)
},
{
"iron_deposit",
("Iron", (PinType)3)
},
{
"mudpile",
("Mudpile", (PinType)3)
},
{
"obsidian",
("Obsidian", (PinType)3)
},
{
"silver",
("Silver", (PinType)3)
},
{
"meteor",
("Meteorite", (PinType)3)
},
{
"flax",
("Flax", (PinType)3)
},
{
"barley",
("Barley", (PinType)3)
},
{
"blueberry",
("BlueBerries", (PinType)3)
},
{
"berries",
("RaspBerries", (PinType)3)
},
{
"shrooms",
("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)
},
{
"smokepuff",
("SmokePuffs", (PinType)3)
},
{
"thing",
("DvergerThings", (PinType)3)
},
{
"dwarfspawner",
("DwarfSpawner", (PinType)2)
},
{
"draugrspawner",
("DraugrSpawner", (PinType)2)
},
{
"totem",
("Totem", (PinType)2)
},
{
"campfire",
("Fire", (PinType)0)
},
{
"tar",
("Tar", (PinType)2)
},
{
"skel",
("Skeleton", (PinType)3)
},
{
"treasure",
("Treasure", (PinType)3)
},
{
"swords",
("MistlandsSwords", (PinType)3)
},
{
"marker",
("Marker", (PinType)2)
},
{
"giant",
("MistlandsGiants", (PinType)3)
}
};
}
private readonly PinSettings _settings;
private readonly PinManager _pinManager;
private readonly PrefabTracker _prefabTracker;
public PinScanner(PinSettings settings, PinManager pinManager, PrefabTracker prefabTracker)
{
_settings = settings;
_pinManager = pinManager;
_prefabTracker = prefabTracker;
}
public void RunScan(Vector3 playerPosition)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_0251: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
if (_settings.ClearNearbyFallbackPinsOnNextScan)
{
_pinManager.RemoveNearbyFallbackPins(playerPosition, _settings.ScanRadius);
_settings.ClearNearbyFallbackPinsOnNextScan = false;
new ConfigLoader(Logger.CreateLogSource("AutoPinner")).SaveDefault(_settings);
}
if (playerPosition.y > 1000f)
{
return;
}
Collider[] array = Physics.OverlapSphere(playerPosition, _settings.ScanRadius, -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_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: 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)
{
string item = item2.Value.Item1;
FieldInfo field = typeof(PinSettings).GetField(item);
if (!(field == null) && !(field.FieldType != typeof(bool)) && (bool)field.GetValue(_settings))
{
matchedLabel = item.ToUpperInvariant();
icon = (PinType)(int)item2.Value.Item2;
return true;
}
}
}
if (_settings.ShowUnmappedPrefabs)
{
string[] array = new string[83]
{
"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"
};
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 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";
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);
}
}
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"] = new Dictionary<string, string>
{
["COPPER"] = "Copper",
["IRON"] = "Iron",
["SILVER"] = "Silver",
["OBSIDIAN"] = "Obsidian",
["MUDPILE"] = "Mudpile",
["METEORITE"] = "Meteorite",
["TROLLCAVE"] = "Troll Cave",
["CRYPT"] = "Crypt",
["ABOMINATION"] = "Abomination",
["FLAX"] = "Flax",
["BARLEY"] = "Barley",
["BLUEBERRIES"] = "Blueberries",
["RASPBERRIES"] = "Raspberries",
["MUSHROOMS"] = "Mushrooms",
["CLOUDBERRIES"] = "Cloudberries",
["THISTLE"] = "Thistle",
["SEEDS"] = "Seeds",
["MAGECAPS"] = "Magecaps",
["YPCONES"] = "Yggdrasil Pine Cones",
["JOTUNNPUFFS"] = "Jotunn Puffs",
["VOLTUREEGG"] = "Vulture Egg",
["DRAGONEGG"] = "Dragon Egg",
["SMOKEPUFFS"] = "Smoke Puffs",
["DVERGERTHINGS"] = "Dvergr Remains",
["DWARFSPAWNER"] = "Greydwarf Nest",
["DRAUGRSPAWNER"] = "Draugr Spawner",
["TOTEM"] = "Fuling Totem",
["FIRE"] = "Campfire",
["TAR"] = "Tar Pit",
["SKELETON"] = "Skeleton",
["TREASURE"] = "Buried Treasure",
["MISTLANDSSWORDS"] = "Sword in the Stone",
["MISTLANDSGIANTS"] = "Giant Remains",
["MARKER"] = "Marker"
},
["ru"] = new Dictionary<string, string>
{
["COPPER"] = "Медь",
["IRON"] = "Железо",
["SILVER"] = "Серебро",
["OBSIDIAN"] = "Обсидиан",
["MUDPILE"] = "Грязевая куча",
["METEORITE"] = "Метеорит",
["TROLLCAVE"] = "Пещера тролля",
["CRYPT"] = "Крипта",
["ABOMINATION"] = "Мерзость",
["FLAX"] = "Лён",
["BARLEY"] = "Ячмень",
["BLUEBERRIES"] = "Черника",
["RASPBERRIES"] = "Малина",
["MUSHROOMS"] = "Грибы",
["CLOUDBERRIES"] = "Морошка",
["THISTLE"] = "Чертополох",
["SEEDS"] = "Семена",
["MAGECAPS"] = "Волшебные шляпки",
["YPCONES"] = "Шишки Иггдрасиля",
["JOTUNNPUFFS"] = "Пух Йотуна",
["VOLTUREEGG"] = "Яйцо стервятника",
["DRAGONEGG"] = "Яйцо дракона",
["SMOKEPUFFS"] = "Клубы дыма",
["DVERGERTHINGS"] = "Останки двергров",
["DWARFSPAWNER"] = "Гнездо серого карлика",
["DRAUGRSPAWNER"] = "Портал драугров",
["TOTEM"] = "Тотем фулингов",
["FIRE"] = "Костер",
["TAR"] = "Смоляная яма",
["SKELETON"] = "Скелет",
["TREASURE"] = "Сокровище",
["MISTLANDSSWORDS"] = "Меч в камне",
["MISTLANDSGIANTS"] = "Останки великанов",
["MARKER"] = "Маркер"
},
["fr"] = new Dictionary<string, string>
{
["COPPER"] = "Cuivre",
["IRON"] = "Fer",
["SILVER"] = "Argent",
["OBSIDIAN"] = "Obsidienne",
["MUDPILE"] = "Tas de boue",
["METEORITE"] = "Météorite",
["TROLLCAVE"] = "Grotte du troll",
["CRYPT"] = "Crypte",
["ABOMINATION"] = "Abomination",
["FLAX"] = "Lin",
["BARLEY"] = "Orge",
["BLUEBERRIES"] = "Myrtilles",
["RASPBERRIES"] = "Framboises",
["MUSHROOMS"] = "Champignons",
["CLOUDBERRIES"] = "Plaquebières",
["THISTLE"] = "Chardon",
["SEEDS"] = "Graines",
["MAGECAPS"] = "Chapeaux de mage",
["YPCONES"] = "Cônes d’Yggdrasil",
["JOTUNNPUFFS"] = "Poussières de Jotunn",
["VOLTUREEGG"] = "Œuf de vautour",
["DRAGONEGG"] = "Œuf de dragon",
["SMOKEPUFFS"] = "Nuages de fumée",
["DVERGERTHINGS"] = "Restes de Dvergr",
["DWARFSPAWNER"] = "Nid de nain gris",
["DRAUGRSPAWNER"] = "Portail Draugr",
["TOTEM"] = "Totem de Fuling",
["FIRE"] = "Feu de camp",
["TAR"] = "Fosse à goudron",
["SKELETON"] = "Squelette",
["TREASURE"] = "Trésor",
["MISTLANDSSWORDS"] = "Épée dans la pierre",
["MISTLANDSGIANTS"] = "Restes de géants",
["MARKER"] = "Marqueur"
},
["de"] = new Dictionary<string, string>
{
["COPPER"] = "Kupfer",
["IRON"] = "Eisen",
["SILVER"] = "Silber",
["OBSIDIAN"] = "Obsidian",
["MUDPILE"] = "Schlammhaufen",
["METEORITE"] = "Meteorit",
["TROLLCAVE"] = "Trollhöhle",
["CRYPT"] = "Gruft",
["ABOMINATION"] = "Abscheulichkeit",
["FLAX"] = "Flachs",
["BARLEY"] = "Gerste",
["BLUEBERRIES"] = "Blaubeeren",
["RASPBERRIES"] = "Himbeeren",
["MUSHROOMS"] = "Pilze",
["CLOUDBERRIES"] = "Moltebeeren",
["THISTLE"] = "Distel",
["SEEDS"] = "Samen",
["MAGECAPS"] = "Magierkappen",
["YPCONES"] = "Yggdrasil-Zapfen",
["JOTUNNPUFFS"] = "Jotunnflusen",
["VOLTUREEGG"] = "Geier-Ei",
["DRAGONEGG"] = "Drachenei",
["SMOKEPUFFS"] = "Rauchwolken",
["DVERGERTHINGS"] = "Dvergr-Überreste",
["DWARFSPAWNER"] = "Grauzwergen-Nest",
["DRAUGRSPAWNER"] = "Draugr-Portal",
["TOTEM"] = "Fuling-Totem",
["FIRE"] = "Lagerfeuer",
["TAR"] = "Teergrube",
["SKELETON"] = "Skelett",
["TREASURE"] = "Schatz",
["MISTLANDSSWORDS"] = "Schwert im Stein",
["MISTLANDSGIANTS"] = "Überreste der Riesen",
["MARKER"] = "Markierung"
},
["es"] = new Dictionary<string, string>
{
["COPPER"] = "Cobre",
["IRON"] = "Hierro",
["SILVER"] = "Plata",
["OBSIDIAN"] = "Obsidiana",
["MUDPILE"] = "Montón de barro",
["METEORITE"] = "Meteorito",
["TROLLCAVE"] = "Cueva de trolls",
["CRYPT"] = "Cripta",
["ABOMINATION"] = "Abominación",
["FLAX"] = "Lino",
["BARLEY"] = "Cebada",
["BLUEBERRIES"] = "Arándanos",
["RASPBERRIES"] = "Frambuesas",
["MUSHROOMS"] = "Setas",
["CLOUDBERRIES"] = "Moras nubes",
["THISTLE"] = "Cardo",
["SEEDS"] = "Semillas",
["MAGECAPS"] = "Sombreros mágicos",
["YPCONES"] = "Conos de Yggdrasil",
["JOTUNNPUFFS"] = "Pelusas de Jotunn",
["VOLTUREEGG"] = "Huevo de buitre",
["DRAGONEGG"] = "Huevo de dragón",
["SMOKEPUFFS"] = "Nubes de humo",
["DVERGERTHINGS"] = "Restos de Dvergr",
["DWARFSPAWNER"] = "Nido de enano gris",
["DRAUGRSPAWNER"] = "Portal Draugr",
["TOTEM"] = "Tótem Fuling",
["FIRE"] = "Hoguera",
["TAR"] = "Pozo de alquitrán",
["SKELETON"] = "Esqueleto",
["TREASURE"] = "Tesoro",
["MISTLANDSSWORDS"] = "Espada en la piedra",
["MISTLANDSGIANTS"] = "Restos de gigantes",
["MARKER"] = "Marcador"
},
["pl"] = new Dictionary<string, string>
{
["COPPER"] = "Miedź",
["IRON"] = "Żelazo",
["SILVER"] = "Srebro",
["OBSIDIAN"] = "Obsydian",
["MUDPILE"] = "Stos błota",
["METEORITE"] = "Meteoryt",
["TROLLCAVE"] = "Jaskinia trolla",
["CRYPT"] = "Krypta",
["ABOMINATION"] = "Potworność",
["FLAX"] = "Len",
["BARLEY"] = "Jęczmień",
["BLUEBERRIES"] = "Jagody",
["RASPBERRIES"] = "Maliny",
["MUSHROOMS"] = "Grzyby",
["CLOUDBERRIES"] = "Malina moroszka",
["THISTLE"] = "Oset",
["SEEDS"] = "Nasiona",
["MAGECAPS"] = "Kapelusze maga",
["YPCONES"] = "Szyszki Yggdrasila",
["JOTUNNPUFFS"] = "Puch Jotunna",
["VOLTUREEGG"] = "Jajo sępa",
["DRAGONEGG"] = "Jajo smoka",
["SMOKEPUFFS"] = "Kłęby dymu",
["DVERGERTHINGS"] = "Pozostałości Dvergrów",
["DWARFSPAWNER"] = "Gniazdo krasnoluda",
["DRAUGRSPAWNER"] = "Pojawiacz Draugrów",
["TOTEM"] = "Totem Fulingów",
["FIRE"] = "Ognisko",
["TAR"] = "Dół ze smołą",
["SKELETON"] = "Szkielet",
["TREASURE"] = "Skarb",
["MISTLANDSSWORDS"] = "Miecz w kamieniu",
["MISTLANDSGIANTS"] = "Szczątki olbrzyma",
["MARKER"] = "Znacznik"
},
["zh"] = new Dictionary<string, string>
{
["COPPER"] = "铜矿",
["IRON"] = "铁矿",
["SILVER"] = "银矿",
["OBSIDIAN"] = "黑曜石",
["MUDPILE"] = "泥堆",
["METEORITE"] = "陨石",
["TROLLCAVE"] = "巨魔洞穴",
["CRYPT"] = "地穴",
["ABOMINATION"] = "憎恶",
["FLAX"] = "亚麻",
["BARLEY"] = "大麦",
["BLUEBERRIES"] = "蓝莓",
["RASPBERRIES"] = "覆盆子",
["MUSHROOMS"] = "蘑菇",
["CLOUDBERRIES"] = "云莓",
["THISTLE"] = "蓟",
["SEEDS"] = "种子",
["MAGECAPS"] = "法师帽",
["YPCONES"] = "世界树松果",
["JOTUNNPUFFS"] = "尤顿绒毛",
["VOLTUREEGG"] = "秃鹰蛋",
["DRAGONEGG"] = "龙蛋",
["SMOKEPUFFS"] = "烟雾",
["DVERGERTHINGS"] = "矮人遗物",
["DWARFSPAWNER"] = "灰矮人巢穴",
["DRAUGRSPAWNER"] = "尸鬼生成器",
["TOTEM"] = "愚林图腾",
["FIRE"] = "营火",
["TAR"] = "焦油坑",
["SKELETON"] = "骷髅",
["TREASURE"] = "宝藏",
["MISTLANDSSWORDS"] = "石中剑",
["MISTLANDSGIANTS"] = "巨人遗骸",
["MARKER"] = "标记"
},
["pt"] = new Dictionary<string, string>
{
["COPPER"] = "Cobre",
["IRON"] = "Ferro",
["SILVER"] = "Prata",
["OBSIDIAN"] = "Obsidiana",
["MUDPILE"] = "Monturo de lama",
["METEORITE"] = "Meteorito",
["TROLLCAVE"] = "Caverna do troll",
["CRYPT"] = "Cripta",
["ABOMINATION"] = "Abominação",
["FLAX"] = "Linho",
["BARLEY"] = "Cevada",
["BLUEBERRIES"] = "Mirtilos",
["RASPBERRIES"] = "Framboesas",
["MUSHROOMS"] = "Cogumelos",
["CLOUDBERRIES"] = "Amoras nubladas",
["THISTLE"] = "Cardo",
["SEEDS"] = "Sementes",
["MAGECAPS"] = "Chapéus mágicos",
["YPCONES"] = "Pinhas de Yggdrasil",
["JOTUNNPUFFS"] = "Fofos de Jotunn",
["VOLTUREEGG"] = "Ovo de abutre",
["DRAGONEGG"] = "Ovo de dragão",
["SMOKEPUFFS"] = "Nuvens de fumaça",
["DVERGERTHINGS"] = "Restos de Dvergr",
["DWARFSPAWNER"] = "Ninho de anão cinzento",
["DRAUGRSPAWNER"] = "Portal Draugr",
["TOTEM"] = "Totem Fuling",
["FIRE"] = "Fogueira",
["TAR"] = "Poça de alcatrão",
["SKELETON"] = "Esqueleto",
["TREASURE"] = "Tesouro",
["MISTLANDSSWORDS"] = "Espada na pedra",
["MISTLANDSGIANTS"] = "Restos de gigantes",
["MARKER"] = "Marcador"
}
};
}
}
public class PinManager
{
private const int PinFlushThreshold = 50;
private readonly HashSet<string> _pinHashes = new HashSet<string>();
private readonly PinSettings _settings;
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(PinSettings settings, ManualLogSource logger, LocalizationManager localizationManager)
{
_settings = settings;
_logger = logger;
_localizationManager = localizationManager;
Directory.CreateDirectory(Path.GetDirectoryName(PinsFilePath));
LoadPinsFromFile();
}
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_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
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) < _settings.PinMergeDistance && 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 (_settings.EnablePinSaving && _newPins.Count >= 50)
{
SavePinsToFile();
}
}
public void TryPeriodicSave()
{
if (_settings.EnablePinSaving && _newPins.Count != 0 && (_newPins.Count >= 50 || Time.time - _lastSaveTime > _settings.SaveInterval))
{
SavePinsToFile();
}
}
public void SaveImmediate()
{
if (_settings.EnablePinSaving)
{
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(PinSettings settings)
{
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)
{
string label = item.m_name.ToUpperInvariant();
if (!IsLabelEnabled(label, settings))
{
list2.Add(item);
}
}
foreach (PinData item2 in list2)
{
Minimap.instance.RemovePin(item2);
}
_logger.LogWarning((object)$"Removed {list2.Count} unwanted pins from the map.");
}
private bool IsLabelEnabled(string label, PinSettings settings)
{
if (!PinScanner.PinLabelMap.LabelToSettingInfo.TryGetValue(label, out (string, PinType) value))
{
return true;
}
FieldInfo field = typeof(PinSettings).GetField(value.Item1);
if (field == null || field.FieldType != typeof(bool))
{
return true;
}
return (bool)field.GetValue(settings);
}
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);
}
}