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);
}
}
}
}