using System;
using System.Diagnostics;
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.SpaceObjects.Controllers;
using CG.Input;
using CG.Space;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ac1a08ccd0b69114cebdadf2c012548719f04284")]
[assembly: AssemblyProduct("Pause")]
[assembly: AssemblyTitle("Allows the game to be paused during a Void Jump.")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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("VoidCrewModdingTeam.Pause", "Pause", "1.0.0")]
[BepInProcess("Void Crew.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class BepinPlugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
private void Awake()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
Configs.Load(this);
((Object)new GameObject("PausedGUI", new Type[1] { typeof(PausedGUI) })).hideFlags = (HideFlags)61;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin VoidCrewModdingTeam.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);
}
}
[HarmonyPatch("UnityEngine.UIElements.Panel, UnityEngine.UIElementsModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", "DefaultTimeSinceStartupMs")]
internal class HudTimersPatch
{
private static bool Prefix(ref long __result)
{
__result = (long)(Time.time * 1000f);
return false;
}
}
public class MyPluginInfo
{
public const string PLUGIN_GUID = "VoidCrewModdingTeam.Pause";
public const string PLUGIN_NAME = "Pause";
public const string USERS_PLUGIN_NAME = "Pause";
public const string PLUGIN_VERSION = "1.0.0";
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 = "Dragon, 18107";
public const string PLUGIN_THUNDERSTORE_ID = "VoidCrewModdingTeam/Pause";
}
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 = 2;
private static bool _isPaused = false;
internal static Player pausePlayer;
private static bool stable = true;
internal static bool IsPaused
{
get
{
return _isPaused;
}
private set
{
if (value != _isPaused)
{
_isPaused = value;
if (value)
{
PhotonNetwork.MinimalTimeScaleToDispatchInFixedUpdate = 0f;
Time.timeScale = 0f;
}
else
{
Time.timeScale = 1f;
PhotonNetwork.MinimalTimeScaleToDispatchInFixedUpdate = -1f;
}
}
}
}
internal static bool CanPause { get; private set; } = false;
internal static void TryTogglePause(Player pauser = null)
{
if (!PhotonNetwork.IsMasterClient)
{
BepinPlugin.Log.LogInfo((object)"TryToggle non-host triggered.");
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 || (!(val2 is VoidJumpTravellingStable) && !(val2 is VoidJumpTravellingUnstable)))
{
IsPaused = false;
return;
}
IsPaused = !IsPaused;
BepinPlugin.Log.LogInfo((object)"Toggled Pause from handler");
ServerTimestampPatch.UpdateTiming(IsPaused);
pausePlayer = pauser ?? PhotonNetwork.LocalPlayer;
SendPause(IsPaused, pausePlayer);
}
internal static void Reset()
{
IsPaused = false;
ServerTimestampPatch.PauseTotal = 0;
}
public override void Handle(object[] arguments, Player sender)
{
if (arguments.Length < 3)
{
return;
}
if ((int)arguments[0] != 2)
{
BepinPlugin.Log.LogInfo((object)$"Received version {(int)arguments[0]}, expected {2}");
}
else if (PhotonNetwork.IsMasterClient)
{
BepinPlugin.Log.LogInfo((object)$"Recieved Pause Request ({(bool)arguments[2]}) message from {sender.NickName}");
if ((MessageType)arguments[1] == MessageType.Pause && Configs.playersCanPauseConfig.Value && (bool)arguments[2] != IsPaused)
{
pausePlayer = sender;
TryTogglePause(pausePlayer);
}
}
else
{
if (!sender.IsMasterClient)
{
return;
}
switch ((MessageType)arguments[1])
{
case MessageType.Pause:
BepinPlugin.Log.LogInfo((object)$"Recieved Pause ({(bool)arguments[2]}) message from {sender.NickName}");
IsPaused = (bool)arguments[2];
if (arguments.Length > 3)
{
pausePlayer = PhotonNetwork.CurrentRoom.GetPlayer((int)arguments[3], false);
ServerTimestampPatch.PauseTotal = (int)arguments[4];
ServerTimestampPatch.UpdateTiming(paused: true);
}
break;
case MessageType.CanPause:
BepinPlugin.Log.LogInfo((object)("Recieved CanPause message from " + sender.NickName));
CanPause = (bool)arguments[2];
break;
}
}
}
internal static void RequestPause(bool pause)
{
if (!PhotonNetwork.IsMasterClient)
{
Send(new object[3]
{
2,
MessageType.Pause,
pause
}, PhotonNetwork.MasterClient);
BepinPlugin.Log.LogInfo((object)"RequestPause sent.");
}
}
internal static void SendPause(bool pause, Player pauser, params Player[] players)
{
if (PhotonNetwork.IsMasterClient)
{
Send(new object[5]
{
2,
MessageType.Pause,
pause,
pauser.ActorNumber,
ServerTimestampPatch.GetPauseTotalForClient()
}, players);
BepinPlugin.Log.LogInfo((object)"SendPause sent.");
}
}
internal static void SendCanPause(params Player[] players)
{
if (PhotonNetwork.IsMasterClient)
{
Send(new object[3]
{
2,
MessageType.CanPause,
Configs.playersCanPauseConfig.Value
}, players);
}
}
private static void Send(object[] arguments, params Player[] players)
{
if (players.Length != 0)
{
ModMessage.Send("VoidCrewModdingTeam.Pause", ModMessage.GetIdentifier(typeof(PauseManager)), players, arguments, true);
}
else
{
ModMessage.Send("VoidCrewModdingTeam.Pause", ModMessage.GetIdentifier(typeof(PauseManager)), (ReceiverGroup)0, arguments, true);
}
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal class ServerTimestampPatch
{
internal static int cachedServerTime;
internal static int PauseTotal;
private static FieldInfo StartupStopwatchFI = AccessTools.Field(typeof(PhotonNetwork), "StartupStopwatch");
internal static int GetPauseTotalForClient()
{
if (PauseManager.IsPaused)
{
return PauseTotal + UnmodifiedServerTimestamp() - cachedServerTime;
}
return PauseTotal;
}
public static int UnmodifiedServerTimestamp()
{
if (!PhotonNetwork.OfflineMode)
{
return ((PhotonPeer)PhotonNetwork.NetworkingClient.LoadBalancingPeer).ServerTimeInMilliSeconds;
}
if (StartupStopwatchFI.GetValue(null) != null && ((Stopwatch)StartupStopwatchFI.GetValue(null)).IsRunning)
{
return (int)((Stopwatch)StartupStopwatchFI.GetValue(null)).ElapsedMilliseconds;
}
return Environment.TickCount;
}
internal static void UpdateTiming(bool paused)
{
if (paused)
{
cachedServerTime = UnmodifiedServerTimestamp();
}
else
{
PauseTotal += UnmodifiedServerTimestamp() - cachedServerTime;
}
}
private static void Postfix(ref int __result)
{
if (PauseManager.IsPaused)
{
__result = cachedServerTime - PauseTotal;
}
else
{
__result -= PauseTotal;
}
}
}
public class VoidManagerPlugin : VoidPlugin
{
public override MultiplayerType MPType => (MultiplayerType)30;
public override string Author => "Dragon, 18107";
public override string Description => "Allows the game to be paused during a Void Jump.";
public override string ThunderstoreID => "VoidCrewModdingTeam/Pause";
public VoidManagerPlugin()
{
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "VoidCrewModdingTeam.Pause");
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();
}
}
}
};
}
}
}