diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1b781a03..26a59d80 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -15,14 +15,14 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
+ java-version: '19'
+ cache: 'gradle'
- - name: Run maven build lifecycle
- run: mvn --batch-mode clean test package
+ - name: Run gradle build lifecycle
+ run: ./gradlew build shadowJar --no-daemon
- name: Upload plugin file
uses: actions/upload-artifact@v2
with:
name: ProtocolLib
- path: target/ProtocolLib.jar
+ path: build/libs/ProtocolLib.jar
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 6f0883fc..b0f9adc9 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -26,16 +26,16 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'temurin'
- java-version: '17'
- cache: 'maven'
+ java-version: '19'
+ cache: 'gradle'
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: 'java'
- - name: Run maven build lifecycle
- run: mvn --batch-mode clean test package
+ - name: Run gradle build lifecycle
+ run: ./gradlew build -x test --no-daemon
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
diff --git a/Readme.md b/Readme.md
index 922a3ac1..e842356d 100644
--- a/Readme.md
+++ b/Readme.md
@@ -20,8 +20,10 @@ Currently maintained by dmulloy2 on behalf of [Spigot](https://www.spigotmc.org/
### Compilation
-ProtocolLib is built with [Maven](https://maven.apache.org/). If you have it installed, just run
-`mvn package` in the root project folder.
+ProtocolLib is built with [Gradle](https://gradle.org/). If you have it installed, just run
+`./gradlew build` in the root project folder. Other gradle targets you may be interested in
+include `clean`, `test`, and `shadowJar`. `shadowJar` will create a jar with all dependencies
+(ByteBuddy) included.
### A new API
@@ -53,7 +55,7 @@ You can also add ProtocolLib as a Maven dependency:
com.comphenix.protocol
ProtocolLib
- 4.7.0
+ 5.0.0-SNAPSHOT
provided
@@ -67,7 +69,7 @@ repositories {
}
dependencies {
- compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.7.0";
+ compileOnly 'com.comphenix.protocol:ProtocolLib:5.0.0-SNAPSHOT'
}
```
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 00000000..52d611a0
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,112 @@
+plugins {
+ id 'java-library'
+ id 'maven-publish'
+ id 'com.github.johnrengelman.shadow' version '8.1.1'
+}
+
+group = 'com.comphenix.protocol'
+version = '5.0.0-SNAPSHOT'
+description = 'Provides access to the Minecraft protocol'
+
+def isSnapshot = version.endsWith('-SNAPSHOT')
+
+repositories {
+ // mavenLocal() // can speed up build, but may fail in CI
+ mavenCentral()
+
+ maven {
+ url 'https://repo.dmulloy2.net/repository/public/'
+ }
+
+ maven {
+ url 'https://hub.spigotmc.org/nexus/content/groups/public/'
+ }
+
+ maven {
+ url 'https://libraries.minecraft.net/'
+ metadataSources {
+ mavenPom()
+ artifact()
+ ignoreGradleMetadataRedirection()
+ }
+ }
+}
+
+dependencies {
+ implementation 'net.bytebuddy:byte-buddy:1.14.3'
+ compileOnly 'org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT'
+ compileOnly 'org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT'
+ compileOnly 'io.netty:netty-all:4.0.23.Final'
+ compileOnly 'net.kyori:adventure-text-serializer-gson:4.13.0'
+ compileOnly 'com.googlecode.json-simple:json-simple:1.1.1'
+
+ testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
+ testImplementation 'org.mockito:mockito-core:4.11.0'
+ testImplementation 'org.mockito:mockito-inline:4.11.0'
+ testImplementation 'io.netty:netty-common:4.1.77.Final'
+ testImplementation 'io.netty:netty-transport:4.1.77.Final'
+ testImplementation 'org.spigotmc:spigot:1.19.4-R0.1-SNAPSHOT'
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+
+ withJavadocJar()
+ withSourcesJar()
+}
+
+shadowJar {
+ dependencies {
+ include(dependency('net.bytebuddy:byte-buddy:.*'))
+ }
+ relocate 'net.bytebuddy', 'com.comphenix.net.bytebuddy'
+ archiveFileName = 'ProtocolLib.jar'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+processResources {
+ def includeBuild = isSnapshot && System.getenv('BUILD_NUMBER')
+ def fullVersion = includeBuild
+ ? version + '-' + System.getenv('BUILD_NUMBER')
+ : version
+
+ eachFile { expand(['version': fullVersion]) }
+}
+
+publishing {
+ publications {
+ mavenJava(MavenPublication) {
+ from components.java
+
+ afterEvaluate {
+ artifactId = 'ProtocolLib'
+ }
+ }
+ }
+
+ repositories {
+ maven {
+ url isSnapshot
+ ? 'https://repo.dmulloy2.net/repository/snapshots/'
+ : 'https://repo.dmulloy2.net/repository/releases/'
+
+ credentials {
+ username project.nexusUsername
+ password project.nexusPassword
+ }
+ }
+ }
+}
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+tasks.withType(Javadoc) {
+ options.encoding = 'UTF-8'
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 00000000..cdfa8a4e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,2 @@
+nexusUsername=""
+nexusPassword=""
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..ccebba77
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 00000000..bdc9a83b
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
+networkTimeout=10000
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 00000000..79a61d42
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,244 @@
+#!/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/HEAD/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
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+# 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*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC3045
+ 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 \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# 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 00000000..93e3f59f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,92 @@
+@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=.
+@rem This is normally unused
+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% equ 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% equ 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!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 00000000..dba5d8e1
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,5 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ */
+
+rootProject.name = 'ProtocolLib'
diff --git a/src/main/java/com/comphenix/protocol/events/PacketOutputHandler.java b/src/main/java/com/comphenix/protocol/events/PacketOutputHandler.java
index 4e8f86b2..739336f0 100644
--- a/src/main/java/com/comphenix/protocol/events/PacketOutputHandler.java
+++ b/src/main/java/com/comphenix/protocol/events/PacketOutputHandler.java
@@ -28,7 +28,7 @@ public interface PacketOutputHandler {
* Note that the buffer is initially filled with the output from the default write method.
*
* In Minecraft 1.6.4, the header is always excluded, whereas it MUST be included in Minecraft 1.7.2. Call
- * {@link NetworkMarker#requireOutputHeader()} to determine this.
+ * NetworkMarker#requireOutputHeader() to determine this.
* @param event - the packet that will be outputted.
* @param buffer - the data that is currently scheduled to be outputted.
* @return The modified byte array to write. NULL is not permitted.
diff --git a/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java b/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
index 4dc8c598..75ac1c08 100644
--- a/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
+++ b/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
@@ -252,10 +252,17 @@ public class PacketRegistry {
protected static void associatePackets(Register register, Map> lookup, PacketType.Protocol protocol, Sender sender) {
for (Map.Entry> entry : lookup.entrySet()) {
- PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
+ int packetId = entry.getKey();
+ Class> packetClass = entry.getValue();
+
+ if (MinecraftReflection.isBundleDelimiter(packetClass)) {
+ continue;
+ }
+
+ PacketType type = PacketType.fromCurrent(protocol, sender, packetId, packetClass);
try {
- register.registerPacket(type, entry.getValue(), sender);
+ register.registerPacket(type, packetClass, sender);
} catch (Exception ex) {
ProtocolLogger.debug("Encountered an exception associating packet " + type, ex);
}
@@ -271,18 +278,28 @@ public class PacketRegistry {
}
}
+ private static final Object registryLock = new Object();
+
/**
* Initializes the packet registry.
*/
private static void initialize() {
- if (!INITIALIZED) {
- INITIALIZED = true;
+ if (INITIALIZED) {
+ return;
+ }
+
+ synchronized (registryLock) {
+ if (INITIALIZED) {
+ return;
+ }
if (MinecraftVersion.BEE_UPDATE.atOrAbove()) {
REGISTER = createNewRegister();
} else {
REGISTER = createOldRegister();
}
+
+ INITIALIZED = true;
}
}
diff --git a/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java b/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java
index 7feba84b..08139233 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java
@@ -65,6 +65,7 @@ public abstract class EnumWrappers {
/**
* @deprecated Replaced by NOT_SET
*/
+ @Deprecated
NONE;
/**
@@ -377,9 +378,9 @@ public abstract class EnumWrappers {
/**
* Wrapped EntityPose enum for use in Entity Metadata Packet.
- *
- * @apiNote Remember to use {@link #toNms()} when adding to a {@link WrappedDataWatcher}.
- * Serializer is obtained using Registry.get(EnumWrappers.getEntityPoseClass())
+ * Remember to use {@link #toNms()} when adding to a {@link WrappedDataWatcher}.
+ * Serializer is obtained using Registry.get(EnumWrappers.getEntityPoseClass())
+ *
* @since 1.13
* @author Lewys Davies (Lew_)
*/
diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedAttribute.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedAttribute.java
index e42acb19..1b44ba54 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/WrappedAttribute.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedAttribute.java
@@ -168,6 +168,7 @@ public class WrappedAttribute extends AbstractWrapper {
* @deprecated Removed in 1.17
*/
@Nullable
+ @Deprecated
public PacketContainer getParentPacket() {
if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
return null;
diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java
index 89b6465a..b30c2476 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java
@@ -941,8 +941,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements IterableNote: If the serializer is optional, values must be
+ *
+ * Note: If the serializer is optional, values must be
* wrapped in an {@link Optional}
*
* @param clazz Class to find serializer for
diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedIntHashMap.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedIntHashMap.java
index ef6f3fcb..08cd8935 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/WrappedIntHashMap.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedIntHashMap.java
@@ -16,6 +16,7 @@ import com.google.common.base.Preconditions;
* @author Kristian
* @deprecated IntHashMap no longer exists
*/
+@Deprecated
public class WrappedIntHashMap extends AbstractWrapper {
private static Method PUT_METHOD;
private static Method GET_METHOD;
diff --git a/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMap.java b/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMap.java
index 56e796b6..c1b1800a 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMap.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMap.java
@@ -136,10 +136,10 @@ public abstract class ConvertedMap extends AbstractConverte
/**
* Returns a string representation of this map. The string representation
* consists of a list of key-value mappings in the order returned by the
- * map's entrySet view's iterator, enclosed in braces
- * ("{}"). Adjacent mappings are separated by the characters
- * ", " (comma and space). Each key-value mapping is rendered as
- * the key followed by an equals sign ("=") followed by the
+ * map's entrySet
view's iterator, enclosed in braces
+ * ("{}"
). Adjacent mappings are separated by the characters
+ * ", "
(comma and space). Each key-value mapping is rendered as
+ * the key followed by an equals sign ("="
) followed by the
* associated value. Keys and values are converted to strings as by
* {@link String#valueOf(Object)}.
*
diff --git a/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMultimap.java b/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMultimap.java
index ab5e03be..5000b1ba 100644
--- a/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMultimap.java
+++ b/src/main/java/com/comphenix/protocol/wrappers/collection/ConvertedMultimap.java
@@ -204,10 +204,10 @@ public abstract class ConvertedMultimap extends AbstractCon
/**
* Returns a string representation of this map. The string representation
* consists of a list of key-value mappings in the order returned by the
- * map's entrySet view's iterator, enclosed in braces
- * ("{}"). Adjacent mappings are separated by the characters
- * ", " (comma and space). Each key-value mapping is rendered as
- * the key followed by an equals sign ("=") followed by the
+ * map's entrySet
view's iterator, enclosed in braces
+ * ("{}"
). Adjacent mappings are separated by the characters
+ * ", "
(comma and space). Each key-value mapping is rendered as
+ * the key followed by an equals sign ("="
) followed by the
* associated value. Keys and values are converted to strings as by
* {@link String#valueOf(Object)}.
*
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 4de8994d..3db7f73c 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,5 @@
name: ProtocolLib
-version: ${project.fullVersion}
+version: ${version}
description: Provides read/write access to the Minecraft protocol.
authors: [dmulloy2, comphenix]
diff --git a/src/test/java/com/comphenix/protocol/BukkitInitialization.java b/src/test/java/com/comphenix/protocol/BukkitInitialization.java
index 0f00d6b9..13df557c 100644
--- a/src/test/java/com/comphenix/protocol/BukkitInitialization.java
+++ b/src/test/java/com/comphenix/protocol/BukkitInitialization.java
@@ -41,17 +41,24 @@ public class BukkitInitialization {
/**
* Statically initializes the mock server for unit testing
*/
- public static synchronized void initializeAll() {
+ public static void initializeAll() {
instance.initialize();
}
+ private static final Object initLock = new Object();
+
/**
- * Initialize Bukkit and ProtocolLib such that we can perfrom unit testing
+ * Initialize Bukkit and ProtocolLib such that we can perform unit testing
*/
private void initialize() {
- if (!this.initialized) {
- // Denote that we're done
- this.initialized = true;
+ if (initialized) {
+ return;
+ }
+
+ synchronized (initLock) {
+ if (initialized) {
+ return;
+ }
try {
LogManager.getLogger();
@@ -104,6 +111,8 @@ public class BukkitInitialization {
// Inject this fake server
Bukkit.setServer(mockedServer);
+
+ initialized = true;
}
}
diff --git a/src/test/java/com/comphenix/protocol/PacketTypeTest.java b/src/test/java/com/comphenix/protocol/PacketTypeTest.java
index de342b68..6f53a60b 100644
--- a/src/test/java/com/comphenix/protocol/PacketTypeTest.java
+++ b/src/test/java/com/comphenix/protocol/PacketTypeTest.java
@@ -49,9 +49,9 @@ public class PacketTypeTest {
BukkitInitialization.initializeAll();
// I'm well aware this is jank, but it does in fact work correctly and give the desired result
- PacketType.onDynamicCreate = className -> {
+ /*PacketType.onDynamicCreate = className -> {
throw new RuntimeException("Dynamically generated packet " + className);
- };
+ };*/
}
@AfterAll
@@ -267,11 +267,6 @@ public class PacketTypeTest {
return builder.toString();
}
- @BeforeAll
- public static void initializeReflection() {
- BukkitInitialization.initializeAll();
- }
-
@Test
public void testFindCurrent() {
assertEquals(PacketType.Play.Client.STEER_VEHICLE,
@@ -297,42 +292,54 @@ public class PacketTypeTest {
@Test
@SuppressWarnings("unchecked")
public void ensureTypesAreCorrect() throws Exception {
- boolean fail = false;
+ PacketType.onDynamicCreate = className -> {
+ throw new RuntimeException("Dynamically generated packet " + className);
+ };
- EnumProtocol[] protocols = EnumProtocol.values();
- for (EnumProtocol protocol : protocols) {
- Field field = EnumProtocol.class.getDeclaredField("k");
- field.setAccessible(true);
+ try {
+ boolean fail = false;
- Map map = (Map) field.get(protocol);
- for (Entry entry : map.entrySet()) {
- Field mapField = entry.getValue().getClass().getDeclaredField("b");
- mapField.setAccessible(true);
+ EnumProtocol[] protocols = EnumProtocol.values();
+ for (EnumProtocol protocol : protocols) {
+ Field field = EnumProtocol.class.getDeclaredField("k");
+ field.setAccessible(true);
- Map, Integer> reverseMap = (Map, Integer>) mapField.get(entry.getValue());
+ Map map = (Map) field.get(protocol);
+ for (Entry entry : map.entrySet()) {
+ Field mapField = entry.getValue().getClass().getDeclaredField("b");
+ mapField.setAccessible(true);
- Map> treeMap = new TreeMap<>();
- for (Entry, Integer> entry1 : reverseMap.entrySet()) {
- treeMap.put(entry1.getValue(), entry1.getKey());
- }
+ Map, Integer> reverseMap = (Map, Integer>) mapField.get(entry.getValue());
- for (Entry> entry1 : treeMap.entrySet()) {
- try {
- PacketType type = PacketType.fromClass(entry1.getValue());
- if (type.getCurrentId() != entry1.getKey()) {
- throw new IllegalStateException(
- "Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got "
- + type.getCurrentId());
+ Map> treeMap = new TreeMap<>();
+ for (Entry, Integer> entry1 : reverseMap.entrySet()) {
+ treeMap.put(entry1.getValue(), entry1.getKey());
+ }
+
+ for (Entry> entry1 : treeMap.entrySet()) {
+ try {
+ PacketType type = PacketType.fromClass(entry1.getValue());
+ if (type.getCurrentId() != entry1.getKey()) {
+ throw new IllegalStateException(
+ "Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got "
+ + type.getCurrentId());
+ }
+ } catch (Throwable ex) {
+ if (ex.getMessage().contains("BundleDelimiterPacket")) {
+ continue;
+ }
+
+ ex.printStackTrace();
+ fail = true;
}
- } catch (Throwable ex) {
- ex.printStackTrace();
- fail = true;
}
}
}
- }
- assertFalse(fail, "Packet type(s) were incorrect!");
+ assertFalse(fail, "Packet type(s) were incorrect!");
+ } finally {
+ PacketType.onDynamicCreate = __ -> { };
+ }
}
@Test