commit 72218f926801f60814b08285a930c55a9a4e783a Author: Telesphoreo Date: Thu Jun 15 17:21:19 2023 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd00d92 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b3ffc8e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# ItemizerX diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..66e8e77 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,54 @@ +plugins { + id("java") + id("com.github.johnrengelman.shadow") version "8.1.1" +} + +group = "dev.plex" +version = "2.0" + +subprojects { + apply(plugin = "com.github.johnrengelman.shadow") + + repositories { + mavenCentral() + + maven { + url = uri("https://repo.codemc.org/repository/nms/") + } + + maven { + url = uri("https://repo.papermc.io/repository/maven-public/") + } + + maven { + url = uri("https://maven.playpro.com/") + } + } +} + +tasks { + shadowJar { + archiveBaseName.set("ItemizerX") + archiveClassifier.set("") + archiveVersion.set("") + } + assemble { + dependsOn("shadowJar") + } + + jar { + enabled = false + } +} + +dependencies { + implementation(project(path = ":core", configuration = "shadow")) + implementation(project(path = ":shared", configuration = "shadow")) + implementation(project(path = ":v1_20_R1", configuration = "shadow")) + implementation(project(path = ":v1_19_R3", configuration = "shadow")) + implementation(project(path = ":v1_19_R2", configuration = "shadow")) + implementation(project(path = ":v1_19_R1", configuration = "shadow")) + implementation(project(path = ":v1_18_R2", configuration = "shadow")) + implementation(project(path = ":v1_18_R1", configuration = "shadow")) + implementation(project(path = ":v1_17_R1", configuration = "shadow")) +} \ No newline at end of file diff --git a/core/.gitignore b/core/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/core/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 0000000..3ce55f7 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + implementation(project(":v1_20_R1")) + implementation(project(":v1_19_R3")) + implementation(project(":v1_19_R2")) + implementation(project(":v1_19_R1")) + implementation(project(":v1_18_R2")) + implementation(project(":v1_18_R1")) + implementation(project(":v1_17_R1")) + compileOnly("io.papermc.paper:paper-api:1.20-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/core/src/main/java/dev/plex/itemizerx/ItemizerX.java b/core/src/main/java/dev/plex/itemizerx/ItemizerX.java new file mode 100644 index 0000000..0c7906b --- /dev/null +++ b/core/src/main/java/dev/plex/itemizerx/ItemizerX.java @@ -0,0 +1,64 @@ +package dev.plex.itemizerx; + +import org.bukkit.plugin.java.JavaPlugin; + +public class ItemizerX extends JavaPlugin { + + public static ItemizerX plugin; + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public void onLoad() { + plugin = this; + } + + @Override + public void onEnable() { + plugin = this; + cpb.getCoreProtect(); + switch (getNMSVersion()) { + case "v1_20_R1": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_20_R1.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_20_R1.ItemizerXTab()); + } + case "v1_19_R3": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_19_R3.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_19_R3.ItemizerXTab()); + } + case "v1_19_R2": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_19_R2.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_19_R2.ItemizerXTab()); + } + case "v1_19_R1": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_19_R1.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_19_R1.ItemizerXTab()); + } + case "v1_18_R2": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_18_R2.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_18_R2.ItemizerXTab()); + } + case "v1_18_R1": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_18_R1.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_18_R1.ItemizerXTab()); + } + case "v1_17_R1": { + getCommand("itemizer").setExecutor(new dev.plex.itemizerx.v1_17_R1.ItemizerXCommand()); + getCommand("itemizer").setTabCompleter(new dev.plex.itemizerx.v1_17_R1.ItemizerXTab()); + } + default: + getLogger().severe("You are trying to run ItemizerX on an incompatible server version."); + getLogger().severe("ItemizerX only supports versions 1.17 to 1.20, disabling plugin."); + getServer().getPluginManager().disablePlugin(this); + } + } + + public String getNMSVersion() { + String v = getServer().getClass().getPackage().getName(); + return v.substring(v.lastIndexOf('.') + 1); + } + + @Override + public void onDisable() { + plugin = null; + } +} diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml new file mode 100644 index 0000000..4ab9695 --- /dev/null +++ b/core/src/main/resources/plugin.yml @@ -0,0 +1,13 @@ +name: ItemizerX +version: 3.0 +api-version: 1.20 +description: A rewrite of Itemizer +author: Focusvity, Telesphoreo +main: dev.plex.itemizerx.ItemizerX +softdepend: + - CoreProtect +commands: + itemizer: + description: The main command for ItemizerX + usage: / + aliases: [ii, it] diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..249e583 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..175aaa0 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Jun 15 15:30:03 CDT 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..1b6c787 --- /dev/null +++ b/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# 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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +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. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# 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. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..553894c --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,12 @@ +rootProject.name = "ItemizerX" +include("core") +include("shared") +include("v1_20_R1") +include("v1_19_R3") +include("v1_19_R2") +include("v1_19_R1") +include("v1_18_R2") +include("v1_18_R1") +include("v1_17_R1") + + diff --git a/shared/.gitignore b/shared/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/shared/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts new file mode 100644 index 0000000..886497f --- /dev/null +++ b/shared/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/shared/src/main/java/dev/plex/itemizerx/CoreProtectBridge.java b/shared/src/main/java/dev/plex/itemizerx/CoreProtectBridge.java new file mode 100644 index 0000000..8c2b4a1 --- /dev/null +++ b/shared/src/main/java/dev/plex/itemizerx/CoreProtectBridge.java @@ -0,0 +1,47 @@ +package dev.plex.itemizerx; + +import net.coreprotect.CoreProtect; +import net.coreprotect.CoreProtectAPI; +import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; + +public class CoreProtectBridge { + + public static CoreProtect cp = null; + public static CoreProtectAPI api = null; + public static boolean logged = false; + + public CoreProtect getCoreProtect() { + try { + final Plugin pl = Bukkit.getPluginManager().getPlugin("CoreProtect"); + if (pl instanceof CoreProtect) { + cp = (CoreProtect) pl; + } else { + if (!logged) { // To stop the console log spam - not persistent on server restarts + Bukkit.getLogger().info("CoreProtect not detected, some features will not be logged!"); + logged = true; + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + return cp; + } + + public CoreProtectAPI getAPI() { + final CoreProtect cp = getCoreProtect(); + + if (cp != null && api == null) { + try { + api = cp.getAPI(); + if (!cp.isEnabled() || !api.isEnabled()) { + Bukkit.getLogger().info("CoreProtect is disabled, some features will not be logged!"); + return null; + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return api; + } +} diff --git a/v1_17_R1/.gitignore b/v1_17_R1/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_17_R1/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_17_R1/build.gradle.kts b/v1_17_R1/build.gradle.kts new file mode 100644 index 0000000..d9b39a2 --- /dev/null +++ b/v1_17_R1/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/AttributeManager.java b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/AttributeManager.java new file mode 100644 index 0000000..c2bd45f --- /dev/null +++ b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_17_R1; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.getOrCreateTag().getList("AttributeModifiers", 10); + if (attrmod == null) { + item.getTag().set("AttributeModifiers", new NBTTagList()); + } + return item.getTag().getList("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.getString("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.setString("Name", args[2]); + c.setString("AttributeName", a.mcName); + c.setDouble("Amount", amount); + op = a.op; + c.setInt("Operation", op); + final Random random = new Random(); + c.setIntArray("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.setString("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.getTag().set("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.getString("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.getTag().set("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.getString("AttributeName")).mcName + + ", " + c.getDouble("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXCommand.java b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXCommand.java new file mode 100644 index 0000000..70f9006 --- /dev/null +++ b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_17_R1; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXTab.java b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXTab.java new file mode 100644 index 0000000..e0353d9 --- /dev/null +++ b/v1_17_R1/src/main/java/dev/plex/itemizerx/v1_17_R1/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_17_R1; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_18_R1/.gitignore b/v1_18_R1/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_18_R1/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_18_R1/build.gradle.kts b/v1_18_R1/build.gradle.kts new file mode 100644 index 0000000..367e075 --- /dev/null +++ b/v1_18_R1/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.18.1-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/AttributeManager.java b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/AttributeManager.java new file mode 100644 index 0000000..d29861c --- /dev/null +++ b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_18_R1; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.t().c("AttributeModifiers", 10); + if (attrmod == null) { + item.t().a("AttributeModifiers", new NBTTagList()); + } + return item.t().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.t().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.t().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXCommand.java b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXCommand.java new file mode 100644 index 0000000..2909552 --- /dev/null +++ b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_18_R1; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXTab.java b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXTab.java new file mode 100644 index 0000000..d0be3da --- /dev/null +++ b/v1_18_R1/src/main/java/dev/plex/itemizerx/v1_18_R1/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_18_R1; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_18_R2/.gitignore b/v1_18_R2/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_18_R2/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_18_R2/build.gradle.kts b/v1_18_R2/build.gradle.kts new file mode 100644 index 0000000..e61c43f --- /dev/null +++ b/v1_18_R2/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.18.2-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/AttributeManager.java b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/AttributeManager.java new file mode 100644 index 0000000..76bf9b9 --- /dev/null +++ b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_18_R2; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.u().c("AttributeModifiers", 10); + if (attrmod == null) { + item.u().a("AttributeModifiers", new NBTTagList()); + } + return item.u().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.u().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.u().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXCommand.java b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXCommand.java new file mode 100644 index 0000000..f35b4f5 --- /dev/null +++ b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_18_R2; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXTab.java b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXTab.java new file mode 100644 index 0000000..364f294 --- /dev/null +++ b/v1_18_R2/src/main/java/dev/plex/itemizerx/v1_18_R2/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_18_R2; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_19_R1/.gitignore b/v1_19_R1/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_19_R1/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_19_R1/build.gradle.kts b/v1_19_R1/build.gradle.kts new file mode 100644 index 0000000..38d0717 --- /dev/null +++ b/v1_19_R1/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/AttributeManager.java b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/AttributeManager.java new file mode 100644 index 0000000..999da73 --- /dev/null +++ b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_19_R1; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.v().c("AttributeModifiers", 10); + if (attrmod == null) { + item.u().a("AttributeModifiers", new NBTTagList()); + } + return item.u().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.u().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.u().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXCommand.java b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXCommand.java new file mode 100644 index 0000000..81f9e66 --- /dev/null +++ b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_19_R1; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXTab.java b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXTab.java new file mode 100644 index 0000000..ce0f250 --- /dev/null +++ b/v1_19_R1/src/main/java/dev/plex/itemizerx/v1_19_R1/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_19_R1; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_19_R2/.gitignore b/v1_19_R2/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_19_R2/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_19_R2/build.gradle.kts b/v1_19_R2/build.gradle.kts new file mode 100644 index 0000000..4f80d43 --- /dev/null +++ b/v1_19_R2/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.19.3-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/AttributeManager.java b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/AttributeManager.java new file mode 100644 index 0000000..1670946 --- /dev/null +++ b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_19_R2; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.v().c("AttributeModifiers", 10); + if (attrmod == null) { + item.u().a("AttributeModifiers", new NBTTagList()); + } + return item.u().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.u().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.u().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXCommand.java b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXCommand.java new file mode 100644 index 0000000..84970bd --- /dev/null +++ b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_19_R2; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXTab.java b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXTab.java new file mode 100644 index 0000000..30bd7d1 --- /dev/null +++ b/v1_19_R2/src/main/java/dev/plex/itemizerx/v1_19_R2/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_19_R2; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_19_R3/.gitignore b/v1_19_R3/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_19_R3/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_19_R3/build.gradle.kts b/v1_19_R3/build.gradle.kts new file mode 100644 index 0000000..e2e6579 --- /dev/null +++ b/v1_19_R3/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/AttributeManager.java b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/AttributeManager.java new file mode 100644 index 0000000..b23e52b --- /dev/null +++ b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_19_R3; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.v().c("AttributeModifiers", 10); + if (attrmod == null) { + item.u().a("AttributeModifiers", new NBTTagList()); + } + return item.u().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.u().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.u().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} \ No newline at end of file diff --git a/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXCommand.java b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXCommand.java new file mode 100644 index 0000000..5b4bdc9 --- /dev/null +++ b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_19_R3; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXTab.java b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXTab.java new file mode 100644 index 0000000..177ca1b --- /dev/null +++ b/v1_19_R3/src/main/java/dev/plex/itemizerx/v1_19_R3/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_19_R3; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +} diff --git a/v1_20_R1/.gitignore b/v1_20_R1/.gitignore new file mode 100644 index 0000000..b63da45 --- /dev/null +++ b/v1_20_R1/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1_20_R1/build.gradle.kts b/v1_20_R1/build.gradle.kts new file mode 100644 index 0000000..816e360 --- /dev/null +++ b/v1_20_R1/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("java") +} + +group = rootProject.group +version = rootProject.version + +dependencies { + implementation(project(":shared")) + compileOnly("org.spigotmc:spigot:1.20.1-R0.1-SNAPSHOT") + compileOnly("net.coreprotect:coreprotect:21.3") +} \ No newline at end of file diff --git a/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/AttributeManager.java b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/AttributeManager.java new file mode 100644 index 0000000..4b0b7bb --- /dev/null +++ b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/AttributeManager.java @@ -0,0 +1,179 @@ +package dev.plex.itemizerx.v1_20_R1; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.world.item.ItemStack; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class AttributeManager { + + public static NBTTagList getAttrList(final ItemStack item) { + NBTTagList attrmod = item.w().c("AttributeModifiers", 10); + if (attrmod == null) { + item.v().a("AttributeModifiers", new NBTTagList()); + } + return item.v().c("AttributeModifiers", 10); + } + + public static void addAttr(final Player player, final String[] args) { + int op; + if (args.length < 4) { + player.sendMessage(colorize("&b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c- " + + "&6Add an attribute")); + return; + } + final Attributes a = Attributes.get(args[2]); + if (a == null) { + player.sendMessage(colorize("&4\"" + args[2] + "\" is not a valid attribute type.")); + return; + } + double amount; + try { + amount = Double.parseDouble(args[3]); + } catch (NumberFormatException ex) { + player.sendMessage(colorize("&4\"" + args[3] + "\" is not a valid number.")); + return; + } + if (Double.isNaN(amount)) { + player.sendMessage(colorize("&4Please do not use &f'NaN (Not a Number)'")); + return; + } + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (c.l("Name").equals(args[2])) { + player.sendMessage(colorize("&4An attribute with the name \"&f" + args[2] + "&4\" already exists!")); + return; + } + } + final NBTTagCompound c = new NBTTagCompound(); + c.a("Name", args[2]); + c.a("AttributeName", a.mcName); + c.a("Amount", amount); + op = a.op; + c.a("Operation", op); + final Random random = new Random(); + c.a("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(colorize("&2Supported options:\n" + + "&e" + StringUtils.join(options, ", "))); + return; + } + c.a("Slot", args[4].toLowerCase()); + } + attrmod.add(c); + nms.v().a("AttributeModifiers", attrmod); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute added!")); + } + + public static void removeAttr(final Player player, final String string) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + final NBTTagList newList = new NBTTagList(); + boolean r = false; + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + if (!c.l("Name").equals(string)) { + newList.add(nbtBase); + } else { + r = true; + } + } + if (!r) { + player.sendMessage(colorize("&4The attribute \"" + string + "\" doesn't exist!")); + return; + } + nms.v().a("AttributeModifiers", newList); + final org.bukkit.inventory.ItemStack is = CraftItemStack.asCraftMirror(nms); + player.getInventory().setItemInMainHand(is); + player.sendMessage(colorize("&2Attribute removed!")); + } + + public static void listAttr(final Player player) { + final ItemStack nms = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand()); + final NBTTagList attrmod = getAttrList(nms); + if (attrmod.size() == 0) { + player.sendMessage(colorize("&eThis item has no attributes.")); + return; + } + player.sendMessage(colorize("&2Item attributes: ")); + for (net.minecraft.nbt.NBTBase nbtBase : attrmod) { + final NBTTagCompound c = (NBTTagCompound) nbtBase; + player.sendMessage(colorize("&e" + Attributes.get(c.l("AttributeName")).mcName + + ", " + c.k("Amount"))); + } + } + + private static String colorize(String string) { + return ChatColor.translateAlternateColorCodes('&', string); + } + + public enum Attributes { + + MAX_HEALTH("generic.max_health", 0), + FOLLOW_RANGE("generic.follow_range", 1), + KNOCKBACK_RESISTANCE("generic.knockback_resistance", 1), + MOVEMENT_SPEED("generic.movement_speed", 1), + DAMAGE("generic.attack_damage", 0), + ARMOR("generic.armor", 0), + ARMOR_TOUGHNESS("generic.armor_toughness", 0), + FLYING_SPEED("generic.flying_speed", 1), + ATTACK_SPEED("generic.attack_speed", 1), + LUCK("generic.luck", 0), + HORSE_JUMP("horse.jump_strength", 1), + ZOMBIE_REINFORCEMENTS("zombie.spawn_reinforcements", 1); + + private final String mcName; + private final int op; + + Attributes(String mcName, int op) { + this.mcName = mcName; + this.op = op; + } + + public static Attributes get(String name) { + for (Attributes attr : values()) { + if (attr.name().equalsIgnoreCase(name) || attr.mcName.equalsIgnoreCase(name)) { + return attr; + } + } + return null; + } + + public static String getAttributes() { + return StringUtils.join(values(), ", "); + } + + public static List getAttributeList() { + List attributes = new ArrayList<>(); + for (Attributes attr : values()) { + attributes.add(attr.name()); + } + return attributes; + } + } +} diff --git a/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXCommand.java b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXCommand.java new file mode 100644 index 0000000..e417e88 --- /dev/null +++ b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXCommand.java @@ -0,0 +1,810 @@ +package dev.plex.itemizerx.v1_20_R1; + +import dev.plex.itemizerx.CoreProtectBridge; +import org.apache.commons.lang.StringUtils; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.enchantments.EnchantmentWrapper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.BookMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemizerXCommand implements CommandExecutor { + + final List POTIONS = Arrays.asList(Material.POTION, Material.LINGERING_POTION, Material.SPLASH_POTION); + CoreProtectBridge cpb = new CoreProtectBridge(); + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String string, String[] args) { + if (!sender.hasPermission("itemizer.use")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.AQUA + "ItemizerX " + ChatColor.GOLD + "v" + + Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getVersion() + + ChatColor.AQUA + " by " + ChatColor.GOLD + + StringUtils.join(Bukkit.getPluginManager().getPlugin("ItemizerX").getDescription().getAuthors(), ", ")); + sender.sendMessage(ChatColor.AQUA + "Type " + ChatColor.GOLD + "/itemizer help " + + ChatColor.AQUA + "for help"); + return true; + } + + if (!(sender instanceof final Player player)) { + sender.sendMessage(colorize("&4You must be a player to execute this command!")); + return true; + } + + final ItemStack item = player.getInventory().getItemInMainHand(); + final boolean hasItem = item.getType() != Material.AIR; + final boolean hasPotion = POTIONS.contains(item.getType()); + final boolean hasBook = item.getType() == Material.WRITTEN_BOOK; + final ItemMeta meta = item.getItemMeta(); + + switch (args[0]) { + case "help" -> { + sender.sendMessage(colorize(""" + &3=============&f[&dItemizerX Commands&f]&3============= + &b/itemizer name <&fname&b> &c- &6Name your item + &b/itemizer id <&fid&b> &c- &6Change the item's material + &b/itemizer lore &c- &6Lore editing command + &b/itemizer potion &c- &6Potion editing command + &b/itemizer attr &c- &6Attribute editing command + &b/itemizer flag &c- &6Flag editing command + &b/itemizer enchant &c- &6Enchant editing command + &b/itemizer title <&fname&b> &c- &6Set the book's title + &b/itemizer author <&fname&b> &c- &6Set the book's author + &b/itemizer head <&fname&b> &c- &6Set the player of the head + &b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign + &b/itemizer clearall &c- &6Clears all metadata from your item""")); + return true; + } + case "name" -> { + if (!sender.hasPermission("itemizer.name")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dName Commands&f]&3===============\n" + + "&b/itemizer name <&fname&b> &c - &6Name your item")); + } else { + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + assert meta != null; + meta.setDisplayName(name); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The name of the item in your hand has been set to &f'" + name + "&f'")); + } + return true; + } + case "id" -> { + if (!sender.hasPermission("itemizer.id")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dID Commands&f]&3===============\n" + + "&b/itemizer id <&fid&b> &c- &6Change the item's material")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + Material material = Material.matchMaterial(args[1].toUpperCase()); + if (material == null) { + sender.sendMessage(colorize("&4The material &f\"" + args[1] + "&f\"&4 does not exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The material of the item has changed to &f'" + material.name() + "'")); + return true; + } + case "lore" -> { + if (!sender.hasPermission("itemizer.lore")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dLore Commands&f]&3=============== + &b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore + &b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore + &b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore + &b/itemizer lore clear &c- &6Clear the item's lore""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.lore.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore add <&ftext&b> &c- &6Add a line of text to your item's lore")); + return true; + } + String lore = colorize(StringUtils.join(args, " ", 2, args.length)); + assert meta != null; + List lores = new ArrayList<>(); + if (meta.getLore() != null) { + lores = meta.getLore(); + } + lores.add(lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + lore + "&f'&2 added to the item's lore")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.lore.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore remove <&findex&b> &c- &6Remove a line of text from your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.remove(index - 1); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "&f'&2 removed from the item's lore")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.lore.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dLore Commands&f]&3===============\n" + + "&b/itemizer lore change <&findex&b> <&ftext&b> &c- &6Change a line of text in your item's lore")); + return true; + } + Integer index = parseInt(sender, args[2]); + if (index == null) { + return true; + } + String lore = colorize(StringUtils.join(args, " ", 3, args.length)); + assert meta != null; + List lores; + if (meta.getLore() != null) { + lores = meta.getLore(); + } else { + sender.sendMessage(colorize("&eThis item has no lores.")); + return true; + } + if (index > lores.size()) { + sender.sendMessage(colorize("&4The item's lore doesn't have line &f'" + index + "'")); + return true; + } + lores.set(index - 1, lore); + meta.setLore(lores); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2Line &f'" + index + "'&2 has changed to &f'" + lore + "&f'")); + return true; + } + case "clear" -> { + if (!sender.hasPermission("itemizer.lore.clear")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (meta.getLore() == null || meta.getLore().isEmpty()) { + sender.sendMessage(colorize("&4The item has no lores.")); + return true; + } + meta.setLore(null); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The item's lore has been cleared!")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer lore &bfor help.")); + return true; + } + } + } + } + case "potion" -> { + if (!sender.hasPermission("itemizer.potion")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dPotion Commands&f]&3=============== + &b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect + &b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect + &b/itemizer potion change <&fname&b> &c- &6Change the potion type + &b/itemizer potion color <&fhexcolor&b> &c- &6Set the potion color + &b/itemizer potion list &c- &6List all potion effects""")); + return true; + } + if (!hasPotion) { + sender.sendMessage("Get a POTION in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.potion.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 5) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion add <&feffect&b> <&flevel&b> <&ftime[tick]&b> &c- &6Add a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage(colorize("&4The potion &f\"" + args[2] + "&f\"&4 does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + Integer tick = parseInt(sender, args[4]); + if (level == null || tick == null) { + return true; + } + final PotionEffect pot = new PotionEffect(potType, tick, level); + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (potionMeta.hasCustomEffect(pot.getType())) { + sender.sendMessage(colorize("&4This potion already has &f" + pot.getType().getName())); + return true; + } + potionMeta.addCustomEffect(pot, false); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(pot.getType().getName() + " &2has been added to the potion")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.potion.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion remove <&feffect&b> &c- &6Remove a potion effect")); + return true; + } + PotionEffectType potType = PotionEffectType.getByName(args[2].toUpperCase()); + if (potType == null) { + sender.sendMessage("&4The potion effect &f\"" + args[2] + "&f\"&4 does not exist!"); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + if (!potionMeta.hasCustomEffect(potType)) { + sender.sendMessage(colorize("This potion does not have &f" + potType.getName())); + return true; + } + potionMeta.removeCustomEffect(potType); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(potType.getName() + " &2has been removed from the potion")); + return true; + } + case "change" -> { + if (!sender.hasPermission("itemizer.potion.change")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion change <&fname&b> &c- &6Change the potion type")); + return true; + } + Material material = Material.matchMaterial(args[2]); + if (material == null || !POTIONS.contains(material)) { + sender.sendMessage(colorize(material != null ? + "&f'" + material.name() + "' &4is not a potion type!" + : + "&4That material doesn't exist!")); + return true; + } + item.setType(material); + sender.sendMessage(colorize("&2The potion in hand has changed to &f'" + material.name() + "'")); + return true; + } + case "color" -> { + if (!sender.hasPermission("itemizer.potion.color")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dPotion Commands&f]&3===============\n" + + "&b/itemizer potion color <&fhexcolor&b> &c- &6Set a potion color")); + return true; + } + final PotionMeta potionMeta = (PotionMeta) meta; + assert potionMeta != null; + try { + java.awt.Color awtColor = java.awt.Color.decode(args[2]); + Color color = Color.fromRGB(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue()); + potionMeta.setColor(color); + item.setItemMeta(potionMeta); + sender.sendMessage(colorize(args[2] + " &2has been set as potion color")); + } catch (NumberFormatException ignored) { + sender.sendMessage(colorize("&4The hex &f\"" + args[2] + "&f\"&4 is invalid!")); + return true; + } + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.potion.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + PotionEffectType[] effects; + for (int i = 0; i < (effects = PotionEffectType.values()).length; i++) { + sb.append(", ").append(effects[i].getName()); + } + sender.sendMessage(colorize("&2Available potion effects: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer potion &bfor help.")); + return true; + } + } + } + } + case "attr" -> { + if (!sender.hasPermission("itemizer.attr")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dAttribute Commands&f]&3=============== + &b/itemizer attr add <&fname&b> <&fstrength&b> [&fslot&b] &c - &6Add an attribute + &b/itemizer attr remove <&fname&b> &c- &6Remove an attribute + &b/itemizer attr list &c- &6List all item's attributes + &b/itemizer attr listall &c- &6List all supported attributes""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } else { + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.attr.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.addAttr(player, args); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.attr.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.removeAttr(player, args[2]); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.attr.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + AttributeManager.listAttr(player); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.attr.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Supported attributes: " + + "&e" + AttributeManager.Attributes.getAttributes())); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer attr &bfor help.")); + return true; + } + } + } + } + case "flag" -> { + if (!sender.hasPermission("itemizer.flag")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dFlag Commands&f]&3=============== + &b/itemizer flag add <&fname&b> &c- &6Add a flag + &b/itemizer flag remove <&fname&b> &c- &6Remove a flag + &b/itemizer flag list &c- &6List all item's flag + &b/itemizer flag listall &c- &6List all available flags""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.flag.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag add <&fname&b> &c- &6Add a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4already added to the item!")); + return true; + } + meta.addItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been added to your item!")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.flag.remove")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dFlag Commands&f]&3===============\n" + + "&b/itemizer flag remove <&fname&b> &c- &6remove a flag")); + return true; + } + ItemFlag flag = null; + try { + flag = ItemFlag.valueOf(args[2].toUpperCase()); + } catch (Exception ignored) { + } + if (flag == null) { + sender.sendMessage(colorize("&4The flag &f\"" + args[2] + "&f\" does not exist!")); + return true; + } + assert meta != null; + if (!meta.getItemFlags().contains(flag)) { + sender.sendMessage(colorize("&4The flag &f'" + args[2].toUpperCase() + "' &4has not been added the item!")); + return true; + } + meta.removeItemFlags(flag); + item.setItemMeta(meta); + sender.sendMessage(colorize("&2The flag &f'" + args[2].toUpperCase() + "' &2has been removed from your item!")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.flag.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getItemFlags()).isEmpty()) { + sender.sendMessage(colorize("&4The item in your hand does not have any flags")); + return true; + } + sender.sendMessage(colorize("&2Item flags: &e" + + StringUtils.join(meta.getItemFlags(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.flag.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + sender.sendMessage(colorize("&2Available item flags: &e" + + StringUtils.join(ItemFlag.values(), ", "))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer flag &bfor help")); + return true; + } + } + } + case "enchant" -> { + if (!sender.hasPermission("itemizer.enchant")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize(""" + &3===============&f[&dEnchant Commands&f]&3=============== + &b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant + &b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant + &b/itemizer enchant list &c- &6List all item's enchants + &b/itemizer enchant listall &c- &6List all available enchants""")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + switch (args[1]) { + case "add" -> { + if (!sender.hasPermission("itemizer.enchant.add")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length < 4) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant add <&fname&b> <&flevel&b> &c- &6Add an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + Integer level = parseInt(sender, args[3]); + if (level == null) { + return true; + } + item.addUnsafeEnchantment(ench, level); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been added to your item")); + return true; + } + case "remove" -> { + if (!sender.hasPermission("itemizer.enchant.remove")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 2) { + sender.sendMessage(colorize("&3===============&f[&dEnchant Commands&f]&3===============\n" + + "&b/itemizer enchant remove <&fname&b> &c- &6Remove an enchant")); + return true; + } + final Enchantment ench = EnchantmentWrapper.getByKey(NamespacedKey.minecraft(args[2].toLowerCase())); + if (ench == null) { + sender.sendMessage(colorize("&4The enchantment &f'" + args[2] + "&f' &4does not exist!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + if (!meta.getEnchants().containsKey(ench)) { + sender.sendMessage(colorize("&4This item doesn't have &f'" + ench.getKey().getKey() + "' &4enchant!")); + return true; + } + item.removeEnchantment(ench); + sender.sendMessage(colorize("&2The enchant &f'" + ench.getKey().getKey() + "' &2has been removed from your item")); + return true; + } + case "list" -> { + if (!sender.hasPermission("itemizer.enchant.list")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + assert meta != null; + if (Objects.requireNonNull(meta.getEnchants()).isEmpty()) { + sender.sendMessage(colorize("&4This item doesn't hold any enchants")); + return true; + } + sender.sendMessage(colorize("&2Item enchants: &e" + + StringUtils.join(meta.getEnchants().keySet(), ", "))); + return true; + } + case "listall" -> { + if (!sender.hasPermission("itemizer.enchant.listall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + StringBuilder sb = new StringBuilder(); + Enchantment[] enchantments; + for (int i = 0; i < (enchantments = Enchantment.values()).length; i++) { + sb.append(", ").append(enchantments[i].getKey().getKey()); + } + sender.sendMessage(colorize("&2Available item enchants: &e" + + sb.toString().replaceFirst(", ", ""))); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer enchant &bfor help.")); + return true; + } + } + } + case "title" -> { + if (!sender.hasPermission("itemizer.title")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dTitle Command&f]&3===============\n" + + "&b/itemizer title <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(StringUtils.join(args, " ", 1, args.length)); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setTitle(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The title of the book has been set to &f'" + name + "&f'")); + return true; + } + case "author" -> { + if (!sender.hasPermission("itemizer.author")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dAuthor Command&f]&3===============\n" + + "&b/itemizer author <&fname&b> &c- &6Set the book's title")); + return true; + } + if (!hasBook) { + sender.sendMessage("Get a WRITTEN_BOOK in hand!"); + return true; + } + String name = colorize(args[1]); + final BookMeta bookMeta = (BookMeta) meta; + assert bookMeta != null; + bookMeta.setAuthor(name); + item.setItemMeta(bookMeta); + sender.sendMessage(colorize("&2The author of the book has been set to &f'" + name + "&f'")); + return true; + } + case "head" -> { + if (!sender.hasPermission("itemizer.head")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (args.length == 1) { + sender.sendMessage(colorize("&3===============&f[&dHead Command&f]&3===============\n" + + "&b/itemizer head <&fname&b> &c- &6Set the player of the head")); + return true; + } + if (item.getType() != Material.PLAYER_HEAD) { + sender.sendMessage("Get a SKULL in hand!"); + return true; + } + String name = args[1]; + if (name.length() > 16) { + name = name.substring(0, 16); + } + final SkullMeta skullMeta = (SkullMeta) meta; + assert skullMeta != null; + skullMeta.setOwner(name); + item.setItemMeta(skullMeta); + sender.sendMessage(colorize("&2The player of the head has been set to &f'" + name + "&f'")); + return true; + } + case "sign" -> { + if (!sender.hasPermission("itemizer.sign")) { + sender.sendMessage("&4You don't have permission to use this command!"); + return true; + } + if (args.length < 3) { + sender.sendMessage(colorize("&3===============&f[&dSign Command&f]&3===============\n" + + "&b/itemizer sign <&fline&b> <&ftext&b> &c- &6Change the line on the sign")); + return true; + } + final Block block = player.getTargetBlockExact(20); + if (block == null || block.getType() == Material.AIR + || !block.getType().toString().contains("SIGN")) { + sender.sendMessage(colorize("&4Please look at a sign!")); + return true; + } + Integer line = parseInt(sender, args[1]); + if (line == null) { + return true; + } else if (line > 4) { + sender.sendMessage(colorize("&4There's maximum of 4 lines on a sign")); + return true; + } + String text = colorize(StringUtils.join(args, " ", 2, args.length)); + if (cpb.getAPI() != null) { + cpb.getAPI().logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData()); + } + Sign sign = (Sign) block.getState(); + sign.setLine(line - 1, text); + sign.update(); + if (cpb.getAPI() != null) { + cpb.getAPI().logPlacement(player.getName(), sign.getLocation(), sign.getType(), sign.getBlockData()); + } + sender.sendMessage(colorize("&2Line &f'" + line + "'&2 has successfully changed to &f'" + text + "&f'")); + return true; + } + case "clearall" -> { + if (!sender.hasPermission("itemizer.clearall")) { + sender.sendMessage(colorize("&4You don't have permission to use this command!")); + return true; + } + if (!hasItem) { + sender.sendMessage("Get an ITEM in hand!"); + return true; + } + item.setItemMeta(null); + sender.sendMessage(colorize("&2All data cleared from your item")); + return true; + } + default -> { + sender.sendMessage(colorize("&bUnknown sub-command. Type &6/itemizer help &bfor help.")); + return true; + } + } + } + + private String colorize(String string) { + Matcher matcher = Pattern.compile("&#[a-fA-F0-9]{6}").matcher(string); + while (matcher.find()) { + String code = matcher.group().replace("&", ""); + string = string.replace("&" + code, net.md_5.bungee.api.ChatColor.of(code) + ""); + } + string = ChatColor.translateAlternateColorCodes('&', string); + return string; + } + + private Integer parseInt(CommandSender sender, String string) { + try { + return Integer.parseInt(string); + } catch (NumberFormatException ex) { + sender.sendMessage(colorize("&f\"" + string + "&f\"&4 is not a valid number!")); + } + return null; + } +} diff --git a/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXTab.java b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXTab.java new file mode 100644 index 0000000..d88360a --- /dev/null +++ b/v1_20_R1/src/main/java/dev/plex/itemizerx/v1_20_R1/ItemizerXTab.java @@ -0,0 +1,105 @@ +package dev.plex.itemizerx.v1_20_R1; + +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemFlag; +import org.bukkit.potion.PotionEffectType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ItemizerXTab implements TabCompleter { + + @Override + public List onTabComplete(CommandSender sender, Command cmd, String string, String[] args) { + if (args.length == 1) { + return Arrays.asList("help", "id", "lore", "potion", "attr", "flag", "enchant", "title", "author", + "head", "sign", "clearall"); + } + + if (args.length == 2) { + switch (args[0]) { + case "id": { + List materials = new ArrayList<>(); + for (Material material : Material.values()) { + materials.add(material.name()); + } + return materials; + } + case "lore": { + return Arrays.asList("add", "remove", "change", "clear"); + } + case "potion": { + return Arrays.asList("add", "remove", "change", "color", "list"); + } + case "attr": + case "flag": + case "enchant": { + return Arrays.asList("add", "remove", "list", "listall"); + } + default: { + return Collections.emptyList(); + } + } + } + + if (args.length == 3) { + switch (args[0]) { + case "potion": { + switch (args[1]) { + case "add": + case "remove": { + List potions = new ArrayList<>(); + for (PotionEffectType effect : PotionEffectType.values()) { + potions.add(effect.getName()); + } + return potions; + } + } + } + case "attr": { + switch (args[1]) { + case "add": + case "remove": { + return AttributeManager.Attributes.getAttributeList(); + } + } + } + case "flag": { + switch (args[1]) { + case "add": + case "remove": { + List flags = new ArrayList<>(); + for (ItemFlag flag : ItemFlag.values()) { + flags.add(flag.name()); + } + return flags; + } + } + } + case "enchant": { + switch (args[1]) { + case "add": + case "remove": { + List enchantments = new ArrayList<>(); + for (Enchantment enchantment : Enchantment.values()) { + enchantments.add(enchantment.getKey().getKey()); + } + return enchantments; + } + } + } + default: { + return Collections.emptyList(); + } + } + } + + return Collections.emptyList(); + } +}