Decompiled source of Aurora World Assets v1.0.0

plugins/AuroraMainMenu.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("AuroraMainMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AuroraMainMenu")]
[assembly: AssemblyTitle("AuroraMainMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace AuroraMainMenu;

[BepInPlugin("com.aurora.mainmenu", "Aurora Main Menu", "2.0.0")]
public class AuroraMenuPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.aurora.mainmenu";

	public const string PluginName = "Aurora Main Menu";

	public const string PluginVersion = "2.0.0";

	public const string ServerAddress = "85.206.119.102";

	public const int ServerPort = 2456;

	internal static AuroraMenuPlugin Instance;

	internal bool IsConnecting;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		Instance = this;
		_harmony = new Harmony("com.aurora.mainmenu");
		_harmony.PatchAll(typeof(FejdStartupPatches));
		_harmony.PatchAll(typeof(LocalizationPatches));
		_harmony.PatchAll(typeof(MountainAtmospherePatches));
		_harmony.PatchAll(typeof(MusicPatches));
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded. Server: {2}:{3}", "Aurora Main Menu", "2.0.0", "85.206.119.102", 2456));
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	internal void ConnectToServer()
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Connecting to {0}:{1} (no password)...", "85.206.119.102", 2456));
		try
		{
			IsConnecting = true;
			ZSteamMatchmaking instance = ZSteamMatchmaking.instance;
			if (instance != null)
			{
				instance.QueueServerJoin(string.Format("{0}:{1}", "85.206.119.102", 2456));
			}
		}
		catch (Exception ex)
		{
			IsConnecting = false;
			((BaseUnityPlugin)this).Logger.LogError((object)("Connection failed: " + ex.Message));
		}
	}
}
[HarmonyPatch]
public static class LocalizationPatches
{
	[HarmonyPatch(typeof(Localization), "TranslateSingleId")]
	[HarmonyPostfix]
	public static void TranslateSingleId_Postfix(ref string __result, string locaId)
	{
		if (__result != null && __result.Equals("Start Game", StringComparison.OrdinalIgnoreCase))
		{
			__result = "Play Aurora";
		}
	}
}
[HarmonyPatch]
public static class FejdStartupPatches
{
	private static Type _cachedTmpType;

	private static PropertyInfo _cachedTextProp;

	private static MethodInfo _cachedSetText;

	private static bool _typesResolved;

	private static bool _pendingCharSelect;

	[HarmonyPatch(typeof(FejdStartup), "Update")]
	[HarmonyPostfix]
	public static void Update_Postfix(FejdStartup __instance)
	{
		if ((Object)(object)__instance.m_mainMenu == (Object)null || !__instance.m_mainMenu.activeInHierarchy)
		{
			return;
		}
		try
		{
			if (!_typesResolved)
			{
				_cachedTmpType = AccessTools.TypeByName("TMPro.TMP_Text");
				_cachedTextProp = _cachedTmpType?.GetProperty("text");
				_cachedSetText = _cachedTmpType?.GetMethod("SetText", new Type[1] { typeof(string) });
				_typesResolved = true;
			}
			if (_cachedTmpType == null || _cachedTextProp == null)
			{
				return;
			}
			Button[] componentsInChildren = __instance.m_mainMenu.GetComponentsInChildren<Button>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Component componentInChildren = ((Component)componentsInChildren[i]).GetComponentInChildren(_cachedTmpType, true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					continue;
				}
				string text = (_cachedTextProp.GetValue(componentInChildren) as string)?.Trim() ?? "";
				if (!text.Equals("Start Game", StringComparison.OrdinalIgnoreCase) && !text.Equals("Start game", StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				if (_cachedSetText != null)
				{
					_cachedSetText.Invoke(componentInChildren, new object[1] { "Play Aurora" });
				}
				else
				{
					_cachedTextProp.SetValue(componentInChildren, "Play Aurora");
				}
				MonoBehaviour[] componentsInParent = componentInChildren.gameObject.GetComponentsInParent<MonoBehaviour>(true);
				foreach (MonoBehaviour val in componentsInParent)
				{
					if (((object)val).GetType().Name.IndexOf("Localize", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						Object.DestroyImmediate((Object)(object)val);
					}
				}
				break;
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[AuroraMenu] Update_Postfix rename error: " + ex.Message));
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "ShowCharacterSelection")]
	[HarmonyPrefix]
	public static bool ShowCharacterSelection_Prefix(FejdStartup __instance)
	{
		AuroraMenuPlugin instance = AuroraMenuPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return true;
		}
		if (instance.IsConnecting)
		{
			return true;
		}
		if (_pendingCharSelect)
		{
			_pendingCharSelect = false;
			return true;
		}
		_pendingCharSelect = true;
		Debug.Log((object)"[AuroraMenu] Play Aurora clicked -> showing character selection");
		__instance.m_characterSelectScreen.SetActive(true);
		__instance.m_mainMenu.SetActive(false);
		try
		{
			AccessTools.Method(typeof(FejdStartup), "UpdateCharacterList", (Type[])null, (Type[])null)?.Invoke(__instance, null);
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[AuroraMenu] UpdateCharacterList: " + ex.Message));
		}
		return false;
	}

	[HarmonyPatch(typeof(FejdStartup), "OnCharacterStart")]
	[HarmonyPrefix]
	public static bool OnCharacterStart_Prefix(FejdStartup __instance)
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		AuroraMenuPlugin instance = AuroraMenuPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return true;
		}
		if (instance.IsConnecting)
		{
			return true;
		}
		try
		{
			Debug.Log((object)"[AuroraMenu] Character selected, connecting to Aurora server...");
			PlayerProfile selectedProfile = GetSelectedProfile(__instance);
			if (selectedProfile == null)
			{
				Debug.LogWarning((object)"[AuroraMenu] No character selected.");
				return true;
			}
			object value = Traverse.Create((object)__instance).Field("m_profileFileSource").GetValue();
			if (value != null)
			{
				Game.SetProfile(selectedProfile.GetFilename(), (FileSource)value);
			}
			else
			{
				Game.SetProfile(selectedProfile.GetFilename(), (FileSource)1);
			}
			__instance.m_characterSelectScreen.SetActive(false);
			instance.ConnectToServer();
			return false;
		}
		catch (Exception arg)
		{
			Debug.LogError((object)$"[AuroraMenu] OnCharacterStart_Prefix error: {arg}");
			return true;
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "OnSelelectCharacterBack")]
	[HarmonyPrefix]
	public static bool OnSelectCharacterBack_Prefix(FejdStartup __instance)
	{
		if ((Object)(object)AuroraMenuPlugin.Instance == (Object)null)
		{
			return true;
		}
		_pendingCharSelect = false;
		__instance.m_characterSelectScreen.SetActive(false);
		__instance.m_mainMenu.SetActive(true);
		Debug.Log((object)"[AuroraMenu] Returned to main menu from character selection.");
		return false;
	}

	private static PlayerProfile GetSelectedProfile(FejdStartup instance)
	{
		try
		{
			Traverse obj = Traverse.Create((object)instance);
			IList list = obj.Field("m_profiles").GetValue() as IList;
			int value = obj.Field("m_profileIndex").GetValue<int>();
			if (list != null && value >= 0 && value < list.Count)
			{
				object? obj2 = list[value];
				return (PlayerProfile)((obj2 is PlayerProfile) ? obj2 : null);
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[AuroraMenu] GetSelectedProfile error: " + ex.Message));
		}
		return null;
	}
}
[HarmonyPatch]
public static class MountainAtmospherePatches
{
	[CompilerGenerated]
	private sealed class <ApplyMountainScene>d__6 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		private int <i>5__2;

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

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

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

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

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<i>5__2 = 0;
				break;
			case 1:
				<>1__state = -1;
				<i>5__2++;
				break;
			}
			if (<i>5__2 < 15)
			{
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			if (_applied)
			{
				return false;
			}
			_applied = true;
			try
			{
				FindMountainPrefabs();
				EnableGlobalSnow();
				HideMeadowStuff();
				SnowifyTerrainOnly();
				ReplaceRocksWithMountainAssets();
				PlaceIceAndSnow();
				ApplyMountainNightLighting();
				ConvertFireToFrostFire();
				SpawnSnowParticles();
				PlaceHaldorNearFire();
				PlaceBogWitchBehindLogo();
				PlaceHildirAndGolem();
				HideMenuUIElements();
				Debug.Log((object)"[AuroraMenu] Mountain scene applied.");
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[AuroraMenu] Mountain scene error: {arg}");
			}
			return false;
		}

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

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

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

		private object <>2__current;

