From a4deef7ff9b6e25f29a65d56a397d55c376f70a9 Mon Sep 17 00:00:00 2001 From: DevDrizzy Date: Sat, 28 Sep 2024 12:54:17 +0500 Subject: [PATCH] Added: New single SkinAPI to be used in all refine plugins Signed-off-by: DevDrizzy --- README.md | 11 +- pom.xml | 45 ++++- .../refinedev/api/tablist/TablistHandler.java | 31 +-- .../tablist/listener/SkinCacheListener.java | 43 ---- .../api/tablist/skin/CachedSkin.java | 38 ---- .../refinedev/api/tablist/skin/SkinCache.java | 187 ------------------ 6 files changed, 69 insertions(+), 286 deletions(-) delete mode 100644 src/main/java/xyz/refinedev/api/tablist/listener/SkinCacheListener.java delete mode 100644 src/main/java/xyz/refinedev/api/tablist/skin/CachedSkin.java delete mode 100644 src/main/java/xyz/refinedev/api/tablist/skin/SkinCache.java diff --git a/README.md b/README.md index e0d69d5..850a163 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ You can initiate and register a TablistAdapter using the following code: ```java import xyz.refinedev.api.tablist.TablistHandler; import xyz.refinedev.api.tablist.adapter.impl.ExampleAdapter; +import xyz.refinedev.api.skin.SkinAPI; import com.github.retrooper.packetevents.PacketEventsAPI; @@ -57,14 +58,22 @@ public class ExamplePlugin extends JavaPlugin { private TablistHandler tablistHandler; private PacketEventsAPI packetEvents; + private SkinAPI skinAPI; @Override public void onEnable() { //this.packetEvents.init(); + //this.skinAPI = new SkinAPI(plugin, gson); + this.tablistHandler = new TablistHandler(plugin); - this.tablistHandler.init(this.packetEvents, new TeamsPacketListener(this.packetEvents)); + this.tablistHandler.init(this.packetEvents); + this.tablistHandler.setupSkinCache(this.skinAPI, true); this.tablistHandler.registerAdapter(new ExampleAdapter(tablist), 20L); } + + public void onDisable() { + //this.skinAPI.unload(); + } } ``` diff --git a/pom.xml b/pom.xml index db723b2..771d44a 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ refine-public - https://maven.refinedev.xyz/repository/public-repo/ + https://maven.refinedev.xyz/public-repo codemc-repo @@ -47,7 +47,7 @@ refine-public - https://maven.refinedev.xyz/repository/public-repo/ + https://maven.refinedev.xyz/public-repo @@ -55,8 +55,32 @@ com.github.retrooper packetevents-spigot - 2.4.0 - provided + 2.5.0 + compile + + + com.google.code.gson + gson + + + org.jetbrains + annotations + + + com.github.retrooper + packetevents-api + + + com.github.retrooper.packetevents + netty-common + + + + + com.github.retrooper + packetevents-api + 2.5.0 + compile com.google.code.gson @@ -66,14 +90,25 @@ org.jetbrains annotations + + com.github.retrooper.packetevents + netty-common + + + xyz.refinedev.api + SkinAPI + 1.0 + compile + + org.projectlombok lombok - 1.18.30 + 1.18.32 jar provided diff --git a/src/main/java/xyz/refinedev/api/tablist/TablistHandler.java b/src/main/java/xyz/refinedev/api/tablist/TablistHandler.java index 4f17e4c..cc3b613 100644 --- a/src/main/java/xyz/refinedev/api/tablist/TablistHandler.java +++ b/src/main/java/xyz/refinedev/api/tablist/TablistHandler.java @@ -1,21 +1,26 @@ package xyz.refinedev.api.tablist; import com.github.retrooper.packetevents.PacketEventsAPI; + +import com.google.common.base.Preconditions; + import lombok.Getter; import lombok.Setter; import lombok.extern.log4j.Log4j2; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scoreboard.Team; + +import xyz.refinedev.api.skin.SkinAPI; + import xyz.refinedev.api.tablist.adapter.TabAdapter; import xyz.refinedev.api.tablist.adapter.impl.ExampleAdapter; -import xyz.refinedev.api.tablist.listener.SkinCacheListener; import xyz.refinedev.api.tablist.listener.TabListener; import xyz.refinedev.api.tablist.listener.TeamsPacketListener; import xyz.refinedev.api.tablist.setup.TabLayout; -import xyz.refinedev.api.tablist.skin.SkinCache; import xyz.refinedev.api.tablist.thread.TablistThread; import java.util.Map; @@ -41,7 +46,7 @@ public class TablistHandler { /** * Our custom Skin Cache that stores every online player's Skin */ - private SkinCache skinCache; + private SkinAPI skinAPI; /** * Tablist Adapter of this instance */ @@ -56,7 +61,6 @@ public class TablistHandler { */ private TablistThread thread; private PacketEventsAPI packetEvents; - private TeamsPacketListener teamsPacketListener; private final boolean debug; @Setter private boolean hook, ignore1_7; private long ticks = 20L; @@ -71,24 +75,27 @@ public TablistHandler(JavaPlugin plugin) { * Set up the PacketEvents instance of this Tablist Handler. * We let the plugin initialize and handle the PacketEvents instance. */ - public void init(PacketEventsAPI packetEventsAPI, TeamsPacketListener listener) { + public void init(PacketEventsAPI packetEventsAPI) { this.packetEvents = packetEventsAPI; this.adapter = new ExampleAdapter(); this.listener = new TabListener(this); - this.teamsPacketListener = listener; - this.packetEvents.getEventManager().registerListener(listener); + this.packetEvents.getEventManager().registerListener(new TeamsPacketListener(this.packetEvents)); Bukkit.getPluginManager().registerEvents(this.listener, plugin); - - this.setupSkinCache(); } - public void setupSkinCache() { - this.skinCache = new SkinCache(); - Bukkit.getPluginManager().registerEvents(new SkinCacheListener(this), plugin); + /** + * Attach the plugin's skin api instance to this tablist. + * + * @param skinAPI {@link SkinAPI} + */ + public void setupSkinCache(SkinAPI skinAPI) { + this.skinAPI = skinAPI; } public void registerAdapter(TabAdapter tabAdapter, long ticks) { + Preconditions.checkNotNull(skinAPI, "SkinAPI was not registered!"); + this.adapter = tabAdapter == null ? new ExampleAdapter() : tabAdapter; if (ticks < 20L) { diff --git a/src/main/java/xyz/refinedev/api/tablist/listener/SkinCacheListener.java b/src/main/java/xyz/refinedev/api/tablist/listener/SkinCacheListener.java deleted file mode 100644 index 84ee911..0000000 --- a/src/main/java/xyz/refinedev/api/tablist/listener/SkinCacheListener.java +++ /dev/null @@ -1,43 +0,0 @@ -package xyz.refinedev.api.tablist.listener; - -import lombok.RequiredArgsConstructor; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerLoginEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import xyz.refinedev.api.tablist.TablistHandler; -import xyz.refinedev.api.tablist.skin.SkinCache; - -/** - *

