diff --git a/dough-api/pom.xml b/dough-api/pom.xml index d9aa5f75..4bb28d00 100644 --- a/dough-api/pom.xml +++ b/dough-api/pom.xml @@ -167,10 +167,6 @@ enginehub-repo https://maven.enginehub.org/repo/ - - IntellectualSites - https://mvn.intellectualsites.com/content/repositories/snapshots/ - funnyguilds-repo https://repo.panda-lang.org/releases @@ -415,6 +411,13 @@ plugin 4.12.0 provided + + + + com.github.PikaMug + LocaleLib + + diff --git a/dough-items/src/main/java/io/github/bakedlibs/dough/items/ItemUtils.java b/dough-items/src/main/java/io/github/bakedlibs/dough/items/ItemUtils.java index c5f1ae61..c3d3b1a9 100644 --- a/dough-items/src/main/java/io/github/bakedlibs/dough/items/ItemUtils.java +++ b/dough-items/src/main/java/io/github/bakedlibs/dough/items/ItemUtils.java @@ -6,6 +6,8 @@ import javax.annotation.Nullable; import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; @@ -174,8 +176,8 @@ public static void damageItem(@Nonnull ItemStack item, int damage, boolean ignor if (item.getType() != Material.AIR && item.getAmount() > 0) { int remove = damage; - if (!ignoreEnchantments && item.getEnchantments().containsKey(Enchantment.DURABILITY)) { - int level = item.getEnchantmentLevel(Enchantment.DURABILITY); + if (!ignoreEnchantments && item.getEnchantments().containsKey(Registry.ENCHANTMENT.get(NamespacedKey.minecraft("unbreaking")))) { + int level = item.getEnchantmentLevel(Registry.ENCHANTMENT.get(NamespacedKey.minecraft("unbreaking"))); for (int i = 0; i < damage; i++) { if (Math.random() * 100 <= (60 + Math.floorDiv(40, (level + 1)))) { diff --git a/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter.java b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter.java index a541f203..a596f0b2 100644 --- a/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter.java +++ b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter.java @@ -7,6 +7,7 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import io.papermc.lib.PaperLib; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.common.DoughLogger; @@ -20,11 +21,19 @@ public interface ItemNameAdapter { public static @Nullable ItemNameAdapter get() { try { - MinecraftVersion version = MinecraftVersion.get(); - if (MinecraftVersion.isMocked()) { // Special case for MockBukkit return new ItemNameAdapterMockBukkit(); + } + + MinecraftVersion version = MinecraftVersion.get(); + + if (version.isAtLeast(1, 20, 4) && PaperLib.isPaper()) { + return new ItemNameAdapterPaper(); + } + + if (version.isAtLeast(1, 20, 5)) { + return new ItemNameAdapter20v5(); } else if (version.isAtLeast(1, 20)) { return new ItemNameAdapter20(); } else if (version.isAtLeast(1, 19)) { diff --git a/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter20v5.java b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter20v5.java new file mode 100644 index 00000000..c2acd256 --- /dev/null +++ b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapter20v5.java @@ -0,0 +1,32 @@ +package io.github.bakedlibs.dough.items.nms; + +import io.github.bakedlibs.dough.reflection.ReflectionUtils; +import io.github.bakedlibs.dough.versions.UnknownServerVersionException; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +class ItemNameAdapter20v5 implements ItemNameAdapter { + + private final Method getCopy; + private final Method getName; + private final Method toString; + + ItemNameAdapter20v5() throws NoSuchMethodException, SecurityException, ClassNotFoundException, UnknownServerVersionException { + super(); + + getCopy = ReflectionUtils.getOBCClass("inventory.CraftItemStack").getMethod("asNMSCopy", ItemStack.class); + getName = ReflectionUtils.getMethodOrAlternative(ReflectionUtils.getNetMinecraftClass("world.item.ItemStack"), "getDisplayName", "G"); + toString = ReflectionUtils.getMethod(ReflectionUtils.getNetMinecraftClass("network.chat.IChatBaseComponent"), "getString"); + } + + @Override + @ParametersAreNonnullByDefault + public String getName(ItemStack item) throws IllegalAccessException, InvocationTargetException { + Object instance = getCopy.invoke(null, item); + return (String) toString.invoke(getName.invoke(instance)); + } + +} diff --git a/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapterPaper.java b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapterPaper.java new file mode 100644 index 00000000..bc0a90ba --- /dev/null +++ b/dough-items/src/main/java/io/github/bakedlibs/dough/items/nms/ItemNameAdapterPaper.java @@ -0,0 +1,16 @@ +package io.github.bakedlibs.dough.items.nms; + +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.reflect.InvocationTargetException; + +public class ItemNameAdapterPaper implements ItemNameAdapter { + @Override + @ParametersAreNonnullByDefault + public String getName(ItemStack item) throws IllegalAccessException, InvocationTargetException { + return PlainTextComponentSerializer.plainText().serialize(Bukkit.getItemFactory().displayName(item)); + } +} diff --git a/dough-protection/pom.xml b/dough-protection/pom.xml index fa2e72ee..d12c8315 100644 --- a/dough-protection/pom.xml +++ b/dough-protection/pom.xml @@ -79,18 +79,36 @@ worldedit-core 7.2.17 provided + + + bukkit + * + + com.sk89q.worldedit worldedit-bukkit 7.2.17 provided + + + bukkit + * + + com.sk89q.worldguard worldguard-bukkit 7.0.9 provided + + + bukkit + * + + @@ -99,6 +117,12 @@ PreciousStones 1.17.2 provided + + + bukkit + * + + @@ -107,6 +131,12 @@ coreprotect 21.3 provided + + + bukkit + * + + @@ -115,6 +145,12 @@ logblock 1.17.0.0-SNAPSHOT provided + + + bukkit + * + + @@ -123,6 +159,12 @@ SimpleClans 7c3db52796 provided + + + bukkit + * + + @@ -131,6 +173,12 @@ GriefPrevention 16.18.2 provided + + + bukkit + * + + @@ -139,6 +187,12 @@ lwc master-4.5.1-g2100b5e-18 provided + + + bukkit + * + + @@ -147,12 +201,24 @@ helper 5.6.14 provided + + + bukkit + * + + com.massivecraft Factions 1.6.9.5-4.1.4-STABLE provided + + + bukkit + * + + @@ -161,6 +227,12 @@ Towny 1b86d017c5 provided + + + bukkit + * + + @@ -169,6 +241,12 @@ Lockette 9dac96e8f8 provided + + + bukkit + * + + @@ -182,6 +260,10 @@ org.projectlombok lombok + + bukkit + * + @@ -194,6 +276,10 @@ plotsquared-core * + + bukkit + * + @@ -203,12 +289,24 @@ RedProtect-Core 7.7.3 provided + + + bukkit + * + + br.net.fabiozumbi12.RedProtect RedProtect-Spigot 7.7.3 provided + + + bukkit + * + + @@ -217,6 +315,12 @@ bentobox 1.20.1 provided + + + bukkit + * + + @@ -225,6 +329,12 @@ blocklocker 1.10.4 provided + + + bukkit + * + + @@ -233,6 +343,12 @@ LandsAPI 6.29.12 provided + + + bukkit + * + + @@ -241,6 +357,12 @@ ChestProtectAPI 3.9.1 provided + + + bukkit + * + + @@ -249,6 +371,17 @@ plugin 4.12.0 provided + + + bukkit + * + + + + com.github.PikaMug + LocaleLib + + @@ -257,6 +390,12 @@ husktowns-bukkit 3.0-988161b provided + + + bukkit + * + + @@ -265,14 +404,26 @@ huskclaims-bukkit 1.0.2-e60150d provided + + + bukkit + * + + - + de.epiceric ShopChest 1.13-SNAPSHOT provided + + + bukkit + * + + @@ -281,6 +432,12 @@ bolt-bukkit 1.0.580 provided + + + bukkit + * + + diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/PlayerHead.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/PlayerHead.java index a8973261..97d1ee07 100644 --- a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/PlayerHead.java +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/PlayerHead.java @@ -80,16 +80,7 @@ public static void setSkin(Block block, PlayerSkin skin, boolean sendBlockUpdate try { GameProfile profile = skin.getProfile(); - Object tileEntity = adapter.getTileEntity(block); - - if (tileEntity != null) { - adapter.setGameProfile(tileEntity, profile); - - if (sendBlockUpdate) { - block.getState().update(true, false); - } - } - + adapter.setGameProfile(block, profile, sendBlockUpdate); } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter.java index 957571d9..c66ac871 100644 --- a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter.java +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import io.papermc.lib.PaperLib; import org.bukkit.block.Block; import com.mojang.authlib.GameProfile; @@ -16,17 +17,16 @@ public interface PlayerHeadAdapter { @ParametersAreNonnullByDefault - @Nullable - Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException; - - @ParametersAreNonnullByDefault - void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException; + void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws IllegalAccessException, InvocationTargetException, InstantiationException; public static @Nullable PlayerHeadAdapter get() { try { MinecraftVersion version = MinecraftVersion.get(); - if (version.isAtLeast(1, 18)) { + if (version.isAtLeast(1, 20, 5)) { + // 1.20.5 mappings + return new PlayerHeadAdapter20v5(); + } else if (version.isAtLeast(1, 18)) { // 1.18 mappings return new PlayerHeadAdapter18(); } else if (version.isAtLeast(1, 17)) { diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter17.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter17.java index de3f8b7a..136593f6 100644 --- a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter17.java +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter17.java @@ -31,9 +31,8 @@ class PlayerHeadAdapter17 implements PlayerHeadAdapter { getTileEntity = ReflectionUtils.getNMSClass("level.WorldServer").getMethod("getTileEntity", blockPosition); } - @Override @ParametersAreNonnullByDefault - public @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { + private @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { Object world = getHandle.invoke(block.getWorld()); Object position = newPosition.newInstance(block.getX(), block.getY(), block.getZ()); @@ -42,8 +41,15 @@ class PlayerHeadAdapter17 implements PlayerHeadAdapter { @Override @ParametersAreNonnullByDefault - public void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException { + public void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object tileEntity = getTileEntity(block); + if (tileEntity == null) return; + setGameProfile.invoke(tileEntity, profile); + + if (sendBlockUpdate) { + block.getState().update(true, false); + } } } diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter18.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter18.java index c0762fc7..f369987a 100644 --- a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter18.java +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter18.java @@ -27,9 +27,8 @@ class PlayerHeadAdapter18 implements PlayerHeadAdapter { getTileEntity = ReflectionUtils.getNMSClass("level.WorldServer").getMethod("getBlockEntity", blockPosition, boolean.class); } - @Override @ParametersAreNonnullByDefault - public @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { + private @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { Object world = getHandle.invoke(block.getWorld()); Object position = newPosition.newInstance(block.getX(), block.getY(), block.getZ()); @@ -38,8 +37,15 @@ class PlayerHeadAdapter18 implements PlayerHeadAdapter { @Override @ParametersAreNonnullByDefault - public void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException { + public void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object tileEntity = getTileEntity(block); + if (tileEntity == null) return; + setGameProfile.invoke(tileEntity, profile); + + if (sendBlockUpdate) { + block.getState().update(true, false); + } } } diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter20v5.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter20v5.java new file mode 100644 index 00000000..abc86dfa --- /dev/null +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapter20v5.java @@ -0,0 +1,58 @@ +package io.github.bakedlibs.dough.skins.nms; + +import com.mojang.authlib.GameProfile; +import io.github.bakedlibs.dough.reflection.ReflectionUtils; +import io.github.bakedlibs.dough.versions.UnknownServerVersionException; +import org.bukkit.block.Block; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +class PlayerHeadAdapter20v5 implements PlayerHeadAdapter { + + private final Constructor newPosition; + private final Constructor newResolvableProfile; + + private final Method getHandle; + private final Method getTileEntity; + private final Method setOwner; + + PlayerHeadAdapter20v5() throws NoSuchMethodException, SecurityException, ClassNotFoundException, UnknownServerVersionException { + Class resolvableProfile = ReflectionUtils.getNetMinecraftClass("world.item.component.ResolvableProfile"); + newResolvableProfile = ReflectionUtils.getConstructor(resolvableProfile, GameProfile.class); + + setOwner = ReflectionUtils.getNetMinecraftClass("world.level.block.entity.TileEntitySkull").getMethod("a", resolvableProfile); + getHandle = ReflectionUtils.getOBCClass("CraftWorld").getMethod("getHandle"); + + Class blockPosition = ReflectionUtils.getNetMinecraftClass("core.BlockPosition"); + newPosition = ReflectionUtils.getConstructor(blockPosition, int.class, int.class, int.class); + + getTileEntity = ReflectionUtils.getNMSClass("level.WorldServer").getMethod("getBlockEntity", blockPosition, boolean.class); + } + + @ParametersAreNonnullByDefault + private @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object world = getHandle.invoke(block.getWorld()); + + Object position = newPosition.newInstance(block.getX(), block.getY(), block.getZ()); + return getTileEntity.invoke(world, position, true); + } + + @Override + @ParametersAreNonnullByDefault + public void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object tileEntity = getTileEntity(block); + if (tileEntity == null) return; + + Object resolvableProfile = newResolvableProfile.newInstance(profile); + setOwner.invoke(tileEntity, resolvableProfile); + + if (sendBlockUpdate) { + block.getState().update(true, false); + } + } + +} diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterBefore17.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterBefore17.java index 40dae6c0..39924465 100644 --- a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterBefore17.java +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterBefore17.java @@ -31,9 +31,8 @@ class PlayerHeadAdapterBefore17 implements PlayerHeadAdapter { getTileEntity = ReflectionUtils.getNMSClass("WorldServer").getMethod("getTileEntity", blockPosition); } - @Override @ParametersAreNonnullByDefault - public @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { + private @Nullable Object getTileEntity(Block block) throws IllegalAccessException, InvocationTargetException, InstantiationException { Object world = getHandle.invoke(block.getWorld()); Object position = newPosition.newInstance(block.getX(), block.getY(), block.getZ()); @@ -42,8 +41,15 @@ class PlayerHeadAdapterBefore17 implements PlayerHeadAdapter { @Override @ParametersAreNonnullByDefault - public void setGameProfile(Object tileEntity, GameProfile profile) throws IllegalAccessException, InvocationTargetException { + public void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Object tileEntity = getTileEntity(block); + if (tileEntity == null) return; + setGameProfile.invoke(tileEntity, profile); + + if (sendBlockUpdate) { + block.getState().update(true, false); + } } } diff --git a/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterPaper.java b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterPaper.java new file mode 100644 index 00000000..4660e1b9 --- /dev/null +++ b/dough-skins/src/main/java/io/github/bakedlibs/dough/skins/nms/PlayerHeadAdapterPaper.java @@ -0,0 +1,50 @@ +package io.github.bakedlibs.dough.skins.nms; + +import com.destroystokyo.paper.profile.PlayerProfile; +import com.destroystokyo.paper.profile.ProfileProperty; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import io.github.bakedlibs.dough.reflection.ReflectionUtils; +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Skull; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +// Not currently in use. +// This does not correctly update heads on updates currently. +public class PlayerHeadAdapterPaper implements PlayerHeadAdapter { + + @Override + @ParametersAreNonnullByDefault + public void setGameProfile(Block block, GameProfile profile, boolean sendBlockUpdate) throws InvocationTargetException, IllegalAccessException { + BlockState state = block.getState(); + if (!(state instanceof Skull)) return; + + Skull skull = (Skull) state; + + Property property = profile.getProperties().get("textures").iterator().next(); + + PlayerProfile paperPlayerProfile = Bukkit.createProfile(profile.getId(), profile.getName()); + + Method getName = ReflectionUtils.getMethod(Property.class, "getName"); + Method getValue = ReflectionUtils.getMethod(Property.class, "getValue"); + Method getSignature = ReflectionUtils.getMethod(Property.class, "getSignature"); + + // Old authlib check + if (getName != null && getValue != null && getSignature != null) { + paperPlayerProfile.setProperty(new ProfileProperty((String) getName.invoke(property), (String) getValue.invoke(property), (String) getSignature.invoke(property))); + } else { + paperPlayerProfile.setProperty(new ProfileProperty(property.name(), property.value(), property.signature())); + } + + skull.setPlayerProfile(paperPlayerProfile); + + if (sendBlockUpdate) { + skull.update(true, false); + } + } +} diff --git a/pom.xml b/pom.xml index 908d3814..3aa0152d 100644 --- a/pom.xml +++ b/pom.xml @@ -278,15 +278,15 @@ - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + paper + https://repo.papermc.io/repository/maven-public/ - org.spigotmc - spigot-api + io.papermc.paper + paper-api 1.18.1-R0.1-SNAPSHOT provided