Beispiel #1
0
        public static void DumpTypesUsedBy(this MethodBase methodBase)
        {
            if (methodBase == null)
            {
                return;
            }

            MelonLogger.Msg("Types used by method: " + methodBase.Name);
            HashSet <string> usedTypes = new HashSet <string>();

            foreach (XrefInstance instance in XrefScanner.UsedBy(methodBase))
            {
                if (instance.Type == XrefType.Method)
                {
                    var resolved = instance.TryResolve();
                    if (resolved == null)
                    {
                        continue;
                    }
                    if (usedTypes.Contains(resolved.DeclaringType?.ToString()))
                    {
                        continue;
                    }
                    usedTypes.Add(resolved.DeclaringType?.ToString());
                    MelonLogger.Msg(resolved.DeclaringType?.ToString());
                }
            }
        }
        public static void ReloadAllAvatars(bool excludeSelf)
        {
            // xref yoinked from https://github.com/loukylor/VRC-Mods/commit/11abd2a62caaae5d0f817e20a0f6852d632da6bb#diff-ba8a2891e08655e0e158ea852ef76bbcb1ea58fc831a6817875c5efa21fef610R84 (GPLv3)
            if (ourReloadAllAvatarsDelegate == null)
            {
                var targetMethod = typeof(VRCPlayer).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                   .Single(it => it.Name.StartsWith("Method_Public_Void_Boolean_") && it.GetParameters().Length == 1 &&
                                           it.GetParameters()[0].IsOptional && XrefScanner.UsedBy(it).Any(jt =>
                {
                    if (jt.Type != XrefType.Method)
                    {
                        return(false);
                    }
                    var m = jt.TryResolve();
                    if (m == null)
                    {
                        return(false);
                    }
                    return(m.DeclaringType == typeof(FeaturePermissionManager) &&
                           m.Name.StartsWith("Method_Public_Void_"));
                }));
                ourReloadAllAvatarsDelegate = (Action <VRCPlayer, bool>)Delegate.CreateDelegate(typeof(Action <VRCPlayer, bool>), targetMethod);
            }

            ourReloadAllAvatarsDelegate(VRCPlayer.field_Internal_Static_VRCPlayer_0, excludeSelf);
        }
Beispiel #3
0
        internal static bool PatchMethods()
        {
            try
            {
                // Left room
                MethodInfo onLeftRoomMethod = typeof(NetworkManager).GetMethod(
                    nameof(NetworkManager.OnLeftRoom),
                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
                    null,
                    Type.EmptyTypes,
                    null);
                origOnLeftRoom = Patch <OnLeftRoom>(onLeftRoomMethod, GetDetour(nameof(OnLeftRoomPatch)));
            }
            catch (Exception e)
            {
                MelonLogger.Error("Failed to patch OnLeftRoom\n" + e.Message);
                return(false);
            }

            try
            {
                // Faded to and joined and initialized room
                MethodInfo fadeMethod = typeof(VRCUiManager).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).First(
                    m => m.Name.StartsWith("Method_Public_Void_String_Single_Action_") &&
                    m.Name.IndexOf("PDM", StringComparison.OrdinalIgnoreCase) == -1 &&
                    m.GetParameters().Length == 3);
                origFadeTo = Patch <FadeTo>(fadeMethod, GetDetour(nameof(FadeToPatch)));
            }
            catch (Exception e)
            {
                MelonLogger.Error("Failed to patch FadeTo\n" + e.Message);
                return(false);
            }

            if (Utilities.IsInVR)
            {
                try
                {
                    // Fixes spinning issue
                    // TL;DR Prevents the tracking manager from applying rotational force
                    MethodInfo applyPlayerMotionMethod = typeof(VRCTrackingManager).GetMethods(BindingFlags.Public | BindingFlags.Static)
                                                         .Where(
                        m => m.Name.StartsWith("Method_Public_Static_Void_Vector3_Quaternion") &&
                        !m.Name.Contains("_PDM_")).First(
                        m => XrefScanner.UsedBy(m).Any(
                            xrefInstance => xrefInstance.Type == XrefType.Method &&
                            xrefInstance.TryResolve()?.ReflectedType
                            ?.Equals(typeof(VRC_StationInternal))
                            == true));
                    origApplyPlayerMotion = Patch <ApplyPlayerMotion>(applyPlayerMotionMethod, GetDetour(nameof(ApplyPlayerMotionPatch)));
                }
                catch (Exception e)
                {
                    MelonLogger.Error("Failed to patch ApplyPlayerMotion\n" + e.Message);
                    return(false);
                }
            }

            return(true);
        }
