Decompiled source of NordGuide v1.0.2

NordGuide.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NordGuide.Core;
using NordGuide.UI;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Sprites;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("NordGuide")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NordGuide")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3e16b1e1-8911-47c5-84bb-6dfc93f6ef80")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NordGuide
{
	[BepInPlugin("genesisproj.nordguide", "NordGuide", "1.0.2")]
	[BepInProcess("valheim.exe")]
	public class NordGuide : BaseUnityPlugin
	{
		public const string PluginGuid = "genesisproj.nordguide";

		public const string PluginName = "NordGuide";

		public const string PluginVersion = "1.0.2";

		internal static ManualLogSource Log;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Logging.Initialize(((BaseUnityPlugin)this).Logger);
			Log.LogInfo((object)"[NordGuide] Initializing...");
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0019: 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_0024: Expected O, but got Unknown
			if (!(((Scene)(ref scene)).name != "main"))
			{
				GameObject val = new GameObject("NordGuideCompass");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<CompassRenderer>();
				Log.LogInfo((object)"[NordGuide] Compass initialized successfully!");
			}
		}

		private void OnDestroy()
		{
			Log.LogInfo((object)"[NordGuide] Unloaded.");
		}
	}
}
namespace NordGuide.UI
{
	internal static class CompassCardinals
	{
		private const float VisibleSpanDeg = 60f;

		private const float EdgeFadeInnerFrac = 0.2f;

		private const float UsableSpanFrac = 0.82f;

		private const float CardinalHeightFactor = 0.6f;

		private const float CardinalYOffsetFrac = 0f;

		private const float UsableHeightFrac = 0.62f;

		public static void Draw(Texture2D texN, Texture2D texE, Texture2D texS, Texture2D texW, Rect barRect, float heading)
		{
			//IL_0006: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			DrawCardinal(texN, 0f, barRect, heading);
			DrawCardinal(texE, 90f, barRect, heading);
			DrawCardinal(texS, 180f, barRect, heading);
			DrawCardinal(texW, -90f, barRect, heading);
		}