		private UnityWebRequest <www>5__2;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			bool result;
			try
			{
				switch (<>1__state)
				{
				default:
					result = false;
					break;
				case 0:
				{
					<>1__state = -1;
					string text = Path.Combine(Paths.ConfigPath, "sounds", "menu_theme.mp3");
					if (!File.Exists(text))
					{
						Debug.LogWarning((object)("[AuroraMenu] Music not found: " + text));
						result = false;
						break;
					}
					string text2 = "file:///" + text.Replace("\\", "/");
					<www>5__2 = UnityWebRequestMultimedia.GetAudioClip(text2, (AudioType)13);
					<>1__state = -3;
					<>2__current = <www>5__2.SendWebRequest();
					<>1__state = 1;
					result = true;
					break;
				}
				case 1:
					<>1__state = -3;
					if ((int)<www>5__2.result != 1)
					{
						Debug.LogError((object)("[AuroraMenu] Music load error: " + <www>5__2.error));
						result = false;
					}
					else
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(<www>5__2);
						if (!((Object)(object)content == (Object)null))
						{
							((Object)content).name = "AuroraMenuTheme";
							MuteExistingMusic();
							if ((Object)(object)_customMusicSource == (Object)null)
							{
								GameObject val = new GameObject("AuroraMenuMusic");
								Object.DontDestroyOnLoad((Object)val);
								_customMusicSource = val.AddComponent<AudioSource>();
							}
							_customMusicSource.clip = content;
							_customMusicSource.loop = true;
							_customMusicSource.volume = 1f;
							_customMusicSource.spatialBlend = 0f;
							_customMusicSource.priority = 0;
							_customMusicSource.Play();
							Debug.Log((object)$"[AuroraMenu] Music playing ({content.length:F0}s).");
							<>m__Finally1();
							<www>5__2 = null;
							result = false;
							break;
						}
						result = false;
					}
					<>m__Finally1();
					break;
				}
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
			return result;
		}

		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 (<www>5__2 != null)
			{
				((IDisposable)<www>5__2).Dispose();
			}
		}

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

	private static bool _applied = false;

	private static AudioSource _customMusicSource;

	private static Dictionary<string, GameObject> _prefabs = new Dictionary<string, GameObject>();

	internal static bool IsCustomMusicPlaying()
	{
		if ((Object)(object)_customMusicSource != (Object)null)
		{
			return _customMusicSource.isPlaying;
		}
		return false;
	}

	internal static void StopCustomMusic()
	{
		if ((Object)(object)_customMusicSource != (Object)null)
		{
			_customMusicSource.Stop();
			Debug.Log((object)"[AuroraMenu] Custom music stopped.");
		}
		try
		{
			if ((Object)(object)MusicMan.instance != (Object)null)
			{
				AudioSource value = Traverse.Create((object)MusicMan.instance).Field("m_musicSource").GetValue<AudioSource>();
				if ((Object)(object)value != (Object)null)
				{
					value.mute = false;
					value.volume = 1f;
				}
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)AudioMan.instance != (Object)null)
			{
				string[] array = new string[3] { "m_musicSource", "m_oceanAmbientSource", "m_windLoopSource" };
				foreach (string text in array)
				{
					try
					{
						AudioSource value2 = Traverse.Create((object)AudioMan.instance).Field(text).GetValue<AudioSource>();
						if ((Object)(object)value2 != (Object)null)
						{
							value2.mute = false;
						}
					}
					catch
					{
					}
				}
			}
		}
		catch
		{
		}
		Debug.Log((object)"[AuroraMenu] Vanilla music system restored.");
	}

	[HarmonyPatch(typeof(FejdStartup), "Start")]
	[HarmonyPostfix]
	public static void Start_Postfix(FejdStartup __instance)
	{
		_applied = false;
		_prefabs.Clear();
		AuroraMenuPlugin instance = AuroraMenuPlugin.Instance;
		if ((Object)(object)instance != (Object)null)
		{
			instance.IsConnecting = false;
		}
		((MonoBehaviour)__instance).StartCoroutine(ApplyMountainScene());
		((MonoBehaviour)__instance).StartCoroutine(LoadAndPlayCustomMusic());
	}

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

	private static void FindMountainPrefabs()
	{
		HashSet<string> hashSet = new HashSet<string>(new string[11]
		{
			"Haldor", "BogWitch", "Hildir", "silvervein", "rock1_mountain", "rock2_mountain", "rock3_mountain", "MineRock_Obsidian", "ice_rock1", "FirTree",
			"StoneGolem"
		});
		GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
		foreach (GameObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && hashSet.Contains(((Object)val).name) && !_prefabs.ContainsKey(((Object)val).name) && (Object)(object)val.GetComponentInChildren<Renderer>(true) != (Object)null)
			{
				_prefabs[((Object)val).name] = val;
				Debug.Log((object)("[AuroraMenu] Found prefab: " + ((Object)val).name));
			}
		}
	}

	private static void ReplaceRocksWithMountainAssets()
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Expected O, but got Unknown
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0350: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("Static");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2 = val.transform.Find("props_al");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Transform val3 = val2.Find("Rocks2");
		if ((Object)(object)val3 == (Object)null)
		{
			return;
		}
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Quaternion> list3 = new List<Quaternion>();
		foreach (Transform item in val3)
		{
			Transform val4 = item;
			list.Add(val4.position);
			list2.Add(val4.localScale);
			list3.Add(val4.rotation);
		}
		((Component)val3).gameObject.SetActive(false);
		GameObject val5 = (_prefabs.ContainsKey("silvervein") ? _prefabs["silvervein"] : null);
		GameObject val6 = (_prefabs.ContainsKey("rock1_mountain") ? _prefabs["rock1_mountain"] : null);
		GameObject val7 = (_prefabs.ContainsKey("rock2_mountain") ? _prefabs["rock2_mountain"] : null);
		GameObject val8 = (_prefabs.ContainsKey("rock3_mountain") ? _prefabs["rock3_mountain"] : null);
		GameObject val9 = (_prefabs.ContainsKey("ice_rock1") ? _prefabs["ice_rock1"] : null);
		GameObject val10 = (_prefabs.ContainsKey("MineRock_Obsidian") ? _prefabs["MineRock_Obsidian"] : null);
		List<GameObject> list4 = new List<GameObject>();
		if ((Object)(object)val5 != (Object)null)
		{
			list4.Add(val5);
			list4.Add(val5);
			list4.Add(val5);
		}
		if ((Object)(object)val6 != (Object)null)
		{
			list4.Add(val6);
			list4.Add(val6);
		}
		if ((Object)(object)val7 != (Object)null)
		{
			list4.Add(val7);
			list4.Add(val7);
		}
		if ((Object)(object)val8 != (Object)null)
		{
			list4.Add(val8);
		}
		if ((Object)(object)val9 != (Object)null)
		{
			list4.Add(val9);
		}
		if ((Object)(object)val10 != (Object)null)
		{
			list4.Add(val10);
		}
		if (list4.Count == 0)
		{
			Debug.LogWarning((object)"[AuroraMenu] No mountain rock prefabs found!");
			((Component)val3).gameObject.SetActive(true);
			return;
		}
		GameObject val11 = new GameObject("MountainRocks");
		val11.transform.SetParent(val2, false);
		Random random = new Random(42);
		int num = 0;
		Vector3 val12 = default(Vector3);
		((Vector3)(ref val12))..ctor(-165.5f, 54.42f, 231.21f);
		Vector3 val13 = default(Vector3);
		((Vector3)(ref val13))..ctor(-165.35f, 54.46f, 229.09f);
		for (int i = 0; i < list.Count; i++)
		{
			float num2 = Vector3.Distance(list[i], val12);
			float num3 = Vector3.Distance(list[i], val13);
			if (!(num2 < 5f) && !(num3 < 4f) && (!(list[i].x > -158f) || !(list[i].z < 226f)))
			{
				GameObject prefab = list4[random.Next(list4.Count)];
				float num4 = 0.12f + (float)random.NextDouble() * 0.15f;
				GameObject val14 = SafeSpawn(prefab, list[i], Vector3.one * num4);
				if ((Object)(object)val14 != (Object)null)
				{
					val14.transform.SetParent(val11.transform, true);
					val14.transform.rotation = list3[i];
					val14.transform.Rotate(0f, (float)random.NextDouble() * 360f, 0f);
					num++;
				}
			}
		}
		Debug.Log((object)$"[AuroraMenu] Replaced rocks with {num} mountain assets (silver veins, mountain rocks, ice).");
	}

	private static void PlaceIceAndSnow()
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: 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_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = (_prefabs.ContainsKey("ice_rock1") ? _prefabs["ice_rock1"] : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		GameObject val2 = GameObject.Find("Static");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Transform val3 = val2.transform.Find("MenuFire");
		if ((Object)(object)val3 == (Object)null)
		{
			return;
		}
		Vector3 position = val3.position;
		int num = 0;
		Random random = new Random(99);
		int num2 = 6;
		for (int i = 0; i < num2; i++)
		{
			float num3 = (float)i / (float)num2 * 360f;
			float num4 = 8f + (float)random.NextDouble() * 8f;
			float num5 = Mathf.Cos(num3 * ((float)Math.PI / 180f)) * num4;
			float num6 = Mathf.Sin(num3 * ((float)Math.PI / 180f)) * num4;
			Vector3 position2 = position + new Vector3(num5, 0f, num6);
			float num7 = 0.06f + (float)random.NextDouble() * 0.08f;
			GameObject val4 = SafeSpawn(val, position2, Vector3.one * num7);
			if ((Object)(object)val4 != (Object)null)
			{
				val4.transform.Rotate(0f, (float)random.NextDouble() * 360f, 0f);
				num++;
			}
		}
		for (int j = 0; j < 4; j++)
		{
			float num8 = (float)random.NextDouble() * 360f;
			float num9 = 3f + (float)random.NextDouble() * 5f;
			float num10 = Mathf.Cos(num8 * ((float)Math.PI / 180f)) * num9;
			float num11 = Mathf.Sin(num8 * ((float)Math.PI / 180f)) * num9;
			Vector3 position3 = position + new Vector3(num10, -0.2f, num11);
			float num12 = 0.04f + (float)random.NextDouble() * 0.06f;
			GameObject val5 = SafeSpawn(val, position3, Vector3.one * num12);
			if ((Object)(object)val5 != (Object)null)
			{
				val5.transform.Rotate(0f, (float)random.NextDouble() * 360f, 0f);
				num++;
			}
		}
		Debug.Log((object)$"[AuroraMenu] Placed {num} ice decorations + snow patches.");
	}

	private static void SnowifyTerrainOnly()
	{
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Expected O, but got Unknown
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Expected O, but got Unknown
		GameObject val = GameObject.Find("Static");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2 = val.transform.Find("Terrain");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Shader val3 = null;
		string[] array = new string[3] { "Standard", "Legacy Shaders/Diffuse", "Diffuse" };
		for (int i = 0; i < array.Length; i++)
		{
			val3 = Shader.Find(array[i]);
			if ((Object)(object)val3 != (Object)null)
			{
				break;
			}
		}
		if ((Object)(object)val3 == (Object)null)
		{
			MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val4 in componentsInChildren)
			{
				object obj;
				if (val4 == null)
				{
					obj = null;
				}
				else
				{
					Material sharedMaterial = ((Renderer)val4).sharedMaterial;
					obj = ((sharedMaterial != null) ? sharedMaterial.shader : null);
				}
				if ((Object)obj != (Object)null && !((Object)((Renderer)val4).sharedMaterial.shader).name.Contains("Water") && !((Object)((Renderer)val4).sharedMaterial.shader).name.Contains("Particle"))
				{
					val3 = ((Renderer)val4).sharedMaterial.shader;
					break;
				}
			}
		}
		if ((Object)(object)val3 == (Object)null)
		{
			return;
		}
		Material val5 = new Material(val3);
		val5.color = new Color(0.75f, 0.78f, 0.85f, 1f);
		if (val5.HasProperty("_Glossiness"))
		{
			val5.SetFloat("_Glossiness", 0.3f);
		}
		if (val5.HasProperty("_Metallic"))
		{
			val5.SetFloat("_Metallic", 0f);
		}
		int num = 0;
		foreach (Transform item in val2)
		{
			Transform val6 = item;
			if (!((Object)val6).name.StartsWith("MenuZone") && !((Object)val6).name.Contains("Terrain"))
			{
				continue;
			}
			MeshRenderer[] componentsInChildren = ((Component)val6).GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val7 in componentsInChildren)
			{
				if (!((Object)(object)val7 == (Object)null))
				{
					Material[] materials = ((Renderer)val7).materials;
					for (int j = 0; j < materials.Length; j++)
					{
						materials[j] = val5;
					}
					((Renderer)val7).materials = materials;
					num++;
				}
			}
		}
		Transform val8 = val2.Find("MenuTerrain_DISTANT");
		if ((Object)(object)val8 != (Object)null)
		{
			MeshRenderer[] componentsInChildren = ((Component)val8).GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val9 in componentsInChildren)
			{
				if (!((Object)(object)val9 == (Object)null))
				{
					Material[] materials2 = ((Renderer)val9).materials;
					for (int k = 0; k < materials2.Length; k++)
					{
						materials2[k] = val5;
					}
					((Renderer)val9).materials = materials2;
					num++;
				}
			}
		}
		Debug.Log((object)$"[AuroraMenu] Snowified {num} terrain renderers (MenuZone only).");
	}

	private static void EnableGlobalSnow()
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		Shader.EnableKeyword("_ADDSNOW_ON");
		Shader.SetGlobalFloat("_AddSnow", 1f);
		Shader.SetGlobalFloat("_SnowAmount", 1f);
		Shader.SetGlobalFloat("_Snow", 1f);
		Shader.SetGlobalVector("_SnowDir", new Vector4(0f, 1f, 0f, 0f));
		Shader.SetGlobalColor("_SnowColor", new Color(0.9f, 0.92f, 0.96f, 1f));
		GameObject val = GameObject.Find("Static");
		if ((Object)(object)val != (Object)null)
		{
			Transform val2 = val.transform.Find("fogplanes");
			if ((Object)(object)val2 != (Object)null)
			{
				MeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val3 in componentsInChildren)
				{
					if ((Object)(object)val3 == (Object)null || (Object)(object)((Renderer)val3).material == (Object)null)
					{
						continue;
					}
					try
					{
						if (((Renderer)val3).material.HasProperty("_Color"))
						{
							((Renderer)val3).material.SetColor("_Color", new Color(0.04f, 0.05f, 0.1f, 0.8f));
						}
						if (((Renderer)val3).material.HasProperty("_TintColor"))
						{
							((Renderer)val3).material.SetColor("_TintColor", new Color(0.04f, 0.05f, 0.1f, 0.8f));
						}
					}
					catch
					{
					}
				}
			}
		}
		Debug.Log((object)"[AuroraMenu] Global snow enabled + fogplanes tinted.");
	}

	private static void HideMeadowStuff()
	{
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Expected O, but got Unknown
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("Static");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2 = val.transform.Find("props_al");
		if ((Object)(object)val2 != (Object)null)
		{
			foreach (Transform item in val2)
			{
				Transform val3 = item;
				string text = ((Object)val3).name.ToLower();
				if (text.Contains("bush") || text.Contains("flower") || text.Contains("meadow") || text.Contains("monster"))
				{
					((Component)val3).gameObject.SetActive(false);
				}
			}
			Transform val4 = val2.Find("Pines");
			Vector3 val5 = default(Vector3);
			((Vector3)(ref val5))..ctor(-165.35f, 54.46f, 229.09f);
			if ((Object)(object)val4 != (Object)null)
			{
				Random random = new Random(77);
				int num = 0;
				int num2 = 0;
				foreach (Transform item2 in val4)
				{
					Transform val6 = item2;
					float num3 = val6.position.z - val5.z;
					float num4 = ((num3 < -2f) ? 0.55f : ((!(num3 > 2f)) ? 0.4f : 0.3f));
					if (random.NextDouble() < (double)num4)
					{
						((Component)val6).gameObject.SetActive(false);
						num++;
						if (num % 4 == 0)
						{
							GameObject val7 = new GameObject("BlueTorch");
							val7.transform.position = val6.position + Vector3.up * 4f;
							Light obj = val7.AddComponent<Light>();
							obj.type = (LightType)2;
							obj.color = new Color(0.15f, 0.45f, 1f, 1f);
							obj.intensity = 4f;
							obj.range = 15f;
							num2++;
						}
					}
				}
				Debug.Log((object)$"[AuroraMenu] Thinned trees: {num} hidden, {num2} blue torches added.");
			}
		}
		Transform val8 = val.transform.Find("Terrain");
		if ((Object)(object)val8 != (Object)null)
		{
			Transform val9 = val8.Find("DistantWater");
			if ((Object)(object)val9 != (Object)null)
			{
				Vector3 position = val9.position;
				position.y = 30f;
				val9.position = position;
			}
		}
		GameObject val10 = GameObject.Find("Backgroundscene");
		if ((Object)(object)val10 != (Object)null)
		{
			Transform val11 = val10.transform.Find("grassroot");
			if ((Object)(object)val11 != (Object)null)
			{
				((Component)val11).gameObject.SetActive(false);
			}
		}
		Debug.Log((object)"[AuroraMenu] Meadow elements hidden.");
	}

	private static void ApplyMountainNightLighting()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		RenderSettings.fog = true;
		RenderSettings.fogMode = (FogMode)3;
		RenderSettings.fogColor = new Color(0.02f, 0.03f, 0.06f, 1f);
		RenderSettings.fogDensity = 0.03f;
		RenderSettings.ambientMode = (AmbientMode)3;
		RenderSettings.ambientLight = new Color(0.015f, 0.02f, 0.04f, 1f);
		RenderSettings.ambientIntensity = 0.15f;
		GameObject val = GameObject.Find("Backgroundscene");
		if ((Object)(object)val != (Object)null)
		{
			Transform val2 = val.transform.Find("Directional Light");
			if ((Object)(object)val2 != (Object)null)
			{
				Light component = ((Component)val2).GetComponent<Light>();
				if ((Object)(object)component != (Object)null)
				{
					component.color = new Color(0.08f, 0.1f, 0.2f, 1f);
					component.intensity = 0.06f;
					((Component)component).transform.rotation = Quaternion.Euler(60f, -30f, 0f);
				}
			}
		}
		GameObject val3 = GameObject.Find("Static");
		if ((Object)(object)val3 != (Object)null)
		{
			Light[] componentsInChildren = val3.GetComponentsInChildren<Light>(true);
			foreach (Light val4 in componentsInChildren)
			{
				if (!((Object)(object)val4 == (Object)null) && (int)val4.type == 0)
				{
					val4.intensity *= 0.1f;
					val4.color = new Color(0.1f, 0.12f, 0.25f, 1f);
				}
			}
		}
		Material skybox = RenderSettings.skybox;
		if ((Object)(object)skybox != (Object)null)
		{
			if (skybox.HasProperty("_Exposure"))
			{
				skybox.SetFloat("_Exposure", 0.05f);
			}
			if (skybox.HasProperty("_Tint"))
			{
				skybox.SetColor("_Tint", new Color(0.04f, 0.06f, 0.12f, 1f));
			}
			if (skybox.HasProperty("_SkyTint"))
			{
				skybox.SetColor("_SkyTint", new Color(0.04f, 0.06f, 0.12f, 1f));
			}
		}
		if ((Object)(object)val3 != (Object)null)
		{
			Transform val5 = val3.transform.Find("fogplanes");
			if ((Object)(object)val5 != (Object)null)
			{
				MeshRenderer[] componentsInChildren2 = ((Component)val5).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val6 in componentsInChildren2)
				{
					if ((Object)(object)val6 == (Object)null || (Object)(object)((Renderer)val6).material == (Object)null)
					{
						continue;
					}
					try
					{
						if (((Renderer)val6).material.HasProperty("_Color"))
						{
							((Renderer)val6).material.SetColor("_Color", new Color(0.04f, 0.06f, 0.1f, 0.8f));
						}
						if (((Renderer)val6).material.HasProperty("_TintColor"))
						{
							((Renderer)val6).material.SetColor("_TintColor", new Color(0.04f, 0.06f, 0.1f, 0.8f));
						}
					}
					catch
					{
					}
				}
			}
		}
		Debug.Log((object)"[AuroraMenu] Mountain night lighting applied.");
	}

	private static void ConvertFireToFrostFire()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.Find("Static");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		Transform val2 = val.transform.Find("MenuFire");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Light[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Light>(true);
		foreach (Light val3 in componentsInChildren)
		{
			if (!((Object)(object)val3 == (Object)null))
			{
				val3.color = new Color(0.2f, 0.45f, 1f, 1f);
				val3.intensity = 1.8f;
				val3.range = 10f;
			}
		}
		ParticleSystemRenderer[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<ParticleSystemRenderer>(true);
		foreach (ParticleSystemRenderer val4 in componentsInChildren2)
		{
			if ((Object)(object)val4 == (Object)null || (Object)(object)((Renderer)val4).material == (Object)null)
			{
				continue;
			}
			try
			{
				Material material = ((Renderer)val4).material;
				if (material.HasProperty("_TintColor"))
				{
					material.SetColor("_TintColor", new Color(0.3f, 0.5f, 1f, 0.5f));
				}
				else if (material.HasProperty("_Color"))
				{
					material.SetColor("_Color", new Color(0.4f, 0.6f, 1f, material.GetColor("_Color").a));
				}
			}
			catch
			{
			}
		}
		ParticleSystem[] componentsInChildren3 = ((Component)val2).GetComponentsInChildren<ParticleSystem>(true);
		foreach (ParticleSystem val5 in componentsInChildren3)
		{
			if (!((Object)(object)val5 == (Object)null))
			{
				try
				{
					MainModule main = val5.main;
					MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.4f, 0.65f, 1f, ((MinMaxGradient)(ref startColor)).color.a));
				}
				catch
				{
				}
			}
		}
		Debug.Log((object)"[AuroraMenu] Frost fire applied.");
	}

	private static void PlaceHaldorNearFire()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: 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_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = null;
		if (_prefabs.ContainsKey("Haldor"))
		{
			val = _prefabs["Haldor"];
		}
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		GameObject val2 = GameObject.Find("Static");
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		Transform val3 = val2.transform.Find("MenuFire");
		if (!((Object)(object)val3 == (Object)null))
		{
			Vector3 position = val3.position;
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(-166.5f, 54.42f, 227.2f);
			GameObject val5 = SafeSpawn(val, val4, Vector3.one * 0.9f);
			if ((Object)(object)val5 != (Object)null)
			{
				val5.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
				GameObject val6 = new GameObject("HaldorLantern");
				val6.transform.SetParent(val5.transform, false);
				val6.transform.localPosition = new Vector3(0f, 3f, 0f);
				Light obj = val6.AddComponent<Light>();
				obj.type = (LightType)2;
				obj.color = new Color(1f, 0.75f, 0.3f, 1f);
				obj.intensity = 4f;
				obj.range = 14f;
				Debug.Log((object)$"[AuroraMenu] Placed Haldor at {val4} near fire at {position}.");
			}
		}
	}

	private static void PlaceBogWitchBehindLogo()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: 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_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = (_prefabs.ContainsKey("BogWitch") ? _prefabs["BogWitch"] : null);
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogWarning((object)"[AuroraMenu] BogWitch prefab not found.");
			return;
		}
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(-168f, 53.5f, 229f);
		GameObject val3 = SafeSpawn(val, val2, Vector3.one * 1.5f);
		if ((Object)(object)val3 != (Object)null)
		{
			Vector3 val4 = new Vector3(-142.53f, 59f, 227.72f) - val2;
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			normalized.y = 0f;
			val3.transform.rotation = Quaternion.LookRotation(normalized);
			GameObject val5 = new GameObject("BogWitchLight");
			val5.transform.SetParent(val3.transform, false);
			val5.transform.localPosition = new Vector3(0f, 4f, 0f);
			Light obj = val5.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(0.15f, 0.8f, 0.25f, 1f);
			obj.intensity = 4f;
			obj.range = 10f;
			GameObject val6 = new GameObject("BogWitchFill");
			val6.transform.SetParent(val3.transform, false);
			val6.transform.localPosition = new Vector3(0f, 2f, 2f);
			Light obj2 = val6.AddComponent<Light>();
			obj2.type = (LightType)2;
			obj2.color = new Color(0.1f, 0.6f, 0.2f, 1f);
			obj2.intensity = 3f;
			obj2.range = 8f;
			GameObject val7 = new GameObject("BogWitchRim");
			val7.transform.SetParent(val3.transform, false);
			val7.transform.localPosition = new Vector3(0f, 7f, -1f);
			Light obj3 = val7.AddComponent<Light>();
			obj3.type = (LightType)0;
			obj3.color = new Color(0.1f, 0.7f, 0.2f, 1f);
			obj3.intensity = 3f;
			obj3.range = 10f;
			obj3.spotAngle = 60f;
			val7.transform.rotation = Quaternion.Euler(90f, 0f, 0f);
			Debug.Log((object)$"[AuroraMenu] Placed BogWitch at {val2} (scale 1.5x).");
		}
	}

	private static void PlaceHildirAndGolem()
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: 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_0191: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(-165.35f, 54.46f, 229.09f);
		GameObject val2 = (_prefabs.ContainsKey("Hildir") ? _prefabs["Hildir"] : null);
		Vector3 val5;
		if ((Object)(object)val2 != (Object)null)
		{
			Vector3 val3 = val + new Vector3(1f, 0f, -2f);
			GameObject val4 = SafeSpawn(val2, val3, Vector3.one * 1f);
			if ((Object)(object)val4 != (Object)null)
			{
				val5 = val - val3;
				Vector3 normalized = ((Vector3)(ref val5)).normalized;
				normalized.y = 0f;
				val4.transform.rotation = Quaternion.LookRotation(normalized);
				Debug.Log((object)$"[AuroraMenu] Placed Hildir at {val3}.");
			}
		}
		else
		{
			Debug.LogWarning((object)"[AuroraMenu] Hildir prefab not found.");
		}
		GameObject val6 = (_prefabs.ContainsKey("StoneGolem") ? _prefabs["StoneGolem"] : null);
		GameObject val7 = (_prefabs.ContainsKey("MineRock_Obsidian") ? _prefabs["MineRock_Obsidian"] : null);
		GameObject val8 = val6 ?? val7;
		if ((Object)(object)val8 != (Object)null)
		{
			Vector3 val9 = default(Vector3);
			((Vector3)(ref val9))..ctor(-156f, 54f, 221f);
			float num = (((Object)(object)val8 == (Object)(object)val6) ? 0.8f : 0.15f);
			GameObject val10 = SafeSpawn(val8, val9, Vector3.one * num);
			if ((Object)(object)val10 != (Object)null)
			{
				val5 = val - val9;
				Vector3 normalized2 = ((Vector3)(ref val5)).normalized;
				normalized2.y = 0f;
				val10.transform.rotation = Quaternion.LookRotation(normalized2);
				Debug.Log((object)$"[AuroraMenu] Placed {((Object)val8).name} at {val9}.");
			}
		}
	}

	private static void SpawnSnowParticles()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: 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_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Expected O, but got Unknown
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		GameObject obj = GameObject.Find("Static");
		Transform val = ((obj != null) ? obj.transform.Find("MenuFire") : null);
		Vector3 val2 = (Vector3)(((Object)(object)val != (Object)null) ? val.position : new Vector3(-165f, 54f, 229f));
		GameObject val3 = new GameObject("MountainSnow");
		val3.transform.position = val2 + Vector3.up * 20f;
		ParticleSystem val4 = val3.AddComponent<ParticleSystem>();
		MainModule main = val4.main;
		((MainModule)(ref main)).loop = true;
		((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(10f);
		((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.5f, 2f);
		((MainModule)(ref main)).startSize = new MinMaxCurve(0.06f, 0.18f);
		((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.85f, 0.9f, 1f, 0.9f));
		((MainModule)(ref main)).maxParticles = 5000;
		((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
		((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0.08f);
		EmissionModule emission = val4.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(400f);
		ShapeModule shape = val4.shape;
		((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)5;
		((ShapeModule)(ref shape)).scale = new Vector3(80f, 2f, 80f);
		ParticleSystemRenderer component = val3.GetComponent<ParticleSystemRenderer>();
		if ((Object)(object)component != (Object)null)
		{
			component.renderMode = (ParticleSystemRenderMode)0;
			ParticleSystemRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<ParticleSystemRenderer>(true);
			foreach (ParticleSystemRenderer val5 in componentsInChildren)
			{
				if ((Object)(object)val5 != (Object)null && (Object)(object)((Renderer)val5).material != (Object)null)
				{
					Material val6 = new Material(((Renderer)val5).material);
					if (val6.HasProperty("_TintColor"))
					{
						val6.SetColor("_TintColor", new Color(1f, 1f, 1f, 0.85f));
					}
					if (val6.HasProperty("_Color"))
					{
						val6.SetColor("_Color", new Color(1f, 1f, 1f, 0.85f));
					}
					((Renderer)component).material = val6;
					break;
				}
			}
		}
		NoiseModule noise = val4.noise;
		((NoiseModule)(ref noise)).enabled = true;
		((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(0.6f);
		((NoiseModule)(ref noise)).frequency = 0.2f;
		((NoiseModule)(ref noise)).damping = true;
		VelocityOverLifetimeModule velocityOverLifetime = val4.velocityOverLifetime;
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
		((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(-0.3f, 0.5f);
		val4.Play();
		Debug.Log((object)"[AuroraMenu] Snow particles spawned.");
	}

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

	private static void MuteExistingMusic()
	{
		try
		{
			AudioSource value = Traverse.Create((object)MusicMan.instance).Field("m_musicSource").GetValue<AudioSource>();
			if ((Object)(object)value != (Object)null)
			{
				value.Stop();
				value.mute = true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)AudioMan.instance != (Object)null)
			{
				string[] array = new string[3] { "m_musicSource", "m_oceanAmbientSource", "m_windLoopSource" };
				foreach (string text in array)
				{
					try
					{
						AudioSource value2 = Traverse.Create((object)AudioMan.instance).Field(text).GetValue<AudioSource>();
						if ((Object)(object)value2 != (Object)null)
						{
							value2.Stop();
							value2.mute = true;
						}
					}
					catch
					{
					}
				}
			}
		}
		catch
		{
		}
		GameObject val = GameObject.Find("Amb_MainMenu");
		if ((Object)(object)val != (Object)null)
		{
			AudioSource component = val.GetComponent<AudioSource>();
			if ((Object)(object)component != (Object)null)
			{
				component.Stop();
				component.mute = true;
			}
		}
	}

	private static void HideMenuUIElements()
	{
		try
		{
			FejdStartup instance = FejdStartup.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			GameObject val = GameObject.Find("GuiRoot");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			string[] array = new string[16]
			{
				"changelog", "change_log", "merch", "store", "patch", "news", "moddedstuff", "modded", "version", "beta",
				"bepinex", "valheimversion", "buildid", "networkversion", "versioninfo", "modding"
			};
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				string text = ((Object)val2).name.ToLower();
				string[] array2 = array;
				foreach (string value in array2)
				{
					if (text.Contains(value))
					{
						((Component)val2).gameObject.SetActive(false);
						break;
					}
				}
			}
			try
			{
				Traverse val3 = Traverse.Create((object)instance);
				string[] array2 = new string[8] { "m_changeLog", "m_changelog", "m_newsPanel", "m_patchNotes", "m_merchPanel", "m_versionLabel", "m_moddedStuff", "m_betaText" };
				foreach (string text2 in array2)
				{
					try
					{
						object value2 = val3.Field(text2).GetValue();
						GameObject val4 = (GameObject)((value2 is GameObject) ? value2 : null);
						if (val4 != null)
						{
							val4.SetActive(false);
							continue;
						}
						Component val5 = (Component)((value2 is Component) ? value2 : null);
						if (val5 != null)
						{
							val5.gameObject.SetActive(false);
						}
					}
					catch
					{
					}
				}
			}
			catch
			{
			}
		}
		catch
		{
		}
	}

	private static GameObject SafeSpawn(GameObject prefab, Vector3 position, Vector3 scale)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			bool activeSelf = prefab.activeSelf;
			prefab.SetActive(false);
			GameObject val = Object.Instantiate<GameObject>(prefab);
			prefab.SetActive(activeSelf);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			DisableGameplayComponents(val);
			val.transform.position = position;
			val.transform.localScale = scale;
			val.SetActive(true);
			return val;
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[AuroraMenu] SafeSpawn failed: " + ex.Message));
			return null;
		}
	}

	private static void DisableGameplayComponents(GameObject obj)
	{
		try
		{
			MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					string name = ((object)val).GetType().Name;
					if (name != "LODGroup" && name != "MeshRenderer" && name != "MeshFilter" && name != "SkinnedMeshRenderer")
					{
						((Behaviour)val).enabled = false;
					}
				}
				catch
				{
				}
			}
			Collider[] componentsInChildren2 = obj.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					val2.enabled = false;
				}
			}
			Rigidbody[] componentsInChildren3 = obj.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					val3.isKinematic = true;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch]
public static class MusicPatches
{
	[HarmonyPatch(typeof(MusicMan), "UpdateMusic")]
	[HarmonyPrefix]
	public static bool UpdateMusic_Prefix()
	{
		if ((Object)(object)FejdStartup.instance != (Object)null && MountainAtmospherePatches.IsCustomMusicPlaying())
		{
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(Player), "OnSpawned")]
	[HarmonyPostfix]
	public static void OnSpawned_Postfix()
	{
		MountainAtmospherePatches.StopCustomMusic();
	}
}

plugins/AuroraProjectButter.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AuroraProjectButter")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: AssemblyProduct("AuroraProjectButter")]
[assembly: AssemblyTitle("AuroraProjectButter")]
[assembly: AssemblyVersion("1.3.0.0")]
namespace AuroraProjectButter;

[BepInPlugin("freyja.AuroraProjectButter", "AuroraProjectButter", "1.3.0")]
public class ButterPlugin : BaseUnityPlugin
{
	internal struct DeferredDungeon
	{
		public DungeonGenerator Generator;

		public Vector3 Position;
	}

	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static ConsoleEvent <>9__27_0;

		public static Func<MethodInfo, bool> <>9__31_0;

		public static Func<MethodInfo, bool> <>9__31_1;

		public static Func<MethodInfo, bool> <>9__31_2;

		public static Func<MethodInfo, bool> <>9__31_3;

		public static Func<MethodInfo, bool> <>9__32_0;

		public static Func<ParameterInfo, string> <>9__32_1;

		public static Predicate<DeferredDungeon> <>9__37_0;

		internal void <Awake>b__27_0(ConsoleEventArgs args)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			DungeonCleanup();
			Player localPlayer = Player.m_localPlayer;
			float num = ((localPlayer != null) ? ((Component)localPlayer).transform.position.y : float.NaN);
			bool flag = IsPlayerTeleporting();
			bool flag2 = IsInGracePeriod();
			args.Context.AddString("[AuroraProjectButter v1.3.0]");
			args.Context.AddString($"  Dungeon Deferral: {TotalDeferred} deferred, {TotalAllowed} allowed, {Deferred.Count} queued");
			args.Context.AddString($"  Sky Filter: {SkyObjectsBlocked} blocked, {SkyObjectsAllowed} allowed");
			args.Context.AddString($"  Player Y: {num:F1}  Teleporting: {flag}  Grace: {flag2}");
			args.Context.AddString($"  World radius: {WorldRadius.Value}");
		}

		internal bool <ApplyDungeonPatches>b__31_0(MethodInfo m)
		{
			return m.Name == "Generate" && !m.IsAbstract;
		}

		internal bool <ApplyDungeonPatches>b__31_1(MethodInfo mi)
		{
			return mi.Name == "Interact";
		}

		internal bool <ApplyDungeonPatches>b__31_2(MethodInfo mi)
		{
			return mi.Name == "HaveTarget";
		}

		internal bool <ApplyDungeonPatches>b__31_3(MethodInfo mi)
		{
			return mi.Name == "OnSpawned";
		}

		internal bool <ApplySkyFilterPatches>b__32_0(MethodInfo m)
		{
			return m.Name == "CreateObject" && !m.IsAbstract;
		}

		internal string <ApplySkyFilterPatches>b__32_1(ParameterInfo p)
		{
			return p.ParameterType.Name;
		}

		internal bool <DungeonCleanup>b__37_0(DeferredDungeon d)
		{
			return (Object)(object)d.Generator == (Object)null;
		}
	}

	public const string PluginGUID = "freyja.AuroraProjectButter";

	public const string PluginName = "AuroraProjectButter";

	public const string PluginVersion = "1.3.0";

	internal static ButterPlugin Instance;

	internal static ManualLogSource Logger;

	private Harmony _harmony;

	internal static readonly List<DeferredDungeon> Deferred = new List<DeferredDungeon>();

	internal static bool IsForceLoading;

	internal static bool IsTeleporting;

	internal static float PlayerSpawnTime = -1f;

	internal static float TeleportEndTime = -1f;

	internal static MethodInfo DG_AwakeMethod;

	internal static int TotalDeferred;

	internal static int TotalAllowed;

	internal static int SkyObjectsBlocked;

	internal static int SkyObjectsAllowed;

	public static ConfigEntry<bool> ModEnabled;

	public static ConfigEntry<bool> VerboseLogging;

	public static ConfigEntry<float> SearchRadius;

	public static ConfigEntry<float> TeleportDelay;

	public static ConfigEntry<bool> ShowLoadingMsg;

	public static ConfigEntry<float> SpawnGracePeriod;

	public static ConfigEntry<bool> SkyFilterEnabled;

	public static ConfigEntry<float> SkyThreshold;

	public static ConfigEntry<float> TeleportGracePeriod;

	public static ConfigEntry<float> WorldRadius;

	private void Awake()
	{
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Expected O, but got Unknown
		Instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle.");
		VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Extra logging.");
		SearchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("DungeonDeferral", "SearchRadius", 300f, "Max distance from entrance to find deferred dungeon.");
		TeleportDelay = ((BaseUnityPlugin)this).Config.Bind<float>("DungeonDeferral", "TeleportDelay", 2.5f, "Seconds to wait after loading dungeon before teleport.");
		ShowLoadingMsg = ((BaseUnityPlugin)this).Config.Bind<bool>("DungeonDeferral", "ShowLoadingMessage", true, "Show 'Loading dungeon...' message.");
		SpawnGracePeriod = ((BaseUnityPlugin)this).Config.Bind<float>("DungeonDeferral", "SpawnGracePeriod", 2f, "Seconds after login to allow all loading.");
		SkyFilterEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("SkyFilter", "Enabled", true, "Skip creating GameObjects for dungeon interior objects while on surface.");
		SkyThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("SkyFilter", "SkyThresholdY", 1000f, "Objects above this Y are considered dungeon interiors.");
		TeleportGracePeriod = ((BaseUnityPlugin)this).Config.Bind<float>("SkyFilter", "TeleportGracePeriod", 5f, "Seconds after ANY teleport where sky filter is disabled. Prevents loading screen freeze.");
		WorldRadius = ((BaseUnityPlugin)this).Config.Bind<float>("SkyFilter", "WorldRadius", 15000f, "Objects beyond this X/Z distance from world center are never filtered. Set higher than your world radius to protect custom sky zones. Default 15000 covers most Expand World Size configs.");
		_harmony = new Harmony("freyja.AuroraProjectButter");
		Logger.LogInfo((object)"── Dungeon Deferral patches ──");
		ApplyDungeonPatches();
		Logger.LogInfo((object)"── Sky Object Filter patches ──");
		ApplySkyFilterPatches();
		object obj = <>c.<>9__27_0;
		if (obj == null)
		{
			ConsoleEvent val = delegate(ConsoleEventArgs args)
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				DungeonCleanup();
				Player localPlayer = Player.m_localPlayer;
				float num = ((localPlayer != null) ? ((Component)localPlayer).transform.position.y : float.NaN);
				bool flag = IsPlayerTeleporting();
				bool flag2 = IsInGracePeriod();
				args.Context.AddString("[AuroraProjectButter v1.3.0]");
				args.Context.AddString($"  Dungeon Deferral: {TotalDeferred} deferred, {TotalAllowed} allowed, {Deferred.Count} queued");
				args.Context.AddString($"  Sky Filter: {SkyObjectsBlocked} blocked, {SkyObjectsAllowed} allowed");
				args.Context.AddString($"  Player Y: {num:F1}  Teleporting: {flag}  Grace: {flag2}");
				args.Context.AddString($"  World radius: {WorldRadius.Value}");
			};
			<>c.<>9__27_0 = val;
			obj = (object)val;
		}
		new ConsoleCommand("butter_status", "Show AuroraProjectButter stats", (ConsoleEvent)obj, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		Logger.LogInfo((object)"=== AuroraProjectButter v1.3.0 loaded ===");
		Logger.LogInfo((object)"  Dungeon Deferral: ON");
		Logger.LogInfo((object)string.Format("  Sky Filter: {0} (Y > {1}, grace {2}s, radius {3})", SkyFilterEnabled.Value ? "ON" : "OFF", SkyThreshold.Value, TeleportGracePeriod.Value, WorldRadius.Value));
	}

	private void OnDestroy()
	{
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
	}

	internal static bool IsPlayerTeleporting()
	{
		if (IsTeleporting)
		{
			return true;
		}
		if (IsForceLoading)
		{
			return true;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return false;
		}
		try
		{
			FieldInfo field = typeof(Player).GetField("m_teleporting", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				return (bool)field.GetValue(localPlayer);
			}
		}
		catch
		{
		}
		return false;
	}

	internal static bool IsInGracePeriod()
	{
		float time = Time.time;
		if (PlayerSpawnTime > 0f && time - PlayerSpawnTime < SpawnGracePeriod.Value)
		{
			return true;
		}
		if (TeleportEndTime > 0f && time - TeleportEndTime < TeleportGracePeriod.Value)
		{
			return true;
		}
		return false;
	}

	private void ApplyDungeonPatches()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Expected O, but got Unknown
		//IL_0273: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Expected O, but got Unknown
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Expected O, but got Unknown
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Expected O, but got Unknown
		try
		{
			DG_AwakeMethod = typeof(DungeonGenerator).GetMethod("Awake", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (DG_AwakeMethod != null)
			{
				_harmony.Patch((MethodBase)DG_AwakeMethod, new HarmonyMethod(typeof(DungeonPatches), "Awake_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"  OK: DungeonGenerator.Awake()");
			}
			else
			{
				Logger.LogError((object)"  FAIL: DungeonGenerator.Awake()");
			}
		}
		catch (Exception arg)
		{
			Logger.LogError((object)$"  DG.Awake: {arg}");
		}
		try
		{
			MethodInfo method = typeof(DungeonGenerator).GetMethod("LoadRoomPrefabsAsync", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			if (method != null)
			{
				_harmony.Patch((MethodBase)method, new HarmonyMethod(typeof(DungeonPatches), "LoadAsync_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"  OK: LoadRoomPrefabsAsync() (fallback)");
			}
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("  LoadAsync: " + ex.Message));
		}
		try
		{
			List<MethodInfo> list = (from m in typeof(DungeonGenerator).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				where m.Name == "Generate" && !m.IsAbstract
				select m).ToList();
			MethodInfo method2 = typeof(DungeonPatches).GetMethod("Generate_Prefix", BindingFlags.Static | BindingFlags.Public);
			int num = 0;
			foreach (MethodInfo item in list)
			{
				try
				{
					_harmony.Patch((MethodBase)item, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch
				{
				}
			}
			Logger.LogInfo((object)$"  OK: {num} Generate overload(s)");
		}
		catch (Exception arg2)
		{
			Logger.LogError((object)$"  Generate: {arg2}");
		}
		try
		{
			MethodInfo methodInfo = typeof(Teleport).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo mi) => mi.Name == "Interact");
			if (methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(DungeonPatches), "Teleport_Interact_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"  OK: Teleport.Interact");
			}
		}
		catch (Exception arg3)
		{
			Logger.LogError((object)$"  Teleport.Interact: {arg3}");
		}
		try
		{
			MethodInfo methodInfo2 = typeof(Teleport).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo mi) => mi.Name == "HaveTarget");
			if (methodInfo2 != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(DungeonPatches), "HaveTarget_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"  OK: Teleport.HaveTarget");
			}
		}
		catch (Exception ex2)
		{
			Logger.LogWarning((object)("  HaveTarget: " + ex2.Message));
		}
		try
		{
			MethodInfo methodInfo3 = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo mi) => mi.Name == "OnSpawned");
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(DungeonPatches), "Player_OnSpawned_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Logger.LogInfo((object)"  OK: Player.OnSpawned");
			}
		}
		catch (Exception ex3)
		{
			Logger.LogWarning((object)("  Player.OnSpawned: " + ex3.Message));
		}
	}

	private void ApplySkyFilterPatches()
	{
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Expected O, but got Unknown
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		if (!SkyFilterEnabled.Value)
		{
			Logger.LogInfo((object)"  Sky Filter DISABLED in config.");
			return;
		}
		try
		{
			List<MethodInfo> list = (from m in typeof(ZNetScene).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				where m.Name == "CreateObject" && !m.IsAbstract
				select m).ToList();
			MethodInfo method = typeof(SkyFilterPatches).GetMethod("CreateObject_Prefix", BindingFlags.Static | BindingFlags.Public);
			int num = 0;
			foreach (MethodInfo item in list)
			{
				ParameterInfo[] parameters = item.GetParameters();
				if (parameters.Length >= 1 && parameters[0].ParameterType == typeof(ZDO))
				{
					_harmony.Patch((MethodBase)item, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					string text = string.Join(", ", parameters.Select((ParameterInfo p) => p.ParameterType.Name));
					Logger.LogInfo((object)("  OK: ZNetScene.CreateObject(" + text + ")"));
					num++;
				}
			}
			if (num == 0)
			{
				Logger.LogWarning((object)"  No ZDO-parameter CreateObject found. Trying all overloads...");
				foreach (MethodInfo item2 in list)
				{
					try
					{
						_harmony.Patch((MethodBase)item2, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
					}
					catch
					{
					}
				}
			}
			if (num == 0)
			{
				Logger.LogError((object)"  FAIL: Could not patch any ZNetScene.CreateObject!");
			}
		}
		catch (Exception arg)
		{
			Logger.LogError((object)$"  ZNetScene.CreateObject: {arg}");
		}
	}

	internal static bool ShouldDefer(string caller, Vector3 genPos)
	{
		//IL_0084: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		if (!ModEnabled.Value)
		{
			return false;
		}
		if (IsForceLoading)
		{
			return false;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			if (VerboseLogging.Value)
			{
				Logger.LogInfo((object)$"[ALLOW:no-player] {caller} at {genPos:F0}");
			}
			TotalAllowed++;
			return false;
		}
		Vector3 position = ((Component)Player.m_localPlayer).transform.position;
		if (IsInGracePeriod())
		{
			if (VerboseLogging.Value)
			{
				Logger.LogInfo((object)$"[ALLOW:grace] {caller} at {genPos:F0}");
			}
			TotalAllowed++;
			return false;
		}
		if (position.y > 1000f)
		{
			if (VerboseLogging.Value)
			{
				Logger.LogInfo((object)$"[ALLOW:in-dungeon] {caller} at {genPos:F0}");
			}
			TotalAllowed++;
			return false;
		}
		if (IsPlayerTeleporting())
		{
			if (VerboseLogging.Value)
			{
				Logger.LogInfo((object)$"[ALLOW:teleporting] {caller} at {genPos:F0}");
			}
			TotalAllowed++;
			return false;
		}
		Logger.LogInfo((object)$"[DEFER] {caller} at {genPos:F0}, player Y={position.y:F0}");
		TotalDeferred++;
		return true;
	}

	internal static void DeferDungeon(DungeonGenerator gen)
	{
		//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_0057: 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)
		Vector3 position = ((Component)gen).transform.position;
		if (!Deferred.Any((DeferredDungeon d) => (Object)(object)d.Generator == (Object)(object)gen))
		{
			Deferred.Add(new DeferredDungeon
			{
				Generator = gen,
				Position = position
			});
		}
	}

	internal static DeferredDungeon? FindNearest(Vector3 origin, float maxDist)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		DungeonCleanup();
		DeferredDungeon? result = null;
		float num = float.MaxValue;
		foreach (DeferredDungeon item in Deferred)
		{
			float num2 = item.Position.x - origin.x;
			float num3 = item.Position.z - origin.z;
			float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
			if (num4 < maxDist && num4 < num)
			{
				num = num4;
				result = item;
			}
		}
		return result;
	}

	internal static void RemoveDeferred(DungeonGenerator gen)
	{
		Deferred.RemoveAll((DeferredDungeon d) => (Object)(object)d.Generator == (Object)(object)gen || (Object)(object)d.Generator == (Object)null);
	}

	internal static void DungeonCleanup()
	{
		Deferred.RemoveAll((DeferredDungeon d) => (Object)(object)d.Generator == (Object)null);
	}

	internal static void ForceLoadDungeon(DungeonGenerator gen)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		if (DG_AwakeMethod == null)
		{
			Logger.LogError((object)"[REPLAY] No Awake method!");
			return;
		}
		IsForceLoading = true;
		try
		{
			Logger.LogInfo((object)$"[REPLAY] Awake() at {((Component)gen).transform.position:F0}");
			DG_AwakeMethod.Invoke(gen, null);
		}
		finally
		{
			IsForceLoading = false;
		}
	}

	internal static Coroutine RunCoroutine(IEnumerator routine)
	{
		ButterPlugin instance = Instance;
		return (instance != null) ? ((MonoBehaviour)instance).StartCoroutine(routine) : null;
	}
}
internal static class SkyFilterPatches
{
	public static bool CreateObject_Prefix(ZDO __0)
	{
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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_0137: Unknown result type (might be due to invalid IL or missing references)
		if (!ButterPlugin.SkyFilterEnabled.Value)
		{
			return true;
		}
		if (__0 == null)
		{
			return true;
		}
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return true;
		}
		if (ButterPlugin.IsPlayerTeleporting())
		{
			ButterPlugin.SkyObjectsAllowed++;
			return true;
		}
		if (ButterPlugin.IsInGracePeriod())
		{
			ButterPlugin.SkyObjectsAllowed++;
			return true;
		}
		Vector3 position = __0.GetPosition();
		float y = position.y;
		if (y <= ButterPlugin.SkyThreshold.Value)
		{
			return true;
		}
		float num = Mathf.Sqrt(position.x * position.x + position.z * position.z);
		if (num > ButterPlugin.WorldRadius.Value)
		{
			ButterPlugin.SkyObjectsAllowed++;
			if (ButterPlugin.VerboseLogging.Value)
			{
				ButterPlugin.Logger.LogInfo((object)$"[SkyFilter:ALLOW] Outside world radius: Y={y:F0} dist={num:F0}");
			}
			return true;
		}
		float y2 = ((Component)Player.m_localPlayer).transform.position.y;
		if (y2 > ButterPlugin.SkyThreshold.Value)
		{
			ButterPlugin.SkyObjectsAllowed++;
			return true;
		}
		ButterPlugin.SkyObjectsBlocked++;
		if (ButterPlugin.VerboseLogging.Value && ButterPlugin.SkyObjectsBlocked % 100 == 1)
		{
			ButterPlugin.Logger.LogInfo((object)$"[SkyFilter:BLOCK] #{ButterPlugin.SkyObjectsBlocked} Y={y:F0} dist={num:F0}");
		}
		return false;
	}
}
internal static class DungeonPatches
{
	[CompilerGenerated]
	private sealed class <LoadAndTeleport>d__5 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Teleport teleport;

		public ButterPlugin.DeferredDungeon deferred;

		public Humanoid character;

		private Exception <ex>5__1;

		private Exception <ex>5__2;

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

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

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

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

		private bool MoveNext()
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (ButterPlugin.ShowLoadingMsg.Value)
				{
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "Loading dungeon...", 0, (Sprite)null);
					}
				}
				ButterPlugin.TeleportEndTime = Time.time;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if ((Object)(object)deferred.Generator != (Object)null)
				{
					try
					{
						ButterPlugin.ForceLoadDungeon(deferred.Generator);
					}
					catch (Exception ex)
					{
						<ex>5__1 = ex;
						ButterPlugin.Logger.LogError((object)$"[OnDemand] Failed: {<ex>5__1}");
					}
					ButterPlugin.RemoveDeferred(deferred.Generator);
				}
				<>2__current = (object)new WaitForSeconds(ButterPlugin.TeleportDelay.Value);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				ButterPlugin.TeleportEndTime = Time.time;
				if ((Object)(object)teleport != (Object)null && (Object)(object)character != (Object)null)
				{
					ButterPlugin.IsTeleporting = true;
					try
					{
						teleport.Interact(character, false, false);
					}
					catch (Exception ex)
					{
						<ex>5__2 = ex;
						ButterPlugin.Logger.LogError((object)$"[OnDemand] Teleport: {<ex>5__2}");
					}
					finally
					{
						ButterPlugin.IsTeleporting = false;
					}
				}
				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();
		}
	}

	public static void Player_OnSpawned_Postfix(Player __instance)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
		{
			ButterPlugin.PlayerSpawnTime = Time.time;
			ButterPlugin.TeleportEndTime = Time.time;
			ButterPlugin.Logger.LogInfo((object)$"[Spawn] Player at {((Component)__instance).transform.position:F0}");
		}
	}

	public static bool Awake_Prefix(DungeonGenerator __instance)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		if (ButterPlugin.ShouldDefer("Awake", ((Component)__instance).transform.position))
		{
			ButterPlugin.DeferDungeon(__instance);
			return false;
		}
		return true;
	}

	public static bool LoadAsync_Prefix(DungeonGenerator __instance)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		if (ButterPlugin.ShouldDefer("LoadAsync", ((Component)__instance).transform.position))
		{
			ButterPlugin.DeferDungeon(__instance);
			return false;
		}
		return true;
	}

	public static bool Generate_Prefix(DungeonGenerator __instance)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		if (ButterPlugin.ShouldDefer("Generate", ((Component)__instance).transform.position))
		{
			ButterPlugin.DeferDungeon(__instance);
			return false;
		}
		return true;
	}

	public static bool Teleport_Interact_Prefix(Teleport __instance, Humanoid character, bool hold, bool alt)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		if (!ButterPlugin.ModEnabled.Value)
		{
			return true;
		}
		if (ButterPlugin.IsTeleporting)
		{
			return true;
		}
		if ((Object)(object)character != (Object)(object)Player.m_localPlayer)
		{
			return true;
		}
		if (hold)
		{
			return true;
		}
		if (((Component)Player.m_localPlayer).transform.position.y > 1000f)
		{
			ButterPlugin.TeleportEndTime = Time.time;
			return true;
		}
		ButterPlugin.DeferredDungeon? deferredDungeon = ButterPlugin.FindNearest(((Component)__instance).transform.position, ButterPlugin.SearchRadius.Value);
		if (!deferredDungeon.HasValue)
		{
			ButterPlugin.TeleportEndTime = Time.time;
			return true;
		}
		ButterPlugin.Logger.LogInfo((object)$"[OnDemand] Entrance → loading dungeon at {deferredDungeon.Value.Position:F0}");
		ButterPlugin.RunCoroutine(LoadAndTeleport(__instance, deferredDungeon.Value, character));
		return false;
	}

	[IteratorStateMachine(typeof(<LoadAndTeleport>d__5))]
	private static IEnumerator LoadAndTeleport(Teleport teleport, ButterPlugin.DeferredDungeon deferred, Humanoid character)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LoadAndTeleport>d__5(0)
		{
			teleport = teleport,
			deferred = deferred,
			character = character
		};
	}

	public static void HaveTarget_Postfix(Teleport __instance, ref bool __result)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		if (ButterPlugin.ModEnabled.Value && (!((Object)(object)Player.m_localPlayer != (Object)null) || !(((Component)Player.m_localPlayer).transform.position.y > 1000f)) && !__result && ButterPlugin.FindNearest(((Component)__instance).transform.position, ButterPlugin.SearchRadius.Value).HasValue)
		{
			__result = true;
		}
	}
}

