private static IEnumerator AddAvatarToList(string avatarId, string avatarName) { bool found = false; foreach (string avatarfavId in AvatarFavMod.favoriteAvatarList) { if (avatarfavId == avatarId) { found = true; VRCModLogger.LogError("[VRCheatAvatarfileImporter] Avatar " + avatarName + " already exist in list"); break; } } if (!found) { using (WWW avtrRequest = new WWW(API.GetApiUrl() + "avatars/" + avatarId + "?apiKey=" + AvatarFavMod.GetApiKey())) { yield return(avtrRequest); int rc = WebRequestsUtils.GetResponseCode(avtrRequest); if (rc == 200) { string uuid = APIUser.CurrentUser?.id ?? ""; SerializableApiAvatar aa = null; try { aa = JsonConvert.DeserializeObject <SerializableApiAvatar>(avtrRequest.text); } catch (Exception e) { VRCModLogger.LogError("[VRCheatAvatarfileImporter] Unable to add the avatar " + avatarName + ": Unable to parse the API response. " + e); } if (aa != null) { if (aa.authorId != uuid) { if (aa.releaseStatus == "public") { VRCModLogger.Log("[VRCheatAvatarfileImporter] Adding avatar " + avatarName + " to the database"); yield return(AddAvatar(avatarId, avatarName)); } else { VRCModLogger.Log("[VRCheatAvatarfileImporter] Unable to add the avatar " + avatarName + ": This avatar is not public anymore (private)"); } } else { VRCModLogger.Log("[VRCheatAvatarfileImporter] Unable to add the avatar " + avatarName + ": This avatar is own avatar"); } } } else { VRCModLogger.Log("[VRCheatAvatarfileImporter] Unable to add the avatar " + avatarName + ": This avatar is not public anymore (deleted)"); } } } }
private void AddAvatar(string id) { bool changed = true; if (!favoriteAvatarList.Contains(id)) { favoriteAvatarList.Add(id); changed = true; } if (!savedFavoriteAvatars.ContainsKey(id)) { savedFavoriteAvatars[id] = new SerializableApiAvatar() { id = id }; changed = true; } if (changed) { Save(); } if (useNetwork && !waitingForServer) { new Thread(() => { VRCModNetworkManager.SendRPC("slaynash.avatarfav.addavatar", id, null, (error) => { addError = "Unable to favorite avatar: " + error; favButton.GetComponent <Button>().interactable = true; }); }).Start(); } }
private void handleFreshJSON(string data, bool nosave = false, bool overwrite = true) { lock (favoriteAvatarList) { lock (savedFavoriteAvatars) { // Update Ui favButton.GetComponent <Button>().interactable = true; SimpleAvatarList avatarList = SimpleAvatarList.ParseJSON(data); //favoriteAvatarList.Clear(); foreach (var id in avatarList.avatarIDs) { if (!favoriteAvatarList.Contains(id)) { favoriteAvatarList.Add(id); } if (!savedFavoriteAvatars.ContainsKey(id) || overwrite) { savedFavoriteAvatars[id] = new SerializableApiAvatar() { id = id, authorId = "", releaseStatus = "" } } ; } if (!nosave) { Save(); } avatarAvailables = true; } } }
void OnLevelWasLoaded(int level) { VRCModLogger.Log("[AvatarFav] OnLevelWasLoaded (" + level + ")"); if (level == (Application.platform == RuntimePlatform.WindowsPlayer ? 1 : 2) && !alreadyLoaded) { alreadyLoaded = true; if (instance != null) { Debug.LogWarning("[AvatarFav] Trying to load the same plugin two time !"); return; } instance = this; VRCModLogger.Log("[AvatarFav] Adding button to UI - Looking up for Change Button"); // Add a "Favorite" / "Unfavorite" button over the "Choose" button of the AvatarPage Transform changeButton = null; pageAvatar = Resources.FindObjectsOfTypeAll <PageAvatar>().First(p => (changeButton = p.transform.Find("Change Button")) != null); VRCModLogger.Log("[AvatarFav] Adding avatar check on Change button"); baseChooseEvent = changeButton.GetComponent <Button>().onClick; changeButton.GetComponent <Button>().onClick = new Button.ButtonClickedEvent(); changeButton.GetComponent <Button>().onClick.AddListener(() => { VRCModLogger.Log("[AvatarFav] Fetching avatar releaseStatus for " + pageAvatar.avatar.apiAvatar.name + " (" + pageAvatar.avatar.apiAvatar.id + ")"); ModManager.StartCoroutine(CheckAndWearAvatar()); }); VRCModLogger.Log("[AvatarFav] Adding favorite button to UI - Duplicating Button"); favButton = UnityUiUtils.DuplicateButton(changeButton, "Favorite", new Vector2(0, 80)); favButton.name = "ToggleFavorite"; favButton.gameObject.SetActive(false); favButtonText = favButton.Find("Text").GetComponent <Text>(); favButton.GetComponent <Button>().interactable = false; favButton.GetComponent <Button>().onClick.AddListener(ToggleAvatarFavorite); VRCModLogger.Log("[AvatarFav] Storing default AvatarModel position"); avatarModel = pageAvatar.transform.Find("AvatarModel"); baseAvatarModelPosition = avatarModel.localPosition; FileInfo[] files = new DirectoryInfo(Environment.CurrentDirectory).GetFiles("Avatars.txt", SearchOption.AllDirectories); VRCModLogger.Log("[AvatarFavMod] Found " + files.Length + " Avatars.txt"); if (files.Length > 0) { VRCModLogger.Log("[AvatarFav] Adding import button to UI - Duplicating Button"); Transform importButton = UnityUiUtils.DuplicateButton(changeButton, "Import Avatars", new Vector2(0, 0)); importButton.name = "ImportAvatars"; importButton.GetComponent <RectTransform>().anchoredPosition = new Vector2(560, 371); importButton.GetComponent <Button>().onClick.AddListener(() => { VRCUiPopupManagerUtils.ShowPopup("AvatarFav", "Do you want to import the public avatars from your VRCheat avatar list ?", "Yes", () => { ModManager.StartCoroutine(VRCheatAvatarfileImporter.ImportAvatarfile()); }, "No", () => { VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup(); }); VRCheatAvatarfileImporter.ImportAvatarfile(); }); } favList = AvatarPageHelper.AddNewList("Favorite Avatar List (Unofficial)", 1); // Get Getter of VRCUiContentButton.PressAction applyAvatarField = typeof(VRCUiContentButton).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).First((field) => field.FieldType == typeof(Action)); VRCModLogger.Log("[AvatarFav] Registering VRCModNetwork events"); VRCModNetworkManager.OnAuthenticated += () => { RequestAvatars(); }; VRCModNetworkManager.SetRPCListener("slaynash.avatarfav.serverconnected", (senderId, data) => { if (waitingForServer) { RequestAvatars(); } }); VRCModNetworkManager.SetRPCListener("slaynash.avatarfav.error", (senderId, data) => addError = data); VRCModNetworkManager.SetRPCListener("slaynash.avatarfav.avatarlistupdated", (senderId, data) => { lock (favoriteAvatarList) { // Update Ui favButton.GetComponent <Button>().interactable = true; SerializableApiAvatar[] serializedAvatars = SerializableApiAvatar.ParseJson(data); favoriteAvatarList.Clear(); foreach (SerializableApiAvatar serializedAvatar in serializedAvatars) { favoriteAvatarList.Add(serializedAvatar.id); } avatarAvailables = true; } }); VRCModLogger.Log("[AvatarFav] Adding avatar search list"); if (pageAvatar != null) { VRCUiPageHeader pageheader = VRCUiManagerUtils.GetVRCUiManager().GetComponentInChildren <VRCUiPageHeader>(true); if (pageheader != null) { searchbar = pageheader.searchBar; if (searchbar != null) { VRCModLogger.Log("[AvatarFav] creating avatar search list"); avatarSearchList = AvatarPageHelper.AddNewList("Search Results", 0); avatarSearchList.ClearAll(); avatarSearchList.gameObject.SetActive(false); avatarSearchList.collapsedCount = 50; avatarSearchList.expandedCount = 50; avatarSearchList.collapseRows = 5; avatarSearchList.extendRows = 5; avatarSearchList.contractedHeight = 850f; avatarSearchList.expandedHeight = 850f; avatarSearchList.GetComponent <LayoutElement>().minWidth = 1600f; avatarSearchList.GetComponentInChildren <GridLayoutGroup>(true).constraintCount = 5; avatarSearchList.expandButton.image.enabled = false; VRCModLogger.Log("[AvatarFav] Overwriting search button"); VRCUiManagerUtils.OnPageShown += (page) => { if (page.GetType() == typeof(PageAvatar)) { UiVRCList[] lists = page.GetComponentsInChildren <UiVRCList>(true); foreach (UiVRCList list in lists) { if (list != avatarSearchList && (list.GetType() != typeof(UiAvatarList) || ((int)categoryField.GetValue(list)) != 0)) { list.gameObject.SetActive(true); } else { list.gameObject.SetActive(false); } } VRCModLogger.Log("[AvatarFav] PageAvatar shown. Enabling searchbar next frame"); ModManager.StartCoroutine(EnableSearchbarNextFrame()); } }; VRCModNetworkManager.SetRPCListener("slaynash.avatarfav.searchresults", (senderid, data) => { AddMainAction(() => { if (data.StartsWith("ERROR")) { VRCUiPopupManagerUtils.ShowPopup("AvatarFav", "Unable to fetch avatars: Server returned error: " + data.Substring("ERROR ".Length), "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } else { avatarSearchList.ClearSpecificList(); if (!avatarSearchList.gameObject.activeSelf) { UiVRCList[] lists = pageAvatar.GetComponentsInChildren <UiVRCList>(true); foreach (UiVRCList list in lists) { if (list != avatarSearchList) { list.gameObject.SetActive(false); } } } SerializableApiAvatar[] serializedAvatars = SerializableApiAvatar.ParseJson(data); string[] avatarsIds = new string[serializedAvatars.Length]; for (int i = 0; i < serializedAvatars.Length; i++) { avatarsIds[i] = serializedAvatars[i].id; } avatarSearchList.specificListIds = avatarsIds; if (avatarSearchList.gameObject.activeSelf) { avatarSearchList.Refresh(); } else { avatarSearchList.gameObject.SetActive(true); } } }); }); } else { VRCModLogger.LogError("[AvatarFav] Unable to find search bar"); } } else { VRCModLogger.LogError("[AvatarFav] Unable to find page header"); } } else { VRCModLogger.LogError("[AvatarFav] Unable to find avatar page"); } VRCModLogger.Log("[AvatarFav] AvatarFav Initialised !"); initialised = true; } }
private IEnumerator CheckAndWearAvatar() { //DebugUtils.PrintHierarchy(pageAvatar.avatar.transform, 0); PipelineManager avatarPipelineManager = pageAvatar.avatar.GetComponentInChildren <PipelineManager>(); if (avatarPipelineManager == null) // Avoid avatars locking for builds <625 { VRCModLogger.Log("[AvatarFav] Current avatar prefab name: " + pageAvatar.avatar.transform.GetChild(0).name); if (pageAvatar.avatar.transform.GetChild(0).name == "avatar_loading2(Clone)") { VRCUiPopupManagerUtils.ShowPopup("Error", "Please wait for this avatar to finish loading before wearing it", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } else { baseChooseEvent.Invoke(); } } else { bool copied = false; string avatarBlueprintID = avatarPipelineManager?.blueprintId ?? ""; if (!avatarBlueprintID.Equals("") && !avatarBlueprintID.Equals(pageAvatar.avatar.apiAvatar.id)) { copied = true; } using (WWW avtrRequest = new WWW(API.GetApiUrl() + "avatars/" + (copied ? avatarBlueprintID : pageAvatar.avatar.apiAvatar.id) + "?apiKey=" + GetApiKey())) { yield return(avtrRequest); int rc = WebRequestsUtils.GetResponseCode(avtrRequest); if (rc == 200) { try { string uuid = APIUser.CurrentUser?.id ?? ""; SerializableApiAvatar aa = JsonConvert.DeserializeObject <SerializableApiAvatar>(avtrRequest.text); if (aa.releaseStatus.Equals("public") || aa.authorId.Equals(uuid)) { baseChooseEvent.Invoke(); } else { if (copied) { VRCUiPopupManagerUtils.ShowPopup("Error", "Unable to put this avatar: This avatar is not the original one, and the one is not public anymore (private)", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } else { VRCUiPopupManagerUtils.ShowPopup("Error", "Unable to put this avatar: This avatar is not public anymore (private)", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } } } catch (Exception e) { VRCModLogger.LogError(e.ToString()); VRCUiPopupManagerUtils.ShowPopup("Error", "Unable to put this avatar: Unable to parse API response", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } } else { if (copied) { VRCUiPopupManagerUtils.ShowPopup("Error", "Unable to put this avatar: This avatar is not the original one, and the one is not public anymore (deleted)", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } else { VRCUiPopupManagerUtils.ShowPopup("Error", "Unable to put this avatar: This avatar is not public anymore (deleted)", "Close", () => VRCUiPopupManagerUtils.GetVRCUiPopupManager().HideCurrentPopup()); } } } } }