		private static void DrawCardinal(Texture2D icon, float angle, Rect barRect, float heading)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)icon == (Object)null))
			{
				float num = 30f;
				float num2 = Mathf.DeltaAngle(heading, angle);
				float num3 = Mathf.Abs(num2);
				if (!(num3 > num))
				{
					float num4 = ((Rect)(ref barRect)).x + ((Rect)(ref barRect)).width * 0.5f;
					float num5 = ((Rect)(ref barRect)).width * 0.82f / 60f;
					float num6 = num4 + num2 * num5;
					float num7 = Mathf.InverseLerp(num, num * 0.2f, num3);
					float num8 = (float)((Texture)icon).width / (float)((Texture)icon).height;
					float num9 = ((Rect)(ref barRect)).height * 0.62f * 0.6f;
					float num10 = num9 * num8;
					float num11 = ((Rect)(ref barRect)).height * 0f;
					Rect val = new Rect(num6 - num10 * 0.5f, ((Rect)(ref barRect)).y + (((Rect)(ref barRect)).height - num9) * 0.5f + num11, num10, num9);
					Color color = GUI.color;
					GUI.color = new Color(1f, 1f, 1f, num7);
					GUI.DrawTexture(val, (Texture)(object)icon, (ScaleMode)0, true);
					GUI.color = color;
				}
			}
		}
	}
	internal static class CompassPOIs
	{
		private const float VisibleSpanDeg = 60f;

		private const float EdgeFadeInnerFrac = 0.2f;

		private const float UsableSpanFrac = 0.82f;

		private const float PoiHeightFactor = 0.5f;

		private const float PoiYOffsetFrac = 0.02f;

		private const float UsableHeightFrac = 0.62f;

		private const float ScaleNearDist = 0f;

		private const float ScaleFarDist = 350f;

		private const float PoiMinScale = 0.2f;

		private const float PoiMaxScale = 1.4f;

		private const float FadeStartFraction = 0.75f;

		private const float PulseAmplitude = 0.15f;

		private const float PulseSpeed = 6f;

		public static void Draw(Rect barRect, float heading, float uiAlpha)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			if (!PinsProvider.TryGetPins(out var pins))
			{
				return;
			}
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			float num = 30f;
			float num2 = ((Rect)(ref barRect)).x + ((Rect)(ref barRect)).width * 0.5f;
			float num3 = ((Rect)(ref barRect)).width * 0.82f / 60f;
			Rect val2 = default(Rect);
			foreach (PinData item in pins)
			{
				if (item == null || (Object)(object)item.m_icon == (Object)null)
				{
					continue;
				}
				Vector3 val = item.m_pos - position;
				float num4 = Mathf.Atan2(val.x, val.z) * 57.29578f;
				float num5 = Mathf.DeltaAngle(heading, num4);
				float num6 = Mathf.Abs(num5);
				if (num6 > num)
				{
					continue;
				}
				float num7 = num2 + num5 * num3;
				float magnitude = ((Vector3)(ref val)).magnitude;
				float num8 = Mathf.InverseLerp(0f, 350f, magnitude);
				float num9 = 1f - num8;
				num9 = Mathf.SmoothStep(0f, 1f, num9);
				float num10 = Mathf.Lerp(0.2f, 1.4f, num9);
				float num11 = ConfigManager.PoiDisappearDistance.Value * 0.75f;
				float value = ConfigManager.PoiDisappearDistance.Value;
				float num12 = Mathf.Clamp01(1f - Mathf.InverseLerp(num11, value, magnitude));
				float num13 = Mathf.InverseLerp(num, num * 0.2f, num6);
				float num14 = num12 * num13 * uiAlpha;
				if (num14 <= 0.01f)
				{
					continue;
				}
				Sprite icon = item.m_icon;
				Texture2D texture = icon.texture;
				if (!((Object)(object)texture == (Object)null))
				{
					Vector4 outerUV = DataUtility.GetOuterUV(icon);
					((Rect)(ref val2))..ctor(outerUV.x, outerUV.y, outerUV.z - outerUV.x, outerUV.w - outerUV.y);
					Rect textureRect = icon.textureRect;
					float num15 = ((Rect)(ref textureRect)).width / ((Rect)(ref textureRect)).height;
					string text = ((Object)icon).name ?? string.Empty;
					bool num16 = text.IndexOf("ping", StringComparison.OrdinalIgnoreCase) >= 0;
					bool flag = text.IndexOf("shout", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("exclam", StringComparison.OrdinalIgnoreCase) >= 0;
					if (num16 || flag)
					{
						num10 *= 1f + 0.15f * Mathf.Sin(Time.time * 6f);
					}
					float num17;
					float num18 = (num17 = ((Rect)(ref barRect)).height * 0.62f * 0.5f * num10) * num15;
					float num19 = ((Rect)(ref barRect)).height * 0.02f;
					float num20 = num7 - num18 * 0.5f;
					float num21 = ((Rect)(ref barRect)).y + (((Rect)(ref barRect)).height - num17) * 0.5f + num19;
					Rect val3 = new Rect(num20, num21, num18, num17);
					GUI.color = new Color(1f, 1f, 1f, num14);
					GUI.DrawTextureWithTexCoords(val3, (Texture)(object)texture, val2);
				}
			}
		}
	}
}
namespace NordGuide.Core
{
	internal static class AssetsManager
	{
		private static readonly Dictionary<string, Texture2D> _texByKey = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Sprite> _sprByKey = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase);

		private static bool _loaded;

		public static void Initialize()
		{
		}

		public static Texture2D Tex(string nameOrFile)
		{
			EnsureLoaded();
			return TryGet(_texByKey, NormalizeKey(nameOrFile));
		}

		public static Sprite Sprite(string nameOrFile)
		{
			EnsureLoaded();
			return TryGet(_sprByKey, NormalizeKey(nameOrFile));
		}

		public static IEnumerable<string> Keys()
		{
			EnsureLoaded();
			return _texByKey.Keys.OrderBy((string k) => k);
		}

