diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index bf6aeb8d..dbcc0909 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -9,7 +9,7 @@ repositories { } dependencies { - implementation("com.gradleup.shadow:shadow-gradle-plugin:9.0.0-rc2") - implementation("com.diffplug.spotless:spotless-plugin-gradle:7.2.1") - implementation("de.skuzzle.restrictimports:restrict-imports-gradle-plugin:2.6.1") + implementation("com.gradleup.shadow:com.gradleup.shadow.gradle.plugin:9.3.0") + implementation("com.diffplug.gradle.spotless:com.diffplug.gradle.spotless.gradle.plugin:8.1.0") + implementation("de.skuzzle.restrictimports:de.skuzzle.restrictimports.gradle.plugin:3.0.0") } diff --git a/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts index 9abf00b3..c50a1138 100644 --- a/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/buildlogic.java-conventions.gradle.kts @@ -16,7 +16,6 @@ repositories { maven("https://repo.pgm.fyi/snapshots") // Sportpaper & other pgm-specific stuff maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") // Spigot repo maven("https://repo.aikar.co/content/groups/aikar/") // aikar repo - maven("https://jitpack.io") // Backup: jitpack } dependencies { @@ -26,8 +25,8 @@ dependencies { implementation("redis.clients:jedis:3.5.1") implementation("co.aikar:idb-core:1.0.0-SNAPSHOT") implementation("co.aikar:idb-bukkit:1.0.0-SNAPSHOT") - implementation("net.kyori:adventure-api:4.24.0") - implementation("net.kyori:adventure-text-serializer-plain:4.24.0") + implementation("net.kyori:adventure-api:4.25.0") + implementation("net.kyori:adventure-text-serializer-plain:4.25.0") implementation("net.kyori:adventure-platform-bukkit:4.4.1") implementation("org.reflections:reflections:0.10.2") @@ -36,11 +35,10 @@ dependencies { compileOnly("tc.oc.occ:AFK:1.0.0-SNAPSHOT") compileOnly("tc.oc.occ:Environment:1.0.0-SNAPSHOT") compileOnly("org.incendo:cloud-annotations:2.0.0") - compileOnly("org.jetbrains:annotations:22.0.0") - compileOnly("com.github.dmulloy2:ProtocolLib:5.3.0") + compileOnly("org.jetbrains:annotations:26.0.2") + compileOnly("net.dmulloy2:ProtocolLib:5.4.0") // Minecraft includes these (or equivalents) - compileOnly("com.mojang:authlib:6.0.54") compileOnly("it.unimi.dsi:fastutil:8.1.0") compileOnly("com.google.guava:guava:17.0") compileOnly("com.google.code.gson:gson:2.10.1") @@ -52,10 +50,10 @@ version = "0.2-SNAPSHOT" description = "A plugin for managing a Minecraft community" tasks { - withType() { + withType { options.encoding = "UTF-8" } - withType() { + withType { options.encoding = "UTF-8" } } @@ -64,7 +62,7 @@ spotless { ratchetFrom = "origin/dev" java { removeUnusedImports() - palantirJavaFormat("2.73.0").style("GOOGLE").formatJavadoc(true) + palantirJavaFormat("2.83.0").style("GOOGLE").formatJavadoc(true) } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 6108691d..17b8d30a 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -28,6 +28,7 @@ tasks.named("shadowJar") { } dependencies { + exclude(dependency("org.jspecify:jspecify")) exclude(dependency("org.jetbrains:annotations")) } @@ -66,12 +67,14 @@ tasks { mapOf( "name" to name, "description" to description, + "apiVersion" to "1.21.10", "mainClass" to "dev.pgm.community.Community", "version" to version, "commitHash" to commitHash, "author" to "applenick", - "url" to "https://pgm.dev/") + "url" to "https://pgm.dev/" ) + ) } } diff --git a/core/src/main/java/dev/pgm/community/mutations/types/mechanics/MobMutation.java b/core/src/main/java/dev/pgm/community/mutations/types/mechanics/MobMutation.java index 7df6708f..edcfe7cf 100644 --- a/core/src/main/java/dev/pgm/community/mutations/types/mechanics/MobMutation.java +++ b/core/src/main/java/dev/pgm/community/mutations/types/mechanics/MobMutation.java @@ -41,7 +41,7 @@ public class MobMutation extends ScheduledMutationBase { private static final int RANDOM_DISTANCE = 45; private static final String MOB_METADATA = "mob-mutation"; - private static MutationListOption TOTAL_MOBS = new MutationListOption( + private static MutationListOption TOTAL_MOBS = new MutationListOption<>( "Total Mobs", "Total number of mobs spawned", MutationType.MOBS.getMaterial(), diff --git a/core/src/main/java/dev/pgm/community/party/menu/MapPartyMainMenu.java b/core/src/main/java/dev/pgm/community/party/menu/MapPartyMainMenu.java index 00fe951e..31bf8b60 100644 --- a/core/src/main/java/dev/pgm/community/party/menu/MapPartyMainMenu.java +++ b/core/src/main/java/dev/pgm/community/party/menu/MapPartyMainMenu.java @@ -1,5 +1,6 @@ package dev.pgm.community.party.menu; +import static dev.pgm.community.util.PlayerUtils.PLAYER_UTILS; import static tc.oc.pgm.util.bukkit.BukkitUtils.colorize; import com.google.common.collect.Lists; @@ -12,7 +13,6 @@ import dev.pgm.community.party.menu.modifiers.MapPartyModifierMenu; import dev.pgm.community.party.menu.settings.MapPartySettingsMenu; import dev.pgm.community.party.presets.MapPartyPreset; -import dev.pgm.community.utils.SkullUtils; import dev.pgm.community.utils.compatibility.Materials; import fr.minuskube.inv.ClickableItem; import fr.minuskube.inv.content.InventoryContents; @@ -245,15 +245,15 @@ private ClickableItem getEmptyItem(int i) { private static final String END_PARTY_SKIN = "http://textures.minecraft.net/texture/e9cdb9af38cf41daa53bc8cda7665c509632d14e678f0f19f263f46e541d8a30"; - private static final ItemStack START_ITEM = SkullUtils.customSkull( + private static final ItemStack START_ITEM = PLAYER_UTILS.customSkull( START_PARTY_SKIN, "&a&lStart Event", "&2Left-Click&7 to start the event now", "&2Right-Click&7 to start event after current match ends"); - private static final ItemStack RESTART_ITEM = SkullUtils.customSkull( + private static final ItemStack RESTART_ITEM = PLAYER_UTILS.customSkull( RESTART_PARTY_SKIN, "&2&lRestart Event", "&7Click to restart the event"); private static final ItemStack END_ITEM = - SkullUtils.customSkull(END_PARTY_SKIN, "&4&lEnd Event", "&7Click to end the event"); + PLAYER_UTILS.customSkull(END_PARTY_SKIN, "&4&lEnd Event", "&7Click to end the event"); } diff --git a/core/src/main/java/dev/pgm/community/party/menu/hosts/HostMenu.java b/core/src/main/java/dev/pgm/community/party/menu/hosts/HostMenu.java index 7decf1a3..6fe162b8 100644 --- a/core/src/main/java/dev/pgm/community/party/menu/hosts/HostMenu.java +++ b/core/src/main/java/dev/pgm/community/party/menu/hosts/HostMenu.java @@ -1,12 +1,12 @@ package dev.pgm.community.party.menu.hosts; +import static dev.pgm.community.util.PlayerUtils.PLAYER_UTILS; import static tc.oc.pgm.util.bukkit.BukkitUtils.colorize; import com.google.common.collect.Lists; import dev.pgm.community.party.feature.MapPartyFeature; import dev.pgm.community.party.hosts.MapPartyHosts; import dev.pgm.community.party.menu.MapPartyMenu; -import dev.pgm.community.utils.SkullUtils; import dev.pgm.community.utils.compatibility.Materials; import fr.minuskube.inv.ClickableItem; import fr.minuskube.inv.content.InventoryContents; @@ -74,7 +74,8 @@ public void render(Player player, InventoryContents contents) { 4, 4, ClickableItem.of( - SkullUtils.customSkull(ADD_SKIN, "&a&lAdd Host", "&7Click to add event host"), c -> { + PLAYER_UTILS.customSkull(ADD_SKIN, "&a&lAdd Host", "&7Click to add event host"), + c -> { new HostAddMenu(hosts).open(getViewer()); })); diff --git a/core/src/main/java/dev/pgm/community/party/menu/maps/MapMenu.java b/core/src/main/java/dev/pgm/community/party/menu/maps/MapMenu.java index b01d7bec..9d56cab9 100644 --- a/core/src/main/java/dev/pgm/community/party/menu/maps/MapMenu.java +++ b/core/src/main/java/dev/pgm/community/party/menu/maps/MapMenu.java @@ -1,5 +1,6 @@ package dev.pgm.community.party.menu.maps; +import static dev.pgm.community.util.PlayerUtils.PLAYER_UTILS; import static tc.oc.pgm.util.bukkit.BukkitUtils.colorize; import dev.pgm.community.party.feature.MapPartyFeature; @@ -7,7 +8,6 @@ import dev.pgm.community.party.types.CustomPoolParty; import dev.pgm.community.party.types.RegularPoolParty; import dev.pgm.community.utils.PGMUtils; -import dev.pgm.community.utils.SkullUtils; import dev.pgm.community.utils.compatibility.Enchantments; import dev.pgm.community.utils.compatibility.Materials; import fr.minuskube.inv.ClickableItem; @@ -75,7 +75,7 @@ private void render(Player player, InventoryContents contents) { 4, 4, ClickableItem.of( - SkullUtils.customSkull( + PLAYER_UTILS.customSkull( ADD_SKIN, "&a&lAdd Map", "&7Click to add a map to the selection"), c -> { new MapAddMenu(getFeature(), getViewer()); diff --git a/core/src/main/java/dev/pgm/community/utils/SkullUtils.java b/core/src/main/java/dev/pgm/community/utils/SkullUtils.java deleted file mode 100644 index dfbfe933..00000000 --- a/core/src/main/java/dev/pgm/community/utils/SkullUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -package dev.pgm.community.utils; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import com.mojang.authlib.properties.PropertyMap; -import dev.pgm.community.utils.compatibility.Materials; -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Base64; -import java.util.UUID; -import org.bukkit.SkullType; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import tc.oc.pgm.util.bukkit.BukkitUtils; - -public class SkullUtils { - - public static ItemStack customSkull(String url, String displayName, String... lore) { - ItemStack head = new ItemStack(Materials.SKULL_ITEM); - head.setDurability((short) SkullType.PLAYER.ordinal()); - if (url.isEmpty()) { - return head; - } - - SkullMeta headMeta = (SkullMeta) head.getItemMeta(); - GameProfile profile = createGameProfile(url); - Field profileField; - try { - profileField = headMeta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(headMeta, profile); - } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ignored) { - ignored.printStackTrace(); - } - headMeta.setDisplayName(BukkitUtils.colorize(displayName)); - headMeta.setLore(MessageUtils.colorizeList(Arrays.asList(lore))); - headMeta.addItemFlags(ItemFlag.values()); - head.setItemMeta(headMeta); - return head; - } - - private static GameProfile createGameProfile(String url) { - GameProfile profile = new GameProfile(UUID.randomUUID(), null); - PropertyMap propertyMap = profile.getProperties(); - if (propertyMap == null) { - return null; - } - - byte[] encodedData = Base64.getEncoder() - .encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", url).getBytes()); - propertyMap.put("textures", new Property("textures", new String(encodedData))); - - return profile; - } -} diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 88a00dd5..7dac449c 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -1,5 +1,6 @@ name: Community description: ${description} +api-version: ${apiVersion} main: ${mainClass} version: ${version} (git-${commitHash}) website: ${url} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8bdaf60c..f8e1ee31 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2a84e188..23449a2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index ef07e016..adff685a 100755 --- a/gradlew +++ b/gradlew @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..e509b2dd --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/platform/platform-modern/build.gradle.kts b/platform/platform-modern/build.gradle.kts index 25a8ea11..e48d32f6 100644 --- a/platform/platform-modern/build.gradle.kts +++ b/platform/platform-modern/build.gradle.kts @@ -4,6 +4,7 @@ plugins { } dependencies { + implementation(project(":core")) implementation(project(":util")) paperweight.paperDevBundle("1.21.10-R0.1-SNAPSHOT") } diff --git a/platform/platform-modern/src/main/java/dev/pgm/community/platform/modern/ModernPlayerUtils.java b/platform/platform-modern/src/main/java/dev/pgm/community/platform/modern/ModernPlayerUtils.java index b2eb37ec..ae5b2bb5 100644 --- a/platform/platform-modern/src/main/java/dev/pgm/community/platform/modern/ModernPlayerUtils.java +++ b/platform/platform-modern/src/main/java/dev/pgm/community/platform/modern/ModernPlayerUtils.java @@ -2,14 +2,27 @@ import static dev.pgm.community.util.Supports.Variant.PAPER; +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; import dev.pgm.community.util.PlayerUtils; import dev.pgm.community.util.Supports; +import dev.pgm.community.utils.MessageUtils; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.UUID; +import org.bukkit.Material; import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerTextures; import tc.oc.pgm.platform.modern.util.Skins; +import tc.oc.pgm.util.bukkit.BukkitUtils; import tc.oc.pgm.util.skin.Skin; @Supports(value = PAPER, minVersion = "1.20.6") @@ -71,4 +84,30 @@ public Skin getPlayerSkin(Player player, Player viewer) { // } // return Skin.EMPTY; } + + @Override + public ItemStack customSkull(String url, String displayName, String... lore) { + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + if (url.isEmpty()) { + return head; + } + + SkullMeta headMeta = (SkullMeta) head.getItemMeta(); + PlayerProfile profile = new CraftPlayerProfile(UUID.randomUUID(), null); + PlayerTextures textures = profile.getTextures(); + + try { + textures.setSkin(new URI(url).toURL()); + profile.setTextures(textures); + headMeta.setPlayerProfile(profile); + } catch (URISyntaxException | MalformedURLException e) { + e.printStackTrace(); + } + + headMeta.setDisplayName(BukkitUtils.colorize(displayName)); + headMeta.setLore(MessageUtils.colorizeList(Arrays.asList(lore))); + headMeta.addItemFlags(ItemFlag.values()); + head.setItemMeta(headMeta); + return head; + } } diff --git a/platform/platform-sportpaper/build.gradle.kts b/platform/platform-sportpaper/build.gradle.kts index 6af8a21a..a1d44a94 100644 --- a/platform/platform-sportpaper/build.gradle.kts +++ b/platform/platform-sportpaper/build.gradle.kts @@ -3,6 +3,7 @@ plugins { } dependencies { + implementation(project(":core")) implementation(project(":util")) compileOnly("app.ashcon:sportpaper:1.8.8-R0.1-SNAPSHOT") } diff --git a/platform/platform-sportpaper/src/main/java/dev/pgm/community/platform/sportpaper/SpPlayerUtils.java b/platform/platform-sportpaper/src/main/java/dev/pgm/community/platform/sportpaper/SpPlayerUtils.java index b6568aaa..192cac9a 100644 --- a/platform/platform-sportpaper/src/main/java/dev/pgm/community/platform/sportpaper/SpPlayerUtils.java +++ b/platform/platform-sportpaper/src/main/java/dev/pgm/community/platform/sportpaper/SpPlayerUtils.java @@ -2,11 +2,25 @@ import static dev.pgm.community.util.Supports.Variant.SPORTPAPER; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; import dev.pgm.community.util.PlayerUtils; import dev.pgm.community.util.Supports; +import dev.pgm.community.utils.MessageUtils; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Base64; +import java.util.UUID; +import org.bukkit.Material; +import org.bukkit.SkullType; import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; import tc.oc.pgm.platform.sportpaper.utils.Skins; +import tc.oc.pgm.util.bukkit.BukkitUtils; import tc.oc.pgm.util.skin.Skin; @Supports(SPORTPAPER) @@ -40,4 +54,43 @@ public Skin getPlayerSkin(Player player, Player viewer) { org.bukkit.Skin skin = player.getSkin(viewer); return new Skin(skin.getData(), skin.getSignature()); } + + @Override + public ItemStack customSkull(String url, String displayName, String... lore) { + ItemStack head = new ItemStack(Material.SKULL_ITEM); + head.setDurability((short) SkullType.PLAYER.ordinal()); + if (url.isEmpty()) { + return head; + } + + SkullMeta headMeta = (SkullMeta) head.getItemMeta(); + GameProfile profile = createGameProfile(url); + Field profileField; + try { + profileField = headMeta.getClass().getDeclaredField("profile"); + profileField.setAccessible(true); + profileField.set(headMeta, profile); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + } + headMeta.setDisplayName(BukkitUtils.colorize(displayName)); + headMeta.setLore(MessageUtils.colorizeList(Arrays.asList(lore))); + headMeta.addItemFlags(ItemFlag.values()); + head.setItemMeta(headMeta); + return head; + } + + private static GameProfile createGameProfile(String url) { + GameProfile profile = new GameProfile(UUID.randomUUID(), null); + PropertyMap propertyMap = profile.getProperties(); + if (propertyMap == null) { + return null; + } + + byte[] encodedData = Base64.getEncoder() + .encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", url).getBytes()); + propertyMap.put("textures", new Property("textures", new String(encodedData))); + + return profile; + } } diff --git a/util/src/main/java/dev/pgm/community/util/PlayerUtils.java b/util/src/main/java/dev/pgm/community/util/PlayerUtils.java index aa797659..99c3679e 100644 --- a/util/src/main/java/dev/pgm/community/util/PlayerUtils.java +++ b/util/src/main/java/dev/pgm/community/util/PlayerUtils.java @@ -1,6 +1,7 @@ package dev.pgm.community.util; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import tc.oc.pgm.util.skin.Skin; public interface PlayerUtils { @@ -15,4 +16,6 @@ public interface PlayerUtils { String getPlayerName(Player player, Player viewer); Skin getPlayerSkin(Player player, Player viewer); + + ItemStack customSkull(String url, String displayName, String... lore); }