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); }
public static void SetupSprite(string fileName, string configName, ref Sprite sprite, bool specialBorder = false) { string texturePath = SetupConfigFile(fileName, ref VRCPlusPet.emptyList); if (texturePath != null) { Texture2D newTexture = new Texture2D(2, 2); byte[] imageByteArray = File.ReadAllBytes(texturePath); //poka-yoke if (imageByteArray.Length < 67 || !ImageConversion.LoadImage(newTexture, imageByteArray)) { MelonLogger.Error(string.Format("Option \"{0}\" | Image loading error", configName)); } else { sprite = Sprite.CreateSprite(newTexture, new Rect(.0f, .0f, newTexture.width, newTexture.height), new Vector2(.5f, .5f), 100f, 0, 0, specialBorder ? new Vector4(35f, 55f, 62f, 41f) : new Vector4(), false); sprite.hideFlags |= HideFlags.DontUnloadUnusedAsset; } } else { MelonLogger.Warning(string.Format("Option \"{0}\" | Image not found (UserData/{1}/{2})", configName, configPath, fileName)); } }
/// <summary> /// Version of TryCast without the generic restriction /// </summary> private static bool TryCast <T>(Il2CppObjectBase obj, out T t) { t = default; var nativeClassPtr = Il2CppClassPointerStore <T> .NativeClassPtr; if (nativeClassPtr == IntPtr.Zero) { MelonLogger.Warning($"{typeof(T)} is not an Il2Cpp reference type"); return(false); } var num = IL2CPP.il2cpp_object_get_class(obj.Pointer); if (!IL2CPP.il2cpp_class_is_assignable_from(nativeClassPtr, num)) { MelonLogger.Warning($"{obj.GetType()} is not a {typeof(T)}"); return(false); } if (RuntimeSpecificsStore.IsInjected(num)) { t = (T)ClassInjectorBase.GetMonoObjectFromIl2CppPointer(obj.Pointer); return(true); } var type = Il2CppClassPointerStore <T> .CreatedTypeRedirect; if ((object)type == null) { type = typeof(T); } t = (T)Activator.CreateInstance(type, obj.Pointer); return(true); }
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); }
private void OnDownloadComplete(string search, bool success) { ActiveDownloads -= 1; if (!success) { MelonLogger.Warning("Download of " + search + " failed"); } if (ActiveDownloads > 0) { return; } if (!IsDownloadingMissing) { SongBrowser.ReloadSongList(); //EnableBackButton(); return; } PlaylistManager.SavePlaylistData(); //EnableBackButton(); if (IsDownloadingMissing) { IsDownloadingMissing = false; SongLoadingManager.EnableButtons(); PlaylistUtil.Popup("Missing playlist songs downloaded."); PopulatePlaylists(); SongBrowser.ReloadSongList(); } }
public override void OnApplicationStart() { AskToPortalSettings.RegisterSettings(); if (MelonHandler.Mods.Any(mod => mod.Info.Name == "Portal Confirmation")) { MelonLogger.Warning("Use of Portal Confirmation by 404 was detected! AskToPortal is NOT Portal Confirmation. AskToPortal is simply a replacement for Portal Confirmation as 404 was BANNED from the VRChat Modding Group. If you wish to use this mod please DELETE Portal Confirmation."); } else { portalInfo = typeof(VRCFlowManager).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_String_WorldTransitionInfo_")).First().GetParameters()[1].ParameterType; portalInfoEnum = portalInfo.GetNestedTypes().First(); enterWorld = typeof(VRCFlowManager).GetMethods() .Where(mb => mb.Name.StartsWith($"Method_Public_Void_String_String_{portalInfo.Name}_Action_1_String_Boolean_") && !mb.Name.Contains("PDM") && CheckMethod(mb, "EnterWorld called with an invalid world id.")).First(); popupV2 = typeof(VRCUiPopupManager).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_String_String_String_Action_String_Action_Action_1_VRCUiPopup_") && !mb.Name.Contains("PDM") && CheckMethod(mb, "UserInterface/MenuContent/Popups/StandardPopupV2")).First(); popupV2Small = typeof(VRCUiPopupManager).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_String_String_String_Action_Action_1_VRCUiPopup_") && !mb.Name.Contains("PDM") && CheckMethod(mb, "UserInterface/MenuContent/Popups/StandardPopupV2")).First(); closePopup = typeof(VRCUiPopupManager).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_") && mb.Name.Length <= 21 && !mb.Name.Contains("PDM") && CheckMethod(mb, "POPUP")).First(); enterPortal = typeof(PortalInternal).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_") && mb.Name.Length <= 21 && CheckUsed(mb, "OnTriggerEnter")).First(); closeMenu = typeof(VRCUiManager).GetMethods() .Where(mb => mb.Name.StartsWith("Method_Public_Void_Boolean_") && CheckUsed(mb, "ShowAddMessagePopup")).First(); Harmony.Patch(enterPortal, prefix: new HarmonyMethod(typeof(AskToPortalMod).GetMethod("OnPortalEnter", BindingFlags.Static | BindingFlags.Public))); Harmony.Patch(typeof(PortalInternal).GetMethod("ConfigurePortal"), prefix: new HarmonyMethod(typeof(AskToPortalMod).GetMethod("OnPortalDropped", BindingFlags.Static | BindingFlags.Public))); Harmony.Patch(typeof(PortalInternal).GetMethod("OnDestroy"), prefix: new HarmonyMethod(typeof(AskToPortalMod).GetMethod("OnPortalDestroyed", BindingFlags.Static | BindingFlags.Public))); MelonLogger.Msg("Initialized!"); } }
public override void OnApplicationStart() { try { TextOwO.Init(); } catch (Exception e) { MelonLogger.Warning("Error at Text: " + Environment.NewLine + e); } try { TextMeshOwO.Init(); } catch (Exception e) { MelonLogger.Warning("Error at TextMesh: " + Environment.NewLine + e); } try { TMPOwO.Init(); } catch (Exception e) { MelonLogger.Warning("Error at TextMeshPro: " + Environment.NewLine + e); } }
internal static void CheckForUpdates(IEnumerable <UpdateInfo> allUpdateInfo, List <UpdateInfo> modsNeedingUpdates) { Parallel.ForEach( allUpdateInfo, async updateInfo => { try { var updater = new UpdaterHttp(updateInfo); if (await updater.IsUpdate()) { lock (modsNeedingUpdates) { modsNeedingUpdates.Add(updateInfo); } } } catch (Exception e) { MelonLogger.Warning($"Encountered exception trying to check {updateInfo.Name} for updates: "); MelonLogger.Warning(e.ToString()); } } ); }
internal static async Task <Variant> ValidateToken(string token) { Client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth", token); Client.DefaultRequestHeaders.Add("Client-ID", ClientID); var response = await Client.GetAsync("https://id.twitch.tv/oauth2/validate"); var responseContent = await response.Content.ReadAsStringAsync(); //MelonLogger.Msg("Validation response: " + responseContent); var responseJson = JSON.Load(responseContent); if (response.IsSuccessStatusCode) { MelonLogger.Msg("That's a success! Setting variables."); _twitchID = responseJson["user_id"]; _twitchToken = token; TwitchAuthed = true; int expiresIn = responseJson["expires_in"]; if (expiresIn < 24 * 60 * 60) // token expires within 24 hours { PopupsToDisplay.Enqueue(new MyPopup(PopupType.Yesno, "Your saved Twitch Authentication is due to expire within the next 24 hours. Do you want to reauthenticate now or later?", "Twitch Integration", "Now", "Later", StreamingSetupMainMenuHook.ShowTwitchAuthPopup)); } } else { MelonLogger.Warning("Preexisting token has expired!"); TwitchAuthFailReason = "a previous authentication has expired."; } return(responseJson); }
public override void OnApplicationStart() { if (MelonHandler.Mods.Any(mod => mod.Info.Name == "VibeGoesBrrr")) { MelonLogger.Warning("VibeGoesBrrr detected. Disabling Vibrator Controller since these mods are incompatible"); return; } NativeMethods.LoadUnmanagedLibraryFromResource(Assembly.GetExecutingAssembly(), "Vibrator_Controller.buttplug_rs_ffi.dll", "buttplug_rs_ffi.dll"); vibratorController = MelonPreferences.CreateCategory("VibratorController"); MelonPreferences.CreateEntry(vibratorController.Identifier, "ActionMenu", true, "action menu integration"); MelonPreferences.CreateEntry(vibratorController.Identifier, "buttonStep", 5, "What % to change when pressing button"); useActionMenu = MelonPreferences.GetEntryValue <bool>(vibratorController.Identifier, "ActionMenu"); buttonStep = MelonPreferences.GetEntryValue <int>(vibratorController.Identifier, "buttonStep"); if (useActionMenu && MelonHandler.Mods.Any(mod => mod.Info.Name == "ActionMenuApi")) { try { new ToyActionMenu(); } catch (Exception) { MelonLogger.Warning("Failed to add action menu button"); } } VRCWSIntegration.Init(); MelonCoroutines.Start(UiManagerInitializer()); CreateButton(); VRCUtils.OnUiManagerInit += createMenu; }
public void Flush() { List <Action> toProcess; if (myToMainThreadQueue.Count == 0) { return; } lock (myToMainThreadQueue) { toProcess = myToMainThreadQueue.ToList(); myToMainThreadQueue.Clear(); } foreach (var action in toProcess) { try { action(); } catch (Exception ex) { MelonLogger.Warning($"Exception in task: {ex}"); } } }
internal static IEnumerator WorldJoinedCoroutine() { for (;;) { var sw = new Stopwatch(); sw.Start(); if (isInstantiated) // 1 Extra check for the rare case scenario that uInstance is not set up fast enough from CurrentUser -> uInstance. { yield return(new WaitForSeconds(1)); { if (!UseMod) { yield break; } userVolumeThreshold = SensitivityValue; userVolumePeak = SensitivityValue * 2; } sw.Stop(); yield break; } if (sw.Elapsed.Seconds >= 100) // This should never happen but a check for it is in place just in case. { MelonLogger.Warning("WorldJoinedCoroutine took too long and was stopped."); yield break; } yield return(new WaitForSeconds(1)); // IEnumerator Speed Control } }
internal static IEnumerator WorldJoinedCoroutine() { for (;;) { var sw = new Stopwatch(); sw.Start(); if (isInstantiated) { yield return(new WaitForSeconds(1)); { Start.OnWorldJoin(); } sw.Stop(); yield break; } if (sw.Elapsed.Seconds >= 100) // This should never happen but a check for it is in place just in case. { MelonLogger.Warning("WorldJoinedCoroutine took too long and was stopped."); yield break; } yield return(new WaitForSeconds(1)); // IEnumerator Speed Control } }
public static List <Regex> LoadPrefetchedIgnore() { var file = Path.Combine(GetHylasHome(), ".prefetch.ignore"); if (!File.Exists(file)) { File.WriteAllText(file, "// 不预加载的列表\r\n// 正则表达式,如 .* 代表忽略所有\r\n// 仅支持 // 单行注释\r\n^Battle/Human/.*$\r\n^Effect/UI/.*$\r\n^Texture/.*$"); } List <Regex> prefetchedIgnore = new List <Regex>(); MelonLogger.Msg($"Prefetch Blacklist:"); try { IEnumerable <string> lines = File.ReadLines(file); foreach (var line in lines) { if (line.StartsWith("//") || line.Trim().Length == 0) { continue; } MelonLogger.Msg($"{line}"); prefetchedIgnore.Add(new Regex(line)); } } catch (Exception e) { MelonLogger.Warning($"{e}"); } return(prefetchedIgnore); }
internal static void Install() { Type PatchType = typeof(ForcedCultureInfo); HarmonyMethod PatchMethod_Get = PatchType.GetMethod("GetMethod", BindingFlags.NonPublic | BindingFlags.Static).ToNewHarmonyMethod(); HarmonyMethod PatchMethod_Set = PatchType.GetMethod("SetMethod", BindingFlags.NonPublic | BindingFlags.Static).ToNewHarmonyMethod(); Type CultureInfoType = typeof(CultureInfo); Type ThreadType = typeof(Thread); foreach (FieldInfo fieldInfo in ThreadType .GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) .Where(x => x.FieldType == CultureInfoType)) { fieldInfo.SetValue(null, SelectedCultureInfo); } foreach (PropertyInfo propertyInfo in ThreadType .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) .Where(x => x.PropertyType == CultureInfoType)) { MethodInfo getMethod = propertyInfo.GetGetMethod(); if (getMethod != null) { try { Core.HarmonyInstance.Patch(getMethod, PatchMethod_Get); } catch (Exception ex) { MelonLogger.Warning($"Exception Patching Thread Get Method {propertyInfo.Name}: {ex}"); } } MethodInfo setMethod = propertyInfo.GetSetMethod(); if (setMethod != null) { try { Core.HarmonyInstance.Patch(setMethod, PatchMethod_Set); } catch (Exception ex) { MelonLogger.Warning($"Exception Patching Thread Set Method {propertyInfo.Name}: {ex}"); } } } }
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 Log(object log, LogType logType = LogType.Normal) { if (logType == LogType.None) { MelonLogger.Msg($"[{prefix}] {log}"); return; } ConsoleColor color = ConsoleColor.White; switch (logType) { case LogType.Normal: color = ConsoleColor.Cyan; break; case LogType.Warning: color = ConsoleColor.Yellow; MelonLogger.Warning($"{log}"); return; case LogType.Error: color = ConsoleColor.Red; MelonLogger.Error($"{log}"); return; case LogType.Success: color = ConsoleColor.Blue; break; } MelonLogger.Msg(color, $"{log}"); }
public Task StoreImageAsync(string url, Il2CppStructArray <byte> data) { if (string.IsNullOrEmpty(url)) { return(Task.CompletedTask); } return(Task.Run(() => { try { if (myFileDatabase.FileStorage.Exists(url)) { return; } myFileDatabase.FileStorage.Upload(url, url, new MemoryStream(data)); var newImageInfo = new StoredImageInfo { Id = url, LastAccessed = DateTime.MinValue }; myImageInfos.Upsert(newImageInfo); } catch (LiteException ex) { if (MelonDebug.IsEnabled()) { MelonLogger.Warning($"Database exception in image store handler: {ex}"); } } })); }
private static void HandleErrors(Error eyeError, Error faceError) { if (eyeError.IsRealError()) { // Msg instead of Warning under the assumption most people will be using only lip tracking MelonLogger.Msg($"Eye Tracking will be unavailable for this session. ({eyeError})"); } else if (eyeError == Error.WORK) { MainMod.AppendEyeParams(); EyeEnabled = true; MelonLogger.Msg("SRanipal Eye Initialized!"); } if (faceError.IsRealError()) { MelonLogger.Warning($"Lip Tracking will be unavailable for this session. ({faceError})"); } else if (faceError == (Error)1051) { while (faceError == (Error)1051) { faceError = SRanipal_API.Initial(SRanipal_Lip_v2.ANIPAL_TYPE_LIP_V2, IntPtr.Zero); } } if (faceError == Error.WORK) { MainMod.AppendLipParams(); FaceEnabled = true; MelonLogger.Msg("SRanipal Lip Initialized!"); } }
private static void Bridge(IntPtr @this, IntPtr handle) { var record = BRIDGE_INDEX[handle]; Logger.Debug(() => $"{record}"); try { var conf = UnhollowerSupport.Il2CppObjectPtrToIl2CppObject <ConfBase>(@this) ?? throw new Exception("Unable to convert ptr to object"); if (Env.IsGameUpdated) { BridgeHelper.DumpConf(conf, record); } else { BridgeHelper.UpdateConf(conf, record); } } catch (Exception e) { var info = Trampoline.GetInfo(handle); MelonLogger.Warning($"Exception occurs in bridge\n{e}\n" + $"this: 0x{@this.ToInt64():X}\n" + $"trampoline info: {info}\n" + $"record: {record}"); } }
public override void OnApplicationStart() { Instance = this; try { //Adapted from knah's JoinNotifier mod found here: https://github.com/knah/VRCMods/blob/master/JoinNotifier/JoinNotifierMod.cs using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ActionMenuUtils.icons")) using (var tempStream = new MemoryStream((int)stream.Length)) { stream.CopyTo(tempStream); iconsAssetBundle = AssetBundle.LoadFromMemory_Internal(tempStream.ToArray(), 0); iconsAssetBundle.hideFlags |= HideFlags.DontUnloadUnusedAsset; } respawnIcon = iconsAssetBundle.LoadAsset_Internal("Assets/Resources/Refresh.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); respawnIcon.hideFlags |= HideFlags.DontUnloadUnusedAsset; helpIcon = iconsAssetBundle.LoadAsset_Internal("Assets/Resources/Help.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); helpIcon.hideFlags |= HideFlags.DontUnloadUnusedAsset; goHomeIcon = iconsAssetBundle.LoadAsset_Internal("Assets/Resources/Home.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); goHomeIcon.hideFlags |= HideFlags.DontUnloadUnusedAsset; resetAvatarIcon = iconsAssetBundle.LoadAsset_Internal("Assets/Resources/Avatar.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); resetAvatarIcon.hideFlags |= HideFlags.DontUnloadUnusedAsset; rejoinInstanceIcon = iconsAssetBundle.LoadAsset_Internal("Assets/Resources/Pin.png", Il2CppType.Of <Texture2D>()).Cast <Texture2D>(); rejoinInstanceIcon.hideFlags |= HideFlags.DontUnloadUnusedAsset; } catch (Exception e) { MelonLogger.Warning("Consider checking for newer version as mod possibly no longer working, Exception occured OnAppStart(): " + e.Message); } // Creates new Api instance and patches all required methods if found actionMenuApi = new ActionMenuAPI(); ModSettings.RegisterSettings(); ModSettings.Apply(); SetupButtons(); //_ = Utils.GetGoHomeDelegate; }
private static void WaitForUiInit() { if (MelonHandler.Mods.Any(x => x.Info.Name.Equals("UI Expansion Kit"))) { typeof(UIXManager).GetMethod("OnApplicationStart").Invoke(null, null); } else { MelonLogger.Warning("UiExpansionKit (UIX) was not detected. Using coroutine to wait for UiInit. Please consider installing UIX.");
private GameObject GetMainModel() { if (avatarMenuMainModel == null) { MelonLogger.Warning("MainModel was not found"); avatarMenuMainModel = GameObject.Find(avatarMenuMainModelPath); } return(avatarMenuMainModel); }
public override void OnApplicationStart() { if (Environment.GetCommandLineArgs().Contains("--updater-dev")) { MelonLogger.Msg("Running in dev mode"); if (File.Exists(targetFilePath)) { System.Reflection.Assembly.LoadFile(targetFilePath); TryStartCore(); return; } else { MelonLogger.Warning("No VRCModUpdater.Core found"); } } MelonLogger.Msg("Checking latest version for github"); string latestVersion = GetLatestVersion(); if (latestVersion == null) { MelonLogger.Error("Failed to fetch latest VRCModUpdater.Core version"); TryStartCore(); return; } MelonLogger.Msg("Latest VRCModUpdater.Core version: " + latestVersion); string assemblyVersion = null; if (File.Exists(targetFilePath)) { try { using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(targetFilePath, new ReaderParameters { ReadWrite = true })) { CustomAttribute melonInfoAttribute = assembly.CustomAttributes.First(a => a.AttributeType.Name == "AssemblyFileVersionAttribute"); assemblyVersion = melonInfoAttribute.ConstructorArguments[0].Value as string; } MelonLogger.Msg("Installed VRCModUpdater.Core version: " + assemblyVersion); } catch (Exception e) { MelonLogger.Error("Failed to load VRCModUpdater.Core. Redownloading.\n" + e); } } if (assemblyVersion != latestVersion) { UpdateCore(latestVersion); } TryStartCore(); }
public static bool CheckTypes <T1>(this object[] parameters, out T1 param1) { param1 = default; if (parameters.Length < 1) { MelonLogger.Warning("Did not have at least 1 param"); return(false); } return(CheckType(parameters[0], out param1)); }
public virtual void SetValue(object value) { if (value is T v) { this.value = v; } else { MelonLogger.Warning($"Error: ModSetting type mismatch between {typeof(T).Name} and {value.GetType().Name}"); } }
internal static void Install() { Type threadType = typeof(Thread); HarmonyMethod patchMethod = AccessTools.Method(typeof(InvariantCurrentCulture), "PatchMethod").ToNewHarmonyMethod(); try{ Core.HarmonyInstance.Patch(AccessTools.PropertyGetter(threadType, "CurrentCulture"), patchMethod); } catch (Exception ex) { MelonLogger.Warning($"Thread.CurrentCulture Exception: {ex}"); } try { Core.HarmonyInstance.Patch(AccessTools.PropertyGetter(threadType, "CurrentUICulture"), patchMethod); } catch (Exception ex) { MelonLogger.Warning($"Thread.CurrentUICulture Exception: {ex}"); } }
public static int CostForDifficulty(int cost, GameModel gameModel) { var difficulty = $"{gameModel.difficultyId}"; if (string.IsNullOrEmpty(difficulty)) { MelonLogger.Warning("Difficulty cannot be determined at this stage of creating the GameModel"); MelonLogger.Warning("Use the list of ModModels to find the difficulty instead"); } return(CostForDifficulty(cost, gameModel.difficultyId)); }
private void TryStartCore() { if (File.Exists(targetFilePath)) { Assembly assembly = System.Reflection.Assembly.LoadFile(targetFilePath); assembly.GetType("VRCModUpdater.Core.VRCModUpdaterCore").GetMethod("Start").Invoke(null, null); } else { MelonLogger.Warning("No VRCModUpdater.Core found"); } }
/// <inheritdoc /> public virtual void SetValue(object val) { if (val is T v) { value = v; OnValueChanged.InvokeAll(v); } else { MelonLogger.Warning($"Error: ModSetting type mismatch between {typeof(T).Name} and {val.GetType().Name}"); } }