Decompiled source of Weather Altar v1.0.3

BepInEx/plugins/WeatherAltar.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("WeatherAltar")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3+d540f715d81476ae587631540cea377a0235dcd2")]
[assembly: AssemblyProduct("WeatherAltar")]
[assembly: AssemblyTitle("WeatherAltar")]
[assembly: AssemblyVersion("1.0.3.0")]
namespace WeatherAltar;

public static class AltarMenu
{
	private const float PanelWidth = 480f;

	private const float PanelHeight = 400f;

	private const float MaxInteractDistance = 5f;

	private const float RefreshInterval = 0.25f;

	private static GameObject _panel;

	private static GameObject _currentWeatherText;

	private static GameObject _priceText;

	private static GameObject _statusText;

	private static GameObject _errorText;

	private static GameObject _offerButtonObject;

	private static readonly GameObject[] ChoiceButtons = (GameObject[])(object)new GameObject[4];

	private static WeatherAltarPiece _altar;

	private static WeatherKind _selected = WeatherKind.None;

	private static bool _inputBlocked;

	private static bool _awaitingServer;

	private static float _refreshTimer;

	public static bool IsOpen
	{
		get
		{
			if ((Object)(object)_panel != (Object)null)
			{
				return _panel.activeSelf;
			}
			return false;
		}
	}

