using System; using System.Collections; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ShipTeleportKey")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+caff75b709da63c082e01784e214d55304ad9240")] [assembly: AssemblyProduct("ShipTeleportKey")] [assembly: AssemblyTitle("ShipTeleportKey")] [assembly: AssemblyVersion("1.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 ShipTeleportKey { [BepInPlugin("dp991.ShipTeleportKey", "ShipTeleportKey", "1.5.4")] public class ShipTeleportKeyPlugin : BaseUnityPlugin { public const string Guid = "dp991.ShipTeleportKey"; public const string Name = "ShipTeleportKey"; public const string Version = "1.5.4"; internal static ManualLogSource Log; internal static ConfigEntry TeleportKey; internal static ConfigEntry KeepItems; internal static ConfigEntry InverseCooldown; private void Awake() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; TeleportKey = ((BaseUnityPlugin)this).Config.Bind("General", "TeleportKey", (Key)97, "Кнопка, по которой телепорт корабля забирает тебя на корабль."); KeepItems = ((BaseUnityPlugin)this).Config.Bind("General", "KeepItemsOnTeleport", true, "Не выбрасывать предметы из рук при телепортации (и обычным, и инверсным телепортом)."); InverseCooldown = ((BaseUnityPlugin)this).Config.Bind("General", "InverseTeleportCooldownSeconds", 10f, "Перезарядка инверсного телепорта (который кидает в помещение) в секундах. В игре по умолчанию 210."); Harmony val = new Harmony("dp991.ShipTeleportKey"); val.PatchAll(typeof(KeepItemsPatches)); val.PatchAll(typeof(CooldownPatches)); val.PatchAll(typeof(TeleportTargetPatches)); val.PatchAll(typeof(NetworkPrefabPatch2)); GameObject val2 = new GameObject("ShipTeleportKeyRunner") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val2); val2.AddComponent(); Log.LogInfo((object)string.Format("{0} {1} загружен. Кнопка телепорта: {2}", "ShipTeleportKey", "1.5.4", TeleportKey.Value)); } } internal class TeleportRunner : MonoBehaviour { private static readonly FieldInfo CooldownField = typeof(ShipTeleporter).GetField("cooldownTime", BindingFlags.Instance | BindingFlags.NonPublic); private bool _teleportInProgress; private bool _firstUpdateLogged; private bool _keyWasPressed; private float _lastPressTime = -10f; private InputAction _teleportAction; private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown if (!_firstUpdateLogged) { _firstUpdateLogged = true; ShipTeleportKeyPlugin.Log.LogInfo((object)$"Update работает. Клавиатура обнаружена: {Keyboard.current != null}."); } Keyboard current = Keyboard.current; if (current == null) { return; } Key value = ShipTeleportKeyPlugin.TeleportKey.Value; if (_teleportAction == null) { string path = ((InputControl)current[value]).path; _teleportAction = new InputAction("ShipTeleportKey.Teleport", (InputActionType)1, path, (string)null, (string)null, (string)null); _teleportAction.performed += delegate { OnTeleportKeyPressed("InputAction"); }; _teleportAction.Enable(); ShipTeleportKeyPlugin.Log.LogInfo((object)("Кнопка привязана через InputAction: " + path)); } bool isPressed = ((ButtonControl)current[value]).isPressed; if (isPressed && !_keyWasPressed) { OnTeleportKeyPressed("опрос isPressed"); } _keyWasPressed = isPressed; } private void OnDisable() { ShipTeleportKeyPlugin.Log.LogWarning((object)"TeleportRunner отключён (OnDisable) — кнопка перестанет работать!"); } private void OnDestroy() { ShipTeleportKeyPlugin.Log.LogWarning((object)"TeleportRunner уничтожен (OnDestroy) — кнопка перестанет работать!"); InputAction teleportAction = _teleportAction; if (teleportAction != null) { teleportAction.Disable(); } InputAction teleportAction2 = _teleportAction; if (teleportAction2 != null) { teleportAction2.Dispose(); } } private void OnTeleportKeyPressed(string source) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!(Time.unscaledTime - _lastPressTime < 0.3f)) { _lastPressTime = Time.unscaledTime; if (!_teleportInProgress) { ShipTeleportKeyPlugin.Log.LogInfo((object)$"Нажата кнопка {ShipTeleportKeyPlugin.TeleportKey.Value} (источник: {source}) — пробую телепортироваться."); TryTeleportSelf(); } } } private void TryTeleportSelf() { ManualLogSource log = ShipTeleportKeyPlugin.Log; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null) { log.LogInfo((object)"StartOfRound.Instance == null (мы в главном меню?) — отмена."); return; } PlayerControllerB localPlayerController = instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { log.LogInfo((object)"localPlayerController == null — отмена."); return; } if (localPlayerController.isTypingChat || localPlayerController.inTerminalMenu) { log.LogInfo((object)$"Игрок занят (чат: {localPlayerController.isTypingChat}, терминал: {localPlayerController.inTerminalMenu}) — отмена."); return; } ShipTeleporter val = FindShipTeleporter(); if ((Object)(object)val == (Object)null) { log.LogInfo((object)"Телепорт на корабле не найден — телепортация невозможна."); return; } float num = ((CooldownField != null) ? ((float)CooldownField.GetValue(val)) : 0f); if (num > 0f) { log.LogInfo((object)$"Телепорт на перезарядке: ещё {num:F0} сек."); HUDManager instance2 = HUDManager.Instance; if (instance2 != null) { instance2.DisplayTip("Телепорт", $"Перезарядка: ещё {(int)num} сек.", false, false, "LC_Tip1"); } return; } ManualCameraRenderer mapScreen = instance.mapScreen; if ((Object)(object)mapScreen == (Object)null) { log.LogInfo((object)"mapScreen == null — отмена."); return; } bool flag = instance.inShipPhase && !localPlayerController.isInsideFactory; int num2 = (flag ? mapScreen.targetTransformIndex : FindPlayerRadarIndex(mapScreen, localPlayerController)); if (num2 < 0 || num2 >= mapScreen.radarTargets.Count) { log.LogWarning((object)"Не удалось определить цель на радаре — отмена."); return; } string arg = mapScreen.radarTargets[num2]?.name ?? "?"; log.LogInfo((object)(flag ? $"На корабле — цель [{num2}]: {arg}." : $"На луне — цель (я) [{num2}]: {arg}.")); if (!flag && (mapScreen.targetTransformIndex != num2 || (Object)(object)mapScreen.targetedPlayer == (Object)null || (Object)(object)mapScreen.targetedPlayer != (Object)(object)localPlayerController)) { ((MonoBehaviour)this).StartCoroutine(SyncRadarAndPress(mapScreen, num2, val)); } else { PressTeleportWithLockedTarget(mapScreen, num2, val); } } private static int FindPlayerRadarIndex(ManualCameraRenderer mapScreen, PlayerControllerB player) { for (int i = 0; i < mapScreen.radarTargets.Count; i++) { TransformAndName val = mapScreen.radarTargets[i]; if (val != null && (Object)(object)val.transform == (Object)(object)((Component)player).transform) { return i; } } return -1; } private static void PressTeleportWithLockedTarget(ManualCameraRenderer mapScreen, int targetIndex, ShipTeleporter teleporter) { TeleportTargetPatches.ApplyRadarTarget(mapScreen, targetIndex); TeleportTargetPatches.LockedTargetIndex = targetIndex; try { ShipTeleportKeyPlugin.Log.LogInfo((object)"Нажимаю кнопку телепорта."); teleporter.PressTeleportButtonOnLocalClient(); } catch (Exception arg) { ShipTeleportKeyPlugin.Log.LogError((object)$"Ошибка при нажатии телепорта: {arg}"); } finally { TeleportTargetPatches.LockedTargetIndex = -1; } } private IEnumerator SyncRadarAndPress(ManualCameraRenderer mapScreen, int targetIndex, ShipTeleporter teleporter) { _teleportInProgress = true; try { ShipTeleportKeyPlugin.Log.LogInfo((object)$"Синхронизирую радар на индекс {targetIndex}..."); mapScreen.SwitchRadarTargetAndSync(targetIndex); yield return (object)new WaitForSecondsRealtime(0.35f); PressTeleportWithLockedTarget(mapScreen, targetIndex, teleporter); } finally { _teleportInProgress = false; } } private static ShipTeleporter FindShipTeleporter() { ShipTeleporter[] array = Object.FindObjectsOfType(); foreach (ShipTeleporter val in array) { if (!val.isInverseTeleporter) { return val; } } return null; } } internal static class TeleportTargetPatches { internal static int LockedTargetIndex = -1; internal static void ApplyRadarTarget(ManualCameraRenderer mapScreen, int index) { if (!((Object)(object)mapScreen == (Object)null) && index >= 0 && index < mapScreen.radarTargets.Count) { TransformAndName val = mapScreen.radarTargets[index]; if (!((Object)(object)val?.transform == (Object)null)) { mapScreen.targetTransformIndex = index; mapScreen.targetedPlayer = ((Component)val.transform).GetComponentInParent(); } } } [HarmonyPatch(typeof(ShipTeleporter), "PressTeleportButtonClientRpc")] [HarmonyPrefix] private static void LockTargetBeforeBeamUp(ShipTeleporter __instance) { if (!__instance.isInverseTeleporter) { ManualCameraRenderer val = StartOfRound.Instance?.mapScreen; if (!((Object)(object)val == (Object)null)) { int index = ((LockedTargetIndex >= 0) ? LockedTargetIndex : val.targetTransformIndex); ApplyRadarTarget(val, index); } } } } internal static class KeepItemsPatches { private static bool _inverseTeleportInProgress; private static bool IsLocalPlayer(PlayerControllerB player) { if ((Object)(object)GameNetworkManager.Instance != (Object)null) { return (Object)(object)player == (Object)(object)GameNetworkManager.Instance.localPlayerController; } return false; } [HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItemsAndSync")] [HarmonyPrefix] private static bool SkipDropOnBeamUp(PlayerControllerB __instance) { if (ShipTeleportKeyPlugin.KeepItems.Value && __instance.shipTeleporterId == 1 && IsLocalPlayer(__instance)) { ShipTeleportKeyPlugin.Log.LogInfo((object)"Телепорт на корабль: оставляю предметы в руках."); return false; } return true; } [HarmonyPatch(typeof(ShipTeleporter), "TeleportPlayerOutWithInverseTeleporter")] [HarmonyPrefix] private static void InverseTeleportStarted() { _inverseTeleportInProgress = true; } [HarmonyPatch(typeof(ShipTeleporter), "TeleportPlayerOutWithInverseTeleporter")] [HarmonyFinalizer] private static void InverseTeleportFinished() { _inverseTeleportInProgress = false; } [HarmonyPatch(typeof(PlayerControllerB), "DropAllHeldItems")] [HarmonyPrefix] private static bool SkipDropOnInverseTeleport(PlayerControllerB __instance) { if (ShipTeleportKeyPlugin.KeepItems.Value && _inverseTeleportInProgress && IsLocalPlayer(__instance)) { ShipTeleportKeyPlugin.Log.LogInfo((object)"Телепорт с корабля: оставляю предметы в руках."); return false; } return true; } } internal static class CooldownPatches { private static readonly FieldInfo CooldownTimeField = typeof(ShipTeleporter).GetField("cooldownTime", BindingFlags.Instance | BindingFlags.NonPublic); [HarmonyPatch(typeof(ShipTeleporter), "Awake")] [HarmonyPostfix] private static void ReduceInverseCooldown(ShipTeleporter __instance) { if (__instance.isInverseTeleporter) { float num = (__instance.cooldownAmount = Mathf.Max(0f, ShipTeleportKeyPlugin.InverseCooldown.Value)); if (CooldownTimeField != null && (float)CooldownTimeField.GetValue(__instance) > num) { CooldownTimeField.SetValue(__instance, num); } ShipTeleportKeyPlugin.Log.LogInfo((object)$"Перезарядка инверсного телепорта установлена: {num} сек."); } } } [HarmonyPatch(typeof(NetworkManager))] internal static class NetworkPrefabPatch2 { private static readonly string MOD_GUID = "dp991.ShipTeleportKey"; [HarmonyPostfix] [HarmonyPatch("SetSingleton")] private static void RegisterPrefab() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(MOD_GUID + " Prefab"); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D); Object.DontDestroyOnLoad((Object)(object)val); NetworkObject obj = val.AddComponent(); typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(obj, GetHash(MOD_GUID)); NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val); static uint GetHash(string value) { return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0; } } } }