Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/discord.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Discord Endpoint
Accessed at https://api.earthmc.net/v3/aurora/discord?query=
Accessed at https://api.earthmc.net/v4/discord

Determine a player's Discord ID from their Minecraft UUID and vice versa using DiscordSRV's link feature.
The player needs to have linked their account beforehand (`/discord link` in game).
Expand Down
88 changes: 0 additions & 88 deletions docs/global-player-stats.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/location.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Location Endpoint
Accessed at https://api.earthmc.net/v3/aurora/location
Accessed at https://api.earthmc.net/v4/location

Get Towny-related information on a specific location, for instance if it belongs to a town.

Expand Down
2 changes: 1 addition & 1 deletion docs/mysterymaster.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Mystery Master Endpoint
Accessed at https://api.earthmc.net/v3/aurora/mm
Accessed at https://api.earthmc.net/v4/mm

The following is an example of the response to a **GET** request to the above URL.
```json5
Expand Down
2 changes: 1 addition & 1 deletion docs/nations.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nations Endpoint
Accessed at https://api.earthmc.net/v3/aurora/nations
Accessed at https://api.earthmc.net/v4/nations

The following is an abridged version of the response to a **GET** request to the above URL which contains every currently registered Towny nation within a JSON array.
```json5
Expand Down
2 changes: 1 addition & 1 deletion docs/nearby.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Nearby Endpoint
Accessed at https://api.earthmc.net/v3/aurora/nearby
Accessed at https://api.earthmc.net/v4/nearby

Returns an array of all the elements of type `search_type` (`TOWN`) in a given `radius` of a target location of type `target_type` (`TOWN`|`COORDINATE`).

Expand Down
2 changes: 1 addition & 1 deletion docs/online.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Online Players Endpoint
Accessed at https://api.earthmc.net/v3/aurora/online
Accessed at https://api.earthmc.net/v4/online

Returns a JSON object with a count of how many players are online and their names and uuid. Players that have opted themselves out of appearing in the API will not
appear in the players array, but are included in the count.
Expand Down
2 changes: 1 addition & 1 deletion docs/players.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Players Endpoint
Accessed at https://api.earthmc.net/v3/aurora/players
Accessed at https://api.earthmc.net/v4/players

The following is an abridged version of the response to a **GET** request to the above URL which contains every currently registered Towny resident within a JSON array.
```json5
Expand Down
2 changes: 1 addition & 1 deletion docs/quarters.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Quarters Endpoint
Accessed at https://api.earthmc.net/v3/aurora/quarters
Accessed at https://api.earthmc.net/v4/quarters

The following is an abridged version of the response to a **GET** request to the above URL which contains every currently registered quarter within a JSON array.
```json5
Expand Down
2 changes: 1 addition & 1 deletion docs/server.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Server Endpoint
Accessed at https://api.earthmc.net/v3/aurora/
Accessed at https://api.earthmc.net/v4/

The following is an example of the response to a **GET** request to the above URL.
```json5
Expand Down
2 changes: 1 addition & 1 deletion docs/shop.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Shop Endpoint
Accessed at https://api.earthmc.net/v4/aurora/shop
Accessed at https://api.earthmc.net/v4/shop

The shop endpoint provides information about player-owned QuickShops.
It is important to note that the information here is not public, and players can only access their own shops' information, using their API key.
Expand Down
4 changes: 2 additions & 2 deletions docs/sse.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Server Sent Events (SSE)
Accessed at https://api.earthmc.net/v4/aurora/events
Accessed at https://api.earthmc.net/v4/events

Server sent events allow clients to connect & listen to specific events sent by the server.

Expand All @@ -19,7 +19,7 @@ These are the current events available:
"ShopSoldItem", "ShopBoughtItem", "ShopOutOfStock", "ShopOutOfSpace", "ShopOutOfGold"
```
Clients must specify which events to listen to by specifying a `?listen=` query parameter in the URL.
Example: `https://api.earthmc.net/v4/aurora/events?listen=NewDay,TownDeleted,NationRenamed`. This would make it so only these events are sent to the client.
Example: `https://api.earthmc.net/v4/events?listen=NewDay,TownDeleted,NationRenamed`. This would make it so only these events are sent to the client.