	public static void Open(WeatherAltarPiece altar)
	{
		//IL_0056: 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_0074: 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_00d0: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: 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_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: 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_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: 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_02b5: 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_02d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0322: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Expected O, but got Unknown
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03da: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Expected O, but got Unknown
		//IL_040c: Unknown result type (might be due to invalid IL or missing references)
		//IL_041b: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_044a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0450: Unknown result type (might be due to invalid IL or missing references)
		if (IsOpen)
		{
			return;
		}
		if (GUIManager.Instance == null)
		{
			Logger.LogWarning((object)"Weather Altar: GUIManager not ready.");
			return;
		}
		if (!Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
		{
			Logger.LogWarning((object)"Weather Altar: CustomGUIFront not available.");
			return;
		}
		_altar = altar;
		_awaitingServer = false;
		_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 480f, 400f, false);
		_panel.SetActive(true);
		GUIManager.Instance.CreateText(Localization.instance.Localize("$piece_mous_weatheraltar"), _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -30f), GUIManager.Instance.AveriaSerifBold, 28, GUIManager.Instance.ValheimOrange, true, Color.black, 440f, 36f, false);
		_currentWeatherText = GUIManager.Instance.CreateText("Weather: natural", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -70f), GUIManager.Instance.AveriaSerif, 18, Color.white, false, Color.black, 420f, 24f, false);
		_priceText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -100f), GUIManager.Instance.AveriaSerif, 18, Color.white, false, Color.black, 420f, 24f, false);
		CreateChoiceButton(WeatherKind.Clear, "Clear", -140f);
		CreateChoiceButton(WeatherKind.Rain, "Rain", -180f);
		CreateChoiceButton(WeatherKind.Storm, "Storm", -220f);
		_errorText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 110f), GUIManager.Instance.AveriaSerif, 15, new Color(1f, 0.55f, 0.35f), false, Color.black, 420f, 28f, false);
		_statusText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 80f), GUIManager.Instance.AveriaSerif, 16, Color.white, false, Color.black, 420f, 20f, false);
		_offerButtonObject = GUIManager.Instance.CreateButton("Offer", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-90f, 50f), 150f, 40f);
		((UnityEvent)_offerButtonObject.GetComponent<Button>().onClick).AddListener(new UnityAction(OnOfferClicked));
		((UnityEvent)GUIManager.Instance.CreateButton("Cancel", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(90f, 50f), 150f, 40f).GetComponent<Button>().onClick).AddListener(new UnityAction(Close));
		GUIManager.Instance.CreateText(Localization.instance.Localize("$mous_weatheraltar_hint"), _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 12f), GUIManager.Instance.AveriaSerif, 13, new Color(0.9f, 0.85f, 0.75f), false, Color.black, 420f, 18f, false);
		_selected = (WeatherService.IsSupported(1) ? WeatherKind.Clear : FirstSupported());
		if (_selected == WeatherKind.None)
		{
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_unavailable"));
		}
		GUIManager.BlockInput(true);
		_inputBlocked = true;
		if (!WeatherService.EverReceivedState && (Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer())
		{
			OfferingRpc.RequestState();
		}
		RefreshLabels();
	}

	private static void CreateChoiceButton(WeatherKind kind, string label, float y)
	{
		//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_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_0072: Expected O, but got Unknown
		GameObject val = GUIManager.Instance.CreateButton(label, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, y), 200f, 32f);
		((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
		{
			Select(kind);
		});
		ChoiceButtons[(uint)kind] = val;
	}

	private static WeatherKind FirstSupported()
	{
		for (byte b = 1; b <= 3; b++)
		{
			if (WeatherService.IsSupported(b))
			{
				return (WeatherKind)b;
			}
		}
		return WeatherKind.None;
	}

	private static void Select(WeatherKind kind)
	{
		if (WeatherService.IsSupported((byte)kind))
		{
			_selected = kind;
			_awaitingServer = false;
			RefreshLabels();
		}
	}

	private static void OnOfferClicked()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_altar == (Object)null) && _selected != WeatherKind.None && !_awaitingServer)
		{
			if (WeatherAltarPiece.GetDistance(_altar.GetZDOID()) > 5f)
			{
				SetErrorText(Localization.instance.Localize("$mous_weatheraltar_toofar"));
				return;
			}
			_awaitingServer = true;
			SetErrorText("");
			OfferingRpc.RequestOffering(_altar, _selected);
			RefreshLabels();
		}
	}

	public static void OnFailure(OfferingFailure failure)
	{
		_awaitingServer = false;
		if (IsOpen)
		{
			SetErrorText(failure);
		}
	}

	public static void OnReceipt(bool accepted)
	{
		_awaitingServer = false;
		if (IsOpen && accepted)
		{
			Close();
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, "$mous_weatheraltar_accepted", 0, (Sprite)null, false);
			}
		}
	}

	private static void SetErrorText(OfferingFailure failure)
	{
		switch (failure)
		{
		case OfferingFailure.NotEnoughCoins:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_needcoins", new string[1] { AltarSettings.CoinCost.Value.ToString() }));
			break;
		case OfferingFailure.NotEnoughHealth:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_needhealth", new string[1] { (AltarSettings.HealthCost.Value + 1f).ToString("0") }));
			break;
		case OfferingFailure.NoAccess:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_noaccess"));
			break;
		case OfferingFailure.TooFar:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_toofar"));
			break;
		case OfferingFailure.Unavailable:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_unavailable"));
			break;
		case OfferingFailure.PriceChanged:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_pricechanged"));
			RefreshLabels();
			break;
		case OfferingFailure.Busy:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_busy"));
			break;
		case OfferingFailure.PaymentFailed:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_paymentfailed"));
			break;
		default:
			SetErrorText(Localization.instance.Localize("$mous_weatheraltar_invalid"));
			break;
		}
	}

	private static void SetErrorText(string message)
	{
		if ((Object)(object)_errorText != (Object)null)
		{
			Text component = _errorText.GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				component.text = message;
			}
		}
	}

	public static void Close()
	{
		if (!((Object)(object)_panel == (Object)null))
		{
			Object.Destroy((Object)(object)_panel);
			_panel = null;
			_altar = null;
			_awaitingServer = false;
			if (_inputBlocked)
			{
				GUIManager.BlockInput(false);
				_inputBlocked = false;
			}
		}
	}

	public static void Update()
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		if (!IsOpen)
		{
			return;
		}
		if (Input.GetKeyDown((KeyCode)27))
		{
			Close();
			return;
		}
		_refreshTimer += Time.unscaledDeltaTime;
		if (_refreshTimer >= 0.25f)
		{
			_refreshTimer = 0f;
			RefreshLabels();
		}
		if ((Object)(object)_altar == (Object)null || (Object)(object)((Component)_altar).gameObject == (Object)null)
		{
			Close();
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
		{
			Close();
		}
		else if ((Object)(object)_altar != (Object)null && (Object)(object)((Component)_altar).gameObject != (Object)null && WeatherAltarPiece.GetDistance(_altar.GetZDOID()) > 5f)
		{
			Close();
		}
	}

	public static void RefreshLabels()
	{
		if (!((Object)(object)_panel == (Object)null))
		{
			RefreshChoiceLabels();
			RefreshPriceLabel();
			RefreshCurrentWeatherLabel();
			RefreshStatusLabel();
		}
	}

	private static void RefreshChoiceLabels()
	{
		//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_004e: 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_012f: 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_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		for (byte b = 1; b <= 3; b++)
		{
			GameObject val = ChoiceButtons[b];
			if (!((Object)(object)val == (Object)null))
			{
				bool flag = WeatherService.IsSupported(b);
				Button component = val.GetComponent<Button>();
				((Selectable)component).interactable = flag;
				ColorBlock colors = ((Selectable)component).colors;
				((ColorBlock)(ref colors)).disabledColor = new Color(0.4f, 0.4f, 0.4f, 0.5f);
				((Selectable)component).colors = colors;
				Text componentInChildren = val.GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					string text = b switch
					{
						2 => "Rain", 
						1 => "Clear", 
						_ => "Storm", 
					};
					bool flag2 = (uint)b == (uint)_selected;
					if (flag)
					{
						componentInChildren.text = (flag2 ? ("» " + text + " «") : text);
						((Graphic)componentInChildren).color = (flag2 ? GUIManager.Instance.ValheimOrange : Color.white);
					}
					else
					{
						componentInChildren.text = text + " (unavailable)";
						((Graphic)componentInChildren).color = new Color(0.55f, 0.55f, 0.55f, 0.7f);
					}
				}
				if ((Object)(object)((Selectable)component).image != (Object)null)
				{
					((Graphic)((Selectable)component).image).color = (Color)((flag && (uint)b == (uint)_selected) ? new Color(1f, 0.72f, 0.35f) : Color.white);
				}
			}
		}
	}

	private static void RefreshPriceLabel()
	{
		if (!((Object)(object)_priceText == (Object)null))
		{
			int value = AltarSettings.CoinCost.Value;
			float value2 = AltarSettings.HealthCost.Value;
			int value3 = AltarSettings.DurationSeconds.Value;
			Text component = _priceText.GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				component.text = $"{value} Coins + {value2:0} HP for {value3}s";
			}
		}
	}

	private static void RefreshCurrentWeatherLabel()
	{
		if ((Object)(object)_currentWeatherText == (Object)null)
		{
			return;
		}
		Text component = _currentWeatherText.GetComponent<Text>();
		if (!((Object)(object)component == (Object)null))
		{
			if (!WeatherService.StateKnown)
			{
				component.text = "Weather: waiting for server...";
			}
			else if (WeatherService.HasActive)
			{
				float num = WeatherService.RemainingSeconds();
				int num2 = (int)(num / 60f);
				int num3 = Mathf.CeilToInt(num % 60f);
				component.text = $"Weather: {WeatherService.Kind} ({num2}:{num3:00})";
			}
			else
			{
				component.text = "Weather: natural";
			}
		}
	}

	private static void RefreshStatusLabel()
	{
		if ((Object)(object)_statusText == (Object)null)
		{
			return;
		}
		Text component = _statusText.GetComponent<Text>();
		if (!((Object)(object)component == (Object)null))
		{
			if (_awaitingServer)
			{
				component.text = "Awaiting server...";
			}
			else
			{
				component.text = "";
			}
		}
	}

	public static void Shutdown()
	{
		Close();
	}
}
public static class AltarSettings
{
	private const string Section = "Offering";