- * This Project is property of Refine Development.
- * Copyright © 2023, All Rights Reserved.
- * Redistribution of this Project is not allowed.
- *

- * - * @author Drizzy - * @version TablistAPI - * @since 10/18/2023 - */ - -@RequiredArgsConstructor -public class SkinCacheListener implements Listener { - - private final TablistHandler instance; - - @EventHandler - public void onLoginEvent(PlayerLoginEvent event) { - Player player = event.getPlayer(); - - SkinCache cache = instance.getSkinCache(); - cache.registerCache(player); - } - - @EventHandler - public void onQuit(PlayerQuitEvent event) { - Player player = event.getPlayer(); - this.instance.getSkinCache().removeCache(player); - } - -} diff --git a/src/main/java/xyz/refinedev/api/tablist/skin/CachedSkin.java b/src/main/java/xyz/refinedev/api/tablist/skin/CachedSkin.java deleted file mode 100644 index 8c7095b..0000000 --- a/src/main/java/xyz/refinedev/api/tablist/skin/CachedSkin.java +++ /dev/null @@ -1,38 +0,0 @@ -package xyz.refinedev.api.tablist.skin; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -/** - * This Project is property of Refine Development © 2021 - 2023 - * Redistribution of this Project is not allowed - * - * @author Drizzy - * @since 9/2/2023 - * @version TablistAPI - */ - -@Getter @Setter -@RequiredArgsConstructor -public class CachedSkin { - - - private final String name; - private final String value; - private final String signature; - - - public int hashCode() { - return name.hashCode(); - } - - public boolean equals(Object obj) { - if (!(obj instanceof CachedSkin)) return false; - - CachedSkin skin = (CachedSkin) obj; - return skin.getName().equals(this.name) - && skin.getValue().equals(this.value) - && skin.getSignature().equals(this.signature); - } -} diff --git a/src/main/java/xyz/refinedev/api/tablist/skin/SkinCache.java b/src/main/java/xyz/refinedev/api/tablist/skin/SkinCache.java deleted file mode 100644 index 7e17ea0..0000000 --- a/src/main/java/xyz/refinedev/api/tablist/skin/SkinCache.java +++ /dev/null @@ -1,187 +0,0 @@ -package xyz.refinedev.api.tablist.skin; - -import com.comphenix.protocol.wrappers.WrappedGameProfile; -import com.comphenix.protocol.wrappers.WrappedSignedProperty; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import lombok.extern.log4j.Log4j2; -import org.bukkit.entity.Player; -import xyz.refinedev.api.tablist.util.Skin; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; - -/** - * This Project is property of Refine Development © 2021 - 2023 - * Redistribution of this Project is not allowed - * - * @author Drizzy - * @version TablistAPI - * @since 9/2/2023 - */ - -@Log4j2 -public class SkinCache { - - public static final CachedSkin DEFAULT = new CachedSkin("Default", Skin.DEFAULT_SKIN.getValue(), Skin.DEFAULT_SKIN.getSignature());; - - private static final String ASHCON_URL = "https://api.ashcon.app/mojang/v2/user/%s"; - private static final String MOJANG_URL = "https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false"; - - private final Map skinCache = new ConcurrentHashMap<>(); - - /** - * Load and cache this {@link Player}'s Skin - * - * @param player {@link Player} - */ - public void registerCache(Player player) { - CompletableFuture skinFuture = CompletableFuture.supplyAsync(() -> { - try { - WrappedGameProfile wrappedGameProfile = WrappedGameProfile.fromPlayer(player); - WrappedSignedProperty prop = wrappedGameProfile.getProperties().get("textures").iterator().next(); - String value = prop.getValue(); - String signature = prop.getSignature(); - - return new CachedSkin(player.getName(), value, signature); - } catch (Exception e) { - return this.fetchSkin(player, false); - } - }); - - skinFuture.whenComplete((skin, action) -> { - if (skin != null) { - this.skinCache.put(player.getName(), skin); - } - }); - } - - /** - * Get a {@link Player}'s Skin - * - * @param player {@link Player} - * @return {@link } - */ - public CachedSkin getSkin(Player player) { - CachedSkin skin = this.skinCache.get(player.getName()); - if (skin == null) { - this.registerCache(player); - return DEFAULT; - } - return skin; - } - - /** - * Remove this player's skin cache - * - * @param player {@link Player} Player - */ - public void removeCache(Player player) { - this.skinCache.remove(player.getName()); - } - - /** - * Fetch a player's skin from the most optimal server - * - * @param player {@link Player} Player - * @param alternative {@link Boolean} Alternative API - * @return {@link CachedSkin} Skin - */ - public CachedSkin fetchSkin(Player player, boolean alternative) { - String name = player.getName(); - UUID uuid = player.getUniqueId(); - - try { - return alternative ? fetchSkinName(name) : fetchSkinUUID(name, uuid); - } catch (NullPointerException | IOException e) { - if (!alternative) { - return fetchSkin(player, true); - } - - return DEFAULT; - } - } - - /** - * Fetches the given player's skin from mojang's session server - * - * @param uuid {@link UUID} Player's UUID - * @return {@link CachedSkin} Skin - */ - public CachedSkin fetchSkinUUID(String name, UUID uuid) throws IOException{ - String uuidStr = uuid.toString(); - - URL url = new URL(String.format(MOJANG_URL, uuidStr)); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - if (connection.getResponseCode() != 200) { - throw new IOException(); - } else { - try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - StringBuilder sb = new StringBuilder(); - - String inputLine; - while ((inputLine = in.readLine()) != null) { - sb.append(inputLine); - } - - JsonElement element = JsonParser.parseString(sb.toString()); - if (!element.isJsonObject()) return null; - - JsonObject object = element.getAsJsonObject(); - JsonArray jsonProperties = object.get("properties").getAsJsonArray(); - JsonObject property = jsonProperties.get(0).getAsJsonObject(); - - String value = property.get("value").getAsString(); - String signature = property.get("signature").getAsString(); - - return new CachedSkin(name, value, signature); - } - } - } - - /** - * Fetches the given player's skin from Ashcon's skin API session server - * - * @param name {@link String} Player name - * @return {@link CachedSkin} Skin - */ - public CachedSkin fetchSkinName(String name) throws IOException { - URL url = new URL(String.format(ASHCON_URL, name)); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - if (connection.getResponseCode() != 200) { - return new CachedSkin(name, Skin.DEFAULT_SKIN.getValue(), Skin.DEFAULT_SKIN.getSignature()); - } else { - try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { - StringBuilder sb = new StringBuilder(); - - String inputLine; - while ((inputLine = in.readLine()) != null) { - sb.append(inputLine); - } - - JsonElement element = JsonParser.parseString(sb.toString()); - if (!element.isJsonObject()) return null; - - JsonObject object = element.getAsJsonObject(); - JsonObject textures = object.get("textures").getAsJsonObject(); - JsonObject raw = textures.get("raw").getAsJsonObject(); - - String value = raw.get("value").getAsString(); - String signature = raw.get("signature").getAsString(); - - return new CachedSkin(name, value, signature); - } - } - } -}