Skip to content
Open
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
8 changes: 7 additions & 1 deletion src/main/java/com/artillexstudios/axgraves/grave/Grave.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ public Grave(Location loc, @NotNull OfflinePlayer offlinePlayer, @NotNull ItemSt
}

entity = NMSHandlers.getNmsHandler().createEntity(EntityType.ARMOR_STAND, location.clone().add(0, 1 + CONFIG.getFloat("head-height", -1.2f), 0));
entity.setItem(EquipmentSlot.HELMET, WrappedItemStack.wrap(Utils.getPlayerHead(offlinePlayer)));
final ItemStack head;
if (CONFIG.getBoolean("custom-skull", false)) {
head = Utils.getBase64Skull(CONFIG.getString("custom-skull-value"));
} else {
head = Utils.getPlayerHead(offlinePlayer);
}
entity.setItem(EquipmentSlot.HELMET, WrappedItemStack.wrap(head));
final ArmorStandMeta meta = (ArmorStandMeta) entity.meta();
meta.small(true);
meta.invisible(true);
Expand Down
57 changes: 56 additions & 1 deletion src/main/java/com/artillexstudios/axgraves/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
package com.artillexstudios.axgraves.utils;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.profile.PlayerProfile;
import org.bukkit.profile.PlayerTextures;
import org.jetbrains.annotations.NotNull;

import java.net.URI;
import java.net.URL;
import java.util.Base64;
import java.util.UUID;
import java.util.logging.Level;

public class Utils {

@NotNull
Expand All @@ -15,7 +27,50 @@ public static ItemStack getPlayerHead(@NotNull OfflinePlayer player) {
skullMeta.setOwningPlayer(player);
it.setItemMeta(skullMeta);
}

return it;
}


@NotNull
public static ItemStack getBase64Skull(@NotNull String b64Texture) {
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
try {
JsonObject jsonObject = new Gson().fromJson(new String(Base64.getDecoder().decode(b64Texture)), JsonObject.class);

if (!jsonObject.has("textures")
|| !jsonObject.getAsJsonObject("textures").has("SKIN")
|| !jsonObject.getAsJsonObject("textures").getAsJsonObject("SKIN").has("url")) {
Bukkit.getLogger().log(Level.WARNING, "[AxGraves] Missing data in custom base64 skull texture when decoded-to JSON.");
return head;
}

String urlString = jsonObject.getAsJsonObject("textures").getAsJsonObject("SKIN").get("url").getAsString();
URL urlObject = URI.create(urlString).toURL();

PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID());
PlayerTextures texturesProfile = profile.getTextures();
texturesProfile.setSkin(urlObject);
profile.setTextures(texturesProfile);

if (head.getItemMeta() instanceof SkullMeta meta) {
meta.setOwnerProfile(profile);
head.setItemMeta(meta);
return head;
}

// if we reach here, it the item meta is not SkullMeta for some reason
Bukkit.getLogger().log(Level.WARNING, "[AxGraves] Failed to set custom skull texture.");
return head;

} catch (IllegalArgumentException e) {
Bukkit.getLogger().log(Level.WARNING, "[AxGraves] Invalid Base64 custom skull texture string provided.", e);
return head;
} catch (JsonSyntaxException e) {
Bukkit.getLogger().log(Level.WARNING, "[AxGraves] Invalid JSON in decoded custom skull texture data.", e);
return head;
} catch (Exception e) {
Bukkit.getLogger().log(Level.SEVERE, "[AxGraves] An unexpected error occurred while creating custom texture skull.", e);
return head;
}
}
}
6 changes: 6 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ auto-rotation:
enabled: false
speed: 10.0

# should the head use a custom base64 texture instead of the player's skin?:
custom-skull: false

# if custom-skull is true, this is the base64 value to set
custom-skull-value: "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvM2Q5OGNmMzA2NmY3MmIyYjdmYjhlYTg3ZGI1MjVmNmYwYjUxNGZiOGIwZGRiMzc0OWZkMTIzYzAzZTAyNDFiNiJ9fX0="

# true: only the person who died and people with axgraves.admin can open the grave
# false: everyone can open the grave
interact-only-own: false
Expand Down