plugins/AuroraWardDecay.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AuroraWardDecay")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AuroraWardDecay")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("91245976-b7c2-4fcd-88a9-505fe801b8e8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace AuroraWardDecay
{
	public class Class1
	{
	}
}
namespace AuroraWardDecayMod
{
	[BepInPlugin("aurora.warddecay", "AuroraWardDecay", "1.0.5")]
	public class AuroraWardDecayPlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <ServerSweepLoop>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public AuroraWardDecayPlugin <>4__this;

			private PrivateArea[] <wards>5__1;

			private long <nowTicks>5__2;

			private long <maxAge>5__3;

			private PrivateArea[] <>s__4;

			private int <>s__5;

			private PrivateArea <pa>5__6;

			private ZNetView <nview>5__7;

			private ZDO <zdo>5__8;

			private long <lastTouched>5__9;

			private Exception <ex>5__10;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<wards>5__1 = null;
				<>s__4 = null;
				<pa>5__6 = null;
				<nview>5__7 = null;
				<zdo>5__8 = null;
				<ex>5__10 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
					{
						break;
					}
					try
					{
						<wards>5__1 = Object.FindObjectsOfType<PrivateArea>();
						if (<wards>5__1 == null || <wards>5__1.Length == 0)
						{
							break;
						}
						<nowTicks>5__2 = NowTicks();
						<maxAge>5__3 = DaysToTicks(DecayDays.Value);
						<>s__4 = <wards>5__1;
						for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++)
						{
							<pa>5__6 = <>s__4[<>s__5];
							if (Object.op_Implicit((Object)(object)<pa>5__6))
							{
								<nview>5__7 = ((Component)<pa>5__6).GetComponent<ZNetView>();
								if (Object.op_Implicit((Object)(object)<nview>5__7) && <nview>5__7.IsValid())
								{
									<zdo>5__8 = <nview>5__7.GetZDO();
									if (<zdo>5__8 != null)
									{
										<lastTouched>5__9 = <zdo>5__8.GetLong("aurora_lastTouched_ticks", 0L);
										if (<lastTouched>5__9 <= 0)
										{
											<zdo>5__8.Set("aurora_lastTouched_ticks", <nowTicks>5__2);
										}
										else
										{
											if (<nowTicks>5__2 - <lastTouched>5__9 >= <maxAge>5__3)
											{
												Object.Destroy((Object)(object)((Component)<pa>5__6).gameObject);
											}
											<nview>5__7 = null;
											<zdo>5__8 = null;
											<pa>5__6 = null;
										}
									}
								}
							}
						}
						<>s__4 = null;
						<wards>5__1 = null;
					}
					catch (Exception ex)
					{
						<ex>5__10 = ex;
						((BaseUnityPlugin)<>4__this).Logger.LogError((object)$"Ward decay sweep failed: {<ex>5__10}");
					}
					break;
				}
				<>2__current = (object)new WaitForSeconds(CheckIntervalSeconds.Value);
				<>1__state = 1;
				return true;
			}

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

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

		public const string PluginGuid = "aurora.warddecay";

		public const string PluginName = "AuroraWardDecay";

		public const string PluginVersion = "1.0.5";

		internal const string ZdoKeyLastTouchedTicks = "aurora_lastTouched_ticks";

		internal static ConfigEntry<float> CheckIntervalSeconds;

		internal static ConfigEntry<double> DecayDays;

		internal static ConfigEntry<bool> RefreshOnInteractOnly;

		internal static ConfigEntry<bool> EnableHoverText;

		internal static ConfigEntry<string> HoverFormat;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			CheckIntervalSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckIntervalSeconds", 30f, "How often the server checks for expired wards.");
			DecayDays = ((BaseUnityPlugin)this).Config.Bind<double>("General", "DecayDays", 7.0, "Days without interaction before a ward expires.");
			RefreshOnInteractOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RefreshOnInteractOnly", true, "If true, only Interact() refreshes the timer (placement always seeds).");
			EnableHoverText = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableHoverText", true, "Show remaining time on ward hover.");
			HoverFormat = ((BaseUnityPlugin)this).Config.Bind<string>("General", "HoverFormat", "<color=yellow><b>Upkeep:</b></color> {0}", "Format for remaining time; {0}=time left.");
			_harmony = new Harmony("aurora.warddecay");
			_harmony.PatchAll();
			((MonoBehaviour)this).StartCoroutine(ServerSweepLoop());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"AuroraWardDecay 1.0.5 loaded");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}

		[IteratorStateMachine(typeof(<ServerSweepLoop>d__12))]
		private IEnumerator ServerSweepLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ServerSweepLoop>d__12(0)
			{
				<>4__this = this
			};
		}

		internal static long NowTicks()
		{
			return (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTime() : DateTime.UtcNow).ToUniversalTime().Ticks;
		}

		internal static long DaysToTicks(double days)
		{
			return TimeSpan.FromDays(days).Ticks;
		}

		internal static string FormatRemaining(long nowTicks, long lastTouchedTicks, double days)
		{
			long num = DaysToTicks(days);
			long num2 = ((lastTouchedTicks > 0) ? Math.Max(0L, num - (nowTicks - lastTouchedTicks)) : num);
			if (num2 <= 0)
			{
				return "expired";
			}
			TimeSpan timeSpan = TimeSpan.FromTicks(num2);
			if (timeSpan.TotalDays >= 1.0)
			{
				return $"{(int)timeSpan.TotalDays}d {timeSpan.Hours}h";
			}
			if (timeSpan.TotalHours >= 1.0)
			{
				return $"{(int)timeSpan.TotalHours}h {timeSpan.Minutes}m";
			}
			return $"{timeSpan.Minutes}m {timeSpan.Seconds}s";
		}
	}
	internal static class SeedHelper
	{
		public static void Seed(PrivateArea pa)
		{
			if (!Object.op_Implicit((Object)(object)pa))
			{
				return;
			}
			ZNetView component = ((Component)pa).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null && zDO.GetLong("aurora_lastTouched_ticks", 0L) == 0)
				{
					zDO.Set("aurora_lastTouched_ticks", AuroraWardDecayPlugin.NowTicks());
				}
			}
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "Awake")]
	public static class Patch_PrivateArea_Awake_Seed
	{
		private static void Postfix(PrivateArea __instance)
		{
			SeedHelper.Seed(__instance);
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "Interact")]
	public static class Patch_PrivateArea_Interact
	{
		private static void Postfix(PrivateArea __instance, bool __result, Humanoid human, bool hold, bool alt)
		{
			if (!__result || !AuroraWardDecayPlugin.RefreshOnInteractOnly.Value)
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.Set("aurora_lastTouched_ticks", AuroraWardDecayPlugin.NowTicks());
				}
			}
		}
	}
	[HarmonyPatch(typeof(PrivateArea), "GetHoverText")]
	public static class Patch_PrivateArea_GetHoverText
	{
		private static void Postfix(PrivateArea __instance, ref string __result)
		{
			if (!AuroraWardDecayPlugin.EnableHoverText.Value)
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				long @long = zDO.GetLong("aurora_lastTouched_ticks", 0L);
				long nowTicks = AuroraWardDecayPlugin.NowTicks();
				string arg = AuroraWardDecayPlugin.FormatRemaining(nowTicks, @long, AuroraWardDecayPlugin.DecayDays.Value);
				StringBuilder stringBuilder = new StringBuilder(__result ?? string.Empty);
				if (!stringBuilder.ToString().EndsWith("\n"))
				{
					stringBuilder.Append('\n');
				}
				stringBuilder.AppendFormat(AuroraWardDecayPlugin.HoverFormat.Value, arg);
				__result = stringBuilder.ToString();
			}
		}
	}
}

plugins/FreyjaLandlord.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FreyjaLandlord.Core;
using FreyjaLandlord.Data;
using FreyjaLandlord.Network;
using FreyjaLandlord.UI;
using FreyjaLandlord.Utils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("freyja")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A comprehensive landlord and territory economy system for Valheim")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FreyjaLandlord")]
[assembly: AssemblyTitle("FreyjaLandlord")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FreyjaLandlord
{
	[BepInPlugin("freyja.landlord", "Freyja Landlord System", "1.0.0")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "freyja.landlord";

		public const string PluginName = "Freyja Landlord System";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		private GameObject _managerObject;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Loading Freyja Landlord System v1.0.0...");
			LandlordConfig.Initialize(((BaseUnityPlugin)this).Config);
			if (!ServerGuard.Init(this))
			{
				Log.LogError((object)"Server authentication failed - mod disabled");
				return;
			}
			_harmony = new Harmony("freyja.landlord");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Harmony patches applied");
			_managerObject = new GameObject("FreyjaLandlordManager");
			Object.DontDestroyOnLoad((Object)(object)_managerObject);
			_managerObject.AddComponent<TerritoryManager>();
			_managerObject.AddComponent<TollManager>();
			_managerObject.AddComponent<DebtManager>();
			_managerObject.AddComponent<AuctionManager>();
			_managerObject.AddComponent<GridManager>();
			_managerObject.AddComponent<DebtorTracker>();
			_managerObject.AddComponent<LandlordRPC>();
			_managerObject.AddComponent<BanManager>();
			_managerObject.AddComponent<ExplorationTracker>();
			_managerObject.AddComponent<LandlordHUD>();
			_managerObject.AddComponent<MapGridOverlay>();
			_managerObject.AddComponent<TerritoryPopup>();
			Log.LogInfo((object)"Freyja Landlord System loaded successfully!");
			Log.LogInfo((object)$"Press {LandlordConfig.HUDToggleKey.Value} to open the Landlord HUD");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)_managerObject != (Object)null)
			{
				Object.Destroy((Object)(object)_managerObject);
			}
		}
	}
	public class PositionTracker : MonoBehaviour
	{
		private float _trackTimer = 0f;

		private const float TrackInterval = 0.5f;

		private Vector2i? _lastReportedGrid = null;

		private void Update()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			ZNet instance = ZNet.instance;
			if (instance == null || !instance.IsServer())
			{
				_trackTimer += Time.deltaTime;
				if (_trackTimer >= 0.5f)
				{
					_trackTimer = 0f;
					ReportPosition();
				}
			}
		}

		private void ReportPosition()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				Vector3 position = ((Component)localPlayer).transform.position;
				Vector2i val = GridUtils.WorldToVisualGrid(position);
				if (!_lastReportedGrid.HasValue || _lastReportedGrid.Value != val)
				{
					_lastReportedGrid = val;
					LandlordRPC.Instance?.ReportPlayerPosition(position);
				}
			}
		}
	}
}
namespace FreyjaLandlord.Utils
{
	public static class BiomeUtils
	{
		private static Dictionary<Vector2i, bool> _merchantCache = new Dictionary<Vector2i, bool>();

		private static float _merchantCacheTime = 0f;

		private const float MerchantCacheLifetime = 60f;

		public static Biome GetBiomeAt(Vector3 position)
		{
			//IL_0016: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (WorldGenerator.instance == null)
			{
				return (Biome)1;
			}
			return WorldGenerator.instance.GetBiome(position);
		}

		public static Dictionary<int, float> SampleBiomeComposition(Vector2i gridPos, int sampleCount = 100)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected I4, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected I4, but got Unknown
			Dictionary<int, float> dictionary = new Dictionary<int, float>();
			Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(gridPos);
			float num = VoronoiGrid.Instance.GetApproximateRegionRadius(gridPos);
			if (num < 200f)
			{
				num = 200f;
			}
			if (num > 2000f)
			{
				num = 2000f;
			}
			int num2 = (int)Mathf.Sqrt((float)sampleCount);
			if (num2 < 5)
			{
				num2 = 5;
			}
			float num3 = num * 2f;
			float num4 = num3 * 2f / (float)num2;
			int num5 = 0;
			Vector3 val = default(Vector3);
			for (int i = 0; i < num2; i++)
			{
				for (int j = 0; j < num2; j++)
				{
					float num6 = regionCenter.x - num3 + ((float)i + 0.5f) * num4;
					float num7 = regionCenter.z - num3 + ((float)j + 0.5f) * num4;
					((Vector3)(ref val))..ctor(num6, 0f, num7);
					Vector2i region = VoronoiGrid.Instance.GetRegion(val);
					if (region.x == gridPos.x && region.y == gridPos.y)
					{
						Biome biomeAt = GetBiomeAt(val);
						int key = (int)biomeAt;
						if (!dictionary.ContainsKey(key))
						{
							dictionary[key] = 0f;
						}
						dictionary[key]++;
						num5++;
					}
				}
			}
			if (num5 > 0)
			{
				foreach (int item in new List<int>(dictionary.Keys))
				{
					dictionary[item] = dictionary[item] / (float)num5 * 100f;
				}
			}
			if (num5 == 0)
			{
				Biome biomeAt2 = GetBiomeAt(regionCenter);
				dictionary[(int)biomeAt2] = 100f;
			}
			return dictionary;
		}