Beispiel #4
0
 public static bool CheckUsed(MethodInfo method, string methodName)
 {
     try
     {
         return(XrefScanner.UsedBy(method)
                .Where(instance => instance.TryResolve() != null && instance.TryResolve().Name.Contains(methodName)).Any());
     }
     catch { }
     return(false);
 }
Beispiel #5
0
 /// <summary>
 /// Checks the methods the given method is used by.
 /// Note: the methods passed into the predicate may be false.
 /// </summary>
 /// <param name="method">The method to check</param>
 /// <param name="predicate">The predicate to check the methods against</param>
 /// <returns>true if the predicate returned true any times, otherwise false</returns>
 public static bool CheckUsedBy(MethodBase method, Func <MethodBase, bool> predicate)
 {
     foreach (XrefInstance instance in XrefScanner.UsedBy(method))
     {
         if (instance.Type == XrefType.Method && predicate.Invoke(instance.TryResolve()))
         {
             return(true);
         }
     }
     return(false);
 }
Beispiel #6
0
        internal static void Patch(HarmonyInstance harmonyInstance)
        {
            try
            {
                // Left room
                harmonyInstance.Patch(
                    typeof(NetworkManager).GetMethod(nameof(NetworkManager.OnLeftRoom), BindingFlags.Public | BindingFlags.Instance),
                    postfix: GetPatch(nameof(LeftWorldPatch)));
            }
            catch (Exception e)
            {
                MelonLogger.Error("Failed to patch OnLeftRoom\n" + e.Message);
            }

            try
            {
                // Faded to and joined and initialized room
                IEnumerable <MethodInfo> fadeMethods = typeof(VRCUiManager).GetMethods()
                                                       .Where(
                    m => m.Name.StartsWith("Method_Public_Void_String_Single_Action_") &&
                    m.GetParameters().Length == 3);
                foreach (MethodInfo fadeMethod in fadeMethods)
                {
                    harmonyInstance.Patch(fadeMethod, postfix: GetPatch(nameof(JoinedRoomPatch)));
                }
            }
            catch (Exception e)
            {
                MelonLogger.Error("Failed to patch FadeTo Initialized room\n" + e.Message);
            }

            if (Utilities.IsInVR)
            {
                try
                {
                    // Fixes spinning issue
                    // TL;DR Prevents the tracking manager from applying rotational force
                    harmonyInstance.Patch(
                        typeof(VRCTrackingManager).GetMethods(BindingFlags.Public | BindingFlags.Static)
                        .Where(m => m.Name.StartsWith("Method_Public_Static_Void_Vector3_Quaternion") && !m.Name.Contains("_PDM_"))
                        .First(
                            m => XrefScanner.UsedBy(m).Any(
                                xrefInstance => xrefInstance.Type == XrefType.Method &&
                                xrefInstance.TryResolve()?.ReflectedType?.Equals(typeof(VRC_StationInternal))
                                == true)),
                        GetPatch(nameof(ApplyPlayerMotionPatch)));
                }
                catch (Exception e)
                {
                    MelonLogger.Error("Failed to patch ApplyPlayerMotion\n" + e.Message);
                }
            }
        }
Beispiel #7
0
        public static void ScanMethod(MethodInfo m)
        {
            MelonLogger.Msg($"Scanning: {m.FullDescription()}");
            foreach (var instance in XrefScanner.XrefScan(m))
            {
                try
                {
                    if (instance.Type == XrefType.Global && instance.ReadAsObject() != null)
                    {
                        try
                        {
                            MelonLogger.Msg($"   Found String: {instance.ReadAsObject().ToString()}");
                        }
                        catch
                        {
                        }
                    }
                    else if (instance.Type == XrefType.Method && instance.TryResolve() != null)
                    {
                        try
                        {
                            MelonLogger.Msg($"   Found Method: {instance.TryResolve().FullDescription()}");
                        }
                        catch
                        {
                        }
                    }
                }
                catch
                {
                }
            }

            foreach (var instance in XrefScanner.UsedBy(m))
            {
                try
                {
                    if (instance.Type == XrefType.Method && instance.TryResolve() != null)
                    {
                        try
                        {
                            MelonLogger.Msg($"   Found Used By Method: {instance.TryResolve().FullDescription()}");
                        }
                        catch
                        {
                        }
                    }
                }
                catch
                {
                }
            }
        }
