The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of Vasodilation v1.2.1
tony4twentys-Vasodilation.dll
Decompiled 2 weeks agousing 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 Peak.Afflictions; using Photon.Pun; using Photon.Realtime; 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 VasodilationMod; [BepInPlugin("tony4twentys.Vasodilation", "Vasodilation", "1.2.0")] public class VasodilationPlugin : BaseUnityPlugin, IInRoomCallbacks, IMatchmakingCallbacks, IOnEventCallback { [Serializable] public struct HostCfg { public float coldPerSecond; public float tickSeconds; public float gateOn; public float gateOff; } [CompilerGenerated] private sealed class <HostAuthoritativeDriver>d__38 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public VasodilationPlugin <>4__this; private WaitForSeconds <wait>5__1; private Player[] <players>5__2; private int <i>5__3; private int <actor>5__4; private object[] <payload>5__5; private RaiseEventOptions <opts>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HostAuthoritativeDriver>d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <wait>5__1 = null; <players>5__2 = null; <payload>5__5 = null; <opts>5__6 = 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 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) 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 (PhotonNetwork.IsMasterClient) { <players>5__2 = PhotonNetwork.PlayerList; <i>5__3 = 0; while (<i>5__3 < <players>5__2.Length) { <actor>5__4 = <players>5__2[<i>5__3].ActorNumber; <payload>5__5 = new object[2] { Synced.coldPerSecond, Synced.tickSeconds }; RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { <actor>5__4 }; <opts>5__6 = val; PhotonNetwork.RaiseEvent((byte)113, (object)<payload>5__5, <opts>5__6, SendOptions.SendUnreliable); if (<>4__this._cfgVerbose.Value) { ((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[Vaso] Sent tick -> actor {<actor>5__4}"); } <payload>5__5 = null; <opts>5__6 = null; <i>5__3++; } <players>5__2 = null; } <>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 const byte EVT_VASO_TICK = 113; 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 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; _cfgColdPerSecond.SettingChanged += delegate { OnHostConfigChanged(); }; _cfgTickSeconds.SettingChanged += delegate { OnHostConfigChanged(); }; _cfgGateOn.SettingChanged += delegate { OnHostConfigChanged(); }; _cfgGateOff.SettingChanged += delegate { OnHostConfigChanged(); }; SceneManager.activeSceneChanged += OnSceneChanged; } 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) { TryReadConfigFromRoom(); RestartHostLoopIfNeeded(); } public void OnJoinedRoom() { if (PhotonNetwork.IsMasterClient) { if (_cfgVerbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Joined room as HOST"); } PublishConfig(); } else { if (_cfgVerbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Vaso] Joined room as CLIENT; reading config"); } TryReadConfigFromRoom(); } TryStartOrStopHostLoop(); } 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) { } public void OnLeftRoom() { } void IInRoomCallbacks.OnPlayerEnteredRoom(Player newPlayer) { if (PhotonNetwork.IsMasterClient) { PublishConfig(); } } void IInRoomCallbacks.OnPlayerLeftRoom(Player otherPlayer) { } void IInRoomCallbacks.OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { if (propertiesThatChanged != null && ((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"VASO_CFG_V1") && propertiesThatChanged[(object)"VASO_CFG_V1"] is string s) { HostCfg synced = Synced; Synced = UnpackCfg(s); if (_cfgVerbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Config updated from room: perSec={Synced.coldPerSecond} tick={Synced.tickSeconds} gates=({Synced.gateOn},{Synced.gateOff}) (was {synced.coldPerSecond}/{synced.tickSeconds})"); } RestartHostLoopIfNeeded(); } } void IInRoomCallbacks.OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } void IInRoomCallbacks.OnMasterClientSwitched(Player newMasterClient) { if (PhotonNetwork.IsMasterClient) { PublishConfig(); } TryStartOrStopHostLoop(); } public void OnEvent(EventData photonEvent) { //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown if (photonEvent == null || photonEvent.Code != 113 || !(photonEvent.CustomData is object[] array) || array.Length < 2) { return; } float num = Convert.ToSingle(array[0]); float num2 = Convert.ToSingle(array[1]); 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 = num, totalTime = num2, character = val }; val.refs.afflictions.AddAffliction((Affliction)(object)val2, false); if (_cfgVerbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Tick applied: per={num} for {num2}s; cold={currentStatus}"); } } 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 TryReadConfigFromRoom() { Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom != null && ((RoomInfo)currentRoom).CustomProperties != null && ((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"VASO_CFG_V1", out object value) && value is string s) { Synced = UnpackCfg(s); } } private void OnHostConfigChanged() { if (PhotonNetwork.IsMasterClient) { PublishConfig(); } } private void PublishConfig() { //IL_002a: 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: Expected O, but got Unknown Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom != null) { Synced = BuildFromHostConfig(); string text = PackCfg(Synced); Hashtable val = new Hashtable { [(object)"VASO_CFG_V1"] = text }; currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); if (_cfgVerbose.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[Vaso] Host published config: perSec={Synced.coldPerSecond} tick={Synced.tickSeconds} gates=({Synced.gateOn},{Synced.gateOff})"); } RestartHostLoopIfNeeded(); } } private void RestartHostLoopIfNeeded() { if (PhotonNetwork.IsMasterClient && Math.Abs(_runningTickSeconds - Synced.tickSeconds) > 0.0001f) { StopHostLoop(); TryStartOrStopHostLoop(); } else if (!PhotonNetwork.IsMasterClient) { StopHostLoop(); } } private void TryStartOrStopHostLoop() { if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { if (_hostLoop == null) { _runningTickSeconds = Synced.tickSeconds; _hostLoop = ((MonoBehaviour)this).StartCoroutine(HostAuthoritativeDriver()); } } else { StopHostLoop(); } } private void StopHostLoop() { if (_hostLoop != null) { ((MonoBehaviour)this).StopCoroutine(_hostLoop); _hostLoop = null; } } [IteratorStateMachine(typeof(<HostAuthoritativeDriver>d__38))] private IEnumerator HostAuthoritativeDriver() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HostAuthoritativeDriver>d__38(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; } }