diff --git a/src/main/java/org/skriptlang/skript/bukkit/misc/MiscModule.java b/src/main/java/org/skriptlang/skript/bukkit/misc/MiscModule.java index e778d8681be..e7b3a51ebbe 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/misc/MiscModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/misc/MiscModule.java @@ -22,7 +22,8 @@ protected void loadSelf(SkriptAddon addon) { ExprQuaternionAxisAngle::register, ExprRotate::register, ExprTextOf::register, - ExprWithYawPitch::register + ExprWithYawPitch::register, + ExprSkullTexture::register ); } diff --git a/src/main/java/org/skriptlang/skript/bukkit/misc/elements/expressions/ExprSkullTexture.java b/src/main/java/org/skriptlang/skript/bukkit/misc/elements/expressions/ExprSkullTexture.java new file mode 100644 index 00000000000..b813c045cf0 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/misc/elements/expressions/ExprSkullTexture.java @@ -0,0 +1,112 @@ +package org.skriptlang.skript.bukkit.misc.elements.expressions; + +import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Example; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.Since; +import ch.njol.skript.expressions.base.SimplePropertyExpression; +import ch.njol.util.coll.CollectionUtils; + +import com.destroystokyo.paper.profile.ProfileProperty; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.Event; +import org.bukkit.inventory.meta.SkullMeta; +import com.destroystokyo.paper.profile.PlayerProfile; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.registration.SyntaxInfo; +import org.skriptlang.skript.registration.SyntaxRegistry; + +import java.util.UUID; + +@Name("Skull Texture") +@Description(""" + The skull texture of a player head. + Allows you to give a skull a custom texture (e.g. instead of it being a Steve head, it's Notch's head). + For the %string% you input a base64 string (think of it like the ID/texture so Minecraft knows what the head should look like). + (The most common place to get a base64 string is https://minecraft-heads.com) + Resetting the texture of a skull will make it look like a Steve/Alex head. + """) +@Example("set the skull texture of {_i} to \"eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTM4NmRmZDc0Y2JhZmJkMWRiZTQ3OWY1ZTAzNzRjMDliZjJlYjRlMzg2NjExZmM0ZmM2OTlmMDJlY2E0ZGQyYyJ9fX0=\"") +@Since("INSERT VERSION") +public class ExprSkullTexture extends SimplePropertyExpression { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(SyntaxRegistry.EXPRESSION, + infoBuilder(ExprSkullTexture.class, String.class, "skull texture", "itemtypes", false) + .supplier(ExprSkullTexture::new) + .priority(SyntaxInfo.SIMPLE) + .addPattern("[the] (skull|head) texture [of] %itemtypes%") + .build()); + } + + @Override + public Class @Nullable [] acceptChange(ChangeMode mode) { + return switch (mode) { + case SET -> CollectionUtils.array(String.class); + case DELETE, RESET -> CollectionUtils.array(); + default -> null; + }; + } + + @Override + public void change(Event event, Object @Nullable [] delta, ChangeMode mode) { + String value = delta == null ? null : (String) delta[0]; + switch (mode) { + case DELETE, RESET: + for (ItemType item : getExpr().getArray(event)) { + if (item.getMaterial() != Material.PLAYER_HEAD) { + continue; + } + SkullMeta meta = (SkullMeta) item.getItemMeta(); + meta.setPlayerProfile(null); + item.setItemMeta(meta); + } + break; + case SET: + for (ItemType item : getExpr().getArray(event)) { + if (item.getMaterial() != Material.PLAYER_HEAD) { + continue; + } + SkullMeta meta = (SkullMeta) item.getItemMeta(); + PlayerProfile playerProfile = Bukkit.createProfile(UUID.randomUUID()); + playerProfile.setProperty(new ProfileProperty("textures", value)); + meta.setPlayerProfile(playerProfile); + item.setItemMeta(meta); + } + } + } + + @Override + public @Nullable String convert(ItemType item) { + if (item.getMaterial() != Material.PLAYER_HEAD) { + return null; + } + SkullMeta meta = (SkullMeta) item.getItemMeta(); + PlayerProfile profile = meta.getPlayerProfile(); + if (profile == null) { + return null; + } + ProfileProperty texture = profile.getProperties().stream() + .filter(property -> property.getName().equals("textures")) + .findFirst() + .orElse(null); + if (!(texture == null)) { + return texture.getValue(); + } else { + return null; + } + } + + @Override + public Class getReturnType() { + return String.class; + } + + @Override + protected String getPropertyName() { + return "skull texture"; + } +} diff --git a/src/test/skript/tests/syntaxes/expressions/ExprSkullTexture.sk b/src/test/skript/tests/syntaxes/expressions/ExprSkullTexture.sk new file mode 100644 index 00000000000..4f01c73b30d --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprSkullTexture.sk @@ -0,0 +1,6 @@ +test "skull texture": + set {_head} to player head + set skull texture of {_head} to "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTM4NmRmZDc0Y2JhZmJkMWRiZTQ3OWY1ZTAzNzRjMDliZjJlYjRlMzg2NjExZmM0ZmM2OTlmMDJlY2E0ZGQyYyJ9fX0=" + assert skull texture of {_head} is "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNTM4NmRmZDc0Y2JhZmJkMWRiZTQ3OWY1ZTAzNzRjMDliZjJlYjRlMzg2NjExZmM0ZmM2OTlmMDJlY2E0ZGQyYyJ9fX0=" with "skull texture should be set" + reset skull texture of {_head} + assert skull texture of {_head} is not set with "skull texture should be reset" \ No newline at end of file