diff --git a/build.gradle.kts b/build.gradle.kts index 0137c10..bd6d918 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,13 +3,13 @@ import xyz.jpenilla.runpaper.task.RunServer plugins { id("java") id("com.github.johnrengelman.shadow") version "8.1.1" - id("io.papermc.paperweight.userdev") version "1.5.8" - id("xyz.jpenilla.run-paper") version "2.2.0" + id("io.papermc.paperweight.userdev") version "1.5.11" + id("xyz.jpenilla.run-paper") version "2.2.2" id("net.minecrell.plugin-yml.bukkit") version "0.6.0" } group = "dev.plex" -version = "2.2" +version = "2.2.1" allprojects { repositories { @@ -70,7 +70,7 @@ bukkit { // Adapted from PlotSquared val supportedVersions = - listOf("1.17.1", "1.18.1", "1.18.2", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2") + listOf("1.17.1", "1.18.1", "1.18.2", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.4") tasks { supportedVersions.forEach { register("runServer-$it") { @@ -104,6 +104,7 @@ dependencies { implementation("org.bstats:bstats-base:3.0.2") implementation("org.bstats:bstats-bukkit:3.0.2") implementation(project(path = ":shared", configuration = "shadow")) + implementation(project(path = ":v1_20_R3", configuration = "shadow")) implementation(project(path = ":v1_20_R2", configuration = "shadow")) implementation(project(path = ":v1_20_R1", configuration = "shadow")) implementation(project(path = ":v1_19_R3", configuration = "shadow")) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c1962a7..7f93135 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 744c64d..1af9e09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index aeb74cb..1aa94a4 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -141,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -149,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -198,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/settings.gradle.kts b/settings.gradle.kts index 39ad803..891073e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ plugins { rootProject.name = "ItemizerX" include("shared") +include("v1_20_R3") include("v1_20_R2") include("v1_20_R1") include("v1_19_R3") diff --git a/src/main/java/dev/plex/itemizerx/ItemizerX.java b/src/main/java/dev/plex/itemizerx/ItemizerX.java index 134f820..8716177 100644 --- a/src/main/java/dev/plex/itemizerx/ItemizerX.java +++ b/src/main/java/dev/plex/itemizerx/ItemizerX.java @@ -25,6 +25,11 @@ public class ItemizerX extends JavaPlugin getCommand("itemizer").setTabCompleter(new ItemizerXTab()); switch (getNMSVersion()) { + case "v1_20_R3" -> + { + getCommand("itemizer").setExecutor(new ItemizerXCommand()); + attr = new dev.plex.itemizerx.v1_20_R3.AttributeManager(); + } case "v1_20_R2" -> { getCommand("itemizer").setExecutor(new ItemizerXCommand()); diff --git a/v1_20_R3/build.gradle.kts b/v1_20_R3/build.gradle.kts new file mode 100644 index 0000000..413bb97 --- /dev/null +++ b/v1_20_R3/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + paperweight.paperDevBundle("1.20.4-R0.1-SNAPSHOT") +} \ No newline at end of file diff --git a/v1_20_R3/src/main/java/dev/plex/itemizerx/v1_20_R3/AttributeManager.java b/v1_20_R3/src/main/java/dev/plex/itemizerx/v1_20_R3/AttributeManager.java new file mode 100644 index 0000000..5ba0e1b --- /dev/null +++ b/v1_20_R3/src/main/java/dev/plex/itemizerx/v1_20_R3/AttributeManager.java @@ -0,0 +1,161 @@ +package dev.plex.itemizerx.v1_20_R3; + +import dev.plex.itemizerx.Attributes; +import dev.plex.itemizerx.IAttributeManager; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang3.StringUtils; +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager implements IAttributeManager +{ + private final MiniMessage mm = MiniMessage.miniMessage(); + + @Override + public ListTag getAttrList(final ItemStack item) + { + ListTag attrmod = item.getOrCreateTag().getList("AttributeModifiers", 10); + if (attrmod == null) + { + item.getTag().put("AttributeModifiers", new CompoundTag()); + } + return item.getTag().getList("AttributeModifiers", 10); + } + + @Override + public void addAttr(final Player player, final String[] args) + { + int op; + if (args.length < 4) + { + player.sendMessage(mm.deserialize("/itemizer attr add <name> <strength>" + + "[slot] - Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) + { + player.sendMessage(mm.deserialize("\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try + { + amount = Double.parseDouble(args[3]); + } + catch (NumberFormatException ex) + { + player.sendMessage(mm.deserialize("\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) + { + player.sendMessage(mm.deserialize("Please do not use 'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final ListTag attrmod = getAttrList(nms); + for (Tag nbtBase : attrmod) + { + final CompoundTag c = (CompoundTag) nbtBase; + if (c.getString("Name").equals(args[2])) + { + player.sendMessage(mm.deserialize("An attribute with the name \"" + args[2] + "\" already exists!")); + return; + } + } + final CompoundTag c = new CompoundTag(); + c.putString("Name", args[2]); + c.putString("AttributeName", a.mcName); + c.putDouble("Amount", amount); + op = a.op; + c.putInt("Operation", op); + final Random random = new Random(); + c.putIntArray("UUID", new int[] + { + random.nextInt(), + random.nextInt(), + random.nextInt(), + random.nextInt() + }); + if (args.length == 5) + { + final List options = new ArrayList<>(); + options.add("mainhand"); + options.add("offhand"); + options.add("head"); + options.add("chest"); + options.add("legs"); + options.add("feet"); + if (!options.contains(args[4].toLowerCase())) + { + player.sendMessage(mm.deserialize("Supported options:")); + player.sendMessage(mm.deserialize("" + StringUtils.join(options, ", "))); + return; + } + c.putString("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.getTag().put("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(mm.deserialize("Attribute added!")); + } + + @Override + public void removeAttr(final Player player, final String string) + { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final ListTag attrmod = getAttrList(nms); + final ListTag newList = new ListTag(); + boolean r = false; + for (Tag nbtBase : attrmod) + { + final CompoundTag c = (CompoundTag) nbtBase; + if (!c.getString("Name").equals(string)) + { + newList.add(nbtBase); + } + else + { + r = true; + } + } + if (!r) + { + player.sendMessage(mm.deserialize("The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.getTag().put("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(mm.deserialize("Attribute removed!")); + } + + @Override + public void listAttr(final Player player) + { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final ListTag attrmod = getAttrList(nms); + if (attrmod.size() == 0) + { + player.sendMessage(mm.deserialize("This item has no attributes.")); + return; + } + player.sendMessage(mm.deserialize("Item attributes: ")); + for (Tag nbtBase : attrmod) + { + final CompoundTag c = (CompoundTag) nbtBase; + player.sendMessage(mm.deserialize("" + Attributes.get(c.getString("AttributeName")).mcName + + ", " + c.getDouble("Amount"))); + } + } +}