		public static bool CellHasMerchant(Vector2i gridPos)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			if (Time.time - _merchantCacheTime > 60f)
			{
				_merchantCache.Clear();
				_merchantCacheTime = Time.time;
			}
			if (_merchantCache.TryGetValue(gridPos, out var value))
			{
				return value;
			}
			bool flag = false;
			Vector3 worldPos = default(Vector3);
			foreach (KeyValuePair<Vector2i, LocationInstance> locationInstance in ZoneSystem.instance.m_locationInstances)
			{
				LocationInstance value2 = locationInstance.Value;
				if (value2.m_location == null)
				{
					continue;
				}
				string text = value2.m_location.m_prefabName?.ToLower() ?? "";
				if (text.Contains("haldor") || text.Contains("hildir"))
				{
					((Vector3)(ref worldPos))..ctor(value2.m_position.x, 0f, value2.m_position.z);
					Vector2i region = VoronoiGrid.Instance.GetRegion(worldPos);
					if (region.x == gridPos.x && region.y == gridPos.y)
					{
						flag = true;
						break;
					}
				}
			}
			_merchantCache[gridPos] = flag;
			return flag;
		}

		public static Biome GetDominantBiome(Dictionary<int, float> composition)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (composition == null || composition.Count == 0)
			{
				return (Biome)1;
			}
			int num = 1;
			float num2 = 0f;
			foreach (KeyValuePair<int, float> item in composition)
			{
				if (item.Value > num2)
				{
					num2 = item.Value;
					num = item.Key;
				}
			}
			return (Biome)num;
		}

		public static bool HasPointOfInterest(Vector2i gridPos)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			Vector3 worldPos = default(Vector3);
			foreach (KeyValuePair<Vector2i, LocationInstance> locationInstance in ZoneSystem.instance.m_locationInstances)
			{
				LocationInstance value = locationInstance.Value;
				if (value.m_location == null)
				{
					continue;
				}
				string prefabName = value.m_location.m_prefabName ?? "";
				if (IsPOILocation(prefabName))
				{
					((Vector3)(ref worldPos))..ctor(value.m_position.x, 0f, value.m_position.z);
					Vector2i region = VoronoiGrid.Instance.GetRegion(worldPos);
					if (region.x == gridPos.x && region.y == gridPos.y)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool IsPOILocation(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			string text = prefabName.ToLower();
			if (text.Contains("altar") || text.Contains("boss"))
			{
				return true;
			}
			if (text.Contains("haldor") || text.Contains("hildir"))
			{
				return true;
			}
			if (text.Contains("infectedmine") || text.Contains("sunkencrypt") || text.Contains("mountaincave") || text.Contains("goblinking"))
			{
				return true;
			}
			return false;
		}

		public static Color GetBiomeColor(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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_002d: Invalid comparison between Unknown and I4
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (1 == 0)
			{
			}
			Color result;
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				case 0:
					goto IL_0070;
				case 1:
					goto IL_00a4;
				case 3:
					goto IL_00be;
				case 2:
					goto IL_0148;
				}
				if ((int)biome != 8)
				{
					if ((int)biome != 16)
					{
						goto IL_0148;
					}
					result = new Color(0.9f, 0.85f, 0.4f);
				}
				else
				{
					result = new Color(0.2f, 0.4f, 0.2f);
				}
			}
			else if ((int)biome <= 64)
			{
				if ((int)biome != 32)
				{
					if ((int)biome != 64)
					{
						goto IL_0148;
					}
					result = new Color(0.7f, 0.9f, 1f);
				}
				else
				{
					result = new Color(0.8f, 0.3f, 0.2f);
				}
			}
			else if ((int)biome != 256)
			{
				if ((int)biome != 512)
				{
					goto IL_0148;
				}
				result = new Color(0.5f, 0.3f, 0.6f);
			}
			else
			{
				result = new Color(0.2f, 0.4f, 0.8f);
			}
			goto IL_0150;
			IL_0148:
			result = Color.gray;
			goto IL_0150;
			IL_00be:
			result = new Color(0.8f, 0.8f, 0.9f);
			goto IL_0150;
			IL_0070:
			result = new Color(0.4f, 0.8f, 0.3f);
			goto IL_0150;
			IL_00a4:
			result = new Color(0.4f, 0.35f, 0.2f);
			goto IL_0150;
			IL_0150:
			if (1 == 0)
			{
			}
			return result;
		}

		public static string GetBiomeName(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (1 == 0)
			{
			}
			string result = (((int)biome == 8) ? "Black Forest" : (((int)biome == 32) ? "Ashlands" : (((int)biome != 64) ? ((object)(Biome)(ref biome)).ToString() : "Deep North")));
			if (1 == 0)
			{
			}
			return result;
		}

		public static float GetBiomeTollMultiplier(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (1 == 0)
			{
			}
			float result;
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				case 0:
					goto IL_0058;
				case 1:
					goto IL_0068;
				case 3:
					goto IL_0070;
				case 2:
					goto IL_00a0;
				}
				if ((int)biome != 8)
				{
					if ((int)biome != 16)
					{
						goto IL_00a0;
					}
					result = 3f;
				}
				else
				{
					result = 1.5f;
				}
			}
			else if ((int)biome <= 64)
			{
				if ((int)biome != 32)
				{
					if ((int)biome != 64)
					{
						goto IL_00a0;
					}
					result = 3f;
				}
				else
				{
					result = 5f;
				}
			}
			else if ((int)biome != 256)
			{
				if ((int)biome != 512)
				{
					goto IL_00a0;
				}
				result = 4f;
			}
			else
			{
				result = 0.5f;
			}
			goto IL_00a8;
			IL_00a0:
			result = 1f;
			goto IL_00a8;
			IL_0070:
			result = 2.5f;
			goto IL_00a8;
			IL_0058:
			result = 1f;
			goto IL_00a8;
			IL_0068:
			result = 2f;
			goto IL_00a8;
			IL_00a8:
			if (1 == 0)
			{
			}
			return result;
		}

		public static List<TerritoryObjective> GetObjectivesForBiome(Biome biome)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			List<TerritoryObjective> list = new List<TerritoryObjective>();
			if ((int)biome <= 8)
			{
				switch (biome - 1)
				{
				case 0:
					goto IL_0056;
				case 1:
					goto IL_00c9;
				case 3:
					goto IL_0103;
				case 2:
					goto IL_01e4;
				}
				if ((int)biome != 8)
				{
					goto IL_01e4;
				}
				list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Greydwarf", "Greydwarfs", 10, forUnlock: true, biome));
				list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Troll", "Trolls", 1, forUnlock: true, biome));
			}
			else if ((int)biome != 16)
			{
				if ((int)biome != 32)
				{
					if ((int)biome != 512)
					{
						goto IL_01e4;
					}
					list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Seeker", "Seekers", 10, forUnlock: true, biome));
					list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Gjall", "Gjalls", 1, forUnlock: true, biome));
				}
				else
				{
					list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Charred_Melee", "Charred Warriors", 15, forUnlock: true, biome));
					list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Morgen", "Morgens", 2, forUnlock: true, biome));
				}
			}
			else
			{
				list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Goblin", "Fulings", 10, forUnlock: true, biome));
				list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Lox", "Loxes", 2, forUnlock: true, biome));
			}
			goto IL_0200;
			IL_0056:
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Boar", "Boars", 5, forUnlock: true, biome));
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Neck", "Necks", 3, forUnlock: true, biome));
			goto IL_0200;
			IL_01e4:
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Greyling", "Greylings", 5, forUnlock: true, biome));
			goto IL_0200;
			IL_0200:
			return list;
			IL_0103:
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Wolf", "Wolves", 5, forUnlock: true, biome));
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Drake", "Drakes", 3, forUnlock: true, biome));
			goto IL_0200;
			IL_00c9:
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Draugr", "Draugrs", 10, forUnlock: true, biome));
			list.Add(new TerritoryObjective(ObjectiveType.KillMonsters, "Blob", "Blobs", 5, forUnlock: true, biome));
			goto IL_0200;
		}
	}
	public static class GridUtils
	{
		public static Vector2i WorldToGrid(Vector3 worldPos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return VoronoiGrid.Instance.GetRegion(worldPos);
		}

		public static Vector2i WorldToVisualGrid(Vector3 worldPos)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			return WorldToGrid(worldPos);
		}

		public static Vector3 GridToWorldCenter(Vector2i grid)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return VoronoiGrid.Instance.GetRegionCenter(grid);
		}

		public static Vector3 GridToWorld(Vector2i grid)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return VoronoiGrid.Instance.GetRegionCenter(grid);
		}

		public static int GridDistance(Vector2i a, Vector2i b)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Vector3 val = GridToWorldCenter(a);
			Vector3 val2 = GridToWorldCenter(b);
			float num = Vector3.Distance(val, val2);
			return Mathf.RoundToInt(num / 100f);
		}

		public static bool IsWithinMapBounds(Vector2i grid)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			float num = LandlordConfig.WorldRadius?.Value ?? 10500f;
			Vector3 val = GridToWorldCenter(grid);
			float num2 = Mathf.Sqrt(val.x * val.x + val.z * val.z);
			return num2 < num;
		}

		public static bool IsInSpawnProtection(Vector2i grid)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (VoronoiGrid.Instance.IsSpawnZone(grid))
			{
				return true;
			}
			float value = LandlordConfig.SpawnProtectionRadius.Value;
			Vector3 val = GridToWorldCenter(grid);
			float num = Mathf.Sqrt(val.x * val.x + val.z * val.z);
			return num <= value;
		}

		public static bool IsInSpawnProtection(Vector3 worldPos)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			float value = LandlordConfig.SpawnProtectionRadius.Value;
			float num = Mathf.Sqrt(worldPos.x * worldPos.x + worldPos.z * worldPos.z);
			return num <= value;
		}

		public static bool GridCellOverlapsSpawnProtection(Vector2i grid)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return IsInSpawnProtection(grid);
		}

		public static int CalculateTollForCell(Vector2i grid)
		{
			//IL_0001: 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_008a: 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)
			if (IsInSpawnProtection(grid))
			{
				return 0;
			}
			Dictionary<int, float> dictionary = BiomeUtils.SampleBiomeComposition(grid);
			float num = 0f;
			foreach (KeyValuePair<int, float> item in dictionary)
			{
				int biomeToll = LandlordConfig.GetBiomeToll((Biome)item.Key);
				num += (float)biomeToll * (item.Value / 100f);
			}
			int num2 = Mathf.Max(1, (int)Math.Ceiling(num));
			float approximateRegionRadius = VoronoiGrid.Instance.GetApproximateRegionRadius(grid);
			float num3 = Mathf.Clamp(approximateRegionRadius / 500f, 0.3f, 3f);
			num2 = Mathf.Max(1, (int)((float)num2 * num3));
			if (CellHasMerchant(grid))
			{
				num2 *= 2;
			}
			return num2;
		}

		public static bool CellHasMerchant(Vector2i grid)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return BiomeUtils.CellHasMerchant(grid);
		}

		public static int GetClaimCost(Vector2i grid)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0018: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected I4, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_00ce: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			Dictionary<int, float> composition = BiomeUtils.SampleBiomeComposition(grid);
			Biome dominantBiome = BiomeUtils.GetDominantBiome(composition);
			if (1 == 0)
			{
			}
			int num;
			if ((int)dominantBiome <= 16)
			{
				switch (dominantBiome - 1)
				{
				case 0:
					goto IL_0068;
				case 1:
					goto IL_007a;
				case 3:
					goto IL_0083;
				case 2:
					goto IL_00b9;
				}
				if ((int)dominantBiome != 8)
				{
					if ((int)dominantBiome != 16)
					{
						goto IL_00b9;
					}
					num = 6000;
				}
				else
				{
					num = 3000;
				}
			}
			else if ((int)dominantBiome <= 64)
			{
				if ((int)dominantBiome != 32)
				{
					if ((int)dominantBiome != 64)
					{
						goto IL_00b9;
					}
					num = 10000;
				}
				else
				{
					num = 9000;
				}
			}
			else if ((int)dominantBiome != 256)
			{
				if ((int)dominantBiome != 512)
				{
					goto IL_00b9;
				}
				num = 7000;
			}
			else
			{
				num = 2000;
			}
			goto IL_00c2;
			IL_00b9:
			num = 2000;
			goto IL_00c2;
			IL_0083:
			num = 5000;
			goto IL_00c2;
			IL_0068:
			num = 2000;
			goto IL_00c2;
			IL_007a:
			num = 4000;
			goto IL_00c2;
			IL_00c2:
			if (1 == 0)
			{
			}
			int num2 = num;
			float approximateRegionRadius = VoronoiGrid.Instance.GetApproximateRegionRadius(grid);
			float num3 = 500f;
			float num4 = Mathf.Clamp(approximateRegionRadius / num3, 0.3f, 3f);
			num2 = (int)((float)num2 * num4);
			if (CellHasMerchant(grid))
			{
				num2 *= 2;
			}
			return num2;
		}

		public static string GetBiomeCompositionString(Vector2i grid)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, float> dictionary = BiomeUtils.SampleBiomeComposition(grid);
			if (dictionary == null || dictionary.Count == 0)
			{
				return "Unknown";
			}
			return TerritoryNaming.GetBiomeCompositionDescription(dictionary);
		}

		public static string GetTerritoryName(Vector2i grid)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, float> biomeComposition = BiomeUtils.SampleBiomeComposition(grid);
			bool hasMerchant = CellHasMerchant(grid);
			bool hasBossAltar = BiomeUtils.HasPointOfInterest(grid);
			return TerritoryNaming.GenerateTerritoryName(grid, biomeComposition, hasMerchant, hasBossAltar);
		}
	}
	public static class TerritoryNaming
	{
		private static readonly string[] NorthPrefixes = new string[5] { "Norðri", "Northern", "Frost", "Winter's", "Boreal" };

		private static readonly string[] SouthPrefixes = new string[5] { "Suðri", "Southern", "Sun's", "Warm", "Golden" };

		private static readonly string[] EastPrefixes = new string[5] { "Austri", "Eastern", "Dawn", "Rising", "Morning" };

		private static readonly string[] WestPrefixes = new string[5] { "Vestri", "Western", "Twilight", "Setting", "Dusk" };

		private static readonly string[] CenterPrefixes = new string[5] { "Miðgarð", "Central", "Heart of", "Ancient", "Old" };

		private static readonly Dictionary<Biome, string[]> BiomeNames = new Dictionary<Biome, string[]>
		{
			{
				(Biome)1,
				new string[8] { "Meadow", "Grassland", "Green Vale", "Peaceful Fields", "Idavoll", "Folkvangr", "Verdant Lea", "Shepherd's Rest" }
			},
			{
				(Biome)8,
				new string[8] { "Dark Woods", "Eerie Forest", "Shadow Grove", "Myrkviðr", "Ironwood", "Troll's Domain", "Whispering Pines", "Draugr's Reach" }
			},
			{
				(Biome)2,
				new string[8] { "Murky Fen", "Poison Marsh", "Dead Man's Bog", "Hel's Mire", "Rotting Wetlands", "Drowned Vale", "Festering Swamp", "Corpse Marsh" }
			},
			{
				(Biome)4,
				new string[8] { "Frost Peak", "Stone Heights", "Jötunheimr", "Eagle's Nest", "Ice Crown", "Thunder Summit", "Goat's Path", "Windswept Ridge" }
			},
			{
				(Biome)16,
				new string[8] { "Golden Plains", "Fuling Lands", "Scorched Fields", "Barren Reach", "Vigriðr", "Blood Prairie", "Deathstalker's Domain", "Sun-bleached Expanse" }
			},
			{
				(Biome)512,
				new string[8] { "Shrouded Vale", "Spider's Web", "Mist Hollow", "Gjöll", "Veiled Ruins", "Ancient's Rest", "Forgotten Realm", "Skuld's Domain" }
			},
			{
				(Biome)32,
				new string[8] { "Scorched Waste", "Múspellheim", "Ember Fields", "Burning Reach", "Cinder Vale", "Charred Domain", "Flame's Edge", "Surt's Realm" }
			},
			{
				(Biome)64,
				new string[8] { "Frozen Waste", "Niflheim", "Eternal Ice", "Frost Giant's Land", "Glacial Expanse", "Winter's End", "Permafrost Domain", "Hrimfaxi's Path" }
			},
			{
				(Biome)256,
				new string[8] { "Ægir's Domain", "Depths", "Serpent's Sea", "Njord's Waters", "Kraken's Reach", "Wayward Waves", "Storm Channel", "Ran's Grasp" }
			}
		};

		private static readonly string[] MixedSuffixes = new string[6] { "Borderlands", "Frontier", "Crossroads", "Threshold", "Edge", "Marches" };

		private static readonly string[] MerchantModifiers = new string[4] { "Market", "Trade Post", "Merchant's Haven", "Trader's Rest" };

		private static readonly string[] BossModifiers = new string[4] { "Altar", "Sacred Ground", "Ritual Site", "Offering Place" };

		public static string GenerateTerritoryName(Vector2i gridPos, Dictionary<int, float> biomeComposition, bool hasMerchant = false, bool hasBossAltar = false)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (biomeComposition == null || biomeComposition.Count == 0)
			{
				return $"Unknown Land ({gridPos.x}, {gridPos.y})";
			}
			int seed = gridPos.x * 10000 + gridPos.y;
			Random random = new Random(seed);
			Biome dominantBiome = GetDominantBiome(biomeComposition);
			float biomePercent = GetBiomePercent(biomeComposition, dominantBiome);
			string directionalPrefix = GetDirectionalPrefix(gridPos, random);
			string text = GetBiomeName(dominantBiome, random);
			if (biomePercent < 70f && biomeComposition.Count > 1)
			{
				Biome secondaryBiome = GetSecondaryBiome(biomeComposition, dominantBiome);
				if (secondaryBiome != dominantBiome)
				{
					string text2 = MixedSuffixes[random.Next(MixedSuffixes.Length)];
					text = GetShortBiomeName(dominantBiome) + "-" + GetShortBiomeName(secondaryBiome) + " " + text2;
				}
			}
			if (hasMerchant)
			{
				string text3 = MerchantModifiers[random.Next(MerchantModifiers.Length)];
				return directionalPrefix + " " + text3;
			}
			if (hasBossAltar)
			{
				string text4 = BossModifiers[random.Next(BossModifiers.Length)];
				return text + " " + text4;
			}
			return directionalPrefix + " " + text;
		}

		public static string GetSimpleName(Vector2i gridPos, Dictionary<int, float> biomeComposition)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			if (biomeComposition == null || biomeComposition.Count == 0)
			{
				return "Unknown";
			}
			int seed = gridPos.x * 10000 + gridPos.y;
			Random rng = new Random(seed);
			Biome dominantBiome = GetDominantBiome(biomeComposition);
			return GetBiomeName(dominantBiome, rng);
		}

		private static string GetDirectionalPrefix(Vector2i gridPos, Random rng)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Vector3 regionCenter = VoronoiGrid.Instance.GetRegionCenter(gridPos);
			float x = regionCenter.x;
			float z = regionCenter.z;
			float num = Mathf.Sqrt(x * x + z * z);
			if (num < 2000f)
			{
				return CenterPrefixes[rng.Next(CenterPrefixes.Length)];
			}
			float num2 = Mathf.Atan2(z, x) * 57.29578f;
			if (num2 >= 45f && num2 < 135f)
			{
				return NorthPrefixes[rng.Next(NorthPrefixes.Length)];
			}
			if (num2 >= -45f && num2 < 45f)
			{
				return EastPrefixes[rng.Next(EastPrefixes.Length)];
			}
			if (num2 >= -135f && num2 < -45f)
			{
				return SouthPrefixes[rng.Next(SouthPrefixes.Length)];
			}
			return WestPrefixes[rng.Next(WestPrefixes.Length)];
		}

		private static string GetBiomeName(Biome biome, Random rng)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (BiomeNames.TryGetValue(biome, out var value))
			{
				return value[rng.Next(value.Length)];
			}
			return ((object)(Biome)(ref biome)).ToString();
		}

		private static string GetShortBiomeName(Biome biome)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected I4, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (1 == 0)
			{
			}
			string result;
			if ((int)biome <= 16)
			{
				switch (biome - 1)
				{
				case 0:
					goto IL_0058;
				case 1:
					goto IL_0068;
				case 3:
					goto IL_0070;
				case 2:
					goto IL_00a0;
				}
				if ((int)biome != 8)
				{
					if ((int)biome != 16)
					{
						goto IL_00a0;
					}
					result = "Plains";
				}
				else
				{
					result = "Forest";
				}
			}
			else if ((int)biome <= 64)
			{
				if ((int)biome != 32)
				{
					if ((int)biome != 64)
					{
						goto IL_00a0;
					}
					result = "Frost";
				}
				else
				{
					result = "Ash";
				}
			}
			else if ((int)biome != 256)
			{
				if ((int)biome != 512)
				{
					goto IL_00a0;
				}
				result = "Mist";
			}
			else
			{
				result = "Sea";
			}
			goto IL_00b0;
			IL_00a0:
			result = ((object)(Biome)(ref biome)).ToString();
			goto IL_00b0;
			IL_0070:
			result = "Mountain";
			goto IL_00b0;
			IL_0058:
			result = "Meadow";
			goto IL_00b0;
			IL_0068:
			result = "Swamp";
			goto IL_00b0;
			IL_00b0:
			if (1 == 0)
			{
			}
			return result;
		}

		private static Biome GetDominantBiome(Dictionary<int, float> composition)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			int num = 1;
			float num2 = 0f;
			foreach (KeyValuePair<int, float> item in composition)
			{
				if (item.Value > num2)
				{
					num2 = item.Value;
					num = item.Key;
				}
			}
			return (Biome)num;
		}

		private static Biome GetSecondaryBiome(Dictionary<int, float> composition, Biome exclude)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Expected I4, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between I4 and Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			int num = (int)exclude;
			float num2 = 0f;
			foreach (KeyValuePair<int, float> item in composition)
			{
				if (item.Key != (int)exclude && item.Value > num2)
				{
					num2 = item.Value;
					num = item.Key;
				}
			}
			return (Biome)num;
		}

		private static float GetBiomePercent(Dictionary<int, float> composition, Biome biome)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected I4, but got Unknown
			float value;
			return composition.TryGetValue((int)biome, out value) ? value : 0f;
		}

		public static string GetBiomeCompositionDescription(Dictionary<int, float> composition)
		{
			if (composition == null || composition.Count == 0)
			{
				return "Unknown terrain";
			}
			List<string> list = new List<string>();
			List<KeyValuePair<int, float>> list2 = new List<KeyValuePair<int, float>>(composition);
			list2.Sort((KeyValuePair<int, float> a, KeyValuePair<int, float> b) => b.Value.CompareTo(a.Value));
			foreach (KeyValuePair<int, float> item in list2)
			{
				if (item.Value >= 5f)
				{
					string biomeName = BiomeUtils.GetBiomeName((Biome)item.Key);
					list.Add($"{biomeName} {item.Value:F0}%");
				}
			}
			return string.Join(", ", list);
		}
	}
	public static class Utils
	{
		public static string GetSaveDataPath()
		{
			return Application.persistentDataPath;
		}

		public static string GetPrefabName(GameObject obj)
		{
			if ((Object)(object)obj == (Object)null)
			{
				return "";
			}
			string text = ((Object)obj).name;
			int num = text.IndexOf("(Clone)");
			if (num > 0)
			{
				text = text.Substring(0, num);
			}
			return text.Trim();
		}

		public static string FormatNumber(int number)
		{
			if (number >= 1000000)
			{
				return $"{(float)number / 1000000f:F1}M";
			}
			if (number >= 1000)
			{
				return $"{(float)number / 1000f:F1}K";
			}
			return number.ToString();
		}

		public static string FormatCoins(int amount)
		{
			return $"{amount} coins";
		}

		public static bool IsDedicatedServer()
		{
			ZNet instance = ZNet.instance;
			return instance != null && instance.IsDedicated();
		}

		public static bool IsServer()
		{
			ZNet instance = ZNet.instance;
			return instance != null && instance.IsServer();
		}

		public static long GetLocalPlayerId()
		{
			Player localPlayer = Player.m_localPlayer;
			return (localPlayer != null) ? localPlayer.GetPlayerID() : 0;
		}

		public static string GetLocalPlayerName()
		{
			Player localPlayer = Player.m_localPlayer;
			return ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Unknown";
		}

		public static int ParseInt(string value, int defaultValue = 0)
		{
			int result;
			return int.TryParse(value, out result) ? result : defaultValue;
		}

		public static Color LerpColor(Color a, Color b, float t)
		{
			//IL_0001: 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_0013: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			return new Color(Mathf.Lerp(a.r, b.r, t), Mathf.Lerp(a.g, b.g, t), Mathf.Lerp(a.b, b.b, t), Mathf.Lerp(a.a, b.a, t));
		}
	}
	public class VoronoiGrid
	{
		private static VoronoiGrid _instance;

		private static readonly object _lock = new object();

		private List<Vector2> _seeds;

		private Dictionary<long, int> _quantizedToIndex;

		private Dictionary<long, List<int>> _spatialGrid;

		private const float SpatialCellSize = 2000f;

		private Dictionary<long, Vector2i> _regionCache;

		private const float CacheQuantize = 8f;

		private float MapRadius = 10500f;

		private float _spawnProtectionRadius;

		public static VoronoiGrid Instance
		{
			get
			{
				if (_instance == null)
				{
					lock (_lock)
					{
						if (_instance == null)
						{
							_instance = new VoronoiGrid();
						}
					}
				}
				return _instance;
			}
		}

		public bool IsInitialized { get; private set; }

		public int SpawnZoneSeedIndex => 0;

		public int RegionCount
		{
			get
			{
				EnsureInitialized();
				return _seeds.Count;
			}
		}

		public static void Reset()
		{
			lock (_lock)
			{
				_instance = null;
			}
		}

		private VoronoiGrid()
		{
			_seeds = new List<Vector2>();
			_quantizedToIndex = new Dictionary<long, int>();
			_spatialGrid = new Dictionary<long, List<int>>();
			_regionCache = new Dictionary<long, Vector2i>();
			IsInitialized = false;
		}

		public void Initialize(string worldName)
		{
			if (!IsInitialized)
			{
				_spawnProtectionRadius = LandlordConfig.SpawnProtectionRadius.Value;
				MapRadius = LandlordConfig.WorldRadius?.Value ?? 10500f;
				int num = LandlordConfig.TerritoryCount?.Value ?? 180;
				int num2 = worldName?.GetHashCode() ?? 0;
				Plugin.Log.LogWarning((object)$"VoronoiGrid: MapRadius={MapRadius}, TerritoryCount={num}, SpawnProtection={_spawnProtectionRadius}, WorldSeed={num2}");
				GenerateSeeds(num2, num);
				BuildSpatialGrid();
				BuildQuantizedIndex();
				IsInitialized = true;
				Plugin.Log.LogWarning((object)$"VoronoiGrid initialized with {_seeds.Count} regions for world '{worldName}' (radius={MapRadius})");
			}
		}

		public void EnsureInitialized()
		{
			if (!IsInitialized)
			{
				string text = null;
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					text = ZNet.instance.GetWorldName();
				}
				if (string.IsNullOrEmpty(text))
				{
					text = "default_world";
				}
				Initialize(text);
			}
		}

		private void GenerateSeeds(int worldSeed, int targetCount)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			_seeds.Clear();
			Random random = new Random(worldSeed);
			_seeds.Add(new Vector2(0f, 0f));
			float num = MapRadius * 2f / Mathf.Sqrt((float)targetCount) * 0.6f;
			int num2 = targetCount * 80;
			int num3 = 0;
			while (_seeds.Count < targetCount && num3 < num2)
			{
				num3++;
				float num4 = (float)(random.NextDouble() * 2.0 * Math.PI);
				float num5 = (float)Math.Sqrt(random.NextDouble()) * (MapRadius - 200f);
				float num6 = num5 * Mathf.Cos(num4);
				float num7 = num5 * Mathf.Sin(num4);
				if (num6 * num6 + num7 * num7 < _spawnProtectionRadius * _spawnProtectionRadius)
				{
					continue;
				}
				float num8 = Mathf.Sqrt(num6 * num6 + num7 * num7);
				float num9 = num8 / MapRadius;
				float num10 = 0.3f + num9 * 1.5f;
				float num11 = 0.7f + (float)random.NextDouble() * 0.6f;
				float num12 = num10 * num11;
				float num13 = num * num12;
				bool flag = false;
				for (int i = 0; i < _seeds.Count; i++)
				{
					float num14 = _seeds[i].x - num6;
					float num15 = _seeds[i].y - num7;
					if (num14 * num14 + num15 * num15 < num13 * num13)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					_seeds.Add(new Vector2(num6, num7));
				}
			}
			float num16 = num * 0.4f;
			float[] array = new float[3]
			{
				MapRadius * 0.7f,
				MapRadius * 0.82f,
				MapRadius * 0.93f
			};
			int num17 = 45;
			for (int j = 0; j < array.Length; j++)
			{
				float num18 = array[j];
				float num19 = (float)j * 0.5f;
				for (int k = 0; k < num17; k++)
				{
					float num20 = ((float)k + num19) / (float)num17 * (float)Math.PI * 2f;
					float num21 = num18 * Mathf.Cos(num20);
					float num22 = num18 * Mathf.Sin(num20);
					bool flag2 = false;
					for (int l = 0; l < _seeds.Count; l++)
					{
						float num23 = _seeds[l].x - num21;
						float num24 = _seeds[l].y - num22;
						if (num23 * num23 + num24 * num24 < num16 * num16)
						{
							flag2 = true;
							break;
						}
					}
					if (!flag2)
					{
						_seeds.Add(new Vector2(num21, num22));
					}
				}
			}
			for (int m = 0; m < 3; m++)
			{
				LloydRelaxation();
			}
			Plugin.Log.LogInfo((object)$"Generated {_seeds.Count} Voronoi seeds (target: {targetCount}, attempts: {num3})");
		}

		private void LloydRelaxation()
		{
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			int num = 80;
			float num2 = MapRadius * 2f / (float)num;
			float[] array = new float[_seeds.Count];
			float[] array2 = new float[_seeds.Count];
			int[] array3 = new int[_seeds.Count];
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num3 = 0f - MapRadius + ((float)i + 0.5f) * num2;
					float num4 = 0f - MapRadius + ((float)j + 0.5f) * num2;
					if (!(num3 * num3 + num4 * num4 > MapRadius * MapRadius))
					{
						int num5 = FindNearestSeedBruteForce(num3, num4);
						if (num5 >= 0)
						{
							array[num5] += num3;
							array2[num5] += num4;
							array3[num5]++;
						}
					}
				}
			}
			for (int k = 0; k < _seeds.Count; k++)
			{
				if (k != SpawnZoneSeedIndex && array3[k] > 0)
				{
					float num6 = array[k] / (float)array3[k];
					float num7 = array2[k] / (float)array3[k];
					if (num6 * num6 + num7 * num7 >= _spawnProtectionRadius * _spawnProtectionRadius && num6 * num6 + num7 * num7 < MapRadius * MapRadius)
					{
						_seeds[k] = new Vector2(num6, num7);
					}
				}
			}
		}

		private float SmoothNoise(float x, float z, int seed)
		{
			int num = Mathf.FloorToInt(x);
			int num2 = Mathf.FloorToInt(z);
			float num3 = x - (float)num;
			float num4 = z - (float)num2;
			num3 = num3 * num3 * (3f - 2f * num3);
			num4 = num4 * num4 * (3f - 2f * num4);
			float num5 = HashFloat(num, num2, seed);
			float num6 = HashFloat(num + 1, num2, seed);
			float num7 = HashFloat(num, num2 + 1, seed);
			float num8 = HashFloat(num + 1, num2 + 1, seed);
			float num9 = num5 + (num6 - num5) * num3;
			float num10 = num7 + (num8 - num7) * num3;
			return num9 + (num10 - num9) * num4;
		}

		private float HashFloat(int x, int z, int seed)
		{
			int num = x * 374761393 + z * 668265263 + seed * 1274126177;
			num = (num ^ (num >> 13)) * 1103515245;
			num ^= num >> 16;
			return (float)(num & 0x7FFFFFFF) / 2.1474836E+09f;
		}

		private float PerturbedDistanceSq(float x, float z, int seedIndex)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			float num = _seeds[seedIndex].x - x;
			float num2 = _seeds[seedIndex].y - z;
			float num3 = Mathf.Sqrt(num * num + num2 * num2);
			float num4 = (float)seedIndex * 73.7f;
			float num5 = (float)seedIndex * 91.3f;
			float num6 = 0f;
			num6 += (Mathf.PerlinNoise((x + num4) * 0.006f, (z + num5) * 0.006f) - 0.5f) * 2f;
			num6 += (Mathf.PerlinNoise((x + num4) * 0.015f, (z + num5) * 0.015f) - 0.5f) * 1f;
			num6 += (Mathf.PerlinNoise((x + num4) * 0.03f, (z + num5) * 0.03f) - 0.5f) * 0.5f;
			num6 += (Mathf.PerlinNoise((x + num4) * 0.06f, (z + num5) * 0.06f) - 0.5f) * 0.25f;
			float num7 = num3 + num6 * 80f;
			return num7 * num7;
		}

		private int FindNearestSeedBruteForce(float x, float z)
		{
			int result = -1;
			float num = float.MaxValue;
			for (int i = 0; i < _seeds.Count; i++)
			{
				float num2 = PerturbedDistanceSq(x, z, i);
				if (num2 < num)
				{
					num = num2;
					result = i;
				}
			}
			return result;
		}

		private void BuildSpatialGrid()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			_spatialGrid.Clear();
			for (int i = 0; i < _seeds.Count; i++)
			{
				long key = SpatialKey(_seeds[i].x, _seeds[i].y);
				if (!_spatialGrid.TryGetValue(key, out var value))
				{
					value = new List<int>();
					_spatialGrid[key] = value;
				}
				value.Add(i);
			}
		}

		private long SpatialKey(float x, float z)
		{
			int num = Mathf.FloorToInt(x / 2000f);
			int num2 = Mathf.FloorToInt(z / 2000f);
			return ((long)num << 32) | (uint)num2;
		}

		private void BuildQuantizedIndex()
		{
			//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_001a: 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)
			_quantizedToIndex.Clear();
			for (int i = 0; i < _seeds.Count; i++)
			{
				Vector2i val = QuantizeSeed(i);
				long key = ((long)val.x << 32) | (uint)val.y;
				_quantizedToIndex[key] = i;
			}
		}

		private Vector2i QuantizeSeed(int index)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = _seeds[index];
			int num = Mathf.RoundToInt(val.x / 10f);
			int num2 = Mathf.RoundToInt(val.y / 10f);
			return new Vector2i(num, num2);
		}

		public Vector2i GetRegion(Vector3 worldPos)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			EnsureInitialized();
			long key = CacheKey(worldPos.x, worldPos.z);
			if (_regionCache.TryGetValue(key, out var value))
			{
				return value;
			}
			int index = FindNearestSeed(worldPos.x, worldPos.z);
			Vector2i val = QuantizeSeed(index);
			if (_regionCache.Count > 500000)
			{
				_regionCache.Clear();
			}
			_regionCache[key] = val;
			return val;
		}

		public Vector3 GetRegionCenter(Vector2i regionId)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			EnsureInitialized();
			int num = RegionIdToIndex(regionId);
			if (num >= 0 && num < _seeds.Count)
			{
				Vector2 val = _seeds[num];
				return new Vector3(val.x, 0f, val.y);
			}
			return new Vector3((float)regionId.x * 10f, 0f, (float)regionId.y * 10f);
		}

		public bool IsSpawnZone(Vector2i regionId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			int num = RegionIdToIndex(regionId);
			return num == SpawnZoneSeedIndex;
		}

		public string GetRegionKey(Vector2i regionId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return $"{regionId.x}_{regionId.y}";
		}

		public bool IsOnBorder(Vector3 worldPos, float threshold = 80f)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			EnsureInitialized();
			float x = worldPos.x;
			float z = worldPos.z;
			int num = -1;
			int num2 = -1;
			float num3 = float.MaxValue;
			float num4 = float.MaxValue;
			int num5 = Mathf.FloorToInt(x / 2000f);
			int num6 = Mathf.FloorToInt(z / 2000f);
			for (int i = -1; i <= 1; i++)
			{
				for (int j = -1; j <= 1; j++)
				{
					long key = ((long)(num5 + i) << 32) | (uint)(num6 + j);
					if (!_spatialGrid.TryGetValue(key, out var value))
					{
						continue;
					}
					for (int k = 0; k < value.Count; k++)
					{
						int num7 = value[k];
						float num8 = _seeds[num7].x - x;
						float num9 = _seeds[num7].y - z;
						float num10 = num8 * num8 + num9 * num9;
						if (num10 < num3)
						{
							num4 = num3;
							num2 = num;
							num3 = num10;
							num = num7;
						}
						else if (num10 < num4)
						{
							num4 = num10;
							num2 = num7;
						}
					}
				}
			}
			if (num < 0 || num2 < 0)
			{
				return false;
			}
			float num11 = Mathf.Sqrt(num3);
			float num12 = Mathf.Sqrt(num4);
			return num12 - num11 < threshold;
		}

		public float GetApproximateRegionRadius(Vector2i regionId)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			EnsureInitialized();
			int num = RegionIdToIndex(regionId);
			if (num < 0)
			{
				return 500f;
			}
			Vector2 val = _seeds[num];
			float num2 = float.MaxValue;
			for (int i = 0; i < _seeds.Count; i++)
			{
				if (i != num)
				{
					float num3 = _seeds[i].x - val.x;
					float num4 = _seeds[i].y - val.y;
					float num5 = num3 * num3 + num4 * num4;
					if (num5 < num2)
					{
						num2 = num5;
					}
				}
			}
			return Mathf.Sqrt(num2) * 0.5f;
		}

		public IReadOnlyList<Vector2> GetAllSeeds()
		{
			EnsureInitialized();
			return _seeds;
		}

		public int RegionIdToIndex(Vector2i regionId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			long key = ((long)regionId.x << 32) | (uint)regionId.y;
			if (_quantizedToIndex.TryGetValue(key, out var value))
			{
				return value;
			}
			return -1;
		}

		public Vector2i IndexToRegionId(int index)
		{
			//IL_0029: 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_001f: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			if (index < 0 || index >= _seeds.Count)
			{
				return new Vector2i(0, 0);
			}
			return QuantizeSeed(index);
		}

		private int FindNearestSeed(float x, float z)
		{
			int num = -1;
			float num2 = float.MaxValue;
			int num3 = Mathf.FloorToInt(x / 2000f);
			int num4 = Mathf.FloorToInt(z / 2000f);
			for (int i = -2; i <= 2; i++)
			{
				for (int j = -2; j <= 2; j++)
				{
					long key = ((long)(num3 + i) << 32) | (uint)(num4 + j);
					if (!_spatialGrid.TryGetValue(key, out var value))
					{
						continue;
					}
					for (int k = 0; k < value.Count; k++)
					{
						int num5 = value[k];
						float num6 = PerturbedDistanceSq(x, z, num5);
						if (num6 < num2)
						{
							num2 = num6;
							num = num5;
						}
					}
				}
			}
			if (num < 0)
			{
				num = FindNearestSeedBruteForce(x, z);
			}
			return num;
		}

		private long CacheKey(float x, float z)
		{
			int num = Mathf.FloorToInt(x / 8f);
			int num2 = Mathf.FloorToInt(z / 8f);
			return ((long)num << 32) | (uint)num2;
		}
	}
}
namespace FreyjaLandlord.UI
{
	public class LandlordHUD : MonoBehaviour
	{
		private bool _isVisible = false;

		private int _currentTab = 0;

		private readonly string[] _tabNames = new string[7] { "Overview", "Your Land", "Leaderboard", "Vassals", "Auctions", "Raid Log", "?" };

		private Vector2 _scrollPos = Vector2.zero;

		private Dictionary<string, string> _renameInputs = new Dictionary<string, string>();

		private string _renamingTerritoryKey = null;

		private bool _isRaiding = false;

		private float _raidTimer = 0f;

		private float _raidDuration = 0f;

		private int _raidKeyType = -1;

		private Vector2i _raidTerritory;

		private List<VaultItem> _raidResults = null;

		private bool _raidSuccess = false;

		private string _raidSuccessMessage = null;

		private int _raidSelectedKey = -1;

		private GameObject _raidVfxInstance = null;

		private Vector2 _raidResultsScroll = Vector2.zero;

		private float _raidNotifyTimer = 0f;

		private Vector2 _raidLogScroll = Vector2.zero;

		private int _raidFlickerIndex = -1;

		private float _raidFlickerTimer = 0f;

		private static int _highlightVaultIndex = -1;

		private bool _showRaidWindow = false;

		private Territory _raidTargetTerritory = null;

		private Rect _raidWindowRect = new Rect(100f, 100f, 450f, 500f);

		private int _raidWindowId;

		private static readonly string[] KeyNames = new string[3] { "Bronze", "Silver", "Gold" };

		private static readonly Color[] KeyColors = (Color[])(object)new Color[3]
		{
			new Color(0.8f, 0.5f, 0.2f),
			new Color(0.75f, 0.75f, 0.8f),
			new Color(1f, 0.85f, 0.4f)
		};

		private GUIStyle _windowStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _tabStyle;

		private GUIStyle _tabActiveStyle;

		private GUIStyle _labelStyle;

		private GUIStyle _labelGoldStyle;

		private GUIStyle _labelGreenStyle;

		private GUIStyle _labelRedStyle;

		private GUIStyle _buttonStyle;

		private GUIStyle _boxStyle;

		private GUIStyle _scrollStyle;

		private Texture2D _pixelTex;

		private Texture2D _panelBg;

		private bool _stylesInit = false;

		private Font _valheimFont;

		private bool _fontLoaded = false;

		private Rect _windowRect;

		private int _windowId;

		private VaultItem _vaultHoverItem = null;

		private Vector2 _vaultHoverPos;

		private bool _rentTooltipActive = false;

		private Vector2 _rentTooltipPos;

		private Dictionary<string, Sprite> _spriteCache = new Dictionary<string, Sprite>();

		private bool _spriteCacheBuilt = false;

		public static LandlordHUD Instance { get; private set; }

		public bool IsVisible => _isVisible;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			_windowId = ((Object)this).GetInstanceID();
			_raidWindowId = _windowId + 1;
		}

