RUMBLE does not support other mod managers. If you want to use a manager, you must use the RUMBLE Mod Manager, a manager specifically designed for this game.
Decompiled source of PingVisualizer v1.1.1
Mods/PingVisualizer.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using FlatLand; using HarmonyLib; using Il2CppExitGames.Client.Photon; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppPhoton.Pun; using Il2CppPhoton.Realtime; using Il2CppRUMBLE.CharacterCreation.Interactable; using Il2CppRUMBLE.Combat.ShiftStones; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Players; using Il2CppRUMBLE.Players.Scaling; using Il2CppRUMBLE.Players.Subsystems; using Il2CppRUMBLE.Pools; using Il2CppRUMBLE.Utilities; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using PingVisualizer; using UIFramework; using UIFramework.Models; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.VFX; using VoidLand; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "PingVisualizer", "1.1.1", "TacoSlayer36", null)] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("PingVisualizer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PingVisualizer")] [assembly: AssemblyTitle("PingVisualizer")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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; } } } namespace PingVisualizer { public static class BuildInfo { public const string Name = "PingVisualizer"; public const string Author = "TacoSlayer36"; public const string Version = "1.1.1"; } public static class Config { public enum HideNearbyType { [Display(Name = "Disabled")] Disabled, [Display(Name = "Only Heads")] OnlyHeads, [Display(Name = "Entirely")] Entirely } public static string UserDataPath = Path.Combine("UserData", "PingVisualizer"); public static string PreferencesFilePath = Path.Combine(UserDataPath, "Config.cfg"); public static MelonPreferences_Category Cat_Visualizer; public static MelonPreferences_Entry<bool> Enabled; public static MelonPreferences_Entry<HideNearbyType> HideNearby; public static MelonPreferences_Entry<string> OneWayColor; public static MelonPreferences_Entry<string> TwoWayColor; public static MelonPreferences_Entry<bool> MatchesOnly; public static MelonPreferences_Category Cat_Client; public static MelonPreferences_Entry<bool> OneWayClient; public static MelonPreferences_Entry<bool> TwoWayClient; public static MelonPreferences_Category Cat_Host; public static MelonPreferences_Entry<bool> OneWayHost; public static MelonPreferences_Entry<bool> TwoWayHost; public static MelonPreferences_Category Cat_Testing; public static MelonPreferences_Entry<int> AssumedHostPing; public static MelonPreferences_Entry<int> AssumedClientPing; public static MelonPreferences_Entry<int> ForcedHostPing; public static MelonPreferences_Entry<int> ForcedClientPing; public static float DefaultHostPing => ((float)ForcedHostPing.EditedValue != -1f) ? ForcedHostPing.EditedValue : AssumedHostPing.EditedValue; public static float DefaultClientPing => ((float)ForcedClientPing.EditedValue != -1f) ? ForcedClientPing.EditedValue : AssumedClientPing.EditedValue; public static void SetUpUI() { Cat_Visualizer = MelonPreferences.CreateCategory("PingVisualizer_Visualizer", "Visualizer"); Cat_Visualizer.SetFilePath(PreferencesFilePath); Enabled = Cat_Visualizer.CreateEntry<bool>("PingVisualizer_Enabled", true, "Enabled", "Enable/Disable all visualization", false, false, (ValueValidator)null, (string)null); MatchesOnly = Cat_Visualizer.CreateEntry<bool>("PingVisualizer_MatchesOnly", true, "Matches Only", "Only show laggards while in a match", false, false, (ValueValidator)null, (string)null); HideNearby = Cat_Visualizer.CreateEntry<HideNearbyType>("PingVisualizer_HideNearby", HideNearbyType.OnlyHeads, "Hide Nearby Laggards", "Hides laggards that are close to you", false, false, (ValueValidator)null, (string)null); OneWayColor = Cat_Visualizer.CreateEntry<string>("PingVisualizer_OneWayColor", "#FF00FF", "One-Way Color", "Color for one-way laggards", false, false, (ValueValidator)null, (string)null); TwoWayColor = Cat_Visualizer.CreateEntry<string>("PingVisualizer_TwoWayColor", "#FFFF00", "Two-Way Color", "Color for two-way laggards", false, false, (ValueValidator)null, (string)null); Cat_Client = MelonPreferences.CreateCategory("PingVisualizer_Client", "Client"); Cat_Client.SetFilePath(PreferencesFilePath); OneWayClient = Cat_Client.CreateEntry<bool>("PingVisualizer_OneWay", false, "One-Way Laggard", "Enable a <#F0F>clone</color> to show your ping delay to the host\n(This has no effect on gameplay, but is the real-time position that the host is seeing you)", false, false, (ValueValidator)null, (string)null); TwoWayClient = Cat_Client.CreateEntry<bool>("PingVisualizer_TwoWay", true, "Two-Way Laggard", "Enable a <#FF0>clone</color> to show your ping delay to the host and back\n(This is the position that can be hit/spawn structures)", false, false, (ValueValidator)null, (string)null); Cat_Host = MelonPreferences.CreateCategory("PingVisualizer_Host", "Host"); Cat_Host.SetFilePath(PreferencesFilePath); OneWayHost = Cat_Host.CreateEntry<bool>("PingVisualizer_OneWay", false, "One-Way Laggard", "Enable a <#F0F>clone</color> to show your ping delay to the opponent\n(This is the real-time position the client is seeing you in)", false, false, (ValueValidator)null, (string)null); TwoWayHost = Cat_Host.CreateEntry<bool>("PingVisualizer_TwoWay", false, "Two-Way Laggard", "Enable a <#FF0>clone</color> to show your ping delay to the opponent and back\n(This is the position the client is seeing you by the time they react on your end)", false, false, (ValueValidator)null, (string)null); Cat_Testing = MelonPreferences.CreateCategory("PingVisualizer_Testing", "Testing"); Cat_Testing.SetFilePath(PreferencesFilePath); AssumedClientPing = Cat_Testing.CreateEntry<int>("PingVisualizer_AssumedClientPing", 70, "Assumed Client Ping", "Ping value to give the client when the actual value cannot be found or doesn't exist", false, false, (ValueValidator)null, (string)null); AssumedHostPing = Cat_Testing.CreateEntry<int>("PingVisualizer_AssumedHostPing", 70, "Assumed Host Ping", "Ping value to give the host when the actual value cannot be found or doesn't exist", false, false, (ValueValidator)null, (string)null); ForcedClientPing = Cat_Testing.CreateEntry<int>("PingVisualizer_ForcedClientPing", -1, "Forced Client Ping", "Override the client ping to this value\n(-1 to disable)", false, false, (ValueValidator)null, (string)null); ForcedHostPing = Cat_Testing.CreateEntry<int>("PingVisualizer_ForcedHostPing", -1, "Forced Host Ping", "Override the host ping to this value\n(-1 to disable)", false, false, (ValueValidator)null, (string)null); MelonModel val = UI.RegisterMelon((MelonBase)(object)Core.Instance, (MelonPreferences_Category[])(object)new MelonPreferences_Category[4] { Cat_Visualizer, Cat_Client, Cat_Host, Cat_Testing }); } public static void OnMyPrefsSaved(string filePath) { if (!(filePath != PreferencesFilePath)) { Core.SetLaggards(); } } } public class Core : MelonMod { public static Core Instance; public static List<PlayerVisualsClone> Laggards = new List<PlayerVisualsClone>(); public static Material PoseGhostMat; public static int BuildIndex = -1; public static bool HasGuard; public static PooledVisualEffect? LocalGuardVFX; public override void OnLateInitializeMelon() { Instance = this; Config.SetUpUI(); ((MelonEventBase<LemonAction<string>>)(object)MelonPreferences.OnPreferencesSaved).Subscribe((LemonAction<string>)Config.OnMyPrefsSaved, 0, false); AssetBundle val = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(HelperFunctions.LoadEmbeddedResource("PingVisualizer.assets.pingvisualizer"))); PoseGhostMat = val.LoadAsset<Material>("Laggard"); PoseGhostMat.SetFloat("_Inflate", 0.003f); ((Object)PoseGhostMat).hideFlags = (HideFlags)61; if (MelonBase.RegisteredMelons.Any((MelonBase m) => m.Info.Name == "FlatLand")) { FlatLandSupport.SetUp(); } if (MelonBase.RegisteredMelons.Any((MelonBase m) => m.Info.Name == "VoidLand")) { VoidLandSupport.SetUp(); } } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { BuildIndex = buildIndex; } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { if (playerInitializePatch.WaitForPlayerRoutine != null) { MelonCoroutines.Stop(playerInitializePatch.WaitForPlayerRoutine); } } public override void OnFixedUpdate() { List<Laggard> list = new List<Laggard>(); foreach (Laggard laggard in Laggards) { if ((Object)(object)laggard.ParentController == (Object)null) { Object.DestroyImmediate((Object)(object)laggard.Visuals); list.Add(laggard); } } foreach (Laggard item in list) { Laggards.Remove(item); } } public static void SetLaggards() { //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) List<Laggard> list = new List<Laggard>(); foreach (Laggard laggard in Laggards) { if ((Object)(object)laggard == (Object)null || (Object)(object)((Component)laggard).gameObject == (Object)null) { list.Add(laggard); continue; } if (!Config.Enabled.EditedValue || (Config.MatchesOnly.EditedValue && BuildIndex < 3)) { ((Component)laggard).gameObject.SetActive(false); continue; } if (laggard.Type == Laggard.LaggardType.OneWay && !laggard.ParentController.IsHost()) { ((Component)laggard).gameObject.SetActive(Config.OneWayClient.EditedValue); } if (laggard.Type == Laggard.LaggardType.TwoWay && !laggard.ParentController.IsHost()) { ((Component)laggard).gameObject.SetActive(Config.TwoWayClient.EditedValue); } if (laggard.Type == Laggard.LaggardType.OneWay && laggard.ParentController.IsHost()) { ((Component)laggard).gameObject.SetActive(Config.OneWayHost.EditedValue); } if (laggard.Type == Laggard.LaggardType.TwoWay && laggard.ParentController.IsHost()) { ((Component)laggard).gameObject.SetActive(Config.TwoWayHost.EditedValue); } if (laggard.Type == Laggard.LaggardType.OneWay) { ((Renderer)laggard.SMR).material.color = HelperFunctions.ParseColor(Config.OneWayColor.EditedValue); } if (laggard.Type == Laggard.LaggardType.TwoWay) { ((Renderer)laggard.SMR).material.color = HelperFunctions.ParseColor(Config.TwoWayColor.EditedValue); } } foreach (Laggard item in list) { Laggards.Remove(item); } } public static float GetPlayerPing(PlayerController controller) { if (controller.IsHost() && Config.ForcedHostPing.EditedValue > 0) { return Config.ForcedHostPing.EditedValue; } if (!controller.IsHost() && Config.ForcedClientPing.EditedValue > 0) { return Config.ForcedClientPing.EditedValue; } if ((Object)(object)controller == (Object)null) { return 0f; } object obj; if (controller == null) { obj = null; } else { PlayerNetworking playerNetworking = controller.PlayerNetworking; if (playerNetworking == null) { obj = null; } else { PhotonView rootPhotonView = playerNetworking.RootPhotonView; obj = ((rootPhotonView != null) ? rootPhotonView.Owner : null); } } Player val = (Player)obj; Hashtable val2 = ((val != null) ? val.CustomProperties : null); if (val2 != null && ((Dictionary<Object, Object>)(object)val2).ContainsKey(Object.op_Implicit("ping"))) { return ((Il2CppObjectBase)val2[Object.op_Implicit("ping")]).Unbox<int>(); } if (val != null) { return controller.IsHost() ? Config.DefaultHostPing : Config.DefaultClientPing; } if (!PhotonNetwork.InRoom) { return Config.DefaultHostPing; } return 0f; } public static float GetHostPing() { if (!PhotonNetwork.InRoom) { return GetPlayerPing(Singleton<PlayerManager>.Instance.LocalPlayer.Controller); } Player masterClient = PhotonNetwork.MasterClient; if (masterClient != null) { _ = masterClient.ActorNumber; if (true) { Player playerByActorNo = Singleton<PlayerManager>.Instance.GetPlayerByActorNo(PhotonNetwork.MasterClient.ActorNumber); return GetPlayerPing((playerByActorNo != null) ? playerByActorNo.Controller : null); } } return 0f; } } [HarmonyPatch(typeof(PlayerController), "Initialize")] public static class playerInitializePatch { public static object WaitForPlayerRoutine; private static void Postfix(ref PlayerController __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 PlayerController val = __instance; if ((int)val.controllerType == 1) { WaitForPlayerRoutine = MelonCoroutines.Start(HelperFunctions.WaitForPlayerLoad(val, processNewPlayer)); } static void processNewPlayer(PlayerController player) { Core.Laggards.Add(Laggard.CreateLaggard(player, Laggard.LaggardType.OneWay)); Core.Laggards.Add(Laggard.CreateLaggard(player, Laggard.LaggardType.TwoWay)); Core.SetLaggards(); } } } public static class FlatLandSupport { public static void SetUp() { main.AddNameToDontDisable("PingVisualizer"); } } internal static class HelperFunctions { public static Color ParseColor(string input) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_001a: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (ColorUtility.TryParseHtmlString(input, ref result)) { return result; } return Color.white; } public static List<Transform> FindChildrenRecursive(Transform parent) { List<Transform> list = new List<Transform>(); for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); list.Add(child); list.AddRange(FindChildrenRecursive(child)); } return list; } public static void DisableAllComponents(GameObject gameObject, List<Behaviour> except = null) { foreach (Behaviour component in gameObject.GetComponents<Behaviour>()) { component.enabled = except?.Contains(component) ?? false; } } public static void CopyAllTransforms(List<Transform> from, List<Transform> to) { //IL_002f: 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_0061: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < from.Count; i++) { if (to.Count >= i || from.Count >= 1) { to[i].position = from[i].position; to[i].rotation = from[i].rotation; to[i].localScale = from[i].localScale; } } } public static string SanitizeString(string Input) { string pattern = "<[^>]*>"; return Regex.Replace(Input, pattern, string.Empty); } public static Vector3 GetRelativeVelocity(Vector3 velocityA, Collision collision) { //IL_0019: 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) //IL_001e: 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_0020: 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_0026: 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) Rigidbody rigidbody = collision.rigidbody; Vector3 val = (((Object)(object)rigidbody != (Object)null) ? rigidbody.velocity : Vector3.zero); return velocityA - val; } public static byte[] LoadEmbeddedResource(string resourcePath) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(resourcePath); if (stream == null) { throw new FileNotFoundException("Embedded resource '" + resourcePath + "' not found."); } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } public static IEnumerator WaitForPlayerLoad(PlayerController player, Action<PlayerController> callback) { int i = 0; int startingBuildIndex = -1; while (true) { i++; if (i == 100) { startingBuildIndex = Core.BuildIndex; } if (i > 100 && startingBuildIndex != Core.BuildIndex) { yield break; } if ((Object)(object)((player != null) ? player.PlayerVisuals : null) != (Object)null && player.IsInitialized && (int)player.PlayerSessionStateSystem.CurrentVRState == 0) { break; } yield return (object)new WaitForFixedUpdate(); } callback(player); } } public static class Extensions { public static Transform GetChest(this PlayerController player) { return ((Component)player).GetComponentInChildren<RigDefinition>().ChestDefinition.Transform; } public static Transform GetHead(this PlayerController player) { return player.PlayerVR.headset.Transform; } public static Vector3 GetStandingPosition(this PlayerController player) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return ((Component)player.PlayerPhysics.footCollider).transform.position; } public static Camera GetCamera(this PlayerController player) { object result; if (player == null) { result = null; } else { PlayerCamera playerCamera = player.PlayerCamera; result = ((playerCamera != null) ? playerCamera.Camera : null); } return (Camera)result; } public static List<BoneDefinition> GetBones(this PlayerController player) { return ((IEnumerable<BoneDefinition>)((Component)player).GetComponentInChildren<RigDefinition>().BoneDefinitions).ToList(); } public static bool IsHost(this PlayerController player) { int result; if (PhotonNetwork.InRoom) { bool? obj; if (player == null) { obj = null; } else { PlayerNetworking playerNetworking = player.PlayerNetworking; if (playerNetworking == null) { obj = null; } else { PhotonView rootPhotonView = playerNetworking.RootPhotonView; if (rootPhotonView == null) { obj = null; } else { Player owner = rootPhotonView.Owner; obj = ((owner != null) ? new bool?(owner.IsMasterClient) : ((bool?)null)); } } } result = ((obj ?? true) ? 1 : 0); } else { result = 1; } return (byte)result != 0; } } [RegisterTypeInIl2Cpp] public class Laggard : PlayerVisualsClone { public enum LaggardType { OneWay, TwoWay } public class LaggardState { public float TimeStamp = 0f; public List<TransformState> BoneStates = new List<TransformState>(); public Vector3 VisualsPos; public Quaternion VisualsRot; public bool IsGuarding; public Vector3? GuardPos; public float? GuardYaw; public LaggardState() { TimeStamp = Time.time; } } public class TransformState { public Vector3 Pos = Vector3.zero; public Quaternion Rot = Quaternion.identity; public Vector3 Scale = Vector3.one; public static TransformState FromTransform(Transform transform) { //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_0014: 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_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) return new TransformState { Pos = transform.localPosition, Rot = transform.localRotation, Scale = transform.localScale }; } public static List<TransformState> FromTransforms(List<Transform> transforms) { //IL_0034: 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_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) List<TransformState> list = new List<TransformState>(); foreach (Transform transform in transforms) { if (!((Object)(object)transform == (Object)null)) { list.Add(new TransformState { Pos = ((Component)transform).transform.localPosition, Rot = ((Component)transform).transform.localRotation, Scale = ((Component)transform).transform.localScale }); } } return list; } public static void CopyStateTo(Transform transform, TransformState state) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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 (!((Object)(object)transform == (Object)null)) { transform.localPosition = state.Pos; transform.localRotation = state.Rot; transform.localScale = state.Scale; } } public static void CopyStatesTo(List<Transform> transforms, List<TransformState> states) { for (int i = 0; i < transforms.Count && i < transforms.Count && i < states.Count; i++) { CopyStateTo(transforms[i], states[i]); } } } public const string OneWayLaggardName = "OneWayLaggard"; public const string TwoWayLaggardName = "TwoWayLaggard"; public const string LaggardParentName = "PingVisualizer"; public static GameObject LaggardParent; public LaggardType Type = LaggardType.OneWay; public List<LaggardState> LaggardStates = new List<LaggardState>(); private VisualEffect guardVFX = null; private bool hadGuardLastFrame = false; public float HostPing => Core.GetHostPing(); public float OwnerPing => Core.GetPlayerPing(ParentController); public float Offset { get { if (Type == LaggardType.OneWay) { return (OwnerPing + HostPing) / 2000f; } if (Type == LaggardType.TwoWay) { return (OwnerPing + HostPing) / 1000f; } return 0f; } } public void StoreState() { //IL_005b: 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_007b: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) LaggardState laggardState = new LaggardState { BoneStates = TransformState.FromTransforms((from b in ParentController.GetBones() select b.Transform).ToList()), VisualsPos = ((Component)ParentController.PlayerVisuals).gameObject.transform.position, VisualsRot = ((Component)ParentController.PlayerVisuals).gameObject.transform.rotation }; Il2CppStructArray<int> currentShiftStoneConfiguration = ((Component)ParentController).GetComponent<PlayerShiftstoneSystem>().GetCurrentShiftStoneConfiguration(); Core.HasGuard = ((Il2CppArrayBase<int>)(object)currentShiftStoneConfiguration)[0] == 3 || ((Il2CppArrayBase<int>)(object)currentShiftStoneConfiguration)[1] == 3; if (!Core.HasGuard) { Core.LocalGuardVFX = null; } else if ((Object)(object)Core.LocalGuardVFX == (Object)null) { Transform obj = ((Component)ParentController).transform.Find("Guardstone_VFX"); Core.LocalGuardVFX = ((obj != null) ? ((Component)obj).GetComponent<PooledVisualEffect>() : null); } if (!hadGuardLastFrame && Core.HasGuard && (Object)(object)Core.LocalGuardVFX != (Object)null && (Object)(object)guardVFX == (Object)null) { GameObject val = Object.Instantiate<GameObject>(((Component)Core.LocalGuardVFX).gameObject); val.SetActive(true); ((Component)val.transform.GetChild(0)).gameObject.SetActive(false); val.transform.SetParent(Visuals.transform, false); guardVFX = val.GetComponent<VisualEffect>(); } hadGuardLastFrame = Core.HasGuard; laggardState.VisualsPos = ((Component)ParentController).transform.GetChild(1).position; PooledVisualEffect? localGuardVFX = Core.LocalGuardVFX; int isGuarding; if (localGuardVFX != null) { _ = localGuardVFX.isPlaying; if (true) { isGuarding = (Core.LocalGuardVFX.isPlaying ? 1 : 0); goto IL_01e7; } } isGuarding = 0; goto IL_01e7; IL_01e7: laggardState.IsGuarding = (byte)isGuarding != 0; PooledVisualEffect? localGuardVFX2 = Core.LocalGuardVFX; laggardState.GuardPos = ((localGuardVFX2 != null) ? new Vector3?(((Component)localGuardVFX2).transform.position) : ((Vector3?)null)); PooledVisualEffect? localGuardVFX3 = Core.LocalGuardVFX; laggardState.GuardYaw = ((localGuardVFX3 != null) ? new float?(((Component)localGuardVFX3).transform.eulerAngles.y) : ((float?)null)); LaggardStates.Add(laggardState); List<LaggardState> list = LaggardStates.Where((LaggardState s) => s.TimeStamp < Time.time - Offset).ToList(); foreach (LaggardState item in list) { LaggardStates.Remove(item); } } public void PlayBackState() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (LaggardStates.Count == 0) { return; } LaggardState laggardState = LaggardStates[0]; if (laggardState == null) { return; } TransformState.CopyStatesTo(BoneTransforms, laggardState.BoneStates); Visuals.transform.position = laggardState.VisualsPos; Visuals.transform.rotation = laggardState.VisualsRot; if (laggardState.GuardPos.HasValue && laggardState.GuardYaw.HasValue && (Object)(object)guardVFX != (Object)null) { ((Component)guardVFX).transform.position = laggardState.GuardPos.Value + Vector3.down * 0.4f; ((Component)guardVFX).transform.rotation = Quaternion.Euler(0f, laggardState.GuardYaw.Value, 0f); if (laggardState.IsGuarding) { VisualEffect obj = guardVFX; if (obj != null) { obj.Play(); } } else { VisualEffect obj2 = guardVFX; if (obj2 != null) { obj2.Stop(); } } } double num = Vector3.Distance(((Component)Head).transform.position, ((Component)Singleton<PlayerManager>.Instance.LocalPlayer.Controller.GetHead()).transform.position); float num2 = (float)Math.Round(Math.Clamp(num - 0.2, 0.0, 1.0), 3); if (Config.HideNearby.EditedValue == Config.HideNearbyType.OnlyHeads) { ((Renderer)SMR).material.SetFloat("_HeadOpacity", num2); } else { ((Renderer)SMR).material.SetFloat("_HeadOpacity", 1f); } if (Config.HideNearby.EditedValue == Config.HideNearbyType.Entirely) { ((Renderer)SMR).material.SetFloat("_BodyOpacity", num2); } else { ((Renderer)SMR).material.SetFloat("_BodyOpacity", 1f); } VisualEffect obj3 = guardVFX; if (obj3 != null) { GameObject gameObject = ((Component)obj3).gameObject; if (gameObject != null) { gameObject.SetActive(num2 > 0.4f || Config.HideNearby.EditedValue != Config.HideNearbyType.Entirely); } } } private void Update() { StoreState(); PlayBackState(); } private void OnDestroy() { Core.Laggards.Remove(this); } public void SetUp() { SetUp(null); ((Object)this).name = ((Type == LaggardType.OneWay) ? "OneWayLaggard" : "TwoWayLaggard"); } public static Laggard CreateLaggard(PlayerController player, LaggardType type) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Laggard laggard = Object.Instantiate<GameObject>(((Component)player.PlayerVisuals).gameObject).AddComponent<Laggard>(); laggard.ParentController = player; laggard.Type = type; laggard.SetUp(); switch (type) { case LaggardType.OneWay: ((Renderer)laggard.SMR).material.color = HelperFunctions.ParseColor(Config.OneWayColor.EditedValue); break; case LaggardType.TwoWay: ((Renderer)laggard.SMR).material.color = HelperFunctions.ParseColor(Config.TwoWayColor.EditedValue); break; } createParentObjectIfNeeded(); ((Component)laggard).transform.SetParent(LaggardParent.transform); return laggard; } private static void createParentObjectIfNeeded() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)LaggardParent != (Object)null)) { LaggardParent = new GameObject("PingVisualizer"); } } } [RegisterTypeInIl2Cpp] public class PlayerVisualsClone : MonoBehaviour { public PlayerController ParentController; public GameObject Visuals; public List<Transform> BoneTransforms = new List<Transform>(); public Transform Head; public SkinnedMeshRenderer SMR; public static void Clone(PlayerController player) { GameObject val = Object.Instantiate<GameObject>(((Component)player.PlayerVisuals).gameObject); val.AddComponent<PlayerVisualsClone>().SetUp(); } public void SetUp(GameObject setupObject = null) { if ((Object)(object)setupObject == (Object)null) { setupObject = ((Component)this).gameObject; } Visuals = setupObject; Transform child = Visuals.transform.GetChild(1).GetChild(0).GetChild(4) .GetChild(0); object obj; if (child == null) { obj = null; } else { Transform child2 = child.GetChild(1); if (child2 == null) { obj = null; } else { GameObject gameObject = ((Component)child2).gameObject; if (gameObject == null) { obj = null; } else { ShiftStone componentInChildren = gameObject.GetComponentInChildren<ShiftStone>(true); obj = ((componentInChildren != null) ? ((Component)componentInChildren).gameObject : null); } } } Object.Destroy((Object)obj); object obj2; if (child == null) { obj2 = null; } else { Transform child3 = child.GetChild(2); if (child3 == null) { obj2 = null; } else { GameObject gameObject2 = ((Component)child3).gameObject; if (gameObject2 == null) { obj2 = null; } else { ShiftStone componentInChildren2 = gameObject2.GetComponentInChildren<ShiftStone>(true); obj2 = ((componentInChildren2 != null) ? ((Component)componentInChildren2).gameObject : null); } } } Object.Destroy((Object)obj2); foreach (Renderer componentsInChild in Visuals.GetComponentsInChildren<Renderer>()) { if (((Object)componentsInChild).name == "FadeScreenRenderer") { Object.Destroy((Object)(object)((Component)componentsInChild).gameObject); continue; } componentsInChild.shadowCastingMode = (ShadowCastingMode)0; componentsInChild.sharedMaterial = Core.PoseGhostMat; ((Component)componentsInChild).gameObject.layer = 0; } for (int num = child.childCount - 1; num > 0; num--) { Transform child4 = child.GetChild(num); if (((Object)child4).name.Contains("VFX")) { ((Component)child4).gameObject.SetActive(false); } } foreach (Collider componentsInChild2 in Visuals.GetComponentsInChildren<Collider>()) { componentsInChild2.enabled = false; } HelperFunctions.DisableAllComponents(Visuals, new List<Behaviour> { (Behaviour)(object)this, (Behaviour)(object)Visuals.GetComponent<RigDefinition>() }); Transform child5 = Visuals.transform.GetChild(2); Object.Destroy((Object)(object)((child5 != null) ? ((Component)child5).gameObject : null)); RigDefinition component = Visuals.GetComponent<RigDefinition>(); BoneTransforms.AddRange(((IEnumerable<BoneDefinition>)component.BoneDefinitions).Select((BoneDefinition b) => b.Transform).ToArray()); Head = component.HeadDefinition.Transform; SMR = Visuals.GetComponentInChildren<SkinnedMeshRenderer>(); } public void ReapplyVisuals() { if (!((Object)(object)Visuals == (Object)null)) { SkinnedMeshRenderer componentInChildren = Visuals.GetComponentInChildren<SkinnedMeshRenderer>(); SkinnedMeshRenderer componentInChildren2 = ((Component)((Component)ParentController).transform.GetChild(1)).GetComponentInChildren<SkinnedMeshRenderer>(); componentInChildren.sharedMesh = componentInChildren2.sharedMesh; } } } [HarmonyPatch(typeof(DressingRoom), "DelayedApplyData", new Type[] { typeof(GeneratedPlayerVisuals) })] public static class dressingRoomPatch { private static void Postfix() { foreach (Laggard laggard in Core.Laggards) { if ((Object)(object)laggard.ParentController == (Object)(object)Singleton<PlayerManager>.Instance.LocalPlayer.Controller) { laggard.ReapplyVisuals(); } } } } public static class VoidLandSupport { public static void SetUp() { main.AddNameToDontDisable("PingVisualizer"); } } }