Decompiled source of Warming Lava v3.0.0

tony4twenty-Warming Lava.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using UnityEngine;
using Zorro.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Warming Lava")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Warming Lava")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f5351afc-7109-4520-8347-767a2b39bc28")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Warming_Lava
{
	[BepInPlugin("tony4twentys.Warming_Lava", "Warming Lava", "3.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class WarmingLavaPlugin : BaseUnityPlugin
	{
		private readonly struct LavaHit
		{
			public readonly string SourceType;

			public readonly string Name;

			public readonly float Distance;

			public readonly float RadiusUsed;

			public LavaHit(string sourceType, string name, float distance, float radiusUsed)
			{
				SourceType = sourceType;
				Name = name;
				Distance = distance;
				RadiusUsed = radiusUsed;
			}
		}

		public const string PluginGuid = "tony4twentys.Warming_Lava";

		public const string PluginName = "Warming Lava";

		public const string PluginVersion = "3.0.0";

		private const float LavaCacheInterval = 4f;

		private const float CheckInterval = 1f;

		private const float ConfigSliderMax = 10f;

		private const float RiversFullMeters = 10f;

		private const float TidesFullMeters = 16.8f;

		private const float RisingFullMeters = 12f;

		private const float MagmaFullMeters = 3.5f;

		private const float FullStrengthDistance = 1f;

		private const float EdgeStrengthFactor = 0.1f;

		private ConfigEntry<float> _maxWarmingPerSecond;

		private ConfigEntry<bool> _overheat;

		private ConfigEntry<bool> _debugLogging;

		private ConfigEntry<bool> _enableLavaRivers;

		private ConfigEntry<float> _lavaRiversWarmthRadius;

		private ConfigEntry<bool> _enableLavaTides;

		private ConfigEntry<float> _lavaTidesWarmthRadius;

		private ConfigEntry<bool> _enableLavaRising;

		private ConfigEntry<float> _lavaRisingWarmthRadius;

		private ConfigEntry<bool> _enableMagmaRocks;

		private ConfigEntry<float> _magmaRockWarmthRadius;

		private LavaRiver[] _lavaRivers = Array.Empty<LavaRiver>();

		private MovingLava[] _movingLavas = Array.Empty<MovingLava>();

		private LavaTides[] _lavaTides = Array.Empty<LavaTides>();

		private readonly List<Transform> _magmaRocks = new List<Transform>(64);

		private float _nextCacheTime;

		internal static WarmingLavaPlugin Instance { get; private set; }

		private WarmingSyncedSettings Effective => GetEffectiveSettings();

		private void Awake()
		{
			Instance = this;
			_maxWarmingPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "MaxWarmingPerSecond", 0.1f, "Max Hot added / Cold subtracted per second when within 1m of a source. Falls off with distance to 10% of this value at the warmth radius edge.");
			_overheat = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "Overheat", false, "When true, add Hot near warmth sources (Hot cancels Cold first). When false, only subtract Cold. Host-synced in multiplayer; disabled in client-only fallback.");
			_debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "DebugLogging", false, "When true, log active 1s checks (not while dormant). Local only — not host-synced.");
			_enableLavaRivers = ((BaseUnityPlugin)this).Config.Bind<bool>("Sources", "EnableLavaRivers", true, "Detect LavaRiver splines.");
			_lavaRiversWarmthRadius = BindScaledRadius("LavaRiversWarmthRadius", "Lava rivers. Slider 0 = off; 10 = {0}m.", 10f);
			_enableLavaTides = ((BaseUnityPlugin)this).Config.Bind<bool>("Sources", "EnableLavaTides", true, "Detect Caldera LavaTides floor lava.");
			_lavaTidesWarmthRadius = BindScaledRadius("LavaTidesWarmthRadius", "Lava tides. Slider 0 = off; 10 = {0}m.", 16.8f);
			_enableLavaRising = ((BaseUnityPlugin)this).Config.Bind<bool>("Sources", "EnableLavaRising", true, "Detect Kiln LavaRising plane (and MovingLava).");
			_lavaRisingWarmthRadius = BindScaledRadius("LavaRisingWarmthRadius", "Rising lava. Slider 0 = off; 10 = {0}m.", 12f);
			_enableMagmaRocks = ((BaseUnityPlugin)this).Config.Bind<bool>("Sources", "EnableMagmaRocks", true, "Detect Rock_MagmaRock props.");
			_magmaRockWarmthRadius = BindScaledRadius("MagmaRockWarmthRadius", "Magma rocks. Slider 0 = off; 10 = {0}m.", 3.5f);
			((BaseUnityPlugin)this).Config.SettingChanged += OnConfigSettingChanged;
			WarmingModAuthorizationService.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[Warming Lava] v3.0.0 loaded. " + $"MaxWarming={_maxWarmingPerSecond.Value:0.###}/s " + "Rivers=" + Fmt(_enableLavaRivers, _lavaRiversWarmthRadius, 10f) + " Tides=" + Fmt(_enableLavaTides, _lavaTidesWarmthRadius, 16.8f) + " Rising=" + Fmt(_enableLavaRising, _lavaRisingWarmthRadius, 12f) + " Magma=" + Fmt(_enableMagmaRocks, _magmaRockWarmthRadius, 3.5f) + " " + $"Overheat={_overheat.Value} Debug={_debugLogging.Value}"));
			((MonoBehaviour)this).StartCoroutine(WarmthTickLoop());
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.SettingChanged -= OnConfigSettingChanged;
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void OnConfigSettingChanged(object sender, SettingChangedEventArgs e)
		{
			if ((object)e.ChangedSetting != _debugLogging)
			{
				WarmingModAuthorizationService.OnHostConfigChangedLocally();
			}
		}

		internal void LogAlways(string message)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)message);
		}

		internal WarmingSyncedSettings BuildLocalSnapshot()
		{
			return new WarmingSyncedSettings
			{
				MaxWarmingPerSecond = _maxWarmingPerSecond.Value,
				Overheat = _overheat.Value,
				EnableLavaRivers = _enableLavaRivers.Value,
				LavaRiversWarmthRadius = _lavaRiversWarmthRadius.Value,
				EnableLavaTides = _enableLavaTides.Value,
				LavaTidesWarmthRadius = _lavaTidesWarmthRadius.Value,
				EnableLavaRising = _enableLavaRising.Value,
				LavaRisingWarmthRadius = _lavaRisingWarmthRadius.Value,
				EnableMagmaRocks = _enableMagmaRocks.Value,
				MagmaRockWarmthRadius = _magmaRockWarmthRadius.Value
			};
		}

		internal WarmingSyncedSettings GetEffectiveSettings()
		{
			if (WarmingModAuthorizationService.IsClientOnlyFallback())
			{
				return BuildLocalSnapshot();
			}
			if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && WarmingModAuthorizationService.IsHostAuthorized && WarmingHostConfigSyncService.HasRemoteHostSettings)
			{
				return WarmingHostConfigSyncService.RemoteHostSettings;
			}
			return BuildLocalSnapshot();
		}

		private ConfigEntry<float> BindScaledRadius(string key, string descriptionFormat, float fullMeters)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<float>("Settings", key, 10f, new ConfigDescription(string.Format(descriptionFormat, fullMeters.ToString("0.##")), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
		}

		private static string Fmt(ConfigEntry<bool> enabled, ConfigEntry<float> slider, float fullMeters)
		{
			if (!enabled.Value)
			{
				return "off";
			}
			return $"{EffectiveMeters(slider.Value, fullMeters):0.##}m(cfg {slider.Value:0.#})";
		}

		private static float EffectiveMeters(float slider01to10, float fullMeters)
		{
			if (slider01to10 <= 0f)
			{
				return 0f;
			}
			return Mathf.Clamp(slider01to10, 0f, 10f) / 10f * fullMeters;
		}

		private static float DistanceStrength(float distance, float radius)
		{
			if (radius <= 0f || distance > radius)
			{
				return 0f;
			}
			if (radius <= 1f || distance <= 1f)
			{
				return 1f;
			}
			float num = (distance - 1f) / (radius - 1f);
			return Mathf.Lerp(1f, 0.1f, Mathf.Clamp01(num));
		}

		private IEnumerator WarmthTickLoop()
		{
			WaitForSecondsRealtime wait = new WaitForSecondsRealtime(1f);
			while (true)
			{
				TryApplyLavaEffects(1f);
				yield return wait;
			}
		}

		private void TryApplyLavaEffects(float interval)
		{
			//IL_00e0: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			bool value = _debugLogging.Value;
			if (WarmingModAuthorizationService.IsWaitingForHostConfig())
			{
				if (value)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[Warming Lava] Waiting for host config snapshot — warmth paused.");
				}
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || localCharacter.data.dead)
			{
				return;
			}
			CharacterAfflictions val = localCharacter.refs?.afflictions;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			WarmingSyncedSettings effective = Effective;
			bool flag = WarmingModAuthorizationService.IsClientOnlyFallback();
			bool flag2 = !flag && effective.Overheat;
			float currentStatus = val.GetCurrentStatus((STATUSTYPE)2);
			if (!flag2 && currentStatus <= 0f)
			{
				return;
			}
			RefreshLavaCacheIfNeeded(effective);
			Vector3 center = localCharacter.Center;
			LavaHit nearest;
			string sourcesInRadius;
			bool flag3 = TryFindWarmthSources(center, effective, out nearest, out sourcesInRadius);
			if (value)
			{
				string text = (flag ? "fallback" : (WarmingModAuthorizationService.CanUseFullGameplay() ? "synced" : "local"));
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Check: mode={1} segment={2} biome={3} time={4} cold={5:F3} overheat={6} lava={7}", "Warming Lava", text, GetSegmentLabel(), GetBiomeLabel(), GetTimeOfDayLabel(), currentStatus, flag2, sourcesInRadius));
			}
			if (!flag3)
			{
				return;
			}
			float num = DistanceStrength(nearest.Distance, nearest.RadiusUsed);
			float num2 = effective.MaxWarmingPerSecond * num * interval;
			if (!(num2 <= 0f))
			{
				string text2;
				if (flag2)
				{
					val.AddStatus((STATUSTYPE)8, num2, false, true, true);
					text2 = "addHot";
				}
				else
				{
					val.SubtractStatus((STATUSTYPE)2, num2, false, false);
					text2 = "reduceCold";
				}
				if (value)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] Applied: {1} amount={2:F3} strength={3:F2} nearest={4} '{5}' dist={6:F2}m / radius={7:F2}m", "Warming Lava", text2, num2, num, nearest.SourceType, nearest.Name, nearest.Distance, nearest.RadiusUsed));
				}
			}
		}

		private void RefreshLavaCacheIfNeeded(WarmingSyncedSettings settings)
		{
			if (!(Time.unscaledTime < _nextCacheTime))
			{
				_nextCacheTime = Time.unscaledTime + 4f;
				_lavaRivers = (settings.EnableLavaRivers ? Object.FindObjectsByType<LavaRiver>((FindObjectsSortMode)0) : Array.Empty<LavaRiver>());
				_movingLavas = (settings.EnableLavaRising ? Object.FindObjectsByType<MovingLava>((FindObjectsSortMode)0) : Array.Empty<MovingLava>());
				_lavaTides = (settings.EnableLavaTides ? Object.FindObjectsByType<LavaTides>((FindObjectsSortMode)0) : Array.Empty<LavaTides>());
				_magmaRocks.Clear();
				if (settings.EnableMagmaRocks)
				{
					CollectMagmaRocks();
				}
			}
		}

		private void CollectMagmaRocks()
		{
			Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsSortMode)0);
			foreach (Transform val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((Object)val).name;
					if (StartsWithIgnoreCase(name, "Rock_MagmaRock") || StartsWithIgnoreCase(name, "MagmaRock"))
					{
						_magmaRocks.Add(val);
					}
				}
			}
		}

		private bool TryFindWarmthSources(Vector3 pos, WarmingSyncedSettings settings, out LavaHit nearest, out string sourcesInRadius)
		{
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			nearest = default(LavaHit);
			float bestDist = float.MaxValue;
			bool found = false;
			StringBuilder list = null;
			float num = EffectiveMeters(settings.LavaRiversWarmthRadius, 10f);
			float num2 = EffectiveMeters(settings.LavaTidesWarmthRadius, 16.8f);
			float num3 = EffectiveMeters(settings.LavaRisingWarmthRadius, 12f);
			float num4 = EffectiveMeters(settings.MagmaRockWarmthRadius, 3.5f);
			if (settings.EnableLavaTides && num2 > 0f)
			{
				for (int i = 0; i < _lavaTides.Length; i++)
				{
					LavaTides val = _lavaTides[i];
					if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled)
					{
						float num5 = DistanceToLiveRendererOrTransform(((Component)val).transform, pos);
						if (!(num5 > num2))
						{
							ConsiderHit(ref list, ref nearest, ref bestDist, ref found, "LavaTides", ((Object)val).name, num5, num2);
						}
					}
				}
			}
			if (settings.EnableLavaRivers && num > 0f)
			{
				for (int j = 0; j < _lavaRivers.Length; j++)
				{
					LavaRiver val2 = _lavaRivers[j];
					if ((Object)(object)val2 == (Object)null || val2.frames == null)
					{
						continue;
					}
					float num6 = float.MaxValue;
					for (int k = 0; k < val2.frames.Count; k++)
					{
						float num7 = Vector3.Distance(pos, val2.frames[k].position);
						if (num7 < num6)
						{
							num6 = num7;
						}
					}
					if (!(num6 > num))
					{
						ConsiderHit(ref list, ref nearest, ref bestDist, ref found, "LavaRiver", ((Object)val2).name, num6, num);
					}
				}
			}
			if (settings.EnableLavaRising && num3 > 0f && TryDistanceToLavaRising(pos, out var dist, out var name) && dist <= num3)
			{
				ConsiderHit(ref list, ref nearest, ref bestDist, ref found, "LavaRising", name, dist, num3);
			}
			if (settings.EnableLavaRising && num3 > 0f)
			{
				for (int l = 0; l < _movingLavas.Length; l++)
				{
					MovingLava val3 = _movingLavas[l];
					if (!((Object)(object)val3 == (Object)null))
					{
						float num8 = DistanceToLiveRendererOrTransform(((Component)val3).transform, pos);
						if (!(num8 > num3))
						{
							ConsiderHit(ref list, ref nearest, ref bestDist, ref found, "MovingLava", ((Object)val3).name, num8, num3);
						}
					}
				}
			}
			if (settings.EnableMagmaRocks && num4 > 0f)
			{
				for (int m = 0; m < _magmaRocks.Count; m++)
				{
					Transform val4 = _magmaRocks[m];
					if (!((Object)(object)val4 == (Object)null))
					{
						float num9 = DistanceToMagmaRock(val4, pos);
						if (!(num9 > num4))
						{
							ConsiderHit(ref list, ref nearest, ref bestDist, ref found, "MagmaRock", ((Object)val4).name, num9, num4);
						}
					}
				}
			}
			sourcesInRadius = ((found && list != null) ? list.ToString() : "none");
			return found;
		}

		private static void ConsiderHit(ref StringBuilder list, ref LavaHit nearest, ref float bestDist, ref bool found, string sourceType, string name, float dist, float radiusUsed)
		{
			AppendHit(ref list, sourceType, name, dist, dist <= 0.05f);
			if (dist < bestDist)
			{
				bestDist = dist;
				nearest = new LavaHit(sourceType, name, dist, radiusUsed);
				found = true;
			}
		}

		private static void AppendHit(ref StringBuilder list, string sourceType, string name, float dist, bool inside)
		{
			if (list == null)
			{
				list = new StringBuilder(128);
			}
			else
			{
				list.Append(" | ");
			}
			list.Append(sourceType).Append(" '").Append(name)
				.Append("' dist=")
				.Append(dist.ToString("F2"))
				.Append('m');
			if (inside)
			{
				list.Append(" (inside)");
			}
		}

		private static bool TryDistanceToLavaRising(Vector3 pos, out float dist, out string name)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			dist = float.MaxValue;
			name = "LavaRising";
			LavaRising val = null;
			try
			{
				val = Singleton<LavaRising>.Instance;
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null && (Object)(object)Singleton<MapHandler>.Instance != (Object)null)
			{
				val = Singleton<MapHandler>.Instance.lavaRising;
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val.lava == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)val.lava).transform;
			name = ((Object)transform).name;
			dist = DistanceToLiveRendererOrTransform(transform, pos);
			return true;
		}

		private static float DistanceToMagmaRock(Transform rock, Vector3 pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			float num = DistanceToLiveRendererOrTransform(rock, pos);
			float num2 = Vector3.Distance(pos, rock.position);
			if (num <= 0.05f && num2 > 1f)
			{
				return num2;
			}
			return num;
		}

		private static float DistanceToLiveRendererOrTransform(Transform root, Vector3 pos)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer componentInChildren = ((Component)root).GetComponentInChildren<MeshRenderer>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Bounds bounds = ((Renderer)componentInChildren).bounds;
				return Vector3.Distance(pos, ((Bounds)(ref bounds)).ClosestPoint(pos));
			}
			return Vector3.Distance(pos, root.position);
		}

		private static bool StartsWithIgnoreCase(string value, string prefix)
		{
			return value?.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) ?? false;
		}

		private static string GetSegmentLabel()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null)
				{
					return "unknown";
				}
				return ((object)Singleton<MapHandler>.Instance.GetCurrentSegment()/*cast due to .constrained prefix*/).ToString();
			}
			catch
			{
				return "unknown";
			}
		}

		private static string GetBiomeLabel()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null)
				{
					return "unknown";
				}
				return ((object)Singleton<MapHandler>.Instance.GetCurrentBiome()/*cast due to .constrained prefix*/).ToString();
			}
			catch
			{
				return "unknown";
			}
		}

		private static string GetTimeOfDayLabel()
		{
			try
			{
				DayNightManager instance = DayNightManager.instance;
				if ((Object)(object)instance == (Object)null)
				{
					return "unknown";
				}
				return $"{instance.TimeOfDayString()} ({instance.timeOfDay:F2})";
			}
			catch
			{
				return "unknown";
			}
		}
	}
	internal struct WarmingSyncedSettings
	{
		internal float MaxWarmingPerSecond;

		internal bool Overheat;

		internal bool EnableLavaRivers;

		internal float LavaRiversWarmthRadius;

		internal bool EnableLavaTides;

		internal float LavaTidesWarmthRadius;

		internal bool EnableLavaRising;

		internal float LavaRisingWarmthRadius;

		internal bool EnableMagmaRocks;

		internal float MagmaRockWarmthRadius;
	}
	internal static class WarmingHostConfigSyncService
	{
		public const int SchemaVersion = 1;

		public const char PairSeparator = ';';

		public const char KeyValueSeparator = '=';

		internal static bool HasRemoteHostSettings { get; private set; }

		internal static WarmingSyncedSettings RemoteHostSettings { get; private set; }

		internal static void ClearRemoteHostConfig()
		{
			HasRemoteHostSettings = false;
			RemoteHostSettings = default(WarmingSyncedSettings);
		}

		internal static void ApplyRemoteSnapshot(string payload)
		{
			if (!PhotonNetwork.IsMasterClient && !string.IsNullOrEmpty(payload))
			{
				if (!TryDeserialize(payload, out var settings))
				{
					WarmingLavaPlugin.Instance?.LogAlways("[Warming Lava] Failed to apply host config snapshot.");
					return;
				}
				HasRemoteHostSettings = true;
				RemoteHostSettings = settings;
				WarmingLavaPlugin.Instance?.LogAlways("[Warming Lava] Applied host config snapshot.");
			}
		}

		internal static string Serialize(WarmingSyncedSettings s)
		{
			StringBuilder stringBuilder = new StringBuilder(256);
			Append(stringBuilder, "v", 1.ToString(CultureInfo.InvariantCulture));
			Append(stringBuilder, "max", F(s.MaxWarmingPerSecond));
			Append(stringBuilder, "overheat", B(s.Overheat));
			Append(stringBuilder, "enRivers", B(s.EnableLavaRivers));
			Append(stringBuilder, "rivers", F(s.LavaRiversWarmthRadius));
			Append(stringBuilder, "enTides", B(s.EnableLavaTides));
			Append(stringBuilder, "tides", F(s.LavaTidesWarmthRadius));
			Append(stringBuilder, "enRising", B(s.EnableLavaRising));
			Append(stringBuilder, "rising", F(s.LavaRisingWarmthRadius));
			Append(stringBuilder, "enMagma", B(s.EnableMagmaRocks));
			Append(stringBuilder, "magma", F(s.MagmaRockWarmthRadius));
			return stringBuilder.ToString();
		}

		internal static bool TryDeserialize(string payload, out WarmingSyncedSettings settings)
		{
			settings = default(WarmingSyncedSettings);
			if (string.IsNullOrEmpty(payload))
			{
				return false;
			}
			settings = default(WarmingSyncedSettings);
			string[] array = payload.Split(new char[1] { ';' });
			int result = 0;
			bool flag = false;
			foreach (string text in array)
			{
				if (string.IsNullOrEmpty(text))
				{
					continue;
				}
				int num = text.IndexOf('=');
				if (num > 0)
				{
					string text2 = text.Substring(0, num);
					string text3 = text.Substring(num + 1);
					switch (text2)
					{
					case "v":
						flag = int.TryParse(text3, NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
						break;
					case "max":
						float.TryParse(text3, NumberStyles.Float, CultureInfo.InvariantCulture, out settings.MaxWarmingPerSecond);
						break;
					case "overheat":
						settings.Overheat = text3 == "1";
						break;
					case "enRivers":
						settings.EnableLavaRivers = text3 == "1";
						break;
					case "rivers":
						float.TryParse(text3, NumberStyles.Float, CultureInfo.InvariantCulture, out settings.LavaRiversWarmthRadius);
						break;
					case "enTides":
						settings.EnableLavaTides = text3 == "1";
						break;
					case "tides":
						float.TryParse(text3, NumberStyles.Float, CultureInfo.InvariantCulture, out settings.LavaTidesWarmthRadius);
						break;
					case "enRising":
						settings.EnableLavaRising = text3 == "1";
						break;
					case "rising":
						float.TryParse(text3, NumberStyles.Float, CultureInfo.InvariantCulture, out settings.LavaRisingWarmthRadius);
						break;
					case "enMagma":
						settings.EnableMagmaRocks = text3 == "1";
						break;
					case "magma":
						float.TryParse(text3, NumberStyles.Float, CultureInfo.InvariantCulture, out settings.MagmaRockWarmthRadius);
						break;
					}
				}
			}
			return flag && result == 1;
		}

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

		private static string B(bool value)
		{
			return value ? "1" : "0";
		}

		private static void Append(StringBuilder builder, string key, string value)
		{
			if (builder.Length > 0)
			{
				builder.Append(';');
			}
			builder.Append(key);
			builder.Append('=');
			builder.Append(value ?? string.Empty);
		}
	}
	internal static class WarmingModAuthorizationService
	{
		private sealed class RoomLifecycleCallbacks : MonoBehaviourPunCallbacks
		{
			public override void OnLeftRoom()
			{
				OnLeftRoomOrDisconnected();
			}

			public override void OnDisconnected(DisconnectCause cause)
			{
				OnLeftRoomOrDisconnected();
			}
		}

		public const string PhotonCustomPropsPluginGuid = "com.snosz.photoncustompropsutils";

		public const string RoomConfigPropertyKey = "warmingLavaConfigV1";

		private static PhotonScopedManager _photonManager;

		private static bool _photonManagerReady;

		private static string _pendingHostConfigPayload;

		private static RoomLifecycleCallbacks _roomCallbacks;

		internal static bool IsHostAuthorized { get; private set; }

		internal static void Initialize()
		{
			Networking.AddHostHasPluginListeners("tony4twentys.Warming_Lava", (Action)OnHostHasMod, (Action)OnHostMissingMod);
			if (PhotonCustomPropsUtilsPlugin.IsReady)
			{
				SetupPhotonManager();
			}
			else
			{
				PhotonCustomPropsUtilsPlugin.OnReady += SetupPhotonManager;
			}
			EnsureRoomCallbacks();
			if (!PhotonNetwork.InRoom)
			{
				SetSoloAuthorized();
			}
		}

		private static void EnsureRoomCallbacks()
		{
			if (Object.op_Implicit((Object)(object)_roomCallbacks))
			{
				return;
			}
			WarmingLavaPlugin instance = WarmingLavaPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				_roomCallbacks = ((Component)instance).gameObject.GetComponent<RoomLifecycleCallbacks>();
				if (!Object.op_Implicit((Object)(object)_roomCallbacks))
				{
					_roomCallbacks = ((Component)instance).gameObject.AddComponent<RoomLifecycleCallbacks>();
				}
			}
		}

		internal static bool CanUseFullGameplay()
		{
			if (!PhotonNetwork.InRoom)
			{
				return true;
			}
			if (!IsHostAuthorized)
			{
				return false;
			}
			if (PhotonNetwork.IsMasterClient)
			{
				return true;
			}
			return WarmingHostConfigSyncService.HasRemoteHostSettings;
		}

		internal static bool IsClientOnlyFallback()
		{
			return PhotonNetwork.InRoom && !IsHostAuthorized;
		}

		internal static bool IsWaitingForHostConfig()
		{
			return PhotonNetwork.InRoom && IsHostAuthorized && !PhotonNetwork.IsMasterClient && !WarmingHostConfigSyncService.HasRemoteHostSettings;
		}

		internal static void SetSoloAuthorized()
		{
			IsHostAuthorized = true;
			_pendingHostConfigPayload = null;
			WarmingHostConfigSyncService.ClearRemoteHostConfig();
		}

		internal static void OnLeftRoomOrDisconnected()
		{
			_pendingHostConfigPayload = null;
			SetSoloAuthorized();
			WarmingLavaPlugin.Instance?.LogAlways("[Warming Lava] Left room — cleared host config sync; solo defaults restored.");
		}

		private static void SetupPhotonManager()
		{
			if (_photonManagerReady)
			{
				return;
			}
			_photonManagerReady = true;
			_photonManager = PhotonCustomPropsUtilsPlugin.GetManager("tony4twentys.Warming_Lava");
			_photonManager.RegisterOnJoinedRoom((Action<Player>)delegate
			{
				if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && IsHostAuthorized)
				{
					PublishHostConfigIfMaster();
				}
			});
			_photonManager.RegisterRoomProperty<string>("warmingLavaConfigV1", (RoomEventType)2, (Action<string>)delegate(string value)
			{
				if (!PhotonNetwork.IsMasterClient && !string.IsNullOrEmpty(value))
				{
					if (!IsHostAuthorized)
					{
						_pendingHostConfigPayload = value;
					}
					else
					{
						WarmingHostConfigSyncService.ApplyRemoteSnapshot(value);
					}
				}
			});
		}

		private static void OnHostHasMod()
		{
			if (PhotonNetwork.InRoom)
			{
				IsHostAuthorized = true;
				WarmingLavaPlugin.Instance?.LogAlways("[Warming Lava] Host has Warming Lava — full config sync enabled.");
				if (PhotonNetwork.IsMasterClient)
				{
					PublishHostConfigIfMaster();
				}
				else if (!string.IsNullOrEmpty(_pendingHostConfigPayload))
				{
					WarmingHostConfigSyncService.ApplyRemoteSnapshot(_pendingHostConfigPayload);
					_pendingHostConfigPayload = null;
				}
			}
		}

		private static void OnHostMissingMod()
		{
			if (PhotonNetwork.InRoom)
			{
				IsHostAuthorized = false;
				_pendingHostConfigPayload = null;
				WarmingHostConfigSyncService.ClearRemoteHostConfig();
				WarmingLavaPlugin.Instance?.LogAlways("[Warming Lava] Host missing Warming Lava — client-only fallback (Cold reduction only, local radius configs, no Overheat).");
			}
		}

		internal static void OnHostConfigChangedLocally()
		{
			if (!PhotonNetwork.InRoom)
			{
				WarmingHostConfigSyncService.ClearRemoteHostConfig();
			}
			else if (IsHostAuthorized && PhotonNetwork.IsMasterClient)
			{
				PublishHostConfigIfMaster();
			}
		}

		private static void PublishHostConfigIfMaster()
		{
			if (_photonManager != null && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient && IsHostAuthorized && !((Object)(object)WarmingLavaPlugin.Instance == (Object)null))
			{
				WarmingSyncedSettings s = WarmingLavaPlugin.Instance.BuildLocalSnapshot();
				string text = WarmingHostConfigSyncService.Serialize(s);
				_photonManager.SetRoomProperty("warmingLavaConfigV1", (object)text);
			}
		}
	}
}