Beispiel #8
0
 private static bool CheckUsed(MethodBase methodBase, string methodName)
 {
     if (!string.IsNullOrEmpty(methodName))
     {
         try
         {
             return(XrefScanner.UsedBy(methodBase)
                    .Where(instance => instance.TryResolve() != null && instance.TryResolve().Name.Contains(methodName)).Any());
         }
         catch (Exception e)
         {
             MelonLogger.Error($"Failed to Xref CheckUsed:\n{e}");
         }
     }
     return(false);
 }
Beispiel #9
0
        /// <summary>
        /// Dumps the Xref information on a method.
        /// This is for DEBUG PURPOSES ONLY.
        /// </summary>
        /// <param name="method">The method to dump information on</param>
        public static void DumpXrefInfo(MethodBase method)
        {
            try
            {
                MelonLogger.Msg(ConsoleColor.Yellow, $"Scanning {method.Name}");

                MelonLogger.Msg(ConsoleColor.Yellow, $"Checking UsedBy");
                DumpScan(XrefScanner.UsedBy(method));

                MelonLogger.Msg(ConsoleColor.Green, "Checking Using");
                DumpScan(XrefScanner.XrefScan(method));
            }
            catch (Exception ex)
            {
                MelonLogger.Error($"Failed while dumping {method.Name}:\n{ex}");
            }
        }
Beispiel #10
0
        public static void HookVrIkInit(HarmonyInstance harmony)
        {
            var vrikInitMethod = typeof(VRCVrIkController).GetMethod(nameof(VRCVrIkController
                                                                            .Method_Public_Virtual_Final_New_Boolean_VRC_AnimationController_Animator_VRCPlayer_Boolean_0));

            harmony.Patch(vrikInitMethod,
                          postfix: new HarmonyMethod(AccessTools.Method(typeof(VrIkHandling), nameof(VrikInitPatch))));

            var methodThatChecksHipTracking = typeof(VRCVrIkController)
                                              .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Single(it =>
                                                                                                                                          XrefScanner.XrefScan(it).Any(jt =>
                                                                                                                                                                       jt.Type == XrefType.Global && "Hip Tracking: Hip tracker found. tracking enabled." ==
                                                                                                                                                                       jt.ReadAsObject()?.ToString()));

            var canSupportHipTrackingCandidates = XrefScanner.XrefScan(methodThatChecksHipTracking).Where(it =>
            {
                if (it.Type != XrefType.Method)
                {
                    return(false);
                }
                var resolved = it.TryResolve();
                if (resolved == null || !resolved.IsStatic)
                {
                    return(false);
                }
                if (!(resolved.DeclaringType == typeof(VRCTrackingManager) && resolved is MethodInfo mi && mi.ReturnType == typeof(bool) && resolved.GetParameters().Length == 0))
                {
                    return(false);
                }
                return(XrefScanner.UsedBy(resolved).Any(jt =>
                                                        jt.Type == XrefType.Method && jt.TryResolve().DeclaringType == typeof(QuickMenu)));
            }).ToList();

            var canSupportHipTracking = canSupportHipTrackingCandidates.Single().TryResolve();

            harmony.Patch(canSupportHipTracking, new HarmonyMethod(AccessTools.Method(typeof(VrIkHandling), nameof(SupportsHipTrackingPatch))));
        }
