using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AdvancedFreeCam.Config; using AdvancedFreeCam.Core; using AdvancedFreeCam.Ghost; using AdvancedFreeCam.Network; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Kai")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d30f35163e6d79db7219adc71d8de9a9f1edad94")] [assembly: AssemblyProduct("AdvancedFreeCam")] [assembly: AssemblyTitle("AdvancedFreeCam")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 AdvancedFreeCam { [BepInPlugin("Kai.AdvancedFreeCam", "AdvancedFreeCam", "2.2.0")] public class AdvancedFreeCam : BaseUnityPlugin { private FreeCamManager? _freeCamManager; private FreeCamGhostManager? _ghostManager; private bool _handshakeApplied; private bool _voiceNetworkRegistered; private bool _ghostNetworkRegistered; private ConfigEntry? _allowHostAliveFreeCam; private ConfigEntry? _allowClientAliveFreeCam; private ConfigEntry? _allowClientDeadFreeCam; private ConfigEntry? _allowHostForceDisable; private ConfigEntry? _allowFreeCamVoice; private ConfigEntry? _allowClientFreeCamVoice; private ConfigEntry? _ghostVisibleToAlivePlayers; private ConfigEntry? _ghostVisibleToSpectators; private ConfigEntry? _ghostVisibleToFreeCamPlayers; internal static AdvancedFreeCam Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal bool HasAuthoritativeRoomConfig { get; private set; } private void Awake() { Instance = this; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; BindConfig(); ApplyHostConfigToRuntime(); _freeCamManager = new FreeCamManager(); _ghostManager = new FreeCamGhostManager(); Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_0019: 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) //IL_0020: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } private void Update() { TryRegisterGhostNetwork(); TryApplyHandshake(); SyncRoomConfig(); _freeCamManager?.Tick(Time.deltaTime); _ghostManager?.Tick(); } private void LateUpdate() { FreeCamPhotoMode.LateTick(); } private void BindConfig() { BindHostConfig(); BindControlsConfig(); BindClientConfig(); } private void BindHostConfig() { _allowHostAliveFreeCam = ((BaseUnityPlugin)this).Config.Bind("Host", "AllowHostAliveFreeCam", true, "Allow the host to enable FreeCam while alive."); _allowClientAliveFreeCam = ((BaseUnityPlugin)this).Config.Bind("Host", "AllowClientAliveFreeCam", false, "Allow clients to enable FreeCam while alive."); _allowClientDeadFreeCam = ((BaseUnityPlugin)this).Config.Bind("Host", "AllowClientDeadFreeCam", true, "Allow clients to enable FreeCam while dead / spectating."); _ghostVisibleToAlivePlayers = ((BaseUnityPlugin)this).Config.Bind("Host", "GhostVisibleToAlivePlayers", false, "Show FreeCam ghost to alive players."); _ghostVisibleToSpectators = ((BaseUnityPlugin)this).Config.Bind("Host", "GhostVisibleToSpectators", true, "Show FreeCam ghost to spectators / dead players."); _ghostVisibleToFreeCamPlayers = ((BaseUnityPlugin)this).Config.Bind("Host", "GhostVisibleToFreeCamPlayers", true, "Show FreeCam ghost to other FreeCam players."); } private void BindControlsConfig() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown FreeCamLocalSettings.ToggleFreeCamKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "ToggleFreeCamKey", (KeyCode)289, "Toggle FreeCam on / off."); FreeCamLocalSettings.TogglePhotoModeKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "TogglePhotoModeKey", (KeyCode)122, "Toggle PhotoMode while FreeCam is active."); FreeCamLocalSettings.FreeCamLookSensitivity = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamLookSensitivity", 1.5f, new ConfigDescription("Mouse look sensitivity while using FreeCam.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); FreeCamLocalSettings.FreeCamMaxMouseDelta = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamMaxMouseDelta", 8f, new ConfigDescription("Maximum mouse input delta per frame while using FreeCam. Lower values reduce sudden camera swings.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 12f), Array.Empty())); FreeCamLocalSettings.FastMoveKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "FastMoveKey", (KeyCode)304, "Hold to move faster while using FreeCam."); FreeCamLocalSettings.MoveUpKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "MoveUpKey", (KeyCode)32, "Move FreeCam upward."); FreeCamLocalSettings.MoveDownKey = ((BaseUnityPlugin)this).Config.Bind("Controls", "MoveDownKey", (KeyCode)306, "Move FreeCam downward."); FreeCamLocalSettings.FreeCamBaseMoveSpeed = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamBaseMoveSpeed", 8f, new ConfigDescription("Default FreeCam movement speed.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 200f), Array.Empty())); FreeCamLocalSettings.FreeCamFastMoveMultiplier = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamFastMoveMultiplier", 3f, new ConfigDescription("Movement speed multiplier while holding FastMoveKey.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f), Array.Empty())); FreeCamLocalSettings.FreeCamMinMoveSpeed = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamMinMoveSpeed", 1f, new ConfigDescription("Minimum FreeCam movement speed when adjusted by mouse wheel.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 200f), Array.Empty())); FreeCamLocalSettings.FreeCamMaxMoveSpeed = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamMaxMoveSpeed", 50f, new ConfigDescription("Maximum FreeCam movement speed when adjusted by mouse wheel.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 200f), Array.Empty())); FreeCamLocalSettings.FreeCamMouseWheelSpeedStep = ((BaseUnityPlugin)this).Config.Bind("Controls", "FreeCamMouseWheelSpeedStep", 1f, new ConfigDescription("FreeCam speed change amount per mouse wheel step.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 50f), Array.Empty())); } private void BindClientConfig() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown FreeCamLocalSettings.PhotoModeNightVision = ((BaseUnityPlugin)this).Config.Bind("Client", "PhotoModeNightVision", 25f, new ConfigDescription("Ambient-light based night vision strength while PhotoMode is enabled. 0 = off, 100 = max.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); } private void ApplyHostConfigToRuntime() { FreeCamConfig instance = FreeCamConfig.Instance; instance.AllowHostAliveFreeCam = _allowHostAliveFreeCam?.Value ?? true; instance.AllowClientAliveFreeCam = _allowClientAliveFreeCam?.Value ?? false; instance.AllowClientDeadFreeCam = _allowClientDeadFreeCam?.Value ?? true; instance.AllowHostForceDisable = _allowHostForceDisable?.Value ?? true; instance.GhostVisibleToAlivePlayers = _ghostVisibleToAlivePlayers?.Value ?? false; instance.GhostVisibleToSpectators = _ghostVisibleToSpectators?.Value ?? true; instance.GhostVisibleToFreeCamPlayers = _ghostVisibleToFreeCamPlayers?.Value ?? true; } private void SyncRoomConfig() { if (!SemiFunc.IsMultiplayer()) { HasAuthoritativeRoomConfig = true; ApplyHostConfigToRuntime(); } else if (!PhotonNetwork.InRoom) { HasAuthoritativeRoomConfig = false; } else if (PhotonNetwork.IsMasterClient) { ApplyHostConfigToRuntime(); FreeCamRoomConfigSync.PushHostConfigToRoom(); HasAuthoritativeRoomConfig = true; } else { HasAuthoritativeRoomConfig = FreeCamRoomConfigSync.TryApplyRoomConfigToRuntime(); } } private void TryRegisterGhostNetwork() { bool flag = SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom && PhotonNetwork.NetworkingClient != null; if (flag != _ghostNetworkRegistered) { if (flag) { FreeCamGhostNetwork.Register(); _ghostNetworkRegistered = true; } else { FreeCamGhostNetwork.Unregister(); _ghostNetworkRegistered = false; } } } private void TryApplyHandshake() { if (!SemiFunc.IsMultiplayer()) { _handshakeApplied = false; } else if (!PhotonNetwork.InRoom) { _handshakeApplied = false; } else if (PhotonNetwork.LocalPlayer != null && !_handshakeApplied) { FreeCamPlayerHandshake.ApplyLocalProperties(); _handshakeApplied = true; } } internal void SetPhotoModeNightVision(float value) { float value2 = Mathf.Clamp(value, 0f, 100f); if (FreeCamLocalSettings.PhotoModeNightVision != null) { FreeCamLocalSettings.PhotoModeNightVision.Value = value2; } } } } namespace AdvancedFreeCam.Patchs { [HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")] internal static class Patch_PlayerAvatar_Revive_GhostReset { internal static void Prefix(PlayerAvatar __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.isLocal) { FreeCamManager.Instance?.DisableFreeCam(); } } } [HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")] internal static class Patch_PlayerAvatar_Death_GhostReset { internal static void Prefix(PlayerAvatar __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.isLocal) { FreeCamManager.Instance?.DisableFreeCam(); } } } [HarmonyPatch(typeof(SemiFunc), "OnLevelGenDone")] internal static class Patch_SemiFunc_OnLevelGenDone_GhostReset { private static void Prefix() { FreeCamGhostManager.Instance?.ClearAll(); FreeCamGhostManager.Instance?.PrewarmFromPlayerList(); } } internal static class Patch_SpectateCameraDeathEffects_FreeCam { [HarmonyPatch(typeof(SpectateCamera), "StateDeath")] private static class SpectateCamera_StateDeath_Patch { private static void Prefix() { //IL_0045: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) _suppressingSpectateDeathEffects = false; _hasSnapshot = false; _hasTopCamera = false; if (!ShouldSuppress()) { return; } Camera val = (((Object)(object)GameDirector.instance != (Object)null) ? GameDirector.instance.MainCamera : null); if ((Object)(object)val == (Object)null) { return; } _mainCameraLocalPosition = ((Component)val).transform.localPosition; _mainCameraLocalRotation = ((Component)val).transform.localRotation; _mainCameraFieldOfView = val.fieldOfView; _mainCameraNearClip = val.nearClipPlane; _mainCameraFarClip = val.farClipPlane; _fog = RenderSettings.fog; Camera[] componentsInChildren = ((Component)val).GetComponentsInChildren(); foreach (Camera val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)val)) { _topCameraFieldOfView = val2.fieldOfView; _hasTopCamera = true; break; } } _hasSnapshot = true; _suppressingSpectateDeathEffects = true; } private static void Postfix() { //IL_0041: 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) if (!_suppressingSpectateDeathEffects || !_hasSnapshot) { ResetFlags(); return; } Camera val = (((Object)(object)GameDirector.instance != (Object)null) ? GameDirector.instance.MainCamera : null); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localPosition = _mainCameraLocalPosition; ((Component)val).transform.localRotation = _mainCameraLocalRotation; val.fieldOfView = _mainCameraFieldOfView; val.nearClipPlane = _mainCameraNearClip; val.farClipPlane = _mainCameraFarClip; if (_hasTopCamera) { Camera[] componentsInChildren = ((Component)val).GetComponentsInChildren(); foreach (Camera val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)val)) { val2.fieldOfView = _topCameraFieldOfView; break; } } } } RenderSettings.fog = _fog; ResetFlags(); } private static void ResetFlags() { _suppressingSpectateDeathEffects = false; _hasSnapshot = false; _hasTopCamera = false; } } [HarmonyPatch(typeof(CameraGlitch), "PlayShort")] private static class CameraGlitch_PlayShort_Patch { private static bool Prefix() { return !_suppressingSpectateDeathEffects; } } [HarmonyPatch(typeof(CameraShake), "Shake")] private static class CameraShake_Shake_Patch { private static bool Prefix(CameraShake __instance) { if (!_suppressingSpectateDeathEffects) { return true; } if ((Object)(object)GameDirector.instance == (Object)null) { return true; } if ((Object)(object)__instance == (Object)(object)GameDirector.instance.CameraShake) { return false; } if ((Object)(object)__instance == (Object)(object)GameDirector.instance.CameraImpact) { return false; } return true; } } [HarmonyPatch(typeof(CameraNoise), "Override")] private static class CameraNoise_Override_Patch { private static bool Prefix() { return !_suppressingSpectateDeathEffects; } } private static bool _suppressingSpectateDeathEffects; private static bool _hasSnapshot; private static bool _hasTopCamera; private static Vector3 _mainCameraLocalPosition; private static Quaternion _mainCameraLocalRotation; private static float _mainCameraFieldOfView; private static float _topCameraFieldOfView; private static float _mainCameraNearClip; private static float _mainCameraFarClip; private static bool _fog; private static bool IsFreeCamActive() { if (FreeCamManager.Instance != null) { return FreeCamManager.Instance.IsActive; } return false; } private static bool AllPlayersDead() { if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null) { return false; } if (GameDirector.instance.PlayerList.Count == 0) { return false; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if ((Object)(object)player != (Object)null && !player.isDisabled) { return false; } } return true; } private static bool ShouldSuppress() { if (!IsFreeCamActive()) { return false; } if ((Object)(object)SpectateCamera.instance == (Object)null) { return false; } if (!SpectateCamera.instance.CheckState((State)0)) { return false; } if (AllPlayersDead()) { return false; } return true; } } [HarmonyPatch(typeof(SpectateCamera), "Awake")] internal static class Patch_SpectateCamera_Awake_FreeCamCleanup { private static void Prefix() { FreeCamManager.Instance?.ForceCleanup("SpectateCamera.Awake"); } } [HarmonyPatch(typeof(SpectateCamera), "PlayerSwitch")] internal static class Patch_SpectateCamera_PlayerSwitch_FreeCamInputBlock { private static bool Prefix() { if (FreeCamManager.Instance == null || !FreeCamManager.Instance.IsActive) { return true; } if (Input.GetKeyDown((KeyCode)32) || Input.GetKeyDown((KeyCode)323) || Input.GetKeyDown((KeyCode)324)) { return false; } return true; } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class Patch_RunManager_ChangeLevel { private static void Prefix() { FreeCamManager.Instance?.PrepareForLevelTransition("RunManager.ChangeLevel"); } } [HarmonyPatch(typeof(RunManager), "RestartScene")] internal static class Patch_RunManager_RestartScene { private static void Prefix() { FreeCamManager.Instance?.PrepareForLevelTransition("RunManager.RestartScene"); } } } namespace AdvancedFreeCam.Network { internal static class FreeCamEventCodes { internal const byte VoiceState = 71; internal const byte GhostState = 72; } internal static class FreeCamGhostNetwork { private const string PayloadTag = "Kai.AdvancedFreeCam:GhostState"; private const int PayloadVersion = 1; private static readonly SendOptions UnreliableSendOptions; internal static void Register() { PhotonNetwork.NetworkingClient.EventReceived += OnEventReceived; } internal static void Unregister() { PhotonNetwork.NetworkingClient.EventReceived -= OnEventReceived; } internal static void SendState(bool active, Vector3 position, Quaternion rotation) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom) { int[] targetActorsWithAdvancedFreeCam = FreeCamPlayerHandshake.GetTargetActorsWithAdvancedFreeCam(); if (targetActorsWithAdvancedFreeCam.Length != 0) { int actorNumber = PhotonNetwork.LocalPlayer.ActorNumber; object[] array = new object[11] { "Kai.AdvancedFreeCam:GhostState", 1, actorNumber, active, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, rotation.w }; RaiseEventOptions val = new RaiseEventOptions { TargetActors = targetActorsWithAdvancedFreeCam }; PhotonNetwork.RaiseEvent((byte)72, (object)array, val, UnreliableSendOptions); } } } private static void OnEventReceived(EventData photonEvent) { //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code != 72 || !(photonEvent.CustomData is object[] array) || array.Length < 11 || !(array[0] is string text) || text != "Kai.AdvancedFreeCam:GhostState") { return; } object obj = array[1]; if (!(obj is int)) { return; } int num = (int)obj; if (num != 1) { return; } obj = array[2]; if (!(obj is int)) { return; } int actorNumber = (int)obj; obj = array[3]; if (!(obj is bool)) { return; } bool active = (bool)obj; obj = array[4]; if (!(obj is float)) { return; } float num2 = (float)obj; obj = array[5]; if (!(obj is float)) { return; } float num3 = (float)obj; obj = array[6]; if (!(obj is float)) { return; } float num4 = (float)obj; obj = array[7]; if (!(obj is float)) { return; } float num5 = (float)obj; obj = array[8]; if (!(obj is float)) { return; } float num6 = (float)obj; obj = array[9]; if (obj is float) { float num7 = (float)obj; obj = array[10]; if (obj is float) { float num8 = (float)obj; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(num2, num3, num4); Quaternion rotation = default(Quaternion); ((Quaternion)(ref rotation))..ctor(num5, num6, num7, num8); FreeCamGhostRegistry.Set(actorNumber, active, position, rotation); } } } static FreeCamGhostNetwork() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) SendOptions unreliableSendOptions = default(SendOptions); ((SendOptions)(ref unreliableSendOptions)).Reliability = false; UnreliableSendOptions = unreliableSendOptions; } } internal static class FreeCamNetworkKeys { internal const string HasMod = "afc_mod"; internal const string ModVersion = "afc_ver"; internal const string RoomConfigVersion = "afc_cfg_ver"; internal const string AllowHostAliveFreeCam = "afc_h_alive"; internal const string AllowClientAliveFreeCam = "afc_c_alive"; internal const string AllowClientDeadFreeCam = "afc_c_dead"; internal const string AllowHostForceDisable = "afc_force"; internal const string AllowFreeCamVoice = "afc_voice"; internal const string AllowClientFreeCamVoice = "afc_c_voice"; internal const string GhostVisibleToAlivePlayers = "afc_g_alive"; internal const string GhostVisibleToSpectators = "afc_g_spec"; internal const string GhostVisibleToFreeCamPlayers = "afc_g_fc"; } internal static class FreeCamPlayerHandshake { internal const int CurrentProtocolVersion = 101; internal static void ApplyLocalProperties() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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 if (PhotonNetwork.LocalPlayer != null) { Hashtable val = new Hashtable { [(object)"afc_mod"] = true, [(object)"afc_ver"] = 101 }; PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } internal static bool HasAdvancedFreeCam(Player? player) { if (player == null) { return false; } if (!((Dictionary)(object)player.CustomProperties).TryGetValue((object)"afc_mod", out object value)) { return false; } if (!(value is bool) || !(bool)value) { return false; } return true; } internal static bool TryGetProtocolVersion(Player? player, out int version) { version = 0; if (player == null) { return false; } if (!((Dictionary)(object)player.CustomProperties).TryGetValue((object)"afc_ver", out object value)) { return false; } if (!(value is int num)) { return false; } version = num; return true; } internal static int[] GetTargetActorsWithAdvancedFreeCam(bool includeSelf = false) { if (!PhotonNetwork.InRoom) { return Array.Empty(); } List list = new List(); Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if ((includeSelf || !val.IsLocal) && HasAdvancedFreeCam(val)) { list.Add(val.ActorNumber); } } return list.ToArray(); } } internal static class FreeCamRoomConfigSync { private const int CurrentRoomConfigVersion = 1; internal static void PushHostConfigToRoom() { //IL_0016: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { FreeCamConfig instance = FreeCamConfig.Instance; Hashtable val = new Hashtable { [(object)"afc_cfg_ver"] = 1, [(object)"afc_h_alive"] = instance.AllowHostAliveFreeCam, [(object)"afc_c_alive"] = instance.AllowClientAliveFreeCam, [(object)"afc_c_dead"] = instance.AllowClientDeadFreeCam, [(object)"afc_force"] = instance.AllowHostForceDisable, [(object)"afc_g_alive"] = instance.GhostVisibleToAlivePlayers, [(object)"afc_g_spec"] = instance.GhostVisibleToSpectators, [(object)"afc_g_fc"] = instance.GhostVisibleToFreeCamPlayers }; PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } internal static bool TryApplyRoomConfigToRuntime() { if (!PhotonNetwork.InRoom) { return false; } Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom == null) { return false; } Hashtable customProperties = ((RoomInfo)currentRoom).CustomProperties; if (customProperties == null || ((Dictionary)(object)customProperties).Count == 0) { return false; } if (!((Dictionary)(object)customProperties).TryGetValue((object)"afc_cfg_ver", out object value)) { return false; } if (!(value is int num) || num != 1) { return false; } FreeCamConfigSnapshot freeCamConfigSnapshot = new FreeCamConfigSnapshot { AllowHostAliveFreeCam = ReadBool(customProperties, "afc_h_alive", fallback: true), AllowClientAliveFreeCam = ReadBool(customProperties, "afc_c_alive", fallback: false), AllowClientDeadFreeCam = ReadBool(customProperties, "afc_c_dead", fallback: true), AllowHostForceDisable = ReadBool(customProperties, "afc_force", fallback: true), AllowFreeCamVoice = ReadBool(customProperties, "afc_voice", fallback: true), AllowClientFreeCamVoice = ReadBool(customProperties, "afc_c_voice", fallback: false), GhostVisibleToAlivePlayers = ReadBool(customProperties, "afc_g_alive", fallback: false), GhostVisibleToSpectators = ReadBool(customProperties, "afc_g_spec", fallback: true), GhostVisibleToFreeCamPlayers = ReadBool(customProperties, "afc_g_fc", fallback: true) }; freeCamConfigSnapshot.ApplyToRuntime(FreeCamConfig.Instance); return true; } private static bool ReadBool(Hashtable props, string key, bool fallback) { if (!((Dictionary)(object)props).TryGetValue((object)key, out object value)) { return fallback; } if (value is bool) { return (bool)value; } return fallback; } } } namespace AdvancedFreeCam.Ghost { internal sealed class FreeCamGhost { private readonly int _actorNumber; private readonly GameObject _root; private readonly Transform _transform; private GameObject _visualRoot; private bool _usingFallback; internal int ActorNumber => _actorNumber; internal Transform Transform => _transform; internal GameObject Root => _root; internal bool UsingFallback => _usingFallback; internal FreeCamGhost(int actorNumber, Vector3 position, Quaternion rotation) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) _actorNumber = actorNumber; _root = new GameObject($"AdvancedFreeCam_Ghost_{actorNumber}"); _transform = _root.transform; _transform.position = position; _transform.rotation = rotation; _visualRoot = FreeCamGhostVisualFactory.CreateDefault(_root.transform, _actorNumber, out _usingFallback); ApplyVisualOffset(); } private void ApplyVisualOffset() { //IL_001b: 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) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_visualRoot == (Object)null)) { Transform transform = _visualRoot.transform; transform.localPosition += new Vector3(0f, -0.25f, 0f); } } internal void SetTransform(Vector3 position, Quaternion rotation) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) _transform.position = position; _transform.rotation = rotation; } internal void SetVisible(bool visible) { if ((Object)(object)_visualRoot != (Object)null) { _visualRoot.SetActive(visible); } } internal void TryRefreshVisual() { if (_usingFallback && !((Object)(object)FreeCamGhostVisualFactory.FindPlayerAvatarByActorNumber(_actorNumber) == (Object)null)) { if ((Object)(object)_visualRoot != (Object)null) { Object.Destroy((Object)(object)_visualRoot); } _visualRoot = FreeCamGhostVisualFactory.CreateDefault(_root.transform, _actorNumber, out _usingFallback); ApplyVisualOffset(); } } internal void Destroy() { Object.Destroy((Object)(object)_root); } } internal sealed class FreeCamGhostManager { private readonly Dictionary _ghosts = new Dictionary(); private const float RemoteStateTimeout = 0.5f; internal static FreeCamGhostManager? Instance { get; private set; } internal FreeCamGhostManager() { Instance = this; } internal void Tick() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)); HashSet hashSet = new HashSet(); foreach (KeyValuePair item in FreeCamGhostRegistry.GetAll()) { int key = item.Key; FreeCamGhostState value = item.Value; if (key == num) { RemoveGhost(key); FreeCamGhostRegistry.Remove(key); continue; } hashSet.Add(key); bool flag = Time.time - value.LastUpdatedTime > 0.5f; if (!value.IsActive || flag) { if (_ghosts.TryGetValue(key, out FreeCamGhost value2)) { value2.SetVisible(visible: false); } } else { FreeCamGhost orCreateGhost = GetOrCreateGhost(key, value.Position, value.Rotation); orCreateGhost.SetTransform(value.Position, value.Rotation); orCreateGhost.TryRefreshVisual(); orCreateGhost.SetVisible(ShouldGhostBeVisible()); } } foreach (KeyValuePair ghost in _ghosts) { if (!hashSet.Contains(ghost.Key)) { ghost.Value.SetVisible(visible: false); } } } internal void ClearAll() { foreach (FreeCamGhost value in _ghosts.Values) { value.Destroy(); } _ghosts.Clear(); FreeCamGhostRegistry.ClearAll(); } internal void RemoveGhost(int actorNumber) { if (_ghosts.TryGetValue(actorNumber, out FreeCamGhost value)) { value.Destroy(); _ghosts.Remove(actorNumber); } } private FreeCamGhost GetOrCreateGhost(int actorNumber, Vector3 position, Quaternion rotation) { //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) if (_ghosts.TryGetValue(actorNumber, out FreeCamGhost value)) { return value; } value = new FreeCamGhost(actorNumber, position, rotation); _ghosts[actorNumber] = value; return value; } internal void PrewarmFromPlayerList() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GameDirector.instance == (Object)null) { return; } int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : (-1)); foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if ((Object)(object)player == (Object)null) { continue; } PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Owner != null) { int actorNumber = component.Owner.ActorNumber; if (actorNumber != num && !_ghosts.ContainsKey(actorNumber)) { Transform transform = ((Component)player).transform; FreeCamGhost orCreateGhost = GetOrCreateGhost(actorNumber, transform.position, transform.rotation); orCreateGhost.SetVisible(visible: false); } } } } private bool ShouldGhostBeVisible() { if (FreeCamManager.Instance != null && FreeCamManager.Instance.IsActive) { return FreeCamPolicy.ShouldGhostBeVisibleToFreeCamViewer(); } if ((Object)(object)PlayerAvatar.instance != (Object)null && PlayerAvatar.instance.isDisabled) { return FreeCamPolicy.ShouldGhostBeVisibleToSpectatorViewer(); } return FreeCamPolicy.ShouldGhostBeVisibleToAliveViewer(); } } internal static class FreeCamGhostMaterialTuner { private static readonly Color BaseTint = new Color(0.78f, 0.9f, 1f, 0.72f); private static readonly Color EmissionTint = new Color(0.25f, 0.55f, 0.9f, 1f); private const float EmissionIntensity = 1.8f; internal static void ApplyGhostLook(Renderer renderer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if ((Object)(object)renderer == (Object)null) { return; } Material[] materials = renderer.materials; Material[] array = (Material[])(object)new Material[materials.Length]; for (int i = 0; i < materials.Length; i++) { Material val = materials[i]; if (!((Object)(object)val == (Object)null)) { Material val2 = new Material(val); ApplyBaseColor(val2); ApplyEmission(val2); ApplyTransparency(val2); array[i] = val2; } } renderer.materials = array; } private static void ApplyBaseColor(Material mat) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty("_Color")) { Color color = mat.GetColor("_Color"); Color val = Color.Lerp(color, BaseTint, 0.45f); val.a = BaseTint.a; mat.SetColor("_Color", val); } if (mat.HasProperty("_BaseColor")) { Color color2 = mat.GetColor("_BaseColor"); Color val2 = Color.Lerp(color2, BaseTint, 0.45f); val2.a = BaseTint.a; mat.SetColor("_EmissionColor", EmissionTint * 1.8f); } } private static void ApplyEmission(Material mat) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty("_EmissionColor")) { mat.EnableKeyword("_EMISSION"); mat.SetColor("_EmissionColor", EmissionTint); DynamicGI.SetEmissive((Renderer)null, EmissionTint); } } private static void ApplyTransparency(Material mat) { if (mat.HasProperty("_Surface")) { try { mat.SetFloat("_Surface", 1f); } catch { } } } } internal sealed class FreeCamGhostNameTag : MonoBehaviour { private Camera _targetCamera; private Transform _followTarget; private Vector3 _offset; internal void Initialize(Transform followTarget, Vector3 offset) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) _followTarget = followTarget; _offset = offset; } private void LateUpdate() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_followTarget != (Object)null) { ((Component)this).transform.position = _followTarget.position + _offset; } if ((Object)(object)_targetCamera == (Object)null) { _targetCamera = Camera.main; } if (!((Object)(object)_targetCamera == (Object)null)) { Vector3 val = ((Component)this).transform.position - ((Component)_targetCamera).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Component)this).transform.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } } } } internal static class FreeCamGhostPoseApplier { internal static void Apply(GameObject root, FreeCamGhostPoseData pose) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) int num = 0; int num2 = 0; foreach (FreeCamGhostPoseNode node in pose.Nodes) { Transform val = FindDeepChild(root.transform, node.Name); if ((Object)(object)val == (Object)null) { num2++; AdvancedFreeCam.Logger.LogWarning((object)("[GhostPose] Missing node: " + node.Name)); continue; } val.localPosition = node.LocalPosition; val.localRotation = node.LocalRotation; val.localScale = node.LocalScale; num++; } AdvancedFreeCam.Logger.LogInfo((object)$"[GhostPose] Applied={num}, Missed={num2}"); } private static Transform? FindDeepChild(Transform parent, string targetName) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (((Object)parent).name == targetName) { return parent; } foreach (Transform item in parent) { Transform parent2 = item; Transform val = FindDeepChild(parent2, targetName); if ((Object)(object)val != (Object)null) { return val; } } return null; } } internal sealed class FreeCamGhostPoseNode { public string Name = ""; public Vector3 LocalPosition; public Quaternion LocalRotation; public Vector3 LocalScale; } internal sealed class FreeCamGhostPoseData { public readonly List Nodes = new List(); } internal static class FreeCamGhostPoseLibrary { private static FreeCamGhostPoseData? _crawl; internal static FreeCamGhostPoseData Crawl => _crawl ?? (_crawl = BuildCrawl()); private static FreeCamGhostPoseData BuildCrawl() { //IL_001b: 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) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) FreeCamGhostPoseData freeCamGhostPoseData = new FreeCamGhostPoseData(); Add(freeCamGhostPoseData, "ANIM BOT", new Vector3(0f, 0f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(0.9f, 0.9f, 0.9f)); Add(freeCamGhostPoseData, "ANIM BODY BOT", new Vector3(0f, -0.507f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); Add(freeCamGhostPoseData, "ANIM BODY TOP", new Vector3(0f, -0.289f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); Add(freeCamGhostPoseData, "ANIM HEAD BOT", new Vector3(0f, -0.358802f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); Add(freeCamGhostPoseData, "ANIM HEAD TOP", new Vector3(0f, 0f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); Add(freeCamGhostPoseData, "ANIM EYE LEFT", new Vector3(0f, 0f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); Add(freeCamGhostPoseData, "ANIM EYE RIGHT", new Vector3(0f, 0f, 0f), new Quaternion(0f, 0f, 0f, 1f), new Vector3(1f, 1f, 1f)); return freeCamGhostPoseData; } private static void Add(FreeCamGhostPoseData pose, string name, Vector3 localPosition, Quaternion localRotation, Vector3 localScale) { //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_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) //IL_0021: 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) pose.Nodes.Add(new FreeCamGhostPoseNode { Name = name, LocalPosition = localPosition, LocalRotation = localRotation, LocalScale = localScale }); } } internal sealed class FreeCamGhostState { public bool IsActive; public Vector3 Position; public Quaternion Rotation = Quaternion.identity; public float LastUpdatedTime; public void Set(bool active, Vector3 position, Quaternion rotation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) IsActive = active; Position = position; Rotation = rotation; LastUpdatedTime = Time.time; } } internal static class FreeCamGhostRegistry { private static readonly Dictionary States = new Dictionary(); internal static void Set(int actorNumber, bool active, Vector3 position, Quaternion rotation) { //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) if (!States.TryGetValue(actorNumber, out FreeCamGhostState value)) { value = new FreeCamGhostState(); States[actorNumber] = value; } value.Set(active, position, rotation); } internal static bool TryGet(int actorNumber, out FreeCamGhostState state) { return States.TryGetValue(actorNumber, out state); } internal static IReadOnlyDictionary GetAll() { return States; } internal static void Remove(int actorNumber) { States.Remove(actorNumber); } internal static void ClearAll() { States.Clear(); } } internal sealed class FreeCamGhostTalkAnimation : MonoBehaviour { private PlayerAvatar _avatar; private Transform _target; private Quaternion _baseLocalRotation; private float _rotationMaxAngle = 45f; private float _smooth = 100f; internal void Initialize(PlayerAvatar avatar, Transform target, float rotationMaxAngle = 45f) { //IL_002a: 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) _avatar = avatar; _target = target; _rotationMaxAngle = rotationMaxAngle; if ((Object)(object)_target != (Object)null) { _baseLocalRotation = _target.localRotation; } } private void Update() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_avatar == (Object)null) && !((Object)(object)_target == (Object)null) && GameManager.Multiplayer() && _avatar.voiceChatFetched && !((Object)(object)_avatar.voiceChat == (Object)null)) { float num = 0f; if (_avatar.voiceChat.clipLoudness > 0.005f && _avatar.voiceChat.overrideNoTalkAnimationTimer <= 0f) { num = Mathf.Lerp(0f, 0f - _rotationMaxAngle, _avatar.voiceChat.clipLoudness * 4f); } Quaternion val = _baseLocalRotation * Quaternion.Euler(num, 0f, 0f); _target.localRotation = Quaternion.Slerp(_target.localRotation, val, _smooth * Time.deltaTime); } } } internal static class FreeCamGhostVisualBuilder { private const string CrawlStateName = "Crawl"; private const float CrawlNormalizedTime = 1f; internal static void PrepareCloneAsGhost(GameObject root) { EnsureVisualRootVisible(root); ApplyAnimatorPose(root); DisableCloneBehaviours(root); ConfigureLights(root); ConfigureRenderers(root); } private static void EnsureVisualRootVisible(GameObject root) { PlayerAvatarVisuals component = root.GetComponent(); if (!((Object)(object)component == (Object)null) && (Object)(object)component.meshParent != (Object)null) { component.meshParent.SetActive(true); } } private static void ApplyAnimatorPose(GameObject root) { Animator component = root.GetComponent(); if ((Object)(object)component == (Object)null) { AdvancedFreeCam.Logger.LogWarning((object)"[Ghost] Animator が見つかりません。"); return; } int num = Animator.StringToHash("Crawl"); if (!component.HasState(0, num)) { AdvancedFreeCam.Logger.LogWarning((object)"[Ghost] Animator State が見つかりません: Crawl"); return; } ((Behaviour)component).enabled = true; component.speed = 1f; component.Play(num, 0, 1f); component.Update(0f); component.Update(0.01f); component.speed = 0f; } private static void DisableCloneBehaviours(GameObject root) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren(true); MonoBehaviour[] array = componentsInChildren; foreach (MonoBehaviour val in array) { ((Behaviour)val).enabled = false; } ParticleSystem[] componentsInChildren2 = root.GetComponentsInChildren(true); ParticleSystem[] array2 = componentsInChildren2; foreach (ParticleSystem val2 in array2) { EmissionModule emission = val2.emission; ((EmissionModule)(ref emission)).enabled = false; val2.Stop(true, (ParticleSystemStopBehavior)0); ((Component)val2).gameObject.SetActive(false); } } private static void ConfigureLights(GameObject root) { Light[] componentsInChildren = root.GetComponentsInChildren(true); Light[] array = componentsInChildren; foreach (Light val in array) { string text = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); if (text == "eye light") { ((Behaviour)val).enabled = true; } else { ((Behaviour)val).enabled = false; } } } private static void ConfigureRenderers(GameObject root) { Renderer[] componentsInChildren = root.GetComponentsInChildren(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { string objectName = ((Object)((Component)val).gameObject).name.ToLowerInvariant(); if (val.enabled = ShouldShowRenderer(objectName)) { val.shadowCastingMode = (ShadowCastingMode)0; val.receiveShadows = false; FreeCamGhostMaterialTuner.ApplyGhostLook(val); } } } private static bool ShouldShowRenderer(string objectName) { switch (objectName) { case "mesh_body_bot": return true; case "mesh_body_top_sphere": return true; case "mesh_body_top_flat": return true; case "mesh_head_bot_sphere": return true; case "mesh_head_bot_flat": return true; case "mesh_head_top": return true; case "mesh_eye_l": return true; case "mesh_eye_r": return true; case "mesh_pupil_l": return true; case "mesh_pupil_r": return true; case "eyelid_upper": return true; case "eyelid_lower": return true; case "mesh_arm_l": return false; case "mesh_arm_r": return false; case "mesh_leg_l": return false; case "mesh_leg_r": return false; default: if (objectName.Contains("mesh_health")) { return false; } if (objectName == "wing mesh") { return false; } if (objectName == "arenacrown") { return false; } if (objectName.Contains("mesh_grabber")) { return false; } objectName.Contains("orb sphere"); return false; } } } internal static class FreeCamGhostVisualCache { private static GameObject? _localCachedVisual; private static bool _rebuildRequested; private static int _waitFrames; internal static bool HasLocalCache => (Object)(object)_localCachedVisual != (Object)null; internal static void RequestRebuild(int waitFrames = 10) { _rebuildRequested = true; _waitFrames = waitFrames; } internal static void Tick() { if (_rebuildRequested && CanBuildNow()) { if (_waitFrames > 0) { _waitFrames--; return; } RebuildLocalCache(); _rebuildRequested = false; } } internal static void RebuildLocalCache() { if (!((Object)(object)PlayerAvatar.instance == (Object)null) && !((Object)(object)PlayerAvatar.instance.playerAvatarVisuals == (Object)null)) { PlayerAvatar instance = PlayerAvatar.instance; GameObject gameObject = ((Component)instance.playerAvatarVisuals).gameObject; GameObject val = Object.Instantiate(gameObject); FreeCamGhostVisualBuilder.PrepareCloneAsGhost(val); _localCachedVisual = val; AdvancedFreeCam.Logger.LogInfo((object)"[GhostCache] Rebuilt local cache."); } } internal static GameObject? InstantiateLocalCache(Transform parent) { if ((Object)(object)_localCachedVisual == (Object)null) { return null; } GameObject val = Object.Instantiate(_localCachedVisual, parent); val.SetActive(true); return val; } internal static void ClearLocalCache() { if ((Object)(object)_localCachedVisual != (Object)null) { Object.Destroy((Object)(object)_localCachedVisual); _localCachedVisual = null; } } private static bool CanBuildNow() { if (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsArena() && !SemiFunc.RunIsShop() && !SemiFunc.RunIsRecording()) { return false; } if ((Object)(object)PlayerAvatar.instance == (Object)null) { return false; } if (PlayerAvatar.instance.isDisabled) { return false; } if ((Object)(object)PlayerAvatar.instance.playerAvatarVisuals == (Object)null) { return false; } return true; } } internal static class FreeCamGhostVisualFactory { internal static GameObject CreateDefault(Transform parent, int actorNumber, out bool usedFallback) { //IL_006a: 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) PlayerAvatar val = FindPlayerAvatarByActorNumber(actorNumber); if ((Object)(object)val == (Object)null || (Object)(object)val.playerAvatarVisuals == (Object)null) { usedFallback = true; return CreateFallbackVisual(parent); } GameObject gameObject = ((Component)val.playerAvatarVisuals).gameObject; GameObject val2 = Object.Instantiate(gameObject); ((Object)val2).name = $"{((Object)gameObject).name}_FreeCamGhost_{actorNumber}"; val2.transform.SetParent(parent, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; FreeCamGhostVisualBuilder.PrepareCloneAsGhost(val2); TryAttachTalkAnimation(val2, val); TryAttachNameTag(val2, val); usedFallback = false; return val2; } internal static PlayerAvatar? FindPlayerAvatarByActorNumber(int actorNumber) { if ((Object)(object)GameDirector.instance == (Object)null) { return null; } foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (!((Object)(object)player == (Object)null)) { PhotonView component = ((Component)player).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Owner != null && component.Owner.ActorNumber == actorNumber) { return player; } } } return null; } private static GameObject CreateFallbackVisual(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("GhostFallbackVisual"); val.transform.SetParent(parent, false); GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)val2).name = "Head"; val2.transform.SetParent(val.transform, false); val2.transform.localPosition = new Vector3(0f, 1.4f, 0f); val2.transform.localScale = new Vector3(0.35f, 0.35f, 0.35f); GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)1); ((Object)val3).name = "Body"; val3.transform.SetParent(val.transform, false); val3.transform.localPosition = new Vector3(0f, 0.75f, 0f); val3.transform.localScale = new Vector3(0.7f, 0.75f, 0.5f); DisableCollider(val2); DisableCollider(val3); return val; } private static void DisableCollider(GameObject obj) { Collider component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } private static void TryAttachTalkAnimation(GameObject clone, PlayerAvatar avatar) { if (!((Object)(object)clone == (Object)null) && !((Object)(object)avatar == (Object)null)) { PlayerAvatarTalkAnimation componentInChildren = clone.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { AdvancedFreeCam.Logger.LogWarning((object)"[Ghost] PlayerAvatarTalkAnimation が見つかりません。口パクを付けられません。"); return; } if ((Object)(object)componentInChildren.objectToRotate == (Object)null) { AdvancedFreeCam.Logger.LogWarning((object)"[Ghost] objectToRotate が null です。口パクを付けられません。"); return; } FreeCamGhostTalkAnimation freeCamGhostTalkAnimation = clone.AddComponent(); freeCamGhostTalkAnimation.Initialize(avatar, componentInChildren.objectToRotate.transform, componentInChildren.rotationMaxAngle); } } private static void TryAttachNameTag(GameObject clone, PlayerAvatar avatar) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)clone == (Object)null) && !((Object)(object)avatar == (Object)null)) { string text = avatar.playerName; if (string.IsNullOrWhiteSpace(text)) { text = "Unknown"; } Transform val = FindHeadAnchor(clone); if ((Object)(object)val == (Object)null) { val = clone.transform; } Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, 0.55f, 0f); GameObject val3 = new GameObject("GhostNameTag"); val3.transform.SetParent(clone.transform, false); val3.transform.position = val.position + val2; TextMeshPro val4 = val3.AddComponent(); ((TMP_Text)val4).text = text; ((TMP_Text)val4).fontSize = 1.2f; ((TMP_Text)val4).alignment = (TextAlignmentOptions)514; ((Graphic)val4).color = Color.white; ((TMP_Text)val4).outlineWidth = 0.2f; ((TMP_Text)val4).enableWordWrapping = false; ((Graphic)val4).raycastTarget = false; FreeCamGhostNameTag freeCamGhostNameTag = val3.AddComponent(); freeCamGhostNameTag.Initialize(val, val2); } } private static Transform FindHeadAnchor(GameObject clone) { Transform[] componentsInChildren = clone.GetComponentsInChildren(true); Transform[] array = componentsInChildren; foreach (Transform val in array) { string text = ((Object)val).name.ToLowerInvariant(); if (text.Contains("head") || text.Contains("helmet") || text.Contains("neck")) { return val; } } return clone.transform; } } } namespace AdvancedFreeCam.Core { internal sealed class FreeCamController { private const float DefaultLookSensitivity = 3f; private const float DefaultMoveSmooth = 8f; private const float DefaultRotateSmooth = 14f; private const float MinPitch = -89f; private const float MaxPitch = 89f; private bool _entered; private Vector3 _currentVelocity = Vector3.zero; private Vector3 _targetVelocity = Vector3.zero; private float _yaw; private float _pitch; internal float LookSensitivity { get; set; } = 3f; internal float MoveSmooth { get; set; } = 8f; internal float RotateSmooth { get; set; } = 14f; public void Enter(Vector3 startPosition, Quaternion startRotation) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0056: Unknown result type (might be due to invalid IL or missing references) Vector3 eulerAngles = ((Quaternion)(ref startRotation)).eulerAngles; _pitch = NormalizeAngle(eulerAngles.x); _yaw = NormalizeAngle(eulerAngles.y); _pitch = Mathf.Clamp(_pitch, -89f, 89f); _currentVelocity = Vector3.zero; _targetVelocity = Vector3.zero; _entered = true; } public void Exit() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) _entered = false; _currentVelocity = Vector3.zero; _targetVelocity = Vector3.zero; } public void Tick(float deltaTime, Transform rigTransform, float moveSpeed) { if (_entered && !((Object)(object)rigTransform == (Object)null)) { UpdateRotation(deltaTime, rigTransform); UpdateMovement(deltaTime, rigTransform, moveSpeed); } } private void UpdateRotation(float deltaTime, Transform rigTransform) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Vector2 val = ReadLookInput(); float freeCamLookSensitivity = FreeCamLocalConfig.GetFreeCamLookSensitivity(); _yaw += val.x * freeCamLookSensitivity; _pitch -= val.y * freeCamLookSensitivity; _pitch = Mathf.Clamp(_pitch, -89f, 89f); Quaternion val2 = Quaternion.Euler(_pitch, _yaw, 0f); rigTransform.rotation = Quaternion.Slerp(rigTransform.rotation, val2, RotateSmooth * deltaTime); } private void UpdateMovement(float deltaTime, Transform rigTransform, float moveSpeed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00b2: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ReadMoveInput(); _targetVelocity = val * moveSpeed; _currentVelocity = Vector3.Lerp(_currentVelocity, _targetVelocity, MoveSmooth * deltaTime); Quaternion val2 = Quaternion.Euler(0f, _yaw, 0f); Vector3 val3 = val2 * Vector3.forward; Vector3 val4 = val2 * Vector3.right; Vector3 val5 = val3 * _currentVelocity.z + val4 * _currentVelocity.x + Vector3.up * _currentVelocity.y; rigTransform.position += val5 * deltaTime; } private static Vector2 ReadLookInput() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")); float freeCamMaxMouseDelta = FreeCamLocalConfig.GetFreeCamMaxMouseDelta(); val.x = Mathf.Clamp(val.x, 0f - freeCamMaxMouseDelta, freeCamMaxMouseDelta); val.y = Mathf.Clamp(val.y, 0f - freeCamMaxMouseDelta, freeCamMaxMouseDelta); return val; } private static Vector3 ReadMoveInput() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; if (Input.GetKey((KeyCode)119)) { val += Vector3.forward; } if (Input.GetKey((KeyCode)115)) { val += Vector3.back; } if (Input.GetKey((KeyCode)97)) { val += Vector3.left; } if (Input.GetKey((KeyCode)100)) { val += Vector3.right; } if (Input.GetKey(FreeCamLocalConfig.GetMoveUpKey())) { val += Vector3.up; } if (Input.GetKey(FreeCamLocalConfig.GetMoveDownKey())) { val += Vector3.down; } if (((Vector3)(ref val)).sqrMagnitude > 1f) { ((Vector3)(ref val)).Normalize(); } return val; } private static float NormalizeAngle(float angle) { if (angle > 180f) { angle -= 360f; } return angle; } } internal static class FreeCamLocalBodyMeshController { private static bool _wasEnabledByFreeCam; internal static void ShowHiddenLocalMeshes() { PlayerAvatarVisuals val = PlayerAvatar.instance?.playerAvatarVisuals; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.meshParent == (Object)null) && (!val.meshParent.activeSelf || !((Object)(object)val.animator != (Object)null) || !((Behaviour)val.animator).enabled)) { val.meshParent.SetActive(true); if ((Object)(object)val.animator != (Object)null) { ((Behaviour)val.animator).enabled = true; } _wasEnabledByFreeCam = true; } } internal static void HideRestoredLocalMeshes() { if (!_wasEnabledByFreeCam) { return; } PlayerAvatarVisuals val = PlayerAvatar.instance?.playerAvatarVisuals; if ((Object)(object)val == (Object)null) { _wasEnabledByFreeCam = false; return; } if ((Object)(object)val.animator != (Object)null) { ((Behaviour)val.animator).enabled = false; } if ((Object)(object)val.meshParent != (Object)null) { val.meshParent.SetActive(false); } _wasEnabledByFreeCam = false; } } internal sealed class FreeCamManager { private readonly FreeCamController _controller = new FreeCamController(); private readonly FreeCamRig _rig = new FreeCamRig(); private FreeCamState _state; private float _currentMoveSpeed = -1f; private float _speedLogTimer; private Transform? _cameraAimTransform; private Transform? _originalParent; private Vector3 _originalLocalPosition; private Quaternion _originalLocalRotation; private bool _isPreparingLevelTransition; private string _lastCleanupLogReason; private float _lastCleanupLogTime = -999f; internal static FreeCamManager? Instance { get; private set; } public bool IsActive => _state == FreeCamState.Active; public Vector3 CurrentPosition { get { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Transform transform = _rig.Transform; if (!((Object)(object)transform != (Object)null)) { return Vector3.zero; } return transform.position; } } public Vector3 CurrentVoicePosition { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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) Transform transform = _rig.Transform; if ((Object)(object)transform != (Object)null && IsActive) { return transform.position; } Camera val = (((Object)(object)GameDirector.instance != (Object)null) ? GameDirector.instance.MainCamera : null); if ((Object)(object)val != (Object)null) { return ((Component)val).transform.position; } return Vector3.zero; } } public FreeCamManager() { Instance = this; } public void Tick(float deltaTime) { if (!ValidateGameState()) { return; } HandleInput(); if (IsActive) { TickActive(deltaTime); if (FreeCamPhotoMode.IsEnabled) { FreeCamPhotoMode.Tick(); } } } public void ToggleFreeCam() { if (IsActive) { DisableFreeCam(); } else { EnableFreeCam(); } } public void EnableFreeCam() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (IsActive) { return; } _isPreparingLevelTransition = false; if (CanUseFreeCamNow() && FreeCamPolicy.CanToggleFreeCam() && !((Object)(object)CameraAim.Instance == (Object)null)) { _cameraAimTransform = ((Component)CameraAim.Instance).transform; CacheOriginalCameraParent(); _rig.EnsureCreated(); Transform transform = _rig.Transform; if (!((Object)(object)transform == (Object)null)) { transform.position = _cameraAimTransform.position; transform.rotation = _cameraAimTransform.rotation; _cameraAimTransform.SetParent(transform, true); _controller.Enter(transform.position, transform.rotation); _state = FreeCamState.Active; FreeCamLocalBodyMeshController.ShowHiddenLocalMeshes(); AdvancedFreeCam.Logger.LogInfo((object)"FreeCam Enabled"); } } } public void DisableFreeCam() { //IL_0016: 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) if (IsActive) { FreeCamPhotoMode.Disable(); if (SemiFunc.IsMultiplayer()) { FreeCamGhostNetwork.SendState(active: false, Vector3.zero, Quaternion.identity); } CleanupInternal(resetAimDisable: true); FreeCamLocalBodyMeshController.HideRestoredLocalMeshes(); AdvancedFreeCam.Logger.LogInfo((object)"FreeCam Disabled"); } } public void ForceCleanup(string reason = "") { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) bool flag = IsActive || _rig.IsValid || (Object)(object)_cameraAimTransform != (Object)null; if (SemiFunc.IsMultiplayer() && IsActive) { FreeCamGhostNetwork.SendState(active: false, Vector3.zero, Quaternion.identity); } CleanupInternal(resetAimDisable: true); if (flag) { LogCleanupReasonOnce("FreeCam cleanup", reason); } } public void PrepareForLevelTransition(string reason = "") { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) bool flag = IsActive || _rig.IsValid || (Object)(object)_cameraAimTransform != (Object)null || FreeCamPhotoMode.IsEnabled; _isPreparingLevelTransition = true; if (SemiFunc.IsMultiplayer() && IsActive) { FreeCamGhostNetwork.SendState(active: false, Vector3.zero, Quaternion.identity); } FreeCamPhotoMode.ForceReset(isChangeLevel: true); _controller.Exit(); _state = FreeCamState.Disabled; if (flag) { LogCleanupReasonOnce("FreeCam prepare level transition", reason); } } private void LogCleanupReasonOnce(string prefix, string reason) { if (!string.IsNullOrWhiteSpace(reason) && (!(_lastCleanupLogReason == reason) || !(Time.unscaledTime - _lastCleanupLogTime < 0.5f))) { _lastCleanupLogReason = reason; _lastCleanupLogTime = Time.unscaledTime; AdvancedFreeCam.Logger.LogWarning((object)(prefix + ": " + reason)); } } private bool ValidateGameState() { if (CanUseFreeCamNow()) { if (_isPreparingLevelTransition) { _isPreparingLevelTransition = false; FinalizePreparedTransitionCleanup(); } return true; } if (_isPreparingLevelTransition) { return false; } if (IsActive || _rig.IsValid || (Object)(object)_cameraAimTransform != (Object)null) { ForceCleanup("Invalid game state"); } return false; } private void HandleSpeedWheelInput() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (IsActive && ((!Input.GetKey((KeyCode)308) && !Input.GetKey((KeyCode)307)) || !FreeCamPhotoMode.IsEnabled)) { EnsureMoveSpeedInitialized(); float y = Input.mouseScrollDelta.y; if (!(Mathf.Abs(y) <= 0.001f)) { float freeCamMouseWheelSpeedStep = FreeCamLocalConfig.GetFreeCamMouseWheelSpeedStep(); float freeCamMinMoveSpeed = FreeCamLocalConfig.GetFreeCamMinMoveSpeed(); float freeCamMaxMoveSpeed = FreeCamLocalConfig.GetFreeCamMaxMoveSpeed(); _currentMoveSpeed = Mathf.Clamp(_currentMoveSpeed + y * freeCamMouseWheelSpeedStep, freeCamMinMoveSpeed, freeCamMaxMoveSpeed); AdvancedFreeCam.Logger.LogInfo((object)$"FreeCam speed: {_currentMoveSpeed:0.0}"); } } } private void EnsureMoveSpeedInitialized() { if (!(_currentMoveSpeed > 0f)) { _currentMoveSpeed = FreeCamLocalConfig.GetFreeCamBaseMoveSpeed(); } } private void FinalizePreparedTransitionCleanup() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) _rig.Destroy(); _cameraAimTransform = null; _originalParent = null; _originalLocalPosition = Vector3.zero; _originalLocalRotation = Quaternion.identity; } private void HandleInput() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(FreeCamLocalConfig.GetToggleFreeCamKey())) { if (!IsActive && !FreeCamPolicy.CanToggleFreeCam()) { AdvancedFreeCam.Logger.LogInfo((object)"FreeCam denied by policy"); } else { ToggleFreeCam(); } } else { if (!IsActive) { return; } HandleSpeedWheelInput(); if (Input.GetKeyDown(FreeCamLocalConfig.GetTogglePhotoModeKey())) { FreeCamPhotoMode.Toggle(); } if (FreeCamPhotoMode.IsEnabled && (Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307))) { float y = Input.mouseScrollDelta.y; if (Mathf.Abs(y) > 0.001f) { float photoModeNightVision = FreeCamLocalConfig.GetPhotoModeNightVision(); float num = Mathf.Clamp(photoModeNightVision + y * 5f, 0f, 100f); AdvancedFreeCam.Instance.SetPhotoModeNightVision(num); FreeCamPhotoMode.ApplyNightVisionOnly(); AdvancedFreeCam.Logger.LogInfo((object)$"PhotoMode NightVision: {num:0}"); } } } } private void TickActive(float deltaTime) { //IL_006f: 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_00a6: Unknown result type (might be due to invalid IL or missing references) CameraAim instance = CameraAim.Instance; if (instance != null) { instance.OverridePlayerAimDisable(true); } PlayerController instance2 = PlayerController.instance; if (instance2 != null) { instance2.InputDisable(0.1f); } Transform transform = _rig.Transform; if ((Object)(object)transform == (Object)null || (Object)(object)_cameraAimTransform == (Object)null || (Object)(object)CameraAim.Instance == (Object)null) { ForceCleanup("Lost references while active"); return; } EnsureMoveSpeedInitialized(); float num = _currentMoveSpeed; if (Input.GetKey(FreeCamLocalConfig.GetFastMoveKey())) { num *= FreeCamLocalConfig.GetFreeCamFastMoveMultiplier(); } _controller.Tick(deltaTime, transform, num); ApplyRigToCameraAim(); if (SemiFunc.IsMultiplayer()) { FreeCamGhostNetwork.SendState(active: true, transform.position, transform.rotation); } } private void CacheOriginalCameraParent() { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cameraAimTransform == (Object)null)) { _originalParent = _cameraAimTransform.parent; _originalLocalPosition = _cameraAimTransform.localPosition; _originalLocalRotation = _cameraAimTransform.localRotation; } } private void CleanupInternal(bool resetAimDisable) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) FreeCamPhotoMode.ForceReset(); RestoreCameraAimSafe(resetAimDisable); _rig.Destroy(); _controller.Exit(); _cameraAimTransform = null; _originalParent = null; _originalLocalPosition = Vector3.zero; _originalLocalRotation = Quaternion.identity; _state = FreeCamState.Disabled; } private bool CanUseFreeCamNow() { if ((Object)(object)RunManager.instance == (Object)null) { return false; } if (RunManager.instance.restarting) { return false; } if (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsShop() && !SemiFunc.RunIsArena() && !SemiFunc.RunIsRecording()) { return false; } if ((Object)(object)PlayerController.instance == (Object)null) { return false; } if ((Object)(object)PlayerAvatar.instance == (Object)null) { return false; } if ((Object)(object)CameraAim.Instance == (Object)null) { return false; } return true; } private void RestoreCameraAimSafe(bool resetAimDisable) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cameraAimTransform == (Object)null) { return; } try { if ((Object)(object)_originalParent != (Object)null) { _cameraAimTransform.SetParent(_originalParent, true); _cameraAimTransform.localPosition = _originalLocalPosition; _cameraAimTransform.localRotation = _originalLocalRotation; } else { _cameraAimTransform.SetParent((Transform)null, true); } if (resetAimDisable && (Object)(object)CameraAim.Instance != (Object)null) { CameraAim.Instance.OverridePlayerAimDisableReset(); } } catch (Exception arg) { AdvancedFreeCam.Logger.LogWarning((object)$"RestoreCameraAimSafe failed: {arg}"); } } private void ApplyRigToCameraAim() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cameraAimTransform == (Object)null)) { _cameraAimTransform.localPosition = Vector3.zero; _cameraAimTransform.localRotation = Quaternion.identity; } } } internal static class FreeCamPhotoMode { private static bool _enabled; private static bool _savedFog; private static bool _fogSaved; private static float _savedFarClipPlane; private static bool _farClipSaved; private static float _savedShadowDistance; private static bool _shadowDistanceSaved; private static float _savedLodBias; private static bool _lodBiasSaved; private static int _savedMaximumLodLevel; private static bool _maximumLodLevelSaved; private static Color _savedAmbientLight; private static bool _ambientLightSaved; private static MenuSpectateList _menuSpectateList; private static SpectateHeadUI _spectateHeadUI; private static SpectateNameUI _spectateNameUI; private static readonly List _disabledMenuPlayerListedObjects = new List(); private const float PhotoModeFarClipPlane = 500f; private const float PhotoModeShadowDistance = 300f; private const float PhotoModeLodBias = 3f; private const int PhotoModeMaximumLodLevel = 0; internal static bool IsEnabled => _enabled; internal static void Toggle() { if (_enabled) { Disable(); } else { Enable(); } } internal static void LateTick() { if (IsEnabled) { ApplyPhotoModeValues(); ApplyNightVision(); } } internal static void Enable() { if (!_enabled) { _enabled = true; SaveCurrentValues(); CacheUIReferences(); ApplyPhotoModeValues(); ApplyNightVision(); HidePhotoModeUI(); HidePhotoModeEquipment(); AdvancedFreeCam.Logger.LogInfo((object)"FreeCam PhotoMode Enabled"); } } internal static void Disable() { if (_enabled) { _enabled = false; RestoreSavedValues(); ClearSavedFlags(); RestorePhotoModeUI(); RestorePhotoModeEquipment(); ResetCachedReferences(); AdvancedFreeCam.Logger.LogInfo((object)"FreeCam PhotoMode Disabled"); } } internal static void ForceReset(bool isChangeLevel = false) { _enabled = false; if (isChangeLevel) { ClearSavedFlags(); ResetCachedReferences(); return; } RestoreSavedValues(); ClearSavedFlags(); RestorePhotoModeUI(); RestorePhotoModeEquipment(); ResetCachedReferences(); } internal static void Tick() { if (_enabled) { ApplyPhotoModeValues(); ApplyNightVision(); HidePhotoModeUI(); HidePhotoModeEquipment(); } } internal static void ApplyNightVisionOnly() { if (_enabled) { ApplyNightVision(); } } private static void SaveCurrentValues() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) _savedFog = RenderSettings.fog; _fogSaved = true; Camera mainCamera = GetMainCamera(); if ((Object)(object)mainCamera != (Object)null) { _savedFarClipPlane = mainCamera.farClipPlane; _farClipSaved = true; } else { _farClipSaved = false; } _savedShadowDistance = QualitySettings.shadowDistance; _shadowDistanceSaved = true; _savedLodBias = QualitySettings.lodBias; _lodBiasSaved = true; _savedMaximumLodLevel = QualitySettings.maximumLODLevel; _maximumLodLevelSaved = true; _savedAmbientLight = RenderSettings.ambientLight; _ambientLightSaved = true; } private static void ApplyPhotoModeValues() { Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { RenderSettings.fog = false; main.farClipPlane = 500f; QualitySettings.shadowDistance = 300f; QualitySettings.lodBias = Mathf.Max(QualitySettings.lodBias, 3f); QualitySettings.maximumLODLevel = 0; } } private static void ApplyNightVision() { //IL_002b: 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_0031: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(FreeCamLocalConfig.GetPhotoModeNightVision(), 0f, 100f); if (!(num <= 0.001f)) { float num2 = Mathf.Clamp01(num / 100f); Color ambientLight = RenderSettings.ambientLight; Color ambientLight2 = Color.Lerp(ambientLight, Color.white * 2f, num2); RenderSettings.ambientLight = ambientLight2; } } private static void RestoreSavedValues() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (_fogSaved) { RenderSettings.fog = _savedFog; } Camera mainCamera = GetMainCamera(); if ((Object)(object)mainCamera != (Object)null && _farClipSaved) { mainCamera.farClipPlane = _savedFarClipPlane; } if (_shadowDistanceSaved) { QualitySettings.shadowDistance = _savedShadowDistance; } if (_lodBiasSaved) { QualitySettings.lodBias = _savedLodBias; } if (_maximumLodLevelSaved) { QualitySettings.maximumLODLevel = _savedMaximumLodLevel; } if (_ambientLightSaved) { RenderSettings.ambientLight = _savedAmbientLight; } } private static void ClearSavedFlags() { _fogSaved = false; _farClipSaved = false; _shadowDistanceSaved = false; _lodBiasSaved = false; _maximumLodLevelSaved = false; _ambientLightSaved = false; } private static void CacheUIReferences() { if ((Object)(object)_menuSpectateList == (Object)null) { _menuSpectateList = Object.FindObjectOfType(true); } if ((Object)(object)_spectateHeadUI == (Object)null) { _spectateHeadUI = SpectateHeadUI.instance; if ((Object)(object)_spectateHeadUI == (Object)null) { _spectateHeadUI = Object.FindObjectOfType(true); } } if ((Object)(object)_spectateNameUI == (Object)null) { _spectateNameUI = SpectateNameUI.instance; if ((Object)(object)_spectateNameUI == (Object)null) { _spectateNameUI = Object.FindObjectOfType(true); } } } private static void HidePhotoModeUI() { if ((Object)(object)HUD.instance != (Object)null) { HUD.instance.Hide(); } if ((Object)(object)MissionUI.instance != (Object)null) { ((SemiUI)MissionUI.instance).Hide(); } if ((Object)(object)BatteryUI.instance != (Object)null) { ((SemiUI)BatteryUI.instance).Hide(); } if ((Object)(object)_spectateNameUI != (Object)null) { ((SemiUI)_spectateNameUI).Hide(); } if ((Object)(object)_spectateHeadUI != (Object)null) { ((SemiUI)_spectateHeadUI).Hide(); } if ((Object)(object)_menuSpectateList != (Object)null) { ((SemiUI)_menuSpectateList).Hide(); HideMenuPlayerListedChildren(); } SemiFunc.UIHideHealth(); SemiFunc.UIHideOvercharge(); SemiFunc.UIHideEnergy(); SemiFunc.UIHideInventory(); SemiFunc.UIHideHaul(); SemiFunc.UIHideGoal(); SemiFunc.UIHideCurrency(); SemiFunc.UIHideAim(); SemiFunc.UIHideTumble(); SemiFunc.UIHideWorldSpace(); SemiFunc.UIHideValuableDiscover(); SemiFunc.UIHideShopCost(); } private static void HideMenuPlayerListedChildren() { for (int i = 0; i < _menuSpectateList.listObjects.Count; i++) { GameObject val = _menuSpectateList.listObjects[i]; if (!((Object)(object)val == (Object)null) && val.activeSelf) { val.SetActive(false); if (!_disabledMenuPlayerListedObjects.Contains(val)) { _disabledMenuPlayerListedObjects.Add(val); } } } } private static void RestorePhotoModeUI() { if ((Object)(object)HUD.instance != (Object)null) { HUD.instance.Show(); } if ((Object)(object)_menuSpectateList != (Object)null) { ((Behaviour)_menuSpectateList).enabled = true; ((SemiUI)_menuSpectateList).Show(); } for (int i = 0; i < _disabledMenuPlayerListedObjects.Count; i++) { GameObject val = _disabledMenuPlayerListedObjects[i]; if (!((Object)(object)val == (Object)null) && !val.activeSelf) { val.SetActive(true); } } _disabledMenuPlayerListedObjects.Clear(); if ((Object)(object)_spectateNameUI != (Object)null) { ((Behaviour)_spectateNameUI).enabled = true; ((SemiUI)_spectateNameUI).Show(); } if ((Object)(object)_spectateHeadUI != (Object)null) { ((Behaviour)_spectateHeadUI).enabled = true; ((SemiUI)_spectateHeadUI).Show(); } if ((Object)(object)SpectateCamera.instance != (Object)null) { SemiFunc.UIShowSpectate(); } } private static void HidePhotoModeEquipment() { FlashlightController instance = FlashlightController.Instance; if (!((Object)(object)instance == (Object)null)) { instance.hideFlashlight = true; instance.active = false; instance.LightActive = false; if ((Object)(object)instance.mesh != (Object)null) { ((Renderer)instance.mesh).enabled = false; } if ((Object)(object)instance.spotlight != (Object)null) { ((Behaviour)instance.spotlight).enabled = false; } if ((Object)(object)instance.halo != (Object)null) { instance.halo.enabled = false; } } } private static void RestorePhotoModeEquipment() { FlashlightController instance = FlashlightController.Instance; if (!((Object)(object)instance == (Object)null)) { instance.hideFlashlight = false; } } private static void ResetCachedReferences() { _menuSpectateList = null; _spectateHeadUI = null; _spectateNameUI = null; _disabledMenuPlayerListedObjects.Clear(); } private static Camera GetMainCamera() { if ((Object)(object)GameDirector.instance != (Object)null && (Object)(object)GameDirector.instance.MainCamera != (Object)null) { return GameDirector.instance.MainCamera; } return Camera.main; } } [HarmonyPatch(typeof(SemiFunc), "UIShowSpectate")] internal static class Patch_SemiFunc_UIShowSpectate_PhotoModeBlock { private static bool Prefix() { return !FreeCamPhotoMode.IsEnabled; } } internal static class Patch_MenuSpectateList_PhotoModeBlock { private static bool Prefix(MenuSpectateList __instance) { if (!FreeCamPhotoMode.IsEnabled) { return true; } ((SemiUI)__instance).Hide(); return false; } } [HarmonyPatch(typeof(MenuPlayerListed), "Update")] internal static class Patch_MenuPlayerListed_PhotoModeBlock { private static bool Prefix() { return !FreeCamPhotoMode.IsEnabled; } } [HarmonyPatch(typeof(LobbyChatUI), "Update")] internal static class Patch_LobbyChatUI_PhotoModeBlock { private static bool Prefix(LobbyChatUI __instance) { if (!FreeCamPhotoMode.IsEnabled) { return true; } ((SemiUI)__instance).Hide(); return false; } } [HarmonyPatch(typeof(MenuPlayerHead), "Update")] internal static class Patch_MenuPlayerHead_PhotoModeBlock { private static bool Prefix() { return !FreeCamPhotoMode.IsEnabled; } } internal sealed class FreeCamRig { private GameObject? _gameObject; internal Transform? Transform { get { if (!((Object)(object)_gameObject != (Object)null)) { return null; } return _gameObject.transform; } } internal bool IsValid => (Object)(object)_gameObject != (Object)null; internal void EnsureCreated() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown if (!((Object)(object)_gameObject != (Object)null)) { _gameObject = new GameObject("AdvancedFreeCam_Rig"); } } internal void SetPose(Vector3 position, Quaternion rotation) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Transform transform = Transform; if (!((Object)(object)transform == (Object)null)) { transform.position = position; transform.rotation = rotation; } } internal void Destroy() { if (!((Object)(object)_gameObject == (Object)null)) { Object.Destroy((Object)(object)_gameObject); _gameObject = null; } } } internal enum FreeCamState { Disabled, Active } } namespace AdvancedFreeCam.Config { internal sealed class FreeCamConfig { internal static FreeCamConfig Instance { get; } = new FreeCamConfig(); internal bool AllowHostAliveFreeCam { get; set; } = true; internal bool AllowClientAliveFreeCam { get; set; } internal bool AllowClientDeadFreeCam { get; set; } = true; internal bool AllowHostForceDisable { get; set; } = true; internal bool GhostVisibleToAlivePlayers { get; set; } internal bool GhostVisibleToSpectators { get; set; } = true; internal bool GhostVisibleToFreeCamPlayers { get; set; } = true; private FreeCamConfig() { } } internal sealed class FreeCamConfigSnapshot { public bool AllowHostAliveFreeCam; public bool AllowClientAliveFreeCam; public bool AllowClientDeadFreeCam; public bool AllowHostForceDisable; public bool AllowFreeCamVoice; public bool AllowClientFreeCamVoice; public bool GhostVisibleToAlivePlayers; public bool GhostVisibleToSpectators; public bool GhostVisibleToFreeCamPlayers; internal static FreeCamConfigSnapshot FromRuntime(FreeCamConfig config) { return new FreeCamConfigSnapshot { AllowHostAliveFreeCam = config.AllowHostAliveFreeCam, AllowClientAliveFreeCam = config.AllowClientAliveFreeCam, AllowClientDeadFreeCam = config.AllowClientDeadFreeCam, AllowHostForceDisable = config.AllowHostForceDisable, GhostVisibleToAlivePlayers = config.GhostVisibleToAlivePlayers, GhostVisibleToSpectators = config.GhostVisibleToSpectators, GhostVisibleToFreeCamPlayers = config.GhostVisibleToFreeCamPlayers }; } internal void ApplyToRuntime(FreeCamConfig config) { config.AllowHostAliveFreeCam = AllowHostAliveFreeCam; config.AllowClientAliveFreeCam = AllowClientAliveFreeCam; config.AllowClientDeadFreeCam = AllowClientDeadFreeCam; config.AllowHostForceDisable = AllowHostForceDisable; config.GhostVisibleToAlivePlayers = GhostVisibleToAlivePlayers; config.GhostVisibleToSpectators = GhostVisibleToSpectators; config.GhostVisibleToFreeCamPlayers = GhostVisibleToFreeCamPlayers; } } internal static class FreeCamLocalConfig { internal static KeyCode GetToggleFreeCamKey() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.ToggleFreeCamKey?.Value) ?? 289); } internal static KeyCode GetTogglePhotoModeKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.TogglePhotoModeKey?.Value) ?? 122); } internal static KeyCode GetFastMoveKey() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.FastMoveKey?.Value) ?? 304); } internal static KeyCode GetMoveUpKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.MoveUpKey?.Value) ?? 32); } internal static KeyCode GetMoveDownKey() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.MoveDownKey?.Value) ?? 306); } internal static bool IsPushToTalkEnabled() { return FreeCamLocalSettings.FreeCamVoicePushToTalk?.Value ?? true; } internal static KeyCode GetPushToTalkKey() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(((??)FreeCamLocalSettings.FreeCamVoicePushToTalkKey?.Value) ?? 118); } internal static float GetPhotoModeNightVision() { return FreeCamLocalSettings.PhotoModeNightVision?.Value ?? 25f; } internal static float GetFreeCamBaseMoveSpeed() { return Mathf.Clamp(FreeCamLocalSettings.FreeCamBaseMoveSpeed?.Value ?? 8f, GetFreeCamMinMoveSpeed(), GetFreeCamMaxMoveSpeed()); } internal static float GetFreeCamLookSensitivity() { return Mathf.Clamp(FreeCamLocalSettings.FreeCamLookSensitivity?.Value ?? 1.5f, 0.1f, 10f); } internal static float GetFreeCamMaxMouseDelta() { return Mathf.Clamp(FreeCamLocalSettings.FreeCamMaxMouseDelta?.Value ?? 8f, 1f, 50f); } internal static float GetFreeCamFastMoveMultiplier() { return Mathf.Max(1f, FreeCamLocalSettings.FreeCamFastMoveMultiplier?.Value ?? 3f); } internal static float GetFreeCamMinMoveSpeed() { return Mathf.Max(0.1f, FreeCamLocalSettings.FreeCamMinMoveSpeed?.Value ?? 1f); } internal static float GetFreeCamMaxMoveSpeed() { return Mathf.Max(GetFreeCamMinMoveSpeed(), FreeCamLocalSettings.FreeCamMaxMoveSpeed?.Value ?? 50f); } internal static float GetFreeCamMouseWheelSpeedStep() { return Mathf.Max(0.1f, FreeCamLocalSettings.FreeCamMouseWheelSpeedStep?.Value ?? 1f); } } internal static class FreeCamLocalSettings { internal static ConfigEntry? ToggleFreeCamKey; internal static ConfigEntry? TogglePhotoModeKey; internal static ConfigEntry? FastMoveKey; internal static ConfigEntry? MoveUpKey; internal static ConfigEntry? MoveDownKey; internal static ConfigEntry? FreeCamVoicePushToTalk; internal static ConfigEntry? FreeCamVoicePushToTalkKey; internal static ConfigEntry? PhotoModeNightVision; internal static ConfigEntry? FreeCamMouseWheelSpeedStep; internal static ConfigEntry? FreeCamBaseMoveSpeed; internal static ConfigEntry? FreeCamFastMoveMultiplier; internal static ConfigEntry? FreeCamMinMoveSpeed; internal static ConfigEntry? FreeCamMaxMoveSpeed; internal static ConfigEntry? FreeCamLookSensitivity; internal static ConfigEntry? FreeCamMaxMouseDelta; } internal static class FreeCamPolicy { internal static bool CanToggleFreeCam() { if (!CanEvaluate()) { return false; } if (!HasUsableAuthority()) { return false; } bool flag = SemiFunc.IsMasterClientOrSingleplayer(); bool flag2 = IsLocalPlayerInDeadState(); FreeCamConfig instance = FreeCamConfig.Instance; if (flag) { if (flag2) { return true; } return instance.AllowHostAliveFreeCam; } if (flag2) { return instance.AllowClientDeadFreeCam; } return instance.AllowClientAliveFreeCam; } internal static bool ShouldGhostBeVisibleToAliveViewer() { if (HasUsableAuthority()) { return FreeCamConfig.Instance.GhostVisibleToAlivePlayers; } return false; } internal static bool ShouldGhostBeVisibleToSpectatorViewer() { if (HasUsableAuthority()) { return FreeCamConfig.Instance.GhostVisibleToSpectators; } return false; } internal static bool ShouldGhostBeVisibleToFreeCamViewer() { if (HasUsableAuthority()) { return FreeCamConfig.Instance.GhostVisibleToFreeCamPlayers; } return false; } private static bool CanEvaluate() { return (Object)(object)PlayerAvatar.instance != (Object)null; } private static bool IsLocalPlayerInDeadState() { PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return false; } return instance.isDisabled; } private static bool HasUsableAuthority() { if (!SemiFunc.IsMultiplayer()) { return true; } if (SemiFunc.IsMasterClientOrSingleplayer()) { return true; } return AdvancedFreeCam.Instance.HasAuthoritativeRoomConfig; } } }