Decompiled source of AuroraEasterEvent v1.0.8

plugins/AuroraEasterEvent.dll

Decompiled a week ago
using System;
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 BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("aurora")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Seasonal Easter event mod for Valheim - Egg Hunt of Idunn")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AuroraEasterEvent")]
[assembly: AssemblyTitle("AuroraEasterEvent")]
[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 AuroraEasterEvent
{
	public static class EggConfig
	{
		public static ConfigEntry<float> PaintedEggDropRate;

		public static ConfigEntry<float> SilverEggDropRate;

		public static ConfigEntry<float> GoldenEggDropRate;

		public static ConfigEntry<float> NestSpawnChance;

		public static ConfigEntry<int> NestMaxPerZone;

		public static ConfigEntry<bool> AnnounceGoldenEggs;

		public static void Initialize(ConfigFile config)
		{
			PaintedEggDropRate = config.Bind<float>("Drops", "PaintedEggDropRate", 25f, "Percent chance for Painted Egg to drop from monsters (Meadows/BlackForest)");
			SilverEggDropRate = config.Bind<float>("Drops", "SilverEggDropRate", 15f, "Percent chance for Silver Egg to drop from monsters (Swamp/Mountain)");
			GoldenEggDropRate = config.Bind<float>("Drops", "GoldenEggDropRate", 5f, "Percent chance for Golden Egg to drop from monsters (Plains/Mistlands/Ashlands)");
			NestSpawnChance = config.Bind<float>("Nests", "NestSpawnChance", 0.15f, "Chance per zone for an egg nest to spawn (0.0-1.0)");
			NestMaxPerZone = config.Bind<int>("Nests", "NestMaxPerZone", 1, "Maximum egg nests per zone");
			AnnounceGoldenEggs = config.Bind<bool>("General", "AnnounceGoldenEggs", true, "Broadcast server message when a player finds a Golden Egg");
		}
	}
	[HarmonyPatch]
	public static class EggDrops
	{
		private static readonly Dictionary<int, long> _lastAttackers = new Dictionary<int, long>();

		[HarmonyPatch(typeof(Character), "RPC_Damage")]
		[HarmonyPostfix]
		public static void TrackAttacker(Character __instance, HitData hit)
		{
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)null) && hit != null && !__instance.IsPlayer() && hit.m_attacker != ZDOID.None)
			{
				ZNetScene instance = ZNetScene.instance;
				GameObject obj = ((instance != null) ? instance.FindInstance(hit.m_attacker) : null);
				Player val = ((obj != null) ? obj.GetComponent<Player>() : null);
				if ((Object)(object)val != (Object)null)
				{
					_lastAttackers[((Object)__instance).GetInstanceID()] = val.GetPlayerID();
				}
			}
		}

		[HarmonyPatch(typeof(Character), "OnDeath")]
		[HarmonyPostfix]
		public static void OnMonsterDeath(Character __instance)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || __instance.IsPlayer())
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (_lastAttackers.TryGetValue(instanceID, out var value))
			{
				_lastAttackers.Remove(instanceID);
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && localPlayer.GetPlayerID() == value)
				{
					ProcessEggDrop(localPlayer, ((Component)__instance).transform.position);
				}
			}
		}

		public static void ProcessEggDrop(Player player, Vector3 monsterPos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000f: 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_0015: 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_001b: 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_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)
			//IL_0054: 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_0059: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: 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)
			Biome val = Heightmap.FindBiome(monsterPos);
			int num = -1;
			float num2 = 0f;
			if ((val & 0x20) != 0 || (val & 0x40) != 0 || (val & 0x200) != 0)
			{
				num = 2;
				num2 = EggConfig.GoldenEggDropRate.Value / 100f;
			}
			else if ((val & 0x10) != 0)
			{
				num = 2;
				num2 = EggConfig.GoldenEggDropRate.Value / 100f;
			}
			else if ((val & 4) != 0 || (val & 2) != 0)
			{
				num = 1;
				num2 = EggConfig.SilverEggDropRate.Value / 100f;
			}
			else if ((val & 8) != 0 || (val & 1) != 0)
			{
				num = 0;
				num2 = EggConfig.PaintedEggDropRate.Value / 100f;
			}
			else
			{
				num = 0;
				num2 = EggConfig.PaintedEggDropRate.Value / 200f;
			}
			if (num < 0 || Random.value > num2)
			{
				return;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			GameObject eggPrefab = EggItems.GetEggPrefab(num);
			if ((Object)(object)eggPrefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)$"EggDrops: Egg prefab null for tier {num}");
				return;
			}
			if (((inventory != null) ? new bool?(inventory.AddItem(eggPrefab, 1)) : null).HasValue)
			{
				string text = EggItems.DisplayNames[num];
				string text2 = num switch
				{
					1 => "#c0c0ff", 
					0 => "#88ff88", 
					_ => "#ffd700", 
				};
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)1, "<color=" + text2 + ">You found a " + text + "!</color>", 0, (Sprite)null, false);
				}
				EggRPC.Instance?.ReportEggFound(player.GetPlayerID(), player.GetPlayerName(), num);
				Plugin.Log.LogInfo((object)$"EggDrop: {player.GetPlayerName()} found {text} in {val}");
				if (num != 2 || !EggConfig.AnnounceGoldenEggs.Value)
				{
					return;
				}
				string playerName = player.GetPlayerName();
				string text3 = "<color=#ffd700>" + playerName + " found a Golden Egg! The gods smile upon them!</color>";
				{
					foreach (Player allPlayer in Player.GetAllPlayers())
					{
						((Character)allPlayer).Message((MessageType)2, text3, 0, (Sprite)null);
					}
					return;
				}
			}
			try
			{
				Object.Instantiate<GameObject>(eggPrefab, ((Component)player).transform.position + Vector3.up * 0.5f, Quaternion.identity).SetActive(true);
				MessageHud instance2 = MessageHud.instance;
				if (instance2 != null)
				{
					instance2.ShowMessage((MessageType)1, "<color=#ffaa00>An egg dropped on the ground! (inventory full)</color>", 0, (Sprite)null, false);
				}
			}
			catch
			{
			}
		}
	}
	public class EggHUD : MonoBehaviour
	{
		private GUIStyle _bgStyle;

		private GUIStyle _titleStyle;

		private GUIStyle _labelStyle;

		private GUIStyle _countStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _medalStyle;

		private GUIStyle _hintStyle;

		private Texture2D _bgTex;

		private Texture2D _borderTex;

		private Texture2D _accentTex;

		private Texture2D _headerBgTex;

		private bool _stylesInit;

		private bool _expanded;

		public static EggHUD Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)8))
			{
				bool flag = false;
				try
				{
					flag = (Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus();
				}
				catch
				{
				}
				if (!flag && !Console.IsVisible() && !TextInput.IsVisible())
				{
					_expanded = !_expanded;
				}
			}
		}

		private void InitStyles()
		{
			//IL_001f: 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_0069: 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_00a8: 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_00c3: Expected O, but got Unknown
			//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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_011f: 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_012c: 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)
			//IL_013a: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_01a8: Expected O, but got Unknown
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Expected O, but got Unknown
			//IL_01f5: 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_0202: 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_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Expected O, but got Unknown
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: 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_0253: 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_0277: Expected O, but got Unknown
			if (!_stylesInit)
			{
				_bgTex = MakeTex(new Color(0.05f, 0.04f, 0.02f, 0.88f));
				_borderTex = MakeTex(new Color(0.72f, 0.58f, 0.22f, 0.8f));
				_accentTex = MakeTex(new Color(0.72f, 0.58f, 0.22f, 0.15f));
				_headerBgTex = MakeTex(new Color(0.12f, 0.1f, 0.05f, 0.95f));
				GUIStyle val = new GUIStyle(GUI.skin.box);
				val.normal.background = _bgTex;
				_bgStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					richText = true
				};
				val2.normal.textColor = new Color(1f, 0.84f, 0f);
				_titleStyle = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					richText = true
				};
				val3.normal.textColor = new Color(0.9f, 0.75f, 0.35f);
				_headerStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					richText = true
				};
				val4.normal.textColor = new Color(0.9f, 0.85f, 0.7f);
				_labelStyle = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)5,
					richText = true
				};
				val5.normal.textColor = Color.white;
				_countStyle = val5;
				GUIStyle val6 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					richText = true
				};
				val6.normal.textColor = new Color(0.9f, 0.85f, 0.7f);
				_medalStyle = val6;
				GUIStyle val7 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 10,
					fontStyle = (FontStyle)2,
					alignment = (TextAnchor)4
				};
				val7.normal.textColor = new Color(0.55f, 0.5f, 0.38f);
				_hintStyle = val7;
				_stylesInit = true;
			}
		}

		private Texture2D MakeTex(Color color)
		{
			//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_000f: 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_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private void DrawBorder(Rect rect, int thickness)
		{
			//IL_0017: 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_0068: 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)
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, (float)thickness), (Texture)(object)_borderTex);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - (float)thickness, ((Rect)(ref rect)).width, (float)thickness), (Texture)(object)_borderTex);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, (float)thickness, ((Rect)(ref rect)).height), (Texture)(object)_borderTex);
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - (float)thickness, ((Rect)(ref rect)).y, (float)thickness, ((Rect)(ref rect)).height), (Texture)(object)_borderTex);
		}

		private void OnGUI()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_00a3: 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_00d8: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: 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_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: 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_0551: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || ((Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2) || InventoryGui.IsVisible() || Hud.IsPieceSelectionVisible())
			{
				return;
			}
			if (_stylesInit && ((Object)(object)_bgTex == (Object)null || (Object)(object)_borderTex == (Object)null))
			{
				_stylesInit = false;
			}
			InitStyles();
			float num = 190f;
			float num2 = (float)Screen.width - num - 230f;
			float num3 = 10f;
			if (!_expanded)
			{
				float num4 = 36f;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(num2, num3, num, num4);
				GUI.Box(val, "", _bgStyle);
				DrawBorder(val, 2);
				GUI.DrawTexture(new Rect(num2 + 2f, num3 + 2f, num - 4f, 18f), (Texture)(object)_headerBgTex);
				GUI.Label(new Rect(num2, num3 + 2f, num, 18f), "Egg Hunt of Idunn", _titleStyle);
				GUI.Label(new Rect(num2, num3 + 21f, num, 14f), "[Backspace] to expand", _hintStyle);
				return;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			int[] array = new int[3];
			if (inventory != null)
			{
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					string text = allItem.m_shared?.m_name ?? "";
					for (int i = 0; i < 3; i++)
					{
						if (text == $"$aurora_egg_{i}")
						{
							array[i] += allItem.m_stack;
						}
					}
				}
			}
			List<PlayerEggStats> leaderboard = EggStats.GetLeaderboard();
			int num5 = Mathf.Min(leaderboard.Count, 5);
			float num6 = 70f;
			float num7 = 24 + Mathf.Max(num5, 1) * 20 + 4;
			float num8 = 28f + num6 + 4f + num7 + 4f;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num2, num3, num, num8);
			GUI.Box(val2, "", _bgStyle);
			DrawBorder(val2, 2);
			GUI.DrawTexture(new Rect(num2 + 2f, num3 + 2f, num - 4f, 22f), (Texture)(object)_headerBgTex);
			GUI.Label(new Rect(num2, num3 + 3f, num, 20f), "Egg Hunt of Idunn", _titleStyle);
			GUI.DrawTexture(new Rect(num2 + 8f, num3 + 25f, num - 16f, 1f), (Texture)(object)_borderTex);
			num3 += 28f;
			string[] array2 = new string[3] { "#88ff88", "#c0c0ff", "#ffd700" };
			string[] array3 = new string[3] { "Painted", "Silver", "Golden" };
			for (int j = 0; j < 3; j++)
			{
				float num9 = num3 + (float)(j * 20);
				GUI.Label(new Rect(num2 + 12f, num9, 100f, 20f), "<color=" + array2[j] + ">" + array3[j] + "</color>", _labelStyle);
				GUI.Label(new Rect(num2 + num - 50f, num9, 38f, 20f), $"<color={array2[j]}>x{array[j]}</color>", _countStyle);
			}
			num3 += num6;
			GUI.DrawTexture(new Rect(num2 + 8f, num3 - 6f, num - 16f, 1f), (Texture)(object)_borderTex);
			GUI.DrawTexture(new Rect(num2 + 2f, num3, num - 4f, 20f), (Texture)(object)_headerBgTex);
			GUI.Label(new Rect(num2, num3 + 1f, num, 18f), "Top Egg Hunters", _headerStyle);
			num3 += 22f;
			if (num5 == 0)
			{
				GUI.Label(new Rect(num2, num3, num, 18f), "No eggs found yet", _hintStyle);
				return;
			}
			for (int k = 0; k < num5; k++)
			{
				PlayerEggStats playerEggStats = leaderboard[k];
				float num10 = num3 + (float)(k * 20);
				int playerTotalEggs = EggStats.GetPlayerTotalEggs(playerEggStats);
				string text2 = k switch
				{
					2 => "<color=#cd7f32>#3</color>", 
					1 => "<color=#c0c0c0>#2</color>", 
					0 => "<color=#ffd700>#1</color>", 
					_ => $"<color=#888888>#{k + 1}</color>", 
				};
				if (k < 3)
				{
					GUI.DrawTexture(new Rect(num2 + 4f, num10, num - 8f, 18f), (Texture)(object)_accentTex);
				}
				string text3 = playerEggStats.PlayerName;
				if (text3 != null && text3.Length > 12)
				{
					text3 = text3.Substring(0, 11) + "..";
				}
				GUI.Label(new Rect(num2 + 8f, num10, num - 56f, 18f), text2 + " " + text3, _medalStyle);
				GUI.Label(new Rect(num2 + num - 50f, num10, 38f, 18f), $"<color=#ffd700>{playerTotalEggs}</color>", _countStyle);
			}
		}
	}
	public static class EggItems
	{
		public static readonly string[] PrefabNames = new string[3] { "aurora_egg_painted", "aurora_egg_silver", "aurora_egg_golden" };

		public static readonly string[] DisplayNames = new string[3] { "Painted Egg", "Silver Egg", "Golden Egg" };

		public static readonly string[] Descriptions = new string[3] { "A colorful painted egg blessed by Idunn. Trade it at a checkpoint for rewards.", "A shimmering silver egg radiating gentle warmth. Idunn's favor flows within.", "A radiant golden egg pulsing with divine energy. Extremely rare and valuable." };

		private static readonly GameObject[] _eggPrefabs = (GameObject[])(object)new GameObject[3];

		private static GameObject _prefabRoot;

		private static bool _itemsCreated = false;

		private static readonly string[] CloneTemplates = new string[3] { "DragonEgg", "DragonEgg", "DragonEgg" };

		private static void CreateEggPrefabs(ObjectDB objectDB)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			if (_itemsCreated || ((Object)(object)objectDB.GetItemPrefab("DragonEgg") == (Object)null && (Object)(object)objectDB.GetItemPrefab("Amber") == (Object)null))
			{
				return;
			}
			if ((Object)(object)_prefabRoot == (Object)null)
			{
				_prefabRoot = new GameObject("AuroraEasterEggPrefabs");
				_prefabRoot.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_prefabRoot);
			}
			for (int i = 0; i < 3; i++)
			{
				if ((Object)(object)_eggPrefabs[i] != (Object)null)
				{
					continue;
				}
				try
				{
					GameObject itemPrefab = objectDB.GetItemPrefab(CloneTemplates[i]);
					if ((Object)(object)itemPrefab == (Object)null)
					{
						itemPrefab = objectDB.GetItemPrefab("Amber");
					}
					if (!((Object)(object)itemPrefab == (Object)null))
					{
						GameObject val = Object.Instantiate<GameObject>(itemPrefab, _prefabRoot.transform);
						((Object)val).name = PrefabNames[i];
						val.SetActive(true);
						ItemDrop component = val.GetComponent<ItemDrop>();
						if (component?.m_itemData?.m_shared != null)
						{
							SharedData shared = component.m_itemData.m_shared;
							shared.m_name = $"$aurora_egg_{i}";
							shared.m_description = $"$aurora_egg_{i}_desc";
							shared.m_maxStackSize = 999;
							shared.m_weight = 0.5f;
							shared.m_maxQuality = 1;
							shared.m_questItem = false;
							shared.m_teleportable = true;
							shared.m_itemType = (ItemType)1;
							component.m_itemData.m_dropPrefab = val;
							_eggPrefabs[i] = val;
							Plugin.Log.LogInfo((object)("EggItems: Created " + PrefabNames[i] + " from " + ((Object)itemPrefab).name));
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("EggItems: Failed to create " + PrefabNames[i] + ": " + ex.Message));
				}
			}
			if ((Object)(object)_eggPrefabs[0] != (Object)null || (Object)(object)_eggPrefabs[1] != (Object)null || (Object)(object)_eggPrefabs[2] != (Object)null)
			{
				_itemsCreated = true;
			}
		}

		public static void RegisterInObjectDB(ObjectDB objectDB)
		{
			if (objectDB?.m_items == null || objectDB.m_items.Count == 0 || objectDB.m_items.Count < 100)
			{
				return;
			}
			if (!_itemsCreated)
			{
				CreateEggPrefabs(objectDB);
			}
			if (!_itemsCreated)
			{
				return;
			}
			int i;
			for (i = 0; i < 3; i++)
			{
				if (!((Object)(object)_eggPrefabs[i] == (Object)null) && !objectDB.m_items.Exists((GameObject x) => (Object)(object)x != (Object)null && ((Object)x).name == PrefabNames[i]))
				{
					objectDB.m_items.Add(_eggPrefabs[i]);
				}
			}
			UpdateHash(objectDB);
			int num = 0;
			for (int j = 0; j < 3; j++)
			{
				if ((Object)(object)objectDB.GetItemPrefab(PrefabNames[j]) != (Object)null)
				{
					num++;
				}
			}
			if (num == 3)
			{
				Plugin.Log.LogInfo((object)$"EggItems: All eggs registered and verified in ObjectDB ({objectDB.m_items.Count} items)");
			}
			else
			{
				Plugin.Log.LogWarning((object)$"EggItems: Only {num}/3 eggs verified after registration");
			}
		}

		private static void UpdateHash(ObjectDB objectDB)
		{
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			string[] array = new string[3] { "m_itemByHash", "m_itemsByHash", "m_itemHashes" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(ObjectDB).GetField(name, bindingAttr);
				if (field == null || !(field.GetValue(objectDB) is Dictionary<int, GameObject> dictionary))
				{
					continue;
				}
				GameObject[] eggPrefabs = _eggPrefabs;
				foreach (GameObject val in eggPrefabs)
				{
					if ((Object)(object)val != (Object)null)
					{
						dictionary[StringExtensionMethods.GetStableHashCode(((Object)val).name)] = val;
					}
				}
				return;
			}
			FieldInfo[] fields = typeof(ObjectDB).GetFields(bindingAttr);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType != typeof(Dictionary<int, GameObject>) || !(fieldInfo.GetValue(objectDB) is Dictionary<int, GameObject> dictionary2) || dictionary2.Count < 50)
				{
					continue;
				}
				GameObject[] eggPrefabs = _eggPrefabs;
				foreach (GameObject val2 in eggPrefabs)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						dictionary2[StringExtensionMethods.GetStableHashCode(((Object)val2).name)] = val2;
					}
				}
				break;
			}
		}

		public static void RegisterInZNetScene(ZNetScene zNetScene)
		{
			if ((Object)(object)zNetScene == (Object)null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Dictionary<int, GameObject> dictionary = null;
			string[] array = new string[2] { "m_namedPrefabs", "m_prefabsByHash" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(ZNetScene).GetField(name, bindingAttr);
				if (!(field == null))
				{
					dictionary = field.GetValue(zNetScene) as Dictionary<int, GameObject>;
					if (dictionary != null)
					{
						break;
					}
				}
			}
			if (dictionary == null)
			{
				return;
			}
			GameObject[] eggPrefabs = _eggPrefabs;
			foreach (GameObject val in eggPrefabs)
			{
				if (!((Object)(object)val == (Object)null))
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name);
					if (!dictionary.ContainsKey(stableHashCode))
					{
						dictionary[stableHashCode] = val;
					}
				}
			}
		}

		public static void RegisterLocalization()
		{
			Localization instance = Localization.instance;
			if (instance == null)
			{
				return;
			}
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			Dictionary<string, string> dictionary = null;
			string[] array = new string[2] { "m_translations", "m_words" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(Localization).GetField(name, bindingAttr);
				if (!(field == null))
				{
					dictionary = field.GetValue(instance) as Dictionary<string, string>;
					if (dictionary != null)
					{
						break;
					}
				}
			}
			if (dictionary != null)
			{
				for (int j = 0; j < 3; j++)
				{
					dictionary[$"aurora_egg_{j}"] = DisplayNames[j];
					dictionary[$"aurora_egg_{j}_desc"] = Descriptions[j];
				}
			}
		}

		public static GameObject GetEggPrefab(int tier)
		{
			if (tier < 0 || tier >= 3)
			{
				return null;
			}
			return _eggPrefabs[tier];
		}

		public static void FixDropPrefab(ItemData item)
		{
			if (item == null || (Object)(object)item.m_dropPrefab != (Object)null)
			{
				return;
			}
			string text = item.m_shared?.m_name ?? "";
			for (int i = 0; i < 3; i++)
			{
				if (text == $"$aurora_egg_{i}")
				{
					object obj = _eggPrefabs[i];
					if (obj == null)
					{
						ObjectDB instance = ObjectDB.instance;
						obj = ((instance != null) ? instance.GetItemPrefab(PrefabNames[i]) : null);
					}
					item.m_dropPrefab = (GameObject)obj;
					break;
				}
			}
			if (!((Object)(object)item.m_dropPrefab == (Object)null) || _itemsCreated || !((Object)(object)ObjectDB.instance != (Object)null))
			{
				return;
			}
			CreateEggPrefabs(ObjectDB.instance);
			for (int j = 0; j < 3; j++)
			{
				if (text == $"$aurora_egg_{j}" && (Object)(object)_eggPrefabs[j] != (Object)null)
				{
					item.m_dropPrefab = _eggPrefabs[j];
					break;
				}
			}
		}
	}
	[HarmonyPatch]
	public static class EggItemPatches
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		[HarmonyPostfix]
		public static void ObjectDB_Awake(ObjectDB __instance)
		{
			EggItems.RegisterInObjectDB(__instance);
			EggItems.RegisterLocalization();
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		[HarmonyPostfix]
		public static void ObjectDB_CopyOtherDB(ObjectDB __instance)
		{
			EggItems.RegisterInObjectDB(__instance);
			EggItems.RegisterLocalization();
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		[HarmonyPostfix]
		public static void ZNetScene_Awake(ZNetScene __instance)
		{
			EggItems.RegisterInZNetScene(__instance);
		}

		[HarmonyPatch(typeof(Humanoid), "DropItem")]
		[HarmonyPrefix]
		public static void DropItem_Fix(ItemData item)
		{
			EggItems.FixDropPrefab(item);
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		[HarmonyPostfix]
		public static void Player_OnSpawned(Player __instance)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Inventory inventory = ((Humanoid)__instance).GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				EggItems.FixDropPrefab(allItem);
			}
			EggRPC.Instance?.RequestStatsFromServer();
		}

		[HarmonyPatch(typeof(Inventory), "Load")]
		[HarmonyPostfix]
		public static void Inventory_Load(Inventory __instance)
		{
			foreach (ItemData allItem in __instance.GetAllItems())
			{
				EggItems.FixDropPrefab(allItem);
			}
		}

		[HarmonyPatch(typeof(Player), "AutoPickup")]
		[HarmonyPrefix]
		public static void AutoPickup_Fix(Player __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			try
			{
				Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, __instance.m_autoPickupRange, LayerMask.GetMask(new string[1] { "item" }));
				foreach (Collider val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						ItemDrop componentInParent = ((Component)val).GetComponentInParent<ItemDrop>();
						if (componentInParent?.m_itemData != null)
						{
							EggItems.FixDropPrefab(componentInParent.m_itemData);
						}
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	public static class EggNests
	{
		private static readonly HashSet<Vector2i> _nestedZones = new HashSet<Vector2i>();

		private static readonly HashSet<Vector2i> _deferredZones = new HashSet<Vector2i>();

		private static float _retryTimer = 0f;

		[HarmonyPatch(typeof(ZoneSystem), "SpawnZone")]
		[HarmonyPostfix]
		public static void OnZoneSpawn(ZoneSystem __instance, Vector2i zoneID)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				TrySpawnNest(zoneID);
			}
		}

		private static void TrySpawnNest(Vector2i zoneID)
		{
			//IL_0005: 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_0045: 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_0069: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Invalid comparison between Unknown and I4
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Invalid comparison between Unknown and I4
			//IL_00ff: 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_0118: Expected I4, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Invalid comparison between Unknown and I4
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Invalid comparison between Unknown and I4
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Invalid comparison between Unknown and I4
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: 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_0229: 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)
			if (_nestedZones.Contains(zoneID))
			{
				return;
			}
			float value = EggConfig.NestSpawnChance.Value;
			if ((float)new Random(zoneID.x * 31337 + zoneID.y * 7919).NextDouble() > value)
			{
				_nestedZones.Add(zoneID);
				return;
			}
			if ((Object)(object)EggItems.GetEggPrefab(0) == (Object)null)
			{
				_deferredZones.Add(zoneID);
				return;
			}
			Vector3 zonePos = ZoneSystem.GetZonePos(zoneID);
			int num = 8;
			Vector3 val = default(Vector3);
			float num4 = default(float);
			for (int i = 0; i < num; i++)
			{
				float num2 = Random.Range(-30f, 30f);
				float num3 = Random.Range(-30f, 30f);
				((Vector3)(ref val))..ctor(zonePos.x + num2, 0f, zonePos.z + num3);
				if (!ZoneSystem.instance.GetGroundHeight(val, ref num4) || num4 < ZoneSystem.instance.m_waterLevel + 0.5f)
				{
					continue;
				}
				val.y = num4 + 0.2f;
				Biome val2 = Heightmap.FindBiome(val);
				int num5;
				if ((int)val2 <= 8)
				{
					switch (val2 - 1)
					{
					default:
						if ((int)val2 != 8)
						{
							break;
						}
						goto case 0;
					case 0:
						num5 = 0;
						goto IL_0148;
					case 1:
					case 3:
						num5 = 1;
						goto IL_0148;
					case 2:
						break;
					}
				}
				else if ((int)val2 == 16 || (int)val2 == 32 || (int)val2 == 512)
				{
					num5 = 2;
					goto IL_0148;
				}
				num5 = 0;
				goto IL_0148;
				IL_0148:
				GameObject eggPrefab = EggItems.GetEggPrefab(num5);
				if ((Object)(object)eggPrefab == (Object)null)
				{
					continue;
				}
				try
				{
					GameObject obj = Object.Instantiate<GameObject>(eggPrefab, val, Quaternion.identity);
					obj.SetActive(true);
					ItemDrop component = obj.GetComponent<ItemDrop>();
					if ((Object)(object)component != (Object)null)
					{
						int stack = num5 switch
						{
							1 => Random.Range(1, 4), 
							0 => Random.Range(2, 6), 
							_ => 1, 
						};
						component.m_itemData.m_stack = stack;
					}
					_nestedZones.Add(zoneID);
					_deferredZones.Remove(zoneID);
					Plugin.Log.LogInfo((object)$"EggNest: Spawned {EggItems.DisplayNames[num5]} x{(component?.m_itemData?.m_stack).GetValueOrDefault(1)} at {val} in zone {zoneID}");
					return;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("EggNest: Failed to spawn: " + ex.Message));
					return;
				}
			}
			_nestedZones.Add(zoneID);
		}

		public static void RetryDeferred()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (_deferredZones.Count == 0)
			{
				return;
			}
			_retryTimer += Time.deltaTime;
			if (_retryTimer < 2f)
			{
				return;
			}
			_retryTimer = 0f;
			if ((Object)(object)EggItems.GetEggPrefab(0) == (Object)null)
			{
				return;
			}
			List<Vector2i> list = new List<Vector2i>(_deferredZones);
			_deferredZones.Clear();
			foreach (Vector2i item in list)
			{
				TrySpawnNest(item);
			}
			if (list.Count > 0)
			{
				Plugin.Log.LogInfo((object)$"EggNest: Retried {list.Count} deferred zones");
			}
		}
	}
	public class EggRPC : MonoBehaviour
	{
		private const string RPC_SyncStats = "AuroraEaster_SyncStats";

		private const string RPC_RequestStats = "AuroraEaster_RequestStats";

		private const string RPC_EggFound = "AuroraEaster_EggFound";

		private bool _rpcsRegistered;

		public static EggRPC Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)this);
			}
			else
			{
				Instance = this;
			}
		}

		private void Start()
		{
			TryRegisterRPCs();
		}

		private void Update()
		{
			if (!_rpcsRegistered)
			{
				TryRegisterRPCs();
			}
		}

		private void TryRegisterRPCs()
		{
			if (!_rpcsRegistered && ZRoutedRpc.instance != null)
			{
				_rpcsRegistered = true;
				ZRoutedRpc.instance.Register<string>("AuroraEaster_SyncStats", (Action<long, string>)RPC_OnSyncStats);
				ZRoutedRpc.instance.Register<string>("AuroraEaster_RequestStats", (Action<long, string>)RPC_OnRequestStats);
				ZRoutedRpc.instance.Register<ZPackage>("AuroraEaster_EggFound", (Action<long, ZPackage>)RPC_OnEggFound);
				Plugin.Log.LogInfo((object)"EggRPC: Registered RPCs");
			}
		}

		private void RPC_OnSyncStats(long sender, string json)
		{
			if (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer())
			{
				EggStats.LoadFromJson(json);
			}
		}

		private void RPC_OnRequestStats(long sender, string dummy)
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				string text = EggStats.SaveToJson();
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null)
				{
					instance.InvokeRoutedRPC(sender, "AuroraEaster_SyncStats", new object[1] { text });
				}
			}
		}

		public void RequestStatsFromServer()
		{
			if (ZRoutedRpc.instance != null && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsServer()))
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(GetServerPeerID(), "AuroraEaster_RequestStats", new object[1] { "" });
			}
		}

		public void ReportEggFound(long playerId, string playerName, int tier)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				EggStats.RecordEggFound(playerId, playerName, tier);
				Plugin.Log.LogInfo((object)$"EggRPC: Recorded egg tier {tier} for {playerName} (direct)");
				BroadcastStats();
				EggStats.Save();
				return;
			}
			ZPackage val = new ZPackage();
			val.Write(playerId);
			val.Write(playerName ?? "");
			val.Write(tier);
			ZRoutedRpc instance2 = ZRoutedRpc.instance;
			if (instance2 != null)
			{
				instance2.InvokeRoutedRPC(GetServerPeerID(), "AuroraEaster_EggFound", new object[1] { val });
			}
		}

		private void RPC_OnEggFound(long sender, ZPackage pkg)
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return;
			}
			long num = pkg.ReadLong();
			string text = pkg.ReadString();
			int num2 = pkg.ReadInt();
			if (num2 >= 0 && num2 <= 2)
			{
				if (num == 0L)
				{
					Plugin.Log.LogWarning((object)$"EggRPC: Received egg find with playerId 0 from sender {sender}, ignoring");
					return;
				}
				EggStats.RecordEggFound(num, text, num2);
				Plugin.Log.LogInfo((object)$"EggRPC: Recorded egg tier {num2} for {text} (playerId={num}) (RPC)");
				BroadcastStats();
				EggStats.Save();
			}
		}

		public void BroadcastStats()
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				string text = EggStats.SaveToJson();
				ZRoutedRpc instance = ZRoutedRpc.instance;
				if (instance != null)
				{
					instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "AuroraEaster_SyncStats", new object[1] { text });
				}
			}
		}

		private long GetServerPeerID()
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return 0L;
			}
			if (ZNet.instance.IsServer())
			{
				return ZNet.GetUID();
			}
			return ZNet.instance.GetServerPeer()?.m_uid ?? 0;
		}
	}
	[Serializable]
	public class PlayerEggStats
	{
		public long PlayerId;

		public string PlayerName;

		public int PaintedEggs;

		public int SilverEggs;

		public int GoldenEggs;
	}
	[Serializable]
	public class EggStatsData
	{
		public List<PlayerEggStats> Players = new List<PlayerEggStats>();

		public int TotalPaintedFound;

		public int TotalSilverFound;

		public int TotalGoldenFound;
	}
	public static class EggStats
	{
		private static EggStatsData _data = new EggStatsData();

		private static float _saveTimer = 0f;

		private static bool _dirty = false;

		private static bool _isServer = false;

		public static EggStatsData Data => _data;

		public static int GetPlayerTotalEggs(PlayerEggStats p)
		{
			return p.PaintedEggs + p.SilverEggs + p.GoldenEggs;
		}

		public static int GetTotalEggsFound()
		{
			return _data.TotalPaintedFound + _data.TotalSilverFound + _data.TotalGoldenFound;
		}

		public static void RecordEggFound(long playerId, string playerName, int tier)
		{
			PlayerEggStats playerEggStats = _data.Players.Find((PlayerEggStats p) => p.PlayerId == playerId);
			if (playerEggStats == null)
			{
				playerEggStats = new PlayerEggStats
				{
					PlayerId = playerId,
					PlayerName = playerName
				};
				_data.Players.Add(playerEggStats);
			}
			playerEggStats.PlayerName = playerName;
			switch (tier)
			{
			case 0:
				playerEggStats.PaintedEggs++;
				_data.TotalPaintedFound++;
				break;
			case 1:
				playerEggStats.SilverEggs++;
				_data.TotalSilverFound++;
				break;
			case 2:
				playerEggStats.GoldenEggs++;
				_data.TotalGoldenFound++;
				break;
			}
			_dirty = true;
		}

		public static List<PlayerEggStats> GetLeaderboard()
		{
			List<PlayerEggStats> list = new List<PlayerEggStats>(_data.Players);
			list.Sort(delegate(PlayerEggStats a, PlayerEggStats b)
			{
				int num = b.GoldenEggs.CompareTo(a.GoldenEggs);
				if (num != 0)
				{
					return num;
				}
				num = b.SilverEggs.CompareTo(a.SilverEggs);
				return (num != 0) ? num : GetPlayerTotalEggs(b).CompareTo(GetPlayerTotalEggs(a));
			});
			return list;
		}

		public static void UpdateSave()
		{
			if (!_dirty)
			{
				return;
			}
			ZNet instance = ZNet.instance;
			if (instance != null && instance.IsServer())
			{
				_saveTimer += Time.deltaTime;
				if (!(_saveTimer < 30f))
				{
					_saveTimer = 0f;
					Save();
					EggRPC.Instance?.BroadcastStats();
				}
			}
		}

		public static void SetIsServer(bool isServer)
		{
			_isServer = isServer;
		}

		public static void Save()
		{
			if (!_isServer)
			{
				return;
			}
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "AuroraEasterEvent");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				string path = Path.Combine(text, "egg_stats.json");
				string contents = JsonUtility.ToJson((object)_data, true);
				File.WriteAllText(path, contents);
				_dirty = false;
				Plugin.Log.LogInfo((object)$"EggStats: Saved ({_data.Players.Count} players, {GetTotalEggsFound()} total eggs)");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("EggStats: Save failed: " + ex.Message));
			}
		}

		public static void Load()
		{
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "AuroraEasterEvent", "egg_stats.json");
				if (!File.Exists(path))
				{
					Plugin.Log.LogInfo((object)"EggStats: No existing stats file, starting fresh");
					return;
				}
				EggStatsData eggStatsData = JsonUtility.FromJson<EggStatsData>(File.ReadAllText(path));
				if (eggStatsData != null)
				{
					if (eggStatsData.Players == null)
					{
						eggStatsData.Players = new List<PlayerEggStats>();
					}
					_data = eggStatsData;
				}
				Plugin.Log.LogInfo((object)$"EggStats: Loaded ({_data.Players.Count} players, {GetTotalEggsFound()} total eggs)");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("EggStats: Load failed: " + ex.Message));
				_data = new EggStatsData();
			}
		}

		public static string SaveToJson()
		{
			return JsonUtility.ToJson((object)_data);
		}

		public static void LoadFromJson(string json)
		{
			try
			{
				_data = JsonUtility.FromJson<EggStatsData>(json) ?? new EggStatsData();
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch]
	public static class EggCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleEvent <>9__0_1;

			internal void <AddCommands>b__0_0(ConsoleEventArgs args)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				string text = ((args.Length >= 2) ? args[1].ToLower() : "painted");
				int result;
				int num = ((args.Length < 3 || !int.TryParse(args[2], out result)) ? 1 : result);
				int num2;
				switch (text)
				{
				case "painted":
					num2 = 0;
					break;
				case "silver":
					num2 = 1;
					break;
				case "golden":
				case "gold":
					num2 = 2;
					break;
				default:
					num2 = 0;
					break;
				}
				GameObject eggPrefab = EggItems.GetEggPrefab(num2);
				if ((Object)(object)eggPrefab == (Object)null)
				{
					args.Context.AddString("Egg prefab not found.");
					return;
				}
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory != null)
				{
					inventory.AddItem(eggPrefab, num);
				}
				args.Context.AddString($"Spawned {num}x {EggItems.DisplayNames[num2]}");
			}

			internal void <AddCommands>b__0_1(ConsoleEventArgs args)
			{
				//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)
				//IL_002c: 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_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Expected I4, but got Unknown
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Invalid comparison between Unknown and I4
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: 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_008e: 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)
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					args.Context.AddString("No local player.");
					return;
				}
				Vector3 position = ((Component)localPlayer).transform.position;
				Biome val = Heightmap.FindBiome(position);
				int num;
				switch (val - 1)
				{
				default:
					if ((int)val == 8)
					{
						goto case 0;
					}
					goto case 2;
				case 0:
					num = 0;
					break;
				case 1:
				case 3:
					num = 1;
					break;
				case 2:
					num = 2;
					break;
				}
				GameObject eggPrefab = EggItems.GetEggPrefab(num);
				if ((Object)(object)eggPrefab == (Object)null)
				{
					args.Context.AddString("No egg prefab.");
					return;
				}
				GameObject obj = Object.Instantiate<GameObject>(eggPrefab, position + Vector3.up * 0.3f, Quaternion.identity);
				obj.SetActive(true);
				ItemDrop component = obj.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_itemData.m_stack = num switch
					{
						1 => 3, 
						0 => 5, 
						_ => 1, 
					};
				}
				args.Context.AddString("Spawned " + EggItems.DisplayNames[num] + " nest at your position.");
			}
		}

		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		[HarmonyPostfix]
		public static void AddCommands()
		{
			//IL_0032: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_006a: 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_0061: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					Player localPlayer2 = Player.m_localPlayer;
					if ((Object)(object)localPlayer2 == (Object)null)
					{
						args.Context.AddString("No local player.");
					}
					else
					{
						string text = ((args.Length >= 2) ? args[1].ToLower() : "painted");
						int result;
						int num2 = ((args.Length < 3 || !int.TryParse(args[2], out result)) ? 1 : result);
						int num3;
						switch (text)
						{
						case "painted":
							num3 = 0;
							break;
						case "silver":
							num3 = 1;
							break;
						case "golden":
						case "gold":
							num3 = 2;
							break;
						default:
							num3 = 0;
							break;
						}
						GameObject eggPrefab2 = EggItems.GetEggPrefab(num3);
						if ((Object)(object)eggPrefab2 == (Object)null)
						{
							args.Context.AddString("Egg prefab not found.");
						}
						else
						{
							Inventory inventory = ((Humanoid)localPlayer2).GetInventory();
							if (inventory != null)
							{
								inventory.AddItem(eggPrefab2, num2);
							}
							args.Context.AddString($"Spawned {num2}x {EggItems.DisplayNames[num3]}");
						}
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("spawneggs", "Spawn eggs: spawneggs <painted|silver|golden> [amount]", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					//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)
					//IL_002c: 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_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references)
					//IL_004b: Expected I4, but got Unknown
					//IL_004b: Unknown result type (might be due to invalid IL or missing references)
					//IL_004d: Invalid comparison between Unknown and I4
					//IL_007e: Unknown result type (might be due to invalid IL or missing references)
					//IL_007f: 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_008e: 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)
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null)
					{
						args.Context.AddString("No local player.");
					}
					else
					{
						Vector3 position = ((Component)localPlayer).transform.position;
						Biome val3 = Heightmap.FindBiome(position);
						int num;
						switch (val3 - 1)
						{
						default:
							if ((int)val3 == 8)
							{
								goto case 0;
							}
							goto case 2;
						case 0:
							num = 0;
							break;
						case 1:
						case 3:
							num = 1;
							break;
						case 2:
							num = 2;
							break;
						}
						GameObject eggPrefab = EggItems.GetEggPrefab(num);
						if ((Object)(object)eggPrefab == (Object)null)
						{
							args.Context.AddString("No egg prefab.");
						}
						else
						{
							GameObject obj3 = Object.Instantiate<GameObject>(eggPrefab, position + Vector3.up * 0.3f, Quaternion.identity);
							obj3.SetActive(true);
							ItemDrop component = obj3.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null)
							{
								component.m_itemData.m_stack = num switch
								{
									1 => 3, 
									0 => 5, 
									_ => 1, 
								};
							}
							args.Context.AddString("Spawned " + EggItems.DisplayNames[num] + " nest at your position.");
						}
					}
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("spawnnest", "Force spawn an egg nest at your position", (ConsoleEvent)obj2, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	[BepInPlugin("aurora.easter.event", "Aurora Easter Event - Egg Hunt of Idunn", "1.0.0")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private GameObject _hudObj;

		private GameObject _rpcObj;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"Aurora Easter Event loading...");
			EggConfig.Initialize(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("aurora.easter.event");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			_rpcObj = new GameObject("AuroraEasterRPC");
			Object.DontDestroyOnLoad((Object)(object)_rpcObj);
			_rpcObj.AddComponent<EggRPC>();
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				_hudObj = new GameObject("AuroraEasterHUD");
				Object.DontDestroyOnLoad((Object)(object)_hudObj);
				_hudObj.AddComponent<EggHUD>();
			}
			else
			{
				Log.LogInfo((object)"Dedicated server mode — HUD skipped");
				EggStats.SetIsServer(isServer: true);
			}
			EggStats.Load();
			Log.LogInfo((object)"Aurora Easter Event loaded! Happy hunting!");
		}

		private void Update()
		{
			EggStats.UpdateSave();
			EggNests.RetryDeferred();
		}

		private void OnApplicationQuit()
		{
			EggStats.Save();
		}

		private void OnDestroy()
		{
			EggStats.Save();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)_hudObj != (Object)null)
			{
				Object.Destroy((Object)(object)_hudObj);
			}
			if ((Object)(object)_rpcObj != (Object)null)
			{
				Object.Destroy((Object)(object)_rpcObj);
			}
		}
	}
	[HarmonyPatch]
	public static class ZNetServerDetection
	{
		[HarmonyPatch(typeof(ZNet), "Awake")]
		[HarmonyPostfix]
		public static void ZNet_Awake(ZNet __instance)
		{
			if (__instance.IsServer())
			{
				EggStats.SetIsServer(isServer: true);
				EggStats.Load();
				Plugin.Log.LogInfo((object)"EggStats: Server detected, stats loaded");
			}
		}
	}
}