using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CG;
using CG.Game;
using CG.Game.Player;
using CG.Game.SpaceObjects.Controllers;
using CG.GameLoopStateMachine.GameStates;
using CG.Input;
using CG.Ship.Modules;
using CG.Space;
using Gameplay.Enhancements;
using Gameplay.Power;
using Gameplay.Ship;
using Gameplay.Utilities;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Opsive.UltimateCharacterController.Character;
using Opsive.UltimateCharacterController.Character.Abilities;
using Opsive.UltimateCharacterController.Traits;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using VoidManager;
using VoidManager.CustomGUI;
using VoidManager.MPModChecks;
using VoidManager.ModMessages;
using VoidManager.Utilities;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Pause")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.3.0")]
[assembly: AssemblyInformationalVersion("0.0.3+2ba816a61a02a0270ff73603bd1ffe85fb93238a")]
[assembly: AssemblyProduct("Pause")]
[assembly: AssemblyTitle("Allows the game to be paused during a Void Jump.")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 Pause
{
[BepInPlugin("18107.Pause", "Pause", "0.0.3")]
[BepInProcess("Void Crew.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class BepinPlugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
private void Awake()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "18107.Pause");
Configs.Load(this);
((Object)new GameObject("PausedGUI", new Type[1] { typeof(PausedGUI) })).hideFlags = (HideFlags)61;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin 18107.Pause is loaded!");
}
}
internal class Configs
{
internal static ConfigEntry<KeyCode> pauseKeyConfig;
internal static ConfigEntry<bool> playersCanPauseConfig;
internal static void Load(BepinPlugin plugin)
{
pauseKeyConfig = ((BaseUnityPlugin)plugin).Config.Bind<KeyCode>("Pause", "PauseKey", (KeyCode)278, (ConfigDescription)null);
playersCanPauseConfig = ((BaseUnityPlugin)plugin).Config.Bind<bool>("Pause", "PlayersCanPause", false, (ConfigDescription)null);
}
}
internal class GUI : ModSettingsMenu
{
public override string Name()
{
return "Pause";
}
public override void Draw()
{
ClientGame current = ClientGame.Current;
object obj;
if (current == null)
{
obj = null;
}
else
{
AbstractPlayerControlledShip playerShip = current.PlayerShip;
if (playerShip == null)
{
obj = null;
}
else
{
Transform transform = ((Component)playerShip).transform;
obj = ((transform != null) ? ((Component)transform).GetComponent<VoidJumpSystem>() : null);
}
}
VoidJumpSystem val = (VoidJumpSystem)obj;
VoidJumpState val2 = ((val != null) ? val.ActiveState : null);
GUILayout.Label("", Array.Empty<GUILayoutOption>());
if (PhotonNetwork.IsMasterClient || PauseManager.CanPause)
{
if (val2 is VoidJumpTravellingStable || val2 is VoidJumpTravellingUnstable)
{
if (GUILayout.Button(PauseManager.IsPaused ? "Resume" : "Pause", Array.Empty<GUILayoutOption>()))
{
PauseManager.TryTogglePause();
}
}
else
{
GUILayout.Button("Pause only available in Void Jump", Array.Empty<GUILayoutOption>());
}
}
else
{
GUILayout.Button((PauseManager.IsPaused ? "Resume" : "Pause") + " not permitted by host", Array.Empty<GUILayoutOption>());
}
GUILayout.Label("", Array.Empty<GUILayoutOption>());
if (GUITools.DrawCheckbox("Allow other players to pause/resume", ref Configs.playersCanPauseConfig))
{
PauseManager.SendCanPause();
}
GUITools.DrawChangeKeybindButton("Pause keybind", ref Configs.pauseKeyConfig);
}
}
public class MyPluginInfo
{
public const string PLUGIN_GUID = "18107.Pause";
public const string PLUGIN_NAME = "Pause";
public const string USERS_PLUGIN_NAME = "Pause";
public const string PLUGIN_VERSION = "0.0.3";
public const string PLUGIN_DESCRIPTION = "Allows the game to be paused during a Void Jump.";
public const string PLUGIN_ORIGINAL_AUTHOR = "18107";
public const string PLUGIN_AUTHORS = "18107";
public const string PLUGIN_THUNDERSTORE_ID = "VoidCrewModdingTeam/Pause";
}
[HarmonyPatch(typeof(GSTallyScreen))]
internal class GSTallyScreenPatch
{
[HarmonyPrefix]
[HarmonyPatch("OnEnter")]
private static void OnEnter()
{
PauseManager.Reset();
}
}
[HarmonyPatch(typeof(VoidJumpTravellingStable))]
internal class VoidJumpTravellingStablePatch
{
[HarmonyPrefix]
[HarmonyPatch("OnExit")]
private static void OnExit()
{
PauseManager.Reset();
}
}
internal class PausedGUI : MonoBehaviour, IShowCursorSource, IInputActionMapRequest
{
private bool guiActive = false;
private Rect WindowPos;
private PausedGUI()
{
}
private void Update()
{
//IL_0064: 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)
if (PauseManager.IsPaused != guiActive)
{
InputActionMapRequests.RemoveRequest((IInputActionMapRequest)(object)this);
guiActive = PauseManager.IsPaused;
if (guiActive)
{
WindowPos = new Rect((float)Screen.width / 4f, (float)Screen.height / 4f, (float)Screen.width / 2f, (float)Screen.height / 2f);
}
CursorUtility.ShowCursor((IShowCursorSource)(object)this, guiActive);
}
}
private void OnGUI()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (guiActive)
{
InputActionMapRequests.AddOrChangeRequest((IInputActionMapRequest)(object)this, (InputStateRequestType)2);
GUI.Window(618107, WindowPos, new WindowFunction(WindowFunction), "Game Paused");
}
}
private void WindowFunction(int WindowID)
{
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.FlexibleSpace();
if (PauseManager.pausePlayer != null)
{
GUILayout.Label("Game paused by " + PauseManager.pausePlayer.NickName, Array.Empty<GUILayoutOption>());
}
else
{
GUILayout.Label("Game paused", Array.Empty<GUILayoutOption>());
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.Label("", Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.FlexibleSpace();
if (PhotonNetwork.IsMasterClient || PauseManager.CanPause)
{
if (GUILayout.Button(" Resume ", Array.Empty<GUILayoutOption>()))
{
PauseManager.TryTogglePause();
}
}
else
{
GUILayout.Button((PauseManager.IsPaused ? "Resume" : "Pause") + " not permitted by host", Array.Empty<GUILayoutOption>());
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
}
}
internal class PauseManager : ModMessage
{
private enum MessageType
{
Pause,
CanPause
}
private const int version = 1;
private static readonly FieldInfo characterHealthField = AccessTools.Field(typeof(Player), "characterHealth");
private static readonly FieldInfo OxygenDepositField = AccessTools.Field(typeof(LocalPlayer), "OxygenDeposit");
private static readonly FieldInfo activationEndTimeField = AccessTools.Field(typeof(Enhancement), "_activationEndTime");
private static readonly FieldInfo currentTemperatureField = AccessTools.Field(typeof(ProtectedPowerSystem), "currentTemperature");
private static LocalPlayer player;
private static float playerOxygen;
private static bool wasInvulnerable;
private static Vector3 position;
private static int startTime;
private static Dictionary<Enhancement, int> EngineTrims;
private static ProtectedPowerSystem breakers;
private static float breakerTemperature;
private static bool _isPaused = false;
internal static Player pausePlayer;
private static bool stable = true;
internal static bool IsPaused
{
get
{
return _isPaused;
}
private set
{
//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Expected O, but got Unknown
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
if (value == _isPaused)
{
return;
}
_isPaused = value;
if (value)
{
Events.Instance.LateUpdate += WhilePaused;
player = LocalPlayer.Instance;
CustomCharacterHealth val = (CustomCharacterHealth)characterHealthField.GetValue(player);
wasInvulnerable = val.IsInvulnerable;
val.IsInvulnerable = true;
playerOxygen = ((Attribute)OxygenDepositField.GetValue(player)).Value;
position = ((CharacterLocomotion)((Player)player).Locomotion).Transform.position;
startTime = PhotonNetwork.ServerTimestamp;
ClientGame current = ClientGame.Current;
object engineTrims;
if (current == null)
{
engineTrims = null;
}
else
{
AbstractPlayerControlledShip playerShip = current.PlayerShip;
if (playerShip == null)
{
engineTrims = null;
}
else
{
Helm module = playerShip.GetModule<Helm>();
if (module == null)
{
engineTrims = null;
}
else
{
ShipEngine engine = module.Engine;
engineTrims = ((engine != null) ? ((Component)engine).GetComponentsInChildren<Enhancement>().ToDictionary((Enhancement trim) => trim, (Enhancement trim) => (int)activationEndTimeField.GetValue(trim) - startTime) : null);
}
}
}
EngineTrims = (Dictionary<Enhancement, int>)engineTrims;
ClientGame current2 = ClientGame.Current;
object obj;
if (current2 == null)
{
obj = null;
}
else
{
AbstractPlayerControlledShip playerShip2 = current2.PlayerShip;
obj = ((playerShip2 != null) ? ((Component)playerShip2).GetComponentInChildren<ProtectedPowerSystem>() : null);
}
breakers = (ProtectedPowerSystem)obj;
float num = (float)currentTemperatureField.GetValue(breakers);
breakerTemperature = Mathf.Min(num - ((ModifiablePrimitive<float, FloatModifier>)(object)breakers.BreakerTemperatureShiftSpeed).Value, num);
}
else
{
Events.Instance.LateUpdate -= WhilePaused;
player = LocalPlayer.Instance;
CustomCharacterHealth val2 = (CustomCharacterHealth)characterHealthField.GetValue(player);
val2.IsInvulnerable = wasInvulnerable;
}
}
}
internal static bool CanPause { get; private set; } = false;
internal static void TryTogglePause(Player pauser = null)
{
if (!PhotonNetwork.IsMasterClient)
{
RequestPause(!IsPaused);
return;
}
ClientGame current = ClientGame.Current;
object obj;
if (current == null)
{
obj = null;
}
else
{
AbstractPlayerControlledShip playerShip = current.PlayerShip;
if (playerShip == null)
{
obj = null;
}
else
{
Transform transform = ((Component)playerShip).transform;
obj = ((transform != null) ? ((Component)transform).GetComponent<VoidJumpSystem>() : null);
}
}
VoidJumpSystem val = (VoidJumpSystem)obj;
VoidJumpState val2 = ((val != null) ? val.ActiveState : null);
if (val2 == null)
{
IsPaused = false;
}
else
{
if (!(val2 is VoidJumpTravellingStable) && !(val2 is VoidJumpTravellingUnstable))
{
return;
}
pausePlayer = pauser ?? PhotonNetwork.LocalPlayer;
if (IsPaused)
{
IsPaused = false;
if (!stable)
{
val.ChangeActiveState<VoidJumpTravellingUnstable>();
stable = true;
}
}
else
{
IsPaused = true;
if (val2 is VoidJumpTravellingUnstable)
{
stable = false;
val.ChangeActiveState<VoidJumpTravellingStable>();
}
}
SendPause(IsPaused, pausePlayer);
}
}
private static void WhilePaused(object o, EventArgs e)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_009b: 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)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
Attribute val = (Attribute)OxygenDepositField.GetValue(player);
if (val.Value < playerOxygen)
{
val.Value = playerOxygen;
}
if (((IEnumerable<Ability>)((UltimateCharacterLocomotion)((Player)player).Locomotion).Abilities).FirstOrDefault((Func<Ability, bool>)((Ability ability) => ability is MoveThroughPoints)).IsActive)
{
position = ((CharacterLocomotion)((Player)player).Locomotion).Transform.position;
}
if (((CharacterLocomotion)((Player)player).Locomotion).Transform.position != position)
{
((CharacterLocomotion)((Player)player).Locomotion).Transform.position = position;
}
int serverTimestamp = PhotonNetwork.ServerTimestamp;
foreach (KeyValuePair<Enhancement, int> engineTrim in EngineTrims)
{
Enhancement key = engineTrim.Key;
int value = engineTrim.Value;
activationEndTimeField.SetValue(key, serverTimestamp + value);
}
currentTemperatureField.SetValue(breakers, breakerTemperature);
}
internal static void Reset()
{
IsPaused = false;
}
public override void Handle(object[] arguments, Player sender)
{
if (arguments.Length < 3)
{
return;
}
if ((int)arguments[0] != 1)
{
BepinPlugin.Log.LogInfo((object)$"Received version {(int)arguments[0]}, expected {1}");
}
else if (PhotonNetwork.IsMasterClient)
{
if ((MessageType)arguments[1] == MessageType.Pause && Configs.playersCanPauseConfig.Value && (bool)arguments[2] != IsPaused)
{
pausePlayer = sender;
TryTogglePause(pausePlayer);
}
}
else
{
if (sender != PhotonNetwork.MasterClient)
{
return;
}
switch ((MessageType)arguments[1])
{
case MessageType.Pause:
IsPaused = (bool)arguments[2];
if (arguments.Length >= 4)
{
pausePlayer = PhotonNetwork.CurrentRoom.GetPlayer((int)arguments[3], false);
}
break;
case MessageType.CanPause:
CanPause = (bool)arguments[2];
break;
}
}
}
internal static void RequestPause(bool pause)
{
if (!PhotonNetwork.IsMasterClient)
{
Send(new object[3]
{
1,
MessageType.Pause,
pause
}, PhotonNetwork.MasterClient);
}
}
internal static void SendPause(bool pause, Player pauser, params Player[] players)
{
if (PhotonNetwork.IsMasterClient)
{
Send(new object[4]
{
1,
MessageType.Pause,
pause,
pauser.ActorNumber
}, players);
}
}
internal static void SendCanPause(params Player[] players)
{
if (PhotonNetwork.IsMasterClient)
{
Send(new object[3]
{
1,
MessageType.CanPause,
Configs.playersCanPauseConfig.Value
}, players);
}
}
private static void Send(object[] arguments, params Player[] players)
{
if (players.Length != 0)
{
ModMessage.Send("18107.Pause", ModMessage.GetIdentifier(typeof(PauseManager)), players, arguments, true);
}
else
{
ModMessage.Send("18107.Pause", ModMessage.GetIdentifier(typeof(PauseManager)), (ReceiverGroup)0, arguments, true);
}
}
}
public class VoidManagerPlugin : VoidPlugin
{
public override MultiplayerType MPType => (MultiplayerType)30;
public override string Author => "18107";
public override string Description => "Allows the game to be paused during a Void Jump.";
public override string ThunderstoreID => "VoidCrewModdingTeam/Pause";
public VoidManagerPlugin()
{
Events.Instance.PlayerEnteredRoom += delegate(object _, PlayerEventArgs playerEventArgs)
{
PauseManager.SendCanPause(playerEventArgs.player);
PauseManager.SendPause(PauseManager.IsPaused, PauseManager.pausePlayer ?? PhotonNetwork.LocalPlayer, playerEventArgs.player);
};
Events.Instance.MasterClientSwitched += delegate
{
PauseManager.SendCanPause();
PauseManager.SendPause(PauseManager.IsPaused, PauseManager.pausePlayer ?? PhotonNetwork.LocalPlayer);
};
Events.Instance.LeftRoom += delegate
{
PauseManager.Reset();
};
Events.Instance.LateUpdate += delegate
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if ((int)Configs.pauseKeyConfig.Value != 0 && UnityInput.Current.GetKeyDown(Configs.pauseKeyConfig.Value) && (!ServiceBase<InputService>.Instance.CursorVisibilityControl.IsCursorShown || PauseManager.IsPaused))
{
if (!PhotonNetwork.IsMasterClient && !PauseManager.CanPause)
{
Messaging.Notification("Not permitted by host", 8000L, false);
}
else
{
ClientGame current = ClientGame.Current;
object obj;
if (current == null)
{
obj = null;
}
else
{
AbstractPlayerControlledShip playerShip = current.PlayerShip;
if (playerShip == null)
{
obj = null;
}
else
{
Transform transform = ((Component)playerShip).transform;
obj = ((transform != null) ? ((Component)transform).GetComponent<VoidJumpSystem>() : null);
}
}
VoidJumpSystem val = (VoidJumpSystem)obj;
VoidJumpState val2 = ((val != null) ? val.ActiveState : null);
if (val2 == null || (!(val2 is VoidJumpTravellingStable) && !(val2 is VoidJumpTravellingUnstable)))
{
Messaging.Notification("Not in void jump", 8000L, false);
}
else
{
PauseManager.TryTogglePause();
}
}
}
};
}
}
}