using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DioCompany.Networking; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.VFX; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DioCompany { public static class AmbientAudioFreeze { private static readonly List Paused = new List(); public static void Freeze(ulong casterClientId) { Transform val = FindCasterRoot(casterClientId); AudioSource[] array = Object.FindObjectsOfType(); foreach (AudioSource val2 in array) { if (!((Object)(object)val2 == (Object)null) && val2.isPlaying && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val))) { val2.Pause(); Paused.Add(val2); } } } public static void Unfreeze() { foreach (AudioSource item in Paused) { if (!((Object)(object)item == (Object)null)) { item.UnPause(); } } Paused.Clear(); } private static Transform FindCasterRoot(ulong casterClientId) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return null; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if ((Object)(object)val != (Object)null && val.playerClientId == casterClientId) { return ((Component)val).transform.root; } } return null; } } public static class CompanyMonsterFreeze { public static void SetFrozen(bool frozen) { DepositItemsDesk val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null || val.monsterAnimations == null) { return; } MonsterAnimation[] monsterAnimations = val.monsterAnimations; foreach (MonsterAnimation val2 in monsterAnimations) { if ((Object)(object)val2?.monsterAnimator != (Object)null) { val2.monsterAnimator.speed = (frozen ? 0f : 1f); } } } } public static class DamageQueue { private class Entry { public EnemyAI Enemy; public int Force; public Vector3 HitDirection; public PlayerControllerB PlayerWhoHit; public bool PlayHitSFX; public int HitId; } private static readonly List Pending = new List(); public static void Enqueue(EnemyAI enemy, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitId) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Pending.Add(new Entry { Enemy = enemy, Force = force, HitDirection = hitDirection, PlayerWhoHit = playerWhoHit, PlayHitSFX = playHitSFX, HitId = hitId }); } public static void ReplayAndClear() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (Pending.Count == 0) { return; } List list = new List(Pending); Pending.Clear(); foreach (Entry item in list) { if (!((Object)(object)item.Enemy == (Object)null)) { item.Enemy.HitEnemyOnLocalClient(item.Force, item.HitDirection, item.PlayerWhoHit, item.PlayHitSFX, item.HitId); } } } } public static class ElevatorFreeze { public static void Freeze() { SetFrozen(frozen: true); } public static void Unfreeze() { SetFrozen(frozen: false); } private static void SetFrozen(bool frozen) { MineshaftElevatorController val = RoundManager.Instance?.currentMineshaftElevator; if (!((Object)(object)val == (Object)null)) { if ((Object)(object)val.elevatorAnimator != (Object)null) { val.elevatorAnimator.speed = (frozen ? 0f : 1f); } AudioSource[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (AudioSource val2 in componentsInChildren) { val2.mute = frozen; } } } } public static class EnemyFreeze { public static void Freeze() { SetFrozen(frozen: true); } public static void Unfreeze() { SetFrozen(frozen: false); } private static void SetFrozen(bool frozen) { List list = RoundManager.Instance?.SpawnedEnemies; if (list == null) { return; } foreach (EnemyAI item in list) { if ((Object)(object)item == (Object)null) { continue; } if ((Object)(object)item.agent != (Object)null) { item.agent.isStopped = frozen; item.agent.updateRotation = !frozen; } if ((Object)(object)item.creatureAnimator != (Object)null) { item.creatureAnimator.speed = (frozen ? 0f : 1f); } AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (AudioSource val in componentsInChildren) { val.mute = frozen; } VisualEffect[] componentsInChildren2 = ((Component)item).GetComponentsInChildren(true); foreach (VisualEffect val2 in componentsInChildren2) { val2.pause = frozen; } ParticleSystem[] componentsInChildren3 = ((Component)item).GetComponentsInChildren(true); foreach (ParticleSystem val3 in componentsInChildren3) { if (frozen) { val3.Pause(true); } else { val3.Play(true); } } } } } public static class FanFreeze { private static bool _loggedOnce; public static void SetFrozen(bool frozen) { if (!_loggedOnce) { _loggedOnce = true; LogAllAnimatorNames(); } Animator[] array = Object.FindObjectsOfType(); foreach (Animator val in array) { if (!((Object)(object)val == (Object)null) && ((Object)((Component)val).gameObject).name.ToLowerInvariant().Contains("fan")) { val.speed = (frozen ? 0f : 1f); } } } private static void LogAllAnimatorNames() { Animator[] array = Object.FindObjectsOfType(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append($"[DioDiag] {array.Length} Animators in scene: "); Animator[] array2 = array; foreach (Animator val in array2) { if ((Object)(object)val != (Object)null) { stringBuilder.Append(((Object)((Component)val).gameObject).name).Append(", "); } } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } public static class FlameEffectFreeze { private static readonly string[] NameKeywords = new string[6] { "fire", "flame", "boost", "thruster", "exhaust", "jet" }; private static readonly string[] SpeedPropertyCandidates = new string[15] { "_Speed", "_ScrollSpeed", "_FlowSpeed", "_NoiseSpeed", "_AnimSpeed", "_AnimationSpeed", "_TimeScale", "_FireSpeed", "_DistortSpeed", "_DistortionSpeed", "_UVSpeed", "_ScrollXSpeed", "_ScrollYSpeed", "_PanSpeed", "_WarpSpeed" }; private static readonly Dictionary FrozenMaterials = new Dictionary(); private static readonly List HiddenRenderers = new List(); private static readonly List DisabledLights = new List(); public static void SetFrozen(bool frozen) { if (frozen) { Renderer[] array = Object.FindObjectsOfType(true); foreach (Renderer val in array) { if ((Object)(object)val == (Object)null || !val.enabled || !MatchesKeyword(((Object)((Component)val).gameObject).name)) { continue; } LogShaderProperties(val); bool flag = false; Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 == (Object)null || FrozenMaterials.ContainsKey(val2)) { continue; } string[] speedPropertyCandidates = SpeedPropertyCandidates; foreach (string text in speedPropertyCandidates) { if (val2.HasProperty(text)) { FrozenMaterials[val2] = (text, val2.GetFloat(text)); val2.SetFloat(text, 0f); flag = true; break; } } } if (!flag && !HiddenRenderers.Contains(val)) { val.enabled = false; HiddenRenderers.Add(val); } } Light[] array2 = Object.FindObjectsOfType(true); foreach (Light val3 in array2) { if (!((Object)(object)val3 == (Object)null) && ((Behaviour)val3).enabled && MatchesKeyword(((Object)((Component)val3).gameObject).name)) { ((Behaviour)val3).enabled = false; DisabledLights.Add(val3); } } return; } foreach (KeyValuePair frozenMaterial in FrozenMaterials) { if ((Object)(object)frozenMaterial.Key != (Object)null) { frozenMaterial.Key.SetFloat(frozenMaterial.Value.Item1, frozenMaterial.Value.Item2); } } FrozenMaterials.Clear(); foreach (Renderer hiddenRenderer in HiddenRenderers) { if ((Object)(object)hiddenRenderer != (Object)null) { hiddenRenderer.enabled = true; } } HiddenRenderers.Clear(); foreach (Light disabledLight in DisabledLights) { if ((Object)(object)disabledLight != (Object)null) { ((Behaviour)disabledLight).enabled = true; } } DisabledLights.Clear(); } private static bool MatchesKeyword(string name) { string text = name.ToLowerInvariant(); string[] nameKeywords = NameKeywords; foreach (string value in nameKeywords) { if (text.Contains(value)) { return true; } } return false; } private static void LogShaderProperties(Renderer renderer) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Invalid comparison between Unknown and I4 //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 Material[] sharedMaterials = renderer.sharedMaterials; foreach (Material val in sharedMaterials) { if ((Object)(object)val == (Object)null || (Object)(object)val.shader == (Object)null) { continue; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[DioDiag] Renderer '" + ((Object)((Component)renderer).gameObject).name + "' material '" + ((Object)val).name + "' shader '" + ((Object)val.shader).name + "' float properties: "); int propertyCount = val.shader.GetPropertyCount(); for (int j = 0; j < propertyCount; j++) { if ((int)val.shader.GetPropertyType(j) == 2 || (int)val.shader.GetPropertyType(j) == 3) { string propertyName = val.shader.GetPropertyName(j); stringBuilder.Append(propertyName).Append('=').Append(val.GetFloat(propertyName)) .Append(", "); } } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } } public static class GlobalEffectsFreeze { private static readonly List PausedParticles = new List(); private static readonly List PausedVfx = new List(); public static void Freeze() { ParticleSystem[] array = Object.FindObjectsOfType(true); foreach (ParticleSystem val in array) { if (!((Object)(object)val == (Object)null) && val.isPlaying) { val.Pause(true); PausedParticles.Add(val); } } VisualEffect[] array2 = Object.FindObjectsOfType(true); foreach (VisualEffect val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !val2.pause) { val2.pause = true; PausedVfx.Add(val2); } } } public static void Unfreeze() { foreach (ParticleSystem pausedParticle in PausedParticles) { if ((Object)(object)pausedParticle != (Object)null) { pausedParticle.Play(true); } } foreach (VisualEffect item in PausedVfx) { if ((Object)(object)item != (Object)null) { item.pause = false; } } PausedParticles.Clear(); PausedVfx.Clear(); } } public static class HostPermissions { public static readonly HashSet AllowedClientIds = new HashSet(); public static bool IsAllowed(ulong clientId) { if ((Object)(object)NetworkManager.Singleton != (Object)null && clientId == 0) { return true; } return AllowedClientIds.Contains(clientId); } } public static class HygrodereFreeze { private static readonly Dictionary FrozenFrequency = new Dictionary(); public static void SetFrozen(bool frozen) { if (frozen) { BlobAI[] array = Object.FindObjectsOfType(); foreach (BlobAI val in array) { if (!((Object)(object)val == (Object)null) && ((EnemyAI)val).skinnedMeshRenderers != null && ((EnemyAI)val).skinnedMeshRenderers.Length != 0) { Material material = ((Renderer)((EnemyAI)val).skinnedMeshRenderers[0]).material; if (!((Object)(object)material == (Object)null) && !FrozenFrequency.ContainsKey(material) && material.HasProperty("_Frequency")) { FrozenFrequency[material] = material.GetFloat("_Frequency"); material.SetFloat("_Frequency", 0f); } } } return; } foreach (KeyValuePair item in FrozenFrequency) { if ((Object)(object)item.Key != (Object)null) { item.Key.SetFloat("_Frequency", item.Value); } } FrozenFrequency.Clear(); } } public static class ItemPhysicsFreeze { private static readonly Dictionary Frozen = new Dictionary(); public static void Freeze() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) GrabbableObject[] array = Object.FindObjectsOfType(); foreach (GrabbableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.propBody == (Object)null) && (!val.isHeld || !((Object)(object)val.playerHeldBy != (Object)null) || val.playerHeldBy.playerClientId != PauseState.CasterClientId) && !val.propBody.isKinematic) { Frozen[val.propBody] = (val.propBody.velocity, val.propBody.angularVelocity); val.propBody.velocity = Vector3.zero; val.propBody.angularVelocity = Vector3.zero; val.propBody.isKinematic = true; } } } public static void Unfreeze() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) foreach (var (val2, tuple2) in Frozen) { if (!((Object)(object)val2 == (Object)null)) { val2.isKinematic = false; val2.velocity = tuple2.Item1; val2.angularVelocity = tuple2.Item2; } } Frozen.Clear(); } } public static class MineFreeze { public static readonly List Active = new List(); public static void Freeze() { SetFrozen(frozen: true); } public static void Unfreeze() { SetFrozen(frozen: false); } private static void SetFrozen(bool frozen) { foreach (Landmine item in Active) { if (!((Object)(object)item == (Object)null)) { if ((Object)(object)item.mineAnimator != (Object)null) { item.mineAnimator.speed = (frozen ? 0f : 1f); } AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (AudioSource val in componentsInChildren) { val.mute = frozen; } } } } } public static class MineQueue { private static readonly MethodInfo TriggerMethod = AccessTools.Method(typeof(Landmine), "TriggerMineOnLocalClientByExiting", (Type[])null, (Type[])null); private static readonly List Pending = new List(); public static void Enqueue(Landmine mine) { Pending.Add(mine); } public static void ReplayAndClear() { if (Pending.Count == 0) { return; } List list = new List(Pending); Pending.Clear(); foreach (Landmine item in list) { if (!((Object)(object)item == (Object)null)) { TriggerMethod?.Invoke(item, null); } } } } public static class ModTick { public static void Tick() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null && ((ButtonControl)current[Plugin.PauseKey.Value]).wasPressedThisFrame) { PauseController.LocalKeyPressed(); } if (PauseState.IsPaused && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsHost && Time.realtimeSinceStartup >= PauseState.PauseEndsAtRealtime) { PauseController.ResumeFromHost(); } PauseEffects.Tick(); PauseAudio.Tick(); ScanPulse.Tick(); } } public static class PauseAudio { private class PendingLoad { public UnityWebRequest Request; public UnityWebRequestAsyncOperation Operation; public Action OnLoaded; } private static readonly List Pending = new List(); private static AudioClip _pauseClip; private static AudioClip _resumeClip; private static bool _loadStarted; public static void LoadClips() { if (!_loadStarted) { _loadStarted = true; StartLoad("DioCompany.Resources.pause_sfx.mp3", delegate(AudioClip clip) { _pauseClip = clip; }); StartLoad("DioCompany.Resources.resume_sfx.mp3", delegate(AudioClip clip) { _resumeClip = clip; }); } } public static void Tick() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 if (Pending.Count == 0) { return; } for (int num = Pending.Count - 1; num >= 0; num--) { PendingLoad pendingLoad = Pending[num]; if (((AsyncOperation)pendingLoad.Operation).isDone) { if ((int)pendingLoad.Request.result == 1) { pendingLoad.OnLoaded(DownloadHandlerAudioClip.GetContent(pendingLoad.Request)); } pendingLoad.Request.Dispose(); Pending.RemoveAt(num); } } } public static void PlayPause() { PlayOneShot(_pauseClip); } public static void PlayResume() { PlayOneShot(_resumeClip); } private static void PlayOneShot(AudioClip clip) { if (!((Object)(object)clip == (Object)null)) { AudioSource val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.UIAudio : null); if ((Object)(object)val != (Object)null) { val.PlayOneShot(clip); } } } private static void StartLoad(string resourceName, Action onLoaded) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourceName); if (stream != null) { string text = Path.Combine(Path.GetTempPath(), Path.GetFileName(resourceName)); using (FileStream destination = File.Create(text)) { stream.CopyTo(destination); } UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file://" + text, (AudioType)13); UnityWebRequestAsyncOperation operation = audioClip.SendWebRequest(); Pending.Add(new PendingLoad { Request = audioClip, Operation = operation, OnLoaded = onLoaded }); } } } public static class PauseController { public static void LocalKeyPressed() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null) { return; } if (PauseState.IsPaused) { if (PauseState.CasterClientId == val.playerClientId) { PauseNetworking.RequestToggle(); } } else { PauseNetworking.RequestToggle(); } } public static void HostHandleToggleRequest(ulong senderClientId) { //IL_0143: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array != null) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append($"[DioDiag] HostHandleToggleRequest senderClientId={senderClientId}, IsPaused={PauseState.IsPaused}. Roster: "); for (int i = 0; i < array.Length; i++) { PlayerControllerB val = array[i]; if (!((Object)(object)val == (Object)null)) { stringBuilder.Append($"[idx={i} name={val.playerUsername} playerClientId={val.playerClientId} isPlayerControlled={val.isPlayerControlled} isOwner={((NetworkBehaviour)val).IsOwner}] "); } } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } if (!PauseState.IsPaused) { if (HostPermissions.IsAllowed(senderClientId) && (!PauseState.CooldownEndsAtRealtime.TryGetValue(senderClientId, out var value) || !(Time.realtimeSinceStartup < value))) { PlayerControllerB val2 = FindPlayerByClientId(senderClientId); if (!((Object)(object)val2 == (Object)null)) { PauseStateData data = PauseStateData.Paused(senderClientId, ((Component)val2).transform.position, Plugin.PauseTimeLimitSeconds.Value); PauseState.PauseEndsAtRealtime = Time.realtimeSinceStartup + data.TimeLimit; PauseNetworking.BroadcastState(data); ApplyStateChange(data); } } } else if (senderClientId == PauseState.CasterClientId) { ResumeFromHost(); } } public static void ResumeFromHost() { PauseStateData data = PauseStateData.Resumed(); PauseState.CooldownEndsAtRealtime[PauseState.CasterClientId] = Time.realtimeSinceStartup + Plugin.PauseCooldownSeconds.Value; PauseNetworking.BroadcastState(data); ApplyStateChange(data); } public static void ApplyStateChange(PauseStateData data) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) PauseState.IsPaused = data.IsPaused; PauseState.CasterClientId = data.CasterClientId; if (data.IsPaused) { PlayerFreeze.ApplyIfNotExempt(data.CasterClientId); EnemyFreeze.Freeze(); TurretFreeze.Freeze(); SpikeTrapFreeze.Freeze(); ElevatorFreeze.Freeze(); MineFreeze.Freeze(); ItemPhysicsFreeze.Freeze(); AmbientAudioFreeze.Freeze(data.CasterClientId); GlobalEffectsFreeze.Freeze(); ShipFreeze.SetFrozen(frozen: true); CompanyMonsterFreeze.SetFrozen(frozen: true); FanFreeze.SetFrozen(frozen: true); FlameEffectFreeze.SetFrozen(frozen: true); RadMechFreeze.SetFrozen(frozen: true); HygrodereFreeze.SetFrozen(frozen: true); PauseEffects.StartPauseEffect(data.CasterPosition); ScanPulse.PlayAt(data.CasterPosition); } else { PlayerFreeze.RemoveFreeze(); EnemyFreeze.Unfreeze(); TurretFreeze.Unfreeze(); SpikeTrapFreeze.Unfreeze(); ElevatorFreeze.Unfreeze(); MineFreeze.Unfreeze(); ItemPhysicsFreeze.Unfreeze(); AmbientAudioFreeze.Unfreeze(); GlobalEffectsFreeze.Unfreeze(); ShipFreeze.SetFrozen(frozen: false); CompanyMonsterFreeze.SetFrozen(frozen: false); FanFreeze.SetFrozen(frozen: false); FlameEffectFreeze.SetFrozen(frozen: false); RadMechFreeze.SetFrozen(frozen: false); HygrodereFreeze.SetFrozen(frozen: false); PauseEffects.EndPauseEffect(); DamageQueue.ReplayAndClear(); MineQueue.ReplayAndClear(); PlayerDamageQueue.ReplayAndClear(); PlayerKillQueue.ReplayAndClear(); } } private static PlayerControllerB FindPlayerByClientId(ulong clientId) { PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return null; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if ((Object)(object)val != (Object)null && val.playerClientId == clientId) { return val; } } return null; } } public static class PauseEffects { private const float TransitionDuration = 0.6f; private static Volume _volume; private static ChromaticAberration _chromaticAberration; private static ColorAdjustments _colorAdjustments; private static bool _transitioning; private static float _transitionStart; private static float _startSaturation; private static float _endSaturation; private static float _startAberration; private static float _endAberration; public static void StartPauseEffect(Vector3 casterWorldPosition) { PauseAudio.PlayPause(); EnsureVolume(); BeginTransition(toGrey: true); } public static void EndPauseEffect() { PauseAudio.PlayResume(); EnsureVolume(); BeginTransition(toGrey: false); } public static void Tick() { if (_transitioning) { float num = Time.unscaledTime - _transitionStart; float num2 = Mathf.Clamp01(num / 0.6f); ((VolumeParameter)(object)_colorAdjustments.saturation).value = Mathf.Lerp(_startSaturation, _endSaturation, num2); ((VolumeParameter)(object)_chromaticAberration.intensity).value = Mathf.Lerp(_startAberration, _endAberration, num2); if (num2 >= 1f) { _transitioning = false; } } } private static void BeginTransition(bool toGrey) { _transitionStart = Time.unscaledTime; _startSaturation = ((VolumeParameter)(object)_colorAdjustments.saturation).value; _endSaturation = (toGrey ? (-100f) : 0f); _startAberration = ((VolumeParameter)(object)_chromaticAberration.intensity).value; _endAberration = (toGrey ? 1f : 0f); _transitioning = true; } private static void EnsureVolume() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (!((Object)(object)_volume != (Object)null)) { GameObject val = new GameObject("DioCompany_TimeStopVolume"); Object.DontDestroyOnLoad((Object)(object)val); _volume = val.AddComponent(); _volume.isGlobal = true; _volume.priority = 1000f; _volume.weight = 1f; VolumeProfile val2 = ScriptableObject.CreateInstance(); _chromaticAberration = val2.Add(false); ((VolumeParameter)(object)_chromaticAberration.intensity).value = 0f; ((VolumeParameter)_chromaticAberration.intensity).overrideState = true; _colorAdjustments = val2.Add(false); ((VolumeParameter)(object)_colorAdjustments.saturation).value = 0f; ((VolumeParameter)_colorAdjustments.saturation).overrideState = true; _volume.profile = val2; Plugin.Log.LogInfo((object)"[PauseEffects] Created dedicated time-stop Volume."); } } } public static class PauseState { public static bool IsPaused; public static ulong CasterClientId; public static float PauseEndsAtRealtime; public static readonly Dictionary CooldownEndsAtRealtime = new Dictionary(); } public static class PlayerDamageQueue { private class Entry { public PlayerControllerB Target; public int Force; public Vector3 HitDirection; public PlayerControllerB PlayerWhoHit; public bool PlayHitSFX; public int HitId; } private static readonly MethodInfo HitMethod = ResolveHitMethod(); private static readonly List Pending = new List(); private static MethodInfo ResolveHitMethod() { InterfaceMapping interfaceMap = typeof(PlayerControllerB).GetInterfaceMap(typeof(IHittable)); int num = Array.IndexOf(interfaceMap.InterfaceMethods, typeof(IHittable).GetMethod("Hit")); return (num >= 0) ? interfaceMap.TargetMethods[num] : null; } public static void Enqueue(PlayerControllerB target, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitId) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Pending.Add(new Entry { Target = target, Force = force, HitDirection = hitDirection, PlayerWhoHit = playerWhoHit, PlayHitSFX = playHitSFX, HitId = hitId }); } public static void ReplayAndClear() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (Pending.Count == 0 || HitMethod == null) { return; } List list = new List(Pending); Pending.Clear(); foreach (Entry item in list) { if (!((Object)(object)item.Target == (Object)null)) { HitMethod.Invoke(item.Target, new object[5] { item.Force, item.HitDirection, item.PlayerWhoHit, item.PlayHitSFX, item.HitId }); } } } } public static class PlayerFreeze { public static bool IsLocalPlayerFrozen() { if (!PauseState.IsPaused) { return false; } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; return (Object)(object)val != (Object)null && val.playerClientId != PauseState.CasterClientId; } public static void ApplyIfNotExempt(ulong casterClientId) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && val.playerClientId != casterClientId) { val.disableMoveInput = true; val.disableLookInput = true; } } public static void RemoveFreeze() { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null)) { val.disableMoveInput = false; val.disableLookInput = false; } } } public static class PlayerKillQueue { private class QueuedKill { public PlayerControllerB Player; public Vector3 BodyVelocity; public bool SpawnBody; public CauseOfDeath CauseOfDeath; public int DeathAnimation; public Vector3 PositionOffset; public bool SetOverrideDropItems; } private static readonly List Queue = new List(); public static void Enqueue(PlayerControllerB player, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation, Vector3 positionOffset, bool setOverrideDropItems) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Queue.Add(new QueuedKill { Player = player, BodyVelocity = bodyVelocity, SpawnBody = spawnBody, CauseOfDeath = causeOfDeath, DeathAnimation = deathAnimation, PositionOffset = positionOffset, SetOverrideDropItems = setOverrideDropItems }); } public static void ReplayAndClear() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) List list = new List(Queue); Queue.Clear(); foreach (QueuedKill item in list) { if (!((Object)(object)item.Player == (Object)null)) { item.Player.KillPlayer(item.BodyVelocity, item.SpawnBody, item.CauseOfDeath, item.DeathAnimation, item.PositionOffset, item.SetOverrideDropItems); } } } } [BepInPlugin("com.paul.diocompany.timestop", "Dio Company - Time Stop", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "com.paul.diocompany.timestop"; public const string Name = "Dio Company - Time Stop"; public const string Version = "1.0.0"; public static ConfigEntry PauseKey; public static ConfigEntry PauseTimeLimitSeconds; public static ConfigEntry PauseCooldownSeconds; public static ConfigEntry ScanPulseColorHex; private Harmony _harmony; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; PauseKey = ((BaseUnityPlugin)this).Config.Bind("Keybinds", "PauseKey", (Key)24, "Requests a time-stop. Usable by the host, or by anyone the host has granted permission to (host types '/allow PlayerName' or '/deny PlayerName' in chat). Pressing it again while your own time-stop is active resumes it early."); PauseTimeLimitSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "PauseTimeLimitSeconds", 30f, "Maximum duration, in seconds, a time-stop lasts before automatically resuming."); PauseCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "PauseCooldownSeconds", 5f, "How long, in seconds, a given player must wait after ending their own time-stop before starting another. Per-player -- doesn't affect anyone else's cooldown."); ScanPulseColorHex = ((BaseUnityPlugin)this).Config.Bind("Effects", "ScanPulseColorHex", "#FF33D9", "Hex color (e.g. #FF33D9) for the scan-pulse flash on time-stop cast. This is purely a local display preference -- it only changes what YOU see, regardless of who casts it."); ((BaseUnityPlugin)this).Config.Remove(new ConfigDefinition("Keybinds", "PermissionMenuKey")); _harmony = new Harmony("com.paul.diocompany.timestop"); _harmony.PatchAll(); PauseNetworking.Init(); PauseAudio.LoadClips(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Dio Company - Time Stop v1.0.0 loaded."); } } public static class RadMechFreeze { private static readonly List Stopped = new List(); public static void SetFrozen(bool frozen) { if (frozen) { RadMechAI[] array = Object.FindObjectsOfType(); foreach (RadMechAI val in array) { if (!((Object)(object)val == (Object)null)) { TryStop(val.rightFootParticle); TryStop(val.leftFootParticle); TryStop(val.bothFeetParticle); TryStop(val.smokeRightLeg); TryStop(val.smokeLeftLeg); TryStop(val.gunArmParticle); TryStop(val.chargeParticle); TryStop(val.blowtorchParticle); } } return; } foreach (ParticleSystem item in Stopped) { if ((Object)(object)item != (Object)null) { item.Play(true); } } Stopped.Clear(); } private static void TryStop(ParticleSystem particle) { if (!((Object)(object)particle == (Object)null) && particle.isPlaying) { particle.Stop(true, (ParticleSystemStopBehavior)0); Stopped.Add(particle); } } } public static class ScanPulse { private const float PulseLifetime = 1.5f; private static readonly Color DefaultPulseColor = new Color(1f, 0.2f, 0.85f, 1f); private static readonly int[] ColorPropertyIds = new int[4] { Shader.PropertyToID("_Color"), Shader.PropertyToID("_BaseColor"), Shader.PropertyToID("_TintColor"), Shader.PropertyToID("_EmissionColor") }; private static Renderer[] _renderers; private static bool _tinted; private static float _untintAtRealtime; public static void PlayAt(Vector3 worldPosition) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) Animator val = (((Object)(object)HUDManager.Instance != (Object)null) ? HUDManager.Instance.scanEffectAnimator : null); if (!((Object)(object)val == (Object)null)) { if (_renderers == null) { _renderers = ((Component)val).GetComponentsInChildren(true); } MaterialPropertyBlock val2 = new MaterialPropertyBlock(); Color configuredColor = GetConfiguredColor(); int[] colorPropertyIds = ColorPropertyIds; foreach (int num in colorPropertyIds) { val2.SetColor(num, configuredColor); } Renderer[] renderers = _renderers; foreach (Renderer val3 in renderers) { val3.SetPropertyBlock(val2); } ((Component)val).transform.position = worldPosition; val.SetTrigger("scan"); _tinted = true; _untintAtRealtime = Time.realtimeSinceStartup + 1.5f; } } public static void Tick() { if (_tinted && !(Time.realtimeSinceStartup < _untintAtRealtime)) { Renderer[] renderers = _renderers; foreach (Renderer val in renderers) { val.SetPropertyBlock((MaterialPropertyBlock)null); } _tinted = false; } } private static Color GetConfiguredColor() { //IL_0027: 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_0023: 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_002f: Unknown result type (might be due to invalid IL or missing references) string value = Plugin.ScanPulseColorHex.Value; Color result = default(Color); if (!string.IsNullOrEmpty(value) && ColorUtility.TryParseHtmlString(value, ref result)) { return result; } return DefaultPulseColor; } } public static class ShipFreeze { public static void SetFrozen(bool frozen) { StartOfRound instance = StartOfRound.Instance; if (!((Object)(object)instance == (Object)null)) { if ((Object)(object)instance.shipAnimator != (Object)null) { instance.shipAnimator.speed = (frozen ? 0f : 1f); } if ((Object)(object)instance.shipDoorsAnimator != (Object)null) { instance.shipDoorsAnimator.speed = (frozen ? 0f : 1f); } ItemDropship val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null && (Object)(object)val.shipAnimator != (Object)null) { val.shipAnimator.speed = (frozen ? 0f : 1f); } } } } public static class SpikeTrapFreeze { public static readonly List Active = new List(); public static void Freeze() { SetFrozen(frozen: true); } public static void Unfreeze() { SetFrozen(frozen: false); } private static void SetFrozen(bool frozen) { foreach (SpikeRoofTrap item in Active) { if (!((Object)(object)item == (Object)null)) { if ((Object)(object)item.spikeTrapAnimator != (Object)null) { item.spikeTrapAnimator.speed = (frozen ? 0f : 1f); } AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (AudioSource val in componentsInChildren) { val.mute = frozen; } } } } } public static class TurretFreeze { public static readonly List Active = new List(); public static void Freeze() { SetFrozen(frozen: true); } public static void Unfreeze() { SetFrozen(frozen: false); } private static void SetFrozen(bool frozen) { foreach (Turret item in Active) { if ((Object)(object)item == (Object)null) { continue; } if ((Object)(object)item.turretAnimator != (Object)null) { item.turretAnimator.speed = (frozen ? 0f : 1f); } if ((Object)(object)item.bulletParticles != (Object)null) { if (frozen) { item.bulletParticles.Pause(true); } else { item.bulletParticles.Play(true); } } AudioSource[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); foreach (AudioSource val in componentsInChildren) { val.mute = frozen; } } } } } namespace DioCompany.Patches { [HarmonyPatch(typeof(HUDManager), "AddTextToChatOnServer")] public static class ChatCommandPatch { private const string AllowPrefix = "/allow "; private const string DenyPrefix = "/deny "; [HarmonyPrefix] private static bool Prefix(string chatMessage) { if (chatMessage == null) { return true; } bool allow; string targetName; if (chatMessage.StartsWith("/allow ", StringComparison.OrdinalIgnoreCase)) { allow = true; targetName = chatMessage.Substring("/allow ".Length).Trim(); } else { if (!chatMessage.StartsWith("/deny ", StringComparison.OrdinalIgnoreCase)) { return true; } allow = false; targetName = chatMessage.Substring("/deny ".Length).Trim(); } HandleCommand(allow, targetName); return false; } private static void HandleCommand(bool allow, string targetName) { if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("Time Stop", "Only the host can grant time-stop permission.", true, false, "LC_Tip1"); } return; } PlayerControllerB[] array = StartOfRound.Instance?.allPlayerScripts; if (array == null) { return; } PlayerControllerB[] array2 = array; foreach (PlayerControllerB val in array2) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && string.Equals(val.playerUsername, targetName, StringComparison.OrdinalIgnoreCase)) { if (allow) { HostPermissions.AllowedClientIds.Add(val.playerClientId); } else { HostPermissions.AllowedClientIds.Remove(val.playerClientId); } HUDManager instance2 = HUDManager.Instance; if (instance2 != null) { instance2.DisplayTip("Time Stop", allow ? (val.playerUsername + " can now use time-stop.") : (val.playerUsername + "'s time-stop permission was revoked."), false, false, "LC_Tip1"); } return; } } HUDManager instance3 = HUDManager.Instance; if (instance3 != null) { instance3.DisplayTip("Time Stop", "No connected player found named '" + targetName + "'.", true, false, "LC_Tip1"); } } } [HarmonyPatch(typeof(DepositItemsDesk), "Update")] public static class CompanyMonsterFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(MineshaftElevatorController))] public static class ElevatorFreezePatch { [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefix() { return !PauseState.IsPaused; } [HarmonyPatch("LateUpdate")] [HarmonyPrefix] private static bool LateUpdatePrefix() { return !PauseState.IsPaused; } } [HarmonyPatch] public static class EnemyContactPatch { private static IEnumerable TargetMethods() { Type[] types = typeof(EnemyAI).Assembly.GetTypes(); foreach (Type type in types) { if (typeof(EnemyAI).IsAssignableFrom(type)) { MethodInfo method = type.GetMethod("OnCollideWithPlayer", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { yield return method; } } } } [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(EnemyAI), "HitEnemyOnLocalClient")] public static class EnemyDamagePatch { [HarmonyPrefix] private static bool Prefix(EnemyAI __instance, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!PauseState.IsPaused) { return true; } PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if ((Object)(object)val == (Object)null || val.playerClientId != PauseState.CasterClientId) { return true; } DamageQueue.Enqueue(__instance, force, hitDirection, playerWhoHit, playHitSFX, hitID); return false; } } [HarmonyPatch] public static class EnemyLogicFreezePatch { private static readonly string[] MethodNames = new string[3] { "Update", "FixedUpdate", "LateUpdate" }; private static IEnumerable TargetMethods() { Type[] types = typeof(EnemyAI).Assembly.GetTypes(); foreach (Type type in types) { if (!typeof(EnemyAI).IsAssignableFrom(type)) { continue; } string[] methodNames = MethodNames; foreach (string name in methodNames) { MethodInfo method = type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { yield return method; } } } } [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(ItemDropship), "Update")] public static class ItemDropshipFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch] public static class ItemFreezePatch { private static IEnumerable TargetMethods() { Type[] types = typeof(GrabbableObject).Assembly.GetTypes(); foreach (Type type in types) { if (typeof(GrabbableObject).IsAssignableFrom(type)) { MethodInfo method = type.GetMethod("Update", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { yield return method; } } } } [HarmonyPrefix] private static bool Prefix(GrabbableObject __instance) { if (!PauseState.IsPaused) { return true; } if (__instance.isHeld && (Object)(object)__instance.playerHeldBy != (Object)null && __instance.playerHeldBy.playerClientId == PauseState.CasterClientId) { return true; } return false; } } [HarmonyPatch(typeof(Landmine), "TriggerMineOnLocalClientByExiting")] public static class MinePatch { [HarmonyPrefix] private static bool Prefix(Landmine __instance) { if (!PauseState.IsPaused) { return true; } MineQueue.Enqueue(__instance); return false; } } [HarmonyPatch(typeof(Landmine), "Start")] public static class MineRegistrationPatch { [HarmonyPostfix] private static void Postfix(Landmine __instance) { if (!MineFreeze.Active.Contains(__instance)) { MineFreeze.Active.Add(__instance); } } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public static class PlayerUpdateFullFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PlayerFreeze.IsLocalPlayerFrozen(); } } [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] public static class PlayerLateUpdateFullFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PlayerFreeze.IsLocalPlayerFrozen(); } } [HarmonyPatch] public static class PlayerHitPatch { private static MethodBase TargetMethod() { InterfaceMapping interfaceMap = typeof(PlayerControllerB).GetInterfaceMap(typeof(IHittable)); int num = Array.IndexOf(interfaceMap.InterfaceMethods, typeof(IHittable).GetMethod("Hit")); return (num >= 0) ? interfaceMap.TargetMethods[num] : null; } [HarmonyPrefix] private static bool Prefix(PlayerControllerB __instance, int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX, int hitID, ref bool __result) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!PauseState.IsPaused) { return true; } PlayerDamageQueue.Enqueue(__instance, force, hitDirection, playerWhoHit, playHitSFX, hitID); __result = true; return false; } } [HarmonyPatch] public static class PlayerInputFreezePatch { private static readonly HashSet Excluded = new HashSet { "OpenMenu_performed" }; private static IEnumerable TargetMethods() { MethodInfo[] methods = typeof(PlayerControllerB).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { if (!Excluded.Contains(method.Name) && (method.Name.EndsWith("_performed") || method.Name.EndsWith("_started") || method.Name.EndsWith("_canceled"))) { yield return method; } } } [HarmonyPrefix] private static bool Prefix() { return !PlayerFreeze.IsLocalPlayerFrozen(); } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] public static class PlayerKillDeferPatch { [HarmonyPrefix] private static bool Prefix(PlayerControllerB __instance, Vector3 bodyVelocity, bool spawnBody, CauseOfDeath causeOfDeath, int deathAnimation, Vector3 positionOffset, bool setOverrideDropItems) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) if (!PauseState.IsPaused) { return true; } if (__instance.playerClientId == PauseState.CasterClientId) { return true; } PlayerKillQueue.Enqueue(__instance, bodyVelocity, spawnBody, causeOfDeath, deathAnimation, positionOffset, setOverrideDropItems); return false; } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] public static class PlayerTickPatch { [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController; if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance != (Object)(object)val)) { ModTick.Tick(); } } } [HarmonyPatch(typeof(RadMechMissile), "FixedUpdate")] public static class RadMechMissileFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(SpikeRoofTrap))] public static class SpikeTrapFreezePatch { [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefix() { return !PauseState.IsPaused; } [HarmonyPatch("OnTriggerStay")] [HarmonyPrefix] private static bool OnTriggerStayPrefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(SpikeRoofTrap), "Start")] public static class SpikeTrapRegistrationPatch { [HarmonyPostfix] private static void Postfix(SpikeRoofTrap __instance) { if (!SpikeTrapFreeze.Active.Contains(__instance)) { SpikeTrapFreeze.Active.Add(__instance); } } } [HarmonyPatch(typeof(TimeOfDay), "MoveTimeOfDay")] public static class TimeOfDayPatch { [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(Turret), "Update")] public static class TurretFreezePatch { [HarmonyPrefix] private static bool Prefix() { return !PauseState.IsPaused; } } [HarmonyPatch(typeof(Turret), "Start")] public static class TurretRegistrationPatch { [HarmonyPostfix] private static void Postfix(Turret __instance) { if (!TurretFreeze.Active.Contains(__instance)) { TurretFreeze.Active.Add(__instance); } } } } namespace DioCompany.Networking { [Serializable] public struct PauseStateData { public bool IsPaused; public ulong CasterClientId; public float CasterPosX; public float CasterPosY; public float CasterPosZ; public float TimeLimit; public Vector3 CasterPosition => new Vector3(CasterPosX, CasterPosY, CasterPosZ); public static PauseStateData Paused(ulong casterClientId, Vector3 casterPosition, float timeLimit) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) return new PauseStateData { IsPaused = true, CasterClientId = casterClientId, CasterPosX = casterPosition.x, CasterPosY = casterPosition.y, CasterPosZ = casterPosition.z, TimeLimit = timeLimit }; } public static PauseStateData Resumed() { return new PauseStateData { IsPaused = false }; } } public static class PauseNetworking { private static LNetworkMessage _toggleRequest; private static LNetworkMessage _stateChanged; private static bool _initialized; public static void Init() { if (!_initialized) { _initialized = true; _toggleRequest = LNetworkMessage.Connect("ToggleRequest", (Action)delegate(bool _, ulong senderClientId) { PauseController.HostHandleToggleRequest(senderClientId); }, (Action)null, (Action)null); _stateChanged = LNetworkMessage.Connect("PauseStateChanged", (Action)null, (Action)PauseController.ApplyStateChange, (Action)null); } } public static void RequestToggle() { _toggleRequest.SendServer(true); } public static void BroadcastState(PauseStateData data) { _stateChanged.SendClients(data); } } }