		private static void EnsureLoaded()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (_loaded)
			{
				return;
			}
			_loaded = true;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string[] manifestResourceNames = executingAssembly.GetManifestResourceNames();
			foreach (string text in manifestResourceNames)
			{
				if (!text.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				string text2 = NormalizeKey(Path.GetFileName(text));
				if (string.IsNullOrEmpty(text2))
				{
					continue;
				}
				try
				{
					using Stream stream = executingAssembly.GetManifestResourceStream(text);
					if (stream == null)
					{
						continue;
					}
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					byte[] data = memoryStream.ToArray();
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
					if (!LoadImageCompat(val, data, markNonReadable: false))
					{
						ManualLogSource log = NordGuide.Log;
						if (log != null)
						{
							log.LogWarning((object)("[Assets] ImageConversion.LoadImage indisponível: " + text));
						}
					}
					else
					{
						((Texture)val).wrapMode = (TextureWrapMode)1;
						((Texture)val).filterMode = (FilterMode)1;
						_texByKey[text2] = val;
						Sprite value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
						_sprByKey[text2] = value;
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log2 = NordGuide.Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[Assets] Falha ao carregar resource: " + text + " -> " + ex.Message));
					}
				}
			}
			ManualLogSource log3 = NordGuide.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)$"[Assets] Carregados {_texByKey.Count} textures / {_sprByKey.Count} sprites embutidos.");
			}
		}

		private static bool LoadImageCompat(Texture2D tex, byte[] data, bool markNonReadable)
		{
			try
			{
				Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule", throwOnError: false);
				if (type == null)
				{
					return false;
				}
				MethodInfo method = type.GetMethod("LoadImage", BindingFlags.Static | BindingFlags.Public, null, new Type[3]
				{
					typeof(Texture2D),
					typeof(byte[]),
					typeof(bool)
				}, null);
				if (method == null)
				{
					return false;
				}
				return (bool)method.Invoke(null, new object[3] { tex, data, markNonReadable });
			}
			catch (Exception ex)
			{
				ManualLogSource log = NordGuide.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Assets] LoadImageCompat falhou: " + ex.Message));
				}
				return false;
			}
		}

		private static string NormalizeKey(string nameOrFile)
		{
			if (string.IsNullOrWhiteSpace(nameOrFile))
			{
				return null;
			}
			string text = nameOrFile.Trim();
			if (text.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - 4);
			}
			int num = text.LastIndexOf('.');
			if (num >= 0 && num + 1 < text.Length)
			{
				text = text.Substring(num + 1);
			}
			return text;
		}

		private static T TryGet<T>(Dictionary<string, T> map, string key) where T : class
		{
			if (key != null && map.TryGetValue(key, out var value))
			{
				return value;
			}
			return null;
		}
	}
	public class CompassRenderer : MonoBehaviour
	{
		private Texture2D bgTexture;

		private Texture2D texN;

		private Texture2D texE;

		private Texture2D texS;

		private Texture2D texW;

		private Rect barRect;

		private float uiAlpha;

		private float displayedHeading;

		private const float fadeSpeed = 2.5f;

		private const float headingLerpSpeed = 2.5f;

		private bool? _lastLocaleIsPt;

		private float _localeCheckTimer;

		private const float LocaleCheckInterval = 2f;

		private void Start()
		{
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsPortugueseLocale();
			bgTexture = AssetsManager.Tex("bg-bussola");
			LoadCardinalTexturesIfNeeded();
			texN = AssetsManager.Tex("PinN");
			texS = AssetsManager.Tex("PinS");
			texE = AssetsManager.Tex(flag ? "PinL" : "PinE") ?? AssetsManager.Tex(flag ? "PinE" : "PinL");
			texW = AssetsManager.Tex(flag ? "PinO" : "PinW") ?? AssetsManager.Tex(flag ? "PinW" : "PinO");
			ManualLogSource log = NordGuide.Log;
			if (log != null)
			{
				log.LogInfo((object)string.Format("[Compass] Locale PT={0}. E= {1}  W= {2}", flag, Object.op_Implicit((Object)(object)texE) ? "ok" : "missing", Object.op_Implicit((Object)(object)texW) ? "ok" : "missing"));
			}
			float num = (float)Screen.width * 0.32f;
			float num2 = (((Object)(object)bgTexture != (Object)null) ? ((float)((Texture)bgTexture).width / (float)((Texture)bgTexture).height) : 7f);
			float num3 = num / num2;
			barRect = new Rect(((float)Screen.width - num) / 2f, 40f, num, num3);
			if (!Object.op_Implicit((Object)(object)bgTexture))
			{
				ManualLogSource log2 = NordGuide.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[Compass] bgTexture não carregada");
				}
			}
			if (!Object.op_Implicit((Object)(object)texN))
			{
				ManualLogSource log3 = NordGuide.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[Compass] texN não carregada");
				}
			}
			if (!Object.op_Implicit((Object)(object)texE))
			{
				ManualLogSource log4 = NordGuide.Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"[Compass] texE não carregada");
				}
			}
			if (!Object.op_Implicit((Object)(object)texS))
			{
				ManualLogSource log5 = NordGuide.Log;
				if (log5 != null)
				{
					log5.LogWarning((object)"[Compass] texS não carregada");
				}
			}
			if (!Object.op_Implicit((Object)(object)texW))
			{
				ManualLogSource log6 = NordGuide.Log;
				if (log6 != null)
				{
					log6.LogWarning((object)"[Compass] texW não carregada");
				}
			}
		}

		private void Update()
		{
			MinimapVisibility.Tick();
			_localeCheckTimer += Time.deltaTime;
			if (_localeCheckTimer >= 2f)
			{
				_localeCheckTimer = 0f;
				LoadCardinalTexturesIfNeeded();
			}
		}

		private void OnDestroy()
		{
			texN = (texE = (texS = (texW = null)));
			bgTexture = null;
			_lastLocaleIsPt = null;
		}

		private void OnGUI()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigManager.EnableCompass.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)Camera.main == (Object)null))
			{
				float num = ((InventoryGui.IsVisible() || Minimap.IsOpen() || Menu.IsVisible() || TextInput.IsVisible()) ? 0f : 1f);
				uiAlpha = Mathf.Lerp(uiAlpha, num, Time.deltaTime * 2.5f);
				if (!(uiAlpha < 0.01f))
				{
					float y = ((Component)Camera.main).transform.eulerAngles.y;
					displayedHeading = Mathf.LerpAngle(displayedHeading, y, Time.deltaTime * 2.5f);
					GUI.color = new Color(1f, 1f, 1f, uiAlpha);
					GUI.DrawTexture(barRect, (Texture)(object)bgTexture, (ScaleMode)0, true);
					GUI.color = new Color(1f, 1f, 1f, uiAlpha);
					CompassCardinals.Draw(texN, texE, texS, texW, barRect, displayedHeading);
					GUI.color = new Color(1f, 1f, 1f, uiAlpha);
					CompassPOIs.Draw(barRect, displayedHeading, uiAlpha);
				}
			}
		}

		private static void DrawSoftShadowUnderBar(Rect barRect, float uiAlpha)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Color color = GUI.color;
			for (int i = 0; i < 12; i++)
			{
				float num = ((float)i + 1f) / 12f;
				float num2 = 0.7f * Mathf.Pow(1f - num, 2.2f);
				float num3 = 20f * num;
				float num4 = 40f * num;
				Rect val = new Rect(((Rect)(ref barRect)).x - num3, ((Rect)(ref barRect)).y + 12f, ((Rect)(ref barRect)).width + 2f * num3, 1f + num4);
				GUI.color = new Color(0f, 0f, 0f, num2 * uiAlpha);
				GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, false);
			}
			GUI.color = color;
		}

		private static Rect Inflate(Rect r, float px)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(((Rect)(ref r)).x - px, ((Rect)(ref r)).y - px, ((Rect)(ref r)).width + px * 2f, ((Rect)(ref r)).height + px * 2f);
		}

		private static bool IsPortugueseLocale()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			try
			{
				string @string = PlayerPrefs.GetString("language", string.Empty);
				if (!string.IsNullOrEmpty(@string))
				{
					@string = @string.ToLowerInvariant();
					if (@string.StartsWith("pt") || @string.Contains("portugu"))
					{
						return true;
					}
					return false;
				}
			}
			catch
			{
			}
			return (int)Application.systemLanguage == 28;
		}

		private void LoadCardinalTexturesIfNeeded()
		{
			bool flag = IsPortugueseLocale();
			if (!_lastLocaleIsPt.HasValue || _lastLocaleIsPt.Value != flag)
			{
				_lastLocaleIsPt = flag;
				texN = AssetsManager.Tex("PinN");
				texS = AssetsManager.Tex("PinS");
				texE = AssetsManager.Tex(flag ? "PinL" : "PinE") ?? AssetsManager.Tex(flag ? "PinE" : "PinL");
				texW = AssetsManager.Tex(flag ? "PinO" : "PinW") ?? AssetsManager.Tex(flag ? "PinW" : "PinO");
				ManualLogSource log = NordGuide.Log;
				if (log != null)
				{
					log.LogInfo((object)string.Format("[Compass] Locale PT={0}. E={1} W={2}", flag, Object.op_Implicit((Object)(object)texE) ? "ok" : "missing", Object.op_Implicit((Object)(object)texW) ? "ok" : "missing"));
				}
			}
		}
	}
	internal static class ConfigManager
	{
		public static ConfigEntry<bool> EnableCompass;

		private static FileSystemWatcher watcher;

		public static ConfigEntry<bool> HideMinimapHud;

		public static ConfigEntry<float> PoiDisappearDistance;

		public static void Initialize(ConfigFile config)
		{
			EnableCompass = config.Bind<bool>("HUD", "Enable Compass", true, "Activates or deactivates NordGuide’s compass.");
			HideMinimapHud = config.Bind<bool>("HUD", "Hide Minimap (Small HUD)", false, "If set to true, the small HUD minimap is hidden (the large world map still works).");
			PoiDisappearDistance = config.Bind<float>("HUD", "POI Disappear Distance", 500f, "Distance (in meters) at which POI icons fully disappear.");
			string configFilePath = config.ConfigFilePath;
			watcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath))
			{
				NotifyFilter = NotifyFilters.LastWrite
			};
			watcher.Changed += delegate
			{
				ReloadConfig(config);
			};
			watcher.EnableRaisingEvents = true;
			Logging.Info("[ConfigManager] Config loaded and watcher active.");
		}

		private static void ReloadConfig(ConfigFile config)
		{
			try
			{
				config.Reload();
				Logging.Info("[ConfigManager] Config reloaded successfully.");
			}
			catch
			{
				Logging.Warning("[ConfigManager] Failed to reload config.");
			}
		}
	}
	internal static class Logging
	{
		private static ManualLogSource _logger;

		public static void Initialize(ManualLogSource log)
		{
			_logger = log;
		}

		public static void Info(string msg)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogInfo((object)msg);
			}
		}

		public static void Warning(string msg)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogWarning((object)msg);
			}
		}

		public static void Error(string msg)
		{
			ManualLogSource logger = _logger;
			if (logger != null)
			{
				logger.LogError((object)msg);
			}
		}
	}
	internal static class MinimapVisibility
	{
		private static FieldInfo _fiSmallRoot;

		private static GameObject _smallRootGO;

		private const int ResolveIntervalFrames = 30;

		private static int _lastResolveFrame;

		public static void Tick()
		{
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			bool value = ConfigManager.HideMinimapHud.Value;
			if ((Object)(object)_smallRootGO == (Object)null || Time.frameCount - _lastResolveFrame >= 30)
			{
				ResolveSmallRoot(instance);
				_lastResolveFrame = Time.frameCount;
			}
			if ((Object)(object)_smallRootGO != (Object)null)
			{
				bool flag = !value;
				if (_smallRootGO.activeSelf != flag)
				{
					_smallRootGO.SetActive(flag);
				}
			}
		}

		private static void ResolveSmallRoot(Minimap mm)
		{
			try
			{
				if (_fiSmallRoot == null)
				{
					BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
					_fiSmallRoot = typeof(Minimap).GetField("m_smallRoot", bindingAttr) ?? typeof(Minimap).GetField("_smallRoot", bindingAttr);
				}
				GameObject val = null;
				if (_fiSmallRoot != null)
				{
					object value = _fiSmallRoot.GetValue(mm);
					GameObject val2 = (GameObject)((value is GameObject) ? value : null);
					if (val2 != null)
					{
						val = val2;
					}
					else
					{
						Transform val3 = (Transform)((value is Transform) ? value : null);
						if (val3 != null)
						{
							val = ((val3 != null) ? ((Component)val3).gameObject : null);
						}
						else
						{
							RectTransform val4 = (RectTransform)((value is RectTransform) ? value : null);
							if (val4 != null)
							{
								val = ((val4 != null) ? ((Component)val4).gameObject : null);
							}
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					RectTransform[] componentsInChildren = ((Component)mm).gameObject.GetComponentsInChildren<RectTransform>(true);
					foreach (RectTransform val5 in componentsInChildren)
					{
						string text = ((Object)val5).name.ToLowerInvariant();
						if (text.Contains("minimap_small") || text == "small" || text.Contains("minimaphud"))
						{
							val = ((Component)val5).gameObject;
							break;
						}
					}
				}
				_smallRootGO = val;
			}
			catch
			{
				_smallRootGO = null;
			}
		}
	}
	internal static class PinsProvider
	{
		private static FieldRef<Minimap, List<PinData>> _pinsRef;

		private static Func<Minimap, List<PinData>> _fallbackGetter;

		private static bool _loggedFail;

		private static bool _resolved;

		public static bool TryGetPins(out List<PinData> pins)
		{
			pins = null;
			Minimap instance = Minimap.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if (!_resolved)
			{
				TryResolveFieldRef();
			}
			try
			{
				if (_pinsRef != null)
				{
					pins = _pinsRef.Invoke(instance);
					if (pins != null && pins.Count > 0)
					{
						return true;
					}
				}
				else if (_fallbackGetter != null)
				{
					pins = _fallbackGetter(instance);
					if (pins != null && pins.Count > 0)
					{
						return true;
					}
				}
			}
			catch
			{
			}
			if (!_loggedFail)
			{
				_loggedFail = true;
				Logging.Warning("[PinsProvider] Falha ao acessar Minimap.m_pins. POIs desativados.");
			}
			return false;
		}

		private static void TryResolveFieldRef()
		{
			if (_resolved)
			{
				return;
			}
			_resolved = true;
			try
			{
				_pinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins");
				if (_pinsRef != null)
				{
					Logging.Info("[PinsProvider] Campo 'm_pins' resolvido com sucesso.");
					return;
				}
				string[] array = new string[3] { "_pins", "pins", "m_AllPins" };
				foreach (string text in array)
				{
					try
					{
						_pinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>(text);
						if (_pinsRef != null)
						{
							Logging.Info("[PinsProvider] Campo resolvido via '" + text + "'.");
							return;
						}
					}
					catch
					{
					}
				}
				BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				FieldInfo fi = typeof(Minimap).GetField("m_pins", bindingAttr) ?? typeof(Minimap).GetField("_pins", bindingAttr) ?? typeof(Minimap).GetField("pins", bindingAttr) ?? typeof(Minimap).GetField("m_AllPins", bindingAttr);
				if (fi != null)
				{
					_fallbackGetter = (Minimap mm) => (List<PinData>)fi.GetValue(mm);
					Logging.Info("[PinsProvider] Campo de pins resolvido via reflection fallback.");
				}
				else
				{
					Logging.Warning("[PinsProvider] Nenhum campo de pins encontrado em Minimap.");
				}
			}
			catch (Exception ex)
			{
				Logging.Warning("[PinsProvider] Erro ao resolver campo de pins: " + ex.Message);
			}
		}

		public static bool TryGetSpriteTextureAndUv(Sprite sprite, out Texture2D tex, out Rect uv)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			tex = null;
			uv = default(Rect);
			if ((Object)(object)sprite == (Object)null)
			{
				return false;
			}
			tex = sprite.texture;
			if ((Object)(object)tex == (Object)null)
			{
				return false;
			}
			Rect rect = sprite.rect;
			uv = new Rect(((Rect)(ref rect)).x / (float)((Texture)tex).width, ((Rect)(ref rect)).y / (float)((Texture)tex).height, ((Rect)(ref rect)).width / (float)((Texture)tex).width, ((Rect)(ref rect)).height / (float)((Texture)tex).height);
			return true;
		}

		public static bool TryGetIMGUIRect(Sprite s, out Texture2D tex, out Rect uv, out bool rotated)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			tex = null;
			uv = default(Rect);
			rotated = false;
			if ((Object)(object)s == (Object)null)
			{
				return false;
			}
			tex = s.texture;
			if ((Object)(object)tex == (Object)null)
			{
				return false;
			}
			Vector2[] uv2 = s.uv;
			float num = Mathf.Min(new float[4]
			{
				uv2[0].x,
				uv2[1].x,
				uv2[2].x,
				uv2[3].x
			});
			float num2 = Mathf.Max(new float[4]
			{
				uv2[0].x,
				uv2[1].x,
				uv2[2].x,
				uv2[3].x
			});
			float num3 = Mathf.Min(new float[4]
			{
				uv2[0].y,
				uv2[1].y,
				uv2[2].y,
				uv2[3].y
			});
			float num4 = Mathf.Max(new float[4]
			{
				uv2[0].y,
				uv2[1].y,
				uv2[2].y,
				uv2[3].y
			});
			uv = new Rect(num, num3, num2 - num, num4 - num3);
			rotated = Mathf.Abs(uv2[1].y - uv2[0].y) > Mathf.Abs(uv2[1].x - uv2[0].x);
			return true;
		}
	}
}