		private void Start()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			_windowRect = new Rect((float)((Screen.width - 800) / 2), (float)(Screen.height - 470), 800f, 450f);
			LoadValheimFont();
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(LandlordConfig.HUDToggleKey.Value))
			{
				_isVisible = !_isVisible;
				if (_isVisible)
				{
					((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
					((Rect)(ref _windowRect)).y = (float)Screen.height - ((Rect)(ref _windowRect)).height - 20f;
				}
			}
			if (Input.GetKeyDown((KeyCode)27))
			{
				if (_showRaidWindow && !_isRaiding)
				{
					_showRaidWindow = false;
					_isVisible = true;
				}
				else if (_isRaiding)
				{
					_isRaiding = false;
					_raidTimer = 0f;
					_raidKeyType = -1;
					_raidSelectedKey = -1;
					_showRaidWindow = false;
					_isVisible = true;
					if ((Object)(object)_raidVfxInstance != (Object)null)
					{
						Object.Destroy((Object)(object)_raidVfxInstance);
						_raidVfxInstance = null;
					}
					MessageHud instance = MessageHud.instance;
					if (instance != null)
					{
						instance.ShowMessage((MessageType)1, "<color=#ff6666>Raid cancelled! Key wasted.</color>", 0, (Sprite)null, false);
					}
				}
				else if (_isVisible)
				{
					_isVisible = false;
				}
			}
			if (_showRaidWindow && _raidTargetTerritory != null && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				Vector2i val = GridUtils.WorldToVisualGrid(((Component)Player.m_localPlayer).transform.position);
				if ((val.x != _raidTargetTerritory.GridX || val.y != _raidTargetTerritory.GridY) && !_isRaiding)
				{
					_showRaidWindow = false;
					_raidTargetTerritory = null;
				}
			}
			if (_isRaiding)
			{
				_raidTimer -= Time.deltaTime;
				_raidNotifyTimer -= Time.deltaTime;
				_raidFlickerTimer -= Time.deltaTime;
				if (_raidFlickerTimer <= 0f)
				{
					_raidFlickerTimer = 0.15f;
					int valueOrDefault = ((TerritoryManager.Instance?.Data?.GetTerritory(_raidTerritory))?.Vault?.Count).GetValueOrDefault();
					_raidFlickerIndex = ((valueOrDefault > 0) ? Random.Range(0, valueOrDefault) : (-1));
				}
				if (_raidNotifyTimer <= 0f)
				{
					_raidNotifyTimer = 10f;
					Player localPlayer = Player.m_localPlayer;
					string arg = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "Someone";
					string arg2 = (TerritoryManager.Instance?.Data?.GetTerritory(_raidTerritory))?.OwnerName ?? "Unknown";
					string message = $"<color=#ff0000>{arg} is raiding {arg2}'s Vault! ({Mathf.CeilToInt(_raidTimer)}s remaining)</color>";
					LandlordRPC.Instance?.BroadcastGlobalMessage(message);
				}
				if ((Object)(object)_raidVfxInstance == (Object)null && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					try
					{
						ZNetScene instance2 = ZNetScene.instance;
						object obj = ((instance2 != null) ? instance2.GetPrefab("vfx_Potion_health_medium") : null);
						if (obj == null)
						{
							ZNetScene instance3 = ZNetScene.instance;
							obj = ((instance3 != null) ? instance3.GetPrefab("vfx_FireAddFuel") : null);
						}
						GameObject val2 = (GameObject)obj;
						if ((Object)(object)val2 != (Object)null)
						{
							_raidVfxInstance = Object.Instantiate<GameObject>(val2, ((Component)Player.m_localPlayer).transform.position, Quaternion.identity, ((Component)Player.m_localPlayer).transform);
						}
					}
					catch
					{
					}
				}
				if (_raidTimer <= 0f)
				{
					ProcessRaidResult();
				}
			}
			if (_isVisible)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				if (ZInput.instance != null)
				{
					ZInput.ResetButtonStatus("Attack");
					ZInput.ResetButtonStatus("SecondaryAttack");
					ZInput.ResetButtonStatus("Block");
					ZInput.ResetButtonStatus("Use");
					ZInput.ResetButtonStatus("Jump");
				}
			}
		}

		private void LateUpdate()
		{
			if (_isVisible)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void LoadValheimFont()
		{
			try
			{
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				Font[] array2 = array;
				foreach (Font val in array2)
				{
					string text = ((Object)val).name.ToLower();
					if (text.Contains("norse") || text.Contains("averia") || text.Contains("valheim"))
					{
						_valheimFont = val;
						_fontLoaded = true;
						Plugin.Log.LogDebug((object)("Loaded Valheim font: " + ((Object)val).name));
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Could not load Valheim font: " + ex.Message));
			}
		}

		private void InitStyles()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Expected O, but got Unknown
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Expected O, but got Unknown
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Expected O, but got Unknown
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Expected O, but got Unknown
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Expected O, but got Unknown
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Expected O, but got Unknown
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Expected O, but got Unknown
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Expected O, but got Unknown
			//IL_0508: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Expected O, but got Unknown
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Expected O, but got Unknown
			//IL_0599: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Expected O, but got Unknown
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d4: Expected O, but got Unknown
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Expected O, but got Unknown
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Expected O, but got Unknown
			if (!_stylesInit)
			{
				_pixelTex = new Texture2D(1, 1);
				_pixelTex.SetPixel(0, 0, Color.white);
				_pixelTex.Apply();
				_panelBg = CreatePanelTexture(64, 64);
				_windowStyle = new GUIStyle(GUI.skin.window);
				_windowStyle.normal.background = _panelBg;
				_windowStyle.onNormal.background = _panelBg;
				_windowStyle.border = new RectOffset(12, 12, 45, 12);
				_windowStyle.padding = new RectOffset(16, 16, 50, 16);
				_windowStyle.normal.textColor = new Color(1f, 0.85f, 0.4f);
				_windowStyle.fontSize = 20;
				_windowStyle.fontStyle = (FontStyle)1;
				_windowStyle.alignment = (TextAnchor)1;
				if (_fontLoaded)
				{
					_windowStyle.font = _valheimFont;
				}
				_headerStyle = new GUIStyle(GUI.skin.label);
				_headerStyle.fontSize = 16;
				_headerStyle.fontStyle = (FontStyle)1;
				_headerStyle.normal.textColor = new Color(1f, 0.85f, 0.4f);
				_headerStyle.margin = new RectOffset(0, 0, 10, 8);
				if (_fontLoaded)
				{
					_headerStyle.font = _valheimFont;
				}
				_tabStyle = new GUIStyle(GUI.skin.button);
				_tabStyle.normal.background = CreateButtonTexture(32, 32, highlighted: false);
				_tabStyle.hover.background = CreateButtonTexture(32, 32, highlighted: true);
				_tabStyle.active.background = CreateButtonTexture(32, 32, highlighted: true);
				_tabStyle.normal.textColor = new Color(0.85f, 0.8f, 0.65f);
				_tabStyle.hover.textColor = new Color(1f, 0.95f, 0.8f);
				_tabStyle.fontSize = 13;
				_tabStyle.fontStyle = (FontStyle)1;
				_tabStyle.padding = new RectOffset(12, 12, 8, 8);
				_tabStyle.margin = new RectOffset(2, 2, 0, 0);
				if (_fontLoaded)
				{
					_tabStyle.font = _valheimFont;
				}
				_tabActiveStyle = new GUIStyle(_tabStyle);
				_tabActiveStyle.normal.background = CreateButtonTexture(32, 32, highlighted: true);
				_tabActiveStyle.normal.textColor = new Color(1f, 0.9f, 0.5f);
				_labelStyle = new GUIStyle(GUI.skin.label);
				_labelStyle.normal.textColor = new Color(0.9f, 0.88f, 0.8f);
				_labelStyle.fontSize = 14;
				_labelStyle.wordWrap = true;
				_labelStyle.richText = true;
				_labelStyle.margin = new RectOffset(0, 0, 2, 2);
				if (_fontLoaded)
				{
					_labelStyle.font = _valheimFont;
				}
				_labelGoldStyle = new GUIStyle(_labelStyle);
				_labelGoldStyle.normal.textColor = new Color(1f, 0.85f, 0.4f);
				_labelGoldStyle.fontStyle = (FontStyle)1;
				_labelGoldStyle.fontSize = 15;
				_labelGreenStyle = new GUIStyle(_labelStyle);
				_labelGreenStyle.normal.textColor = new Color(0.5f, 0.95f, 0.4f);
				_labelGreenStyle.fontStyle = (FontStyle)1;
				_labelRedStyle = new GUIStyle(_labelStyle);
				_labelRedStyle.normal.textColor = new Color(0.98f, 0.5f, 0.4f);
				_labelRedStyle.fontStyle = (FontStyle)1;
				_buttonStyle = new GUIStyle(GUI.skin.button);
				_buttonStyle.normal.background = CreateButtonTexture(32, 32, highlighted: false);
				_buttonStyle.hover.background = CreateButtonTexture(32, 32, highlighted: true);
				_buttonStyle.active.background = CreateButtonTexture(32, 32, highlighted: true);
				_buttonStyle.normal.textColor = new Color(1f, 0.9f, 0.7f);
				_buttonStyle.hover.textColor = Color.white;
				_buttonStyle.fontSize = 14;
				_buttonStyle.fontStyle = (FontStyle)1;
				_buttonStyle.padding = new RectOffset(14, 14, 8, 8);
				_buttonStyle.margin = new RectOffset(0, 0, 4, 4);
				if (_fontLoaded)
				{
					_buttonStyle.font = _valheimFont;
				}
				_boxStyle = new GUIStyle(GUI.skin.box);
				_boxStyle.normal.background = CreateInsetTexture(32, 32);
				_boxStyle.padding = new RectOffset(10, 10, 8, 8);
				_boxStyle.margin = new RectOffset(0, 0, 4, 4);
				_scrollStyle = new GUIStyle(GUI.skin.scrollView);
				_stylesInit = true;
			}
		}

		private Texture2D CreatePanelTexture(int width, int height)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.08f, 0.06f, 0.04f, 0.96f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.45f, 0.35f, 0.22f, 0.9f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.02f, 0.015f, 0.01f, 1f);
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					Color val5;
					if (j < 3 || j >= width - 3 || i < 3 || i >= height - 3)
					{
						val5 = val4;
					}
					else if (j < 5 || j >= width - 5 || i < 5 || i >= height - 5)
					{
						val5 = val3;
					}
					else
					{
						float num = (float)i / (float)height;
						val5 = Color.Lerp(val2, new Color(val2.r * 1.1f, val2.g * 1.1f, val2.b * 1.1f, val2.a), num * 0.3f);
					}
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply();
			((Texture)val).filterMode = (FilterMode)0;
			return val;
		}

		private Texture2D CreateButtonTexture(int width, int height, bool highlighted)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height);
			Color val2 = (highlighted ? new Color(0.28f, 0.2f, 0.12f, 0.95f) : new Color(0.18f, 0.13f, 0.08f, 0.95f));
			Color val3 = (highlighted ? new Color(0.5f, 0.38f, 0.22f, 1f) : new Color(0.35f, 0.27f, 0.16f, 1f));
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.06f, 0.04f, 0.02f, 1f);
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					Color val5;
					if (i >= height - 2)
					{
						val5 = val3;
					}
					else if (i < 2)
					{
						val5 = val4;
					}
					else if (j < 1 || j >= width - 1)
					{
						val5 = Color.Lerp(val2, val4, 0.4f);
					}
					else
					{
						float num = (float)i / (float)height;
						val5 = Color.Lerp(val2, val3, num * 0.25f);
					}
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply();
			return val;
		}

		private Texture2D CreateInsetTexture(int width, int height)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0086: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(width, height);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.05f, 0.04f, 0.025f, 0.9f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.02f, 0.015f, 0.01f, 0.95f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.12f, 0.09f, 0.05f, 0.9f);
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					Color val5 = ((i < height - 2) ? ((i >= 2) ? val2 : val4) : val3);
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply();
			return val;
		}

		private void OnGUI()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if ((_isVisible || _showRaidWindow) && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				InitStyles();
				Event current = Event.current;
				if (((int)current.type == 4 || (int)current.type == 5) && (int)current.keyCode != 27 && current.keyCode != LandlordConfig.HUDToggleKey.Value)
				{
					current.Use();
				}
				if ((int)current.type == 6)
				{
					current.Use();
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				if (_isVisible)
				{
					_windowRect = GUI.Window(_windowId, _windowRect, new WindowFunction(DrawWindow), "", _windowStyle);
				}
				if (_showRaidWindow && _raidTargetTerritory != null)
				{
					_raidWindowRect = GUILayout.Window(_raidWindowId, _raidWindowRect, new WindowFunction(DrawRaidWindow), "Vault Raid", _windowStyle, Array.Empty<GUILayoutOption>());
				}
			}
		}

		private void DrawWindow(int id)
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			DrawTitleBar();
			GUILayout.Space(48f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			for (int i = 0; i < _tabNames.Length; i++)
			{
				GUILayoutOption[] array = (GUILayoutOption[])(object)((!(_tabNames[i] == "?")) ? new GUILayoutOption[1] { GUILayout.Height(32f) } : new GUILayoutOption[2]
				{
					GUILayout.Width(34f),
					GUILayout.Height(32f)
				});
				if (GUILayout.Button(_tabNames[i], (i == _currentTab) ? _tabActiveStyle : _tabStyle, array))
				{
					_currentTab = i;
					_scrollPos = Vector2.zero;
				}
			}
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			DrawSeparator();
			GUILayout.Space(6f);
			_scrollPos = GUILayout.BeginScrollView(_scrollPos, _scrollStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			switch (_currentTab)
			{
			case 0:
				DrawOverview();
				break;
			case 1:
				DrawYourLand();
				break;
			case 2:
				DrawLeaderboard();
				break;
			case 3:
				DrawVassals();
				break;
			case 4:
				DrawAuctions();
				break;
			case 5:
				DrawRaidLog();
				break;
			case 6:
				DrawHelp();
				break;
			}
			GUILayout.EndScrollView();
			DrawRentTooltipIfNeeded();
			DrawVaultTooltipIfNeeded();
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width - 40f, 45f));
		}

		private void DrawTitleBar()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = new Color(0.06f, 0.045f, 0.03f, 0.95f);
			GUI.DrawTexture(new Rect(5f, 5f, ((Rect)(ref _windowRect)).width - 10f, 38f), (Texture)(object)_pixelTex);
			GUI.color = new Color(0.55f, 0.42f, 0.25f, 0.8f);
			GUI.DrawTexture(new Rect(5f, 42f, ((Rect)(ref _windowRect)).width - 10f, 1f), (Texture)(object)_pixelTex);
			GUI.color = Color.white;
			GUIStyle val = new GUIStyle(_headerStyle);
			val.fontSize = 18;
			val.alignment = (TextAnchor)4;
			GUI.Label(new Rect(0f, 8f, ((Rect)(ref _windowRect)).width, 32f), "LAND MANAGEMENT", val);
			if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 38f, 10f, 28f, 26f), "X", _tabStyle))
			{
				_isVisible = false;
			}
		}

		private void DrawSeparator()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUI.color = new Color(0.45f, 0.35f, 0.22f, 0.5f);
			GUI.DrawTexture(rect, (Texture)(object)_pixelTex);
			GUI.color = Color.white;
		}

		private void DrawSectionHeader(string text)
		{
			GUILayout.Space(4f);
			GUILayout.Label(text, _labelGoldStyle, Arr

plugins/VikingMessages.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("VikingMessages")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyDescription("Elden Ring-inspired message system for Valheim")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Viking Messages")]
[assembly: AssemblyTitle("Viking Messages")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VikingMessages
{
	[Serializable]
	public class VikingMessage
	{
		public string Id;

		public Vector3 Position;

		public Quaternion Rotation;

		public string Template;

		public string Words;

		public int EmoteIndex;

		public long AuthorId;

		public string AuthorName;

		public int Reputation;

		public List<long> VotedPlayers = new List<long>();

		public DateTime CreatedTime;

		public string[] EquippedItems = new string[0];

		public Vector3 LookDirection;
	}
	[Serializable]
	public class PlayerReputation
	{
		public long PlayerId;

		public string PlayerName;

		public int TotalReputation;

		public int MessageCount;

		public PlayerReputation()
		{
		}

		public PlayerReputation(long id, string name)
		{
			PlayerId = id;
			PlayerName = name;
			TotalReputation = 0;
			MessageCount = 0;
		}
	}
	[Serializable]
	public class LeaderboardData
	{
		public List<PlayerReputation> Players = new List<PlayerReputation>();
	}
	public class GhostPhantom : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <PlayEmoteDelayed>d__21 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public string emoteName;

			public GhostPhantom <>4__this;

			private string <triggerName>5__1;

			private Exception <ex>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)<>4__this._animator != (Object)null)
					{
						try
						{
							((Behaviour)<>4__this._animator).enabled = true;
							<>4__this._animator.speed = 0.7f;
							<triggerName>5__1 = "emote_" + emoteName.ToLower();
							ManualLogSource log = VikingMessagesPlugin.Log;
							if (log != null)
							{
								log.LogInfo((object)("Attempting to play emote trigger: " + <triggerName>5__1));
							}
							<>4__this._animator.SetTrigger(<triggerName>5__1);
							<triggerName>5__1 = null;
						}
						catch (Exception ex)
						{
							<ex>5__2 = ex;
							ManualLogSource log2 = VikingMessagesPlugin.Log;
							if (log2 != null)
							{
								log2.LogWarning((object)("Failed to play emote " + emoteName + ": " + <ex>5__2.Message));
							}
						}
					}
					else
					{
						ManualLogSource log3 = VikingMessagesPlugin.Log;
						if (log3 != null)
						{
							log3.LogWarning((object)"No animator available for ghost emote");
						}
					}
					return false;
				}
			}

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

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

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

			private object <>2__current;

			public GhostPhantom <>4__this;

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

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

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

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

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if ((Object)(object)Player.m_localPlayer == (Object)null)
					{
						ManualLogSource log = VikingMessagesPlugin.Log;
						if (log != null)
						{
							log.LogWarning((object)"No local player for ghost clone");
						}
						<>4__this.CreateFallbackGhost();
					}
					else
					{
						<>4__this.CreatePlayerClone();
					}
					<>4__this.CreateGlowLight();
					<>4__this.Show();
					return false;
				}
			}

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

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

		private float _displayDuration = 5f;

		private float _currentTimer;

		private float _fadeInTime = 0.5f;

		private bool _isVisible;

		private List<Renderer> _renderers = new List<Renderer>();

		private static readonly Color GhostColor = new Color(0.85f, 0.9f, 1f, 0.7f);

		private GameObject _visualClone;

		private Animator _animator;

		private Light _glowLight;

		private string _pendingEmote;

		private VikingMessage _message;

		public void Initialize(VikingMessage message, float duration = 5f)
		{
			_message = message;
			_displayDuration = duration;
			_pendingEmote = GetEmoteName(message.EmoteIndex);
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"GhostPhantom.Initialize: emote={_pendingEmote}, emoteIndex={message.EmoteIndex}");
			}
		}

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

		[IteratorStateMachine(typeof(<SetupGhostCoroutine>d__13))]
		private IEnumerator SetupGhostCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetupGhostCoroutine>d__13(0)
			{
				<>4__this = this
			};
		}

		private void CreatePlayerClone()
		{
			//IL_007a: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Player localPlayer = Player.m_localPlayer;
				Transform val = ((Component)localPlayer).transform.Find("Visual");
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log = VikingMessagesPlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)"Could not find Visual transform on player");
					}
					CreateFallbackGhost();
					return;
				}
				_visualClone = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)this).transform);
				((Object)_visualClone).name = "GhostVisual";
				_visualClone.transform.localPosition = Vector3.zero;
				_visualClone.transform.localRotation = Quaternion.identity;
				_visualClone.transform.localScale = Vector3.one;
				_animator = _visualClone.GetComponent<Animator>();
				if ((Object)(object)_animator == (Object)null)
				{
					_animator = _visualClone.GetComponentInChildren<Animator>();
				}
				DisableComponents(_visualClone);
				Renderer[] componentsInChildren = _visualClone.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.enabled = true;
						SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
						if (val3 != null)
						{
							val3.updateWhenOffscreen = true;
						}
					}
				}
				Transform[] componentsInChildren2 = _visualClone.GetComponentsInChildren<Transform>(true);
				foreach (Transform val4 in componentsInChildren2)
				{
					if ((Object)(object)val4 != (Object)null && (Object)(object)((Component)val4).gameObject != (Object)null)
					{
						((Component)val4).gameObject.SetActive(true);
					}
				}
				ApplyGhostMaterials(_visualClone);
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"Ghost clone created successfully with {_renderers.Count} renderers");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log3 = VikingMessagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)$"Failed to create player clone: {arg}");
				}
				CreateFallbackGhost();
			}
		}

		private void DisableComponents(GameObject obj)
		{
			MonoBehaviour[] componentsInChildren = obj.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)this)
				{
					((Behaviour)val).enabled = false;
				}
			}
			ZNetView[] componentsInChildren2 = obj.GetComponentsInChildren<ZNetView>(true);
			foreach (ZNetView val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					Object.Destroy((Object)(object)val2);
				}
			}
			ZSyncTransform[] componentsInChildren3 = obj.GetComponentsInChildren<ZSyncTransform>(true);
			foreach (ZSyncTransform val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					Object.Destroy((Object)(object)val3);
				}
			}
			ZSyncAnimation[] componentsInChildren4 = obj.GetComponentsInChildren<ZSyncAnimation>(true);
			foreach (ZSyncAnimation val4 in componentsInChildren4)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					Object.Destroy((Object)(object)val4);
				}
			}
			VisEquipment[] componentsInChildren5 = obj.GetComponentsInChildren<VisEquipment>(true);
			foreach (VisEquipment val5 in componentsInChildren5)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					Object.Destroy((Object)(object)val5);
				}
			}
			Collider[] componentsInChildren6 = obj.GetComponentsInChildren<Collider>(true);
			foreach (Collider val6 in componentsInChildren6)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					val6.enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren7 = obj.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val7 in componentsInChildren7)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					val7.Stop();
				}
			}
			AudioSource[] componentsInChildren8 = obj.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val8 in componentsInChildren8)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					((Behaviour)val8).enabled = false;
				}
			}
		}

		private void ApplyGhostMaterials(GameObject obj)
		{
			_renderers.Clear();
			Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					_renderers.Add(val);
					Material[] array = (Material[])(object)new Material[val.sharedMaterials.Length];
					for (int j = 0; j < val.sharedMaterials.Length; j++)
					{
						Material val2 = CreateGhostMaterial(val.sharedMaterials[j]);
						array[j] = val2;
					}
					val.materials = array;
				}
			}
		}

		private Material CreateGhostMaterial(Material sourceMat)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Sprites/Default");
			}
			Material val2 = new Material(val);
			if ((Object)(object)sourceMat != (Object)null && sourceMat.HasProperty("_MainTex"))
			{
				val2.mainTexture = sourceMat.mainTexture;
			}
			val2.color = GhostColor;
			val2.SetFloat("_Mode", 3f);
			val2.SetInt("_SrcBlend", 5);
			val2.SetInt("_DstBlend", 10);
			val2.SetInt("_ZWrite", 0);
			val2.DisableKeyword("_ALPHATEST_ON");
			val2.EnableKeyword("_ALPHABLEND_ON");
			val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val2.renderQueue = 3000;
			val2.EnableKeyword("_EMISSION");
			val2.SetColor("_EmissionColor", new Color(0.3f, 0.4f, 0.5f));
			return val2;
		}

		private void CreateFallbackGhost()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"Creating fallback ghost (primitive shapes)");
			}
			Material val = CreateGhostMaterial(null);
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)1);
			((Object)val2).name = "GhostBody";
			val2.transform.SetParent(((Component)this).transform);
			val2.transform.localPosition = new Vector3(0f, 1f, 0f);
			val2.transform.localScale = new Vector3(0.5f, 0.7f, 0.35f);
			Object.Destroy((Object)(object)val2.GetComponent<Collider>());
			Renderer component = val2.GetComponent<Renderer>();
			component.material = val;
			_renderers.Add(component);
			GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val3).name = "GhostHead";
			val3.transform.SetParent(((Component)this).transform);
			val3.transform.localPosition = new Vector3(0f, 1.85f, 0f);
			val3.transform.localScale = new Vector3(0.35f, 0.35f, 0.35f);
			Object.Destroy((Object)(object)val3.GetComponent<Collider>());
			Renderer component2 = val3.GetComponent<Renderer>();
			component2.material = Object.Instantiate<Material>(val);
			_renderers.Add(component2);
			GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)1);
			val4.transform.SetParent(((Component)this).transform);
			val4.transform.localPosition = new Vector3(-0.4f, 1.2f, 0f);
			val4.transform.localRotation = Quaternion.Euler(0f, 0f, 30f);
			val4.transform.localScale = new Vector3(0.12f, 0.35f, 0.12f);
			Object.Destroy((Object)(object)val4.GetComponent<Collider>());
			val4.GetComponent<Renderer>().material = Object.Instantiate<Material>(val);
			_renderers.Add(val4.GetComponent<Renderer>());
			GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)1);
			val5.transform.SetParent(((Component)this).transform);
			val5.transform.localPosition = new Vector3(0.4f, 1.2f, 0f);
			val5.transform.localRotation = Quaternion.Euler(0f, 0f, -30f);
			val5.transform.localScale = new Vector3(0.12f, 0.35f, 0.12f);
			Object.Destroy((Object)(object)val5.GetComponent<Collider>());
			val5.GetComponent<Renderer>().material = Object.Instantiate<Material>(val);
			_renderers.Add(val5.GetComponent<Renderer>());
		}

		private void CreateGlowLight()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("GhostLight");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localPosition = new Vector3(0f, 1.2f, 0f);
			_glowLight = val.AddComponent<Light>();
			_glowLight.type = (LightType)2;
			_glowLight.color = new Color(0.7f, 0.8f, 1f);
			_glowLight.intensity = 0.8f;
			_glowLight.range = 3f;
			_glowLight.shadows = (LightShadows)0;
		}

		public void Show()
		{
			((Component)this).gameObject.SetActive(true);
			_isVisible = true;
			_currentTimer = _displayDuration;
			if (!string.IsNullOrEmpty(_pendingEmote))
			{
				((MonoBehaviour)this).StartCoroutine(PlayEmoteDelayed(_pendingEmote));
			}
			UpdateAlpha(0f);
		}

		[IteratorStateMachine(typeof(<PlayEmoteDelayed>d__21))]
		private IEnumerator PlayEmoteDelayed(string emoteName)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PlayEmoteDelayed>d__21(0)
			{
				<>4__this = this,
				emoteName = emoteName
			};
		}

		public void Hide()
		{
			_isVisible = false;
			((Component)this).gameObject.SetActive(false);
			foreach (Renderer renderer in _renderers)
			{
				if (!((Object)(object)renderer != (Object)null))
				{
					continue;
				}
				Material[] materials = renderer.materials;
				foreach (Material val in materials)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)val);
					}
				}
			}
			Object.Destroy((Object)(object)((Component)this).gameObject, 0.1f);
		}

		private void Update()
		{
			if (_isVisible)
			{
				_currentTimer -= Time.deltaTime;
				EnsureRenderersEnabled();
				float num = _displayDuration - _currentTimer;
				float num2 = 2f;
				float alpha = ((num < _fadeInTime) ? (num / _fadeInTime * 0.7f) : ((!(_currentTimer < num2)) ? 0.7f : (_currentTimer / num2 * 0.7f)));
				UpdateAlpha(alpha);
				if ((Object)(object)_glowLight != (Object)null)
				{
					_glowLight.intensity = 0.6f + Mathf.Sin(Time.time * 3f) * 0.2f;
				}
				if (_currentTimer <= 0f)
				{
					Hide();
				}
			}
		}

		private void EnsureRenderersEnabled()
		{
			if ((Object)(object)_visualClone == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = _visualClone.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !val.enabled)
				{
					val.enabled = true;
				}
			}
			Transform[] componentsInChildren2 = _visualClone.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && !((Component)val2).gameObject.activeSelf && ((Object)(object)((Component)val2).GetComponent<Renderer>() != (Object)null || (Object)(object)((Component)val2).GetComponent<SkinnedMeshRenderer>() != (Object)null))
				{
					((Component)val2).gameObject.SetActive(true);
				}
			}
		}

		private void UpdateAlpha(float alpha)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			Color ghostColor = GhostColor;
			ghostColor.a = alpha;
			foreach (Renderer renderer in _renderers)
			{
				if ((Object)(object)renderer == (Object)null)
				{
					continue;
				}
				Material[] materials = renderer.materials;
				foreach (Material val in materials)
				{
					if ((Object)(object)val != (Object)null)
					{
						val.color = ghostColor;
					}
				}
			}
		}

		private string GetEmoteName(int emoteIndex)
		{
			List<string> availableEmotes = MessageTemplates.AvailableEmotes;
			if (availableEmotes != null && emoteIndex >= 0 && emoteIndex < availableEmotes.Count)
			{
				return availableEmotes[emoteIndex];
			}
			return "wave";
		}

		private void OnDestroy()
		{
			foreach (Renderer renderer in _renderers)
			{
				if (!((Object)(object)renderer != (Object)null))
				{
					continue;
				}
				Material[] materials = renderer.materials;
				foreach (Material val in materials)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)val);
					}
				}
			}
			_renderers.Clear();
		}
	}
	public static class GhostPhantomManager
	{
		private static GhostPhantom _currentGhost;

		public static void ShowGhost(Vector3 position, Quaternion rotation, VikingMessage message, float duration = 5f)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_currentGhost != (Object)null)
				{
					_currentGhost.Hide();
					_currentGhost = null;
				}
				GameObject val = new GameObject("VikingMessageGhost");
				val.transform.position = position;
				val.transform.rotation = rotation;
				_currentGhost = val.AddComponent<GhostPhantom>();
				_currentGhost.Initialize(message, duration);
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Ghost spawned at {position} with rotation {((Quaternion)(ref rotation)).eulerAngles}");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Failed to spawn ghost: {arg}");
				}
			}
		}

		public static void HideCurrentGhost()
		{
			if ((Object)(object)_currentGhost != (Object)null)
			{
				_currentGhost.Hide();
				_currentGhost = null;
			}
		}

		public static void Cleanup()
		{
			HideCurrentGhost();
		}
	}
	public static class LeaderboardManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__CloseLeaderboard;
		}

		private static GameObject _leaderboardUI;

		private static bool _isVisible;

		private static bool _hasStealthBuff;

		private static bool _hasCarryBuff;

		public const float CARRY_WEIGHT_BONUS = 500f;

		private static SE_Stats _reputationBuff;

		private const string BUFF_NAME = "SE_ReputationTop3";

		public static bool IsVisible => _isVisible;

		public static void ShowLeaderboard()
		{
			if ((Object)(object)_leaderboardUI != (Object)null)
			{
				CloseLeaderboard();
				return;
			}
			CreateLeaderboardUI();
			_isVisible = true;
			GUIManager.BlockInput(true);
		}

		public static void CloseLeaderboard()
		{
			if ((Object)(object)_leaderboardUI != (Object)null)
			{
				Object.Destroy((Object)(object)_leaderboardUI);
				_leaderboardUI = null;
			}
			_isVisible = false;
			GUIManager.BlockInput(false);
		}

		private static void CreateLeaderboardUI()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance == null)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"GUIManager not ready");
				}
				return;
			}
			try
			{
				_leaderboardUI = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 500f, 550f, false);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("CreateWoodpanel failed: " + ex.Message));
				}
			}
			if ((Object)(object)_leaderboardUI == (Object)null)
			{
				_leaderboardUI = CreateFallbackPanel();
			}
			if ((Object)(object)_leaderboardUI == (Object)null)
			{
				ManualLogSource log3 = VikingMessagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)"Failed to create leaderboard UI");
				}
			}
			else
			{
				PopulateLeaderboardContent();
			}
		}

		private static GameObject CreateFallbackPanel()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00bd: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("VikingMessages_LeaderboardCanvas");
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 100;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			val.AddComponent<GraphicRaycaster>();
			GameObject val4 = new GameObject("Panel");
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = val4.AddComponent<RectTransform>();
			val5.sizeDelta = new Vector2(500f, 550f);
			val5.anchorMin = new Vector2(0.5f, 0.5f);
			val5.anchorMax = new Vector2(0.5f, 0.5f);
			val5.anchoredPosition = Vector2.zero;
			Image val6 = val4.AddComponent<Image>();
			((Graphic)val6).color = new Color(0.18f, 0.12f, 0.08f, 0.97f);
			CreateBorderFrame(val4.transform, new Vector2(500f, 550f));
			return val4;
		}

		private static void CreateBorderFrame(Transform parent, Vector2 size)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00b1: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("OuterBorder");
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.6f, 0.45f, 0.2f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(size.x + 8f, size.y + 8f);
			component.anchoredPosition = Vector2.zero;
			val.transform.SetAsFirstSibling();
			GameObject val3 = new GameObject("InnerBorder");
			val3.transform.SetParent(parent, false);
			Image val4 = val3.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.1f, 0.07f, 0.04f);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(size.x + 4f, size.y + 4f);
			component2.anchoredPosition = Vector2.zero;
			val3.transform.SetSiblingIndex(1);
			GameObject val5 = new GameObject("TopBar");
			val5.transform.SetParent(parent, false);
			Image val6 = val5.AddComponent<Image>();
			((Graphic)val6).color = new Color(0.5f, 0.38f, 0.18f);
			RectTransform component3 = val5.GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(size.x - 40f, 4f);
			component3.anchorMin = new Vector2(0.5f, 1f);
			component3.anchorMax = new Vector2(0.5f, 1f);
			component3.anchoredPosition = new Vector2(0f, -25f);
			GameObject val7 = new GameObject("BottomBar");
			val7.transform.SetParent(parent, false);
			Image val8 = val7.AddComponent<Image>();
			((Graphic)val8).color = new Color(0.5f, 0.38f, 0.18f);
			RectTransform component4 = val7.GetComponent<RectTransform>();
			component4.sizeDelta = new Vector2(size.x - 40f, 4f);
			component4.anchorMin = new Vector2(0.5f, 0f);
			component4.anchorMax = new Vector2(0.5f, 0f);
			component4.anchoredPosition = new Vector2(0f, 25f);
		}

		private static void PopulateLeaderboardContent()
		{
			//IL_003b: 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)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			Font font = ((instance != null) ? instance.AveriaSerifBold : null);
			Font font2 = ((instance != null) ? instance.AveriaSerif : null);
			Color color = (Color)(((??)instance?.ValheimOrange) ?? new Color(1f, 0.64f, 0.1f));
			CreateStyledText(_leaderboardUI.transform, "Reputation Leaderboard", new Vector2(0f, -40f), 28, color, font, (TextAnchor)4, outline: true);
			CreateStyledText(_leaderboardUI.transform, "Top 3 players gain +100% Stamina Regen & +500 Carry Weight", new Vector2(0f, -75f), 14, new Color(0.85f, 0.8f, 0.65f), font2, (TextAnchor)4, outline: true);
			CreateStyledText(_leaderboardUI.transform, "[F7] Toggle", new Vector2(0f, -95f), 12, new Color(0.6f, 0.55f, 0.4f), font2, (TextAnchor)4, outline: false);
			CreateStyledText(_leaderboardUI.transform, "Rank", new Vector2(-180f, -130f), 16, color, font, (TextAnchor)4, outline: true, bottomAnchor: false, 60f);
			CreateStyledText(_leaderboardUI.transform, "Player", new Vector2(-50f, -130f), 16, color, font, (TextAnchor)3, outline: true, bottomAnchor: false, 150f);
			CreateStyledText(_leaderboardUI.transform, "Reputation", new Vector2(140f, -130f), 16, color, font, (TextAnchor)4, outline: true, bottomAnchor: false, 100f);
			CreateDividerLine(_leaderboardUI.transform, new Vector2(0f, -150f), 420f);
			List<PlayerReputation> leaderboard = MessageManagerAlt.GetLeaderboard();
			float num = -175f;
			int num2 = 1;
			foreach (PlayerReputation item in leaderboard.Take(12))
			{
				bool flag = num2 <= 3;
				Color val = (Color)(flag ? GetRankColor(num2) : new Color(0.9f, 0.85f, 0.7f));
				if (flag)
				{
					CreateRowHighlight(_leaderboardUI.transform, new Vector2(0f, num), val);
				}
				string rankDisplay = GetRankDisplay(num2);
				CreateStyledText(_leaderboardUI.transform, rankDisplay, new Vector2(-180f, num), 16, val, font, (TextAnchor)4, outline: true, bottomAnchor: false, 60f);
				string text = item.PlayerName ?? "Unknown";
				if (string.IsNullOrEmpty(text) || string.IsNullOrWhiteSpace(text))
				{
					text = "Anonymous";
				}
				if (text.Length > 18)
				{
					text = text.Substring(0, 15) + "...";
				}
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Leaderboard display: rank={num2}, name='{text}', rep={item.TotalReputation}");
				}
				CreateStyledText(_leaderboardUI.transform, text, new Vector2(-50f, num), 15, val, font2, (TextAnchor)3, outline: true, bottomAnchor: false, 150f);
				CreateStyledText(_leaderboardUI.transform, item.TotalReputation.ToString(), new Vector2(140f, num), 16, val, font, (TextAnchor)4, outline: true, bottomAnchor: false, 100f);
				num -= 32f;
				num2++;
			}
			if (leaderboard.Count == 0)
			{
				CreateStyledText(_leaderboardUI.transform, "No reputation data yet!", new Vector2(0f, -220f), 18, new Color(0.75f, 0.7f, 0.55f), font, (TextAnchor)4, outline: true);
				CreateStyledText(_leaderboardUI.transform, "Place messages and earn votes to appear here.", new Vector2(0f, -255f), 14, new Color(0.6f, 0.55f, 0.45f), font2, (TextAnchor)4, outline: true);
			}
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				long playerID = Player.m_localPlayer.GetPlayerID();
				if (MessageManagerAlt.IsPlayerInTop3(playerID))
				{
					CreateStyledText(_leaderboardUI.transform, "★ You are in the Top 3! Buffs Active ★", new Vector2(0f, 80f), 16, new Color(0.4f, 1f, 0.4f), font, (TextAnchor)4, outline: true, bottomAnchor: true);
				}
			}
			CreateCloseButton(_leaderboardUI.transform);
		}

		private static void CreateStyledText(Transform parent, string text, Vector2 position, int fontSize, Color color, Font font, TextAnchor alignment, bool outline, bool bottomAnchor = false, float width = 400f)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text_" + text.Substring(0, Math.Min(10, text.Length)));
			val.transform.SetParent(parent, false);
			Text val2 = val.AddComponent<Text>();
			val2.text = text;
			val2.font = font ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			val2.fontSize = fontSize;
			((Graphic)val2).color = color;
			val2.alignment = alignment;
			val2.horizontalOverflow = (HorizontalWrapMode)1;
			val2.verticalOverflow = (VerticalWrapMode)1;
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(width, 30f);
			if (bottomAnchor)
			{
				component.anchorMin = new Vector2(0.5f, 0f);
				component.anchorMax = new Vector2(0.5f, 0f);
			}
			else
			{
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
			}
			component.anchoredPosition = position;
			if (outline)
			{
				Outline val3 = val.AddComponent<Outline>();
				((Shadow)val3).effectColor = Color.black;
				((Shadow)val3).effectDistance = new Vector2(1f, -1f);
			}
		}

		private static void CreateDividerLine(Transform parent, Vector2 position, float width)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Divider");
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.5f, 0.4f, 0.25f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(width, 2f);
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.anchoredPosition = position;
		}

		private static void CreateRowHighlight(Transform parent, Vector2 position, Color baseColor)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("RowHighlight");
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = new Color(baseColor.r * 0.25f, baseColor.g * 0.25f, baseColor.b * 0.15f, 0.4f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(420f, 28f);
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.anchoredPosition = position;
			val.transform.SetSiblingIndex(3);
		}

		private static void CreateCloseButton(Transform parent)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00db: 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_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Expected O, but got Unknown
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			GUIManager instance = GUIManager.Instance;
			if (instance != null)
			{
				try
				{
					GameObject val = instance.CreateButton("Close", parent, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 45f), 140f, 45f);
					if ((Object)(object)val != (Object)null)
					{
						Button component = val.GetComponent<Button>();
						if (component != null)
						{
							ButtonClickedEvent onClick = component.onClick;
							object obj = <>O.<0>__CloseLeaderboard;
							if (obj == null)
							{
								UnityAction val2 = CloseLeaderboard;
								<>O.<0>__CloseLeaderboard = val2;
								obj = (object)val2;
							}
							((UnityEvent)onClick).AddListener((UnityAction)obj);
						}
						return;
					}
				}
				catch
				{
				}
			}
			GameObject val3 = new GameObject("CloseButton");
			val3.transform.SetParent(parent, false);
			Image val4 = val3.AddComponent<Image>();
			((Graphic)val4).color = new Color(0.35f, 0.25f, 0.15f);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(140f, 45f);
			component2.anchorMin = new Vector2(0.5f, 0f);
			component2.anchorMax = new Vector2(0.5f, 0f);
			component2.anchoredPosition = new Vector2(0f, 45f);
			Button val5 = val3.AddComponent<Button>();
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			ColorBlock colors = ((Selectable)val5).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.35f, 0.25f, 0.15f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.45f, 0.35f, 0.2f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.25f, 0.18f, 0.1f);
			((Selectable)val5).colors = colors;
			ButtonClickedEvent onClick2 = val5.onClick;
			object obj3 = <>O.<0>__CloseLeaderboard;
			if (obj3 == null)
			{
				UnityAction val6 = CloseLeaderboard;
				<>O.<0>__CloseLeaderboard = val6;
				obj3 = (object)val6;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj3);
			GameObject val7 = new GameObject("Border");
			val7.transform.SetParent(val3.transform, false);
			Image val8 = val7.AddComponent<Image>();
			((Graphic)val8).color = new Color(0.55f, 0.42f, 0.22f);
			RectTransform component3 = val7.GetComponent<RectTransform>();
			component3.sizeDelta = new Vector2(144f, 49f);
			component3.anchoredPosition = Vector2.zero;
			val7.transform.SetAsFirstSibling();
			GameObject val9 = new GameObject("Text");
			val9.transform.SetParent(val3.transform, false);
			Text val10 = val9.AddComponent<Text>();
			val10.text = "Close";
			val10.font = ((instance != null) ? instance.AveriaSerifBold : null) ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			val10.fontSize = 18;
			((Graphic)val10).color = new Color(1f, 0.9f, 0.7f);
			val10.alignment = (TextAnchor)4;
			RectTransform component4 = val9.GetComponent<RectTransform>();
			component4.sizeDelta = new Vector2(140f, 45f);
			component4.anchoredPosition = Vector2.zero;
			Outline val11 = val9.AddComponent<Outline>();
			((Shadow)val11).effectColor = Color.black;
			((Shadow)val11).effectDistance = new Vector2(1f, -1f);
		}

		private static string GetRankDisplay(int rank)
		{
			return rank switch
			{
				1 => "1st", 
				2 => "2nd", 
				3 => "3rd", 
				_ => rank.ToString(), 
			};
		}

		private static Color GetRankColor(int rank)
		{
			//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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(rank switch
			{
				1 => new Color(1f, 0.84f, 0f), 
				2 => new Color(0.78f, 0.78f, 0.8f), 
				3 => new Color(0.85f, 0.55f, 0.25f), 
				_ => Color.white, 
			});
		}

		public static void CheckAndApplyBuffs()
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				long playerID = Player.m_localPlayer.GetPlayerID();
				bool flag = MessageManagerAlt.IsPlayerInTop3(playerID);
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"CheckAndApplyBuffs: localId={playerID}, shouldHave={flag}, hasCarry={_hasCarryBuff}");
				}
				if (flag && !_hasCarryBuff)
				{
					ApplyBuffs();
				}
				else if (!flag && _hasCarryBuff)
				{
					RemoveBuffs();
				}
			}
		}

		private static void ApplyBuffs()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			_hasCarryBuff = true;
			_hasStealthBuff = true;
			try
			{
				SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan();
				if (sEMan != null)
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_ReputationTop3");
					StatusEffect statusEffect = sEMan.GetStatusEffect(stableHashCode);
					if ((Object)(object)statusEffect != (Object)null)
					{
						sEMan.RemoveStatusEffect(statusEffect, false);
					}
					SE_Stats val = ScriptableObject.CreateInstance<SE_Stats>();
					((Object)val).name = "SE_ReputationTop3";
					((StatusEffect)val).m_name = "Reputation Champion";
					((StatusEffect)val).m_tooltip = "Top 3 Reputation Bonus:\n• +500 Carry Weight\n• +100% Stamina Regeneration";
					try
					{
						string[] array = new string[5] { "Thunderstone", "DragonTear", "SurtlingCore", "Coins", "Ruby" };
						string[] array2 = array;
						foreach (string text in array2)
						{
							ObjectDB instance = ObjectDB.instance;
							GameObject val2 = ((instance != null) ? instance.GetItemPrefab(text) : null);
							if (!((Object)(object)val2 != (Object)null))
							{
								continue;
							}
							ItemDrop component = val2.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null && component.m_itemData?.m_shared?.m_icons != null && component.m_itemData.m_shared.m_icons.Length != 0)
							{
								((StatusEffect)val).m_icon = component.m_itemData.m_shared.m_icons[0];
								ManualLogSource log = VikingMessagesPlugin.Log;
								if (log != null)
								{
									log.LogInfo((object)("Using icon from " + text));
								}
								break;
							}
						}
						if ((Object)(object)((StatusEffect)val).m_icon == (Object)null)
						{
							ObjectDB instance2 = ObjectDB.instance;
							StatusEffect val3 = ((instance2 != null) ? instance2.GetStatusEffect(StringExtensionMethods.GetStableHashCode("Rested")) : null);
							if ((Object)(object)val3 != (Object)null && (Object)(object)val3.m_icon != (Object)null)
							{
								((StatusEffect)val).m_icon = val3.m_icon;
							}
						}
					}
					catch
					{
					}
					val.m_addMaxCarryWeight = 500f;
					val.m_staminaRegenMultiplier = 2f;
					((StatusEffect)val).m_ttl = 0f;
					sEMan.AddStatusEffect((StatusEffect)(object)val, false, 0, 0f);
					_reputationBuff = val;
					ManualLogSource log2 = VikingMessagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"Top 3 buffs applied via StatusEffect (hash={stableHashCode}): +500 carry, +100% stamina regen");
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = VikingMessagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("Failed to apply StatusEffect buff: " + ex.Message));
				}
			}
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "<color=yellow>Top 3 Reputation Bonus Active!</color>\n+500 Carry Weight & +100% Stamina Regen", 0, (Sprite)null);
			}
		}

		private static void RemoveBuffs()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			try
			{
				SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan();
				if (sEMan != null)
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode("SE_ReputationTop3");
					StatusEffect statusEffect = sEMan.GetStatusEffect(stableHashCode);
					if ((Object)(object)statusEffect != (Object)null)
					{
						sEMan.RemoveStatusEffect(statusEffect, false);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Failed to remove buff: " + ex.Message));
				}
			}
			_hasCarryBuff = false;
			_hasStealthBuff = false;
			_reputationBuff = null;
			ManualLogSource log2 = VikingMessagesPlugin.Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"Top 3 buffs removed");
			}
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "<color=#888888>Reputation Bonus Removed</color>", 0, (Sprite)null);
			}
		}

		public static bool HasStealthBuff()
		{
			return _hasStealthBuff;
		}

		public static float GetCarryWeightBonus()
		{
			return _hasCarryBuff ? 500f : 0f;
		}

		public static void Update()
		{
			if (_isVisible && Input.GetKeyDown((KeyCode)27))
			{
				CloseLeaderboard();
			}
			else if (Input.GetKeyDown((KeyCode)288))
			{
				if (_isVisible)
				{
					CloseLeaderboard();
				}
				else if ((Object)(object)Player.m_localPlayer != (Object)null && !InventoryGui.IsVisible() && !Menu.IsVisible() && !Console.IsVisible())
				{
					ShowLeaderboard();
				}
			}
		}
	}
	[HarmonyPatch]
	public static class LeaderboardPatches
	{
	}
	public class MessageGlyphItem : MonoBehaviour, Hoverable
	{
		private ItemDrop _itemDrop;

		private void Awake()
		{
			_itemDrop = ((Component)this).GetComponent<ItemDrop>();
		}

		public string GetHoverText()
		{
			return "Message Glyph\n[<color=yellow><b>E</b></color>] Place Message";
		}

		public string GetHoverName()
		{
			return "Message Glyph";
		}
	}
	public class MessagePlacementHandler : MonoBehaviour
	{
		private static MessagePlacementHandler _instance;

		private bool _isPlacing;

		private float _placementTimer;

		private const float PlacementDuration = 2f;

		private Vector3 _placementPosition;

		private Quaternion _placementRotation;

		public static MessagePlacementHandler Instance
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("MessagePlacementHandler");
					_instance = val.AddComponent<MessagePlacementHandler>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return _instance;
			}
		}

		public bool IsPlacing => _isPlacing;

		private void Update()
		{
			if (_isPlacing)
			{
				_placementTimer -= Time.deltaTime;
				if (_placementTimer <= 0f)
				{
					FinishPlacement();
				}
				if ((Object)(object)Player.m_localPlayer != (Object)null && !((Character)Player.m_localPlayer).IsEncumbered() && !((Character)Player.m_localPlayer).InAttack() && !(((Character)Player.m_localPlayer).GetHealth() < ((Character)Player.m_localPlayer).GetMaxHealth() * 0.9f))
				{
				}
			}
		}

		public void StartPlacement(Player player)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			if (!_isPlacing)
			{
				_isPlacing = true;
				_placementTimer = 2f;
				_placementPosition = ((Component)player).transform.position + ((Component)player).transform.forward * 1.5f;
				_placementRotation = Quaternion.Euler(0f, ((Component)player).transform.eulerAngles.y, 0f);
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(_placementPosition + Vector3.up * 5f, Vector3.down, ref val, 10f, LayerMask.GetMask(new string[3] { "Default", "static_solid", "terrain" })))
				{
					_placementPosition = ((RaycastHit)(ref val)).point;
				}
				player.StartEmote("kneel", true);
				((Character)player).Message((MessageType)2, "Placing message...", 0, (Sprite)null);
				VikingMessagesPlugin.Log.LogInfo((object)"Started message placement");
			}
		}

		private void FinishPlacement()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			_isPlacing = false;
			MessageUIManager.UI.ShowCreateUI(_placementPosition, _placementRotation);
			VikingMessagesPlugin.Log.LogInfo((object)"Finished placement, opening UI");
		}

		public void CancelPlacement()
		{
			if (_isPlacing)
			{
				_isPlacing = false;
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					((Character)Player.m_localPlayer).Message((MessageType)1, "Placement cancelled", 0, (Sprite)null);
				}
			}
		}
	}
	[HarmonyPatch]
	public static class MessageGlyphPatches
	{
		[HarmonyPatch(typeof(Player), "ConsumeItem")]
		[HarmonyPrefix]
		public static bool ConsumeItem_Prefix(Player __instance, ItemData item, ref bool __result)
		{
			object obj;
			if (item == null)
			{
				obj = null;
			}
			else
			{
				GameObject dropPrefab = item.m_dropPrefab;
				obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
			}
			if ((string?)obj != "MessageGlyph")
			{
				return true;
			}
			if (!CanPlaceMessage(__instance))
			{
				((Character)__instance).Message((MessageType)2, "Cannot place message here!", 0, (Sprite)null);
				__result = false;
				return false;
			}
			MessagePlacementHandler.Instance.StartPlacement(__instance);
			((Humanoid)__instance).GetInventory().RemoveItem(item, 1);
			__result = true;
			return false;
		}

		[HarmonyPatch(typeof(Humanoid), "UseItem")]
		[HarmonyPrefix]
		public static bool UseItem_Prefix(Humanoid __instance, ItemData item)
		{
			object obj;
			if (item == null)
			{
				obj = null;
			}
			else
			{
				GameObject dropPrefab = item.m_dropPrefab;
				obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
			}
			if ((string?)obj != "MessageGlyph")
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				((Humanoid)val).ConsumeItem(((Humanoid)val).GetInventory(), item, false);
				return false;
			}
			return true;
		}

		private static bool CanPlaceMessage(Player player)
		{
			if (((Character)player).InInterior())
			{
				return false;
			}
			if (((Character)player).IsSwimming())
			{
				return false;
			}
			if (((Character)player).IsAttached())
			{
				return false;
			}
			if (((Character)player).IsDead())
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(Character), "Damage")]
		[HarmonyPostfix]
		public static void Character_Damage_Postfix(Character __instance, HitData hit)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && MessagePlacementHandler.Instance.IsPlacing)
			{
				MessagePlacementHandler.Instance.CancelPlacement();
			}
		}
	}
	public static class MessageManagerAlt
	{
		private static Dictionary<string, VikingMessage> _messages = new Dictionary<string, VikingMessage>();

		private static Dictionary<long, PlayerReputation> _playerReputations = new Dictionary<long, PlayerReputation>();

		private static string _saveFilePath;

		private static string _leaderboardFilePath;

		private static string _currentWorldName;

		public const string RPC_PlaceMessage = "VikingMessages_PlaceMessage";

		public const string RPC_VoteMessage = "VikingMessages_VoteMessage";

		public const string RPC_RequestSync = "VikingMessages_RequestSync";

		public const string RPC_SyncMessages = "VikingMessages_SyncMessages";

		public const string RPC_RemoveMessage = "VikingMessages_RemoveMessage";

		public const string RPC_SyncTemplates = "VikingMessages_SyncTemplates";

		public const string RPC_SyncLeaderboard = "VikingMessages_SyncLeaderboard";

		public const string RPC_NotifyAppraise = "VikingMessages_NotifyAppraise";

		private static bool _rpcsRegistered = false;

		public static void Initialize()
		{
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)"MessageManagerAlt initialized");
			}
		}

		public static void RegisterRPCs()
		{
			if (_rpcsRegistered || ZRoutedRpc.instance == null)
			{
				return;
			}
			try
			{
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_PlaceMessage", (Action<long, ZPackage>)RPC_OnPlaceMessage);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_VoteMessage", (Action<long, ZPackage>)RPC_OnVoteMessage);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_RequestSync", (Action<long, ZPackage>)RPC_OnRequestSync);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_SyncMessages", (Action<long, ZPackage>)RPC_OnSyncMessages);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_RemoveMessage", (Action<long, ZPackage>)RPC_OnRemoveMessage);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_SyncTemplates", (Action<long, ZPackage>)RPC_OnSyncTemplates);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_SyncLeaderboard", (Action<long, ZPackage>)RPC_OnSyncLeaderboard);
				ZRoutedRpc.instance.Register<ZPackage>("VikingMessages_NotifyAppraise", (Action<long, ZPackage>)RPC_OnNotifyAppraise);
				_rpcsRegistered = true;
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"RPCs registered successfully");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Failed to register RPCs: {arg}");
				}
			}
		}

		private static void RPC_OnPlaceMessage(long sender, ZPackage pkg)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = pkg.ReadString();
				Vector3 position = pkg.ReadVector3();
				Quaternion rotation = pkg.ReadQuaternion();
				string template = pkg.ReadString();
				string words = pkg.ReadString();
				int num = pkg.ReadInt();
				string text2 = pkg.ReadString();
				Vector3 lookDirection = pkg.ReadVector3();
				int num2 = pkg.ReadInt();
				string[] array = new string[num2];
				for (int i = 0; i < num2; i++)
				{
					array[i] = pkg.ReadString();
				}
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"RPC_OnPlaceMessage: id={text}, author={text2}, emote={num}");
				}
				VikingMessage value = new VikingMessage
				{
					Id = text,
					Position = position,
					Rotation = rotation,
					Template = template,
					Words = words,
					EmoteIndex = num,
					AuthorId = sender,
					AuthorName = text2,
					Reputation = 0,
					CreatedTime = DateTime.UtcNow,
					VotedPlayers = new List<long>(),
					EquippedItems = array,
					LookDirection = lookDirection
				};
				_messages[text] = value;
				UpdatePlayerMessageCount(sender, text2);
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					SaveMessages();
					SaveLeaderboard();
				}
				BroadcastMessageSync();
				BroadcastLeaderboard();
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error processing PlaceMessage: {arg}");
				}
			}
		}

		private static void RPC_OnVoteMessage(long sender, ZPackage pkg)
		{
			try
			{
				string text = pkg.ReadString();
				bool flag = pkg.ReadBool();
				if (!_messages.TryGetValue(text, out var value) || value.VotedPlayers.Contains(sender) || value.AuthorId == sender)
				{
					return;
				}
				value.VotedPlayers.Add(sender);
				value.Reputation += (flag ? 1 : (-1));
				UpdatePlayerReputation(value.AuthorId, value.AuthorName, flag ? 1 : (-1));
				if (flag && (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					NotifyAuthorOfAppraise(value.AuthorId);
				}
				if (value.Reputation <= VikingMessagesPlugin.MinReputation.Value)
				{
					_messages.Remove(text);
					ManualLogSource log = VikingMessagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)("Message " + text + " removed due to low reputation"));
					}
				}
				if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
				{
					SaveMessages();
					SaveLeaderboard();
				}
				BroadcastMessageSync();
				BroadcastLeaderboard();
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error processing VoteMessage: {arg}");
				}
			}
		}

		private static void NotifyAuthorOfAppraise(long authorId)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			try
			{
				ZPackage val = new ZPackage();
				val.Write("appraise");
				List<ZNetPeer> peers = ZNet.instance.GetPeers();
				foreach (ZNetPeer item in peers)
				{
					if (((ZDOID)(ref item.m_characterID)).UserID == authorId)
					{
						ZRoutedRpc.instance.InvokeRoutedRPC(item.m_uid, "VikingMessages_NotifyAppraise", new object[1] { val });
						ManualLogSource log = VikingMessagesPlugin.Log;
						if (log != null)
						{
							log.LogInfo((object)$"Sent appraise notification to {authorId}");
						}
						break;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("Failed to notify author: " + ex.Message));
				}
			}
		}

		private static void RPC_OnNotifyAppraise(long sender, ZPackage pkg)
		{
			try
			{
				string text = pkg.ReadString();
				if (text == "appraise")
				{
					Player localPlayer = Player.m_localPlayer;
					if (localPlayer != null)
					{
						((Character)localPlayer).Message((MessageType)2, "<color=#FFD700>Your message was appraised!</color>", 0, (Sprite)null);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Error processing notification: " + ex.Message));
				}
			}
		}

		private static void RPC_OnRequestSync(long sender, ZPackage pkg)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Sync requested by {sender}");
				}
				SendMessagesToClient(sender);
				SendTemplatesToClient(sender);
				SendLeaderboardToClient(sender);
			}
		}

		private static void RPC_OnSyncMessages(long sender, ZPackage pkg)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return;
			}
			try
			{
				int num = pkg.ReadInt();
				Dictionary<string, VikingMessage> dictionary = new Dictionary<string, VikingMessage>();
				for (int i = 0; i < num; i++)
				{
					VikingMessage vikingMessage = new VikingMessage
					{
						Id = pkg.ReadString(),
						Position = pkg.ReadVector3(),
						Rotation = pkg.ReadQuaternion(),
						Template = pkg.ReadString(),
						Words = pkg.ReadString(),
						EmoteIndex = pkg.ReadInt(),
						AuthorId = pkg.ReadLong(),
						AuthorName = pkg.ReadString(),
						Reputation = pkg.ReadInt(),
						LookDirection = pkg.ReadVector3()
					};
					int num2 = pkg.ReadInt();
					vikingMessage.EquippedItems = new string[num2];
					for (int j = 0; j < num2; j++)
					{
						vikingMessage.EquippedItems[j] = pkg.ReadString();
					}
					int num3 = pkg.ReadInt();
					vikingMessage.VotedPlayers = new List<long>();
					for (int k = 0; k < num3; k++)
					{
						vikingMessage.VotedPlayers.Add(pkg.ReadLong());
					}
					dictionary[vikingMessage.Id] = vikingMessage;
				}
				_messages = dictionary;
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Synced {num} messages from server");
				}
				RefreshAllMessageStones();
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error processing SyncMessages: {arg}");
				}
			}
		}

		private static void RPC_OnRemoveMessage(long sender, ZPackage pkg)
		{
			try
			{
				string key = pkg.ReadString();
				if (_messages.ContainsKey(key))
				{
					_messages.Remove(key);
					if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
					{
						SaveMessages();
					}
					BroadcastMessageSync();
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Error processing RemoveMessage: {arg}");
				}
			}
		}

		private static void RPC_OnSyncTemplates(long sender, ZPackage pkg)
		{
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return;
			}
			try
			{
				string json = pkg.ReadString();
				MessageTemplates.LoadFromServerJson(json);
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Templates synced from server");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Error processing SyncTemplates: {arg}");
				}
			}
		}

		private static void RPC_OnSyncLeaderboard(long sender, ZPackage pkg)
		{
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer())
			{
				return;
			}
			try
			{
				int num = pkg.ReadInt();
				_playerReputations.Clear();
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"RPC_OnSyncLeaderboard: Receiving {num} players");
				}
				for (int i = 0; i < num; i++)
				{
					PlayerReputation playerReputation = new PlayerReputation
					{
						PlayerId = pkg.ReadLong(),
						PlayerName = pkg.ReadString(),
						TotalReputation = pkg.ReadInt(),
						MessageCount = pkg.ReadInt()
					};
					_playerReputations[playerReputation.PlayerId] = playerReputation;
					ManualLogSource log2 = VikingMessagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"  Player {i}: id={playerReputation.PlayerId}, name='{playerReputation.PlayerName}', rep={playerReputation.TotalReputation}");
					}
				}
				ManualLogSource log3 = VikingMessagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogInfo((object)$"Synced leaderboard: {num} players");
				}
				LeaderboardManager.CheckAndApplyBuffs();
			}
			catch (Exception arg)
			{
				ManualLogSource log4 = VikingMessagesPlugin.Log;
				if (log4 != null)
				{
					log4.LogError((object)$"Error processing SyncLeaderboard: {arg}");
				}
			}
		}

		public static void PlaceMessage(Vector3 position, Quaternion rotation, string template, string words, int emoteIndex)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0078: Expected O, but got Unknown
			//IL_0083: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				string text = Guid.NewGuid().ToString();
				string playerName = Player.m_localPlayer.GetPlayerName();
				Vector3 forward = ((Component)Player.m_localPlayer).transform.forward;
				string[] array = CapturePlayerEquipment();
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"PlaceMessage: id={text}, author='{playerName}', emote={emoteIndex}");
				}
				ZPackage val = new ZPackage();
				val.Write(text);
				val.Write(position);
				val.Write(rotation);
				val.Write(template);
				val.Write(words);
				val.Write(emoteIndex);
				val.Write(playerName ?? "Unknown");
				val.Write(forward);
				val.Write(array.Length);
				string[] array2 = array;
				foreach (string text2 in array2)
				{
					val.Write(text2 ?? "");
				}
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VikingMessages_PlaceMessage", new object[1] { val });
			}
		}

		private static string[] CapturePlayerEquipment()
		{
			List<string> list = new List<string>();
			try
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					return list.ToArray();
				}
				VisEquipment component = ((Component)Player.m_localPlayer).GetComponent<VisEquipment>();
				if ((Object)(object)component == (Object)null)
				{
					return list.ToArray();
				}
				Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
				if (inventory == null)
				{
					return list.ToArray();
				}
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (allItem.m_equipped && (Object)(object)allItem.m_dropPrefab != (Object)null)
					{
						list.Add(((Object)allItem.m_dropPrefab).name);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Failed to capture equipment: " + ex.Message));
				}
			}
			return list.ToArray();
		}

		public static bool VoteMessage(string messageId, bool isLike)
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			if (!_messages.TryGetValue(messageId, out var value))
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Message not found!", 0, (Sprite)null);
				}
				return false;
			}
			Player localPlayer2 = Player.m_localPlayer;
			long num = ((localPlayer2 != null) ? localPlayer2.GetPlayerID() : 0);
			Player localPlayer3 = Player.m_localPlayer;
			string value2 = ((localPlayer3 != null) ? localPlayer3.GetPlayerName() : null) ?? "";
			if (value.AuthorId == num || (!string.IsNullOrEmpty(value2) && !string.IsNullOrEmpty(value.AuthorName) && value.AuthorName.Equals(value2, StringComparison.OrdinalIgnoreCase)))
			{
				Player localPlayer4 = Player.m_localPlayer;
				if (localPlayer4 != null)
				{
					((Character)localPlayer4).Message((MessageType)2, "You cannot appraise your own message!", 0, (Sprite)null);
				}
				return false;
			}
			if (value.VotedPlayers.Contains(num))
			{
				Player localPlayer5 = Player.m_localPlayer;
				if (localPlayer5 != null)
				{
					((Character)localPlayer5).Message((MessageType)2, "You have already rated this message!", 0, (Sprite)null);
				}
				return false;
			}
			ZPackage val = new ZPackage();
			val.Write(messageId);
			val.Write(isLike);
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VikingMessages_VoteMessage", new object[1] { val });
			return true;
		}

		public static void RequestMessages()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (ZRoutedRpc.instance != null)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Requesting sync from server");
				}
				ZPackage val = new ZPackage();
				ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VikingMessages_RequestSync", new object[1] { val });
			}
		}

		public static VikingMessage GetMessage(string messageId)
		{
			VikingMessage value;
			return _messages.TryGetValue(messageId, out value) ? value : null;
		}

		public static IEnumerable<VikingMessage> GetAllMessages()
		{
			return _messages.Values;
		}

		public static int GetMessageCount()
		{
			return _messages.Count;
		}

		private static void UpdatePlayerMessageCount(long playerId, string playerName)
		{
			if (!_playerReputations.TryGetValue(playerId, out var value))
			{
				value = new PlayerReputation(playerId, playerName);
				_playerReputations[playerId] = value;
			}
			value.MessageCount++;
			value.PlayerName = playerName;
		}

		private static void UpdatePlayerReputation(long playerId, string playerName, int delta)
		{
			if (!_playerReputations.TryGetValue(playerId, out var value))
			{
				value = new PlayerReputation(playerId, playerName);
				_playerReputations[playerId] = value;
			}
			value.TotalReputation += delta;
			value.PlayerName = playerName;
		}

		public static List<PlayerReputation> GetLeaderboard()
		{
			Dictionary<string, PlayerReputation> dictionary = new Dictionary<string, PlayerReputation>();
			foreach (PlayerReputation value2 in _playerReputations.Values)
			{
				string key = (string.IsNullOrEmpty(value2.PlayerName) ? $"id_{value2.PlayerId}" : value2.PlayerName.ToLower());
				if (dictionary.TryGetValue(key, out var value))
				{
					value.TotalReputation += value2.TotalReputation;
					value.MessageCount += value2.MessageCount;
					if (string.IsNullOrEmpty(value.PlayerName) && !string.IsNullOrEmpty(value2.PlayerName))
					{
						value.PlayerName = value2.PlayerName;
					}
				}
				else
				{
					dictionary[key] = new PlayerReputation
					{
						PlayerId = value2.PlayerId,
						PlayerName = value2.PlayerName,
						TotalReputation = value2.TotalReputation,
						MessageCount = value2.MessageCount
					};
				}
			}
			return dictionary.Values.OrderByDescending((PlayerReputation p) => p.TotalReputation).ToList();
		}

		public static bool IsPlayerInTop3(long playerId)
		{
			Player localPlayer = Player.m_localPlayer;
			string localPlayerName = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "";
			List<PlayerReputation> list = GetLeaderboard().Take(3).ToList();
			bool flag = list.Any((PlayerReputation p) => p.PlayerId == playerId || (!string.IsNullOrEmpty(localPlayerName) && !string.IsNullOrEmpty(p.PlayerName) && p.PlayerName.Equals(localPlayerName, StringComparison.OrdinalIgnoreCase)));
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"IsPlayerInTop3: playerId={playerId}, name={localPlayerName}, top3Count={list.Count}, result={flag}");
			}
			if (list.Count > 0)
			{
				foreach (PlayerReputation item in list)
				{
					ManualLogSource log2 = VikingMessagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"  Top3 player: id={item.PlayerId}, name='{item.PlayerName}', rep={item.TotalReputation}");
					}
				}
			}
			return flag;
		}

		private static void SendMessagesToClient(long clientId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(_messages.Count);
			foreach (VikingMessage value in _messages.Values)
			{
				val.Write(value.Id);
				val.Write(value.Position);
				val.Write(value.Rotation);
				val.Write(value.Template ?? "");
				val.Write(value.Words ?? "");
				val.Write(value.EmoteIndex);
				val.Write(value.AuthorId);
				val.Write(value.AuthorName ?? "Unknown");
				val.Write(value.Reputation);
				val.Write(value.LookDirection);
				string[] array = value.EquippedItems ?? new string[0];
				val.Write(array.Length);
				string[] array2 = array;
				foreach (string text in array2)
				{
					val.Write(text ?? "");
				}
				val.Write(value.VotedPlayers?.Count ?? 0);
				if (value.VotedPlayers == null)
				{
					continue;
				}
				foreach (long votedPlayer in value.VotedPlayers)
				{
					val.Write(votedPlayer);
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(clientId, "VikingMessages_SyncMessages", new object[1] { val });
		}

		private static void BroadcastMessageSync()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(_messages.Count);
			foreach (VikingMessage value in _messages.Values)
			{
				val.Write(value.Id);
				val.Write(value.Position);
				val.Write(value.Rotation);
				val.Write(value.Template ?? "");
				val.Write(value.Words ?? "");
				val.Write(value.EmoteIndex);
				val.Write(value.AuthorId);
				val.Write(value.AuthorName ?? "Unknown");
				val.Write(value.Reputation);
				val.Write(value.LookDirection);
				string[] array = value.EquippedItems ?? new string[0];
				val.Write(array.Length);
				string[] array2 = array;
				foreach (string text in array2)
				{
					val.Write(text ?? "");
				}
				val.Write(value.VotedPlayers?.Count ?? 0);
				if (value.VotedPlayers == null)
				{
					continue;
				}
				foreach (long votedPlayer in value.VotedPlayers)
				{
					val.Write(votedPlayer);
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VikingMessages_SyncMessages", new object[1] { val });
		}

		private static void SendTemplatesToClient(long clientId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			string serverTemplatesJson = MessageTemplates.GetServerTemplatesJson();
			ZPackage val = new ZPackage();
			val.Write(serverTemplatesJson);
			ZRoutedRpc.instance.InvokeRoutedRPC(clientId, "VikingMessages_SyncTemplates", new object[1] { val });
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Sent templates to client {clientId}");
			}
		}

		private static void SendLeaderboardToClient(long clientId)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			List<PlayerReputation> list = _playerReputations.Values.ToList();
			val.Write(list.Count);
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"SendLeaderboardToClient: Sending {list.Count} players to {clientId}");
			}
			foreach (PlayerReputation item in list)
			{
				val.Write(item.PlayerId);
				val.Write(item.PlayerName ?? "Unknown");
				val.Write(item.TotalReputation);
				val.Write(item.MessageCount);
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)$"  Sending player: id={item.PlayerId}, name='{item.PlayerName}', rep={item.TotalReputation}");
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(clientId, "VikingMessages_SyncLeaderboard", new object[1] { val });
		}

		private static void BroadcastLeaderboard()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			List<PlayerReputation> list = _playerReputations.Values.ToList();
			val.Write(list.Count);
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"BroadcastLeaderboard: Broadcasting {list.Count} players");
			}
			foreach (PlayerReputation item in list)
			{
				val.Write(item.PlayerId);
				val.Write(item.PlayerName ?? "Unknown");
				val.Write(item.TotalReputation);
				val.Write(item.MessageCount);
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VikingMessages_SyncLeaderboard", new object[1] { val });
		}

		public static void SpawnMessageStone(VikingMessage msg)
		{
			//IL_0018: 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)
			if (!((Object)(object)VikingMessagesPlugin.MessageStonePrefab == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(VikingMessagesPlugin.MessageStonePrefab, msg.Position, msg.Rotation);
				val.SetActive(true);
				MessageStone component = val.GetComponent<MessageStone>();
				if ((Object)(object)component != (Object)null)
				{
					component.Initialize(msg);
				}
			}
		}

		private static void RefreshAllMessageStones()
		{
			MessageStone[] array = Object.FindObjectsOfType<MessageStone>();
			MessageStone[] array2 = array;
			foreach (MessageStone messageStone in array2)
			{
				Object.Destroy((Object)(object)((Component)messageStone).gameObject);
			}
			foreach (VikingMessage value in _messages.Values)
			{
				SpawnMessageStone(value);
			}
			ManualLogSource log = VikingMessagesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Refreshed {_messages.Count} message stones");
			}
		}

		private static void SetupSavePath(string worldName)
		{
			if (string.IsNullOrEmpty(worldName))
			{
				worldName = "Unknown";
			}
			_currentWorldName = worldName;
			string text = Path.Combine(Paths.ConfigPath, "VikingMessages");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			string text2 = string.Join("_", worldName.Split(Path.GetInvalidFileNameChars()));
			_saveFilePath = Path.Combine(text, "messages_" + text2 + ".json");
			_leaderboardFilePath = Path.Combine(text, "leaderboard_" + text2 + ".json");
		}

		public static void SaveMessages()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			if (string.IsNullOrEmpty(_saveFilePath))
			{
				SetupSavePath(ZNet.instance.GetWorldName());
			}
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("{");
				stringBuilder.AppendLine("  \"Messages\": [");
				List<VikingMessage> list = _messages.Values.ToList();
				for (int i = 0; i < list.Count; i++)
				{
					VikingMessage vikingMessage = list[i];
					stringBuilder.AppendLine("    {");
					stringBuilder.AppendLine("      \"Id\": \"" + Escape(vikingMessage.Id) + "\",");
					stringBuilder.AppendLine("      \"PosX\": " + F(vikingMessage.Position.x) + ", \"PosY\": " + F(vikingMessage.Position.y) + ", \"PosZ\": " + F(vikingMessage.Position.z) + ",");
					stringBuilder.AppendLine("      \"RotX\": " + F(vikingMessage.Rotation.x) + ", \"RotY\": " + F(vikingMessage.Rotation.y) + ", \"RotZ\": " + F(vikingMessage.Rotation.z) + ", \"RotW\": " + F(vikingMessage.Rotation.w) + ",");
					stringBuilder.AppendLine("      \"Template\": \"" + Escape(vikingMessage.Template) + "\",");
					stringBuilder.AppendLine("      \"Words\": \"" + Escape(vikingMessage.Words) + "\",");
					stringBuilder.AppendLine($"      \"EmoteIndex\": {vikingMessage.EmoteIndex},");
					stringBuilder.AppendLine($"      \"AuthorId\": {vikingMessage.AuthorId},");
					stringBuilder.AppendLine("      \"AuthorName\": \"" + Escape(vikingMessage.AuthorName) + "\",");
					stringBuilder.AppendLine($"      \"Reputation\": {vikingMessage.Reputation},");
					stringBuilder.AppendLine("      \"LookDirX\": " + F(vikingMessage.LookDirection.x) + ", \"LookDirY\": " + F(vikingMessage.LookDirection.y) + ", \"LookDirZ\": " + F(vikingMessage.LookDirection.z) + ",");
					stringBuilder.Append("      \"Equipment\": [");
					if (vikingMessage.EquippedItems != null && vikingMessage.EquippedItems.Length != 0)
					{
						stringBuilder.Append(string.Join(", ", vikingMessage.EquippedItems.Select((string e) => "\"" + Escape(e) + "\"")));
					}
					stringBuilder.AppendLine("],");
					stringBuilder.Append("      \"VotedPlayers\": [");
					if (vikingMessage.VotedPlayers != null && vikingMessage.VotedPlayers.Count > 0)
					{
						stringBuilder.Append(string.Join(", ", vikingMessage.VotedPlayers));
					}
					stringBuilder.AppendLine("]");
					stringBuilder.AppendLine((i < list.Count - 1) ? "    }," : "    }");
				}
				stringBuilder.AppendLine("  ]");
				stringBuilder.AppendLine("}");
				File.WriteAllText(_saveFilePath, stringBuilder.ToString());
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Saved {_messages.Count} messages");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = VikingMessagesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Failed to save messages: {arg}");
				}
			}
		}

		public static void SaveLeaderboard()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			if (string.IsNullOrEmpty(_leaderboardFilePath))
			{
				SetupSavePath(ZNet.instance.GetWorldName());
			}
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("{");
				stringBuilder.AppendLine("  \"Players\": [");
				List<PlayerReputation> list = _playerReputations.Values.ToList();
				for (int i = 0; i < list.Count; i++)
				{
					PlayerReputation playerReputation = list[i];
					stringBuilder.AppendLine("    {");
					stringBuilder.AppendLine($"      \"PlayerId\": {playerReputation.PlayerId},");
					stringBuilder.AppendLine("      \"PlayerName\": \"" + Escape(playerReputation.PlayerName) + "\",");
					stringBuilder.AppendLine($"      \"TotalReputation\": {playerReputation.TotalReputation},");
					stringBuilder.AppendLine($"      \"MessageCount\": {playerReputation.MessageCount}");
					stringBuilder.AppendLine((i < list.Count - 1) ? "    }," : "    }");
				}
				stringBuilder.AppendLine("  ]");
				stringBuilder.AppendLine("}");
				File.WriteAllText(_leaderboardFilePath, stringBuilder.ToString());
			}
			catch (Exception arg)
			{
				ManualLogSource log = VikingMessagesPlugin.Log;
				if (log != null)
				{
					log.LogError((object)$"Failed to save leaderboard: {arg}");
				}
			}
		}

		public static void LoadMessages()
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			SetupSavePath(ZNet.instance.GetWorldName());
			try
			{
				if (File.Exists(_saveFilePath))
				{
					string json = File.ReadAllText(_saveFilePath);
					ParseMessagesJson(json);
					ManualLogSource log = VikingMessagesPlugin.Log;
					if (log != null)
					{
						log.LogInfo((object)$"Loaded {_messages.Count} messages");
					}
				}
				if (File.Exists(_leaderboardFilePath))
				{
					string json2 = File.ReadAllText(_leaderboardFilePath);
					ParseLeaderboardJson(json2);
					ManualLogSource log2 = VikingMessagesPlugin.Log;
					if (log2 != null)
					{
						log2.LogInfo((object)$"Loaded {_playerReputations.Count} player reputations");
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log3 = VikingMessagesPlugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)$"Failed to load data: {arg}");
				}
			}
		}

		private static void ParseMessagesJson(string json)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			_messages.Clear();
			int startIndex = 0;
			while ((startIndex = json.IndexOf("\"Id\":", startIndex)) >= 0)
			{
				try
				{
					VikingMessage vikingMessage = new VikingMessage();
					vikingMessage.Id = ExtractString(json, "Id", startIndex);
					vikingMessage.Position = new Vector3(ExtractFloat(json, "PosX", startIndex), ExtractFloat(json, "PosY", startIndex), ExtractFloat(json, "PosZ", startIndex));
					vikingMessage.Rotation = new Quaternion(ExtractFloat(json, "RotX", startIndex), ExtractFloat(json, "RotY", startIndex), ExtractFloat(json, "RotZ", startIndex), ExtractFloat(json, "RotW", startIndex));
					vikingMessage.Template = ExtractString(json, "Template", startIndex);
					vikingMessage.Words = ExtractString(json, "Words", startIndex);
					vikingMessage.EmoteIndex = (int)ExtractFloat(json, "EmoteIndex", startIndex);
					vikingMessage.AuthorId = (long)ExtractFloat(json, "AuthorId", startIndex);
					vikingMessage.AuthorName = ExtractString(json, "AuthorName", startIndex);
					vikingMessage.Reputation = (int)ExtractFloat(json, "Reputation", startIndex);
					vikingMessage.LookDirection = new Vector3(ExtractFloat(json, "LookDirX", startIndex), ExtractFloat(json, "LookDirY", startIndex), ExtractFloat(json, "LookDirZ", startIndex));
					vikingMessage.EquippedItems = ExtractStringArray(json, "Equipment", startIndex);
					vikingMessage.VotedPlayers = ExtractLongArray(json, "VotedPlayers", startIndex);
					if (!string.IsNullOrEmpty(vikingMessage.Id))
					{
						_messages[vikingMessage.Id] = vikingMessage;
					}
				}
				catch
				{
				}
				startIndex++;
			}
		}

		private static void ParseLeaderboardJson(string json)
		{
			_playerReputations.Clear();
			int startIndex = 0;
			while ((startIndex = json.IndexOf("\"PlayerId\":", startIndex)) >= 0)
			{
				try
				{
					PlayerReputation playerReputation = new PlayerReputation();
					playerReputation.PlayerId = (long)ExtractFloat(json, "PlayerId", startIndex);
					playerReputation.PlayerName = ExtractString(json, "PlayerName", startIndex);
					playerReputation.TotalReputation = (int)ExtractFloat(json, "TotalReputation", startIndex);
					playerReputation.MessageCount = (int)ExtractFloat(json, "MessageCount", startIndex);
					if (playerReputation.PlayerId != 0)
					{
						_playerReputations[playerReputation.PlayerId] = playerReputation;
					}
				}
				catch
				{
				}
				startIndex++;
			}
		}

		private static string F(float v)
		{
			return v.ToString(CultureInfo.InvariantCulture);
		}

		private static string Escape(string s)
		{
			return s?.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") ?? "";
		}

		private static string ExtractString(string json, string field, int startIdx)
		{
			string text = "\"" + field + "\": \"";
			int num = json.IndexOf(text, startIdx);
			if (num < 0 || num > startIdx + 2000)
			{
				return "";
			}
			num += text.Length;
			int num2 = json.IndexOf("\"", num);
			if (num2 < 0)
			{
				return "";
			}
			return json.Substring(num, num2 - num).Replace("\\n", "\n").Replace("\\\"", "\"");
		}

		private static float ExtractFloat(string json, string field, int startIdx)
		{
			string text = "\"" + field + "\": ";
			int num = json.IndexOf(text, startIdx);
			if (num < 0 || num > startIdx + 2000)
			{
				return 0f;
			}
			num += text.Length;
			int i;
			for (i = num; i < json.Length && (char.IsDigit(json[i]) || json[i] == '.' || json[i] == '-' || json[i] == 'E' || json[i] == 'e' || json[i] == '+'); i++)
			{
			}
			float.TryParse(json.Substring(num, i - num), NumberStyles.Float, CultureInfo.InvariantCulture, out var result);
			return result;
		}

		private static string[] ExtractStringArray(string json, string field, int startIdx)
		{
			List<string> list = new List<string>();
			string text = "\"" + field + "\": [";
			int num = json.IndexOf(text, startIdx);
			if (num < 0 || num > startIdx + 2000)
			{
				return list.ToArray();
			}
			num += text.Length;
			int num2 = json.IndexOf("]", num);
			if (num2 < 0)
			{
				return list.ToArray();
			}
			string text2 = json.Substring(num, num2 - num);
			int startIndex = 0;
			while ((startIndex = text2.IndexOf("\"", startIndex)) >= 0)
			{
				int num3 = startIndex + 1;
				int num4 = text2.IndexOf("\"", num3);
				if (num4 > num3)
				{
					list.Add(text2.Substring(num3, num4 - num3));
				}
				startIndex = num4 + 1;
			}
			return list.ToArray();
		}

		private static List<long> ExtractLongArray(string json, string field, int startIdx)
		{
			List<long> list = new List<long>();
			string text = "\"" + field + "\": [";
			int num = json.IndexOf(text, startIdx);
			if (num < 0 || num > startIdx + 2000)
			{
				return list;
			}
			num += text.Length;
			int num2 = json.IndexOf("]", num);
			if (num2 < 0)
			{
				return list;
			}
			string text2 = json.Substring(num, num2 - num);
			string[] array = text2.Split(new char[1] { ',' });
			foreach (string text3 in array)
			{
				if (long.TryParse(text3.Trim(), out var result))
				{
					list.Add(result);
				}
			}
			return list;
		}
	}
	[HarmonyPatch]
	public static class NetworkingPatches
	{
		[CompilerGenerated]
		private sealed class <DelayedLoad>d__2 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
		

plugins/WardInfusion/WardInfusion.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using WardInfusion.Patches;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WardInfusion")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds Ward Essence item to protect individual build pieces like chests, portals, and workstations")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WardInfusion")]
[assembly: AssemblyTitle("WardInfusion")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WardInfusion
{
	public class WardedPiece : MonoBehaviour
	{
		private ZNetView m_nview;

		private Piece m_piece;

		private GameObject m_wardEffect;

		private static GameObject s_wardEffectPrefab;

		private long m_cachedOwner;

		private bool m_cachedActive;

		private List<long> m_cachedPermitted = new List<long>();

		private float m_updateTimer;

		private const float UpdateInterval = 1f;

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_piece = ((Component)this).GetComponent<Piece>();
			if (!((Object)(object)m_nview == (Object)null))
			{
				m_nview.Register<long>("WardInfusion_SetOwner", (Action<long, long>)RPC_SetOwner);
				m_nview.Register<bool>("WardInfusion_SetActive", (Action<long, bool>)RPC_SetActive);
				m_nview.Register<string>("WardInfusion_SetPermitted", (Action<long, string>)RPC_SetPermitted);
				m_nview.Register<long>("WardInfusion_AddPermitted", (Action<long, long>)RPC_AddPermitted);
				m_nview.Register<long>("WardInfusion_RemovePermitted", (Action<long, long>)RPC_RemovePermitted);
			}
		}

		private void Start()
		{
			UpdateCache();
			CreateWardEffect();
			UpdateVisuals();
		}

		private void Update()
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_updateTimer += Time.deltaTime;
				if (m_updateTimer >= 1f)
				{
					m_updateTimer = 0f;
					UpdateCache();
					UpdateVisuals();
				}
			}
		}

		private void UpdateCache()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (zDO == null)
			{
				return;
			}
			m_cachedOwner = zDO.GetLong(WardInfusionPlugin.WardOwnerHash, 0L);
			m_cachedActive = zDO.GetBool(WardInfusionPlugin.WardActiveHash, true);
			string @string = zDO.GetString(WardInfusionPlugin.WardPermittedHash, "");
			m_cachedPermitted.Clear();
			if (string.IsNullOrEmpty(@string))
			{
				return;
			}
			string[] array = @string.Split(new char[1] { ',' });
			foreach (string s in array)
			{
				if (long.TryParse(s, out var result))
				{
					m_cachedPermitted.Add(result);
				}
			}
		}

		private void CreateWardEffect()
		{
			//IL_00a4: 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)
			//IL_00c4: 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)
			if ((Object)(object)s_wardEffectPrefab == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone");
				if ((Object)(object)prefab != (Object)null)
				{
					PrivateArea component = prefab.GetComponent<PrivateArea>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.m_enabledEffect != (Object)null)
					{
						s_wardEffectPrefab = component.m_enabledEffect;
					}
				}
			}
			if ((Object)(object)s_wardEffectPrefab != (Object)null)
			{
				m_wardEffect = Object.Instantiate<GameObject>(s_wardEffectPrefab, ((Component)this).transform);
				m_wardEffect.transform.localPosition = Vector3.up * 0.5f;
				m_wardEffect.transform.localScale = Vector3.one * 0.3f;
			}
		}

		private void UpdateVisuals()
		{
			if ((Object)(object)m_wardEffect != (Object)null)
			{
				bool active = IsWarded() && m_cachedActive;
				m_wardEffect.SetActive(active);
			}
		}

		public bool IsWarded()
		{
			return m_cachedOwner != 0;
		}

		public bool IsWardActive()
		{
			return m_cachedActive;
		}

		public long GetOwner()
		{
			return m_cachedOwner;
		}

		public bool IsOwner(long playerID)
		{
			return m_cachedOwner == playerID;
		}

		public bool IsPermitted(long playerID)
		{
			if (!IsWarded())
			{
				return true;
			}
			if (!m_cachedActive)
			{
				return true;
			}
			if (IsOwner(playerID))
			{
				return true;
			}
			return m_cachedPermitted.Contains(playerID);
		}

		public bool IsLocalPlayerPermitted()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			return IsPermitted(localPlayer.GetPlayerID());
		}

		public List<long> GetPermittedPlayers()
		{
			return new List<long>(m_cachedPermitted);
		}

		public void SetOwner(long playerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.InvokeRPC("WardInfusion_SetOwner", new object[1] { playerID });
			}
		}

		public void InitializeWard(long ownerID, bool active = true)
		{
			if ((Object)(object)m_nview == (Object)null)
			{
				m_nview = ((Component)this).GetComponent<ZNetView>();
			}
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"InitializeWard: No valid ZNetView");
				m_cachedOwner = ownerID;
				m_cachedActive = active;
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (zDO != null)
			{
				zDO.Set(WardInfusionPlugin.WardOwnerHash, ownerID);
				zDO.Set(WardInfusionPlugin.WardActiveHash, active);
				WardInfusionPlugin.Instance.Logger.LogInfo((object)$"InitializeWard: Set owner to {ownerID}, active: {active}");
			}
			m_cachedOwner = ownerID;
			m_cachedActive = active;
			UpdateVisuals();
		}

		public void SetActive(bool active)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.InvokeRPC("WardInfusion_SetActive", new object[1] { active });
			}
		}

		public void AddPermitted(long playerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.InvokeRPC("WardInfusion_AddPermitted", new object[1] { playerID });
			}
		}

		public void RemovePermitted(long playerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
			{
				m_nview.InvokeRPC("WardInfusion_RemovePermitted", new object[1] { playerID });
			}
		}

		public void RemoveWard()
		{
			SetOwner(0L);
			SetActive(active: true);
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
			{
				m_nview.InvokeRPC("WardInfusion_SetPermitted", new object[1] { "" });
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer != (Object)null))
			{
				return;
			}
			GameObject wardEssencePrefab = WardInfusionPlugin.WardEssencePrefab;
			if ((Object)(object)wardEssencePrefab != (Object)null)
			{
				ItemDrop component = wardEssencePrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					((Humanoid)localPlayer).GetInventory().AddItem(wardEssencePrefab, 1);
					((Character)localPlayer).Message((MessageType)1, "Ward Essence returned to inventory", 0, (Sprite)null);
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Returned Ward Essence to player inventory");
				}
			}
		}

		private void RPC_SetOwner(long sender, long ownerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsOwner())
			{
				ZDO zDO = m_nview.GetZDO();
				if (zDO != null)
				{
					zDO.Set(WardInfusionPlugin.WardOwnerHash, ownerID);
					m_cachedOwner = ownerID;
					UpdateVisuals();
				}
			}
		}

		private void RPC_SetActive(long sender, bool active)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsOwner())
			{
				ZDO zDO = m_nview.GetZDO();
				if (zDO != null)
				{
					zDO.Set(WardInfusionPlugin.WardActiveHash, active);
					m_cachedActive = active;
					UpdateVisuals();
				}
			}
		}

		private void RPC_SetPermitted(long sender, string permittedStr)
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsOwner())
			{
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (zDO == null)
			{
				return;
			}
			zDO.Set(WardInfusionPlugin.WardPermittedHash, permittedStr);
			m_cachedPermitted.Clear();
			if (string.IsNullOrEmpty(permittedStr))
			{
				return;
			}
			string[] array = permittedStr.Split(new char[1] { ',' });
			foreach (string s in array)
			{
				if (long.TryParse(s, out var result))
				{
					m_cachedPermitted.Add(result);
				}
			}
		}

		private void RPC_AddPermitted(long sender, long playerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsOwner() && !m_cachedPermitted.Contains(playerID))
			{
				m_cachedPermitted.Add(playerID);
				SavePermitted();
			}
		}

		private void RPC_RemovePermitted(long sender, long playerID)
		{
			if (!((Object)(object)m_nview == (Object)null) && m_nview.IsOwner() && m_cachedPermitted.Remove(playerID))
			{
				SavePermitted();
			}
		}

		private void SavePermitted()
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsOwner())
			{
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (zDO != null)
			{
				string text = string.Join(",", m_cachedPermitted.Select((long id) => id.ToString()));
				zDO.Set(WardInfusionPlugin.WardPermittedHash, text);
			}
		}

		public string GetOwnerName()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			if (!IsWarded() || m_cachedOwner == 0)
			{
				return "None";
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				long playerID = localPlayer.GetPlayerID();
				if (playerID == m_cachedOwner)
				{
					return localPlayer.GetPlayerName();
				}
			}
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				List<PlayerInfo> playerList = ZNet.instance.GetPlayerList();
				if (playerList != null)
				{
					foreach (PlayerInfo item in playerList)
					{
						PlayerInfo current = item;
						ZDOID characterID = current.m_characterID;
						if (((ZDOID)(ref characterID)).UserID == m_cachedOwner)
						{
							return current.m_name;
						}
						if (((ZDOID)(ref current.m_characterID)).ID == m_cachedOwner)
						{
							return current.m_name;
						}
					}
				}
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (allPlayer.GetPlayerID() == m_cachedOwner)
				{
					return allPlayer.GetPlayerName();
				}
			}
			if ((Object)(object)m_piece != (Object)null)
			{
				long creator = m_piece.GetCreator();
				if (creator == m_cachedOwner)
				{
					return "You";
				}
			}
			return "Unknown";
		}

		private void OnDestroy()
		{
			if ((Object)(object)m_wardEffect != (Object)null)
			{
				Object.Destroy((Object)(object)m_wardEffect);
			}
		}
	}
	public class WardHoverable : MonoBehaviour, Hoverable
	{
		private Piece m_piece;

		private Smelter m_smelter;

		private void Awake()
		{
			m_piece = ((Component)this).GetComponentInParent<Piece>();
			m_smelter = ((Component)this).GetComponentInParent<Smelter>();
		}

		public string GetHoverText()
		{
			string text = "";
			text = (((Object)(object)m_piece != (Object)null) ? Localization.instance.Localize(m_piece.m_name) : ((!((Object)(object)m_smelter != (Object)null)) ? ((Object)((Component)this).gameObject).name.Replace("(Clone)", "").Trim() : ((Object)m_smelter).name.Replace("(Clone)", "").Trim()));
			WardedPiece componentInParent = ((Component)this).GetComponentInParent<WardedPiece>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.IsWarded())
			{
				return WardInfusionManager.GetWardedHoverText(componentInParent, text);
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory != null)
				{
					bool flag = false;
					foreach (ItemData allItem in inventory.GetAllItems())
					{
						if (allItem.m_shared.m_name == "Ward Essence" || ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "WardEssence"))
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						return text + "\n[<color=yellow><b>Alt + E</b></color>] Infuse Ward";
					}
				}
			}
			return text;
		}

		public string GetHoverName()
		{
			if ((Object)(object)m_piece != (Object)null)
			{
				return Localization.instance.Localize(m_piece.m_name);
			}
			return ((Object)((Component)this).gameObject).name.Replace("(Clone)", "").Trim();
		}

		public static void AddToPiece(GameObject pieceObj)
		{
			if ((Object)(object)pieceObj == (Object)null)
			{
				return;
			}
			int num = 0;
			Collider component = pieceObj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null && (Object)(object)pieceObj.GetComponent<WardHoverable>() == (Object)null)
			{
				pieceObj.AddComponent<WardHoverable>();
				num++;
			}
			Collider[] componentsInChildren = pieceObj.GetComponentsInChildren<Collider>(true);
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if (!((Object)(object)((Component)val).GetComponent<WardHoverable>() != (Object)null) && !val.isTrigger)
				{
					((Component)val).gameObject.AddComponent<WardHoverable>();
					num++;
				}
			}
			WardInfusionPlugin.Instance.Logger.LogInfo((object)$"WardHoverable: Added {num} components to {((Object)pieceObj).name}");
		}
	}
	public static class WardInfusionManager
	{
		private static bool s_itemRegistered = false;

		private static bool s_recipeRegistered = false;

		private static WardedPiece s_currentWardedPiece;

		public static readonly HashSet<string> WardablePieces = new HashSet<string>
		{
			"piece_chest_wood", "piece_chest", "piece_chest_private", "piece_chest_blackmetal", "portal_wood", "portal", "smelter", "blastfurnace", "charcoal_kiln", "piece_bathtub",
			"piece_workbench", "piece_workbench_ext1", "piece_workbench_ext2", "piece_workbench_ext3", "piece_workbench_ext4", "forge", "forge_ext1", "forge_ext2", "forge_ext3", "forge_ext4",
			"forge_ext5", "forge_ext6", "piece_stonecutter", "piece_artisanstation", "piece_cauldron", "fermenter", "piece_spinningwheel", "windmill", "eitrrefinery", "piece_magetable",
			"piece_cookingstation", "piece_cookingstation_iron", "piece_oven", "piece_beehive", "piece_groundtorch_wood", "piece_brazierceiling01", "blackforge", "blackforge_ext1", "blackforge_ext2"
		};

		public static bool CanBeWarded(GameObject piece)
		{
			if ((Object)(object)piece == (Object)null)
			{
				return false;
			}
			string prefabName = Utils.GetPrefabName(piece);
			string item = prefabName.ToLower();
			bool flag = WardablePieces.Contains(prefabName) || WardablePieces.Contains(item);
			if (!flag && ((Object)(object)piece.GetComponent<Container>() != (Object)null || (Object)(object)piece.GetComponent<TeleportWorld>() != (Object)null || (Object)(object)piece.GetComponent<CraftingStation>() != (Object)null || (Object)(object)piece.GetComponent<Fermenter>() != (Object)null || (Object)(object)piece.GetComponent<Beehive>() != (Object)null || (Object)(object)piece.GetComponent<CookingStation>() != (Object)null || (Object)(object)piece.GetComponent<Smelter>() != (Object)null))
			{
				flag = true;
			}
			return flag;
		}

		public static void RegisterWardEssenceItem(ObjectDB objectDB)
		{
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			if (s_itemRegistered || (Object)(object)objectDB == (Object)null)
			{
				return;
			}
			if (objectDB.m_items == null || objectDB.m_items.Count == 0)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"ObjectDB items not loaded yet, skipping registration");
				return;
			}
			try
			{
				GameObject itemPrefab = objectDB.GetItemPrefab("WardEssence");
				if ((Object)(object)itemPrefab != (Object)null)
				{
					WardInfusionPlugin.WardEssencePrefab = itemPrefab;
					s_itemRegistered = true;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Ward Essence already registered");
					return;
				}
				GameObject itemPrefab2 = objectDB.GetItemPrefab("SurtlingCore");
				if ((Object)(object)itemPrefab2 == (Object)null)
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)"Could not find SurtlingCore");
					return;
				}
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Creating Ward Essence item...");
				bool activeSelf = itemPrefab2.activeSelf;
				itemPrefab2.SetActive(false);
				GameObject val = Object.Instantiate<GameObject>(itemPrefab2);
				((Object)val).name = "WardEssence";
				itemPrefab2.SetActive(activeSelf);
				Object.DontDestroyOnLoad((Object)(object)val);
				ZSyncTransform[] componentsInChildren = val.GetComponentsInChildren<ZSyncTransform>(true);
				foreach (ZSyncTransform val2 in componentsInChildren)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Removed ZSyncTransform components");
				ZNetView component = val.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null)
				{
					FieldInfo field = typeof(ZNetView).GetField("m_prefabName", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(component, "WardEssence");
						WardInfusionPlugin.Instance.Logger.LogInfo((object)"Set ZNetView.m_prefabName to WardEssence");
					}
				}
				ItemDrop component2 = val.GetComponent<ItemDrop>();
				if ((Object)(object)component2 == (Object)null)
				{
					WardInfusionPlugin.Instance.Logger.LogError((object)"ItemDrop component not found!");
					Object.Destroy((Object)(object)val);
					return;
				}
				ItemData itemData = component2.m_itemData;
				itemData.m_shared.m_name = "Ward Essence";
				itemData.m_shared.m_description = "A magical essence that can protect individual build pieces. Hold Alt+E on a chest, portal, workstation, or other interactable piece to ward it.";
				itemData.m_shared.m_itemType = (ItemType)1;
				itemData.m_shared.m_maxStackSize = 50;
				itemData.m_shared.m_weight = 0.5f;
				itemData.m_shared.m_teleportable = true;
				ZNetScene instance = ZNetScene.instance;
				GameObject val3 = ((instance != null) ? instance.GetPrefab("guard_stone") : null);
				if ((Object)(object)val3 != (Object)null)
				{
					Piece component3 = val3.GetComponent<Piece>();
					if ((Object)(object)component3 != (Object)null && (Object)(object)component3.m_icon != (Object)null)
					{
						itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { component3.m_icon };
						WardInfusionPlugin.Instance.Logger.LogInfo((object)"Copied icon from guard_stone");
					}
				}
				itemData.m_dropPrefab = val;
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Ward Essence item configured");
				objectDB.m_items.Add(val);
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name);
				try
				{
					FieldInfo field2 = typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field2 != null && field2.GetValue(objectDB) is Dictionary<int, GameObject> dictionary && !dictionary.ContainsKey(stableHashCode))
					{
						dictionary[stableHashCode] = val;
						WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Added to ObjectDB.m_itemByHash with hash {stableHashCode}");
					}
				}
				catch (Exception ex)
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)("Could not update ObjectDB hash: " + ex.Message));
				}
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					try
					{
						FieldInfo field3 = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic);
						if (field3 != null && field3.GetValue(ZNetScene.instance) is Dictionary<int, GameObject> dictionary2 && !dictionary2.ContainsKey(stableHashCode))
						{
							dictionary2[stableHashCode] = val;
							WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Added to ZNetScene.m_namedPrefabs with hash {stableHashCode}");
						}
					}
					catch (Exception ex2)
					{
						WardInfusionPlugin.Instance.Logger.LogWarning((object)("Could not register with ZNetScene: " + ex2.Message));
					}
				}
				WardInfusionPlugin.WardEssencePrefab = val;
				s_itemRegistered = true;
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Ward Essence item registered successfully!");
			}
			catch (Exception arg)
			{
				WardInfusionPlugin.Instance.Logger.LogError((object)$"Failed to register Ward Essence: {arg}");
			}
		}

		public static void RegisterWardEssenceRecipe(ObjectDB objectDB)
		{
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Expected O, but got Unknown
			if (s_recipeRegistered)
			{
				return;
			}
			if ((Object)(object)objectDB == (Object)null)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"RegisterWardEssenceRecipe: objectDB is null");
				return;
			}
			if ((Object)(object)WardInfusionPlugin.WardEssencePrefab == (Object)null)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"RegisterWardEssenceRecipe: WardEssencePrefab is null - item not registered yet");
				return;
			}
			if (objectDB.m_items == null || objectDB.m_items.Count == 0)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"RegisterWardEssenceRecipe: objectDB.m_items is empty");
				return;
			}
			if (objectDB.m_recipes == null)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"RegisterWardEssenceRecipe: objectDB.m_recipes is null");
				return;
			}
			try
			{
				if ((Object)(object)objectDB.m_recipes.Find((Recipe x) => (Object)(object)x != (Object)null && ((Object)x).name == "Recipe_WardEssence") != (Object)null)
				{
					s_recipeRegistered = true;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Ward Essence recipe already exists");
					return;
				}
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Creating Ward Essence recipe...");
				List<Requirement> list = new List<Requirement>();
				string value = WardInfusionPlugin.WardEssenceRecipe.Value;
				WardInfusionPlugin.Instance.Logger.LogInfo((object)("Recipe string: " + value));
				string[] array = value.Split(new char[1] { ',' });
				foreach (string text in array)
				{
					string[] array2 = text.Trim().Split(new char[1] { ':' });
					if (array2.Length != 2)
					{
						continue;
					}
					string text2 = array2[0].Trim();
					int num = int.Parse(array2[1].Trim());
					GameObject itemPrefab = objectDB.GetItemPrefab(text2);
					if ((Object)(object)itemPrefab != (Object)null)
					{
						ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
						if ((Object)(object)component != (Object)null)
						{
							list.Add(new Requirement
							{
								m_resItem = component,
								m_amount = num,
								m_recover = true
							});
							WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Added ingredient: {text2} x{num}");
						}
					}
					else
					{
						WardInfusionPlugin.Instance.Logger.LogWarning((object)("Recipe item not found: " + text2));
					}
				}
				if (list.Count == 0)
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)"No valid ingredients found for Ward Essence recipe!");
					return;
				}
				Recipe val = ScriptableObject.CreateInstance<Recipe>();
				((Object)val).name = "Recipe_WardEssence";
				val.m_item = WardInfusionPlugin.WardEssencePrefab.GetComponent<ItemDrop>();
				val.m_amount = WardInfusionPlugin.WardEssenceCraftAmount.Value;
				val.m_enabled = true;
				val.m_minStationLevel = 1;
				ZNetScene instance = ZNetScene.instance;
				GameObject val2 = ((instance != null) ? instance.GetPrefab("piece_workbench") : null);
				if ((Object)(object)val2 != (Object)null)
				{
					CraftingStation component2 = val2.GetComponent<CraftingStation>();
					val.m_craftingStation = component2;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Recipe set to require workbench");
				}
				else
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)"Could not find workbench prefab, recipe will be hand-craftable");
				}
				val.m_resources = list.ToArray();
				objectDB.m_recipes.Add(val);
				s_recipeRegistered = true;
				WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Ward Essence recipe registered successfully! Total recipes: {objectDB.m_recipes.Count}");
			}
			catch (Exception arg)
			{
				WardInfusionPlugin.Instance.Logger.LogError((object)$"Failed to register Ward Essence recipe: {arg}");
			}
		}

		public static bool ApplyWardToPiece(Player player, GameObject pieceObj)
		{
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)pieceObj == (Object)null)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"ApplyWardToPiece: player or pieceObj is null");
				return false;
			}
			WardInfusionPlugin.Instance.Logger.LogInfo((object)("ApplyWardToPiece: Trying to ward " + ((Object)pieceObj).name));
			GameObject val = pieceObj;
			TeleportWorld componentInParent = pieceObj.GetComponentInParent<TeleportWorld>();
			Container componentInParent2 = pieceObj.GetComponentInParent<Container>();
			CraftingStation componentInParent3 = pieceObj.GetComponentInParent<CraftingStation>();
			Fermenter componentInParent4 = pieceObj.GetComponentInParent<Fermenter>();
			Beehive componentInParent5 = pieceObj.GetComponentInParent<Beehive>();
			CookingStation componentInParent6 = pieceObj.GetComponentInParent<CookingStation>();
			Smelter componentInParent7 = pieceObj.GetComponentInParent<Smelter>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				val = ((Component)componentInParent).gameObject;
			}
			else if ((Object)(object)componentInParent2 != (Object)null)
			{
				val = ((Component)componentInParent2).gameObject;
			}
			else if ((Object)(object)componentInParent3 != (Object)null)
			{
				val = ((Component)componentInParent3).gameObject;
			}
			else if ((Object)(object)componentInParent4 != (Object)null)
			{
				val = ((Component)componentInParent4).gameObject;
			}
			else if ((Object)(object)componentInParent5 != (Object)null)
			{
				val = ((Component)componentInParent5).gameObject;
			}
			else if ((Object)(object)componentInParent6 != (Object)null)
			{
				val = ((Component)componentInParent6).gameObject;
			}
			else if ((Object)(object)componentInParent7 != (Object)null)
			{
				val = ((Component)componentInParent7).gameObject;
			}
			WardInfusionPlugin.Instance.Logger.LogInfo((object)("ApplyWardToPiece: Target object is " + ((Object)val).name));
			if (!CanBeWarded(val))
			{
				((Character)player).Message((MessageType)2, "Cannot apply ward to this piece.", 0, (Sprite)null);
				return false;
			}
			WardedPiece wardedPiece = val.GetComponent<WardedPiece>();
			if ((Object)(object)wardedPiece != (Object)null && wardedPiece.IsWarded())
			{
				((Character)player).Message((MessageType)2, "This piece is already warded.", 0, (Sprite)null);
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			ItemData val2 = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_shared.m_name == "Ward Essence" || ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "WardEssence"))
				{
					val2 = allItem;
					break;
				}
			}
			if (val2 == null)
			{
				((Character)player).Message((MessageType)2, "You need Ward Essence to ward this piece.", 0, (Sprite)null);
				return false;
			}
			inventory.RemoveItem(val2, 1);
			WardInfusionPlugin.Instance.Logger.LogInfo((object)("ApplyWardToPiece: Removed Ward Essence, applying ward to " + ((Object)val).name));
			if ((Object)(object)wardedPiece == (Object)null)
			{
				wardedPiece = val.AddComponent<WardedPiece>();
			}
			long playerID = player.GetPlayerID();
			WardInfusionPlugin.Instance.Logger.LogInfo((object)$"ApplyWardToPiece: Setting owner to {playerID} ({player.GetPlayerName()})");
			wardedPiece.InitializeWard(playerID);
			((Character)player).Message((MessageType)2, "Ward applied!", 0, (Sprite)null);
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("vfx_Place_stone_wall_2x1");
				if ((Object)(object)prefab != (Object)null)
				{
					Object.Instantiate<GameObject>(prefab, pieceObj.transform.position, Quaternion.identity);
				}
			}
			return true;
		}

		public static void ShowWardUI(WardedPiece wardedPiece)
		{
			s_currentWardedPiece = wardedPiece;
			if ((Object)(object)wardedPiece == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			long playerID = localPlayer.GetPlayerID();
			bool flag = wardedPiece.IsOwner(playerID);
			bool flag2 = wardedPiece.IsWardActive();
			string ownerName = wardedPiece.GetOwnerName();
			string text = (flag2 ? "Active" : "Inactive");
			if (flag)
			{
				string text2 = "Owner: " + ownerName + "\nStatus: " + text + "\n\n[1] " + (flag2 ? "Deactivate Ward" : "Activate Ward") + "\n[2] Remove Ward";
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)2, text2, 0, (Sprite)null, false);
				}
			}
			else if (!flag2)
			{
				bool flag3 = wardedPiece.IsPermitted(playerID);
				string text3 = "Owner: " + ownerName + "\nStatus: " + text + "\n\n[1] " + (flag3 ? "Remove Yourself" : "Add Yourself");
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)2, text3, 0, (Sprite)null, false);
				}
			}
			else
			{
				string text4 = "Owner: " + ownerName + "\nStatus: " + text + "\n\nWard is active. Ask owner to deactivate.";
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)2, text4, 0, (Sprite)null, false);
				}
			}
		}

		public static void HandleWardUIInput(int key)
		{
			if ((Object)(object)s_currentWardedPiece == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			long playerID = localPlayer.GetPlayerID();
			bool flag = s_currentWardedPiece.IsOwner(playerID);
			bool flag2 = s_currentWardedPiece.IsWardActive();
			if (flag)
			{
				switch (key)
				{
				case 1:
					s_currentWardedPiece.SetActive(!flag2);
					((Character)localPlayer).Message((MessageType)2, flag2 ? "Ward deactivated." : "Ward activated!", 0, (Sprite)null);
					break;
				case 2:
					s_currentWardedPiece.RemoveWard();
					((Character)localPlayer).Message((MessageType)2, "Ward removed.", 0, (Sprite)null);
					break;
				}
			}
			else if (!flag2 && key == 1)
			{
				if (s_currentWardedPiece.IsPermitted(playerID))
				{
					s_currentWardedPiece.RemovePermitted(playerID);
					((Character)localPlayer).Message((MessageType)2, "You have been removed from this ward.", 0, (Sprite)null);
				}
				else
				{
					s_currentWardedPiece.AddPermitted(playerID);
					((Character)localPlayer).Message((MessageType)2, "You have been added to this ward.", 0, (Sprite)null);
				}
			}
			s_currentWardedPiece = null;
		}

		public static string GetWardedHoverText(WardedPiece wardedPiece, string originalText)
		{
			if ((Object)(object)wardedPiece == (Object)null || !wardedPiece.IsWarded())
			{
				return originalText;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return originalText;
			}
			string ownerName = wardedPiece.GetOwnerName();
			bool flag = wardedPiece.IsOwner(localPlayer.GetPlayerID());
			bool flag2 = wardedPiece.IsLocalPlayerPermitted();
			bool flag3 = wardedPiece.IsWardActive();
			string text = (flag3 ? "<color=green>Active</color>" : "<color=yellow>Inactive</color>");
			string text2 = "\n<color=#00FFFF>[Warded]</color> " + text;
			text2 = text2 + "\nOwner: " + ownerName;
			if (flag || !flag3)
			{
				text2 += "\n<color=yellow>[Alt+E]</color> Manage Ward";
			}
			if (!flag2 && flag3)
			{
				text2 += "\n<color=red>No Access</color>";
			}
			return originalText + text2;
		}
	}
	[BepInPlugin("com.wardinfusion.valheim", "WardInfusion", "1.0.42")]
	public class WardInfusionPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.wardinfusion.valheim";

		public const string PluginName = "WardInfusion";

		public const string PluginVersion = "1.0.42";

		private static WardInfusionPlugin _instance;

		private Harmony _harmony;

		public static ConfigEntry<string> WardEssenceRecipe;

		public static ConfigEntry<int> WardEssenceCraftAmount;

		public static GameObject WardEssencePrefab;

		public static ItemData WardEssenceItem;

		public static readonly int WardOwnerHash = StringExtensionMethods.GetStableHashCode("WardInfusion_Owner");

		public static readonly int WardActiveHash = StringExtensionMethods.GetStableHashCode("WardInfusion_Active");

		public static readonly int WardPermittedHash = StringExtensionMethods.GetStableHashCode("WardInfusion_Permitted");

		public static WardInfusionPlugin Instance => _instance;

		public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			_instance = this;
			WardEssenceRecipe = ((BaseUnityPlugin)this).Config.Bind<string>("General", "WardEssenceRecipe", "FineWood:5,SurtlingCore:1,GreydwarfEye:5", "Recipe for Ward Essence (format: item:amount,item:amount)");
			WardEssenceCraftAmount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "WardEssenceCraftAmount", 1, "Amount of Ward Essence crafted per recipe");
			_harmony = new Harmony("com.wardinfusion.valheim");
			try
			{
				SafePatcher.ApplyPatches(_harmony);
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Failed to apply patches: {arg}");
			}
			Logger.LogInfo((object)"WardInfusion v1.0.42 loaded!");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace WardInfusion.Patches
{
	public static class SafePatcher
	{
		private static bool s_lateRegistrationDone;

		private static float s_lastInteractTime;

		private static bool s_waitingForInput;

		private static WardedPiece s_targetWard;

		public static void ApplyPatches(Harmony harmony)
		{
			TryPatch(harmony, typeof(ObjectDB), "Awake", null, typeof(SafePatcher).GetMethod("ObjectDB_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Game), "Start", null, typeof(SafePatcher).GetMethod("Game_Start_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Player), "OnSpawned", null, typeof(SafePatcher).GetMethod("Player_OnSpawned_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Player), "Update", null, typeof(SafePatcher).GetMethod("Player_Update_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatchInteract(harmony, typeof(Container), "Container_Interact_Prefix");
			TryPatchInteract(harmony, typeof(TeleportWorld), "TeleportWorld_Interact_Prefix");
			TryPatchInteract(harmony, typeof(Fermenter), "Fermenter_Interact_Prefix");
			TryPatchInteract(harmony, typeof(Beehive), "Beehive_Interact_Prefix");
			TryPatchInteract(harmony, typeof(CraftingStation), "CraftingStation_Interact_Prefix");
			TryPatchInteract(harmony, typeof(CookingStation), "CookingStation_Interact_Prefix");
			TryPatch(harmony, typeof(ItemDrop), "DropItem", typeof(SafePatcher).GetMethod("ItemDrop_DropItem_Prefix", BindingFlags.Static | BindingFlags.Public), null);
			TryPatchHoverText(harmony, typeof(Container), "Container_GetHoverText_Postfix");
			TryPatchHoverText(harmony, typeof(TeleportWorld), "TeleportWorld_GetHoverText_Postfix");
			TryPatchHoverText(harmony, typeof(Fermenter), "Fermenter_GetHoverText_Postfix");
			TryPatchHoverText(harmony, typeof(Beehive), "Beehive_GetHoverText_Postfix");
			TryPatchHoverText(harmony, typeof(CraftingStation), "CraftingStation_GetHoverText_Postfix");
			TryPatchHoverText(harmony, typeof(CookingStation), "CookingStation_GetHoverText_Postfix");
			TryPatch(harmony, typeof(Smelter), "Awake", null, typeof(SafePatcher).GetMethod("Smelter_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Container), "Awake", null, typeof(SafePatcher).GetMethod("Container_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(TeleportWorld), "Awake", null, typeof(SafePatcher).GetMethod("TeleportWorld_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(CraftingStation), "Awake", null, typeof(SafePatcher).GetMethod("CraftingStation_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Fermenter), "Awake", null, typeof(SafePatcher).GetMethod("Fermenter_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(Beehive), "Awake", null, typeof(SafePatcher).GetMethod("Beehive_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
			TryPatch(harmony, typeof(CookingStation), "Awake", null, typeof(SafePatcher).GetMethod("CookingStation_Awake_Postfix", BindingFlags.Static | BindingFlags.Public));
		}

		private static void TryPatch(Harmony harmony, Type targetType, string methodName, MethodInfo prefix, MethodInfo postfix)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					object obj = harmony;
					obj = methodInfo;
					obj = (object)((!(prefix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(prefix));
					obj = (object)((!(postfix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(postfix));
					((Harmony)obj).Patch((MethodBase)obj, (HarmonyMethod)obj, (HarmonyMethod)obj, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					WardInfusionPlugin.Instance.Logger.LogInfo((object)("Patched " + targetType.Name + "." + methodName));
				}
				else
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)("Method not found: " + targetType.Name + "." + methodName));
				}
			}
			catch (Exception ex)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)("Failed to patch " + targetType.Name + "." + methodName + ": " + ex.Message));
			}
		}

		private static void TryPatchInteract(Harmony harmony, Type targetType, string prefixMethodName)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			try
			{
				MethodInfo[] methods = targetType.GetMethods(BindingFlags.Instance | BindingFlags.Public);
				MethodInfo methodInfo = null;
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo2 in array)
				{
					if (methodInfo2.Name == "Interact")
					{
						methodInfo = methodInfo2;
						break;
					}
				}
				if (methodInfo != null)
				{
					MethodInfo method = typeof(SafePatcher).GetMethod(prefixMethodName, BindingFlags.Static | BindingFlags.Public);
					if (method != null)
					{
						harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						WardInfusionPlugin.Instance.Logger.LogInfo((object)("Patched " + targetType.Name + ".Interact"));
					}
				}
				else
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)("Interact method not found on " + targetType.Name));
				}
			}
			catch (Exception ex)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)("Failed to patch " + targetType.Name + ".Interact: " + ex.Message));
			}
		}

		private static void TryPatchHoverText(Harmony harmony, Type targetType, string postfixMethodName)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(targetType, "GetHoverText", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					MethodInfo method = typeof(SafePatcher).GetMethod(postfixMethodName, BindingFlags.Static | BindingFlags.Public);
					if (method != null)
					{
						harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
				}
			}
			catch (Exception ex)
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)("Failed to patch " + targetType.Name + ".GetHoverText: " + ex.Message));
			}
		}

		public static void ObjectDB_Awake_Postfix(ObjectDB __instance)
		{
			WardInfusionPlugin.Instance.Logger.LogInfo((object)"ObjectDB.Awake called");
			TryRegisterItems(__instance, "ObjectDB.Awake");
		}

		public static void Game_Start_Postfix()
		{
			WardInfusionPlugin.Instance.Logger.LogInfo((object)"Game.Start called - attempting registration");
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				TryRegisterItems(ObjectDB.instance, "Game.Start");
			}
			else
			{
				WardInfusionPlugin.Instance.Logger.LogWarning((object)"Game.Start: ObjectDB.instance is null");
			}
			if ((Object)(object)WardInfusionPlugin.WardEssencePrefab != (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				EnsureZNetSceneRegistration();
			}
		}

		private static void EnsureZNetSceneRegistration()
		{
			try
			{
				GameObject wardEssencePrefab = WardInfusionPlugin.WardEssencePrefab;
				if ((Object)(object)wardEssencePrefab == (Object)null)
				{
					return;
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)wardEssencePrefab).name);
				FieldInfo field = typeof(ObjectDB).GetField("m_itemByHash", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null && (Object)(object)ObjectDB.instance != (Object)null && field.GetValue(ObjectDB.instance) is Dictionary<int, GameObject> dictionary && !dictionary.ContainsKey(stableHashCode))
				{
					dictionary[stableHashCode] = wardEssencePrefab;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Added Ward Essence to ObjectDB.m_itemByHash (hash: {stableHashCode})");
				}
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					FieldInfo field2 = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field2 != null && field2.GetValue(ZNetScene.instance) is Dictionary<int, GameObject> dictionary2 && !dictionary2.ContainsKey(stableHashCode))
					{
						dictionary2[stableHashCode] = wardEssencePrefab;
						WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Added Ward Essence to ZNetScene.m_namedPrefabs (hash: {stableHashCode})");
					}
				}
				ItemDrop component = wardEssencePrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_itemData.m_dropPrefab = wardEssencePrefab;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Set dropPrefab to WardEssence");
				}
			}
			catch (Exception arg)
			{
				WardInfusionPlugin.Instance.Logger.LogError((object)$"EnsureZNetSceneRegistration failed: {arg}");
			}
		}

		public static void Player_OnSpawned_Postfix()
		{
			if (!s_lateRegistrationDone)
			{
				WardInfusionPlugin.Instance.Logger.LogInfo((object)"Player.OnSpawned - final registration attempt");
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					TryRegisterItems(ObjectDB.instance, "Player.OnSpawned");
					s_lateRegistrationDone = true;
				}
				else
				{
					WardInfusionPlugin.Instance.Logger.LogWarning((object)"Player.OnSpawned: ObjectDB.instance is null");
				}
			}
		}

		public static void ItemDrop_DropItem_Prefix(ItemData item, int amount, Vector3 position, Quaternion rotation)
		{
			if (item != null && (item.m_shared.m_name == "Ward Essence" || ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "WardEssence")) && (Object)(object)item.m_dropPrefab == (Object)null)
			{
				GameObject wardEssencePrefab = WardInfusionPlugin.WardEssencePrefab;
				if ((Object)(object)wardEssencePrefab != (Object)null)
				{
					item.m_dropPrefab = wardEssencePrefab;
					WardInfusionPlugin.Instance.Logger.LogInfo((object)"Fixed Ward Essence dropPrefab");
				}
			}
		}

		public static void Smelter_Awake_Postfix(Smelter __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				WardHoverable.AddToPiece(((Component)__instance).gameObject);
				WardInfusionPlugin.Instance.Logger.LogInfo((object)("Added WardHoverable to Smelter: " + ((Object)((Component)__instance).gameObject).name));
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void Container_Awake_Postfix(Container __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void TeleportWorld_Awake_Postfix(TeleportWorld __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void CraftingStation_Awake_Postfix(CraftingStation __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void Fermenter_Awake_Postfix(Fermenter __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void Beehive_Awake_Postfix(Beehive __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		public static void CookingStation_Awake_Postfix(CookingStation __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				TryRestoreWard(((Component)__instance).gameObject);
			}
		}

		private static void TryRestoreWard(GameObject pieceObj)
		{
			if ((Object)(object)pieceObj == (Object)null || (Object)(object)pieceObj.GetComponent<WardedPiece>() != (Object)null)
			{
				return;
			}
			ZNetView component = pieceObj.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				long @long = zDO.GetLong(WardInfusionPlugin.WardOwnerHash, 0L);
				if (@long != 0)
				{
					WardedPiece wardedPiece = pieceObj.AddComponent<WardedPiece>();
					WardInfusionPlugin.Instance.Logger.LogInfo((object)$"Restored ward on {((Object)pieceObj).name} (Owner: {@long})");
				}
			}
		}

		private static void TryRegisterItems(ObjectDB objectDB, string source)
		{
			try
			{
				WardInfusionPlugin.Instance.Logger.LogInfo((object)("[" + source + "] Attempting item registration..."));
				WardInfusionPlugin.Instance.Logger.LogInfo((object)$"[{source}] ObjectDB.m_items count: {objectDB.m_items?.Count ?? (-1)}");
				WardInfusionManager.RegisterWardEssenceItem(objectDB);
				WardInfusionManager.RegisterWardEssenceRecipe(objectDB);
			}
			catch (Exception arg)
			{
				WardInfusionPlugin.Instance.Logger.LogError((object)$"[{source}] Registration failed: {arg}");
			}
		}

		public static void Player_Update_Postfix(Player __instance)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (Input.GetKey((KeyCode)308) && Input.GetKeyDown((KeyCode)101))
			{
				GameObject hoverObject = ((Humanoid)__instance).GetHoverObject();
				GameObject val = null;
				if ((Object)(object)hoverObject != (Object)null)
				{
					Smelter componentInParent = hoverObject.GetComponentInParent<Smelter>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						val = ((Component)componentInParent).gameObject;
					}
					else
					{
						Piece componentInParent2 = hoverObject.GetComponentInParent<Piece>();
						if ((Object)(object)componentInParent2 != (Object)null)
						{
							val = ((Component)componentInParent2).gameObject;
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Camera main = Camera.main;
					if ((Object)(object)main != (Object)null)
					{
						Ray val2 = main.ScreenPointToRay(new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f, 0f));
						RaycastHit[] array = Physics.RaycastAll(val2, 50f);
						Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
						RaycastHit[] array2 = array;
						for (int i = 0; i < array2.Length; i++)
						{
							RaycastHit val3 = array2[i];
							if (!((Object)(object)((Component)((RaycastHit)(ref val3)).collider).gameObject.GetComponent<Heightmap>() != (Object)null) && ((Component)((RaycastHit)(ref val3)).collider).gameObject.layer != 8)
							{
								Smelter componentInParent3 = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Smelter>();
								if ((Object)(object)componentInParent3 != (Object)null)
								{
									val = ((Component)componentInParent3).gameObject;
									break;
								}
								Piece componentInParent4 = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent<Piece>();
								if ((Object)(object)componentInParent4 != (Object)null && WardInfusionManager.CanBeWarded(((Component)componentInParent4).gameObject))
								{
									val = ((Component)componentInParent4).gameObject;
									break;
								}
							}
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					WardedPiece wardedPiece = val.GetComponent<WardedPiece>();
					if ((Object)(object)wardedPiece == (Object)null)
					{
						wardedPiece = val.GetComponentInParent<WardedPiece>();
					}
					if ((Object)(object)wardedPiece != (Object)null && wardedPiece.IsWarded())
					{
						s_targetWard = wardedPiece;
						s_waitingForInput = true;
						s_lastInteractTime = Time.time;
						WardInfusionManager.ShowWardUI(wardedPiece);
					}
					else
					{
						Inventory inventory = ((Humanoid)__instance).GetInventory();
						if (inventory != null)
						{
							bool flag = false;
							foreach (ItemData allItem in inventory.GetAllItems())
							{
								if (allItem.m_shared.m_name == "Ward Essence" || ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "WardEssence"))
								{
									flag = true;
									break;
								}
							}
							if (flag)
							{
								WardInfusionManager.ApplyWardToPiece(__instance, val);
							}
						}
					}
				}
			}
			if (s_waitingForInput && (Object)(object)s_targetWard != (Object)null)
			{
				if (Time.time - s_lastInteractTime > 5f)
				{
					s_waitingForInput = false;
					s_targetWard = null;
				}
				else if (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257))
				{
					WardInfusionManager.HandleWardUIInput(1);
					s_waitingForInput = false;
					s_targetWard = null;
				}
				else if (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258))
				{
					WardInfusionManager.HandleWardUIInput(2);
					s_waitingForInput = false;
					s_targetWard = null;
				}
				else if (Input.GetKeyDown((KeyCode)27))
				{
					s_waitingForInput = false;
					s_targetWard = null;
				}
			}
		}

		public static bool Container_Interact_Prefix(Container __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		public static bool TeleportWorld_Interact_Prefix(TeleportWorld __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		public static bool Fermenter_Interact_Prefix(Fermenter __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		public static bool Beehive_Interact_Prefix(Beehive __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		public static bool CraftingStation_Interact_Prefix(CraftingStation __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		public static bool CookingStation_Interact_Prefix(CookingStation __instance, ref bool __result)
		{
			if (TryApplyWardFromInteract(((Component)__instance).gameObject, ref __result))
			{
				return false;
			}
			return CheckWardPermission(((Component)__instance).gameObject, ref __result);
		}

		private static bool TryApplyWardFromInteract(GameObject obj, ref bool result)
		{
			if (!Input.GetKey((KeyCode)308))
			{
				return false;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (inventory == null)
			{
				return false;
			}
			ItemData val = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_shared.m_name == "Ward Essence" || ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "WardEssence"))
				{
					val = allItem;
					break;
				}
			}
			if (val != null)
			{
				bool flag = WardInfusionManager.ApplyWardToPiece(localPlayer, obj);
				result = flag;
				return true;
			}
			return false;
		}

		private static bool CheckWardPermission(GameObject obj, ref bool result)
		{
			WardedPiece wardedPiece = obj.GetComponent<WardedPiece>();
			if ((Object)(object)wardedPiece == (Object)null)
			{
				wardedPiece = obj.GetComponentInParent<WardedPiece>();
			}
			if ((Object)(object)wardedPiece != (Object)null && wardedPiece.IsWarded() && !wardedPiece.IsLocalPlayerPermitted())
			{
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, "You are not permitted to use this.", 0, (Sprite)null);
				}
				result = false;
				return false;
			}
			return true;
		}

		public static void Container_GetHoverText_Postfix(Container __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		public static void TeleportWorld_GetHoverText_Postfix(TeleportWorld __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		public static void Fermenter_GetHoverText_Postfix(Fermenter __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		public static void Beehive_GetHoverText_Postfix(Beehive __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		public static void CraftingStation_GetHoverText_Postfix(CraftingStation __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		public static void CookingStation_GetHoverText_Postfix(CookingStation __instance, ref string __result)
		{
			AddWardedHoverText(((Component)__instance).gameObject, ref __result);
		}

		private static void AddWardedHoverText(GameObject obj, ref string result)
		{
			WardedPiece wardedPiece = obj.GetComponent<WardedPiece>();
			if ((Object)(object)wardedPiece == (Object)null)
			{
				wardedPiece = obj.GetComponentInParent<WardedPiece>();
			}
			if ((Object)(object)wardedPiece != (Object)null && wardedPiece.IsWarded())
			{
				result = WardInfusionManager.GetWardedHoverText(wardedPiece, result);
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer != (Object)null) || !WardInfusionManager.CanBeWarded(obj))
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (inventory == null)
			{
				return;
			}
			bool flag = false;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_shared.m_name == "Ward Essence" || ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "WardEssence"))
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				result += "\n[<color=yellow><b>Alt + E</b></color>] Infuse Ward";
			}
		}
	}
}