Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Weather Altar v1.0.3
BepInEx/plugins/WeatherAltar.dll
Decompiled a week agousing 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(); } }