Beispiel #11
0
        static MethodInfo ms_applyStoredCalibration = null; // IKTweaks

        public static void ResolveMethods()
        {
            // void VRCTrackingManager.PrepareForCalibration()
            if (ms_prepareForCalibration == null)
            {
                var l_methods = typeof(VRCTrackingManager).GetMethods().Where(m =>
                                                                              m.Name.StartsWith("Method_Public_Static_Void_") && (m.ReturnType == typeof(void)) && !m.GetParameters().Any() &&
                                                                              XrefScanner.XrefScan(m).Where(x => (x.Type == XrefType.Global) && x.ReadAsObject().ToString().Contains("trying to calibrate")).Any() &&
                                                                              XrefScanner.UsedBy(m).Where(x => (x.Type == XrefType.Method) && (x.TryResolve()?.DeclaringType == typeof(VRCFbbIkController))).Any()
                                                                              );

                if (l_methods.Any())
                {
                    ms_prepareForCalibration = l_methods.First();
                    Main.Logger.Msg("VRCTrackingManager.PrepareForCalibration -> VRCTrackingManager." + ms_prepareForCalibration.Name);
                }
                else
                {
                    Main.Logger.Warning("Can't resolve VRCTrackingManager.PrepareForCalibration");
                }
            }

            // void VRCTracking.RestoreTrackingAfterCalibration()
            if (ms_restoreTrackingAfterCalibration == null)
            {
                var l_methods = typeof(VRCTrackingManager).GetMethods().Where(m =>
                                                                              m.Name.StartsWith("Method_Public_Static_Void_") && (m.Name != ms_prepareForCalibration?.Name) && (m.ReturnType == typeof(void)) && !m.GetParameters().Any() &&
                                                                              XrefScanner.UsedBy(m).Where(x => (x.Type == XrefType.Method) && (x.TryResolve()?.DeclaringType == typeof(VRCFbbIkController))).Any()
                                                                              );

                if (l_methods.Any())
                {
                    ms_restoreTrackingAfterCalibration = l_methods.First();
                    Main.Logger.Msg("VRCTrackingManager.RestoreTrackingAfterCalibration -> VRCTrackingManager." + ms_restoreTrackingAfterCalibration.Name);
                }
                else
                {
                    Main.Logger.Warning("Can't resolve VRCTrackingManager.RestoreTrackingAfterCalibration");
                }
            }

            // void IKTweaks.CalibrationManager.Calibrate(GameObject avatarRoot)
            if (ms_calibrate == null)
            {
                foreach (MelonLoader.MelonMod l_mod in MelonLoader.MelonHandler.Mods)
                {
                    if (l_mod.Info.Name == "IKTweaks")
                    {
                        Type l_cbType = null;
                        l_mod.Assembly.GetTypes().DoIf(t => t.Name == "CalibrationManager", t => l_cbType = t);
                        if (l_cbType != null)
                        {
                            ms_calibrate = l_cbType.GetMethod("Calibrate");
                            Main.Logger.Msg("IKTweaks.CalibrationManager.Calibrate " + ((ms_calibrate != null) ? "found" : "not found"));
                        }
                        break;
                    }
                }
            }

            // Task IKTweaks.CalibrationManager.ApplyStoredCalibration(GameObject avatarRoot, string avatarId)
            if (ms_applyStoredCalibration == null)
            {
                foreach (MelonLoader.MelonMod l_mod in MelonLoader.MelonHandler.Mods)
                {
                    if (l_mod.Info.Name == "IKTweaks")
                    {
                        Type l_cbType = null;
                        l_mod.Assembly.GetTypes().DoIf(t => t.Name == "CalibrationManager", t => l_cbType = t);
                        if (l_cbType != null)
                        {
                            ms_applyStoredCalibration = l_cbType.GetMethod("ApplyStoredCalibration", BindingFlags.NonPublic | BindingFlags.Static);
                            Main.Logger.Msg("IKTweaks.CalibrationManager.ApplyStoredCalibration " + ((ms_applyStoredCalibration != null) ? "found" : "not found"));
                        }
                        break;
                    }
                }
            }
        }
Beispiel #12
0
        private static Transform GetTrackedTransform(VRCTracking.ID id)
        {
            ourGetTrackedTransform ??= (Func <VRCTracking.ID, Transform>)Delegate.CreateDelegate(
                typeof(Func <VRCTracking.ID, Transform>), typeof(VRCTrackingManager)
                .GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).Single(it =>
                                                                                                          it.Name.StartsWith("Method_Public_Static_Transform_ID_") && XrefScanner.UsedBy(it)
                                                                                                          .Any(
                                                                                                              jt =>
            {
                var mr = jt.TryResolve();
                return(mr?.DeclaringType == typeof(PedalOption_HudPosition) && mr.Name == "Update");
            })));

            return(ourGetTrackedTransform(id));
        }