From 875a39bd181b44b28ead8ae10eb852da1d9da993 Mon Sep 17 00:00:00 2001
From: Pesek <42549665+Pesekjak@users.noreply.github.com>
Date: Tue, 1 Oct 2024 18:58:06 +0200
Subject: [PATCH] Preventing NPE caused by creation of PlayerProfile from
OfflinePlayer (#7091)
---
.../java/ch/njol/skript/aliases/ItemType.java | 54 +++++++--------
.../ch/njol/skript/bukkitutil/ItemUtils.java | 29 ++++++++
.../ch/njol/skript/expressions/ExprSkull.java | 67 ++++---------------
.../skript/expressions/ExprSkullOwner.java | 35 ++++------
4 files changed, 81 insertions(+), 104 deletions(-)
diff --git a/src/main/java/ch/njol/skript/aliases/ItemType.java b/src/main/java/ch/njol/skript/aliases/ItemType.java
index 8b78d39229b..aa772d2b646 100644
--- a/src/main/java/ch/njol/skript/aliases/ItemType.java
+++ b/src/main/java/ch/njol/skript/aliases/ItemType.java
@@ -1,21 +1,3 @@
-/**
- * This file is part of Skript.
- *
- * Skript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Skript is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Skript. If not, see .
- *
- * Copyright Peter Güttinger, SkriptLang team and contributors
- */
package ch.njol.skript.aliases;
import ch.njol.skript.aliases.ItemData.OldItemData;
@@ -41,6 +23,7 @@
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Tag;
+import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Skull;
@@ -391,22 +374,35 @@ public boolean hasType() {
*/
public boolean setBlock(Block block, boolean applyPhysics) {
for (int i = random.nextInt(types.size()); i < types.size(); i++) {
- ItemData d = types.get(i);
- Material blockType = ItemUtils.asBlock(d.type);
+ ItemData data = types.get(i);
+ Material blockType = ItemUtils.asBlock(data.type);
+
if (blockType == null) // Ignore items which cannot be placed
continue;
- if (BlockUtils.set(block, blockType, d.getBlockValues(), applyPhysics)) {
- ItemMeta itemMeta = getItemMeta();
- if (itemMeta instanceof SkullMeta) {
- OfflinePlayer offlinePlayer = ((SkullMeta) itemMeta).getOwningPlayer();
- if (offlinePlayer == null)
- continue;
- Skull skull = (Skull) block.getState();
+
+ if (!BlockUtils.set(block, blockType, data.getBlockValues(), applyPhysics))
+ continue;
+
+ ItemMeta itemMeta = getItemMeta();
+
+ if (itemMeta instanceof SkullMeta) {
+ OfflinePlayer offlinePlayer = ((SkullMeta) itemMeta).getOwningPlayer();
+ if (offlinePlayer == null)
+ continue;
+ Skull skull = (Skull) block.getState();
+ if (offlinePlayer.getName() != null) {
skull.setOwningPlayer(offlinePlayer);
- skull.update(false, applyPhysics);
+ } else if (ItemUtils.CAN_CREATE_PLAYER_PROFILE) {
+ //noinspection deprecation
+ skull.setOwnerProfile(Bukkit.createPlayerProfile(offlinePlayer.getUniqueId(), ""));
+ } else {
+ //noinspection deprecation
+ skull.setOwner("");
}
- return true;
+ skull.update(false, applyPhysics);
}
+
+ return true;
}
return false;
}
diff --git a/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java b/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java
index ced9f5a8367..a74a604664d 100644
--- a/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java
+++ b/src/main/java/ch/njol/skript/bukkitutil/ItemUtils.java
@@ -21,7 +21,9 @@
import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.util.slot.Slot;
+import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
import org.bukkit.Tag;
import org.bukkit.TreeType;
import org.bukkit.block.Block;
@@ -32,9 +34,11 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
+import java.util.UUID;
/**
* Miscellaneous static utility methods related to items.
@@ -44,6 +48,7 @@ public class ItemUtils {
public static final boolean HAS_MAX_DAMAGE = Skript.methodExists(Damageable.class, "getMaxDamage");
// Introduced in Paper 1.21
public static final boolean HAS_RESET = Skript.methodExists(Damageable.class, "resetDamage");
+ public static final boolean CAN_CREATE_PLAYER_PROFILE = Skript.methodExists(Bukkit.class, "createPlayerProfile", UUID.class, String.class);
/**
* Gets damage/durability of an item, or 0 if it does not have damage.
@@ -148,6 +153,30 @@ public static void setDamage(ItemType itemType, int damage) {
}
}
+ /**
+ * Sets the owner of a player head.
+ * @param skull player head item to modify
+ * @param player owner of the head
+ */
+ public static void setHeadOwner(ItemType skull, OfflinePlayer player) {
+ ItemMeta meta = skull.getItemMeta();
+ if (!(meta instanceof SkullMeta))
+ return;
+
+ SkullMeta skullMeta = (SkullMeta) meta;
+
+ if (player.getName() != null) {
+ skullMeta.setOwningPlayer(player);
+ } else if (CAN_CREATE_PLAYER_PROFILE) {
+ //noinspection deprecation
+ skullMeta.setOwnerProfile(Bukkit.createPlayerProfile(player.getUniqueId(), ""));
+ } else {
+ skullMeta.setOwningPlayer(null);
+ }
+
+ skull.setItemMeta(skullMeta);
+ }
+
/**
* Gets a block material corresponding to given item material, which might
* be the given material. If no block material is found, null is returned.
diff --git a/src/main/java/ch/njol/skript/expressions/ExprSkull.java b/src/main/java/ch/njol/skript/expressions/ExprSkull.java
index bce8422a76d..8b8c0e0e19b 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprSkull.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprSkull.java
@@ -1,86 +1,45 @@
-/**
- * This file is part of Skript.
- *
- * Skript is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Skript is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Skript. If not, see .
- *
- * Copyright Peter Güttinger, SkriptLang team and contributors
- */
package ch.njol.skript.expressions;
+import ch.njol.skript.bukkitutil.ItemUtils;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
-import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.Nullable;
-import ch.njol.skript.Skript;
-import ch.njol.skript.aliases.Aliases;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
-import ch.njol.skript.lang.Expression;
-import ch.njol.skript.lang.SkriptParser.ParseResult;
-import ch.njol.util.Kleenean;
-/**
- * @author Peter Güttinger
- */
@Name("Player Skull")
@Description("Gets a skull item representing a player. Skulls for other entities are provided by the aliases.")
-@Examples({"give the victim's skull to the attacker",
- "set the block at the entity to the entity's skull"})
+@Examples({
+ "give the victim's skull to the attacker",
+ "set the block at the entity to the entity's skull"
+})
@Since("2.0")
-public class ExprSkull extends SimplePropertyExpression