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 BepInEx;
using BepInEx.Configuration;
using ExitGames.Client.Photon;
using Microsoft.CodeAnalysis;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using PhotonCustomPropsUtils;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Vasodilation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Vasodilation")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15fa7750-965f-4249-837f-3d54157b5401")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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]
[Microsoft.CodeAnalysis.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 VasodilationMod
{
[BepInPlugin("tony4twentys.Vasodilation", "Vasodilation", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class VasodilationPlugin : BaseUnityPlugin, IInRoomCallbacks, IMatchmakingCallbacks
{
[Serializable]
public struct HostCfg
{
public float coldPerSecond;
public float tickSeconds;
public float gateOn;
public float gateOff;
}
[CompilerGenerated]
private sealed class <HostAuthoritativeDriver>d__37 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public VasodilationPlugin <>4__this;
private WaitForSeconds <wait>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <HostAuthoritativeDriver>d__37(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<wait>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<wait>5__1 = new WaitForSeconds(Mathf.Max(0.05f, Synced.tickSeconds));
break;
case 1:
<>1__state = -1;
break;
}
if (<>4__this._allowVaso)
{
if (<>4__this._cfgVerbose.Value)
{
((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[Vaso] Tick loop: applying perSec={Synced.coldPerSecond} total={Synced.tickSeconds}");
}
<>4__this.ApplyTick(Synced.coldPerSecond, Synced.tickSeconds);
}
<>2__current = <wait>5__1;
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const string ROOM_CFG_KEY = "VASO_CFG_V1";
private ConfigEntry<float> _cfgColdPerSecond;
private ConfigEntry<float> _cfgTickSeconds;
private ConfigEntry<float> _cfgGateOn;
private ConfigEntry<float> _cfgGateOff;
private ConfigEntry<bool> _cfgVerbose;
public static HostCfg Synced;
private Coroutine _hostLoop;
private float _runningTickSeconds;
private PhotonScopedManager _photonManager;
public bool IsHost = false;
private bool _allowVaso = false;
private void Awake()
{
_cfgColdPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ColdPerSecond", -0.06f, string.Empty);
_cfgTickSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickSeconds", 1f, string.Empty);
_cfgGateOn = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ColdGateOn", 0.025f, string.Empty);
_cfgGateOff = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ColdGateOff", 0f, string.Empty);
_cfgVerbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogs", false, string.Empty);
Synced = BuildFromHostConfig();
_runningTickSeconds = Synced.tickSeconds;
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Awake: initial cfg built; waiting for scene/Photon events");
}
_cfgColdPerSecond.SettingChanged += delegate
{
OnHostConfigChanged();
};
_cfgTickSeconds.SettingChanged += delegate
{
OnHostConfigChanged();
};
_cfgGateOn.SettingChanged += delegate
{
OnHostConfigChanged();
};
_cfgGateOff.SettingChanged += delegate
{
OnHostConfigChanged();
};
SceneManager.activeSceneChanged += OnSceneChanged;
InitializePhotonManager();
}
private void OnEnable()
{
PhotonNetwork.AddCallbackTarget((object)this);
}
private void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget((object)this);
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnSceneChanged;
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("[Vaso] Scene changed: " + ((Scene)(ref oldScene)).name + " -> " + ((Scene)(ref newScene)).name));
}
RestartHostLoopIfNeeded();
}
public void OnJoinedRoom()
{
CheckHostStatus();
}
public void OnCreatedRoom()
{
}
public void OnCreateRoomFailed(short returnCode, string message)
{
}
public void OnFriendListUpdate(List<FriendInfo> friendList)
{
}
public void OnJoinRandomFailed(short returnCode, string message)
{
}
public void OnJoinRoomFailed(short returnCode, string message)
{
}
void IInRoomCallbacks.OnPlayerEnteredRoom(Player newPlayer)
{
if (PhotonNetwork.IsMasterClient)
{
PublishConfig();
}
}
void IInRoomCallbacks.OnPlayerLeftRoom(Player otherPlayer)
{
}
void IInRoomCallbacks.OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
}
void IInRoomCallbacks.OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
{
}
void IInRoomCallbacks.OnMasterClientSwitched(Player newMasterClient)
{
if (PhotonNetwork.IsMasterClient)
{
PublishConfig();
}
TryStartOrStopHostLoop();
}
private HostCfg BuildFromHostConfig()
{
HostCfg result = default(HostCfg);
result.coldPerSecond = _cfgColdPerSecond.Value;
result.tickSeconds = Mathf.Max(0.05f, _cfgTickSeconds.Value);
result.gateOn = Mathf.Max(0f, _cfgGateOn.Value);
result.gateOff = Mathf.Max(0f, _cfgGateOff.Value);
return result;
}
private static string PackCfg(HostCfg c)
{
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
return c.coldPerSecond.ToString(invariantCulture) + "|" + c.tickSeconds.ToString(invariantCulture) + "|" + c.gateOn.ToString(invariantCulture) + "|" + c.gateOff.ToString(invariantCulture);
}
private static HostCfg UnpackCfg(string s)
{
CultureInfo invariantCulture = CultureInfo.InvariantCulture;
string[] array = (s ?? string.Empty).Split(new char[1] { '|' });
HostCfg hostCfg = default(HostCfg);
hostCfg.coldPerSecond = -0.06f;
hostCfg.tickSeconds = 1f;
hostCfg.gateOn = 0.025f;
hostCfg.gateOff = 0f;
HostCfg result = hostCfg;
if (array.Length >= 4)
{
float.TryParse(array[0], NumberStyles.Float, invariantCulture, out result.coldPerSecond);
float.TryParse(array[1], NumberStyles.Float, invariantCulture, out result.tickSeconds);
float.TryParse(array[2], NumberStyles.Float, invariantCulture, out result.gateOn);
float.TryParse(array[3], NumberStyles.Float, invariantCulture, out result.gateOff);
}
return result;
}
private void OnHostConfigChanged()
{
if (PhotonNetwork.IsMasterClient)
{
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Host config changed; publishing to room");
}
PublishConfig();
}
}
private void PublishConfig()
{
Room currentRoom = PhotonNetwork.CurrentRoom;
if (currentRoom == null)
{
return;
}
Synced = BuildFromHostConfig();
string text = PackCfg(Synced);
if (PhotonNetwork.IsMasterClient && _photonManager != null)
{
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Setting room property via PhotonCustomPropsUtils");
}
_photonManager.SetRoomProperty("VASO_CFG_V1", (object)text);
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Host published config: perSec={Synced.coldPerSecond} tick={Synced.tickSeconds} gates=({Synced.gateOn},{Synced.gateOff})");
}
RestartHostLoopIfNeeded();
}
else if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] PhotonCustomPropsUtils not ready; skipping direct property set to avoid duplication");
}
}
private void RestartHostLoopIfNeeded()
{
if (Math.Abs(_runningTickSeconds - Synced.tickSeconds) > 0.0001f)
{
StopHostLoop();
TryStartOrStopHostLoop();
}
}
private void TryStartOrStopHostLoop()
{
if (_allowVaso)
{
if (_hostLoop == null)
{
_runningTickSeconds = Synced.tickSeconds;
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Starting tick loop");
}
_hostLoop = ((MonoBehaviour)this).StartCoroutine(HostAuthoritativeDriver());
}
}
else
{
if (_cfgVerbose.Value && _hostLoop != null)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Stopping tick loop (not allowed)");
}
StopHostLoop();
}
}
private void StopHostLoop()
{
if (_hostLoop != null)
{
((MonoBehaviour)this).StopCoroutine(_hostLoop);
_hostLoop = null;
}
}
[IteratorStateMachine(typeof(<HostAuthoritativeDriver>d__37))]
private IEnumerator HostAuthoritativeDriver()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <HostAuthoritativeDriver>d__37(0)
{
<>4__this = this
};
}
private Character FindLocalCharacter()
{
foreach (Character allCharacter in Character.AllCharacters)
{
if ((Object)(object)allCharacter != (Object)null && (Object)(object)((MonoBehaviourPun)allCharacter).photonView != (Object)null && ((MonoBehaviourPun)allCharacter).photonView.IsMine)
{
return allCharacter;
}
}
return null;
}
private void ApplyTick(float perSecond, float totalTime)
{
//IL_00dc: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Expected O, but got Unknown
Character val = FindLocalCharacter();
if ((Object)(object)val == (Object)null || val.refs == null || (Object)(object)val.refs.afflictions == (Object)null)
{
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] No local character; skip tick");
}
return;
}
bool flag = (Object)(object)val.data != (Object)null && val.data.isSprinting;
float currentStatus = val.refs.afflictions.GetCurrentStatus((STATUSTYPE)2);
if (!flag || currentStatus <= Synced.gateOff)
{
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Tick ignored: sprinting={flag} cold={currentStatus}");
}
return;
}
Affliction_AdjustColdOverTime val2 = new Affliction_AdjustColdOverTime
{
statusPerSecond = perSecond,
totalTime = totalTime,
character = val
};
val.refs.afflictions.AddAffliction((Affliction)(object)val2, false);
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Tick applied: per={perSecond} for {totalTime}s; cold={currentStatus}");
}
}
private void InitializePhotonManager()
{
if (PhotonCustomPropsUtilsPlugin.IsReady)
{
SetupPhotonManager();
}
else
{
PhotonCustomPropsUtilsPlugin.OnReady += SetupPhotonManager;
}
}
private void SetupPhotonManager()
{
_photonManager = PhotonCustomPropsUtilsPlugin.GetManager("tony4twentys.Vasodilation");
_photonManager.RegisterOnJoinedRoom((Action<Player>)delegate
{
CheckHostStatus();
});
_photonManager.RegisterRoomProperty<string>("VASO_CFG_V1", (RoomEventType)2, (Action<string>)delegate(string configData)
{
if (!IsHost && !string.IsNullOrEmpty(configData))
{
HostCfg synced = Synced;
Synced = UnpackCfg(configData);
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Config updated from room (PCPU): perSec={Synced.coldPerSecond} tick={Synced.tickSeconds} gates=({Synced.gateOn},{Synced.gateOff}) (was {synced.coldPerSecond}/{synced.tickSeconds})");
}
_allowVaso = true;
RestartHostLoopIfNeeded();
}
});
}
private void CheckHostStatus()
{
if (!PhotonNetwork.InRoom)
{
return;
}
if (PhotonNetwork.IsMasterClient)
{
if (!IsHost)
{
IsHost = true;
_allowVaso = true;
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Joined room as HOST");
}
PublishConfig();
}
}
else if (IsHost)
{
IsHost = false;
_allowVaso = false;
if (_cfgVerbose.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Joined room as CLIENT; awaiting config");
}
}
TryStartOrStopHostLoop();
}
public void OnLeftRoom()
{
IsHost = false;
_allowVaso = false;
StopHostLoop();
}
}
}