internal static bool Download(string url, string destination) { if (string.IsNullOrEmpty(url)) { MelonLogger.Error($"url cannot be Null or Empty!"); return(false); } if (string.IsNullOrEmpty(destination)) { MelonLogger.Error($"destination cannot be Null or Empty!"); return(false); } if (File.Exists(destination)) { File.Delete(destination); } MelonLogger.Msg($"Downloading {url} to {destination}"); try { Core.webClient.DownloadFile(url, destination); } catch (Exception ex) { MelonLogger.Error(ex.ToString()); if (File.Exists(destination)) { File.Delete(destination); } return(false); } return(true); }
private void CreateGameObjects() { MelonLogger.Msg("Finding original GameObjects"); var UIRoot = GameObject.Find("UserInterface/MenuContent/Popups/LoadingPopup"); var InfoPanel = GameObject.Find("UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingInfoPanel"); var SkyCube = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingBackground_TealGradient/SkyCube_Baked"); var bubbles = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/3DElements/LoadingBackground_TealGradient/_FX_ParticleBubbles"); var loginBubbles = GameObject.Find("/UserInterface/LoadingBackground_TealGradient_Music/_FX_ParticleBubbles"); var StartScreen = GameObject.Find("/UserInterface/LoadingBackground_TealGradient_Music/"); var originalStartScreenAudio = GameObject.Find("/UserInterface/LoadingBackground_TealGradient_Music/LoadingSound"); var originalStartScreenSkyCube = GameObject.Find("/UserInterface/LoadingBackground_TealGradient_Music/SkyCube_Baked"); var originalLoadingAudio = GameObject.Find("/UserInterface/MenuContent/Popups/LoadingPopup/LoadingSound"); MelonLogger.Msg("Creating new GameObjects"); loadScreenPrefab = CreateGameObject(loadScreenPrefab, new Vector3(400, 400, 400), "UserInterface/MenuContent/Popups/", "LoadingPopup"); loginPrefab = CreateGameObject(loginPrefab, new Vector3(0.5f, 0.5f, 0.5f), "UserInterface/", "LoadingBackground_TealGradient_Music"); // newCube = CreateGameObject(newCube, new Vector3(0.5f, 0.5f, 0.5f), "UserInterface/", "LoadingBackground_TealGradient_Music"); MelonLogger.Msg("Disabling original GameObjects"); // Disable original objects from loading screen SkyCube.active = false; bubbles.active = false; originalLoadingAudio.active = false; // Disable original objects from login screen originalStartScreenAudio.active = false; originalStartScreenSkyCube.active = false; loginBubbles.active = false; // Apply any preferences (yes ik this is lazy) OnPreferencesSaved(); }
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()); } } }
private static void DumpScan(IEnumerable <XrefInstance> scan) { foreach (XrefInstance instance in scan) { if (instance.Type == XrefType.Global) { MelonLogger.Msg(instance.Type); MelonLogger.Msg(instance.ReadAsObject().ToString()); MelonLogger.Msg(""); continue; } MethodBase resolvedMethod = instance.TryResolve(); if (instance.Type == XrefType.Method) { if (resolvedMethod == null) { MelonLogger.Msg("null"); MelonLogger.Msg("null"); } else { MelonLogger.Msg(resolvedMethod.Name); MelonLogger.Msg(resolvedMethod.DeclaringType.FullName); } MelonLogger.Msg(""); } } }
private static void WhitelistUser(APIUser user) { if (user == null) { return; } if (UserPermissionHandler.IsWhitelisted(user.id)) { UserPermissionHandler.RemoveFromWhitelist(user.id); MelonLogger.Msg($"{user.displayName} removed from whitelist"); Utilities.QueueHudMessage($"{user.displayName} removed from whitelist"); } else { if (UserPermissionHandler.IsBlacklisted(user.id)) { UserPermissionHandler.RemoveFromBlacklist(user.id); } UserPermissionHandler.AddToWhitelist(user); MelonLogger.Msg($"{user.displayName} added to whitelist"); Utilities.QueueHudMessage($"{user.displayName} added to whitelist"); } UserPermissionHandler.SaveSettings(); }
// Completely stolen from Psychloor's PlayerRotator (https://github.com/Psychloor/PlayerRotater) public static IEnumerator CheckWorld(ApiWorld world) { string worldId = world.id; // Check if black/whitelisted from EmmVRC - thanks Emilia and the rest of EmmVRC Staff WWW www = new WWW($"https://thetrueyoshifan.com/RiskyFuncsCheck.php?worldid={worldId}", null, new Dictionary <string, string>()); while (!www.isDone) { yield return(new WaitForEndOfFrame()); } string result = www.text?.Trim().ToLower(); www.Dispose(); if (!string.IsNullOrWhiteSpace(result)) { switch (result) { case "allowed": MelonLogger.Msg("World allowed to show player distance"); PlayerEntry.worldAllowed = true; yield break; case "denied": MelonLogger.Msg("World NOT allowed to show player distance"); PlayerEntry.worldAllowed = false; yield break; } } // no result from server or they're currently down // Check tags then. should also be in cache as it just got downloaded API.Fetch <ApiWorld>( worldId, new Action <ApiContainer>( container => { ApiWorld apiWorld; if ((apiWorld = container.Model.TryCast <ApiWorld>()) != null) { foreach (string worldTag in apiWorld.tags) { if (worldTag.IndexOf("game", StringComparison.OrdinalIgnoreCase) >= 0) { MelonLogger.Msg("World NOT allowed to show player distance"); PlayerEntry.worldAllowed = false; return; } } MelonLogger.Msg("World allowed to show player distance"); PlayerEntry.worldAllowed = true; return; } else { MelonLogger.Error("Failed to cast ApiModel to ApiWorld"); } }), disableCache: false); }
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 static void ExportDefaultStyle(string baseDir, StyleEngine styleEngine) { var textAssetType = Il2CppType.Of <TextAsset>(); var spriteType = Il2CppType.Of <Sprite>(); var audioClipType = Il2CppType.Of <AudioClip>(); MelonLogger.Msg($"Exporting default VRC skin to {baseDir}"); foreach (var keyValuePair in styleEngine.field_Private_Dictionary_2_Tuple_2_String_Type_Object_0) { var basePath = Path.Combine(baseDir, keyValuePair.Key.Item1); if (keyValuePair.Key.Item2 == textAssetType) { Directory.CreateDirectory(Path.GetDirectoryName(basePath) !); var textAsset = keyValuePair.Value.Cast <TextAsset>(); File.WriteAllBytes(basePath + ".txt", textAsset.bytes); } else if (keyValuePair.Key.Item2 == spriteType) { Directory.CreateDirectory(Path.GetDirectoryName(basePath) !); var sprite = keyValuePair.Value.Cast <Sprite>(); SpriteSnipperUtil.SaveSpriteAsPngWithMetadata(sprite, basePath + ".png"); } else if (keyValuePair.Key.Item2 == audioClipType) { Directory.CreateDirectory(Path.GetDirectoryName(basePath) !); var audioClip = keyValuePair.Value.Cast <AudioClip>(); WriteWaveFile(basePath + ".wav", audioClip); } } MelonLogger.Msg($"Export finished"); }
/// <summary> Logs a GameObject and all of its components to the console </summary> /// <param name="gameObject">The GameObject to log</param> /// <param name="max">Maximum amount of times to traverse down children</param> /// <param name="n_depth">This parameter should be ignored</param> public static void LogGameObject(GameObject gameObject, int max = -1, int?n_depth = null) { int depth = n_depth ?? 0; if (max != -1 && depth > max) { return; } MelonLogger.Msg(ConsoleColor.Green, "".PadLeft(depth * 4, ' ') + gameObject.name); Component[] components = gameObject.GetComponents <Component>(); for (int i = 0; i < components.Length; i++) { MelonLogger.Msg( ConsoleColor.Cyan, "".PadLeft((depth + 1) * 4, ' ') + ((gameObject.name.Length + 2 < components[i].ToString().Length) ? components[i].ToString().Substring( gameObject.name.Length + 2, components[i].ToString().Length - gameObject.name.Length - 3 ) : components[i].ToString()) ); } for (int i = 0; i < gameObject.transform.childCount; i++) { LogGameObject(gameObject.transform.GetChild(i).gameObject, max, depth + 1); } }
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); }
internal static void Load() { TomletMain.RegisterMapper(WriteColor, ReadColor); FilePath = Path.Combine(Core.FolderPath, "Config.cfg"); General = CreateCat <cGeneral>(FilePath, nameof(General)); bool UseDefault = true; if (!string.IsNullOrEmpty(General.Theme) && !General.Theme.Equals("Default") && !General.Theme.Equals("Random")) { try { // To-Do: Sanatize themeName General.Theme = General.Theme .Replace("\\", "") .Replace("/", ""); ThemePath = Path.Combine(Core.ThemesFolderPath, General.Theme); if (Directory.Exists(ThemePath)) { UseDefault = false; } else { throw new DirectoryNotFoundException(ThemePath); } } catch (Exception ex) { MelonLogger.Error($"Failed to find Start Screen Theme: {ex}"); } } if (General.Theme.Equals("Random")) { ThemePath = UIUtils.RandomFolder(Core.ThemesFolderPath); UseDefault = false; } if (UseDefault) { General.Theme = "Default"; ThemePath = Path.Combine(Core.ThemesFolderPath, General.Theme); if (!Directory.Exists(ThemePath)) { Directory.CreateDirectory(ThemePath); } } MelonLogger.Msg($"Using Start Screen Theme: \"{General.Theme}\""); Background = CreateCat <cBackground>(nameof(Background), true); LogoImage = CreateCat <LogoImageSettings>(nameof(LogoImage), true); LoadingImage = CreateCat <LoadingImageSettings>(nameof(LoadingImage), true); VersionText = CreateCat <VersionTextSettings>(nameof(VersionText), true); ProgressText = CreateCat <ProgressTextSettings>(nameof(ProgressText), true); ProgressBar = CreateCat <cProgressBar>(nameof(ProgressBar), true); MelonPreferences.SaveCategory <cGeneral>(nameof(General), false); }
public override async void OnApplicationStart() { base.OnApplicationStart(); MelonLogger.Msg("Starting up Twitch Integration..."); MelonLogger.Msg("Checking for existing authentication..."); Directory.CreateDirectory(Path.GetDirectoryName(TwitchauthPath) ?? throw new InvalidOperationException()); if (!File.Exists(TwitchauthPath)) { TwitchAuthFailReason = " you started this mod for the first time."; } else { var content = File.Exists(TwitchauthPath) ? File.ReadAllText(TwitchauthPath) : ""; content = content.Trim(); //MelonLogger.Msg("Content was: \"" + content + "\""); if (!content.Equals("")) { await ValidateToken(content); } else { TwitchAuthFailReason = "the authentication file was empty. Did you do that?"; } } }
// ReSharper disable once InconsistentNaming public static bool PreResLoad(ref UnityEngine.Object __result, string path) { MelonLogger.Msg(path); const string templateObjectPath = "Game/Portrait/Woman/Body/101"; if (!path.IsPortrait()) { return(true); } var pp = path.ToPhysicalPath(); if (!pp.Exist()) { return(true); } // Can't use base method directly because of the missing of reverse path. // FIXME: There is no guarantee `Load<T>` won't use `Load` internally var orig = g.res.Load <GameObject>(templateObjectPath); var template = UnityEngine.Object.Instantiate(orig).Cast <GameObject>(); var renderer = template.GetComponentInChildren <SpriteRenderer>(); renderer.LoadCustomSprite(pp); __result = template; return(false); }
public Object Get() { if (Interlocked.CompareExchange(ref expired, FALSE, TRUE) == TRUE) { cacheLock.EnterWriteLock(); try { if (go != null) { MelonLogger.Msg("Update expired"); } Update(); return(go); } finally { cacheLock.ExitWriteLock(); } } cacheLock.EnterReadLock(); try { return(go); } finally { cacheLock.ExitReadLock(); } }
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}"); }
private static void Postfix(SongSelect __instance) { FilterPanel.Initialize(); ScoreHistory.LoadHistory(PlatformChooser.I.GetLeaderboardID()); MelonCoroutines.Start(SongBrowser.UpdateLastSongCount()); MelonLogger.Msg("Updating song count"); }
public override void OnApplicationStart() { MelonLogger.Msg("Paragon Sentry In Shop mod loaded"); Directory.CreateDirectory($"{dir}"); if (File.Exists(config)) { MelonLogger.Msg("Reading config file"); using (StreamReader sr = File.OpenText(config)) { string s = ""; while ((s = sr.ReadLine()) != null) { SentryParagonCost = int.Parse(s.Substring(s.IndexOf(char.Parse("=")) + 1)); } } MelonLogger.Msg("Done reading"); } else { MelonLogger.Msg("Creating config file"); using (StreamWriter sw = File.CreateText(config)) { sw.WriteLine("ParagonSentryCost=5000"); } MelonLogger.Msg("Done Creating"); } }
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 GetNewInstancePrefix(ref string tags) { MelonLogger.Msg("Mono Stacktrace:\n" + new StackTrace().ToString()); MelonLogger.Msg("Il2Cpp Stacktrace:\n" + new Il2CppSystem.Diagnostics.StackTrace().ToString()); ServerDef targetServer; if (new StackTrace().GetFrame(2).GetMethod().DeclaringType == typeof(PopupRoomInstance)) { targetServer = serverList[serverDropdown.value]; } else { targetServer = ss.AppSettings.UseNameServer ? ServerDef.CloudServer("", ss.AppSettings.FixedRegion, ss.AppSettings.AppIdRealtime, ss.AppSettings.AppVersion) : ServerDef.DedicatedServer("", ss.AppSettings.Server, ss.AppSettings.Port); } if (targetServer != defaultServer) { if (targetServer.cloud) { tags += "~cloud(" + targetServer.region + "," + targetServer.appId + "," + targetServer.appVersion + ")"; } else { tags += "~server(" + targetServer.address + "," + targetServer.port + ")"; } } MelonLogger.Msg("generated instance id: " + tags); }
public override void OnApplicationStart() { MelonPreferences.CreateCategory("ReloadAvatars", "ReloadAvatars Settings"); reloadAvatarPref = (MelonPreferences_Entry <bool>)MelonPreferences.CreateEntry("ReloadAvatars", "ReloadAvatar", true, "Enable/Disable Reload Avatar Button"); reloadAllAvatarsPref = (MelonPreferences_Entry <bool>)MelonPreferences.CreateEntry("ReloadAvatars", "ReloadAllAvatars", true, "Enable/Disable Reload All Avatars Button"); MethodInfo reloadAvatarMethod = typeof(VRCPlayer).GetMethods().First(mi => mi.Name.StartsWith("Method_Private_Void_Boolean_") && mi.Name.Length < 31 && mi.GetParameters().Any(pi => pi.IsOptional)); MethodInfo reloadAllAvatarsMethod = typeof(VRCPlayer).GetMethods().Where(mi => mi.Name.StartsWith("Method_Public_Void_Boolean_") && mi.Name.Length < 30 && mi.GetParameters().Any(pi => pi.IsOptional)).First(); // Both methods seem to do the same thing ExpansionKitApi.GetExpandedMenu(ExpandedMenu.UserQuickMenu).AddSimpleButton("Reload Avatar", new Action(() => { try { reloadAvatarMethod.Invoke(QuickMenu.prop_QuickMenu_0.field_Private_Player_0.field_Internal_VRCPlayer_0, new object[] { true }); } catch (Exception ex) { MelonLogger.Error("Error while reloading single avatar:\n" + ex.ToString()); } // Ignore }), new Action <GameObject>((gameObject) => { reloadAvatarButton = gameObject; reloadAvatarButton.SetActive(reloadAllAvatarsPref.Value); })); ExpansionKitApi.GetExpandedMenu(ExpandedMenu.QuickMenu).AddSimpleButton("Reload All Avatars", new Action(() => { try { reloadAllAvatarsMethod.Invoke(VRCPlayer.field_Internal_Static_VRCPlayer_0, new object[] { true }); } catch (Exception ex) { MelonLogger.Error("Error while reloading all avatars:\n" + ex.ToString()); } // Ignore }), new Action <GameObject>((gameObject) => { reloadAllAvatarsButton = gameObject; reloadAllAvatarsButton.SetActive(reloadAvatarPref.Value); })); MelonLogger.Msg("Initialized!"); }
public static unsafe void SetupHooking() { try { var intPtr = (IntPtr)typeof(VRCAvatarManager.MulticastDelegateNPublicSealedVoGaVRBoUnique) .GetField( "NativeMethodInfoPtr_Invoke_Public_Virtual_New_Void_GameObject_VRC_AvatarDescriptor_Boolean_0", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); Imports.Hook(intPtr, new Action <IntPtr, IntPtr, IntPtr, bool>(OnAvatarInstantiated).Method.MethodHandle .GetFunctionPointer()); _onAvatarInstantiatedDelegate = Marshal.GetDelegateForFunctionPointer <AvatarInstantiatedDelegate>(*(IntPtr *)(void *)intPtr); intPtr = (IntPtr)typeof(VRCAvatarManager) .GetField( "NativeMethodInfoPtr_Method_Public_Boolean_ApiAvatar_String_Single_MulticastDelegateNPublicSealedVoGaVRBoUnique_0", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null); Imports.Hook(intPtr, new Action <IntPtr, IntPtr, string, float, IntPtr>(OnAvatarSwitch).Method.MethodHandle .GetFunctionPointer()); _avatarSwitch = Marshal.GetDelegateForFunctionPointer <OnAvatarSwitchDelegate>(*(IntPtr *)(void *)intPtr); } catch (Exception ex) { MelonLogger.Msg("Patch Failed " + ex); } }
public static void UiInit() { MelonLogger.Msg("Loading UI..."); menu = new SubMenu(QuickMenu.prop_QuickMenu_0.gameObject, "InstanceHistoryModMenu"); openButton = new SingleButton(QuickMenu.prop_QuickMenu_0.transform.FindChild("ShortcutMenu").gameObject, new Vector3(Config.openButtonX.Value, Config.openButtonY.Value), "Instance History", new Action(OpenInstanceHistoryMenu), "Open instance history", "InstancenHistoryButton"); openButton.gameObject.SetActive(!(InstanceHistoryMod.HasUIX && Config.useUIX.Value)); Config.openButtonX.OnValueChanged += OnPositionChange; Config.openButtonY.OnValueChanged += OnPositionChange; if (InstanceHistoryMod.HasUIX) { typeof(UIXManager).GetMethod("AddOpenButtonToUIX").Invoke(null, null); } pageUp = new SingleButton(menu.gameObject, GameObject.Find("UserInterface/QuickMenu/EmojiMenu/PageUp"), new Vector3(4, 0), "", new Action(() => InstanceIndex -= 9), $"Go up a page", "UpPageButton"); pageDown = new SingleButton(menu.gameObject, GameObject.Find("UserInterface/QuickMenu/EmojiMenu/PageDown"), new Vector3(4, 2), "", new Action(() => InstanceIndex += 9), $"Go down a page", "DownPageButton"); backButton = new SingleButton(menu.gameObject, new Vector3(4, 0), "Back", new Action(() => UiManager.OpenSubMenu("UserInterface/QuickMenu/ShortcutMenu")), "Press to go back to the Shortcut Menu", "BackButton", textColor: Color.yellow); backButton.gameObject.SetActive(false); pageNumLabel = new Label(menu.gameObject, new Vector3(4, 1), $"Page: 1 of {LastPageNum}", "PageNumberLabel"); for (int i = 0; i < 9; i++) { buttons[i] = new SingleButton(menu.gameObject, new Vector3((i % 3) + 1, Mathf.Floor(i / 3)), "Placeholder text", null, "Placeholder text", $"World Button {i + 1}", resize: true); } MelonLogger.Msg("UI Loaded!"); }
/// <summary> /// Prints relevant info about this node to the console including: /// <br/> /// /// </summary> /// <param name="node"></param> public static void PrintInfo(this UnityDisplayNode node) { var start = $"-------------Information about UnityDisplayNode {node.name}-------------"; MelonLogger.Msg(start); MelonLogger.Msg("Generic Renderers:"); for (var i = 0; i < node.genericRenderers.Count; i++) { var renderer = node.genericRenderers[i]; MelonLogger.Msg($" {i}. {renderer.name} ({renderer.GetIl2CppType().Name})"); } MelonLogger.Msg(""); MelonLogger.Msg("Generic Render Layers:"); for (var i = 0; i < node.genericRendererLayers.Count; i++) { var layer = node.genericRendererLayers[i]; MelonLogger.Msg($" {i}. {layer}"); } MelonLogger.Msg(""); MelonLogger.Msg("Component Hierarchy:"); node.gameObject.RecursivelyLog(); MelonLogger.Msg(new string('-', start.Length)); }
public void callupdater() { loadFile(); MelonLogger.Msg("Latest SticksUItilityMod version: " + latestVersion); MelonLogger.Msg("Checking for updates..."); if (File.Exists(modfile)) { try { using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(modfile, new ReaderParameters { ReadWrite = true })) { CustomAttribute melonInfoAttribute = assembly.CustomAttributes.First(a => a.AttributeType.Name == "AssemblyFileVersionAttribute"); assemblyVersion = melonInfoAttribute.ConstructorArguments[0].Value as string; } MelonLogger.Msg("Installed SticksUItilityMod version: " + assemblyVersion); } catch (Exception e) { MelonLogger.Error("Failed to load SticksUItilityMod. Redownloading.\n" + e); } } if (assemblyVersion != latestVersion) { Update(latestVersion); } }
public override void VRChat_OnUiManagerInit() { ClassInjector.RegisterTypeInIl2Cpp <EnableDisableListener>(); Config.RegisterSettings(); // Initialize Constants util Constants.UIInit(); LoadAssetBundle(); // Initialize UIManager UIManager.Init(); // Initialize submenu for the list MenuManager.CreateMainSubMenu(); // TODO: Add opacity options, maybe color too, (maybe even for each stage of ping and fps??) MenuManager.AddMenuListeners(); MenuManager.CreateSubMenus(); PlayerEntry.Patch(Harmony); EntryManager.AddGeneralInfoEntries(); MenuManager.CreateGeneralInfoSubMenus(); MenuManager.AdjustSubMenus(); // Initialize on leave and join events NetworkHooks.NetworkInit(); NetworkHooks.OnPlayerJoin += new Action <Player>((player) => OnPlayerJoin(player)); NetworkHooks.OnPlayerLeave += new Action <Player>((player) => OnPlayerLeave(player)); MelonLogger.Msg("Initialized!"); }
public virtual void Deactivate() { if (!defaultParams.active) { MelonLogger.Msg(type.ToString() + " cancelled"); return; } MelonLogger.Msg(type.ToString() + " deactivated"); defaultParams.active = false; ModStatusHandler.RemoveStatusDisplays(type, ModStatusHandler.UpdateType.Ingame); ModStatusHandler.UpdateStatusDisplays(type, defaultParams.name, defaultParams.cooldown.ToString(), defaultParams.user, defaultParams.color, ModStatusHandler.UpdateType.ScoreOverlay); ModifierManager.ProcessQueue(); MelonCoroutines.Start(CooldownTimer(defaultParams.cooldown)); if (ModifierManager.nukeActive) { foreach (Modifier mod in ModifierManager.activeModifiers) { if (mod.defaultParams.active) { return; } } ModifierManager.nukeActive = false; } }
private static unsafe bool ApplyUser32SetTimerPatch() { IntPtr original = PEUtils.GetExportedFunctionPointerForModule("USER32.dll", "SetTimer"); MelonLogger.Msg($"User32::SetTimer original: 0x{(long)original:X}"); if (original == IntPtr.Zero) { MelonLogger.Error("Failed to find USER32.dll::SetTimer"); return(false); } // We get a native function pointer to User32SetTimerDetour from our current class //IntPtr detourPtr = typeof(Core).GetMethod("User32SetTimerDetour", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer(); IntPtr detourPtr = Marshal.GetFunctionPointerForDelegate((User32SetTimerDelegate)User32SetTimerDetour); if (detourPtr == IntPtr.Zero) { MelonLogger.Error("Failed to find User32SetTimerDetour"); return(false); } // And we patch SetTimer to replace it by our hook MelonLogger.Msg($"Applying USER32.dll::SetTimer Hook at 0x{original.ToInt64():X}"); MelonUtils.NativeHookAttach((IntPtr)(&original), detourPtr); MelonLogger.Msg($"Creating delegate for original USER32.dll::SetTimer (0x{original.ToInt64():X})"); user32SetTimerOriginal = (User32SetTimerDelegate)Marshal.GetDelegateForFunctionPointer(original, typeof(User32SetTimerDelegate)); MelonLogger.Msg("Applied USER32.dll::SetTimer patch"); return(true); }
public AvatarModule() : base(ExpandedMenu.AvatarMenu, FavCatMod.Database.AvatarFavorites, GetListsParent(), false, false) { myCurrentAnnoyingMessage = CanPerformAdditiveActions ? "WillBeObsolete" : (CanShowExistingLists ? "CantAddWithCanny" : "NoFavorites"); MelonLogger.Msg("Adding button to UI - Looking up for Change Button"); var foundAvatarPage = Resources.FindObjectsOfTypeAll <PageAvatar>()?.FirstOrDefault(p => p.transform.Find("Change Button") != null); if (foundAvatarPage == null) { throw new ApplicationException("No avatar page, can't initialize extended favorites"); } myPageAvatar = foundAvatarPage; ExpansionKitApi.GetExpandedMenu(ExpandedMenu.UserDetailsMenu).AddSimpleButton("Search known public avatars", DoSearchKnownAvatars); var expandEnforcer = new GameObject(ExpandEnforcerGameObjectName, new[] { Il2CppType.Of <RectTransform>(), Il2CppType.Of <LayoutElement>() }); expandEnforcer.transform.SetParent(GetListsParent(), false); var layoutElement = expandEnforcer.GetComponent <LayoutElement>(); layoutElement.minWidth = 1534; layoutElement.minHeight = 0; myPageAvatar.gameObject.AddComponent <EnableDisableListener>().OnEnabled += () => { if (FavCatSettings.DontShowAnnoyingMessage == myCurrentAnnoyingMessage || myHasShownAnnoyingMessageThisRun) { return; } ShowAnnoyingMessage(); }; myInitialised = true; }
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(""); }
private static ISupportModule_To Initialize(ISupportModule_From interface_from) { Interface = interface_from; string game_version = ApplicationHandler.GetVersion(); if (string.IsNullOrEmpty(game_version) || game_version.Equals("0")) { game_version = ApplicationHandler.GetBuildGUID(); } MelonLogger.Msg($"Game Version: {game_version}"); SetDefaultConsoleTitleWithGameName(game_version); UnityMappers.RegisterMappers(); try { SceneManager.sceneLoaded += OnSceneLoad; } catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneLoaded override failed: {ex}"); } try { SceneManager.sceneUnloaded += OnSceneUnload; } catch (Exception ex) { MelonLogger.Error($"SceneManager.sceneUnloaded override failed: {ex}"); } return(new SupportModule_To()); }