	public static ConfigEntry<int> CoinCost;

	public static ConfigEntry<float> HealthCost;

	public static ConfigEntry<int> DurationSeconds;

	public static void Init(ConfigFile config)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Expected O, but got Unknown
		ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};
		CoinCost = config.Bind<int>("Offering", "CoinCost", 10, new ConfigDescription("Coins required per offering.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000), new object[1] { val }));
		HealthCost = config.Bind<float>("Offering", "HealthCost", 10f, new ConfigDescription("Health sacrificed per offering (nonlethal).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), new object[1] { val }));
		DurationSeconds = config.Bind<int>("Offering", "DurationSeconds", 600, new ConfigDescription("How long the purchased weather lasts, in real seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 3600), new object[1] { val }));
	}
}
public enum OfferingFailure : byte
{
	None,
	Unavailable,
	InvalidRequest,
	TooFar,
	NoAccess,
	NotEnoughCoins,
	NotEnoughHealth,
	PriceChanged,
	Busy,
	PaymentFailed
}
public static class OfferingRpc
{
	private sealed class ServerRequest
	{
		public long RequestId;

		public ZDOID AltarId;

		public WeatherKind Kind;

		public int CoinCost;

		public float HealthCost;

		public int DurationSeconds;
	}

	private sealed class CompletedRequest
	{
		public long RequestId;
	}

	private const long NoPeer = 0L;

	private const string RequestStateName = "RequestState";

	private const string OfferName = "Offer";

	private const string QuoteName = "Quote";

	private const string PaymentName = "Payment";

	private const string StateName = "State";

	private const string RejectName = "Reject";

	private static CustomRPC _requestState;

	private static CustomRPC _offer;

	private static CustomRPC _quote;

	private static CustomRPC _payment;

	private static CustomRPC _state;

	private static CustomRPC _reject;

	private static readonly Dictionary<long, ServerRequest> PendingByPeer = new Dictionary<long, ServerRequest>();

	private static readonly Dictionary<long, CompletedRequest> CompletedByPeer = new Dictionary<long, CompletedRequest>();

	private static long _nextRequestId = 1L;

	private static long _pendingRequestId;

	private static ZDOID _pendingAltarId = ZDOID.None;

	private static bool _outcomeRecorded;

	private static bool _paid;

	private static OfferingFailure _failure = OfferingFailure.None;

	public static void Register()
	{
		//IL_0012: 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_0028: Expected O, but got Unknown
		//IL_0028: Expected O, but got Unknown
		//IL_003a: 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_0050: Expected O, but got Unknown
		//IL_0050: Expected O, but got Unknown
		//IL_0062: 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_0078: Expected O, but got Unknown
		//IL_0078: Expected O, but got Unknown
		//IL_008a: 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_00a0: Expected O, but got Unknown
		//IL_00a0: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Expected O, but got Unknown
		//IL_00c8: Expected O, but got Unknown
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Expected O, but got Unknown
		//IL_00ef: Expected O, but got Unknown
		NetworkManager instance = NetworkManager.Instance;
		_requestState = instance.AddRPC("RequestState", new CoroutineHandler(OnRequestStateServer), new CoroutineHandler(OnRequestStateClient));
		_offer = instance.AddRPC("Offer", new CoroutineHandler(OnOfferServer), new CoroutineHandler(OnOfferClient));
		_quote = instance.AddRPC("Quote", new CoroutineHandler(OnQuoteServer), new CoroutineHandler(OnQuoteClient));
		_payment = instance.AddRPC("Payment", new CoroutineHandler(OnPaymentServer), new CoroutineHandler(OnPaymentClient));
		_state = instance.AddRPC("State", new CoroutineHandler(OnStateServer), new CoroutineHandler(OnStateClient));
		_reject = instance.AddRPC("Reject", new CoroutineHandler(OnRejectServer), new CoroutineHandler(OnRejectClient));
	}

	public static void Shutdown()
	{
		PendingByPeer.Clear();
		CompletedByPeer.Clear();
		_pendingRequestId = 0L;
		_outcomeRecorded = false;
		_paid = false;
		_failure = OfferingFailure.None;
	}

	private static long ServerTarget()
	{
		if ((Object)(object)ZNet.instance == (Object)null)
		{
			return 0L;
		}
		if (ZNet.instance.IsServer())
		{
			return ZNet.GetUID();
		}
		return ZNet.instance.GetServerPeer()?.m_uid ?? 0;
	}

	private static bool IsLocal(long target)
	{
		if ((Object)(object)ZNet.instance != (Object)null)
		{
			return target == ZNet.GetUID();
		}
		return false;
	}

	private static bool IsServerOrigin(long sender)
	{
		if (sender == ServerTarget() || sender == ZNet.GetUID())
		{
			return true;
		}
		Logger.LogWarning((object)$"Weather Altar: ignored packet from non-server peer {sender} (server is {ServerTarget()}).");
		return false;
	}

	private static ZPackage Rewind(ZPackage package)
	{
		//IL_0006: 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_0013: Expected O, but got Unknown
		ZPackage val = new ZPackage(package.GetArray());
		val.SetPos(0);
		return val;
	}

	private static bool TryReadEnvelope(ZPackage package, out long worldUid)
	{
		worldUid = 0L;
		if (package == null || (Object)(object)ZNet.instance == (Object)null)
		{
			return false;
		}
		try
		{
			worldUid = package.ReadLong();
			if (worldUid == ZNet.instance.GetWorldUID())
			{
				return true;
			}
			Logger.LogWarning((object)$"Weather Altar: ignored packet for world {worldUid} (this world is {ZNet.instance.GetWorldUID()}).");
			return false;
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("Weather Altar: ignored malformed packet: " + ex.Message));
			return false;
		}
	}

	private static void SendEnvelopeToServer(CustomRPC rpc, Action<ZPackage> writeBody)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Expected O, but got Unknown
		if (!((Object)(object)ZNet.instance == (Object)null))
		{
			ZPackage val = new ZPackage();
			val.Write(ZNet.instance.GetWorldUID());
			writeBody?.Invoke(val);
			long num = ServerTarget();
			if (IsLocal(num))
			{
				InvokeServerHandler(rpc, ZNet.GetUID(), Rewind(val));
			}
			else
			{
				rpc.SendPackage(num, val);
			}
		}
	}

	private static void InvokeServerHandler(CustomRPC rpc, long sender, ZPackage package)
	{
		switch (rpc.Name)
		{
		case "RequestState":
			HandleRequestStateServer(sender, package);
			break;
		case "Offer":
			HandleOfferServer(sender, package);
			break;
		case "Payment":
			HandlePaymentServer(sender, package);
			break;
		}
	}

	private static void InvokeClientHandler(CustomRPC rpc, long sender, ZPackage package)
	{
		switch (rpc.Name)
		{
		case "Quote":
			HandleQuoteClient(sender, package);
			break;
		case "Reject":
			HandleRejectClient(sender, package);
			break;
		case "State":
			HandleStateClient(sender, package);
			break;
		}
	}

	private static void SendToClient(long recipient, CustomRPC rpc, ZPackage package)
	{
		if (IsLocal(recipient))
		{
			InvokeClientHandler(rpc, recipient, Rewind(package));
		}
		else
		{
			rpc.SendPackage(recipient, package);
		}
	}

	public static void RequestState()
	{
		if (!((Object)(object)ZNet.instance == (Object)null))
		{
			SendEnvelopeToServer(_requestState, null);
		}
	}

	public static void RequestOffering(WeatherAltarPiece altar, WeatherKind kind)
	{
		//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)
		if ((Object)(object)ZNet.instance == (Object)null)
		{
			return;
		}
		if (_pendingRequestId != 0L && !_outcomeRecorded)
		{
			Logger.LogWarning((object)"Weather Altar: a request is already pending.");
			return;
		}
		_pendingRequestId = _nextRequestId++;
		_pendingAltarId = altar.GetZDOID();
		_outcomeRecorded = false;
		_paid = false;
		_failure = OfferingFailure.None;
		SendEnvelopeToServer(_offer, delegate(ZPackage package)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			package.Write(_pendingRequestId);
			package.Write(_pendingAltarId);
			package.Write((byte)kind);
			package.Write(AltarSettings.CoinCost.Value);
			package.Write(AltarSettings.HealthCost.Value);
			package.Write(AltarSettings.DurationSeconds.Value);
		});
	}

	private static void HandleRequestStateServer(long sender, ZPackage package)
	{
		if (TryReadEnvelope(package, out var _))
		{
			SendStateSnapshot(sender, 0L, 0L);
		}
	}

	private static void HandleOfferServer(long sender, ZPackage package)
	{
		//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_00bc: 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_00e6: 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_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		if (!TryReadEnvelope(package, out var _))
		{
			return;
		}
		long num;
		ZDOID val;
		byte kind;
		int num2;
		float num3;
		int num4;
		try
		{
			num = package.ReadLong();
			val = package.ReadZDOID();
			kind = package.ReadByte();
			num2 = package.ReadInt();
			num3 = package.ReadSingle();
			num4 = package.ReadInt();
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("Weather Altar: failed to decode Offer: " + ex.Message));
			return;
		}
		if (float.IsNaN(num3) || float.IsInfinity(num3))
		{
			RejectRequest(sender, num, OfferingFailure.InvalidRequest);
			return;
		}
		if (PendingByPeer.TryGetValue(sender, out var value))
		{
			if (value.RequestId == num)
			{
				SendQuote(sender, value);
			}
			else
			{
				RejectRequest(sender, num, OfferingFailure.Busy);
			}
			return;
		}
		if (!WeatherService.TryGetSupportedKind(kind, out var resolved))
		{
			RejectRequest(sender, num, OfferingFailure.Unavailable);
			return;
		}
		ZDOMan instance = ZDOMan.instance;
		ZDO val2 = ((instance != null) ? instance.GetZDO(val) : null);
		if (val2 == null || val2.GetPrefab() != WeatherAltarPiece.PrefabHash)
		{
			RejectRequest(sender, num, OfferingFailure.InvalidRequest);
			return;
		}
		Vector3 position = val2.GetPosition();
		ZDO playerZdo = GetPlayerZdo(sender);
		if (playerZdo == null || playerZdo.GetOwner() != sender || Vector3.Distance(playerZdo.GetPosition(), position) > 7f)
		{
			RejectRequest(sender, num, OfferingFailure.TooFar);
			return;
		}
		if (num2 != AltarSettings.CoinCost.Value || Math.Abs(num3 - AltarSettings.HealthCost.Value) > 0.01f || num4 != AltarSettings.DurationSeconds.Value)
		{
			RejectRequest(sender, num, OfferingFailure.PriceChanged);
			return;
		}
		PendingByPeer[sender] = new ServerRequest
		{
			RequestId = num,
			AltarId = val,
			Kind = resolved,
			CoinCost = AltarSettings.CoinCost.Value,
			HealthCost = AltarSettings.HealthCost.Value,
			DurationSeconds = AltarSettings.DurationSeconds.Value
		};
		SendQuote(sender, PendingByPeer[sender]);
	}

	private static ZDO GetPlayerZdo(long senderUid)
	{
		//IL_001f: 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_0024: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: 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 (senderUid == ZNet.GetUID())
		{
			Player localPlayer = Player.m_localPlayer;
			ZDOID val = (((Object)(object)localPlayer != (Object)null) ? ((Character)localPlayer).GetZDOID() : ZDOID.None);
			if (!(val != ZDOID.None))
			{
				return null;
			}
			ZDOMan instance = ZDOMan.instance;
			if (instance == null)
			{
				return null;
			}
			return instance.GetZDO(val);
		}
		ZNet instance2 = ZNet.instance;
		ZNetPeer val2 = ((instance2 != null) ? instance2.GetPeer(senderUid) : null);
		if (val2 == null)
		{
			return null;
		}
		ZDOMan instance3 = ZDOMan.instance;
		if (instance3 == null)
		{
			return null;
		}
		return instance3.GetZDO(val2.m_characterID);
	}

	private static void HandlePaymentServer(long sender, ZPackage package)
	{
		if (!TryReadEnvelope(package, out var _))
		{
			return;
		}
		long num;
		bool flag;
		byte b;
		try
		{
			num = package.ReadLong();
			flag = package.ReadBool();
			b = package.ReadByte();
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("Weather Altar: failed to decode Payment: " + ex.Message));
			return;
		}
		CompletedRequest value2;
		if (PendingByPeer.TryGetValue(sender, out var value) && value.RequestId == num)
		{
			PendingByPeer.Remove(sender);
			if (flag && b == 0)
			{
				WeatherService.Commit(value.Kind, value.DurationSeconds);
				CompletedByPeer[sender] = new CompletedRequest
				{
					RequestId = num
				};
				BroadcastStateToClients(sender, num);
			}
			else
			{
				OfferingFailure failure = (OfferingFailure)(Enum.IsDefined(typeof(OfferingFailure), b) ? b : 9);
				RejectRequest(sender, num, failure);
			}
		}
		else if (CompletedByPeer.TryGetValue(sender, out value2) && value2.RequestId == num)
		{
			SendStateSnapshot(sender, sender, num);
		}
		else
		{
			RejectRequest(sender, num, OfferingFailure.InvalidRequest);
		}
	}

	private static void SendStateSnapshot(long recipient, long receiptPeer, long receiptRequest)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(ZNet.instance.GetWorldUID());
		val.Write(WeatherService.Revision);
		val.Write((byte)WeatherService.Kind);
		val.Write(WeatherService.RemainingSeconds());
		val.Write(WeatherService.SupportedMask);
		val.Write(receiptPeer);
		val.Write(receiptRequest);
		SendToClient(recipient, _state, val);
	}

	private static void BroadcastStateToClients(long receiptPeer, long receiptRequest)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		SendStateSnapshot(ZNet.GetUID(), receiptPeer, receiptRequest);
		ZPackage val = new ZPackage();
		val.Write(ZNet.instance.GetWorldUID());
		val.Write(WeatherService.Revision);
		val.Write((byte)WeatherService.Kind);
		val.Write(WeatherService.RemainingSeconds());
		val.Write(WeatherService.SupportedMask);
		val.Write(receiptPeer);
		val.Write(receiptRequest);
		_state.SendPackage(0L, val);
	}

	public static void BroadcastExpiry()
	{
		BroadcastStateToClients(0L, 0L);
	}

	private static void SendQuote(long recipient, ServerRequest request)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		ZPackage val = new ZPackage();
		val.Write(ZNet.instance.GetWorldUID());
		val.Write(request.RequestId);
		val.Write(request.AltarId);
		val.Write((byte)request.Kind);
		val.Write(request.CoinCost);
		val.Write(request.HealthCost);
		val.Write(request.DurationSeconds);
		SendToClient(recipient, _quote, val);
	}

	private static void RejectRequest(long recipient, long requestId, OfferingFailure failure)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		ZPackage val = new ZPackage();
		val.Write(ZNet.instance.GetWorldUID());
		val.Write(requestId);
		val.Write((byte)failure);
		SendToClient(recipient, _reject, val);
	}

	private static void HandleQuoteClient(long sender, ZPackage package)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		if (!IsServerOrigin(sender) || !TryReadEnvelope(package, out var _))
		{
			return;
		}
		long num;
		byte kind;
		int num2;
		float num3;
		int num4;
		try
		{
			num = package.ReadLong();
			package.ReadZDOID();
			kind = package.ReadByte();
			num2 = package.ReadInt();
			num3 = package.ReadSingle();
			num4 = package.ReadInt();
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("Weather Altar: failed to decode Quote: " + ex.Message));
			return;
		}
		if (num != _pendingRequestId)
		{
			return;
		}
		if (_outcomeRecorded)
		{
			SendPayment(num, _paid, _failure);
			return;
		}
		if (!WeatherService.TryGetSupportedKind(kind, out var _) || num2 <= 0 || num3 < 0f || float.IsNaN(num3) || float.IsInfinity(num3) || num4 <= 0)
		{
			RecordOutcome(paid: false, OfferingFailure.InvalidRequest);
			SendPayment(num, paid: false, OfferingFailure.InvalidRequest);
			return;
		}
		OfferingFailure offeringFailure = ValidateLocalPayment();
		if (offeringFailure != OfferingFailure.None)
		{
			RecordOutcome(paid: false, offeringFailure);
			SendPayment(num, paid: false, offeringFailure);
		}
		else
		{
			PayLocally(num2, num3);
			RecordOutcome(paid: true, OfferingFailure.None);
			SendPayment(num, paid: true, OfferingFailure.None);
		}
	}

	private static OfferingFailure ValidateLocalPayment()
	{
		//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_002c: 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)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
		{
			return OfferingFailure.InvalidRequest;
		}
		if (_pendingAltarId == ZDOID.None)
		{
			return OfferingFailure.InvalidRequest;
		}
		if (WeatherAltarPiece.GetDistance(_pendingAltarId) > 5f)
		{
			return OfferingFailure.TooFar;
		}
		if (!WeatherAltarPiece.CheckAccess(_pendingAltarId))
		{
			return OfferingFailure.NoAccess;
		}
		if (CountCoins() < AltarSettings.CoinCost.Value)
		{
			return OfferingFailure.NotEnoughCoins;
		}
		float value = AltarSettings.HealthCost.Value;
		if (((Character)localPlayer).GetHealth() - value < 1f)
		{
			return OfferingFailure.NotEnoughHealth;
		}
		return OfferingFailure.None;
	}

	private static int CountCoins()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return 0;
		}
		string coinName = GetCoinName();
		if (coinName != null)
		{
			return ((Humanoid)localPlayer).GetInventory().CountItems(coinName, -1, true);
		}
		return 0;
	}

	private static void PayLocally(int coinCost, float healthCost)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null))
		{
			string coinName = GetCoinName();
			if (coinName != null)
			{
				((Humanoid)localPlayer).GetInventory().RemoveItem(coinName, coinCost, -1, true);
			}
			((Character)localPlayer).SetHealth(Mathf.Max(1f, ((Character)localPlayer).GetHealth() - healthCost));
			Hud instance = Hud.instance;
			if (instance != null)
			{
				instance.DamageFlash();
			}
		}
	}

	private static string GetCoinName()
	{
		ObjectDB instance = ObjectDB.instance;
		GameObject val = ((instance != null) ? instance.GetItemPrefab("Coins") : null);
		ItemDrop val2 = (((Object)(object)val == (Object)null) ? null : val.GetComponent<ItemDrop>());
		if (!((Object)(object)val2 == (Object)null))
		{
			return val2.m_itemData.m_shared.m_name;
		}
		return null;
	}

	private static void RecordOutcome(bool paid, OfferingFailure failure)
	{
		_paid = paid;
		_failure = failure;
		_outcomeRecorded = true;
	}

	private static void SendPayment(long requestId, bool paid, OfferingFailure failure)
	{
		SendEnvelopeToServer(_payment, delegate(ZPackage package)
		{
			package.Write(requestId);
			package.Write(paid);
			package.Write((byte)failure);
		});
	}

	private static void HandleStateClient(long sender, ZPackage package)
	{
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		if (!IsServerOrigin(sender) || !TryReadEnvelope(package, out var _))
		{
			return;
		}
		long num;
		byte kind;
		float remainingSeconds;
		byte supportedMask;
		long num2;
		long num3;
		try
		{
			num = package.ReadLong();
			kind = package.ReadByte();
			remainingSeconds = package.ReadSingle();
			supportedMask = package.ReadByte();
			num2 = package.ReadLong();
			num3 = package.ReadLong();
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("Weather Altar: failed to decode State: " + ex.Message));
			return;
		}
		int num4;
		if (_pendingRequestId != 0L && num2 == ZNet.GetUID())
		{
			num4 = ((num3 == _pendingRequestId) ? 1 : 0);
			if (num4 != 0)
			{
				RecordOutcome(paid: true, OfferingFailure.None);
			}
		}
		else
		{
			num4 = 0;
		}
		if (!WeatherService.TryGetSupportedKind(kind, out var resolved))
		{
			resolved = WeatherKind.None;
		}
		if (num >= WeatherService.Revision || !WeatherService.EverReceivedState)
		{
			WeatherService.ApplySnapshot(num, resolved, remainingSeconds);
			WeatherService.SupportedMask = supportedMask;
		}
		if (num4 != 0)
		{
			_pendingRequestId = 0L;
			_pendingAltarId = ZDOID.None;
			AltarMenu.OnReceipt(accepted: true);
		}
	}

	private static void HandleRejectClient(long sender, ZPackage package)
	{
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (IsServerOrigin(sender) && TryReadEnvelope(package, out var _))
		{
			long num;
			byte b;
			try
			{
				num = package.ReadLong();
				b = package.ReadByte();
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Weather Altar: failed to decode Reject: " + ex.Message));
				return;
			}
			OfferingFailure failure = (OfferingFailure)(Enum.IsDefined(typeof(OfferingFailure), b) ? b : 2);
			if (_pendingRequestId != 0L && num == _pendingRequestId)
			{
				RecordOutcome(paid: false, failure);
				_pendingRequestId = 0L;
				_pendingAltarId = ZDOID.None;
				AltarMenu.OnFailure(failure);
			}
		}
	}

	private static IEnumerator OnRequestStateServer(long sender, ZPackage package)
	{
		HandleRequestStateServer(sender, package);
		yield break;
	}

	private static IEnumerator OnOfferServer(long sender, ZPackage package)
	{
		HandleOfferServer(sender, package);
		yield break;
	}

	private static IEnumerator OnQuoteServer(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnPaymentServer(long sender, ZPackage package)
	{
		HandlePaymentServer(sender, package);
		yield break;
	}

	private static IEnumerator OnStateServer(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnRejectServer(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnRequestStateClient(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnOfferClient(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnQuoteClient(long sender, ZPackage package)
	{
		HandleQuoteClient(sender, package);
		yield break;
	}

	private static IEnumerator OnPaymentClient(long sender, ZPackage package)
	{
		yield break;
	}

	private static IEnumerator OnStateClient(long sender, ZPackage package)
	{
		HandleStateClient(sender, package);
		yield break;
	}

	private static IEnumerator OnRejectClient(long sender, ZPackage package)
	{
		HandleRejectClient(sender, package);
		yield break;
	}
}
public class WeatherAltarPiece : MonoBehaviour, Interactable, Hoverable
{
	public const string PrefabName = "Mous_WeatherAltar";

	private const string BasePrefabName = "guard_stone";

	private float _hoverOffset;

	private static Action _vanillaPrefabsHandler;

	private static float _templateHoverOffset;

	private static bool _registered;

	private ZNetView _nview;

	public static int PrefabHash { get; private set; } = -1;

	public static bool LocalServerRefuseRequests { get; private set; }

	public static void Register()
	{
		_vanillaPrefabsHandler = delegate
		{
			OnVanillaPrefabsAvailable();
		};
		PrefabManager.OnVanillaPrefabsAvailable += _vanillaPrefabsHandler;
	}

	private static void OnVanillaPrefabsAvailable()
	{
		//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_0020: 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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		PrefabManager.OnVanillaPrefabsAvailable -= _vanillaPrefabsHandler;
		_vanillaPrefabsHandler = null;
		PieceConfig val = new PieceConfig
		{
			Name = "$piece_mous_weatheraltar",
			Description = "$piece_mous_weatheraltar_desc",
			PieceTable = "Hammer",
			AllowedInDungeons = false
		};
		CustomPiece val2 = new CustomPiece("Mous_WeatherAltar", "guard_stone", val);
		GameObject piecePrefab = val2.PiecePrefab;
		if ((Object)(object)piecePrefab == (Object)null)
		{
			Logger.LogError((object)"Weather Altar: failed to clone guard_stone. Offerings are disabled.");
			LocalServerRefuseRequests = true;
			return;
		}
		PrivateArea component = piecePrefab.GetComponent<PrivateArea>();
		if ((Object)(object)component == (Object)null)
		{
			Logger.LogError((object)"Weather Altar: cloned prefab lacks PrivateArea. Offerings are disabled.");
			LocalServerRefuseRequests = true;
			return;
		}
		Piece component2 = piecePrefab.GetComponent<Piece>();
		WearNTear component3 = piecePrefab.GetComponent<WearNTear>();
		ZNetView component4 = piecePrefab.GetComponent<ZNetView>();
		if ((Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null || (Object)(object)component4 == (Object)null)
		{
			Logger.LogError((object)"Weather Altar: cloned prefab lacks Piece/WearNTear/ZNetView. Offerings are disabled.");
			LocalServerRefuseRequests = true;
			return;
		}
		PrefabHash = StringExtensionMethods.GetStableHashCode("Mous_WeatherAltar");
		_templateHoverOffset = component.m_hoverOffset;
		if ((Object)(object)component.m_enabledEffect != (Object)null)
		{
			component.m_enabledEffect.SetActive(false);
		}
		if ((Object)(object)component.m_areaMarker != (Object)null && (Object)(object)((Component)component.m_areaMarker).gameObject != (Object)null)
		{
			((Component)component.m_areaMarker).gameObject.SetActive(false);
		}
		if ((Object)(object)component.m_connectEffect != (Object)null)
		{
			component.m_connectEffect.SetActive(false);
		}
		if ((Object)(object)component.m_inRangeEffect != (Object)null)
		{
			component.m_inRangeEffect.SetActive(false);
		}
		Object.DestroyImmediate((Object)(object)component);
		piecePrefab.AddComponent<WeatherAltarPiece>()._hoverOffset = _templateHoverOffset;
		PieceManager.Instance.AddPiece(val2);
		_registered = true;
		CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
		string text = "English";
		localization.AddTranslation(ref text, new Dictionary<string, string>
		{
			{ "piece_mous_weatheraltar", "Weather Altar" },
			{ "piece_mous_weatheraltar_desc", "Offer coins and blood to change the weather for everyone." },
			{ "mous_weatheraltar_prompt", "Make an offering" },
			{ "mous_weatheraltar_hint", "Affects outdoor weather worldwide. Events and interiors take priority." },
			{ "mous_weatheraltar_noaccess", "You do not have access." },
			{ "mous_weatheraltar_toofar", "Too far away." },
			{ "mous_weatheraltar_unavailable", "This weather is unavailable." },
			{ "mous_weatheraltar_needcoins", "Not enough coins ($1 needed)." },
			{ "mous_weatheraltar_needhealth", "You must have at least $1 HP." },
			{ "mous_weatheraltar_pricechanged", "Price changed - please confirm again." },
			{ "mous_weatheraltar_busy", "Another offering is already in progress." },
			{ "mous_weatheraltar_paymentfailed", "Offering failed." },
			{ "mous_weatheraltar_invalid", "Offering rejected." },
			{ "mous_weatheraltar_accepted", "Offering accepted." }
		});
		Logger.LogInfo((object)"Weather Altar: registered piece from guard_stone clone.");
	}

	private void Awake()
	{
		_nview = ((Component)this).GetComponent<ZNetView>();
	}

	public ZDOID GetZDOID()
	{
		//IL_0029: 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_003d: Unknown result type (might be due to invalid IL or missing references)
		ZNetView nview = _nview;
		return (ZDOID)(((??)((nview == null) ? ((ZDOID?)null) : nview.GetZDO()?.m_uid)) ?? ZDOID.None);
	}

	public static float GetDistance(ZDOID altarId)
	{
		//IL_0012: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		ZDOMan instance = ZDOMan.instance;
		ZDO val = ((instance != null) ? instance.GetZDO(altarId) : null);
		if ((Object)(object)localPlayer == (Object)null || val == null)
		{
			return float.MaxValue;
		}
		return Vector3.Distance(((Component)localPlayer).transform.position, val.GetPosition());
	}

	public static bool CheckAccess(ZDOID altarId)
	{
		//IL_000c: 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)
		ZDOMan instance = ZDOMan.instance;
		ZDO val = ((instance != null) ? instance.GetZDO(altarId) : null);
		if (val == null)
		{
			return false;
		}
		return PrivateArea.CheckAccess(val.GetPosition(), 0f, true, false);
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		//IL_0073: 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_008e: Unknown result type (might be due to invalid IL or missing references)
		if (hold)
		{
			return false;
		}
		Player val = (Player)(object)((user is Player) ? user : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
		{
			return false;
		}
		if (!_registered || LocalServerRefuseRequests || (Object)(object)_nview == (Object)null || !_nview.IsValid())
		{
			return false;
		}
		ZDO zDO = _nview.GetZDO();
		if (zDO == null || zDO.GetPrefab() != PrefabHash)
		{
			return false;
		}
		if (Vector3.Distance(((Component)val).transform.position, zDO.GetPosition()) > val.m_maxInteractDistance)
		{
			return false;
		}
		if (!PrivateArea.CheckAccess(zDO.GetPosition(), 0f, true, false))
		{
			((Character)Player.m_localPlayer).Message((MessageType)2, "$mous_weatheraltar_noaccess", 0, (Sprite)null, false);
			return true;
		}
		if (!WeatherService.StateKnown)
		{
			OfferingRpc.RequestState();
			return true;
		}
		AltarMenu.Open(this);
		return true;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}

	public string GetHoverName()
	{
		return Localization.instance.Localize("$piece_mous_weatheraltar");
	}

	public string GetHoverText()
	{
		return Localization.instance.Localize("$piece_mous_weatheraltar\n[<color=yellow><b>$KEY_Use</b></color>] $mous_weatheraltar_prompt");
	}

	public float GetHoverOffset()
	{
		return _hoverOffset;
	}
}
[BepInPlugin("com.mous.weatheraltar", "Weather Altar", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class WeatherAltarPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.mous.weatheraltar";

	public const string PluginName = "Weather Altar";

	public const string PluginVersion = "1.0.3";

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		AltarSettings.Init(((BaseUnityPlugin)this).Config);
		_harmony = new Harmony("com.mous.weatheraltar");
		_harmony.PatchAll();
		OfferingRpc.Register();
		WeatherAltarPiece.Register();
		Logger.LogInfo((object)"Weather Altar 1.0.3 loaded");
	}

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

	private void Update()
	{
		WeatherService.Update();
		AltarMenu.Update();
	}
}
public enum WeatherKind : byte
{
	None,
	Clear,
	Rain,
	Storm
}
public static class WeatherKindNames
{
	public static readonly string[] Names = new string[3] { "Clear", "Rain", "ThunderStorm" };

	public static bool IsValid(byte value)
	{
		if (value >= 1)
		{
			return value <= 3;
		}
		return false;
	}

	public static string GetEnvName(WeatherKind kind)
	{
		int num = (int)(kind - 1);
		if ((uint)num >= Names.Length)
		{
			return null;
		}
		return Names[num];
	}
}
public static class WeatherService
{
	[HarmonyPatch(typeof(EnvMan), "Awake")]
	public static class EnvManAwakePatch
	{
		private static void Postfix()
		{
			ResetSession();
			ResolvePresets();
		}
	}

	[HarmonyPatch(typeof(EnvMan), "GetEnvironmentOverride")]
	public static class EnvOverridePatch
	{
		private static void Postfix(ref string __result)
		{
			if (!string.IsNullOrEmpty(__result))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).InInterior() && HasActive)
			{
				string envName = WeatherKindNames.GetEnvName(Kind);
				if (!string.IsNullOrEmpty(envName))
				{
					__result = envName;
				}
			}
		}
	}

	private static double _deadline;

	private static bool _deadlineActive;

	private static readonly bool[] Supported = new bool[4];

	public static WeatherKind Kind { get; private set; } = WeatherKind.None;

	public static long Revision { get; private set; }

	public static byte SupportedMask { get; set; }

	public static bool HasActive
	{
		get
		{
			if (Kind != WeatherKind.None && _deadlineActive)
			{
				return RemainingSeconds() > 0f;
			}
			return false;
		}
	}

	public static bool StateKnown { get; private set; }

	public static bool EverReceivedState { get; private set; }

	public static float RemainingSeconds()
	{
		if (!_deadlineActive)
		{
			return 0f;
		}
		double num = _deadline - Time.realtimeSinceStartupAsDouble;
		if (!(num > 0.0))
		{
			return 0f;
		}
		return (float)num;
	}

	public static void ResetSession()
	{
		Kind = WeatherKind.None;
		Revision = 0L;
		_deadline = 0.0;
		_deadlineActive = false;
		StateKnown = false;
		EverReceivedState = false;
		SupportedMask = 0;
		for (int i = 0; i < Supported.Length; i++)
		{
			Supported[i] = false;
		}
	}

	public static void ResolvePresets()
	{
		SupportedMask = 0;
		for (int i = 0; i < Supported.Length; i++)
		{
			Supported[i] = false;
		}
		EnvMan instance = EnvMan.instance;
		if (!Object.op_Implicit((Object)(object)instance))
		{
			return;
		}
		for (byte b = 1; b <= 3; b++)
		{
			string envName = WeatherKindNames.GetEnvName((WeatherKind)b);
			if (instance.m_environments.Exists((EnvSetup env) => env.m_name == envName))
			{
				Supported[b] = true;
				SupportedMask |= (byte)(1 << b - 1);
			}
			else
			{
				Logger.LogWarning((object)("Weather Altar: environment '" + envName + "' not found in this world; choice disabled."));
			}
		}
		StateKnown = true;
	}

	public static bool IsSupported(byte kind)
	{
		if (!WeatherKindNames.IsValid(kind))
		{
			return false;
		}
		return Supported[kind];
	}

	public static bool TryGetSupportedKind(byte kind, out WeatherKind resolved)
	{
		resolved = WeatherKind.None;
		if (!WeatherKindNames.IsValid(kind) || !Supported[kind])
		{
			return false;
		}
		resolved = (WeatherKind)kind;
		return true;
	}

	public static void Commit(WeatherKind kind, int durationSeconds)
	{
		Kind = kind;
		Revision++;
		if (kind == WeatherKind.None)
		{
			_deadlineActive = false;
			_deadline = 0.0;
		}
		else
		{
			_deadlineActive = true;
			_deadline = Time.realtimeSinceStartupAsDouble + (double)Math.Max(0, durationSeconds);
		}
	}

	public static void ApplySnapshot(long revision, WeatherKind kind, float remainingSeconds)
	{
		Revision = revision;
		Kind = kind;
		_deadlineActive = kind != WeatherKind.None && remainingSeconds > 0f;
		_deadline = Time.realtimeSinceStartupAsDouble + (double)Math.Max(0f, remainingSeconds);
		StateKnown = true;
		EverReceivedState = true;
	}

	public static void Update()
	{
		if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && Kind != WeatherKind.None && _deadlineActive && RemainingSeconds() <= 0f)
		{
			Commit(WeatherKind.None, 0);
			OfferingRpc.BroadcastExpiry();
		}
	}

	public static void Shutdown()
	{
		ResetSession();
	}
}