public static bool HasMethodCallWithName(this MethodInfo m, string txt) { foreach (var instance in XrefScanner.XrefScan(m)) { try { if (instance.Type == XrefType.Method && instance.TryResolve() != null) { try { if (instance.TryResolve().Name.Contains(txt)) { return(true); } } catch (Exception e) { MelonLogger.Warning(e); } } } catch { } } return(false); }
internal static void XrefDump(this MethodBase methodBase) { MelonLogger.Msg("Scanning Method: " + methodBase.Name); foreach (XrefInstance instance in XrefScanner.XrefScan(methodBase)) { switch (instance.Type) { case XrefType.Global: MelonLogger.Msg($"\tGlobal Instance: {instance.ReadAsObject()?.ToString()}"); break; case XrefType.Method: var resolved = instance.TryResolve(); if (resolved == null) { MelonLogger.Msg("\tNull Method Instance"); } else { MelonLogger.Msg($"\tMethod Instance: {resolved.DeclaringType?.Name} {resolved.Name}"); } break; default: break; } } MelonLogger.Msg(""); }
public static bool HasMethodWithDeclaringType(this MethodInfo m, Type declaringType) { foreach (var instance in XrefScanner.XrefScan(m)) { try { if (instance.Type == XrefType.Method && instance.TryResolve() != null) { try { if (declaringType == instance.TryResolve().DeclaringType) { return(true); } } catch (Exception e) { MelonLogger.Warning(e); } } } catch { } } return(false); }
public static void Refresh(this SimpleAvatarPedestal pedestal, ApiAvatar avatar) { if (ourPedestalRefreshDelegate == null) { var target = typeof(SimpleAvatarPedestal) .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Single( it => { if (it.ReturnType != typeof(void)) { return(false); } var parameters = it.GetParameters(); if (parameters.Length != 1 || parameters[0].ParameterType != typeof(ApiAvatar)) { return(false); } return(XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "local")); }); ourPedestalRefreshDelegate = (PedestalRefreshDelegate)Delegate.CreateDelegate(typeof(PedestalRefreshDelegate), target); } ourPedestalRefreshDelegate(pedestal, avatar); }
public override void OnApplicationStart() { MelonPrefs.RegisterCategory(SettingsCategory, "Friends+ Home"); MelonPrefs.RegisterString(SettingsCategory, SettingStartupName, nameof(ApiWorldInstance.AccessType.FriendsOfGuests), "Startup instance type"); MelonPrefs.RegisterString(SettingsCategory, SettingButtonName, nameof(ApiWorldInstance.AccessType.FriendsOfGuests), "\"Go Home\" instance type"); if (MelonHandler.Mods.Any(it => it.Info.Name == "UI Expansion Kit" && !it.Info.Version.StartsWith("0.1."))) { RegisterUix2Extension(); } foreach (var methodInfo in typeof(VRCFlowManagerVRC).GetMethods()) { if (methodInfo.ReturnType != typeof(void) || methodInfo.GetParameters().Length != 0) { continue; } if (!XrefScanner.XrefScan(methodInfo).Any(it => it.Type == XrefType.Global && it.ReadAsObject()?.ToString() == "Going to Home Location: ")) { continue; } MelonLogger.Log($"Patched {methodInfo.Name}"); harmonyInstance.Patch(methodInfo, postfix: new HarmonyMethod(AccessTools.Method(typeof(FriendsPlusHomeMod), nameof(GoHomePatch)))); } }
public static void DisplayErrorAvatar(this SimpleAvatarPedestal @this) { if (ourDisplayErrorAvatarDelegate == null) { var target = typeof(SimpleAvatarPedestal) .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance).Single( it => { if (it.ReturnType != typeof(void) || it.Name.Contains("_PDM_")) { return(false); } var parameters = it.GetParameters(); if (parameters.Length != 0) { return(false); } return(XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "local")); }); ourDisplayErrorAvatarDelegate = (DisplayErrorAvatarDelegate)Delegate.CreateDelegate(typeof(DisplayErrorAvatarDelegate), target); } ourDisplayErrorAvatarDelegate(@this); }
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 canSupportHipTracking = XrefScanner.XrefScan(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()))).Single(it => { if (it.Type != XrefType.Method) { return(false); } var resolved = it.TryResolve(); if (resolved == null || !resolved.IsStatic) { return(false); } return(resolved.DeclaringType == typeof(VRCTrackingManager) && resolved is MethodInfo mi && mi.ReturnType == typeof(bool) && resolved.GetParameters().Length == 0); }).TryResolve(); harmony.Patch(canSupportHipTracking, new HarmonyMethod(AccessTools.Method(typeof(VrIkHandling), nameof(SupportsHipTrackingPatch)))); }
internal static void HookFullBodyController(HarmonyInstance harmony) { var fbbIkInit = typeof(VRCFbbIkController).GetMethod(nameof(VRCFbbIkController.Method_Public_Virtual_Final_New_Boolean_VRC_AnimationController_Animator_VRCPlayer_Boolean_0)); harmony.Patch(fbbIkInit, new HarmonyMethod(typeof(FullBodyHandling), nameof(FbbIkInitPrefix)), new HarmonyMethod(typeof(FullBodyHandling), nameof(FbbIkInitPostfix))); harmony.Patch(AccessTools.Method(typeof(FullBodyBipedIK), nameof(FullBodyBipedIK.LateUpdate)), new HarmonyMethod(typeof(FullBodyHandling), nameof(LateUpdatePrefix))); harmony.Patch(AccessTools.Method(typeof(FullBodyBipedIK), nameof(FullBodyBipedIK.Update)), new HarmonyMethod(typeof(FullBodyHandling), nameof(UpdatePrefix))); harmony.Patch(AccessTools.Method(typeof(FullBodyBipedIK), nameof(FullBodyBipedIK.FixedUpdate)), new HarmonyMethod(typeof(FullBodyHandling), nameof(FixedUpdatePrefix))); harmony.Patch(AccessTools.Method(typeof(VRCTrackingManager), nameof(VRCTrackingManager.Method_Public_Static_Boolean_String_0)), new HarmonyMethod(typeof(FullBodyHandling), nameof(IsCalibratedForAvatarPrefix))); var userOfHfts = typeof(VRCFbbIkController) .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Single(it => XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "Hip+Feet Tracking: 3 trackers found, tracking enabled.")); var hipAndFeetTrackingSupported = (MethodInfo)XrefScanner.XrefScan(userOfHfts).Single(it => { if (it.Type != XrefType.Method) { return(false); } var resolved = it.TryResolve() as MethodInfo; return(resolved != null && resolved.DeclaringType == typeof(VRCTrackingManager) && resolved.IsStatic && resolved.GetParameters().Length == 0 && resolved.ReturnType == typeof(bool)); }).TryResolve(); harmony.Patch(hipAndFeetTrackingSupported, new HarmonyMethod(typeof(FullBodyHandling), nameof(PatchHipAndFeetTracking))); ourIsFbtSupported = (Func <bool>)Delegate.CreateDelegate(typeof(Func <bool>), hipAndFeetTrackingSupported); }
public override void OnApplicationStart() { var category = MelonPreferences.CreateCategory(SettingsCategory, "Friends+ Home"); StartupName = category.CreateEntry(SettingStartupName, nameof(InstanceAccessType.FriendsOfGuests), "Startup instance type"); ButtonName = category.CreateEntry(SettingButtonName, nameof(InstanceAccessType.FriendsOfGuests), "\"Go Home\" instance type"); if (MelonHandler.Mods.Any(it => it.Info.Name == "UI Expansion Kit" && !it.Info.Version.StartsWith("0.1."))) { RegisterUix2Extension(); } foreach (var methodInfo in typeof(VRCFlowManager).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) { if (methodInfo.ReturnType != typeof(void) || methodInfo.GetParameters().Length != 0) { continue; } if (!XrefScanner.XrefScan(methodInfo).Any(it => it.Type == XrefType.Global && it.ReadAsObject()?.ToString() == "Going to Home Location: ")) { continue; } MelonLogger.Msg($"Patched {methodInfo.Name}"); HarmonyInstance.Patch(methodInfo, postfix: new HarmonyMethod(AccessTools.Method(typeof(FriendsPlusHomeMod), nameof(GoHomePatch)))); } DoAfterUiManagerInit(OnUiManagerInit); }
public static bool SameClassMethodCallCount(this MethodInfo m, int calls) { var count = 0; foreach (var instance in XrefScanner.XrefScan(m)) { try { if (instance.Type == XrefType.Method && instance.TryResolve() != null) { try { if (m.DeclaringType == instance.TryResolve().DeclaringType) { count++; } } catch (Exception e) { MelonLogger.Warning(e); } } } catch { } } return(count == calls); }
// Yoinked with love from https://github.com/BenjaminZehowlt/DynamicBonesSafety/blob/master/DynamicBonesSafetyMod.cs // or well, the current alternative https://github.com/loukylor/VRC-Mods/blob/main/PlayerList/Utilities/Xref.cs public static bool CheckMethod(MethodInfo method, string match) { try { return(XrefScanner.XrefScan(method) .Where(instance => instance.Type == XrefType.Global && instance.ReadAsObject().ToString().Contains(match)).Any()); } catch { } return(false); }
/// <summary> /// Checks the methods the given method uses. /// 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 CheckUsing(MethodBase method, Func <MethodBase, bool> predicate) { foreach (XrefInstance instance in XrefScanner.XrefScan(method)) { if (instance.Type == XrefType.Method && predicate.Invoke(instance.TryResolve())) { return(true); } } return(false); }
/// <summary> /// Checks the strings in the given method's body. /// </summary> /// <param name="method">The method to check</param> /// <param name="predicate">The predicate to check the strings against</param> /// <returns>true if the predicate returned true any times, otherwise false</returns> public static bool CheckStrings(MethodInfo method, Func <string, bool> predicate) { foreach (XrefInstance instance in XrefScanner.XrefScan(method)) { if (instance.Type == XrefType.Global && predicate.Invoke(instance.ReadAsObject().ToString())) { return(true); } } return(false); }
private static bool checkXref(MethodBase m, string match) { try { return(XrefScanner.XrefScan(m).Any( instance => instance.Type == XrefType.Global && instance.ReadAsObject() != null && instance.ReadAsObject().ToString() .Equals(match, StringComparison.OrdinalIgnoreCase))); } catch { } // ignored return(false); }
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 { } } }
/// <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}"); } }
private static bool checkXrefNoStrings(MethodBase m) { try { foreach (XrefInstance instance in XrefScanner.XrefScan(m)) { if (instance.Type != XrefType.Global || instance.ReadAsObject() == null) { continue; } return(false); } return(true); } catch (Exception e) { MelonLogger.Log("For loop failed:" + e); } return(false); }
public static bool CheckXrefStrings(MethodBase m, List <string> keywords) { try { foreach (string keyword in keywords) { if (!XrefScanner.XrefScan(m).Any( instance => instance.Type == XrefType.Global && instance.ReadAsObject() != null && instance.ReadAsObject().ToString() .Equals(keyword, StringComparison.OrdinalIgnoreCase))) { return(false); } } return(true); } catch { } return(false); }
public static bool HasStringLiterals(this MethodInfo m) { foreach (var instance in XrefScanner.XrefScan(m)) { try { if (instance.Type == XrefType.Global && instance.ReadAsObject() != null) { return(true); } } catch { } } return(false); }
public static bool CheckUsing(MethodInfo method, string match, Type type) { foreach (XrefInstance instance in XrefScanner.XrefScan(method)) { if (instance.Type == XrefType.Method) { try { if (instance.TryResolve().DeclaringType == type && instance.TryResolve().Name.Contains(match)) { return(true); } } catch { } } } return(false); }
public static bool CheckStringsCount(this MethodInfo m, int count) { var total = 0; foreach (var instance in XrefScanner.XrefScan(m)) { try { if (instance.Type == XrefType.Global && instance.ReadAsObject() != null) { total++; } } catch { } } return(total == count); }
private static bool XRefScanForMethod(this MethodBase methodBase, string methodName = null, string reflectedType = null) { var found = false; foreach (XrefInstance xref in XrefScanner.XrefScan(methodBase)) { if (xref.Type != XrefType.Method) { continue; } MethodBase resolved = xref.TryResolve(); if (resolved == null) { continue; } if (!string.IsNullOrEmpty(methodName)) { found = !string.IsNullOrEmpty(resolved.Name) && resolved.Name.IndexOf(methodName, StringComparison.OrdinalIgnoreCase) >= 0; } if (!string.IsNullOrEmpty(reflectedType)) { found = !string.IsNullOrEmpty(resolved.ReflectedType?.Name) && resolved.ReflectedType.Name.IndexOf(reflectedType, StringComparison.OrdinalIgnoreCase) >= 0; } if (found) { return(true); } } return(false); }
public override void OnApplicationStart() { AdvancedSafetySettings.RegisterSettings(); var matchingMethods = typeof(AssetManagement) .GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly).Where(it => it.Name.StartsWith("Method_Public_Static_Object_Object_Vector3_Quaternion_Boolean_Boolean_Boolean_") && it.GetParameters().Length == 6).ToList(); MethodBase patchTarget = null; foreach (var methodInfo in typeof(AssetManagement).GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) { foreach (var it in XrefScanner.XrefScan(methodInfo)) { if (it.Type != XrefType.Method) { continue; } var methodBase = it.TryResolve(); if (methodBase == null) { continue; } if (matchingMethods.Contains(methodBase)) { patchTarget = methodBase; goto haveTarget; } } } haveTarget: if (patchTarget != null) { unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(patchTarget).GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(ObjectInstantiatePatch), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourOriginalInstantiate = Marshal.GetDelegateForFunctionPointer <ObjectInstantiateDelegate>(originalMethodPointer); } } else { MelonLogger.LogError("Patch target for object instantiation not found, avatar filtering will not work"); } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumA).GetMethod( nameof(AMEnumA.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchA), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextA = originalMethodPointer; } unsafe { var originalMethodPointer = *(IntPtr *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); Imports.Hook((IntPtr)(&originalMethodPointer), typeof(AdvancedSafetyMod).GetMethod(nameof(MoveNextPatchB), BindingFlags.Static | BindingFlags.NonPublic) !.MethodHandle.GetFunctionPointer()); ourMoveNextB = originalMethodPointer; } unsafe { var originalMethodInfo = (Il2CppMethodInfo *)(IntPtr)UnhollowerUtils .GetIl2CppMethodInfoPointerFieldForGeneratedMethod(typeof(AMEnumB).GetMethod( nameof(AMEnumB.MoveNext))) .GetValue(null); var methodInfoCopy = (Il2CppMethodInfo *)Marshal.AllocHGlobal(Marshal.SizeOf <Il2CppMethodInfo>()); * methodInfoCopy = *originalMethodInfo; ourInvokeMethodInfo = (IntPtr)methodInfoCopy; } PortalHiding.OnApplicationStart(); AvatarHiding.OnApplicationStart(); if (MelonHandler.Mods.Any(it => it.Info.SystemType.Name == nameof(UiExpansionKitMod))) { typeof(UiExpansionKitSupport).GetMethod(nameof(UiExpansionKitSupport.OnApplicationStart), BindingFlags.Static | BindingFlags.Public) !.Invoke(null, new object[0]); } }
//Gracefully taken from Advanced Invites https://github.com/Psychloor/AdvancedInvites/blob/master/AdvancedInvites/Utilities.cs#L356 public static bool XRefScanFor(this MethodBase methodBase, string searchTerm) { return(XrefScanner.XrefScan(methodBase).Any( xref => xref.Type == XrefType.Global && xref.ReadAsObject()?.ToString().IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 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; } } } }
public override void OnApplicationStart() { var cat = MelonPreferences.CreateCategory("ogtrustranks", "OGTrustRanks"); _enabledPref = cat.CreateEntry("enabled", true, "Enabled"); _knownColorRPref = cat.CreateEntry("KnownColorR", 255, "Red component of the Known color"); _knownColorGPref = cat.CreateEntry("KnownColorG", 122, "Green component of the Known color"); _knownColorBPref = cat.CreateEntry("KnownColorB", 66, "Blue component of the Known color"); _trustedColorRPref = cat.CreateEntry("TrustedColorR", 130, "Red component of the Trusted color"); _trustedColorGPref = cat.CreateEntry("TrustedColorG", 66, "Green component of the Trusted color"); _trustedColorBPref = cat.CreateEntry("TrustedColorB", 230, "Blue component of the Trusted color"); _veteranColorRPref = cat.CreateEntry("VeteranColorR", 171, "Red component of the Veteran color"); _veteranColorGPref = cat.CreateEntry("VeteranColorG", 205, "Green component of the Veteran color"); _veteranColorBPref = cat.CreateEntry("VeteranColorB", 239, "Blue component of the Veteran color"); _legendaryColorRPref = cat.CreateEntry("LegendaryColorR", 255, "Red component of the Legendary color"); _legendaryColorGPref = cat.CreateEntry("LegendaryColorG", 105, "Green component of the Legendary color"); _legendaryColorBPref = cat.CreateEntry("LegendaryColorB", 180, "Blue component of the Legendary color"); _reloadAvatar = cat.CreateEntry("ReloadAvatar", false, "Reload avatars when fetched rank to update colors for BTKANameplateMod"); UpdateColors(); var harmony = new HarmonyLib.Harmony("OGTrustRanks"); foreach (var method in typeof(VRCPlayer).GetMethods()) { if (!method.Name.StartsWith("Method_Public_Static_String_APIUser_") || method.Name.Length != 37) { continue; } if (_showSocialRankMethod == null) { var xrefInstance = XrefScanner.XrefScan(method).FirstOrDefault(x => { if (x.Type != XrefType.Method) { return(false); } var m = x.TryResolve(); if (m == null || !m.IsStatic || m.DeclaringType != typeof(VRCPlayer)) { return(false); } var asInfo = m as MethodInfo; if (asInfo == null || asInfo.ReturnType != typeof(bool)) { return(false); } if (m.GetParameters().Length != 1 && m.GetParameters()[0].ParameterType != typeof(APIUser)) { return(false); } return(XrefScanner.XrefScan(m).Count() > 1); }); if (xrefInstance.Type == XrefType.Method) { _showSocialRankMethod = xrefInstance.TryResolve(); } } harmony.Patch(method, new HarmonyMethod(typeof(OGTrustRanks).GetMethod(nameof(GetFriendlyDetailedNameForSocialRank), BindingFlags.NonPublic | BindingFlags.Static))); } var colorForRankTargetMethods = typeof(VRCPlayer).GetMethods().Where(it => it.ReturnType.ToString().Equals("UnityEngine.Color") && it.GetParameters().Length == 1 && it.GetParameters()[0].ParameterType.ToString().Equals("VRC.Core.APIUser")).ToList(); colorForRankTargetMethods.ForEach(it => harmony.Patch(it, new HarmonyMethod(typeof(OGTrustRanks).GetMethod(nameof(GetColorForSocialRank), BindingFlags.NonPublic | BindingFlags.Static))) ); // Thanks loukylor _reloadAvatarMethod = typeof(VRCPlayer).GetMethods().First(mi => mi.Name.StartsWith("Method_Private_Void_Boolean_") && mi.Name.Length < 31 && mi.GetParameters().Any(pi => pi.IsOptional)); MelonCoroutines.Start(InitializeNetworkHooks()); MelonCoroutines.Start(FetchAPIUsers()); }
private static void SetTrackerVisibility(bool visible) { if (ourSetVisibilityDelegate == null) { var method = typeof(VRCTrackingSteam) .GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Single(it => it.ReturnType == typeof(void) && it.GetParameters().Length == 1 && it.GetParameters()[0].ParameterType == typeof(bool) && XrefScanner.XrefScan(it) .Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "Model")); ourSetVisibilityDelegate = (Action <VRCTrackingSteam, bool>)Delegate.CreateDelegate(typeof(Action <VRCTrackingSteam, bool>), method); } foreach (var vrcTracking in VRCTrackingManager.field_Private_Static_VRCTrackingManager_0.field_Private_List_1_VRCTracking_0) { var vrcTrackingSteam = vrcTracking.TryCast <VRCTrackingSteam>(); if (vrcTrackingSteam == null) { continue; } ourSetVisibilityDelegate(vrcTrackingSteam, visible); return; } }
public static void DisplayWorldInfoPage(ApiWorld world) { if (ourShowWorldInfoPageDelegate == null) { var target = typeof(UiWorldList) .GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static).Single(it => it.Name.StartsWith("Method_Public_Static_Void_ApiWorld") && XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "UserInterface/MenuContent/Screens/WorldInfo")); ourShowWorldInfoPageDelegate = (Action <ApiWorld>)Delegate.CreateDelegate(typeof(Action <ApiWorld>), target); } ourShowWorldInfoPageDelegate(world); }
public void OnUiManagerInit() { VRCUiPageAuthentication authPage = GetAuthPage(); Button doneButton = authPage.transform.Find("ButtonDone (1)").GetComponent <Button>(); Button.ButtonClickedEvent doneButton_onClick = doneButton.onClick; doneButton.onClick = new Button.ButtonClickedEvent(); doneButton.onClick.AddListener(new Action(() => { SavePlayerPrefs(); doneButton_onClick.Invoke(); })); GameObject.Find("UserInterface/MenuContent/Screens/Authentication/Login2FA/BoxLogin2FA/ButtonBack").GetComponent <Button>().onClick.AddListener(new Action(LoadPlayerPrefs)); Transform popupcheckboxtrans = GameObject.Find("UserInterface/MenuContent/Popups/PerformanceSettingsPopup").GetComponent <PopupPerformanceOptions>().dynamicBoneOptionsPage.transform.Find("Checkboxes/LimitDynamicBoneUsage"); GameObject newcheckbox = GameObject.Instantiate(popupcheckboxtrans.gameObject, authPage.field_Public_UiInputField_0.transform.parent); newcheckbox.name = "RememberMe"; GameObject.Destroy(newcheckbox.transform.GetChild(2).gameObject); GameObject.Destroy(newcheckbox.transform.GetChild(3).gameObject); GameObject.Destroy(newcheckbox.transform.GetChild(4).gameObject); GameObject.Destroy(newcheckbox.transform.GetChild(5).gameObject); Transform newcheckbox_desc_trans = newcheckbox.transform.Find("Description"); newcheckbox_desc_trans.GetComponent <Text>().text = "Remember Me"; Toggle newcheckbox_toggle = newcheckbox.GetComponent <Toggle>(); newcheckbox_toggle.isOn = SecurePlayerPrefs.HasKey(ToggleKey); newcheckbox_toggle.onValueChanged = new Toggle.ToggleEvent(); newcheckbox_toggle.onValueChanged.AddListener(new Action <bool>((newvalue) => { if (!newvalue) { SecurePlayerPrefs.DeleteKey(ToggleKey); } else { SecurePlayerPrefs.SetString(ToggleKey, "true", SecurePlayerPrefsPassword); } })); newcheckbox.transform.localPosition = new Vector3((authPage.field_Public_UiInputField_1.transform.localPosition.x - 130), (authPage.field_Public_UiInputField_1.transform.localPosition.y - 45), authPage.field_Public_UiInputField_1.transform.localPosition.z); authPage.field_Public_UiInputField_0.transform.localPosition = new Vector3(authPage.field_Public_UiInputField_0.transform.localPosition.x, (authPage.field_Public_UiInputField_0.transform.localPosition.y + 30), authPage.field_Public_UiInputField_0.transform.localPosition.z); authPage.field_Public_UiInputField_1.transform.localPosition = new Vector3(authPage.field_Public_UiInputField_1.transform.localPosition.x, (authPage.field_Public_UiInputField_1.transform.localPosition.y + 30), authPage.field_Public_UiInputField_1.transform.localPosition.z); ValidateTextTargetMethod = typeof(InputFieldValidator).GetMethods(BindingFlags.Instance | BindingFlags.Public) .Single(it => it.GetParameters().Length == 1 && XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "^([\\w\\.\\-\\+]+)@([\\w\\-]+)((\\.(\\w){2,3})+)$")); LoadPlayerPrefs(); VRCUiManager uiManager = GetVRCUiManager(); uiManager.field_Private_Action_1_VRCUiPage_0 = ( (uiManager.field_Private_Action_1_VRCUiPage_0 == null) ? new Action <VRCUiPage>(OnPageShown) : Il2CppSystem.Delegate.Combine(uiManager.field_Private_Action_1_VRCUiPage_0, (Il2CppSystem.Action <VRCUiPage>) new Action <VRCUiPage>(OnPageShown)).Cast <Il2CppSystem.Action <VRCUiPage> >() ); }
public override void OnApplicationStart() { FolderPath = string.Format("{0}/VRChat", new object[] { Environment.GetFolderPath(Environment.SpecialFolder.MyPictures) }); if (Directory.Exists(FolderPath)) { string[] filepaths = Directory.GetFiles(FolderPath, "VRChat_*.png", SearchOption.TopDirectoryOnly); if (filepaths.Length > 0) { foreach (string file in filepaths) { DateTime fileinfo = File.GetLastWriteTime(file); string filefolderpath = string.Format("{0}/{1}", new object[] { FolderPath, fileinfo.ToString("yyyy-MM-dd") }); if (!Directory.Exists(filefolderpath)) { Directory.CreateDirectory(filefolderpath); } string newfile = string.Format("{0}/{1}.png", new object[] { filefolderpath, fileinfo.ToString("HH-mm-ss.fff") }); if (!File.Exists(newfile)) { File.Move(file, newfile); } } } } var TargetMethod = typeof(ObjectPublicCaUnique).GetMethods(BindingFlags.Static | BindingFlags.Public).Single(it => it.GetParameters().Length == 2 && XrefScanner.XrefScan(it).Any(jt => jt.Type == XrefType.Global && jt.ReadAsObject()?.ToString() == "{0}/VRChat/VRChat_{1}x{2}_{3}.png")); HarmonyInstance harmonyInstance = HarmonyInstance.Create("PhotoOrganization"); harmonyInstance.Patch(TargetMethod, new HarmonyMethod(typeof(PhotoOrganization).GetMethod("CameraFolderOrganize", BindingFlags.Static | BindingFlags.NonPublic))); }