From 2a1f44b1bb27b92ffbdb5d9f5b1be15984031f9f Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Sun, 7 Jan 2024 18:26:17 +0100 Subject: [PATCH] expose skin texture methods in api --- .../java/lol/pyr/znpcsplus/api/skin/Skin.java | 6 ++++ .../znpcsplus/api/skin/SkinDescriptor.java | 7 ++++ .../citizens/model/traits/SkinTrait.java | 4 +-- .../conversion/znpcs/ZNpcImporter.java | 5 ++- .../znpcsplus/skin/BaseSkinDescriptor.java | 6 ++-- .../skin/SkinDescriptorFactoryImpl.java | 2 +- .../skin/{Skin.java => SkinImpl.java} | 27 ++++++++++++--- .../znpcsplus/skin/cache/MojangSkinCache.java | 34 +++++++++---------- .../skin/descriptor/FetchingDescriptor.java | 6 ++-- .../skin/descriptor/MirrorDescriptor.java | 6 ++-- .../skin/descriptor/PrefetchedDescriptor.java | 12 +++---- 11 files changed, 72 insertions(+), 43 deletions(-) create mode 100644 api/src/main/java/lol/pyr/znpcsplus/api/skin/Skin.java rename plugin/src/main/java/lol/pyr/znpcsplus/skin/{Skin.java => SkinImpl.java} (79%) diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/skin/Skin.java b/api/src/main/java/lol/pyr/znpcsplus/api/skin/Skin.java new file mode 100644 index 0000000..53ed651 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/api/skin/Skin.java @@ -0,0 +1,6 @@ +package lol.pyr.znpcsplus.api.skin; + +public interface Skin { + String getTexture(); + String getSignature(); +} diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/skin/SkinDescriptor.java b/api/src/main/java/lol/pyr/znpcsplus/api/skin/SkinDescriptor.java index 9d849fe..2e93207 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/skin/SkinDescriptor.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/skin/SkinDescriptor.java @@ -1,4 +1,11 @@ package lol.pyr.znpcsplus.api.skin; +import org.bukkit.entity.Player; + +import java.util.concurrent.CompletableFuture; + public interface SkinDescriptor { + CompletableFuture fetch(Player player); + Skin fetchInstant(Player player); + boolean supportsInstant(Player player); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java index 439c9ff..d21ab4e 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/SkinTrait.java @@ -4,7 +4,7 @@ import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; import lol.pyr.znpcsplus.npc.NpcImpl; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; @@ -21,7 +21,7 @@ public class SkinTrait extends SectionCitizensTrait { public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { String texture = section.getString("textureRaw"); String signature = section.getString("signature"); - if (texture != null && signature != null) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(texture, signature))); + if (texture != null && signature != null) npc.setProperty(registry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new SkinImpl(texture, signature))); return npc; } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java index 3ecdad1..52ea3c1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java @@ -25,7 +25,7 @@ import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.scheduling.TaskScheduler; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor; @@ -36,7 +36,6 @@ import lol.pyr.znpcsplus.util.LookType; import lol.pyr.znpcsplus.util.NpcLocation; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.DyeColor; import org.bukkit.inventory.ItemStack; @@ -130,7 +129,7 @@ public class ZNpcImporter implements DataImporter { npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new FetchingDescriptor(skinCache, model.getSkinName())); } else if (model.getSkin() != null && model.getSignature() != null) { - npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(model.getSkin(), model.getSignature()))); + npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new SkinImpl(model.getSkin(), model.getSignature()))); } Map toggleValues = model.getNpcToggleValues(); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/BaseSkinDescriptor.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/BaseSkinDescriptor.java index c98064b..3c63364 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/BaseSkinDescriptor.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/BaseSkinDescriptor.java @@ -13,8 +13,8 @@ import java.util.List; import java.util.concurrent.CompletableFuture; public interface BaseSkinDescriptor extends SkinDescriptor { - CompletableFuture fetch(Player player); - Skin fetchInstant(Player player); + CompletableFuture fetch(Player player); + SkinImpl fetchInstant(Player player); boolean supportsInstant(Player player); String serialize(); @@ -27,7 +27,7 @@ public interface BaseSkinDescriptor extends SkinDescriptor { for (int i = 0; i < (arr.length - 1) / 3; i++) { properties.add(new TextureProperty(arr[i + 1], arr[i + 2], arr[i + 3])); } - return new PrefetchedDescriptor(new Skin(properties)); + return new PrefetchedDescriptor(new SkinImpl(properties)); } throw new IllegalArgumentException("Unknown SkinDescriptor type!"); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinDescriptorFactoryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinDescriptorFactoryImpl.java index b6656ed..0eeb491 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinDescriptorFactoryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinDescriptorFactoryImpl.java @@ -36,7 +36,7 @@ public class SkinDescriptorFactoryImpl implements SkinDescriptorFactory { @Override public SkinDescriptor createStaticDescriptor(String texture, String signature) { - return new PrefetchedDescriptor(new Skin(texture, signature)); + return new PrefetchedDescriptor(new SkinImpl(texture, signature)); } @Override diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/Skin.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinImpl.java similarity index 79% rename from plugin/src/main/java/lol/pyr/znpcsplus/skin/Skin.java rename to plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinImpl.java index 356bb91..66bc999 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/Skin.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/SkinImpl.java @@ -6,6 +6,7 @@ import com.github.retrooper.packetevents.protocol.player.TextureProperty; import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import lol.pyr.znpcsplus.api.skin.Skin; import lol.pyr.znpcsplus.reflection.Reflections; import java.lang.reflect.InvocationTargetException; @@ -13,21 +14,21 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class Skin { +public class SkinImpl implements Skin { private final long timestamp = System.currentTimeMillis(); private final List properties; private static final boolean V1_20_2 = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_20_2); - public Skin(String texture, String signature) { + public SkinImpl(String texture, String signature) { properties = new ArrayList<>(1); properties.add(new TextureProperty("textures", texture, signature)); } - public Skin(Collection properties) { + public SkinImpl(Collection properties) { this.properties = new ArrayList<>(properties); } - public Skin(Object propertyMap) { + public SkinImpl(Object propertyMap) { this.properties = new ArrayList<>(); try { Collection properties = (Collection) Reflections.PROPERTY_MAP_VALUES_METHOD.get().invoke(propertyMap); @@ -51,7 +52,7 @@ public class Skin { } } - public Skin(JsonObject obj) { + public SkinImpl(JsonObject obj) { properties = new ArrayList<>(); for (JsonElement e : obj.get("properties").getAsJsonArray()) { JsonObject o = e.getAsJsonObject(); @@ -71,4 +72,20 @@ public class Skin { public boolean isExpired() { return System.currentTimeMillis() - timestamp > 60000L; } + + @Override + public String getTexture() { + for (TextureProperty property : properties) + if (property.getName().equalsIgnoreCase("textures")) + return property.getValue(); + return null; + } + + @Override + public String getSignature() { + for (TextureProperty property : properties) + if (property.getName().equalsIgnoreCase("textures")) + return property.getSignature(); + return null; + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java index de90ca5..2a54509 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java @@ -4,7 +4,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.reflection.Reflections; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -24,7 +24,7 @@ public class MojangSkinCache { private final ConfigManager configManager; - private final Map cache = new ConcurrentHashMap<>(); + private final Map cache = new ConcurrentHashMap<>(); private final Map idCache = new ConcurrentHashMap<>(); public MojangSkinCache(ConfigManager configManager) { @@ -32,11 +32,11 @@ public class MojangSkinCache { } public void cleanCache() { - for (Map.Entry entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey()); + for (Map.Entry entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey()); for (Map.Entry entry : idCache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey()); } - public CompletableFuture fetchByName(String name) { + public CompletableFuture fetchByName(String name) { Player player = Bukkit.getPlayerExact(name); if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player)); @@ -53,7 +53,7 @@ public class MojangSkinCache { if (obj.has("errorMessage")) return fetchByNameFallback(name).join(); String id = obj.get("id").getAsString(); idCache.put(name.toLowerCase(), new CachedId(id)); - Skin skin = fetchByUUID(id).join(); + SkinImpl skin = fetchByUUID(id).join(); if (skin == null) return fetchByNameFallback(name).join(); return skin; } @@ -69,7 +69,7 @@ public class MojangSkinCache { }); } - public CompletableFuture fetchByNameFallback(String name) { + public CompletableFuture fetchByNameFallback(String name) { Player player = Bukkit.getPlayerExact(name); if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player)); @@ -89,7 +89,7 @@ public class MojangSkinCache { JsonObject textures = obj.get("textures").getAsJsonObject(); String value = textures.get("raw").getAsJsonObject().get("value").getAsString(); String signature = textures.get("raw").getAsJsonObject().get("signature").getAsString(); - Skin skin = new Skin(value, signature); + SkinImpl skin = new SkinImpl(value, signature); cache.put(uuid, skin); return skin; } @@ -105,7 +105,7 @@ public class MojangSkinCache { }); } - public CompletableFuture fetchByUrl(URL url, String variant) { + public CompletableFuture fetchByUrl(URL url, String variant) { return CompletableFuture.supplyAsync(() -> { URL apiUrl = parseUrl("https://api.mineskin.org/generate/url"); HttpURLConnection connection = null; @@ -127,7 +127,7 @@ public class MojangSkinCache { if (obj.has("error")) return null; if (!obj.has("data")) return null; JsonObject texture = obj.get("data").getAsJsonObject().get("texture").getAsJsonObject(); - return new Skin(texture.get("value").getAsString(), texture.get("signature").getAsString()); + return new SkinImpl(texture.get("value").getAsString(), texture.get("signature").getAsString()); } } catch (IOException exception) { @@ -147,26 +147,26 @@ public class MojangSkinCache { if (!idCache.containsKey(name)) return false; CachedId id = idCache.get(name); if (id.isExpired() || !cache.containsKey(id.getId())) return false; - Skin skin = cache.get(id.getId()); + SkinImpl skin = cache.get(id.getId()); return !skin.isExpired(); } - public Skin getFullyCachedByName(String s) { + public SkinImpl getFullyCachedByName(String s) { String name = s.toLowerCase(); if (!idCache.containsKey(name)) return null; CachedId id = idCache.get(name); if (id.isExpired() || !cache.containsKey(id.getId())) return null; - Skin skin = cache.get(id.getId()); + SkinImpl skin = cache.get(id.getId()); if (skin.isExpired()) return null; return skin; } - public CompletableFuture fetchByUUID(String uuid) { + public CompletableFuture fetchByUUID(String uuid) { Player player = Bukkit.getPlayer(uuid); if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player)); if (cache.containsKey(uuid)) { - Skin skin = cache.get(uuid); + SkinImpl skin = cache.get(uuid); if (!skin.isExpired()) return CompletableFuture.completedFuture(skin); } @@ -179,7 +179,7 @@ public class MojangSkinCache { try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) { JsonObject obj = JsonParser.parseReader(reader).getAsJsonObject(); if (obj.has("errorMessage")) return null; - Skin skin = new Skin(obj); + SkinImpl skin = new SkinImpl(obj); cache.put(uuid, skin); return skin; } @@ -195,12 +195,12 @@ public class MojangSkinCache { }); } - public Skin getFromPlayer(Player player) { + public SkinImpl getFromPlayer(Player player) { try { Object playerHandle = Reflections.GET_PLAYER_HANDLE_METHOD.get().invoke(player); Object gameProfile = Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle); Object propertyMap = Reflections.GET_PROPERTY_MAP_METHOD.get().invoke(gameProfile); - return new Skin(propertyMap); + return new SkinImpl(propertyMap); } catch (IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/FetchingDescriptor.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/FetchingDescriptor.java index 17364a2..d99ad2c 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/FetchingDescriptor.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/FetchingDescriptor.java @@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.skin.descriptor; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.util.PapiUtil; import org.bukkit.entity.Player; @@ -19,12 +19,12 @@ public class FetchingDescriptor implements BaseSkinDescriptor, SkinDescriptor { } @Override - public CompletableFuture fetch(Player player) { + public CompletableFuture fetch(Player player) { return skinCache.fetchByName(PapiUtil.set(player, name)); } @Override - public Skin fetchInstant(Player player) { + public SkinImpl fetchInstant(Player player) { return skinCache.getFullyCachedByName(PapiUtil.set(player, name)); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/MirrorDescriptor.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/MirrorDescriptor.java index 247015f..8971d0b 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/MirrorDescriptor.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/MirrorDescriptor.java @@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.skin.descriptor; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import org.bukkit.entity.Player; @@ -16,12 +16,12 @@ public class MirrorDescriptor implements BaseSkinDescriptor, SkinDescriptor { } @Override - public CompletableFuture fetch(Player player) { + public CompletableFuture fetch(Player player) { return CompletableFuture.completedFuture(skinCache.getFromPlayer(player)); } @Override - public Skin fetchInstant(Player player) { + public SkinImpl fetchInstant(Player player) { return skinCache.getFromPlayer(player); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java index 3e177dd..c852080 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java @@ -3,7 +3,7 @@ package lol.pyr.znpcsplus.skin.descriptor; import com.github.retrooper.packetevents.protocol.player.TextureProperty; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor; -import lol.pyr.znpcsplus.skin.Skin; +import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import org.bukkit.entity.Player; @@ -11,9 +11,9 @@ import java.net.URL; import java.util.concurrent.CompletableFuture; public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor { - private final Skin skin; + private final SkinImpl skin; - public PrefetchedDescriptor(Skin skin) { + public PrefetchedDescriptor(SkinImpl skin) { this.skin = skin; } @@ -26,12 +26,12 @@ public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor } @Override - public CompletableFuture fetch(Player player) { + public CompletableFuture fetch(Player player) { return CompletableFuture.completedFuture(skin); } @Override - public Skin fetchInstant(Player player) { + public SkinImpl fetchInstant(Player player) { return skin; } @@ -40,7 +40,7 @@ public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor return true; } - public Skin getSkin() { + public SkinImpl getSkin() { return skin; }