From c5b84806405d6e6c5467b98ada6f8c9223398730 Mon Sep 17 00:00:00 2001 From: roro1506HD Date: Tue, 9 Aug 2022 18:18:30 +0200 Subject: [PATCH 1/3] Reworked pets to deprecate enum and to work with 'new' resource endpoints --- .../main/java/net/hypixel/api/HypixelAPI.java | 7 ++ .../java/net/hypixel/api/pets/IPetRarity.java | 9 ++ .../net/hypixel/api/pets/IPetRepository.java | 19 +++ .../java/net/hypixel/api/pets/IPetType.java | 13 ++ .../main/java/net/hypixel/api/pets/Pet.java | 2 +- .../java/net/hypixel/api/pets/PetStats.java | 15 ++- .../java/net/hypixel/api/pets/PetType.java | 17 ++- .../hypixel/api/pets/impl/PetRarityImpl.java | 33 +++++ .../api/pets/impl/PetRepositoryImpl.java | 118 ++++++++++++++++++ .../hypixel/api/pets/impl/PetTypeImpl.java | 50 ++++++++ ...ckwardsCompatibilityPetRepositoryImpl.java | 81 ++++++++++++ .../net/hypixel/api/reply/PlayerReply.java | 12 +- .../java/net/hypixel/api/util/Rarity.java | 27 +++- .../hypixel/api/example/GetPetsExample.java | 71 +++++++++++ 14 files changed, 465 insertions(+), 9 deletions(-) create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRarityImpl.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetTypeImpl.java create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java create mode 100644 hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/HypixelAPI.java b/hypixel-api-core/src/main/java/net/hypixel/api/HypixelAPI.java index 99bb2e78..4bc0694d 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/HypixelAPI.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/HypixelAPI.java @@ -7,6 +7,8 @@ import net.hypixel.api.http.HTTPQueryParams; import net.hypixel.api.http.HypixelHttpClient; import net.hypixel.api.http.HypixelHttpResponse; +import net.hypixel.api.pets.IPetRepository; +import net.hypixel.api.pets.impl.PetRepositoryImpl; import net.hypixel.api.reply.*; import net.hypixel.api.reply.skyblock.*; import net.hypixel.api.reply.skyblock.bingo.SkyBlockBingoDataReply; @@ -222,6 +224,11 @@ public CompletableFuture getResource(String resource) { return requestResource(resource); } + public CompletableFuture getPetRepository() { + return getResource(ResourceType.VANITY_PETS) + .thenApply(PetRepositoryImpl::new); + } + public CompletableFuture getSkyBlockProfile(String profile) { return get(SkyBlockProfileReply.class, "skyblock/profile", HTTPQueryParams.create() diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java new file mode 100644 index 00000000..539d0ef9 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java @@ -0,0 +1,9 @@ +package net.hypixel.api.pets; + +public interface IPetRarity { + + String getName(); + + String getColor(); + +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java new file mode 100644 index 00000000..e923ee64 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java @@ -0,0 +1,19 @@ +package net.hypixel.api.pets; + +import java.util.Collection; + +public interface IPetRepository { + + IPetType getTypeByKey(String type); + + IPetType getTypeByPackage(String typePackage); + + Collection getTypesForRarity(IPetRarity rarity); + + IPetRarity getRarityByName(String name); + + Collection getRarities(); + + Collection getTypes(); + +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java new file mode 100644 index 00000000..34626a06 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java @@ -0,0 +1,13 @@ +package net.hypixel.api.pets; + +public interface IPetType { + + String getKey(); + + String getName(); + + IPetRarity getRarity(); + + String getPackage(); + +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java index b1cf078c..266edd56 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java @@ -13,7 +13,7 @@ public class Pet { 23210, 23750, 24280, 24830, 25380, 25930, 26500, 27070, 27640, 28220, 28810, 29400, 30000 }; - private Map stats; + private final Map stats; private int level; private int experience; private String name; diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java index 976f56e6..746e7230 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java @@ -1,27 +1,34 @@ package net.hypixel.api.pets; +import net.hypixel.api.pets.impl.compatibility.BackwardsCompatibilityPetRepositoryImpl; + import java.util.HashMap; import java.util.Map; public class PetStats { - private Map petMap = new HashMap<>(); + private final Map petMap = new HashMap<>(); + @Deprecated public PetStats(Map> petStats) { + this(BackwardsCompatibilityPetRepositoryImpl.INSTANCE, petStats); + } + + public PetStats(IPetRepository petRepository, Map> petStats) { for (Map.Entry> stringMapEntry : petStats.entrySet()) { try { - petMap.put(PetType.valueOf(stringMapEntry.getKey()), new Pet(stringMapEntry.getValue())); + petMap.put(petRepository.getTypeByKey(stringMapEntry.getKey()), new Pet(stringMapEntry.getValue())); } catch (IllegalArgumentException e) { System.out.println("Invalid pet! " + stringMapEntry.getKey()); } } } - public Pet getPet(PetType type) { + public Pet getPet(IPetType type) { return petMap.get(type); } - public Map getAllPets() { + public Map getAllPets() { return petMap; } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java index 5f72c4ae..1b9a2bb9 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java @@ -2,7 +2,8 @@ import net.hypixel.api.util.Rarity; -public enum PetType { +@Deprecated +public enum PetType implements IPetType { CAT_BLACK("Cat: Black", Rarity.COMMON), CAT_RED("Cat: Red", Rarity.COMMON), @@ -127,6 +128,7 @@ public enum PetType { public static final PetType[] VALUES = values(); + private final String key; private final String name; private final Rarity rarity; @@ -135,15 +137,28 @@ public enum PetType { } PetType(String name, Rarity rarity) { + this.key = name(); this.name = name; this.rarity = rarity; } + @Override + public String getKey() { + return key; + } + + @Override public String getName() { return name; } + @Override public Rarity getRarity() { return rarity; } + + @Override + public String getPackage() { + return null; + } } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRarityImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRarityImpl.java new file mode 100644 index 00000000..d331dac5 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRarityImpl.java @@ -0,0 +1,33 @@ +package net.hypixel.api.pets.impl; + +import com.google.gson.JsonObject; +import net.hypixel.api.pets.IPetRarity; + +public class PetRarityImpl implements IPetRarity { + + private final String name; + private final String color; + + public PetRarityImpl(JsonObject jsonObject) { + this.name = jsonObject.get("name").getAsString(); + this.color = jsonObject.get("color").getAsString(); + } + + @Override + public String getName() { + return name; + } + + @Override + public String getColor() { + return color; + } + + @Override + public String toString() { + return "PetRarityImpl{" + + "name='" + name + '\'' + + ", color='" + color + '\'' + + '}'; + } +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java new file mode 100644 index 00000000..8178cfd2 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java @@ -0,0 +1,118 @@ +package net.hypixel.api.pets.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.hypixel.api.pets.IPetRarity; +import net.hypixel.api.pets.IPetRepository; +import net.hypixel.api.pets.IPetType; +import net.hypixel.api.reply.ResourceReply; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; + +public class PetRepositoryImpl implements IPetRepository { + + private final ResourceReply reply; + + private final Collection rarities; + private final Collection types; + + public PetRepositoryImpl(ResourceReply reply) { + this.reply = reply; + + if (!reply.isSuccess()) { + throw new IllegalStateException("Cannot transform unsuccessful resource reply to pet repository"); + } + + this.rarities = parseCollection("rarities", PetRarityImpl::new); + this.types = parseCollection("types", jsonObject -> new PetTypeImpl(this, jsonObject)); + } + + private Collection parseCollection(String key, Function factory) { + Set set = new HashSet<>(); + + JsonArray jsonArray = reply.getResponse().get(key).getAsJsonArray(); + + for (JsonElement element : jsonArray) { + if (!element.isJsonObject()) { + throw new IllegalStateException("Invalid element in " + key + ": expected json object but got " + element); + } + + set.add(factory.apply(element.getAsJsonObject())); + } + + return Collections.unmodifiableSet(set); + } + + @Override + public IPetType getTypeByKey(String type) { + for (IPetType petType : types) { + if (petType.getKey().equals(type)) { + return petType; + } + } + + return null; + } + + @Override + public IPetType getTypeByPackage(String typePackage) { + for (IPetType petType : types) { + if (petType.getPackage().equals(typePackage)) { + return petType; + } + } + + return null; + } + + @Override + public Collection getTypesForRarity(IPetRarity rarity) { + Set petTypes = new HashSet<>(); + + for (IPetType petType : types) { + if (petType.getRarity().equals(rarity)) { + petTypes.add(petType); + } + } + + return petTypes; + } + + @Override + public IPetRarity getRarityByName(String name) { + for (IPetRarity rarity : rarities) { + if (rarity.getName().equals(name)) { + return rarity; + } + } + + return null; + } + + @Override + public Collection getRarities() { + return rarities; + } + + @Override + public Collection getTypes() { + return types; + } + + @Override + public String toString() { + return "PetRepositoryImpl{" + + "rarities=" + rarities + + ", types=" + types + + '}'; + } + + public ResourceReply getReply() { + return reply; + } +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetTypeImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetTypeImpl.java new file mode 100644 index 00000000..e7ff780f --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetTypeImpl.java @@ -0,0 +1,50 @@ +package net.hypixel.api.pets.impl; + +import com.google.gson.JsonObject; +import net.hypixel.api.pets.IPetRarity; +import net.hypixel.api.pets.IPetType; + +public class PetTypeImpl implements IPetType { + + private final String key; + private final String name; + private final IPetRarity rarity; + private final String typePackage; + + public PetTypeImpl(PetRepositoryImpl repository, JsonObject jsonObject) { + this.key = jsonObject.get("key").getAsString(); + this.name = jsonObject.get("name").getAsString(); + this.rarity = jsonObject.get("rarity").isJsonNull() ? null : repository.getRarityByName(jsonObject.get("rarity").getAsString()); + this.typePackage = jsonObject.get("package").getAsString(); + } + + @Override + public String getKey() { + return key; + } + + @Override + public String getName() { + return name; + } + + @Override + public IPetRarity getRarity() { + return rarity; + } + + @Override + public String getPackage() { + return typePackage; + } + + @Override + public String toString() { + return "PetTypeImpl{" + + "key='" + key + '\'' + + ", name='" + name + '\'' + + ", rarity=" + rarity + + ", typePackage='" + typePackage + '\'' + + '}'; + } +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java new file mode 100644 index 00000000..867545f5 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java @@ -0,0 +1,81 @@ +package net.hypixel.api.pets.impl.compatibility; + +import net.hypixel.api.pets.IPetRarity; +import net.hypixel.api.pets.IPetRepository; +import net.hypixel.api.pets.IPetType; +import net.hypixel.api.pets.PetType; +import net.hypixel.api.util.Rarity; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public class BackwardsCompatibilityPetRepositoryImpl implements IPetRepository { + + public static final BackwardsCompatibilityPetRepositoryImpl INSTANCE = new BackwardsCompatibilityPetRepositoryImpl(); + + private final Collection rarities; + private final Collection types; + + public BackwardsCompatibilityPetRepositoryImpl() { + this.rarities = Arrays.asList(Rarity.values()); + this.types = Arrays.asList(PetType.VALUES); + } + + @Override + public IPetType getTypeByKey(String type) { + for (IPetType petType : types) { + if (petType.getKey().equals(type)) { + return petType; + } + } + + return null; + } + + @Override + public IPetType getTypeByPackage(String typePackage) { + return null; // Always return null, deprecated PetType enum doesn't include packages + } + + @Override + public Collection getTypesForRarity(IPetRarity rarity) { + Set petTypes = new HashSet<>(); + + for (IPetType petType : types) { + if (petType.getRarity().equals(rarity)) { + petTypes.add(petType); + } + } + + return petTypes; + } + + @Override + public IPetRarity getRarityByName(String name) { + try { + return Rarity.valueOf(name); + } catch (IllegalArgumentException ignored) { + return null; + } + } + + @Override + public Collection getRarities() { + return rarities; + } + + @Override + public Collection getTypes() { + return types; + } + + @Override + public String toString() { + return "BackwardsCompatibilityPetRepositoryImpl{" + + "rarities=" + rarities + + ", types=" + types + + '}'; + } +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java b/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java index 93c1ea89..c02c2bc4 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java @@ -6,7 +6,9 @@ import com.google.gson.reflect.TypeToken; import net.hypixel.api.HypixelAPI; import net.hypixel.api.data.type.GameType; +import net.hypixel.api.pets.IPetRepository; import net.hypixel.api.pets.PetStats; +import net.hypixel.api.pets.impl.compatibility.BackwardsCompatibilityPetRepositoryImpl; import net.hypixel.api.util.ILeveling; import net.hypixel.api.util.UnstableHypixelObject; import net.hypixel.api.util.Utilities; @@ -227,7 +229,15 @@ public GameType getMostRecentGameType() { /** * @return Information about the player's lobby pets, or {@code null} if they have none. */ + @Deprecated public PetStats getPetStats() { + return getPetStats(BackwardsCompatibilityPetRepositoryImpl.INSTANCE); + } + + /** + * @return Information about the player's lobby pets, or {@code null} if they have none. + */ + public PetStats getPetStats(IPetRepository petRepository) { JsonObject petStats = getObjectProperty("petStats"); if (petStats == null) { return null; @@ -235,7 +245,7 @@ public PetStats getPetStats() { Type statsObjectType = new TypeToken>>() { }.getType(); - return new PetStats(Utilities.GSON.fromJson(petStats, statsObjectType)); + return new PetStats(petRepository, Utilities.GSON.fromJson(petStats, statsObjectType)); } /** diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/util/Rarity.java b/hypixel-api-core/src/main/java/net/hypixel/api/util/Rarity.java index f55da255..f02610ef 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/util/Rarity.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/util/Rarity.java @@ -1,7 +1,30 @@ package net.hypixel.api.util; -public enum Rarity { +import net.hypixel.api.pets.IPetRarity; - COMMON, RARE, EPIC, LEGENDARY +public enum Rarity implements IPetRarity { + COMMON("GREEN"), + RARE("BLUE"), + EPIC("DARK_PURPLE"), + LEGENDARY("GOLD"), + ; + + private final String name; + private final String color; + + Rarity(String color) { + this.name = name(); + this.color = color; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getColor() { + return color; + } } diff --git a/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java new file mode 100644 index 00000000..d18484f0 --- /dev/null +++ b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java @@ -0,0 +1,71 @@ +package net.hypixel.api.example; + +import net.hypixel.api.HypixelAPI; +import net.hypixel.api.pets.IPetRarity; +import net.hypixel.api.pets.IPetType; +import net.hypixel.api.pets.Pet; +import net.hypixel.api.pets.PetStats; +import net.hypixel.api.reply.PlayerReply; + +import java.util.Map; + +public class GetPetsExample { + public static void main(String[] args) { + HypixelAPI api = ExampleUtil.API; + + api.getPetRepository() + .exceptionally(throwable -> { + throwable.printStackTrace(); + System.exit(0); + return null; + }) + .thenAccept(petRepository -> { + System.out.println("Fetched pet rarities:"); + for (IPetRarity rarity : petRepository.getRarities()) { + System.out.println("\t" + rarity.getName()); + System.out.println("\t\tColor: " + rarity.getColor()); + } + + System.out.println(); + System.out.println("Fetched pet types:"); + + for (IPetType type : petRepository.getTypes()) { + System.out.println("\t" + type.getKey()); + System.out.println("\t\tName: " + type.getName()); + System.out.println("\t\tRarity: " + type.getRarity()); + } + + api.getPlayerByUuid(ExampleUtil.HYPIXEL) + .exceptionally(throwable -> { + throwable.printStackTrace(); + System.exit(0); + return null; + }) + .thenAccept(playerReply -> { + PlayerReply.Player player = playerReply.getPlayer(); + + if (!player.exists()) { + System.err.println("Player not found!"); + System.exit(0); + return; + } + + PetStats petStats = player.getPetStats(petRepository); + + System.out.println("Pet stats of \"" + player.getName() + "\":"); + + if (petStats == null) { + System.out.println("No pet stats found for player."); + } else { + for (Map.Entry entry : petStats.getAllPets().entrySet()) { + System.out.println("\t" + entry.getKey().getKey() + ": " + entry.getValue().getLevel()); + } + } + + System.exit(0); + }); + }); + + ExampleUtil.await(); + } +} From 2a93797dc5bc6fff168f037480b3d7fc82036b8c Mon Sep 17 00:00:00 2001 From: roro1506HD Date: Thu, 15 Jun 2023 15:08:52 +0200 Subject: [PATCH 2/3] Added javadoc and added IPetRepository#hasPlayerUnlocked --- .../java/net/hypixel/api/pets/IPetRarity.java | 14 +++++ .../net/hypixel/api/pets/IPetRepository.java | 48 ++++++++++++++++- .../java/net/hypixel/api/pets/IPetType.java | 16 ++++++ .../main/java/net/hypixel/api/pets/Pet.java | 37 +++++++++++++ .../java/net/hypixel/api/pets/PetStats.java | 42 ++++++++++++++- .../java/net/hypixel/api/pets/PetType.java | 5 ++ .../pets/impl/AbstractPetRepositoryImpl.java | 54 +++++++++++++++++++ .../api/pets/impl/PetRepositoryImpl.java | 3 +- ...ckwardsCompatibilityPetRepositoryImpl.java | 8 +-- .../net/hypixel/api/reply/PlayerReply.java | 1 + .../hypixel/api/example/GetPetsExample.java | 2 +- 11 files changed, 221 insertions(+), 9 deletions(-) create mode 100644 hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/AbstractPetRepositoryImpl.java diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java index 539d0ef9..c1f8ce48 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRarity.java @@ -2,8 +2,22 @@ public interface IPetRarity { + /** + * Retrieves the name of this pet rarity. + * This is only for pets and should not be mistaken with {@link net.hypixel.api.util.Rarity}. + * Even though they currently are the same values, this might change in the future and should be used accordingly. + * + * @return the name of this rarity + */ String getName(); + /** + * Retrieves the color of this pet rarity + * This is only for pets and should not be mistaken with {@link net.hypixel.api.util.Rarity}. + * Even though they currently are the same values, this might change in the future and should be used accordingly. + * + * @return the color of this rarity + */ String getColor(); } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java index e923ee64..4212204b 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetRepository.java @@ -1,19 +1,65 @@ package net.hypixel.api.pets; +import net.hypixel.api.reply.PlayerReply.Player; + import java.util.Collection; public interface IPetRepository { - IPetType getTypeByKey(String type); + /** + * Gets the pet type associated with the provided key parameter + * A pet type is an object holding the pet's key, name, rarity and package. + * + * @param key the key of the pet + * @return {@code null} if no pet type matches the key, otherwise the pet type associated with that key + */ + IPetType getTypeByKey(String key); + /** + * Gets the pet type associated with the provided package parameter + * A pet type is an object holding the pet's key, name, rarity and package. + * + * @param typePackage the package of the pet + * @return {@code null} if using + * {@link net.hypixel.api.pets.impl.compatibility.BackwardsCompatibilityPetRepositoryImpl} or if no pet type + * matches the package, otherwise the pet type associated with that package + */ IPetType getTypeByPackage(String typePackage); + /** + * Lists all pets matching the given {@link IPetRarity} + * + * @param rarity The rarity of the pets + * @return A collection (usually a {@link java.util.Set}) that contains all matched pets. If no pets are found, + * this returns an empty collection. + */ Collection getTypesForRarity(IPetRarity rarity); + /** + * Gets the pet rarity matching the provided name + * + * @param name the name of the rarity + * @return {@code null} if no rarity matches the provided name, otherwise returns the matched rarity + */ IPetRarity getRarityByName(String name); + /** + * Gets if a player has unlocked the specified {@link IPetType} + * + * @param type the pet type the player must have + * @param player the player to check against + * @return {@code true} if the player has unlocked the pet, otherwise {@code false} + */ + boolean hasPlayerUnlocked(IPetType type, Player player); + + /** + * @return a collection of all the cached rarities + */ Collection getRarities(); + /** + * @return a collection of all the cached pet types + */ Collection getTypes(); } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java index 34626a06..5120e134 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/IPetType.java @@ -2,12 +2,28 @@ public interface IPetType { + /** + * @return the key of this pet type + */ String getKey(); + /** + * @return the name of this pet type + */ String getName(); + /** + * Note that the rarity can be {@code null} + * + * @return the rarity of this pet type + */ IPetRarity getRarity(); + /** + * Note that the package is always {@code null} when using the backwards-compatible repository. + * + * @return the package of this pet type + */ String getPackage(); } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java index 266edd56..3471ba75 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/Pet.java @@ -33,10 +33,20 @@ public Pet(Map stats) { updateLevel(); } + /** + * Gets the custom name of the pet, if present + * + * @return {@code null} if no custom name has been set for the pet, otherwise returns the custom name + */ public String getName() { return name; } + /** + * Gets the average happiness, what we mean by "average happiness" is the mean value of all the {@link PetAttribute} + * + * @return the average happiness, with a min value of {@code 0.0} + */ public double getAverageHappiness() { double attributeAverage = 0; for (PetAttribute attribute : PetAttribute.values()) { @@ -46,6 +56,12 @@ public double getAverageHappiness() { return attributeAverage / PetAttribute.values().length; } + /** + * Gets the value associated with the attribute + * + * @param attribute the attribute + * @return the value associated with the value, or {@code 1} if not found or not a number + */ public int getAttribute(PetAttribute attribute) { @SuppressWarnings("unchecked") Map attributeObject = (Map) stats.get(attribute.name()); @@ -71,6 +87,11 @@ public int getAttribute(PetAttribute attribute) { return Math.max(0, Math.round(value - iterations * attribute.getDecay())); } + /** + * Updates the cached level based on the experience + * + * @return {@code false} no matter what + */ public boolean updateLevel() { int xp = experience; int level = 1; @@ -86,10 +107,21 @@ public boolean updateLevel() { return false; } + /** + * Gets the level of this pet + * + * @return the level + */ public int getLevel() { return level; } + /** + * Gets the experience required to level up to the provided level + * + * @param level the target level + * @return the experience amount required to reach the provided level + */ public int getExperienceUntilLevel(int level) { int xp = 0; for (int i = 0; i < Math.min(level - 1, 100); i++) { @@ -98,6 +130,11 @@ public int getExperienceUntilLevel(int level) { return xp; } + /** + * Gets the experience amount starting from the current level + * + * @return the current experience starting from the current level + */ public int getLevelProgress() { return experience - getExperienceUntilLevel(level); } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java index 746e7230..18bd43e3 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetStats.java @@ -1,6 +1,7 @@ package net.hypixel.api.pets; import net.hypixel.api.pets.impl.compatibility.BackwardsCompatibilityPetRepositoryImpl; +import net.hypixel.api.reply.PlayerReply; import java.util.HashMap; import java.util.Map; @@ -24,11 +25,50 @@ public PetStats(IPetRepository petRepository, Map> p } } + /** + * Gets a specific pet based on its pet type. Each player can only have one pet per type + * + * Note: If this returns {@code null}, it doesn't mean that the player hasn't unlocked the pet. + * What it does mean though, is that the player hasn't given any attributes nor a name to the pet + * + * To check if a player has unlocked a pet, use {@link IPetRepository#hasPlayerUnlocked(IPetType, PlayerReply.Player)} + * + * @param type the pet type to retrieve + * @return {@code null} if the player hasn't given a name and hasn't given any {@link PetAttribute}, + * otherwise the {@link Pet} instance + */ public Pet getPet(IPetType type) { return petMap.get(type); } - public Map getAllPets() { + /** + * Lists all the pets the player have + * + * @return a map filled with all the pets the player have + * @deprecated Use {@link #listAllPets()} instead + */ + @Deprecated + public Map getAllPets() { + Map oldPets = new HashMap<>(); + + for (Map.Entry entry : petMap.entrySet()) { + if (!(entry.getKey() instanceof PetType)) { + oldPets.clear(); + throw new IllegalStateException("Cannot use #getAllPets when using the new pet repository. Please use #listAllPets"); + } + + oldPets.put((PetType) entry.getKey(), entry.getValue()); + } + + return oldPets; + } + + /** + * Lists all the pets the player have + * + * @return a map filled with all the pets the player have + */ + public Map listAllPets() { return petMap; } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java index 1b9a2bb9..8ceead24 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/PetType.java @@ -2,6 +2,10 @@ import net.hypixel.api.util.Rarity; +/** + * The old and deprecated enum for the pet types + * @deprecated Consider using the {@link IPetRepository} + */ @Deprecated public enum PetType implements IPetType { @@ -162,3 +166,4 @@ public String getPackage() { return null; } } + diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/AbstractPetRepositoryImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/AbstractPetRepositoryImpl.java new file mode 100644 index 00000000..e183d784 --- /dev/null +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/AbstractPetRepositoryImpl.java @@ -0,0 +1,54 @@ +package net.hypixel.api.pets.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import net.hypixel.api.pets.IPetRepository; +import net.hypixel.api.pets.IPetType; +import net.hypixel.api.pets.PetType; +import net.hypixel.api.reply.PlayerReply; + +public abstract class AbstractPetRepositoryImpl implements IPetRepository { + + @Override + public boolean hasPlayerUnlocked(IPetType type, PlayerReply.Player player) { + if (type instanceof PetType) { + throw new IllegalArgumentException("Old PetType enum doesn't include packages, which are required to use this method. Please use the new pet repository"); + } + + String packageName = type.getPackage(); + + if (packageName == null) { + throw new IllegalArgumentException("The provided pet type doesn't have a package, which is required to use this method"); + } + + JsonObject vanityMeta = player.getObjectProperty("vanityMeta"); + + // Make sure vanityMeta is present as well as the inner packages array + if (vanityMeta == null || !vanityMeta.has("packages")) { + return false; + } + + JsonElement packages = vanityMeta.get("packages"); + + // Check if packages is an array + if (!(packages instanceof JsonArray)) { + return false; + } + + JsonArray packagesArray = packages.getAsJsonArray(); + + // Loop through packages until we find the pet type, if one matches + for (JsonElement element : packagesArray) { + // Make sure the element is a json primitive, so we can #getAsString without worry + if (element instanceof JsonPrimitive) { + if (element.getAsString().equalsIgnoreCase(packageName)) { + return true; + } + } + } + + return false; + } +} diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java index 8178cfd2..0f057150 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/PetRepositoryImpl.java @@ -4,7 +4,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import net.hypixel.api.pets.IPetRarity; -import net.hypixel.api.pets.IPetRepository; import net.hypixel.api.pets.IPetType; import net.hypixel.api.reply.ResourceReply; @@ -14,7 +13,7 @@ import java.util.Set; import java.util.function.Function; -public class PetRepositoryImpl implements IPetRepository { +public class PetRepositoryImpl extends AbstractPetRepositoryImpl { private final ResourceReply reply; diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java index 867545f5..1498b857 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/pets/impl/compatibility/BackwardsCompatibilityPetRepositoryImpl.java @@ -1,9 +1,9 @@ package net.hypixel.api.pets.impl.compatibility; import net.hypixel.api.pets.IPetRarity; -import net.hypixel.api.pets.IPetRepository; import net.hypixel.api.pets.IPetType; import net.hypixel.api.pets.PetType; +import net.hypixel.api.pets.impl.AbstractPetRepositoryImpl; import net.hypixel.api.util.Rarity; import java.util.Arrays; @@ -11,7 +11,7 @@ import java.util.HashSet; import java.util.Set; -public class BackwardsCompatibilityPetRepositoryImpl implements IPetRepository { +public class BackwardsCompatibilityPetRepositoryImpl extends AbstractPetRepositoryImpl { public static final BackwardsCompatibilityPetRepositoryImpl INSTANCE = new BackwardsCompatibilityPetRepositoryImpl(); @@ -24,9 +24,9 @@ public BackwardsCompatibilityPetRepositoryImpl() { } @Override - public IPetType getTypeByKey(String type) { + public IPetType getTypeByKey(String key) { for (IPetType petType : types) { - if (petType.getKey().equals(type)) { + if (petType.getKey().equals(key)) { return petType; } } diff --git a/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java b/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java index c02c2bc4..1fef2305 100644 --- a/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java +++ b/hypixel-api-core/src/main/java/net/hypixel/api/reply/PlayerReply.java @@ -228,6 +228,7 @@ public GameType getMostRecentGameType() { /** * @return Information about the player's lobby pets, or {@code null} if they have none. + * @deprecated Use {@link #getPetStats(IPetRepository)} instead */ @Deprecated public PetStats getPetStats() { diff --git a/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java index d18484f0..b2c4a7d7 100644 --- a/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java +++ b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java @@ -57,7 +57,7 @@ public static void main(String[] args) { if (petStats == null) { System.out.println("No pet stats found for player."); } else { - for (Map.Entry entry : petStats.getAllPets().entrySet()) { + for (Map.Entry entry : petStats.listAllPets().entrySet()) { System.out.println("\t" + entry.getKey().getKey() + ": " + entry.getValue().getLevel()); } } From 39160bdf5809e52686779619da08694c24a574f5 Mon Sep 17 00:00:00 2001 From: roro1506HD Date: Thu, 15 Jun 2023 15:31:19 +0200 Subject: [PATCH 3/3] Updated get pets example --- .../java/net/hypixel/api/example/GetPetsExample.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java index b2c4a7d7..59c7a61f 100644 --- a/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java +++ b/hypixel-api-example/src/main/java/net/hypixel/api/example/GetPetsExample.java @@ -35,6 +35,8 @@ public static void main(String[] args) { System.out.println("\t\tRarity: " + type.getRarity()); } + System.out.println(); + api.getPlayerByUuid(ExampleUtil.HYPIXEL) .exceptionally(throwable -> { throwable.printStackTrace(); @@ -62,6 +64,15 @@ public static void main(String[] args) { } } + IPetType catBlack = petRepository.getTypeByKey("CAT_BLACK"); + IPetType blaze = petRepository.getTypeByKey("BLAZE"); + + System.out.println(); + System.out.println("Does " + player.getName() + " have the " + catBlack.getName() + + " pet? " + (petRepository.hasPlayerUnlocked(catBlack, player) ? "Yes." : "No.")); + System.out.println("Does " + player.getName() + " have the " + blaze.getName() + + " pet? " + (petRepository.hasPlayerUnlocked(blaze, player) ? "Yes." : "No.")); + System.exit(0); }); });