Skip to content

Commit d6f3895

Browse files
TheNullicornmdashlwHydroPageConnorLinfoot
authored
Add player object (#260)
* Wrap player object in class * Add utility methods to player * Add javadocs for player object * Add javadocs for property accessors * Add get level method to player * Update examples * Fix incorrect network exp * Use getLongProperty instead of getNumberProperty.longValue * Use fallback when displayname is not present * Fix exp calculation Co-authored-by: mdashlw <[email protected]> * Add method for recent GameType * Add method for PetStats * Add methods to check player api visibility * Add rank color & mc version methods to player * Fix incorrect javadocs * Fix javadoc typo * Remove methods that access player settings * Add public constructor to Player * Check for exception in GetPlayerExample * Return UUID instead of String from getUuid * Move GSON into Utilities * Clarify getUuid javadoc Co-authored-by: Noe <[email protected]> * Change getPlusColor to getSelectedPlusColor * Explicitly exit in GetPlayerExample * Clean up uuidFromString Co-authored-by: Noe <[email protected]> * Add hasProperty() to Player * Add ComplexHypixelObject for property methods * Remove extra parenthesis * Simplify uuidFromString * Begin property filter * Let keys be removed from filter * Check for null keys * Document PropertyFilter * Overload player fetch methods w/ filters * Allow batch filtering * Detect & fix key collisions * Respect escapes when applying * Respect escapes in #getProperty(...) * Apply suggestions from code review Co-authored-by: Noe <[email protected]> * Make raw non-null * Change "complex" to "unstable" * Only compile key splitter once * Private constructor & final for Utilities * Remove redundant getProperty() logic * More getProperty() simplifying * Change with() to including() * Remove "keys" from method names * Clarify property javadocs * Update exists() check * Formatting & example change * Fix null players & flip filter/object dependence * Clarify documentation for players * Use ZonedDateTime instead of Date * Use a more informative example * Add a note about getRaw() * Suppression on lazily assigned field * Change toString() for null players * Fix broken import Co-authored-by: mdashlw <[email protected]> Co-authored-by: Noe <[email protected]> Co-authored-by: Connor Linfoot <[email protected]>
1 parent 85feb8b commit d6f3895

File tree

14 files changed

+1019
-43
lines changed

14 files changed

+1019
-43
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ the [Example Code](https://github.com/HypixelDev/PublicAPI/tree/master/hypixel-a
4040
#### Hypixel Maven Repo
4141

4242
```xml
43+
4344
<repository>
4445
<id>Hypixel</id>
4546
<url>https://repo.hypixel.net/repository/Hypixel/</url>

hypixel-api-core/src/main/java/net/hypixel/api/HypixelAPI.java

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
11
package net.hypixel.api;
22

3-
import com.google.gson.Gson;
4-
import com.google.gson.GsonBuilder;
53
import com.google.gson.JsonObject;
64
import com.google.gson.JsonSyntaxException;
7-
import net.hypixel.api.adapters.*;
8-
import net.hypixel.api.data.type.GameType;
9-
import net.hypixel.api.data.type.ServerType;
105
import net.hypixel.api.exceptions.BadResponseException;
116
import net.hypixel.api.exceptions.BadStatusCodeException;
127
import net.hypixel.api.http.HTTPQueryParams;
138
import net.hypixel.api.http.HypixelHttpClient;
149
import net.hypixel.api.http.HypixelHttpResponse;
1510
import net.hypixel.api.reply.*;
1611
import net.hypixel.api.reply.skyblock.*;
12+
import net.hypixel.api.util.PropertyFilter;
1713
import net.hypixel.api.util.ResourceType;
14+
import net.hypixel.api.util.Utilities;
1815

19-
import java.time.ZonedDateTime;
2016
import java.util.UUID;
2117
import java.util.concurrent.CompletableFuture;
2218

2319
public class HypixelAPI {
24-
25-
private static final Gson GSON = new GsonBuilder()
26-
.registerTypeAdapter(UUID.class, new UUIDTypeAdapter())
27-
.registerTypeAdapter(GameType.class, new GameTypeTypeAdapter())
28-
.registerTypeAdapter(ServerType.class, new ServerTypeTypeAdapter())
29-
.registerTypeAdapter(ZonedDateTime.class, new DateTimeTypeAdapter())
30-
.registerTypeAdapterFactory(new BoostersTypeAdapterFactory<>(BoostersReply.Booster.class))
31-
.create();
3220
private static final String BASE_URL = "https://api.hypixel.net/";
3321

3422
private final HypixelHttpClient httpClient;
@@ -81,6 +69,31 @@ public CompletableFuture<PlayerReply> getPlayerByUuid(String player) {
8169
);
8270
}
8371

72+
/**
73+
* Same as {@link #getPlayerByUuid(UUID)}, but the resulting player object will only contain
74+
* properties explicitly included via a {@link PropertyFilter filter}.
75+
*/
76+
public CompletableFuture<PlayerReply> getPlayerByUuid(UUID player, PropertyFilter filter) {
77+
return applyFilterFuture(getPlayerByUuid(player), filter);
78+
}
79+
80+
/**
81+
* Same as {@link #getPlayerByUuid(String)}, but the resulting player object will only contain
82+
* properties explicitly included via a {@link PropertyFilter filter}.
83+
*/
84+
public CompletableFuture<PlayerReply> getPlayerByUuid(String player, PropertyFilter filter) {
85+
return applyFilterFuture(getPlayerByUuid(player), filter);
86+
}
87+
88+
/**
89+
* Same as {@link #getPlayerByName(String)}, but the resulting player object will only contain
90+
* properties explicitly included via a {@link PropertyFilter filter}.
91+
*/
92+
@Deprecated
93+
public CompletableFuture<PlayerReply> getPlayerByName(String player, PropertyFilter filter) {
94+
return applyFilterFuture(getPlayerByName(player), filter);
95+
}
96+
8497
/**
8598
* @param player the minecraft username of the player.
8699
* @return {@link CompletableFuture} containing {@link PlayerReply}
@@ -257,6 +270,16 @@ public CompletableFuture<SkyBlockBazaarReply> getSkyBlockBazaar() {
257270
return get(SkyBlockBazaarReply.class, "skyblock/bazaar");
258271
}
259272

273+
/**
274+
* Applies a {@code filter} to a player object when it is received in an API response.
275+
*/
276+
private CompletableFuture<PlayerReply> applyFilterFuture(CompletableFuture<PlayerReply> future, PropertyFilter filter) {
277+
return future.thenApply(reply -> {
278+
reply.getPlayer().filter(filter);
279+
return reply;
280+
});
281+
}
282+
260283
private <R extends AbstractReply> CompletableFuture<R> get(Class<R> clazz, String request) {
261284
return get(clazz, request, null);
262285
}
@@ -270,16 +293,16 @@ private <R extends AbstractReply> CompletableFuture<R> get(Class<R> clazz, Strin
270293
.thenApply(this::checkResponse)
271294
.thenApply(response -> {
272295
if (clazz == ResourceReply.class) {
273-
return checkReply((R) new ResourceReply(GSON.fromJson(response.getBody(), JsonObject.class)));
296+
return checkReply((R) new ResourceReply(Utilities.GSON.fromJson(response.getBody(), JsonObject.class)));
274297
}
275-
return checkReply(GSON.fromJson(response.getBody(), clazz));
298+
return checkReply(Utilities.GSON.fromJson(response.getBody(), clazz));
276299
});
277300
}
278301

279302
private CompletableFuture<ResourceReply> requestResource(String resource) {
280303
return httpClient.makeRequest(BASE_URL + "resources/" + resource)
281304
.thenApply(this::checkResponse)
282-
.thenApply(response -> checkReply(new ResourceReply(GSON.fromJson(response.getBody(), JsonObject.class))));
305+
.thenApply(response -> checkReply(new ResourceReply(Utilities.GSON.fromJson(response.getBody(), JsonObject.class))));
283306
}
284307

285308
/**
@@ -292,7 +315,7 @@ private HypixelHttpResponse checkResponse(HypixelHttpResponse response) {
292315

293316
String cause;
294317
try {
295-
cause = GSON.fromJson(response.getBody(), JsonObject.class).get("cause").getAsString();
318+
cause = Utilities.GSON.fromJson(response.getBody(), JsonObject.class).get("cause").getAsString();
296319
} catch (JsonSyntaxException ignored) {
297320
cause = "Unknown (body is not json)";
298321
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.hypixel.api.adapters;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.JsonElement;
5+
import com.google.gson.TypeAdapter;
6+
import com.google.gson.stream.JsonReader;
7+
import com.google.gson.stream.JsonToken;
8+
import com.google.gson.stream.JsonWriter;
9+
import net.hypixel.api.reply.PlayerReply.Player;
10+
11+
import java.io.IOException;
12+
13+
public class PlayerTypeAdapter extends TypeAdapter<Player> {
14+
15+
private final TypeAdapter<JsonElement> defaultAdapter;
16+
17+
public PlayerTypeAdapter() {
18+
defaultAdapter = new Gson().getAdapter(JsonElement.class);
19+
}
20+
21+
@Override
22+
public void write(JsonWriter out, Player value) throws IOException {
23+
defaultAdapter.write(out, value.getRaw());
24+
}
25+
26+
@Override
27+
public Player read(JsonReader in) throws IOException {
28+
JsonToken type = in.peek();
29+
if (type == JsonToken.NULL) {
30+
in.nextNull();
31+
return new Player(null);
32+
}
33+
return new Player(defaultAdapter.read(in));
34+
}
35+
}
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.hypixel.api.adapters;
22

33
import com.google.gson.*;
4+
import net.hypixel.api.util.Utilities;
45

56
import java.lang.reflect.Type;
67
import java.util.UUID;
@@ -14,11 +15,6 @@ public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext
1415

1516
@Override
1617
public UUID deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
17-
String uuid = json.getAsString();
18-
if (uuid.contains("-")) {
19-
return UUID.fromString(uuid);
20-
} else {
21-
return UUID.fromString(uuid.substring(0, 8) + "-" + uuid.substring(8, 12) + "-" + uuid.substring(12, 16) + "-" + uuid.substring(16, 20) + "-" + uuid.substring(20, 32));
22-
}
18+
return Utilities.uuidFromString(json.getAsString());
2319
}
2420
}

0 commit comments

Comments
 (0)