Most Town events include a `town` field with the name & UUID of the town. The same applies to nations with a `nation` field.
### Authorized player events
Expand Down
2 changes: 1 addition & 1 deletion docs/towns.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Towns Endpoint
Accessed at https://api.earthmc.net/v3/aurora/towns
Accessed at https://api.earthmc.net/v4/towns

The following is an abridged version of the response to a **GET** request to the above URL which contains every currently registered Towny town within a JSON array.
```json5
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/earthmc/emcapi/EMCAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public Integrations integrations() {

public String getURLPath() {
String version = getConfig().getString("networking.api_version", "3");
return "v" + version + "/" + getConfig().getString("networking.url_path");
return "v" + version;
}

public APIDatabase getDatabase() {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/net/earthmc/emcapi/endpoint/ShopEndpoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,30 @@
import org.jetbrains.annotations.Nullable;
import org.maxgamer.quickshop.api.shop.Shop;

import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

public class ShopEndpoint extends PostEndpoint<List<Shop>> {
private final QuickShopIntegration integration;
private static final Map<UUID, Long> LAST_QUERY_MAP = new ConcurrentHashMap<>();
private static final int COOLDOWN_SECONDS = 3600;

public ShopEndpoint(EMCAPI plugin) {
super(plugin);
this.integration = plugin.integrations().quickShopIntegration();
plugin.getServer().getAsyncScheduler().runAtFixedRate(plugin, t ->
LAST_QUERY_MAP.entrySet().removeIf(entry -> entry.getValue() < Instant.now().getEpochSecond() - COOLDOWN_SECONDS),
1,
1,
TimeUnit.HOURS
);
}

@Override
Expand All @@ -48,6 +59,9 @@ public JsonElement getJsonElement(List<Shop> object, @Nullable String key) {
final Map<String, JsonElement> shops = new ConcurrentHashMap<>();
int counter = 0;
UUID keyOwner = KeyManager.getKeyOwner(key);
if (keyOwner == null) {
return null;
}

final List<CompletableFuture<Void>> shopFutures = new ArrayList<>();

Expand All @@ -72,6 +86,10 @@ public JsonElement getJsonElement(List<Shop> object, @Nullable String key) {
}

CompletableFuture.allOf(shopFutures.toArray(new CompletableFuture[]{})).join();
if (shops.isEmpty()) {
LAST_QUERY_MAP.put(keyOwner, Instant.now().getEpochSecond());
return null;
}

final JsonObject shopsObject = new JsonObject();
for (final Map.Entry<String, JsonElement> entry : shops.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.earthmc.emcapi.endpoint;
package net.earthmc.emcapi.endpoint.legacy;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.TownyEconomyHandler;
import com.palmergames.bukkit.towny.object.Resident;
import github.scarsz.discordsrv.DiscordSRV;
import io.javalin.http.BadRequestResponse;
import net.earthmc.emcapi.EMCAPI;
import net.earthmc.emcapi.manager.KeyManager;
Expand All @@ -16,8 +17,10 @@

import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;

public class PlayersEndpoint extends PostEndpoint<Resident> {
private static final Pattern DISCORD_ID_PATTERN = Pattern.compile("^\\d{17,19}$");

public PlayersEndpoint(final EMCAPI plugin) {
super(plugin);
Expand All @@ -34,6 +37,12 @@ public Resident getObjectOrNull(JsonElement element, @Nullable String key) {
} catch (IllegalArgumentException e) {
resident = TownyAPI.getInstance().getResident(string);
}
if (resident == null && DISCORD_ID_PATTERN.matcher(string).find()) {
UUID uuid = getUUIDFromDiscordId(string);
if (uuid != null) {
resident = TownyAPI.getInstance().getResident(uuid);
}
}

if (resident != null && plugin.getOptOut().playerOptedOut(resident.getUUID()) && !resident.getUUID().equals(KeyManager.getKeyOwner(key))) {
return null;
Expand Down Expand Up @@ -85,6 +94,8 @@ public JsonElement getJsonElement(Resident resident, @Nullable String key) {

playerObject.add("friends", EndpointUtils.getResidentArray(resident.getFriends()));

playerObject.addProperty("discord", getDiscordId(resident.getUUID()));

return playerObject;
}

Expand All @@ -97,4 +108,20 @@ private JsonArray getRankArray(List<String> ranks) {

return jsonArray;
}

private String getDiscordId(UUID uuid) {
if (!plugin.integrations().discordIntegration().isEnabled()) {
return null;
}
return DiscordSRV.getPlugin().getAccountLinkManager().getDiscordId(uuid);
}

private UUID getUUIDFromDiscordId(String discordId) {
if (!plugin.integrations().discordIntegration().isEnabled()) {
return null;
}
if (!DISCORD_ID_PATTERN.matcher(discordId).find()) return null;

return DiscordSRV.getPlugin().getAccountLinkManager().getUuid(discordId);
}
}
15 changes: 0 additions & 15 deletions src/main/java/net/earthmc/emcapi/manager/EndpointManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import io.javalin.Javalin;
import io.javalin.http.BadRequestResponse;
import net.earthmc.emcapi.EMCAPI;
import net.earthmc.emcapi.endpoint.DiscordEndpoint;
import net.earthmc.emcapi.endpoint.LocationEndpoint;
import net.earthmc.emcapi.endpoint.MysteryMasterEndpoint;
import net.earthmc.emcapi.endpoint.NearbyEndpoint;
Expand All @@ -21,7 +20,6 @@
import net.earthmc.emcapi.endpoint.towny.list.PlayersListEndpoint;
import net.earthmc.emcapi.endpoint.towny.list.QuartersListEndpoint;
import net.earthmc.emcapi.endpoint.towny.list.TownsListEndpoint;
import net.earthmc.emcapi.integration.DiscordIntegration;
import net.earthmc.emcapi.integration.MysteryMasterIntegration;
import net.earthmc.emcapi.integration.QuartersIntegration;
import net.earthmc.emcapi.integration.QuickShopIntegration;
Expand Down Expand Up @@ -50,7 +48,6 @@ public void loadEndpoints() {
loadQuartersEndpoint();
loadLocationEndpoint();
loadNearbyEndpoint();
loadDiscordEndpoint();
loadOnlinePlayersEndpoint();
loadMysteryMasterEndpoint();
loadShopsEndpoint();
Expand Down Expand Up @@ -141,18 +138,6 @@ private void loadNearbyEndpoint() {
});
}

private void loadDiscordEndpoint() {
DiscordEndpoint discordEndpoint = new DiscordEndpoint(plugin);
final DiscordIntegration discordIntegration = plugin.integrations().discordIntegration();

javalin.post(URLPath + "/discord", ctx -> {
discordIntegration.throwIfDisabled();

QueryBody parsedBody = parseBody(ctx.body());
ctx.json(discordEndpoint.lookup(parsedBody.query, parsedBody.template, parsedBody.key));
});
}

private void loadOnlinePlayersEndpoint() {
OnlineEndpoint onlineEndpoint = new OnlineEndpoint();
javalin.get(URLPath + "/online", ctx -> ctx.json(onlineEndpoint.lookup()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import io.javalin.http.BadRequestResponse;
import kotlin.Pair;
import net.earthmc.emcapi.EMCAPI;
import net.earthmc.emcapi.endpoint.DiscordEndpoint;
import net.earthmc.emcapi.endpoint.legacy.DiscordEndpoint;
import net.earthmc.emcapi.endpoint.legacy.DocumentationEndpoint;
import net.earthmc.emcapi.endpoint.LocationEndpoint;
import net.earthmc.emcapi.endpoint.legacy.MudkipEndpoint;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,28 @@ public String lookup(JsonArray queryArray, @Nullable JsonObject template, @Nulla
if (object == null) {
continue;
}
jsonArray.add(getTemplateJsonElement(object, template, key));
JsonElement formatted = getTemplateJsonElement(object, template, key);
if (formatted == null) {
continue;
}
jsonArray.add(formatted);
}

return jsonArray.toString();
}

/**
* @param element The query provided by the user
* @param key The API key, if any provided
* @return The queried object if found, otherwise null
*/
public abstract T getObjectOrNull(JsonElement element, @Nullable String key);

/**
* @param object The object to describe
* @param key The API key, if any provided
* @return A JsonElement describing this object, or null if anything went wrong (E.g. cooldown, unauthorized key)
*/
public abstract JsonElement getJsonElement(T object, @Nullable String key);

public JsonElement getTemplateJsonElement(T object, JsonObject template, @Nullable String key) {
Expand Down
Loading
Loading