using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalNetworkAPI;
using TerminalApi;
using TerminalApi.Classes;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ForceTeleportAll")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ForceTeleportAll")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("400e4f1b-7434-404a-87c0-4c37ec11cd5b")]
[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 ForceTeleportAll;
[HarmonyPatch]
internal static class ShipTeleporterPatch
{
[HarmonyPatch(typeof(ShipTeleporter), "SetRandomSeed")]
[HarmonyPrefix]
private static void SetRandomSeedPreFix(ref bool ___isInverseTeleporter, ref bool ___hasBeenSpawnedThisSession, ref bool ___hasBeenSpawnedThisSessionInverse)
{
ForceTeleportAllBase.LoggerInstance.LogDebug((object)"IN PREFIX");
if (TeleportHandler.isMod)
{
ForceTeleportAllBase.LoggerInstance.LogDebug((object)"Ismod is true");
___isInverseTeleporter = true;
___hasBeenSpawnedThisSession = true;
___hasBeenSpawnedThisSessionInverse = true;
}
}
[HarmonyPatch(typeof(ShipTeleporter), "SetRandomSeed")]
[HarmonyPostfix]
private static void SetRandomSeedPostFix(ref Random ___shipTeleporterSeed)
{
ForceTeleportAllBase.LoggerInstance.LogDebug((object)"IN POSTFIX");
if (TeleportHandler.isMod)
{
TeleportHandler._random = new Random(StartOfRound.Instance.randomMapSeed);
}
}
}
internal class TeleportHandler : MonoBehaviour
{
private static readonly ManualLogSource LoggerInstance = ForceTeleportAllBase.LoggerInstance;
public static bool isMod;
public static Random _random;
private static PlayerControllerB PlayerToTeleport;
private static AudioSource PlayerAudioSource;
private AudioClip ShipTeleporterSpinInverseSFX;
private AudioClip ShipTeleporterBeamSFX;
public static Vector3 GetRandomPosition()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: 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)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
LoggerInstance.LogDebug((object)"Getting random teleport position");
int num = _random.Next(0, RoundManager.Instance.insideAINodes.Length);
Vector3 position = RoundManager.Instance.insideAINodes[num].transform.position;
LoggerInstance.LogDebug((object)$"Teleport position set to {position}");
return position;
}
public void SetTeleportData(ulong clientId)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
PlayerToTeleport = LethalNetworkExtensions.GetPlayerController(clientId);
PlayerAudioSource = (AudioSource)((Component)PlayerToTeleport).gameObject.AddComponent(typeof(AudioSource));
PlayerAudioSource.spatialBlend = 1f;
PlayerAudioSource.volume = 10f;
try
{
ShipTeleporterSpinInverseSFX = NetworkManagement.ShipTeleporterSpinInverseSFX.Value;
ShipTeleporterBeamSFX = NetworkManagement.ShipTeleporterBeamSFX.Value;
}
catch (Exception ex)
{
LoggerInstance.LogError((object)("An error occurred while setting teleport data: " + ex.Message));
}
}
public void StartTeleport()
{
LoggerInstance.LogDebug((object)"Inside StartTeleport");
((MonoBehaviour)this).StartCoroutine(InverseTeleportPlayer());
LoggerInstance.LogDebug((object)"Finished StartTeleport");
}
private IEnumerator InverseTeleportPlayer()
{
Vector3 _teleportPos = GetRandomPosition();
if (_teleportPos != Vector3.zero)
{
PlayerToTeleport.beamUpParticle.Play();
PlayAudioOnPlayerLocal(playOneShot: false);
yield return (object)new WaitForSeconds(4.5f);
PlayAudioOnPlayerLocal(playOneShot: true);
yield return (object)new WaitForSeconds(0.1f);
PlayerToTeleport.TeleportPlayer(_teleportPos, false, 0f, false, true);
yield return (object)new WaitForSeconds(0.1f);
PlayAudioOnPlayerLocal(playOneShot: true);
LoggerInstance.LogDebug((object)("Finished Teleport for " + PlayerToTeleport.playerUsername));
}
}
public static ShipTeleporter GetTeleporter(bool selectInverse = false)
{
ShipTeleporter[] array = Object.FindObjectsOfType<ShipTeleporter>();
for (int i = 0; i < array.Length; i++)
{
if (selectInverse == array[i].isInverseTeleporter)
{
return array[i];
}
}
return null;
}
private void PlayAudioOnPlayerLocal(bool playOneShot)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
try
{
if (playOneShot)
{
((Component)PlayerAudioSource).transform.position = ((Component)PlayerToTeleport).transform.position;
PlayerAudioSource.PlayOneShot(ShipTeleporterBeamSFX);
}
else
{
PlayerAudioSource.clip = ShipTeleporterSpinInverseSFX;
((Component)PlayerAudioSource).transform.position = ((Component)PlayerToTeleport).transform.position;
PlayerAudioSource.Play();
}
}
catch (Exception ex)
{
LoggerInstance.LogError((object)("PlayAudioOnPlayerLocal failed: " + ex.Message));
}
}
}
internal static class NetworkManagement
{
private static ManualLogSource LoggerInstance = ForceTeleportAllBase.LoggerInstance;
public static LethalServerEvent serverEvent = new LethalServerEvent("FTEevent", (Action<ulong>)null);
public static LethalClientEvent clientEvent = new LethalClientEvent("FTEevent", (Action)null, (Action<ulong>)null);
[PublicNetworkVariable]
public static LethalNetworkVariable<AudioClip> ShipTeleporterSpinInverseSFX = new LethalNetworkVariable<AudioClip>("ShipTeleporterSpinInverseSFX");
[PublicNetworkVariable]
public static LethalNetworkVariable<AudioClip> ShipTeleporterBeamSFX = new LethalNetworkVariable<AudioClip>("ShipTeleporterBeamSFX");
public static LethalNetworkVariable<bool> configHostOnly = new LethalNetworkVariable<bool>("configHostOnly");
public static LethalNetworkVariable<bool> configHostIncluded = new LethalNetworkVariable<bool>("configHostIncluded");
public static LethalNetworkVariable<bool> configUserIncluded = new LethalNetworkVariable<bool>("configUserIncluded");
public static LethalNetworkVariable<bool> configRequireTeleporter = new LethalNetworkVariable<bool>("configRequireTeleporter");
public static LethalNetworkVariable<bool> configRequireInverse = new LethalNetworkVariable<bool>("configRequireInverse");
public static LethalNetworkVariable<bool> configRespectCooldown = new LethalNetworkVariable<bool>("configRespectCooldown");
public static TeleportHandler teleportHandler;
public static PlayerControllerB CurrentClient => GameNetworkManager.Instance.localPlayerController;
public static void Init()
{
serverEvent.OnReceived += RecieveFromClient;
clientEvent.OnReceived += RecieveFromServer;
}
private static void RecieveFromClient(ulong clientId)
{
PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId);
PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
LoggerInstance.LogDebug((object)(localPlayerController.playerUsername + ": Recieved teleportall command from client: " + playerController.playerUsername + ", running MassTeleport..."));
MassTeleport(clientId);
}
private static void RecieveFromServer()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
ulong actualClientId = GameNetworkManager.Instance.localPlayerController.actualClientId;
LoggerInstance.LogDebug((object)$"{actualClientId} recieved teleportall command from server");
GameObject val = new GameObject();
teleportHandler = val.AddComponent<TeleportHandler>();
teleportHandler.SetTeleportData(actualClientId);
teleportHandler.StartTeleport();
}
public static void MassTeleport(ulong clientId)
{
int num = 0;
LoggerInstance.LogDebug((object)"MassTeleport Start");
LoggerInstance.LogDebug((object)$"{GameNetworkManager.Instance.localPlayerController} should only get this");
PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId);
LoggerInstance.LogDebug((object)(playerController.playerUsername + " used the teleportall command"));
LoggerInstance.LogDebug((object)"Starting loop");
for (int i = 0; i < StartOfRound.Instance.allPlayerObjects.Length; i++)
{
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
if (!val.isPlayerControlled)
{
continue;
}
LoggerInstance.LogDebug((object)$"Attempting teleport {val.playerUsername}, steamId: {val.playerSteamId}");
if (RoundManager.Instance.insideAINodes.Length == 0)
{
continue;
}
LoggerInstance.LogDebug((object)$"insideAINodes = {RoundManager.Instance.insideAINodes.Length}");
if (!val.isHostPlayerObject || configHostIncluded.Value)
{
LoggerInstance.LogDebug((object)"Pass host check in for loop");
if (!val.inTerminalMenu || configUserIncluded.Value)
{
LoggerInstance.LogDebug((object)"Pass userIncluded check in for loop");
serverEvent.InvokeClient(val.actualClientId);
num++;
LoggerInstance.LogDebug((object)$"_teleportCount is {num}");
}
}
}
LoggerInstance.LogDebug((object)$"Teleported {num} players...");
}
public static void GetAudioClips()
{
LoggerInstance.LogDebug((object)"Inside GetAudioClips");
AudioClip val = ShipTeleporterSpinInverseSFX.Value;
AudioClip val2 = ShipTeleporterBeamSFX.Value;
LoggerInstance.LogDebug((object)$"Values for audio files are {val} and {val2}");
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
LoggerInstance.LogDebug((object)"Getting audio files from game");
AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
LoggerInstance.LogDebug((object)$"Found {array.Length} audio files");
LoggerInstance.LogDebug((object)"Setting audio files in foreach loop");
AudioClip[] array2 = array;
foreach (AudioClip val3 in array2)
{
if (((Object)val3).name == "ShipTeleporterSpinInverse")
{
LoggerInstance.LogDebug((object)"Found AudioClip 'ShipTeleporterSpinInverse'");
val = val3;
}
if (((Object)val3).name == "ShipTeleporterBeam")
{
LoggerInstance.LogDebug((object)"Found AudioClip 'ShipTeleporterBeam'");
val2 = val3;
}
}
if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
{
LoggerInstance.LogDebug((object)"Setting audio files to network variables");
ShipTeleporterSpinInverseSFX.Value = val;
ShipTeleporterBeamSFX.Value = val2;
}
else
{
LoggerInstance.LogError((object)"Failed to get audio files");
}
}
else
{
LoggerInstance.LogDebug((object)"Audio files already loaded, skipping GetAudioClips");
}
}
}
[HarmonyPatch]
internal static class RoundManagerPatch
{
private static readonly ManualLogSource LoggerInstance = ForceTeleportAllBase.LoggerInstance;
[HarmonyPatch(typeof(RoundManager), "GenerateNewFloor")]
[HarmonyPostfix]
private static void GenerateNewFloorPatch(RoundManager __instance)
{
LoggerInstance.LogDebug((object)"SERVER: GenerateNewFloorPatch ran!");
TeleportHandler._random = new Random(StartOfRound.Instance.randomMapSeed + 17 + (int)GameNetworkManager.Instance.localPlayerController.playerClientId);
LoggerInstance.LogDebug((object)$"SERVER: Initialized a new random number generator with seed {StartOfRound.Instance.randomMapSeed}");
if (GameNetworkManager.Instance.isHostingGame)
{
NetworkManagement.configHostOnly.Value = ForceTeleportAllBase.configHostOnly.Value;
NetworkManagement.configHostIncluded.Value = ForceTeleportAllBase.configHostIncluded.Value;
NetworkManagement.configUserIncluded.Value = ForceTeleportAllBase.configUserIncluded.Value;
NetworkManagement.configRequireTeleporter.Value = ForceTeleportAllBase.configRequireTeleporter.Value;
NetworkManagement.configRequireInverse.Value = ForceTeleportAllBase.configRequireInverse.Value;
NetworkManagement.configRespectCooldown.Value = ForceTeleportAllBase.configRespectCooldown.Value;
LoggerInstance.LogDebug((object)$"SERVER: Config values set to {NetworkManagement.configHostOnly.Value}, {NetworkManagement.configHostIncluded.Value}, {NetworkManagement.configUserIncluded.Value}, {NetworkManagement.configRequireTeleporter.Value}, {NetworkManagement.configRequireInverse.Value}, {NetworkManagement.configRespectCooldown.Value}");
NetworkManagement.GetAudioClips();
}
}
}
[BepInPlugin("Snowlance.ForceTeleportAll", "Force Teleport Everyone", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ForceTeleportAllBase : BaseUnityPlugin
{
private const string modGUID = "Snowlance.ForceTeleportAll";
private const string modName = "Force Teleport Everyone";
private const string modVersion = "1.0.0";
private static string MTResult;
private readonly Harmony harmony = new Harmony("Snowlance.ForceTeleportAll");
public static ConfigEntry<bool> configHostOnly;
public static ConfigEntry<bool> configHostIncluded;
public static ConfigEntry<bool> configUserIncluded;
public static ConfigEntry<bool> configRequireTeleporter;
public static ConfigEntry<bool> configRequireInverse;
public static ConfigEntry<bool> configRespectCooldown;
public static ForceTeleportAllBase PluginInstance;
public static ManualLogSource LoggerInstance { get; private set; }
private void Awake()
{
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Expected O, but got Unknown
if ((Object)(object)PluginInstance == (Object)null)
{
PluginInstance = this;
}
LoggerInstance = ((BaseUnityPlugin)PluginInstance).Logger;
LoggerInstance.LogDebug((object)"Plugin Force Teleport Everyone loaded successfully.");
NetworkManagement.Init();
configHostOnly = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Host Settings", "Host only?", false, "If this is left true, only the host will be able to run the command.");
configHostIncluded = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Host Settings", "Should Host Teleport?", true, "If this is off, the command will teleport everyone EXCEPT for the host.");
configUserIncluded = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Teleporter Settings", "Should Terminal User Teleport?", true, "If set to false, will not teleport whoever used the command.");
configRequireTeleporter = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Teleporter Settings", "Require Teleporter?", false, "If this is true, a teleporter needs to be bought first before you can use the command.");
configRequireInverse = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Teleporter Settings", "Require Inverse Teleporter?", false, "If this is true, an inverse teleporter needs to be bought first before you can use the command.");
configRespectCooldown = ((BaseUnityPlugin)PluginInstance).Config.Bind<bool>("Teleporter Settings", "Respect Cooldown?", false, "If left as false, this will run the command even if the teleporters are on cooldown.");
harmony.PatchAll();
TerminalApi.AddCommand("teleportall", new CommandInfo
{
DisplayTextSupplier = delegate
{
if (StartOfRound.Instance.inShipPhase)
{
return "Cannot use this command until ship is landed.\n";
}
LoggerInstance.LogInfo((object)(NetworkManagement.CurrentClient.playerUsername + ": Attempt teleporting all players..."));
if (CheckConfigs())
{
NetworkManagement.clientEvent.InvokeServer();
}
return MTResult + "\n";
},
Category = "Other"
}, (string)null, true);
}
private bool CheckConfigs()
{
ShipTeleporter teleporter = TeleportHandler.GetTeleporter();
ShipTeleporter teleporter2 = TeleportHandler.GetTeleporter(selectInverse: true);
ManualLogSource loggerInstance = LoggerInstance;
loggerInstance.LogDebug((object)"Got teleporters");
if (!StartOfRound.Instance.shipHasLanded)
{
loggerInstance.LogDebug((object)"Ship isnt landed...");
MTResult = "Cannot use this command until ship is landed.";
return false;
}
loggerInstance.LogDebug((object)"Pass Ship has landed");
if (teleporter == null && configRequireTeleporter.Value)
{
loggerInstance.LogDebug((object)"No regular teleporter owned");
MTResult = "A teleporter is required to use this command...";
return false;
}
loggerInstance.LogDebug((object)"Pass teleporter check");
if (teleporter2 == null && configRequireInverse.Value)
{
if (teleporter2.cooldownAmount != 0f && configRespectCooldown.Value)
{
loggerInstance.LogDebug((object)"Teleporter on cooldown.");
MTResult = $"The Inverse Teleporter is on cooldown. {teleporter2.cooldownAmount} seconds until this command can be used...";
return false;
}
loggerInstance.LogDebug((object)"No inverse teleporter owned");
MTResult = "An inverse teleporter is required to use this command...";
return false;
}
loggerInstance.LogDebug((object)"Pass inverse check");
if (!StartOfRound.Instance.localPlayerController.isHostPlayerObject && configHostOnly.Value)
{
loggerInstance.LogDebug((object)"The host didnt use the command.");
MTResult = "Only the server owner is allowed to run this command...";
return false;
}
MTResult = $"Attempting to teleport {StartOfRound.Instance.allPlayerScripts.Length - 2} players...";
return true;
}
}