Compare commits

...
20 Commits
Author SHA1 Message Date
Dan Mulloy 41bb4bacb2 Update version to 4.8.0 for release 2022-03-04 16:28:13 -05:00
Pasqual Koschmieder 9487c42985 Update to 1.18.2 (#1521) 2022-02-28 13:36:20 -05:00
derklaro 55f7b67f9d Update to junit 5, remove powermock 2022-02-25 00:11:26 -05:00
Pasqual Koschmieder e44d1e6051 Improve auto wrapper handling (#1518) 2022-02-25 00:02:11 -05:00
Pasqual Koschmieder baecaf4ca4 Remove unsafe reflection trying to access the modifiers field (#1517) 2022-02-24 23:56:22 -05:00
Pasqual Koschmieder 151d4a289f Prevent memory leaks with loads of PacketMarker objects (#1511)
closes #1509
2022-02-24 16:41:43 -05:00
Pasqual Koschmieder 1b4d79b302 Fix compile issues with the latest spigot version (#1510) 2022-02-24 16:18:56 -05:00
Pasqual Koschmieder 74833f8680 Correctly resolve protocol version of player (#1473) 2022-01-02 12:32:46 -06:00
Pasqual Koschmieder e77f8ced4c Update to 1.18.1 (#1461)
No changes required except for registering the protocol version
2021-12-19 20:50:22 -05:00
Dan Mulloy 1cd83e493d Update version to 4.8.0-SNAPSHOT 2021-11-30 14:14:50 -05:00
Pasqual Koschmieder 40b6c66491 Update to minecraft 1.18 (#1446) 2021-11-30 14:10:03 -05:00
LewUwU 723fc2c7ec Update NettyVersion.java (#1438)
The issue was caused due to a change in the pom of netty (for dependencies)

(#Generated by netty-parent/pom.xml
#Mon, 11 Oct 2021 13:22:16 +0200

netty-all.version=4.1.69.Final
netty-all.buildDate=2021-10-11 13\:22\:16 +0200
netty-all.commitDate=2021-10-11 09\:21\:07 +0000
netty-all.shortCommitHash=34a31522f0
netty-all.longCommitHash=34a31522f0145e2d434aaea2ef8ac5ed8d1a91a0
netty-all.repoStatus=dirty)

Is not more netty-common, now is netty-all
2021-11-14 12:09:34 -05:00
Dan Mulloy dd687ce175 Fix NPE in PlayerInfoData equals
Fixes #1400
Closes #1106
2021-11-14 00:41:20 -05:00
Nassim Jahnke 8774d87d59 Add 1.17 long jump pose (#1409) 2021-11-13 23:51:37 -05:00
Dan Mulloy 8361cf078f Fix GH actions build 2021-09-22 13:29:23 -04:00
Rothes dbedab0c14 Check entityID whether is negative or not. (#1362) 2021-09-22 10:51:47 -04:00
Pim van der Loos 5dda8c8ab1 Fix entity tracker methods for 1.17 (#1354)
- In 1.17, EntityTrackerEntries use ServerPlayerConnections instead of EntityPlayers as they did before. This caused the updateEntity to silently fail when removing the players from the trackedPlayers collection (of connections). This was resolved by retrieving the connections of the players before removing them from the list on 1.17+.
The getEntityTrackers method failed because it could not find any players for the same reason. This was resolved by retrieving the player from the connection before retrieving the Bukkit player from the EntityPlayer object when running on 1.17+.
- This fixes dmulloy2/ProtocolLib#1340
2021-07-26 23:51:24 -07:00
Dan Mulloy 4c0c18d7c6 Remove stack trace for list converter
Addresses #1331
2021-07-10 11:09:56 -04:00
Dan Mulloy 9c20455bf6 Update version to 4.7.1-SNAPSHOT 2021-07-10 11:08:35 -04:00
Dan Mulloy 8175443da0 Update to 4.7.0 2021-07-09 17:16:07 -04:00
73 changed files with 1563 additions and 1310 deletions

No files matched your search

+2 -3
View File
@@ -12,9 +12,8 @@ jobs:
- name: Setup java
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '16'
check-latest: true
distribution: 'temurin'
java-version: '17'
- name: Run maven build lifecycle
run: mvn --batch-mode clean test package
+2 -1
View File
@@ -179,4 +179,5 @@ logs/
.gradle/
build/
logs/
logs/
.java-version
+2 -2
View File
@@ -53,7 +53,7 @@ You can also add ProtocolLib as a Maven dependency:
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.6.0</version>
<version>4.7.0</version>
</dependency>
</dependencies>
````
@@ -66,7 +66,7 @@ repositories {
}
dependencies {
compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.6.0";
compileOnly group: "com.comphenix.protocol", name: "ProtocolLib", version: "4.7.0";
}
```
+2 -2
View File
@@ -1,5 +1,5 @@
before_install:
- source "$HOME/.sdkman/bin/sdkman-init.sh"
- sdk update
- sdk install java 16.0.1.hs-adpt
- sdk use java 16.0.1.hs-adpt
- sdk install java 17.0.1-tem
- sdk use java 17.0.1-tem
+71 -34
View File
@@ -1,10 +1,10 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.comphenix.protocol</groupId>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<name>ProtocolLib</name>
<version>4.7.0-SNAPSHOT</version>
<version>4.8.0</version>
<description>Provides read/write access to the Minecraft protocol.</description>
<url>https://github.com/dmulloy2/ProtocolLib</url>
@@ -16,8 +16,10 @@
<project.build.number></project.build.number>
<project.fullVersion>${project.version}</project.fullVersion>
<powermock.version>2.0.7</powermock.version>
<spigot.version>1.17.1-R0.1-SNAPSHOT</spigot.version>
<junit.version>5.8.2</junit.version>
<mockito.version>4.3.1</mockito.version>
<netty.version>4.1.74.Final</netty.version>
<spigot.version>1.18.2-R0.1-SNAPSHOT</spigot.version>
</properties>
<build>
@@ -71,7 +73,7 @@
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<version>3.10.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
@@ -81,7 +83,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<version>3.2.2</version>
<configuration>
<archive>
<manifestEntries>
@@ -99,6 +101,14 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
<configuration>
<trimStackTrace>false</trimStackTrace>
<useFile>false</useFile>
@@ -108,22 +118,22 @@
<value>${project.version}</value>
</property>
</systemProperties>
<!-- TODO figure out a better way to do this before Java 17 -->
<!-- We're currently waiting on powermock, but we may need to switch -->
<argLine>--illegal-access=permit</argLine>
<!-- We need this as we use reflection in tests to ensure equality -->
<argLine>--add-opens java.base/java.util=ALL-UNNAMED</argLine>
</configuration>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<version>3.3.2</version>
<configuration>
<failOnError>false</failOnError>
<encoding>ISO-8859-1</encoding>
<doctitle>ProtocolLib JavaDocs</doctitle>
<windowtitle>ProtocolLib JavaDocs</windowtitle>
<bottom>Copyright &#169; {inceptionYear}&#x2013;{currentYear}
Comphenix and dmulloy2. Licensed under the GNU GPL v2.</bottom>
Comphenix and dmulloy2. Licensed under the GNU GPL v2.
</bottom>
<additionalOptions>
<additionalOption>-Xdoclint:none</additionalOption>
</additionalOptions>
@@ -185,7 +195,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<version>3.3.2</version>
<executions>
<execution>
<id>attach-javadocs</id>
@@ -227,7 +237,7 @@
<licenses>
<license>
<name>GNU GENERAL PUBLIC LICENSE - Version 2, June 1991</name>
<url>http://www.gnu.org/licenses/gpl-2.0.txt</url>
<url>https://www.gnu.org/licenses/gpl-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
@@ -236,7 +246,7 @@
<developer>
<id>dmulloy2</id>
<name>Dan Mulloy</name>
<url>http://dmulloy2.net/</url>
<url>https://dmulloy2.net/</url>
<roles>
<role>developer</role>
<role>maintainer</role>
@@ -246,7 +256,7 @@
<id>aadnk</id>
<name>Kristian S. Stangeland</name>
<email>kr_stang@hotmail.com</email>
<url>http://comphenix.net/</url>
<url>https://comphenix.net/</url>
<roles>
<role>former author</role>
</roles>
@@ -277,61 +287,88 @@
</repositories>
<dependencies>
<!-- Compile with the old version of Netty for backwards compat -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.23.Final</version>
<scope>provided</scope>
</dependency>
<!-- core minecraft dependencies -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>${spigot.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>${spigot.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Compile with the old version of Netty for backwards compat -->
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.0.23.Final</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/net.kyori/adventure-text-serializer-gson -->
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-serializer-gson</artifactId>
<version>4.5.1</version>
<version>4.9.3</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.11.0</version>
<version>1.12.8</version>
</dependency>
<!-- Testing dependencies -->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.5.10</version>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-inline -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-common -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<groupId>io.netty</groupId>
<artifactId>netty-common</artifactId>
<version>${netty.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-transport -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>${netty.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -19,6 +19,7 @@ package com.comphenix.protocol;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -31,13 +32,16 @@ import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.injector.netty.WirePacket;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.base.Charsets;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.libs.org.apache.commons.io.HexDump;
import org.bukkit.plugin.Plugin;
/**
@@ -47,6 +51,8 @@ import org.bukkit.plugin.Plugin;
public class PacketLogging implements CommandExecutor, PacketListener {
public static final String NAME = "packetlog";
private static MethodAccessor HEX_DUMP;
private List<PacketType> sendingTypes = new ArrayList<>();
private List<PacketType> receivingTypes = new ArrayList<>();
@@ -199,7 +205,13 @@ public class PacketLogging implements CommandExecutor, PacketListener {
private static String hexDump(byte[] bytes) throws IOException {
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
HexDump.dump(bytes, 0, output, 0);
if (HEX_DUMP == null) {
Class<?> hexDumpClass = MinecraftReflection.getLibraryClass("org.apache.commons.io.HexDump");
HEX_DUMP = Accessors.getMethodAccessor(FuzzyReflection.fromClass(hexDumpClass)
.getMethodByParameters("dump", byte[].class, long.class, OutputStream.class, int.class));
}
HEX_DUMP.invoke(null, bytes, 0, output, 0);
return new String(output.toByteArray(), Charsets.UTF_8);
}
}
@@ -137,7 +137,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
public static final PacketType OPEN_WINDOW_HORSE = new PacketType(PROTOCOL, SENDER, 0x1F, "OpenWindowHorse");
public static final PacketType INITIALIZE_BORDER = new PacketType(PROTOCOL, SENDER, 0x20, "InitializeBorder");
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x21, "KeepAlive", "SPacketKeepAlive");
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x22, "MapChunk", "SPacketChunkData");
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x22, "MapChunk", "SPacketChunkData", "LevelChunkWithLight");
public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x23, "WorldEvent", "SPacketEffect");
public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x24, "WorldParticles", "SPacketParticles");
public static final PacketType LIGHT_UPDATE = new PacketType(PROTOCOL, SENDER, 0x25, "LightUpdate");
@@ -190,22 +190,23 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x54, "Mount", "SPacketSetPassengers");
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x55, "ScoreboardTeam", "SPacketTeams");
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x56, "ScoreboardScore", "SPacketUpdateScore");
public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x57, "SetSubtitleText");
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x58, "UpdateTime", "SPacketTimeUpdate");
public static final PacketType SET_TITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x59, "SetTitleText");
public static final PacketType SET_TITLES_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x5A, "SetTitlesAnimation");
public static final PacketType ENTITY_SOUND = new PacketType(PROTOCOL, SENDER, 0x5B, "EntitySound", "SPacketSoundEffect");
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x5C, "NamedSoundEffect");
public static final PacketType STOP_SOUND = new PacketType(PROTOCOL, SENDER, 0x5D, "StopSound");
public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x5E, "PlayerListHeaderFooter", "SPacketPlayerListHeaderFooter");
public static final PacketType NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x5F, "NBTQuery");
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x60, "Collect", "SPacketCollectItem");
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x61, "EntityTeleport", "SPacketEntityTeleport");
public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x62, "Advancements", "SPacketAdvancementInfo");
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x63, "UpdateAttributes", "SPacketEntityProperties");
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x64, "EntityEffect", "SPacketEntityEffect");
public static final PacketType RECIPE_UPDATE = new PacketType(PROTOCOL, SENDER, 0x65, "RecipeUpdate");
public static final PacketType TAGS = new PacketType(PROTOCOL, SENDER, 0x66, "Tags");
public static final PacketType UPDATE_SIMULATION_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x57, "SetSimulationDistance");
public static final PacketType SET_SUBTITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x58, "SetSubtitleText");
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x59, "UpdateTime", "SPacketTimeUpdate");
public static final PacketType SET_TITLE_TEXT = new PacketType(PROTOCOL, SENDER, 0x5A, "SetTitleText");
public static final PacketType SET_TITLES_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x5B, "SetTitlesAnimation");
public static final PacketType ENTITY_SOUND = new PacketType(PROTOCOL, SENDER, 0x5C, "EntitySound", "SPacketSoundEffect");
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x5D, "NamedSoundEffect");
public static final PacketType STOP_SOUND = new PacketType(PROTOCOL, SENDER, 0x5E, "StopSound");
public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x5F, "PlayerListHeaderFooter", "SPacketPlayerListHeaderFooter");
public static final PacketType NBT_QUERY = new PacketType(PROTOCOL, SENDER, 0x60, "NBTQuery");
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x61, "Collect", "SPacketCollectItem");
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x62, "EntityTeleport", "SPacketEntityTeleport");
public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x63, "Advancements", "SPacketAdvancementInfo");
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x64, "UpdateAttributes", "SPacketEntityProperties");
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x65, "EntityEffect", "SPacketEntityEffect");
public static final PacketType RECIPE_UPDATE = new PacketType(PROTOCOL, SENDER, 0x66, "RecipeUpdate");
public static final PacketType TAGS = new PacketType(PROTOCOL, SENDER, 0x67, "Tags");
// ---- Removed in 1.9
@@ -38,12 +38,12 @@ public class ProtocolLibrary {
/**
* The maximum version ProtocolLib has been tested with.
*/
public static final String MAXIMUM_MINECRAFT_VERSION = "1.17.1";
public static final String MAXIMUM_MINECRAFT_VERSION = "1.18.2";
/**
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.17.1) was released.
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.18.2) was released.
*/
public static final String MINECRAFT_LAST_RELEASE_DATE = "2021-07-06";
public static final String MINECRAFT_LAST_RELEASE_DATE = "2022-02-28";
/**
* Plugins that are currently incompatible with ProtocolLib.
@@ -45,6 +45,7 @@ import net.bytebuddy.matcher.ElementMatchers;
import org.bukkit.*;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.profile.PlayerProfile;
import com.comphenix.protocol.utility.ByteBuddyFactory;
@@ -176,7 +177,12 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable {
public UUID getUniqueId() {
return uuid;
}
@Override
public PlayerProfile getPlayerProfile() {
return null;
}
@Override
public String getName() {
return name;
@@ -28,6 +28,7 @@ import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftFields;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.WrappedIntHashMap;
@@ -67,7 +68,10 @@ class EntityUtilities {
Collection<?> trackedPlayers = getTrackedPlayers(entity);
List<Object> nmsPlayers = unwrapBukkit(observers);
trackedPlayers.removeAll(nmsPlayers);
List<Object> removingEntries = MinecraftVersion.CAVES_CLIFFS_1.atOrAbove() ?
getPlayerConnections(nmsPlayers) : nmsPlayers;
trackedPlayers.removeAll(removingEntries);
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
@@ -103,7 +107,9 @@ class EntityUtilities {
// Wrap every player - we also ensure that the underlying tracker list is immutable
for (Object tracker : trackedPlayers) {
if (MinecraftReflection.isMinecraftPlayer(tracker)) {
if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove() && MinecraftReflection.isServerHandler(tracker)) {
result.add(MinecraftReflection.getBukkitPlayerFromConnection(tracker));
} else if (MinecraftReflection.isMinecraftPlayer(tracker)) {
result.add((Player) MinecraftReflection.getBukkitEntity(tracker));
}
}
@@ -266,6 +272,12 @@ class EntityUtilities {
}
}
private List<Object> getPlayerConnections(List<Object> nmsPlayers) {
List<Object> connections = new ArrayList<>(nmsPlayers.size());
nmsPlayers.forEach(nmsPlayer -> connections.add(MinecraftFields.getPlayerConnection(nmsPlayer)));
return connections;
}
private List<Object> unwrapBukkit(List<Player> players) {
List<Object> output = Lists.newArrayList();
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
@@ -30,6 +30,7 @@ import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.VolatileField;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
import com.comphenix.protocol.utility.ByteBuddyFactory;
import com.comphenix.protocol.utility.ByteBuddyGenerated;
import com.comphenix.protocol.utility.MinecraftFields;
@@ -56,6 +57,7 @@ import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.*;
@@ -84,6 +86,7 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
// Versioning
private static Class<?> PACKET_SET_PROTOCOL = null;
private static FieldAccessor PROTOCOL_VERSION_ACCESSOR = null;
private static AtomicInteger keyId = new AtomicInteger();
private static AttributeKey<Integer> PROTOCOL_KEY;
@@ -272,7 +275,7 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
@Override
public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception {
super.write(ctx, packet, promise);
ChannelInjector.this.finalWrite();
ChannelInjector.this.finalWrite(packet);
}
@Override
@@ -541,7 +544,7 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
/**
* Invoked when a packet has been written to the channel
*/
private void finalWrite() {
private void finalWrite(Object packet) {
PacketEvent event = finalEvent;
if (event != null) {
@@ -550,6 +553,10 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
currentEvent = null;
processor.invokePostEvent(event, NetworkMarker.getNetworkMarker(event));
// remove the stored packet markers to prevent memory leaks
// See: https://github.com/dmulloy2/ProtocolLib/issues/1509
packetMarker.remove(packet);
}
}
@@ -662,15 +669,21 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
if (PACKET_SET_PROTOCOL == null) {
try {
PACKET_SET_PROTOCOL = PacketType.Handshake.Client.SET_PROTOCOL.getPacketClass();
// resolve the protocol version field here - if we're unable to find it we don't need to worry about it
Field protocolVersionField = FuzzyReflection.fromClass(PACKET_SET_PROTOCOL, true).getField(FuzzyFieldContract.newBuilder()
.banModifier(Modifier.STATIC)
.typeExact(int.class)
.build());
PROTOCOL_VERSION_ACCESSOR = Accessors.getFieldAccessor(protocolVersionField);
} catch (Throwable ex) {
PACKET_SET_PROTOCOL = getClass(); // If we can't find it don't worry about it
}
}
if (PACKET_SET_PROTOCOL.equals(packetClass)) {
FuzzyReflection fuzzy = FuzzyReflection.fromObject(packet);
try {
int protocol = (int) fuzzy.invokeMethod(packet, "getProtocol", int.class);
int protocol = (int) PROTOCOL_VERSION_ACCESSOR.get(packet);
originalChannel.attr(PROTOCOL_KEY).set(protocol);
} catch (Throwable ex) {
// Oh well
@@ -54,7 +54,7 @@ public class NettyByteBufAdapter extends AbstractByteBuf {
private static FieldAccessor READER_INDEX;
private static FieldAccessor WRITER_INDEX;
private static final int CAPACITY = Short.MAX_VALUE;
private static final int CAPACITY = Integer.MAX_VALUE;
private NettyByteBufAdapter(DataInputStream input, DataOutputStream output) {
// Just pick a figure
@@ -385,4 +385,4 @@ public class PipelineProxy implements ChannelPipeline {
return pipeline.voidPromise();
}
*/
}
}
@@ -17,6 +17,7 @@ package com.comphenix.protocol.reflect;
* limitations under the License.
*/
import com.comphenix.protocol.reflect.accessors.Accessors;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
@@ -394,20 +395,12 @@ public class FieldUtils {
writeStaticField(field, value);
}
/**
* @deprecated Use {@link #writeStaticField(Class, String, Object, boolean)} instead.
*/
@Deprecated
public static void writeStaticFinalField(Class<?> clazz, String fieldName, Object value, boolean forceAccess) throws Exception {
Field field = getField(clazz, fieldName, forceAccess);
if (field == null) {
throw new IllegalArgumentException("Cannot locate field " + fieldName + " in " + clazz);
}
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setAccessible(true);
field.set(null, value);
writeStaticField(clazz, fieldName, value, forceAccess);
}
/**
@@ -442,12 +435,8 @@ public class FieldUtils {
if (field == null) {
throw new IllegalArgumentException("The field must not be null");
}
if (forceAccess && !field.isAccessible()) {
field.setAccessible(true);
} else {
MemberUtils.setAccessibleWorkaround(field);
}
field.set(target, value);
Accessors.getFieldAccessor(field, forceAccess).set(target, value);
}
/**
@@ -308,7 +308,9 @@ public class StructureModifier<TField> {
* @param fieldIndex - index of the field.
* @param value - TRUE if this field should be read only, FALSE otherwise.
* @throws FieldAccessException If we cannot modify the read-only status.
* @deprecated In recent java versions (starting at 9) the modifier field is secured and will not be writeable.
*/
@Deprecated
public void setReadOnly(int fieldIndex, boolean value) throws FieldAccessException {
if (fieldIndex < 0 || fieldIndex >= data.size())
throw new IllegalArgumentException("Index parameter is not within [0 - " + data.size() + ")");
@@ -325,7 +327,9 @@ public class StructureModifier<TField> {
* @param field - the field to change.
* @param isReadOnly - TRUE if the field should be read only, FALSE otherwise.
* @throws IllegalAccessException If an error occured.
* @deprecated In recent java versions (starting at 9) the modifier field is secured and will not be writeable.
*/
@Deprecated
protected static void setFinalState(Field field, boolean isReadOnly) throws IllegalAccessException {
if (isReadOnly)
FieldUtils.writeField((Object) field, "modifiers", field.getModifiers() | Modifier.FINAL, true);
@@ -1,14 +1,28 @@
package com.comphenix.protocol.reflect.accessors;
import com.comphenix.protocol.ProtocolLogger;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.WrongMethodTypeException;
import java.lang.reflect.Field;
final class DefaultFieldAccessor implements FieldAccessor {
private final Field field;
private MethodHandle setter;
public DefaultFieldAccessor(Field field) {
this.field = field;
// try to get a getter and setter handle for the field
if (UnsafeFieldAccess.hasTrustedLookup()) {
try {
setter = UnsafeFieldAccess.findSetter(field);
} catch (ReflectiveOperationException exception) {
ProtocolLogger.debug("Unable to get setter for field " + field, exception);
}
}
}
@Override
public Object get(Object instance) {
try {
@@ -19,18 +33,25 @@ final class DefaultFieldAccessor implements FieldAccessor {
throw new IllegalStateException("Cannot use reflection.", e);
}
}
@Override
public void set(Object instance, Object value) {
try {
field.set(instance, value);
} catch (IllegalArgumentException e) {
if (setter == null) {
field.set(instance, value);
} else {
setter.invoke(instance, value);
}
} catch (IllegalArgumentException | ClassCastException e) {
throw new RuntimeException("Cannot set field " + field + " to value " + value, e);
} catch (IllegalAccessException e) {
} catch (IllegalAccessException | WrongMethodTypeException e) {
throw new IllegalStateException("Cannot use reflection.", e);
} catch (Throwable ignored) {
// cannot happen - this might only occur when the handle targets a method
throw new RuntimeException("Cannot happen");
}
}
@Override
public Field getField() {
return field;
@@ -43,16 +64,17 @@ final class DefaultFieldAccessor implements FieldAccessor {
@Override
public boolean equals(Object obj) {
if (this == obj)
if (this == obj) {
return true;
}
if (obj instanceof DefaultFieldAccessor) {
DefaultFieldAccessor other = (DefaultFieldAccessor) obj;
return other.field == field;
}
return true;
}
@Override
public String toString() {
return "DefaultFieldAccessor [field=" + field + "]";
@@ -0,0 +1,48 @@
package com.comphenix.protocol.reflect.accessors;
import com.comphenix.protocol.ProtocolLogger;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.logging.Level;
final class UnsafeFieldAccess {
private static final Lookup TRUSTED_LOOKUP;
static {
Lookup trusted = null;
try {
// get the unsafe class
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
// get the unsafe instance
Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
sun.misc.Unsafe unsafe = (sun.misc.Unsafe) theUnsafe.get(null);
// get the trusted lookup field
Field trustedLookup = Lookup.class.getDeclaredField("IMPL_LOOKUP");
// get access to the base and offset value of it
long offset = unsafe.staticFieldOffset(trustedLookup);
Object baseValue = unsafe.staticFieldBase(trustedLookup);
// get the trusted lookup instance
trusted = (Lookup) unsafe.getObject(baseValue, offset);
} catch (Exception exception) {
ProtocolLogger.log(Level.SEVERE, "Unable to retrieve trusted lookup", exception);
}
TRUSTED_LOOKUP = trusted;
}
public static boolean hasTrustedLookup() {
return TRUSTED_LOOKUP != null;
}
public static MethodHandle findSetter(Field field) throws ReflectiveOperationException {
if (Modifier.isStatic(field.getModifiers())) {
return TRUSTED_LOOKUP.findStaticSetter(field.getDeclaringClass(), field.getName(), field.getType());
} else {
return TRUSTED_LOOKUP.findSetter(field.getDeclaringClass(), field.getName(), field.getType());
}
}
}
@@ -58,8 +58,6 @@ public abstract class CompiledStructureModifier extends StructureModifier<Object
throw new IllegalStateException("Cannot make compiled field " + fieldIndex + " read only.");
}
}
super.setReadOnly(fieldIndex, value);
}
// Speed up the default writer
@@ -21,10 +21,10 @@ package com.comphenix.protocol.utility;
*/
public final class Constants {
public static final String PACKAGE_VERSION = "v1_17_R1";
public static final String PACKAGE_VERSION = "v1_18_R2";
public static final String NMS = "net.minecraft";
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;
public static final MinecraftVersion CURRENT_VERSION = MinecraftVersion.CAVES_CLIFFS_1;
public static final MinecraftVersion CURRENT_VERSION = MinecraftVersion.CAVES_CLIFFS_2;
public static void init() {
MinecraftReflection.setMinecraftPackage(NMS, OBC);
@@ -15,15 +15,16 @@ public class MinecraftFields {
// Cached accessors
private static volatile FieldAccessor CONNECTION_ACCESSOR;
private static volatile FieldAccessor NETWORK_ACCESSOR;
private static volatile FieldAccessor CONNECTION_ENTITY_ACCESSOR;
private MinecraftFields() {
// Not constructable
}
/**
* Retrieve the network mananger associated with a particular player.
* Retrieve the network manager associated with a particular player.
* @param player - the player.
* @return The network manager, or NULL if no network manager has been asssociated yet.
* @return The network manager, or NULL if no network manager has been associated yet.
*/
public static Object getNetworkManager(Player player) {
Object nmsPlayer = BukkitUnwrapper.getInstance().unwrapItem(player);
@@ -50,9 +51,13 @@ public class MinecraftFields {
Preconditions.checkNotNull(player, "player cannot be null!");
return getPlayerConnection(BukkitUnwrapper.getInstance().unwrapItem(player));
}
// Retrieve player connection from a native instance
private static Object getPlayerConnection(Object nmsPlayer) {
/**
* Retrieve the PlayerConnection (or NetServerHandler) associated with a player.
* @param nmsPlayer - the NMS player.
* @return The player connection.
*/
public static Object getPlayerConnection(Object nmsPlayer) {
Preconditions.checkNotNull(nmsPlayer, "nmsPlayer cannot be null!");
if (CONNECTION_ACCESSOR == null) {
@@ -61,4 +66,21 @@ public class MinecraftFields {
}
return CONNECTION_ACCESSOR.get(nmsPlayer);
}
/**
* Retrieves the EntityPlayer player field from a PlayerConnection.
*
* @param playerConnection The PlayerConnection object from which to retrieve the EntityPlayer field.
* @return The value of the EntityPlayer field in the PlayerConnection.
*/
public static Object getPlayerFromConnection(Object playerConnection) {
Preconditions.checkNotNull(playerConnection, "playerConnection cannot be null!");
if (CONNECTION_ENTITY_ACCESSOR == null) {
Class<?> connectionClass = MinecraftReflection.getPlayerConnectionClass();
Class<?> entityPlayerClass = MinecraftReflection.getEntityPlayerClass();
CONNECTION_ENTITY_ACCESSOR = Accessors.getFieldAccessor(connectionClass, entityPlayerClass, true);
}
return CONNECTION_ENTITY_ACCESSOR.get(playerConnection);
}
}
@@ -76,6 +76,11 @@ public class MinecraftProtocolVersion {
map.put(new MinecraftVersion(1, 17, 0), 755);
map.put(new MinecraftVersion(1, 17, 1), 756);
map.put(new MinecraftVersion(1, 18, 0), 757);
map.put(new MinecraftVersion(1, 18, 1), 757);
map.put(new MinecraftVersion(1, 18, 2), 758);
return map;
}
@@ -41,6 +41,7 @@ import javax.annotation.Nonnull;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.PacketType;
@@ -376,6 +377,21 @@ public class MinecraftReflection {
}
}
/**
* Retrieve the Bukkit player from a given PlayerConnection.
* @param playerConnection The PlayerConnection.
* @return A bukkit player.
* @throws RuntimeException If we were unable to retrieve the Bukkit player.
*/
public static Player getBukkitPlayerFromConnection(Object playerConnection)
{
try {
return (Player) getBukkitEntity(MinecraftFields.getPlayerFromConnection(playerConnection));
} catch (Exception e) {
throw new IllegalArgumentException("Cannot get Bukkit entity from connection " + playerConnection, e);
}
}
/**
* Determine if a given object can be found within the package net.minecraft.server.
* @param obj - the object to test.
@@ -2251,13 +2267,7 @@ public class MinecraftReflection {
}
public static Class<?> getFastUtilClass(String className) {
try {
return getMinecraftLibraryClass("it.unimi.dsi.fastutil." + className);
} catch (RuntimeException ex) {
Class<?> clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil." + className);
setMinecraftLibraryClass("it.unimi.dsi.fastutil." + className, clazz);
return clazz;
}
return getLibraryClass("it.unimi.dsi.fastutil." + className);
}
public static Class<?> getInt2ObjectMapClass() {
@@ -2267,4 +2277,14 @@ public class MinecraftReflection {
public static Class<?> getIntArrayListClass() {
return getFastUtilClass("ints.IntArrayList");
}
public static Class<?> getLibraryClass(String classname) {
try {
return getMinecraftLibraryClass(classname);
} catch (RuntimeException ex) {
Class<?> clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs." + classname);
setMinecraftLibraryClass(classname, clazz);
return clazz;
}
}
}
@@ -44,6 +44,11 @@ public class MinecraftVersion implements Comparable<MinecraftVersion>, Serializa
*/
private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-.]+).*");
/**
* Version 1.18 - caves and cliffs part 2
*/
public static final MinecraftVersion CAVES_CLIFFS_2 = new MinecraftVersion("1.18");
/**
* Version 1.17 - caves and cliffs part 1
*/
@@ -6,7 +6,8 @@ import io.netty.util.Version;
import java.util.Map;
public class NettyVersion {
private final static String NETTY_ARTIFACT_ID = "netty-common";
private final static String NETTY_COMMON_ID = "netty-common";
private final static String NETTY_ALL_ID = "netty-all";
private static NettyVersion version;
public static NettyVersion getVersion() {
@@ -18,7 +19,10 @@ public class NettyVersion {
private static NettyVersion detectVersion() {
Map<String, Version> nettyArtifacts = Version.identify();
Version version = nettyArtifacts.get(NETTY_ARTIFACT_ID);
Version version = nettyArtifacts.get(NETTY_COMMON_ID);
if(version == null) {
version = nettyArtifacts.get(NETTY_ALL_ID);
}
if(version != null) {
return new NettyVersion(version.artifactVersion());
}
@@ -738,4 +738,4 @@ public class ZeroBuffer extends ByteBuf {
public ByteBuf retain() {
return null;
}
}
}
@@ -16,6 +16,12 @@
*/
package com.comphenix.protocol.wrappers;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.reflect.instances.DefaultInstances;
import com.google.common.base.Defaults;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;
@@ -41,9 +47,18 @@ import com.comphenix.protocol.utility.MinecraftReflection;
* @author dmulloy2
*/
public class AutoWrapper<T> implements EquivalentConverter<T> {
private static final Object[] NO_ARGS = new Object[0];
private Map<Integer, Function<Object, Object>> wrappers = new HashMap<>();
private Map<Integer, Function<Object, Object>> unwrappers = new HashMap<>();
// lazy
private FieldAccessor[] nmsAccessors;
private FieldAccessor[] wrapperAccessors;
private Object[] nmsDefaultArgs;
private ConstructorAccessor nmsInstanceCreator;
private Class<T> wrapperClass;
private Class<?> nmsClass;
@@ -79,75 +94,77 @@ public class AutoWrapper<T> implements EquivalentConverter<T> {
throw new InvalidWrapperException(wrapperClass.getSimpleName() + " is not accessible!", ex);
}
Field[] wrapperFields = wrapperClass.getDeclaredFields();
Field[] nmsFields = Arrays
.stream(nmsClass.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.toArray(Field[]::new);
// ensures that all accessors are present
computeFieldAccessors();
for (int i = 0; i < wrapperFields.length; i++) {
try {
Field wrapperField = wrapperFields[i];
for (int i = 0; i < wrapperAccessors.length; i++) {
FieldAccessor source = nmsAccessors[i];
FieldAccessor target = wrapperAccessors[i];
Field nmsField = nmsFields[i];
if (!nmsField.isAccessible())
nmsField.setAccessible(true);
Object value = source.get(nmsObject);
if (wrappers.containsKey(i))
value = wrappers.get(i).apply(value);
Object value = nmsField.get(nmsObject);
if (wrappers.containsKey(i))
value = wrappers.get(i).apply(value);
wrapperField.set(instance, value);
} catch (Exception ex) {
throw new InvalidWrapperException("Failed to wrap field at index " + i, ex);
}
target.set(instance, value);
}
return instance;
}
public Object unwrap(Object wrapper) {
Object instance;
// ensures that all accessors are present
computeFieldAccessors();
computeNmsConstructorAccess();
try {
instance = nmsClass.newInstance();
} catch (ReflectiveOperationException ex) {
throw new InvalidWrapperException("Failed to construct new " + nmsClass.getSimpleName(), ex);
}
Object instance = nmsInstanceCreator.invoke(nmsDefaultArgs);
Field[] wrapperFields = wrapperClass.getDeclaredFields();
Field[] nmsFields = Arrays
.stream(nmsClass.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.toArray(Field[]::new);
for (int i = 0; i < wrapperAccessors.length; i++) {
FieldAccessor source = wrapperAccessors[i];
FieldAccessor target = nmsAccessors[i];
for (int i = 0; i < wrapperFields.length; i++) {
try {
Field wrapperField = wrapperFields[i];
Object value = source.get(wrapper);
if (unwrappers.containsKey(i))
value = unwrappers.get(i).apply(value);
Field nmsField = nmsFields[i];
if (!nmsField.isAccessible())
nmsField.setAccessible(true);
if (Modifier.isFinal(nmsField.getModifiers()))
unsetFinal(nmsField);
Object value = wrapperField.get(wrapper);
if (unwrappers.containsKey(i))
value = unwrappers.get(i).apply(value);
nmsField.set(instance, value);
} catch (ReflectiveOperationException ex) {
throw new InvalidWrapperException("Failed to unwrap field", ex);
}
target.set(instance, value);
}
return instance;
}
private void unsetFinal(Field field) throws ReflectiveOperationException {
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
private void computeFieldAccessors() {
if (nmsAccessors == null) {
nmsAccessors = Arrays
.stream(nmsClass.getDeclaredFields())
.filter(field -> !Modifier.isStatic(field.getModifiers()))
.map(field -> Accessors.getFieldAccessor(field, true))
.toArray(FieldAccessor[]::new);
}
if (wrapperAccessors == null) {
wrapperAccessors = Arrays
.stream(wrapperClass.getDeclaredFields())
.map(field -> Accessors.getFieldAccessor(field, true))
.toArray(FieldAccessor[]::new);
}
}
private void computeNmsConstructorAccess() {
if (nmsInstanceCreator == null) {
ConstructorAccessor noArgs = Accessors.getConstructorAccessorOrNull(nmsClass);
if (noArgs != null) {
// no args constructor is available - use it
nmsInstanceCreator = noArgs;
nmsDefaultArgs = NO_ARGS;
} else {
// use the first constructor of the class
nmsInstanceCreator = Accessors.getConstructorAccessor(nmsClass.getDeclaredConstructors()[0]);
nmsDefaultArgs = Arrays
.stream(nmsInstanceCreator.getConstructor().getParameterTypes())
.map(type -> type.isPrimitive() ? Defaults.defaultValue(type) : null)
.toArray(Object[]::new);
}
}
}
// ---- Equivalent conversion
@@ -284,7 +284,7 @@ public class BukkitConverters {
}
};
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
// ex.printStackTrace();
supplier = ArrayList::new;
newList = new ArrayList<>();
}
@@ -717,7 +717,7 @@ public class BukkitConverters {
ProtocolManager manager = managerRef.get();
// Use the entity ID to get a reference to the entity
if (id != null && manager != null) {
if (id != null && id >= 0 && manager != null) {
return manager.getEntityFromID(world, id);
} else {
return null;
@@ -384,6 +384,7 @@ public abstract class EnumWrappers {
SWIMMING,
SPIN_ATTACK,
CROUCHING,
LONG_JUMPING,
DYING;
private final static EquivalentConverter<EntityPose> POSE_CONVERTER = EnumWrappers.getEntityPoseConverter();
@@ -19,6 +19,7 @@ package com.comphenix.protocol.wrappers;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.reflect.EquivalentConverter;
@@ -26,7 +27,6 @@ import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
import com.google.common.base.Objects;
/**
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
@@ -176,19 +176,19 @@ public class PlayerInfoData {
if (obj instanceof PlayerInfoData) {
PlayerInfoData other = (PlayerInfoData) obj;
return profile.equals(other.profile) && latency == other.latency && gameMode == other.gameMode
&& displayName.equals(other.displayName);
&& Objects.equals(displayName, other.displayName);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(latency, gameMode, profile, displayName);
return Objects.hash(latency, gameMode, profile, displayName);
}
@Override
public String toString() {
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s",
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s]",
latency, gameMode, profile, displayName);
}
}
@@ -495,7 +495,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
.build();
List<Method> methods = fuzzy.getMethodList(contract);
for (Method method : methods) {
if (method.getName().equals("set") || method.getName().equals("watch")) {
if (method.getName().equals("set") || method.getName().equals("watch") || method.getName().equals("b")) {
SETTER = Accessors.getMethodAccessor(method);
} else {
REGISTER = Accessors.getMethodAccessor(method);
@@ -5,10 +5,10 @@ import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
@@ -46,9 +46,14 @@ public class WrappedRegistry {
REGISTRY = ImmutableMap.copyOf(regMap);
GET = Accessors.getMethodAccessor(regClass, "get", MinecraftReflection.getMinecraftKeyClass());
FuzzyReflection fuzzy = FuzzyReflection.fromClass(regClass, false);
GET = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract
.newBuilder()
.parameterCount(1)
.returnDerivedOf(Object.class)
.requireModifier(Modifier.ABSTRACT)
.parameterExactType(MinecraftReflection.getMinecraftKeyClass())
.build()));
GET_KEY = Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract
.newBuilder()
.parameterCount(1)
@@ -3,6 +3,10 @@ package com.comphenix.integration.protocol;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.reflect.FieldUtils;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
@@ -10,7 +14,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.simple.SimpleLogger;
import org.bukkit.Bukkit;
@@ -18,41 +21,25 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoadOrder;
import org.bukkit.plugin.PluginManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.reflect.FieldUtils;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
// TODO Migrate this to Gradle if necessary
// Damn final classes ...
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
@PrepareForTest(PluginDescriptionFile.class)
public class SimpleCraftBukkitITCase {
// The fake plugin
private static volatile Plugin FAKE_PLUGIN = null;
/**
* The maximum amount of time to wait before a server has started.
* <p>
* We have to give it the ample time of 60 seconds, as a server may have to
* generate the spawn area in three worlds.
* We have to give it the ample time of 60 seconds, as a server may have to generate the spawn area in three worlds.
*/
private static final int TIMEOUT_MS = 60000;
// The fake plugin
private static volatile Plugin FAKE_PLUGIN = null;
/**
* Setup the CraftBukkit server for all the tests.
* @throws IOException Unable to setup server.
*
* @throws IOException Unable to setup server.
* @throws InterruptedException Thread interrupted.
*/
//@BeforeClass
//@BeforeAll
public static void setupCraftBukkit() throws Exception {
setupPlugins();
@@ -63,17 +50,18 @@ public class SimpleCraftBukkitITCase {
System.out.println("Loader of SimpleLogger: " + SimpleLogger.class.getClassLoader());
System.out.println("Loader of Logger: " + Logger.class.getClassLoader());
}
// We need to wait until the server object is ready
while (Bukkit.getServer() == null)
while (Bukkit.getServer() == null) {
Thread.sleep(1);
}
// Make it clear this plugin doesn't exist
FAKE_PLUGIN = createPlugin("FakeTestPluginIntegration");
// No need to look for updates
FieldUtils.writeStaticField(ProtocolLibrary.class, "UPDATES_DISABLED", Boolean.TRUE, true);
// Wait until the server and all the plugins have loaded
Bukkit.getScheduler().callSyncMethod(FAKE_PLUGIN, new Callable<Object>() {
@Override
@@ -82,26 +70,22 @@ public class SimpleCraftBukkitITCase {
return null;
}
}).get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
// Plugins are now ready
ProtocolLibrary.getConfig().setDebug(true);
}
/**
* Close the CraftBukkit server when they're done.
*/
//@AfterClass
//@AfterAll
public static void shutdownCraftBukkit() {
Bukkit.shutdown();
}
//@Test
public void testPingPacket() throws Throwable {
TestPingPacket.newTest().startTest(FAKE_PLUGIN);
}
/**
* Copy ProtocolLib into the plugins folder.
*
* @throws IOException If anything went wrong.
*/
private static void setupPlugins() throws IOException {
@@ -109,27 +93,27 @@ public class SimpleCraftBukkitITCase {
File srcDirectory = new File("../");
File bestFile = null;
int bestLength = Integer.MAX_VALUE;
for (File file : srcDirectory.listFiles()) {
String name = file.getName();
if (file.isFile() && name.startsWith("ProtocolLib") && name.length() < bestLength) {
bestLength = name.length();
bestFile = file;
}
}
if (bestFile == null) {
throw new IllegalStateException("Cannot find ProtocolLib in " + srcDirectory);
}
// Copy the ProtocolLib plugin to the server
if (pluginDirectory.exists()) {
deleteFolder(pluginDirectory);
}
pluginDirectory.mkdirs();
File destination = new File(pluginDirectory, bestFile.getName()).getAbsoluteFile();
Files.copy(bestFile, destination);
}
@@ -148,46 +132,53 @@ public class SimpleCraftBukkitITCase {
}
}
}
/**
* Load a specific fake plugin.
*
* @param plugin - the plugin to load.
*/
@SuppressWarnings("unchecked")
private static void initializePlugin(Plugin plugin) {
PluginManager manager = Bukkit.getPluginManager();
try {
List<Plugin> plugins = (List<Plugin>) FieldUtils.readField(manager, "plugins", true);
Map<String, Plugin> lookupNames = (Map<String, Plugin>) FieldUtils.readField(manager, "lookupNames", true);
/// Associate this plugin
plugins.add(plugin);
lookupNames.put(plugin.getName(), plugin);
Map<String, Plugin> lookupNames = (Map<String, Plugin>) FieldUtils.readField(manager, "lookupNames", true);
/// Associate this plugin
plugins.add(plugin);
lookupNames.put(plugin.getName(), plugin);
} catch (Exception e) {
throw new RuntimeException("Unable to access the fields of " + manager, e);
}
}
/**
* Create a mockable plugin for all the tests.
*
* @param fakePluginName - the fake plugin name.
* @return The plugin.
*/
private static Plugin createPlugin(String fakePluginName) {
Plugin plugin = mock(Plugin.class);
PluginDescriptionFile description = mock(PluginDescriptionFile.class);
when(description.getDepend()).thenReturn(Lists.newArrayList("ProtocolLib"));
when(description.getSoftDepend()).thenReturn(Collections.<String>emptyList());
when(description.getLoadBefore()).thenReturn(Collections.<String>emptyList());
when(description.getSoftDepend()).thenReturn(Collections.emptyList());
when(description.getLoadBefore()).thenReturn(Collections.emptyList());
when(description.getLoad()).thenReturn(PluginLoadOrder.POSTWORLD);
when(plugin.getName()).thenReturn(fakePluginName);
when(plugin.getServer()).thenReturn(Bukkit.getServer());
when(plugin.isEnabled()).thenReturn(true);
when(plugin.getDescription()).thenReturn(description);
return plugin;
}
//@Test
public void testPingPacket() throws Throwable {
TestPingPacket.newTest().startTest(FAKE_PLUGIN);
}
}
@@ -1,5 +1,10 @@
package com.comphenix.integration.protocol;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.utility.StreamSerializer;
import com.google.common.io.ByteStreams;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
@@ -10,84 +15,110 @@ import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.utility.StreamSerializer;
import com.google.common.io.ByteStreams;
public class SimpleMinecraftClient {
private static final int CONNECT_TIMEOUT = 2500;
private static final int READ_TIMEOUT = 15000;
// Current Minecraft version
private final int protocolVersion;
private static final int CONNECT_TIMEOUT = 2500;
private static final int READ_TIMEOUT = 15000;
// Typical Minecraft serializer
private static final StreamSerializer serializer = StreamSerializer.getDefault();
// Current Minecraft version
private final int protocolVersion;
// Typical Minecraft serializer
private static StreamSerializer serializer = StreamSerializer.getDefault();
public SimpleMinecraftClient(int protocolVersion) {
public SimpleMinecraftClient(int protocolVersion) {
this.protocolVersion = protocolVersion;
}
/**
* Query the local server for ping information.
* @return The server information.
* @throws IOException
*/
public String queryLocalPing() throws IOException {
return queryServerPing(new InetSocketAddress("localhost", 25565));
/**
* Write a byte array to the output stream, prefixed by a length.
*
* @param output - the stream.
* @param data - the data to write.
*/
private static void writeByteArray(DataOutputStream output, byte[] data) throws IOException {
StreamSerializer.getDefault().serializeVarInt(output, data.length);
if (data.length > 0) {
output.write(data);
}
}
/**
* Read a byte array from an input stream, prefixed by length.
*
* @param input - the input stream.
* @return The read byte array.
*/
private static byte[] readByteArray(DataInputStream input) throws IOException {
int length = serializer.deserializeVarInt(input);
byte[] data = new byte[length];
ByteStreams.readFully(input, data);
return data;
}
/**
* Query the local server for ping information.
*
* @return The server information.
* @throws IOException
*/
public String queryLocalPing() throws IOException {
return this.queryServerPing(new InetSocketAddress("localhost", 25565));
}
/**
* Query the given server for its list ping information.
*
* @param address - the server hostname and port.
* @return The server information.
* @throws IOException
*/
public String queryServerPing(InetSocketAddress address) throws IOException {
Socket socket = null;
OutputStream output = null;
InputStream input = null;
try {
socket = new Socket();
socket.connect(address, CONNECT_TIMEOUT);
Socket socket = null;
OutputStream output = null;
InputStream input = null;
// Shouldn't take that long
socket.setSoTimeout(READ_TIMEOUT);
// Retrieve sockets
output = socket.getOutputStream();
input = socket.getInputStream();
try {
socket = new Socket();
socket.connect(address, CONNECT_TIMEOUT);
// The output writer
DataOutputStream data = new DataOutputStream(output);
// Shouldn't take that long
socket.setSoTimeout(READ_TIMEOUT);
// Request a server information packet
writePacket(data, new HandshakePacket(protocolVersion, address.getHostName(), address.getPort(), 1));
writePacket(data, new RequestPacket());
data.flush();
// Read a single packet, and close the connection
SimplePacket packet = readPacket(new DataInputStream(input), Protocol.STATUS);
socket.close();
return ((ResponsePacket) packet).getPingJson();
} finally {
if (input != null)
input.close();
if (output != null)
output.close();
if (socket != null)
socket.close();
}
// Retrieve sockets
output = socket.getOutputStream();
input = socket.getInputStream();
// The output writer
DataOutputStream data = new DataOutputStream(output);
// Request a server information packet
this.writePacket(data, new HandshakePacket(this.protocolVersion, address.getHostName(), address.getPort(), 1));
this.writePacket(data, new RequestPacket());
data.flush();
// Read a single packet, and close the connection
SimplePacket packet = this.readPacket(new DataInputStream(input), Protocol.STATUS);
socket.close();
return ((ResponsePacket) packet).getPingJson();
} finally {
if (input != null) {
input.close();
}
if (output != null) {
output.close();
}
if (socket != null) {
socket.close();
}
}
}
private void writePacket(DataOutputStream output, SimplePacket packet) throws IOException {
ByteArrayOutputStream packetBuffer = new ByteArrayOutputStream();
DataOutputStream packetOutput = new DataOutputStream(packetBuffer);
// Prefix the packet with a length field
packet.write(packetOutput);
writeByteArray(output, packetBuffer.toByteArray());
@@ -96,14 +127,15 @@ public class SimpleMinecraftClient {
private SimplePacket readPacket(DataInputStream input, Protocol protocol) throws IOException {
while (true) {
byte[] buffer = readByteArray(input);
// Skip empty packets
if (buffer.length == 0)
if (buffer.length == 0) {
continue;
DataInputStream data = getDataInput(buffer);
}
DataInputStream data = this.getDataInput(buffer);
PacketType type = PacketType.findCurrent(protocol, Sender.SERVER, serializer.deserializeVarInt(data));
if (type == PacketType.Status.Server.SERVER_INFO) {
ResponsePacket response = new ResponsePacket();
response.read(type, data);
@@ -116,69 +148,47 @@ public class SimpleMinecraftClient {
/**
* Wrap an input stream around a byte array.
*
* @param bytes - the array.
* @return The wrapped input stream.
*/
private DataInputStream getDataInput(byte[] bytes) {
return new DataInputStream(new ByteArrayInputStream(bytes));
}
/**
* Write a byte array to the output stream, prefixed by a length.
* @param output - the stream.
* @param data - the data to write.
*/
private static void writeByteArray(DataOutputStream output, byte[] data) throws IOException {
StreamSerializer.getDefault().serializeVarInt(output, data.length);
if (data.length > 0) {
output.write(data);
}
}
/**
* Read a byte array from an input stream, prefixed by length.
* @param input - the input stream.
* @return The read byte array.
*/
private static byte[] readByteArray(DataInputStream input) throws IOException {
int length = serializer.deserializeVarInt(input);
byte[] data = new byte[length];
ByteStreams.readFully(input, data);
return data;
}
private static class RequestPacket extends SimplePacket {
public RequestPacket() {
super(PacketType.Status.Client.START);
}
}
private static class ResponsePacket extends SimplePacket {
private String ping;
public ResponsePacket() {
super(PacketType.Status.Server.SERVER_INFO);
}
@Override
public void read(PacketType type, DataInputStream input) throws IOException {
super.read(type, input);
ping = serializer.deserializeString(input, 32000);
this.ping = this.serializer.deserializeString(input, 32000);
}
public String getPingJson() {
return ping;
return this.ping;
}
}
private static class HandshakePacket extends SimplePacket {
private int protocol;
private String host;
private int port;
private int nextState;
private final int protocol;
private final String host;
private final int port;
private final int nextState;
public HandshakePacket(int protocol, String host, int port, int nextState) {
super(PacketType.Handshake.Client.SET_PROTOCOL);
this.protocol = protocol;
@@ -190,25 +200,26 @@ public class SimpleMinecraftClient {
@Override
public void write(DataOutputStream output) throws IOException {
super.write(output);
serializer.serializeVarInt(output, protocol);
serializer.serializeString(output, host);
output.writeShort(port);
serializer.serializeVarInt(output, nextState);
this.serializer.serializeVarInt(output, this.protocol);
this.serializer.serializeString(output, this.host);
output.writeShort(this.port);
this.serializer.serializeVarInt(output, this.nextState);
}
}
private static class SimplePacket {
protected final PacketType type;
protected final StreamSerializer serializer = StreamSerializer.getDefault();
public SimplePacket(PacketType type) {
this.type = type;
}
public void write(DataOutputStream output) throws IOException {
serializer.serializeVarInt(output, type.getCurrentId());
this.serializer.serializeVarInt(output, this.type.getCurrentId());
}
@SuppressWarnings("unused")
public void read(PacketType type, DataInputStream input) throws IOException {
// Note - we don't read the packet id
@@ -1,21 +1,20 @@
package com.comphenix.integration.protocol;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.bukkit.plugin.Plugin;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import org.bukkit.plugin.Plugin;
public class TestPingPacket {
// Current versions
private static final int PROTOCOL_VERSION = 4;
@@ -30,6 +29,7 @@ public class TestPingPacket {
/**
* Create a new test ping packet test.
*
* @return The new test.
*/
public static TestPingPacket newTest() {
@@ -38,17 +38,18 @@ public class TestPingPacket {
/**
* Invoked when the test should be started.
*
* @param plugin - the current plugin.
* @throws Throwable Anything went wrong.
*/
public void startTest(Plugin plugin) throws Throwable {
try {
String transmitted = testInterception(plugin).
get(TIMEOUT_PING_MS, TimeUnit.MILLISECONDS);
String transmitted = this.testInterception(plugin).
get(TIMEOUT_PING_MS, TimeUnit.MILLISECONDS);
// Make sure it's the same
System.out.println("Server string: " + transmitted);
assertEquals(source, transmitted);
assertEquals(this.source, transmitted);
} catch (ExecutionException e) {
throw e.getCause();
}
@@ -56,12 +57,12 @@ public class TestPingPacket {
private Future<String> testInterception(Plugin test) {
ProtocolLibrary.getProtocolManager().addPacketListener(
new PacketAdapter(test, PacketType.Status.Server.SERVER_INFO) {
@Override
public void onPacketSending(PacketEvent event) {
source = event.getPacket().getServerPings().read(0).toJson();
}
});
new PacketAdapter(test, PacketType.Status.Server.SERVER_INFO) {
@Override
public void onPacketSending(PacketEvent event) {
TestPingPacket.this.source = event.getPacket().getServerPings().read(0).toJson();
}
});
// Invoke the client on a separate thread
return Executors.newSingleThreadExecutor().submit(new Callable<String>() {
@@ -71,8 +72,9 @@ public class TestPingPacket {
String information = client.queryLocalPing();
// Wait for the listener to catch up
for (int i = 0; i < 1000 && (source == null); i++)
for (int i = 0; i < 1000 && (TestPingPacket.this.source == null); i++) {
Thread.sleep(1);
}
return information;
}
@@ -1,50 +1,45 @@
package com.comphenix.protocol;
import java.util.Collections;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.utility.Constants;
import com.mojang.bridge.game.GameVersion;
import java.util.Collections;
import java.util.List;
import net.minecraft.SharedConstants;
import net.minecraft.core.IRegistry;
import net.minecraft.server.DispenserRegistry;
import net.minecraft.server.level.WorldServer;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_17_R1.CraftServer;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.v1_17_R1.util.Versioning;
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.v1_18_R2.util.Versioning;
import org.spigotmc.SpigotWorldConfig;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Used to ensure that ProtocolLib and Bukkit is prepared to be tested.
*
* @author Kristian
*/
public class BukkitInitialization {
private static final BukkitInitialization instance = new BukkitInitialization();
private boolean initialized;
private boolean packaged;
private BukkitInitialization() {
System.out.println("Created new BukkitInitialization on " + Thread.currentThread().getName());
}
private boolean initialized;
private boolean packaged;
public static synchronized void initializePackage() {
instance.setPackage();
}
public static synchronized void initializeItemMeta() {
/**
* Statically initializes the mock server for unit testing
*/
public static synchronized void initializeAll() {
instance.initialize();
}
@@ -52,9 +47,9 @@ public class BukkitInitialization {
* Initialize Bukkit and ProtocolLib such that we can perfrom unit testing
*/
private void initialize() {
if (!initialized) {
if (!this.initialized) {
// Denote that we're done
initialized = true;
this.initialized = true;
try {
LogManager.getLogger();
@@ -63,10 +58,10 @@ public class BukkitInitialization {
ex.printStackTrace();
}
initializePackage();
instance.setPackage();
SharedConstants.a();
DispenserRegistry.init();
DispenserRegistry.a();
try {
IRegistry.class.getName();
@@ -74,12 +69,15 @@ public class BukkitInitialization {
ex.printStackTrace();
}
String releaseTarget = SharedConstants.b().getReleaseTarget();
String serverVersion = CraftServer.class.getPackage().getImplementationVersion();
// Mock the server object
Server mockedServer = mock(Server.class);
when(mockedServer.getLogger()).thenReturn(java.util.logging.Logger.getLogger("Minecraft"));
when(mockedServer.getName()).thenReturn("Mock Server");
when(mockedServer.getVersion()).thenReturn(CraftServer.class.getPackage().getImplementationVersion());
when(mockedServer.getVersion()).thenReturn(serverVersion + " (MC: " + releaseTarget + ")");
when(mockedServer.getBukkitVersion()).thenReturn(Versioning.getBukkitVersion());
when(mockedServer.getItemFactory()).thenReturn(CraftItemFactory.instance());
@@ -110,8 +108,8 @@ public class BukkitInitialization {
* Ensure that package names are correctly set up.
*/
private void setPackage() {
if (!packaged) {
packaged = true;
if (!this.packaged) {
this.packaged = true;
try {
LogManager.getLogger();
@@ -2,39 +2,38 @@
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Test;
import com.comphenix.protocol.utility.MinecraftProtocolVersion;
import com.comphenix.protocol.utility.MinecraftVersion;
import org.junit.jupiter.api.Test;
public class MinecraftVersionTest {
@Test
public void testComparision() {
MinecraftVersion within = new MinecraftVersion(1, 2, 5);
MinecraftVersion outside = new MinecraftVersion(1, 7, 0);
MinecraftVersion lower = new MinecraftVersion(1, 0, 0);
MinecraftVersion highest = new MinecraftVersion(1, 4, 5);
MinecraftVersion atLeast = new MinecraftVersion(1, 8, 8);
// Make sure this is valid
@@ -54,8 +53,9 @@ public class MinecraftVersionTest {
assertEquals(MinecraftVersion.extractVersion("CraftBukkit R3.0 (MC: 1.4.3)"), "1.4.3");
assertEquals(MinecraftVersion.extractVersion("CraftBukkit Test Beta 1 (MC: 1.10.01 )"), "1.10.01");
assertEquals(MinecraftVersion.extractVersion("Hello (MC: 2.3.4)"), "2.3.4");
assertEquals(MinecraftVersion.fromServerVersion("git-Cauldron-Reloaded-1.7.10-1.1388.1.0 (MC: 1.7.10)"), new MinecraftVersion(1, 7, 10));
assertEquals(MinecraftVersion.fromServerVersion("git-Cauldron-Reloaded-1.7.10-1.1388.1.0 (MC: 1.7.10)"),
new MinecraftVersion(1, 7, 10));
assertEquals(MinecraftVersion.fromServerVersion("git-Bukkit-18fbb24 (MC: 1.8.8)"), new MinecraftVersion(1, 8, 8));
}
}
@@ -1,62 +1,63 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2016 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol;
import java.lang.reflect.Field;
import java.util.*;
import java.util.Map.Entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.PacketType.Sender;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.injector.packet.PacketRegistry;
import com.comphenix.protocol.utility.Constants;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import net.minecraft.network.EnumProtocol;
import net.minecraft.network.protocol.EnumProtocolDirection;
import net.minecraft.network.protocol.login.PacketLoginInStart;
import org.apache.commons.lang.WordUtils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class PacketTypeTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
// I'm well aware this is jank, but it does in fact work correctly and give the desired result
PacketType.onDynamicCreate = className -> {
throw new RuntimeException("Dynamically generated packet " + className);
throw new RuntimeException("Dynamically generated packet " + className);
};
}
@AfterClass
@AfterAll
public static void afterClass() {
PacketType.onDynamicCreate = __ -> {};
PacketType.onDynamicCreate = __ -> {
};
}
@SuppressWarnings("unchecked")
@@ -229,7 +230,8 @@ public class PacketTypeTest {
names.add(alias);
}
}
} catch (Exception ignored) { }
} catch (Exception ignored) {
}
return names;
}
@@ -246,14 +248,15 @@ public class PacketTypeTest {
return builder.toString();
}
@BeforeClass
@BeforeAll
public static void initializeReflection() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
public void testFindCurrent() {
assertEquals(PacketType.Play.Client.STEER_VEHICLE, PacketType.findCurrent(Protocol.PLAY, Sender.CLIENT, "SteerVehicle"));
assertEquals(PacketType.Play.Client.STEER_VEHICLE,
PacketType.findCurrent(Protocol.PLAY, Sender.CLIENT, "SteerVehicle"));
}
@Test
@@ -264,12 +267,12 @@ public class PacketTypeTest {
@Test
public void testDeprecation() {
assertTrue("Packet isn't properly deprecated", PacketType.Status.Server.OUT_SERVER_INFO.isDeprecated());
assertTrue("Deprecated packet isn't properly included",
PacketRegistry.getServerPacketTypes().contains(PacketType.Status.Server.OUT_SERVER_INFO));
assertFalse("Packet isn't properly deprecated", PacketType.Play.Server.CHAT.isDeprecated());
assertEquals("Deprecated packets aren't equal", PacketType.Status.Server.OUT_SERVER_INFO,
PacketType.Status.Server.SERVER_INFO);
assertTrue(PacketType.Status.Server.OUT_SERVER_INFO.isDeprecated(), "Packet isn't properly deprecated");
assertTrue(PacketRegistry.getServerPacketTypes().contains(PacketType.Status.Server.OUT_SERVER_INFO),
"Deprecated packet isn't properly included");
assertFalse(PacketType.Play.Server.CHAT.isDeprecated(), "Packet isn't properly deprecated");
assertEquals(PacketType.Status.Server.OUT_SERVER_INFO, PacketType.Status.Server.SERVER_INFO,
"Deprecated packets aren't equal");
}
@Test
@@ -284,7 +287,7 @@ public class PacketTypeTest {
Map<EnumProtocolDirection, Object> map = (Map<EnumProtocolDirection, Object>) field.get(protocol);
for (Entry<EnumProtocolDirection, Object> entry : map.entrySet()) {
Field mapField = entry.getValue().getClass().getDeclaredField("a");
Field mapField = entry.getValue().getClass().getDeclaredField("b");
mapField.setAccessible(true);
Map<Class<?>, Integer> reverseMap = (Map<Class<?>, Integer>) mapField.get(entry.getValue());
@@ -297,9 +300,11 @@ public class PacketTypeTest {
for (Entry<Integer, Class<?>> entry1 : treeMap.entrySet()) {
try {
PacketType type = PacketType.fromClass(entry1.getValue());
if (type.getCurrentId() != entry1.getKey())
if (type.getCurrentId() != entry1.getKey()) {
throw new IllegalStateException(
"Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got " + type.getCurrentId());
"Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got "
+ type.getCurrentId());
}
} catch (Throwable ex) {
ex.printStackTrace();
fail = true;
@@ -308,7 +313,7 @@ public class PacketTypeTest {
}
}
assertTrue("Packet type(s) were incorrect!", !fail);
assertFalse(fail, "Packet type(s) were incorrect!");
}
@Test
@@ -324,6 +329,6 @@ public class PacketTypeTest {
}
}
}
assertFalse("Packet type(s) failed to instantiate", fail);
assertFalse(fail, "Packet type(s) failed to instantiate");
}
}
@@ -2,30 +2,28 @@
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.concurrency;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class BlockingHashMapTest {
@@ -35,25 +33,21 @@ public class BlockingHashMapTest {
final BlockingHashMap<Integer, String> map = BlockingHashMap.create();
ExecutorService service = Executors.newSingleThreadExecutor();
// Create a reader
Future<String> future = service.submit(new Callable<String>() {
@Override
public String call() throws Exception {
// Combine for easy reading
return map.get(0) + map.get(1);
}
Future<String> future = service.submit(() -> {
// Combine for easy reading
return map.get(0) + map.get(1);
});
// Wait a bit
Thread.sleep(50);
// Insert values
map.put(0, "hello ");
map.put(1, "world");
// Wait for the other thread to complete
assertEquals(future.get(), "hello world");
}
}
@@ -1,26 +1,31 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2012 Kristian S.
* Stangeland
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.events;
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;
import static com.comphenix.protocol.utility.TestUtils.assertItemCollectionsEqual;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static com.comphenix.protocol.utility.TestUtils.equivalentItem;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
@@ -30,30 +35,48 @@ import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.Util;
import com.comphenix.protocol.wrappers.BlockPosition;
import com.comphenix.protocol.wrappers.*;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.ComponentConverter;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
import com.comphenix.protocol.wrappers.MovingObjectPositionBlock;
import com.comphenix.protocol.wrappers.Pair;
import com.comphenix.protocol.wrappers.WrappedBlockData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.WrappedEnumEntityUseAction;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.google.common.collect.Lists;
import net.md_5.bungee.api.chat.*;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.hover.content.Text;
import net.minecraft.core.IRegistry;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes.AttributeSnapshot;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectList;
import net.minecraft.world.entity.ai.attributes.AttributeBase;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.world.entity.npc.VillagerData;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.entity.npc.VillagerType;
import net.minecraft.world.level.dimension.DimensionManager;
import org.apache.commons.lang.SerializationUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.bukkit.ChatColor;
@@ -66,34 +89,26 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import static com.comphenix.protocol.utility.TestUtils.*;
import static org.junit.Assert.*;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
// Ensure that the CraftItemFactory is mockable
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*", "javax.management.*", "javax.xml.parsers.*", "com.sun.org.apache.xerces.internal.jaxp.*" })
//@PrepareForTest(CraftItemFactory.class)
public class PacketContainerTest {
// Helper converters
private EquivalentConverter<WrappedDataWatcher> watchConvert = BukkitConverters.getDataWatcherConverter();
private EquivalentConverter<ItemStack> itemConvert = BukkitConverters.getItemStackConverter();
private static BaseComponent[] TEST_COMPONENT;
// Helper converters
private final EquivalentConverter<WrappedDataWatcher> watchConvert = BukkitConverters.getDataWatcherConverter();
private final EquivalentConverter<ItemStack> itemConvert = BukkitConverters.getItemStackConverter();
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
TEST_COMPONENT =
new ComponentBuilder("Hit or miss?")
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://reddit.com"))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { new TextComponent("The \"front page\" of the internet") }))
.append("I guess they never miss, huh?").create();
TEST_COMPONENT = new ComponentBuilder("Hit or miss?")
.event(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://reddit.com"))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("The \"front page\" of the internet")))
.append("I guess they never miss, huh?")
.create();
}
private <T> void testPrimitive(StructureModifier<T> modifier, int index, T initialValue, T testValue) {
@@ -123,7 +138,7 @@ public class PacketContainerTest {
// Contains a byte array we will test
PacketContainer customPayload = new PacketContainer(PacketType.Login.Client.ENCRYPTION_BEGIN);
StructureModifier<byte[]> bytes = customPayload.getByteArrays();
byte[] testArray = new byte[] { 1, 2, 3 };
byte[] testArray = new byte[]{1, 2, 3};
// It's NULL at first
// assertEquals(null, bytes.read(0));
@@ -140,60 +155,60 @@ public class PacketContainerTest {
@Test
public void testGetBytes() {
PacketContainer spawnMob = new PacketContainer(PacketType.Play.Server.SPAWN_ENTITY_LIVING);
testPrimitive(spawnMob.getBytes(), 0, (byte)0, (byte)1);
this.testPrimitive(spawnMob.getBytes(), 0, (byte) 0, (byte) 1);
}
@Test
public void testGetShorts() {
PacketContainer itemData = new PacketContainer(PacketType.Play.Server.REL_ENTITY_MOVE);
testPrimitive(itemData.getShorts(), 0, (short)0, (short)1);
this.testPrimitive(itemData.getShorts(), 0, (short) 0, (short) 1);
}
@Test
public void testGetIntegers() {
PacketContainer updateSign = new PacketContainer(PacketType.Play.Client.CLOSE_WINDOW);
testPrimitive(updateSign.getIntegers(), 0, 0, 1);
this.testPrimitive(updateSign.getIntegers(), 0, 0, 1);
}
@Test
public void testGetLongs() {
PacketContainer updateTime = new PacketContainer(PacketType.Play.Server.UPDATE_TIME);
testPrimitive(updateTime.getLongs(), 0, (long)0, (long)1);
this.testPrimitive(updateTime.getLongs(), 0, (long) 0, (long) 1);
}
@Test
public void testGetFloat() {
PacketContainer explosion = new PacketContainer(PacketType.Play.Server.EXPLOSION);
testPrimitive(explosion.getFloat(), 0, (float)0, (float)0.8);
this.testPrimitive(explosion.getFloat(), 0, (float) 0, (float) 0.8);
}
@Test
public void testGetDoubles() {
PacketContainer explosion = new PacketContainer(PacketType.Play.Server.EXPLOSION);
testPrimitive(explosion.getDoubles(), 0, (double)0, 0.8);
this.testPrimitive(explosion.getDoubles(), 0, (double) 0, 0.8);
}
@Test
public void testGetStrings() {
PacketContainer explosion = new PacketContainer(PacketType.Play.Client.CHAT);
testPrimitive(explosion.getStrings(), 0, "", "hello");
this.testPrimitive(explosion.getStrings(), 0, "", "hello");
}
@Test
public void testGetStringArrays() {
PacketContainer packet = new PacketContainer(PacketType.Play.Client.UPDATE_SIGN);
testObjectArray(packet.getStringArrays(), 0,
new String[] { "", "", "", "" },
new String[] { "hello", "world" }
this.testObjectArray(packet.getStringArrays(), 0,
new String[]{"", "", "", ""},
new String[]{"hello", "world"}
);
}
@Test
public void testGetIntegerArrays() {
// Contains a byte array we will test
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MAP_CHUNK);
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MOUNT);
StructureModifier<int[]> integers = packet.getIntegerArrays();
int[] testArray = new int[] { 1, 2, 3 };
int[] testArray = new int[]{1, 2, 3};
assertArrayEquals(new int[0], integers.read(0));
@@ -205,14 +220,14 @@ public class PacketContainerTest {
public void testGetItemModifier() {
PacketContainer windowClick = new PacketContainer(PacketType.Play.Client.WINDOW_CLICK);
ItemStack item = itemWithData();
ItemStack item = this.itemWithData();
StructureModifier<ItemStack> items = windowClick.getItemModifier();
// assertNull(items.read(0));
// Insert the item and check if it's there
items.write(0, item);
assertTrue("Item " + item + " != " + items.read(0), equivalentItem(item, items.read(0)));
assertTrue(equivalentItem(item, items.read(0)), "Item " + item + " != " + items.read(0));
}
private ItemStack itemWithData() {
@@ -230,7 +245,7 @@ public class PacketContainerTest {
StructureModifier<List<ItemStack>> itemAccess = windowItems.getItemListModifier();
List<ItemStack> items = new ArrayList<>();
items.add(itemWithData());
items.add(this.itemWithData());
items.add(new ItemStack(Material.DIAMOND_AXE));
assertEquals(itemAccess.read(0).size(), 0);
@@ -246,8 +261,9 @@ public class PacketContainerTest {
@Test
public void testGetWorldTypeModifier() {
// Not used in Netty
if (MinecraftReflection.isUsingNetty())
if (MinecraftReflection.isUsingNetty()) {
return;
}
PacketContainer loginPacket = new PacketContainer(PacketType.Play.Server.LOGIN);
StructureModifier<WorldType> worldAccess = loginPacket.getWorldTypeModifier();
@@ -358,7 +374,8 @@ public class PacketContainerTest {
@Test
public void testGameProfiles() {
PacketContainer spawnEntity = new PacketContainer(PacketType.Login.Server.SUCCESS);
WrappedGameProfile profile = new WrappedGameProfile(UUID.fromString("d7047a08-3150-4aa8-a2f2-7c1e2b17e298"), "name");
WrappedGameProfile profile = new WrappedGameProfile(UUID.fromString("d7047a08-3150-4aa8-a2f2-7c1e2b17e298"),
"name");
spawnEntity.getGameProfiles().write(0, profile);
assertEquals(profile, spawnEntity.getGameProfiles().read(0));
@@ -371,7 +388,7 @@ public class PacketContainerTest {
WrappedChatComponent.fromChatMessage("You shall not " + ChatColor.ITALIC + "pass!")[0]);
assertEquals("{\"extra\":[{\"text\":\"You shall not \"},{\"italic\":true,\"text\":\"pass!\"}],\"text\":\"\"}",
chatPacket.getChatComponents().read(0).getJson());
chatPacket.getChatComponents().read(0).getJson());
}
@Test
@@ -389,8 +406,8 @@ public class PacketContainerTest {
public void testIntList() {
PacketContainer destroy = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY);
destroy.getIntLists().write(0, new ArrayList<Integer>() {{
add(420);
add(69);
this.add(420);
this.add(69);
}});
List<Integer> back = destroy.getIntLists().read(0);
assertEquals(back.size(), 2);
@@ -405,13 +422,14 @@ public class PacketContainerTest {
// Initialize some test data
List<AttributeModifier> modifiers = Lists.newArrayList(
new AttributeModifier(UUID.randomUUID(), "Unknown synced attribute modifier", 10, AttributeModifier.Operation.a));
new AttributeModifier(UUID.randomUUID(), "Unknown synced attribute modifier", 10,
AttributeModifier.Operation.a));
// Obtain an AttributeSnapshot instance. This is complicated by the fact that AttributeSnapshots
// are inner classes (which is ultimately pointless because AttributeSnapshots don't access any
// members of the packet itself)
PacketPlayOutUpdateAttributes packet = (PacketPlayOutUpdateAttributes) attribute.getHandle();
AttributeBase base = IRegistry.al.get(MinecraftKey.a("generic.max_health"));
AttributeBase base = IRegistry.aj.a(MinecraftKey.a("generic.max_health"));
AttributeSnapshot snapshot = new AttributeSnapshot(base, 20.0D, modifiers);
attribute.getSpecificModifier(List.class).write(0, Lists.newArrayList(snapshot));
@@ -428,7 +446,7 @@ public class PacketContainerTest {
}
field.setAccessible(true);
testEquality(field.get(snapshot), field.get(clonedSnapshot));
this.testEquality(field.get(snapshot), field.get(clonedSnapshot));
} catch (AssertionError e) {
throw e;
} catch (Throwable ex) {
@@ -461,26 +479,33 @@ public class PacketContainerTest {
@SuppressWarnings("deprecation")
public void testPotionEffect() {
PotionEffect effect = new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 20 * 60, 1);
MobEffect mobEffect = new MobEffect(MobEffectList.fromId(effect.getType().getId()), effect.getDuration(), effect.getAmplifier(), effect.isAmbient(),
MobEffect mobEffect = new MobEffect(MobEffectList.a(effect.getType().getId()), effect.getDuration(),
effect.getAmplifier(), effect.isAmbient(),
effect.hasParticles());
int entityId = 42;
// The constructor we want to call
PacketConstructor creator = PacketConstructor.DEFAULT.withPacket(
PacketType.Play.Server.ENTITY_EFFECT, new Class<?>[] { int.class, MobEffect.class });
PacketType.Play.Server.ENTITY_EFFECT, new Class<?>[]{int.class, MobEffect.class});
PacketContainer packet = creator.createPacket(entityId, mobEffect);
assertEquals(entityId, (int) packet.getIntegers().read(0));
assertEquals(effect.getType().getId(), (byte) packet.getBytes().read(0));
assertEquals(effect.getAmplifier(), (byte) packet.getBytes().read(1));
assertEquals(effect.getDuration(), (int) packet.getIntegers().read(1));
assertEquals(entityId, packet.getIntegers().read(0));
assertEquals(effect.getType().getId(), packet.getIntegers().read(1));
assertEquals(effect.getAmplifier(), (byte) packet.getBytes().read(0));
assertEquals(effect.getDuration(), packet.getIntegers().read(2));
int e = 0;
if (effect.isAmbient()) e |= 1;
if (effect.hasParticles()) e |= 2;
if (effect.hasIcon()) e |= 4;
if (effect.isAmbient()) {
e |= 1;
}
if (effect.hasParticles()) {
e |= 2;
}
if (effect.hasIcon()) {
e |= 4;
}
assertEquals(e, (byte) packet.getBytes().read(2));
assertEquals(e, (byte) packet.getBytes().read(1));
}
@Test
@@ -540,7 +565,7 @@ public class PacketContainerTest {
optStruct = container.getOptionalStructures().read(0);
assertTrue(optStruct.isPresent());
struct = optStruct.get();
testEquality(
this.testEquality(
struct.getChatComponents().read(0),
WrappedChatComponent.fromText("hi there")
);
@@ -591,14 +616,14 @@ public class PacketContainerTest {
public void testMultiBlockChange() {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.MULTI_BLOCK_CHANGE);
packet.getShortArrays().writeSafely(0, new short[] { 420, 69 });
assertArrayEquals(new short[] { 420, 69}, packet.getShortArrays().readSafely(0));
packet.getShortArrays().writeSafely(0, new short[]{420, 69});
assertArrayEquals(new short[]{420, 69}, packet.getShortArrays().readSafely(0));
packet.getBlockDataArrays().writeSafely(0, new WrappedBlockData[] {
packet.getBlockDataArrays().writeSafely(0, new WrappedBlockData[]{
WrappedBlockData.createData(Material.IRON_BARS),
WrappedBlockData.createData(Material.IRON_BLOCK)
});
assertArrayEquals(new WrappedBlockData[] {
assertArrayEquals(new WrappedBlockData[]{
WrappedBlockData.createData(Material.IRON_BARS),
WrappedBlockData.createData(Material.IRON_BLOCK)
}, packet.getBlockDataArrays().readSafely(0));
@@ -613,9 +638,10 @@ public class PacketContainerTest {
@Test
public void testGameStateChange() {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
assertTrue(packet.getGameStateIDs().read(0) == 0);
assertEquals(0, (int) packet.getGameStateIDs().read(0));
packet.getGameStateIDs().write(0, 2);
assertTrue(packet.getGameStateIDs().read(0) == 2);
assertEquals(2, (int) packet.getGameStateIDs().read(0));
}
@Test
@@ -663,31 +689,26 @@ public class PacketContainerTest {
assertEquals(position, clone.getPosition());
}
@Test
public void testSetSimulationDistance() {
// first packet which is a record - set will fail if we missed something during patching
PacketContainer container = new PacketContainer(PacketType.Play.Server.UPDATE_SIMULATION_DISTANCE);
container.getIntegers().write(0, 1234);
assertEquals(1234, (int) container.getIntegers().read(0));
}
@Test
public void testMapChunk() {
// this is a special case as we are generating a data serializer class (we only need to construct the packet)
PacketContainer container = new PacketContainer(PacketType.Play.Server.MAP_CHUNK);
// check if we can read an nbt compound from the class
assertTrue(container.getNbtModifier().optionRead(0).isPresent());
}
/**
* Actions from the outbound Boss packet. Used for testing generic enums.
* @author dmulloy2
*/
public enum Action {
ADD,
REMOVE,
UPDATE_PCT,
UPDATE_NAME,
UPDATE_STYLE,
UPDATE_PROPERTIES
assertTrue(container.getStructures().read(0).getNbtModifier().optionRead(0).isPresent());
}
@Test
public void testComponentArrays() {
PacketContainer signChange = new PacketContainer(PacketType.Play.Server.TILE_ENTITY_DATA);
WrappedChatComponent[] components = new WrappedChatComponent[] {
WrappedChatComponent[] components = new WrappedChatComponent[]{
WrappedChatComponent.fromText("hello world"), WrappedChatComponent.fromText(""),
WrappedChatComponent.fromText(""), WrappedChatComponent.fromText("")
};
@@ -706,10 +727,11 @@ public class PacketContainerTest {
} else {
// Make sure all the fields are equivalent
for (int i = 0; i < firstMod.size(); i++) {
if (firstMod.getField(i).getType().isArray())
assertArrayEquals(getArray(firstMod.read(i)), getArray(secondMod.read(i)));
else
testEquality(firstMod.read(i), secondMod.read(i));
if (firstMod.getField(i).getType().isArray()) {
assertArrayEquals(this.getArray(firstMod.read(i)), this.getArray(secondMod.read(i)));
} else {
this.testEquality(firstMod.read(i), secondMod.read(i));
}
}
}
}
@@ -720,8 +742,9 @@ public class PacketContainerTest {
// Try constructing all the packets
for (PacketType type : PacketType.values()) {
if (type.isDeprecated() || type.name().contains("CUSTOM_PAYLOAD") || type.name().contains("TAGS") || !type.isSupported()
|| type == PacketType.Play.Server.RECIPES) {
if (type.isDeprecated() || type.name().contains("CUSTOM_PAYLOAD") || type.name().contains("TAGS")
|| !type.isSupported()
|| type == PacketType.Play.Server.RECIPES) {
continue;
}
@@ -740,9 +763,9 @@ public class PacketContainerTest {
"String"),
new WrappedWatchableObject(new WrappedDataWatcherObject(0, Registry.get(Float.class)), 1.0F),
new WrappedWatchableObject(new WrappedDataWatcherObject(0, Registry.getChatComponentSerializer(true)),
Optional.of(ComponentConverter.fromBaseComponent(TEST_COMPONENT).getHandle())),
Optional.of(ComponentConverter.fromBaseComponent(TEST_COMPONENT).getHandle())),
new WrappedWatchableObject(new WrappedDataWatcherObject(0, Registry.get(VillagerData.class)),
new VillagerData(VillagerType.b, VillagerProfession.c, 69))
new VillagerData(VillagerType.b, VillagerProfession.c, 69))
));
} else if (type == PacketType.Play.Server.CHAT) {
constructed.getChatComponents().write(0, ComponentConverter.fromBaseComponent(TEST_COMPONENT));
@@ -751,17 +774,17 @@ public class PacketContainerTest {
// Clone the packet both ways
PacketContainer shallowCloned = constructed.shallowClone();
assertPacketsEqual(constructed, shallowCloned);
this.assertPacketsEqual(constructed, shallowCloned);
PacketContainer deepCloned = constructed.deepClone();
assertPacketsEqual(constructed, deepCloned);
this.assertPacketsEqual(constructed, deepCloned);
} catch (Exception ex) {
ex.printStackTrace();
failed = true;
}
}
assertFalse("Packet(s) failed to clone", failed);
assertFalse(failed, "Packet(s) failed to clone");
}
// Convert to objects that support equals()
@@ -778,26 +801,26 @@ public class PacketContainerTest {
if (a instanceof Optional) {
if (b instanceof Optional) {
testEquality(((Optional<?>) a).orElse(null), ((Optional<?>) b).orElse(null));
this.testEquality(((Optional<?>) a).orElse(null), ((Optional<?>) b).orElse(null));
return;
} else {
throw new AssertionError("a was optional, but b was not");
}
}
if (a.equals(b) || Objects.equals(a, b) || stringEquality(a, b)) {
if (a.equals(b) || Objects.equals(a, b) || this.stringEquality(a, b)) {
return;
}
if (MinecraftReflection.isDataWatcher(a)) {
a = watchConvert.getSpecific(a);
b = watchConvert.getSpecific(b);
a = this.watchConvert.getSpecific(a);
b = this.watchConvert.getSpecific(b);
} else if (MinecraftReflection.isItemStack(a)) {
a = itemConvert.getSpecific(a);
b = itemConvert.getSpecific(b);
a = this.itemConvert.getSpecific(a);
b = this.itemConvert.getSpecific(b);
}
if (a instanceof ItemStack || b instanceof ItemStack) {
if (a instanceof ItemStack && b instanceof ItemStack) {
assertItemsEqual((ItemStack) a, (ItemStack) b);
return;
}
@@ -820,20 +843,38 @@ public class PacketContainerTest {
/**
* Get the underlying array as an object array.
*
* @param val - array wrapped as an Object.
* @return An object array.
*/
private Object[] getArray(Object val) {
if (val instanceof Object[])
if (val instanceof Object[]) {
return (Object[]) val;
if (val == null)
}
if (val == null) {
return null;
}
int arrlength = Array.getLength(val);
Object[] outputArray = new Object[arrlength];
for (int i = 0; i < arrlength; ++i)
for (int i = 0; i < arrlength; ++i) {
outputArray[i] = Array.get(val, i);
}
return outputArray;
}
/**
* Actions from the outbound Boss packet. Used for testing generic enums.
*
* @author dmulloy2
*/
public enum Action {
ADD,
REMOVE,
UPDATE_PCT,
UPDATE_NAME,
UPDATE_STYLE,
UPDATE_PROPERTIES
}
}
@@ -1,72 +1,70 @@
package com.comphenix.protocol.events;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.UUID;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;
public class SerializedOfflinePlayerTest {
@Mock
static OfflinePlayer offlinePlayer;
private static final String name = "playerName";
private static final long firstPlayed = 1000L;
private static final long lastPlayed = firstPlayed + 100L;
private static final boolean isOp = false;
private static final boolean playedBefore = true;
private static final boolean whitelisted = true;
@Mock
static OfflinePlayer offlinePlayer;
private static UUID uuid;
private static SerializedOfflinePlayer serializedOfflinePlayer;
private static final String name = "playerName";
private static UUID uuid;
private static final long firstPlayed = 1000L;
private static final long lastPlayed = firstPlayed + 100L;
private static final boolean isOp = false;
private static final boolean playedBefore = true;
private static final boolean whitelisted = true;
@BeforeEach
public void initMocks() {
MockitoAnnotations.openMocks(this);
private static SerializedOfflinePlayer serializedOfflinePlayer;
uuid = UUID.randomUUID();
when(offlinePlayer.getName()).thenReturn(name);
when(offlinePlayer.getUniqueId()).thenReturn(uuid);
when(offlinePlayer.getFirstPlayed()).thenReturn(firstPlayed);
when(offlinePlayer.getLastPlayed()).thenReturn(lastPlayed);
when(offlinePlayer.isOp()).thenReturn(isOp);
when(offlinePlayer.hasPlayedBefore()).thenReturn(playedBefore);
when(offlinePlayer.isWhitelisted()).thenReturn(whitelisted);
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
serializedOfflinePlayer = new SerializedOfflinePlayer(offlinePlayer);
}
uuid = UUID.randomUUID();
when(offlinePlayer.getName()).thenReturn(name);
when(offlinePlayer.getUniqueId()).thenReturn(uuid);
when(offlinePlayer.getFirstPlayed()).thenReturn(firstPlayed);
when(offlinePlayer.getLastPlayed()).thenReturn(lastPlayed);
when(offlinePlayer.isOp()).thenReturn(isOp);
when(offlinePlayer.hasPlayedBefore()).thenReturn(playedBefore);
when(offlinePlayer.isWhitelisted()).thenReturn(whitelisted);
@Test
public void getProxyPlayer() {
Player player = serializedOfflinePlayer.getProxyPlayer();
assertNotNull(player);
serializedOfflinePlayer = new SerializedOfflinePlayer(offlinePlayer);
}
// getDisplayName only works for online players.
assertThrows(UnsupportedOperationException.class, player::getDisplayName);
@Test
public void getProxyPlayer() {
Player player = serializedOfflinePlayer.getProxyPlayer();
Assert.assertNotNull(player);
assertEquals(uuid, player.getUniqueId());
assertEquals(name, player.getName());
assertEquals(firstPlayed, player.getFirstPlayed());
assertEquals(lastPlayed, player.getLastPlayed());
assertEquals(isOp, player.isOp());
assertEquals(playedBefore, player.hasPlayedBefore());
assertEquals(whitelisted, player.isWhitelisted());
}
// getDisplayName only works for online players.
assertThrows(UnsupportedOperationException.class, player::getDisplayName);
@Test
public void getSecondProxyPlayer() {
// Make sure that the proxyPlayer generation doesn't work only once.
Player player = serializedOfflinePlayer.getProxyPlayer();
assertNotNull(player);
assertEquals(uuid, player.getUniqueId());
assertEquals(name, player.getName());
assertEquals(firstPlayed, player.getFirstPlayed());
assertEquals(lastPlayed, player.getLastPlayed());
assertEquals(isOp, player.isOp());
assertEquals(playedBefore, player.hasPlayedBefore());
assertEquals(whitelisted, player.isWhitelisted());
}
@Test
public void getSecondProxyPlayer() {
// Make sure that the proxyPlayer generation doesn't work only once.
Player player = serializedOfflinePlayer.getProxyPlayer();
Assert.assertNotNull(player);
assertEquals(uuid, player.getUniqueId());
}
assertEquals(uuid, player.getUniqueId());
}
}
@@ -1,51 +1,41 @@
package com.comphenix.protocol.injector;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.reflect.accessors.Accessors;
import static com.comphenix.protocol.utility.TestUtils.setFinalField;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.lang.reflect.Field;
import net.minecraft.server.level.ChunkProviderServer;
import net.minecraft.server.level.EntityTrackerEntry;
import net.minecraft.server.level.PlayerChunkMap;
import net.minecraft.server.level.PlayerChunkMap.EntityTracker;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.Entity;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.bukkit.craftbukkit.v1_17_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.reflect.Field;
import static com.comphenix.protocol.utility.TestUtils.setFinalField;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class EntityUtilitiesTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
public void testReflection() throws ReflectiveOperationException {
public void testReflection() {
CraftWorld bukkit = mock(CraftWorld.class);
WorldServer world = mock(WorldServer.class);
when(bukkit.getHandle()).thenReturn(world);
ChunkProviderServer provider = mock(ChunkProviderServer.class);
when(world.getChunkProvider()).thenReturn(provider);
when(world.k()).thenReturn(provider);
PlayerChunkMap chunkMap = mock(PlayerChunkMap.class);
Field chunkMapField = FuzzyReflection.fromClass(ChunkProviderServer.class, true)
@@ -1,53 +1,46 @@
package com.comphenix.protocol.injector;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.comphenix.protocol.injector.PluginVerifier.VerificationResult;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginLoadOrder;
import org.bukkit.plugin.PluginManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import com.comphenix.protocol.injector.PluginVerifier.VerificationResult;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
// Damn final classes
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
@PrepareForTest(PluginDescriptionFile.class)
public class PluginVerifierTest {
@Test
public void testDependecies() {
List<Plugin> plugins = Lists.newArrayList();
Server server = mockServer(plugins);
Plugin library = mockPlugin(server, "ProtocolLib", PluginLoadOrder.POSTWORLD);
Plugin skillPlugin = mockPlugin(server, "SkillPlugin", "RaidCraft-API", "RCPermissions", "RCConversations");
Plugin raidCraftAPI = mockPlugin(server, "RaidCraft-API", "WorldGuard", "WorldEdit");
Plugin conversations = mockPlugin(server, "RCConversations", "RaidCraft-API");
Plugin permissions = mockPlugin(server, "RCPermissions", "RaidCraft-API");
Server server = this.mockServer(plugins);
Plugin library = this.mockPlugin(server, "ProtocolLib", PluginLoadOrder.POSTWORLD);
Plugin skillPlugin = this.mockPlugin(server, "SkillPlugin", "RaidCraft-API", "RCPermissions", "RCConversations");
Plugin raidCraftAPI = this.mockPlugin(server, "RaidCraft-API", "WorldGuard", "WorldEdit");
Plugin conversations = this.mockPlugin(server, "RCConversations", "RaidCraft-API");
Plugin permissions = this.mockPlugin(server, "RCPermissions", "RaidCraft-API");
// Add the plugins
plugins.addAll(Arrays.asList(library, skillPlugin, raidCraftAPI, conversations, permissions));
PluginVerifier verifier = new PluginVerifier(library);
// Verify the root - it should have no dependencies on ProtocolLib
assertEquals(VerificationResult.NO_DEPEND, verifier.verify(skillPlugin));
}
private Server mockServer(final List<Plugin> plugins) {
Server mockServer = mock(Server.class);
PluginManager manager = mock(PluginManager.class);
@@ -57,7 +50,7 @@ public class PluginVerifierTest {
@Override
public Plugin answer(InvocationOnMock invocation) throws Throwable {
String name = (String) invocation.getArguments()[0];
for (Plugin plugin : plugins) {
if (Objects.equal(name, plugin.getName())) {
return plugin;
@@ -68,20 +61,20 @@ public class PluginVerifierTest {
});
return mockServer;
}
private Plugin mockPlugin(Server server, String name,String... depend) {
return mockPlugin(server, name, PluginLoadOrder.POSTWORLD, depend);
private Plugin mockPlugin(Server server, String name, String... depend) {
return this.mockPlugin(server, name, PluginLoadOrder.POSTWORLD, depend);
}
private Plugin mockPlugin(Server server, String name, PluginLoadOrder order, String... depend) {
Plugin plugin = mock(Plugin.class);
PluginDescriptionFile file = mock(PluginDescriptionFile.class);
when(plugin.getServer()).thenReturn(server);
when(plugin.getName()).thenReturn(name);
when(plugin.toString()).thenReturn(name);
when(plugin.getDescription()).thenReturn(file);
// This is the difficult part
when(file.getLoad()).thenReturn(order);
when(file.getDepend()).thenReturn(Arrays.asList(depend));
@@ -2,85 +2,84 @@
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.injector;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import com.comphenix.protocol.concurrency.SortedCopyOnWriteArray;
import com.comphenix.protocol.events.ListenerPriority;
import com.google.common.primitives.Ints;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
public class SortedCopyOnWriteArrayTest {
@Test
public void testInsertion() {
final int MAX_NUMBER = 50;
SortedCopyOnWriteArray<Integer> test = new SortedCopyOnWriteArray<Integer>();
// Generate some numbers
List<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < MAX_NUMBER; i++) {
numbers.add(i);
}
// Random insertion to test it all
Collections.shuffle(numbers);
// O(n^2) of course, so don't use too large numbers
for (int i = 0; i < MAX_NUMBER; i++) {
test.add(numbers.get(i));
}
// Check that everything is correct
for (int i = 0; i < MAX_NUMBER; i++) {
assertEquals((Integer) i, test.get(i));
}
}
@Test
public void testOrder() {
PriorityStuff a = new PriorityStuff(ListenerPriority.HIGH, 1);
PriorityStuff b = new PriorityStuff(ListenerPriority.NORMAL, 2);
PriorityStuff c = new PriorityStuff(ListenerPriority.NORMAL, 3);
SortedCopyOnWriteArray<PriorityStuff> test = new SortedCopyOnWriteArray<PriorityStuff>();
test.add(a);
test.add(b);
test.add(c);
// Make sure the normal's are in the right order
assertEquals(2, test.get(0).id);
assertEquals(3, test.get(1).id);
// Test remove
test.remove(b);
assertEquals(2, test.size());
assertFalse(test.contains(b));
}
private static class PriorityStuff implements Comparable<PriorityStuff> {
public ListenerPriority priority;
public int id;
@@ -92,8 +91,8 @@ public class SortedCopyOnWriteArrayTest {
@Override
public int compareTo(PriorityStuff other) {
// This ensures that lower priority listeners are executed first
return Ints.compare(priority.getSlot(),
other.priority.getSlot());
return Ints.compare(this.priority.getSlot(),
other.priority.getSlot());
}
}
}
@@ -3,32 +3,27 @@
*/
package com.comphenix.protocol.injector;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.injector.netty.WirePacket;
import com.comphenix.protocol.wrappers.EnumWrappers.ChatType;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class WirePacketTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
// @Test
@@ -36,8 +31,9 @@ public class WirePacketTest {
List<String> failures = new ArrayList<>();
for (PacketType type : PacketType.values()) {
if (type.isDeprecated())
if (type.isDeprecated()) {
continue;
}
try {
PacketContainer packet = new PacketContainer(type);
@@ -57,7 +53,7 @@ public class WirePacketTest {
@Test
public void testSerialization() {
int id = 42;
byte[] array = { 1, 3, 7, 21, 88, 67, 8 };
byte[] array = {1, 3, 7, 21, 88, 67, 8};
WirePacket packet = new WirePacket(id, array);
@@ -1,42 +1,42 @@
package com.comphenix.protocol.injector.server;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.junit.Assert.*;
public class TemporaryPlayerFactoryTest {
private static final TemporaryPlayerFactory temporaryPlayerFactory = new TemporaryPlayerFactory();
private static final TemporaryPlayerFactory temporaryPlayerFactory = new TemporaryPlayerFactory();
@Mock
Server server;
@Mock
SocketInjector socketInjector;
@Mock
Server server;
@Mock
SocketInjector socketInjector;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@BeforeEach
public void initMocks() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testUnavailableSocketInjector()
{
Player player = temporaryPlayerFactory.createTemporaryPlayer(server);
assertThrows(IllegalStateException.class, player::getPlayer);
}
@Test
public void testUnavailableSocketInjector() {
Player player = temporaryPlayerFactory.createTemporaryPlayer(this.server);
assertThrows(IllegalStateException.class, player::getPlayer);
}
@Test
public void createTemporaryPlayer() {
@Test
public void createTemporaryPlayer() {
Player player = temporaryPlayerFactory.createTemporaryPlayer(server, socketInjector);
assertEquals(server, player.getServer());
Player player = temporaryPlayerFactory.createTemporaryPlayer(this.server, this.socketInjector);
assertEquals(this.server, player.getServer());
// May seem dumb, but this makes sure that the .equals method is still instact.
assertEquals(player, player);
}
// May seem dumb, but this makes sure that the .equals method is still instact.
assertEquals(player, player);
}
}
@@ -1,52 +1,21 @@
package com.comphenix.protocol.reflect.accessors;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class AccessorsTest {
// --- Some classes we can use for testing ---
private static class Entity {
private int id;
public Entity(int id) {
this.id = id;
}
public int getId() {
return id;
}
@SuppressWarnings("unused")
private void setId(int value) {
this.id = value;
}
}
private static class Player extends Entity {
private String name;
public Player(int id, String name) {
super(id);
this.name = name;
}
public String getName() {
return name;
}
}
// --- Test classes ---
@Test
public void testField() {
Player player = new Player(123, "ABC");
Accessors.getFieldAccessor(player.getClass(), "id", true).set(player, 0);
Accessors.getFieldAccessor(player.getClass(), "name", true).set(player, "MODIFIED");
assertEquals(0, player.getId());
assertEquals("MODIFIED", player.getName());
}
@Test
public void testMethod() {
Player player = new Player(123, "ABC");
@@ -54,4 +23,37 @@ public class AccessorsTest {
Accessors.getMethodAccessor(player.getClass(), "setId", int.class).invoke(player, 0);
assertEquals(0, player.getId());
}
// --- Some classes we can use for testing ---
private static class Entity {
private int id;
public Entity(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
@SuppressWarnings("unused")
private void setId(int value) {
this.id = value;
}
}
private static class Player extends Entity {
private final String name;
public Player(int id, String name) {
super(id);
this.name = name;
}
public String getName() {
return this.name;
}
}
}
@@ -1,31 +1,27 @@
package com.comphenix.protocol.reflect.cloning;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import java.util.Arrays;
import java.util.List;
import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class AggregateClonerTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
public void testArrays() {
public void testArrays() {
List<Integer> input = Arrays.asList(1, 2, 3);
assertEquals(input, AggregateCloner.DEFAULT.clone(input));
}
@@ -44,6 +40,6 @@ public class AggregateClonerTest {
NonNullList<ItemStack> list1 = (NonNullList<ItemStack>) cloned.getModifier().read(1);
assertEquals(list.size(), list1.size());
assertArrayEquals(list.toArray(), list1.toArray());
Assertions.assertArrayEquals(list.toArray(), list1.toArray());
}
}
@@ -3,46 +3,47 @@
*/
package com.comphenix.protocol.updater;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.comphenix.protocol.updater.Updater.UpdateType;
import java.util.logging.Logger;
import org.bukkit.Server;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.junit.BeforeClass;
import org.junit.Test;
import com.comphenix.protocol.updater.Updater.UpdateType;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class UpdaterTest {
private static final int BUKKIT_DEV_ID = 45564;
private static Plugin plugin;
// @BeforeClass
@BeforeAll
public static void preparePlugin() {
Server server = mock(Server.class);
when(server.getUpdateFolder()).thenReturn(null);
plugin = mock(Plugin.class);
String version = System.getProperty("projectVersion");
if (version == null) version = "4.4.0";
if (version == null) {
version = "4.4.0";
}
when(plugin.getDescription()).thenReturn(new PluginDescriptionFile("ProtocolLib", version, null));
when(plugin.getLogger()).thenReturn(Logger.getLogger("ProtocolLib"));
when(plugin.getDataFolder()).thenReturn(null);
when(plugin.getServer()).thenReturn(server);
}
// @Test
@Test
public void testUpdaterType() {
assertEquals(Updater.create(plugin, BUKKIT_DEV_ID, null, UpdateType.NO_DOWNLOAD, true).getClass(), SpigotUpdater.class);
assertEquals(Updater.create(plugin, BUKKIT_DEV_ID, null, UpdateType.NO_DOWNLOAD, true).getClass(),
SpigotUpdater.class);
}
// @Test
@@ -54,23 +55,10 @@ public class UpdaterTest {
try {
remote = updater.getSpigotVersion();
} catch (Throwable ex) {
ex.printStackTrace();
fail("Failed to check for updates");
fail("Failed to check for updates", ex);
}
System.out.println("Determined remote Spigot version: " + remote);
System.out.println("Update available: " + updater.versionCheck(remote));
}
// @Test
public void testBukkitUpdater() {
BukkitUpdater updater = new BukkitUpdater(plugin, BUKKIT_DEV_ID, null, UpdateType.NO_DOWNLOAD, true);
if (! updater.read()) {
fail("Failed to check for updates");
}
String remote = updater.getLatestName();
System.out.println("Determined remote Bukkit Dev version: " + remote);
System.out.println("Update available: " + updater.versionCheck(remote));
}
}
@@ -1,19 +1,17 @@
package com.comphenix.protocol.utility;
import static org.junit.Assert.assertNotNull;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.comphenix.protocol.BukkitInitialization;
import java.lang.reflect.Field;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class MinecraftMethodsTest {
@BeforeClass
@BeforeAll
public static void initializeReflection() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
@@ -30,8 +28,8 @@ public class MinecraftMethodsTest {
@Test
public void initializePacket() throws NoSuchFieldException, IllegalAccessException {
setNull("packetReadByteBuf");
setNull("packetWriteByteBuf");
this.setNull("packetReadByteBuf");
this.setNull("packetWriteByteBuf");
assertNotNull(MinecraftMethods.getPacketWriteByteBufMethod());
// TODO it's now a constructor
@@ -1,25 +1,16 @@
package com.comphenix.protocol.utility;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import com.comphenix.protocol.BukkitInitialization;
import com.mojang.authlib.GameProfile;
import net.minecraft.nbt.NBTCompressedStreamTools;
import net.minecraft.network.chat.ChatComponentText;
import net.minecraft.network.chat.IChatBaseComponent;
@@ -29,26 +20,23 @@ import net.minecraft.network.syncher.DataWatcher;
import net.minecraft.server.network.PlayerConnection;
import net.minecraft.world.level.ChunkCoordIntPair;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
public class MinecraftReflectionTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
// Mocking objects
private interface FakeEntity {
Entity getBukkitEntity();
}
private interface FakeBlock {
Block getBukkitEntity();
}
@AfterClass
@AfterAll
public static void undoMocking() {
// NOP
MinecraftReflection.minecraftPackage = null;
@@ -66,9 +54,9 @@ public class MinecraftReflectionTest {
verify(block, times(1)).getBukkitEntity();
}
@Test(expected = IllegalArgumentException.class)
@Test
public void testIllegalClass() {
MinecraftReflection.getBukkitEntity("Hello");
assertThrows(IllegalArgumentException.class, () -> MinecraftReflection.getBukkitEntity("Hello"));
}
@Test
@@ -78,7 +66,8 @@ public class MinecraftReflectionTest {
@Test
public void testAttributeSnapshot() {
assertEquals(PacketPlayOutUpdateAttributes.AttributeSnapshot.class, MinecraftReflection.getAttributeSnapshotClass());
assertEquals(PacketPlayOutUpdateAttributes.AttributeSnapshot.class,
MinecraftReflection.getAttributeSnapshotClass());
}
@Test
@@ -156,4 +145,15 @@ public class MinecraftReflectionTest {
// this class is package-private in PacketPlayInUseEntity, so we can only check if no exception is thrown during retrieval
MinecraftReflection.getEnumEntityUseActionClass();
}
// Mocking objects
private interface FakeEntity {
Entity getBukkitEntity();
}
private interface FakeBlock {
Block getBukkitEntity();
}
}
@@ -1,37 +1,38 @@
package com.comphenix.protocol.utility;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.junit.Test;
import org.junit.jupiter.api.Test;
public class SnapshotVersionTest {
@Test
public void testDates() {
SnapshotVersion a = new SnapshotVersion("12w50b");
SnapshotVersion b = new SnapshotVersion("13w05a");
expect(a.getSnapshotDate(), 12, 50);
expect(b.getSnapshotDate(), 13, 5);
this.expect(a.getSnapshotDate(), 12, 50);
this.expect(b.getSnapshotDate(), 13, 5);
// Test equality
assertEquals(a, new SnapshotVersion("12w50b"));
}
@Test(expected=IllegalArgumentException.class)
@Test
public void testDateParsingProblem() {
// This date is not valid
new SnapshotVersion("12w80a");
assertThrows(IllegalArgumentException.class, () -> new SnapshotVersion("12w80a"));
}
@Test(expected=IllegalArgumentException.class)
@Test
public void testMissingWeekVersion() {
new SnapshotVersion("13w05");
assertThrows(IllegalArgumentException.class, () -> new SnapshotVersion("13w05"));
}
private void expect(Date date, int year, int week) {
Calendar calendar = Calendar.getInstance(Locale.US);
calendar.setTime(date);
@@ -1,38 +1,30 @@
package com.comphenix.protocol.utility;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.io.*;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.Assert.assertEquals;
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
//@PrepareForTest(CraftItemFactory.class)
public class StreamSerializerTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
/*@Test
public void testMinecraftReflection() {
assertEquals(IntHashMap.class, MinecraftReflection.getIntHashMapClass());
}*/
@Test
public void testStrings() throws IOException {
StreamSerializer serializer = new StreamSerializer();
@@ -1,15 +1,16 @@
package com.comphenix.protocol.utility;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.reflect.accessors.Accessors;
import java.lang.reflect.Field;
import java.util.List;
import sun.misc.Unsafe;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
public class TestUtils {
public static void assertItemCollectionsEqual(List<ItemStack> first, List<ItemStack> second) {
@@ -45,12 +46,7 @@ public class TestUtils {
}
}
public static void setFinalField(Object obj, Field field, Object newValue) throws ReflectiveOperationException {
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) unsafeField.get(null);
long offset = unsafe.objectFieldOffset(field);
unsafe.putObject(obj, offset, newValue);
public static void setFinalField(Object obj, Field field, Object newValue) {
Accessors.getFieldAccessor(field, true).set(obj, newValue);
}
}
@@ -0,0 +1,112 @@
package com.comphenix.protocol.wrappers;
import static com.comphenix.protocol.utility.MinecraftReflection.getMinecraftClass;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertSame;
import com.comphenix.protocol.BukkitInitialization;
import net.minecraft.advancements.AdvancementDisplay;
import net.minecraft.advancements.AdvancementFrameType;
import net.minecraft.network.chat.ChatComponentText;
import net.minecraft.world.item.Items;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class AutoWrapperTest {
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeAll();
}
@Test
public void testToNms() {
WrappedAdvancementDisplay display = new WrappedAdvancementDisplay();
display.title = WrappedChatComponent.fromText("Test123");
display.description = WrappedChatComponent.fromText("Test567");
display.item = new ItemStack(Material.SAND);
display.background = new MinecraftKey("test");
display.frameType = WrappedFrameType.CHALLENGE;
display.announceChat = false;
display.showToast = true;
display.hidden = true;
display.x = 5f;
display.y = 67f;
AdvancementDisplay nms = (AdvancementDisplay) displayWrapper().unwrap(display);
assertTrue(nms.h());
assertTrue(nms.j());
assertFalse(nms.i());
assertEquals("test", nms.d().a());
assertEquals("Test123", nms.a().a());
assertEquals("Test567", nms.b().a());
assertSame(AdvancementFrameType.b, nms.e());
assertSame(Items.L, nms.c().c());
assertEquals(5f, nms.f(), 0f);
assertEquals(67f, nms.g(), 0f);
}
@Test
public void testFromNms() {
AdvancementDisplay display = new AdvancementDisplay(
new net.minecraft.world.item.ItemStack(Items.L),
new ChatComponentText("Test123"),
new ChatComponentText("Test567"),
new net.minecraft.resources.MinecraftKey("minecraft", "test"),
AdvancementFrameType.b,
true,
false,
true
);
display.a(5f, 67f);
WrappedAdvancementDisplay wrapped = displayWrapper().wrap(display);
assertTrue(wrapped.showToast);
assertTrue(wrapped.hidden);
assertFalse(wrapped.announceChat);
assertEquals("test", wrapped.background.getKey());
assertEquals("{\"text\":\"Test123\"}", wrapped.title.getJson());
assertEquals("{\"text\":\"Test567\"}", wrapped.description.getJson());
assertSame(WrappedFrameType.CHALLENGE, wrapped.frameType);
assertSame(Material.SAND, wrapped.item.getType());
assertEquals(5f, wrapped.x, 0f);
assertEquals(67f, wrapped.y, 0f);
}
private AutoWrapper<WrappedAdvancementDisplay> displayWrapper() {
return AutoWrapper
.wrap(WrappedAdvancementDisplay.class, "advancements.AdvancementDisplay")
.field(0, BukkitConverters.getWrappedChatComponentConverter())
.field(1, BukkitConverters.getWrappedChatComponentConverter())
.field(2, BukkitConverters.getItemStackConverter())
.field(3, MinecraftKey.getConverter())
.field(4, EnumWrappers.getGenericConverter(getMinecraftClass("advancements.AdvancementFrameType"),
WrappedFrameType.class));
}
public enum WrappedFrameType {
TASK,
CHALLENGE,
GOAL
}
public static final class WrappedAdvancementDisplay {
public WrappedChatComponent title;
public WrappedChatComponent description;
public ItemStack item;
public MinecraftKey background;
public WrappedFrameType frameType;
public boolean showToast;
public boolean announceChat;
public boolean hidden;
public float x;
public float y;
}
}
@@ -1,25 +1,24 @@
package com.comphenix.protocol.wrappers;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.EquivalentConverter;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.BeforeClass;
import org.junit.Test;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class BukkitConvertersTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -1,17 +1,16 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class ChunkCoordIntPairTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
@@ -23,10 +22,10 @@ public class ChunkCoordIntPairTest {
assertEquals(2, specific.getChunkZ());
net.minecraft.world.level.ChunkCoordIntPair roundtrip =
(net.minecraft.world.level.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
getGeneric(specific);
(net.minecraft.world.level.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
getGeneric(specific);
assertEquals(1, roundtrip.b);
assertEquals(2, roundtrip.c);
assertEquals(1, roundtrip.c);
assertEquals(2, roundtrip.d);
}
}
@@ -1,27 +1,26 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.cloning.AggregateCloner;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class CloningTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
public void cloneGameProfile() {
WrappedGameProfile profile = new WrappedGameProfile("8817d9ec-72e6-4abe-a496-cda667c3efe1", "name");
WrappedGameProfile copy = WrappedGameProfile.fromHandle(
AggregateCloner.DEFAULT.clone(profile.getHandle())
AggregateCloner.DEFAULT.clone(profile.getHandle())
);
assertEquals(profile, copy);
}
}
@@ -1,40 +1,31 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.Sets;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.google.common.collect.Sets;
import java.util.Set;
import net.minecraft.network.EnumProtocol;
import net.minecraft.network.protocol.game.PacketPlayInClientCommand.EnumClientCommand;
import net.minecraft.world.EnumHand;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.EnumHand;
import net.minecraft.world.entity.player.EnumChatVisibility;
import net.minecraft.world.level.EnumGamemode;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class EnumWrappersTest {
private static class EnumClass {
public EnumProtocol protocol;
public EnumClientCommand command;
public EnumChatVisibility visibility;
public EnumDifficulty difficulty;
public EnumHand hand;
// public EnumEntityUseAction action; // moved to PacketPlayInUseEntity but is private
public EnumGamemode mode;
}
@BeforeClass
private static final Set<String> KNOWN_INVALID = Sets.newHashSet(
"Particle", "WorldBorderAction", "CombatEventType", "TitleAction"
);
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
@@ -48,13 +39,13 @@ public class EnumWrappersTest {
// obj.action = EnumEntityUseAction.INTERACT;
obj.mode = EnumGamemode.e;
assertEquals(obj.protocol, roundtrip(obj, "protocol", EnumWrappers.getProtocolConverter()) );
assertEquals(obj.command, roundtrip(obj, "command", EnumWrappers.getClientCommandConverter()) );
assertEquals(obj.visibility, roundtrip(obj, "visibility", EnumWrappers.getChatVisibilityConverter()) );
assertEquals(obj.difficulty, roundtrip(obj, "difficulty", EnumWrappers.getDifficultyConverter()) );
assertEquals(obj.hand, roundtrip(obj, "hand", EnumWrappers.getHandConverter()) );
assertEquals(obj.protocol, this.roundtrip(obj, "protocol", EnumWrappers.getProtocolConverter()));
assertEquals(obj.command, this.roundtrip(obj, "command", EnumWrappers.getClientCommandConverter()));
assertEquals(obj.visibility, this.roundtrip(obj, "visibility", EnumWrappers.getChatVisibilityConverter()));
assertEquals(obj.difficulty, this.roundtrip(obj, "difficulty", EnumWrappers.getDifficultyConverter()));
assertEquals(obj.hand, this.roundtrip(obj, "hand", EnumWrappers.getHandConverter()));
// assertEquals(obj.action, roundtrip(obj, "action", EnumWrappers.getEntityUseActionConverter()) );
assertEquals(obj.mode, roundtrip(obj, "mode", EnumWrappers.getGameModeConverter()) );
assertEquals(obj.mode, this.roundtrip(obj, "mode", EnumWrappers.getGameModeConverter()));
}
@SuppressWarnings("unchecked")
@@ -62,16 +53,23 @@ public class EnumWrappersTest {
FieldAccessor accessor = Accessors.getFieldAccessor(target.getClass(), fieldName, true);
return (T) converter.getGeneric(
converter.getSpecific(accessor.get(target))
converter.getSpecific(accessor.get(target))
);
}
private static final Set<String> KNOWN_INVALID = Sets.newHashSet(
"Particle", "WorldBorderAction", "CombatEventType", "TitleAction"
);
@Test
public void testValidity() {
assertEquals(EnumWrappers.INVALID, KNOWN_INVALID);
}
private static class EnumClass {
public EnumProtocol protocol;
public EnumClientCommand command;
public EnumChatVisibility visibility;
public EnumDifficulty difficulty;
public EnumHand hand;
// public EnumEntityUseAction action; // moved to PacketPlayInUseEntity but is private
public EnumGamemode mode;
}
}
@@ -1,44 +1,35 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2015 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import org.bukkit.Location;
import org.bukkit.Material;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.utility.MinecraftReflection;
import org.bukkit.Location;
import org.bukkit.Material;
/**
* @author dmulloy2
*/
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
public class MultiBlockChangeTest {
// @BeforeClass
// @BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
// @Test
@@ -55,7 +46,7 @@ public class MultiBlockChangeTest {
// Make sure the location is correct
assertEquals(loc, info.getLocation(null));
MultiBlockChangeInfo[] array = { info, info };
MultiBlockChangeInfo[] array = {info, info};
EquivalentConverter<MultiBlockChangeInfo[]> converter = Converters.array(
MinecraftReflection.getMultiBlockChangeInfoClass(),
@@ -1,40 +1,35 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2015 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import java.util.UUID;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
import java.util.UUID;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class PlayerInfoDataTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -1,98 +1,97 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedAttributeModifier.Operation;
import com.google.common.collect.Lists;
import java.util.List;
import net.minecraft.core.IRegistry;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes.AttributeSnapshot;
import net.minecraft.resources.MinecraftKey;
import net.minecraft.world.entity.ai.attributes.AttributeBase;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.resources.MinecraftKey;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class WrappedAttributeTest {
private WrappedAttributeModifier doubleModifier;
private WrappedAttributeModifier constantModifier;
private WrappedAttribute attribute;
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Before
@BeforeEach
public void setUp() {
// Create a couple of modifiers
doubleModifier =
WrappedAttributeModifier.newBuilder().
name("Double Damage").
amount(1).
operation(Operation.ADD_PERCENTAGE).
build();
constantModifier =
WrappedAttributeModifier.newBuilder().
name("Damage Bonus").
amount(5).
operation(Operation.ADD_NUMBER).
build();
this.doubleModifier =
WrappedAttributeModifier.newBuilder().
name("Double Damage").
amount(1).
operation(Operation.ADD_PERCENTAGE).
build();
this.constantModifier =
WrappedAttributeModifier.newBuilder().
name("Damage Bonus").
amount(5).
operation(Operation.ADD_NUMBER).
build();
// Create attribute
attribute = WrappedAttribute.newBuilder().
this.attribute = WrappedAttribute.newBuilder().
attributeKey("generic.attackDamage").
baseValue(2).
packet(new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES)).
modifiers(Lists.newArrayList(constantModifier, doubleModifier)).
modifiers(Lists.newArrayList(this.constantModifier, this.doubleModifier)).
build();
}
@Test
public void testEquality() {
// Check wrapped equality
assertEquals(doubleModifier, doubleModifier);
assertNotSame(constantModifier, doubleModifier);
assertEquals(doubleModifier.getHandle(), getModifierCopy(doubleModifier));
assertEquals(constantModifier.getHandle(), getModifierCopy(constantModifier));
assertEquals(this.doubleModifier, this.doubleModifier);
assertNotSame(this.constantModifier, this.doubleModifier);
assertEquals(this.doubleModifier.getHandle(), this.getModifierCopy(this.doubleModifier));
assertEquals(this.constantModifier.getHandle(), this.getModifierCopy(this.constantModifier));
}
@Test
public void testAttribute() {
assertEquals(attribute, WrappedAttribute.fromHandle(getAttributeCopy(attribute)));
assertTrue(attribute.hasModifier(doubleModifier.getUUID()));
assertTrue(attribute.hasModifier(constantModifier.getUUID()));
assertEquals(this.attribute, WrappedAttribute.fromHandle(this.getAttributeCopy(this.attribute)));
assertTrue(this.attribute.hasModifier(this.doubleModifier.getUUID()));
assertTrue(this.attribute.hasModifier(this.constantModifier.getUUID()));
}
@Test
public void testFromTemplate() {
assertEquals(attribute, WrappedAttribute.newBuilder(attribute).build());
assertEquals(this.attribute, WrappedAttribute.newBuilder(this.attribute).build());
}
/**
* Retrieve the equivalent NMS attribute.
*
* @param attribute - the wrapped attribute.
* @return The equivalent NMS attribute.
*/
private AttributeSnapshot getAttributeCopy(WrappedAttribute attribute) {
List<AttributeModifier> modifiers = Lists.newArrayList();
for (WrappedAttributeModifier wrapper : attribute.getModifiers()) {
modifiers.add((AttributeModifier) wrapper.getHandle());
}
AttributeBase base = IRegistry.al.get(MinecraftKey.a(attribute.getAttributeKey()));
AttributeBase base = IRegistry.aj.a(MinecraftKey.a(attribute.getAttributeKey()));
return new AttributeSnapshot(base, attribute.getBaseValue(), modifiers);
}
@@ -1,35 +1,31 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2015 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2015 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.wrappers;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.GlassPane;
import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_17_R1.block.impl.CraftStainedGlassPane;
import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_18_R2.block.impl.CraftStainedGlassPane;
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
@@ -37,9 +33,9 @@ import static org.junit.Assert.assertEquals;
public class WrappedBlockDataTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -60,7 +56,7 @@ public class WrappedBlockDataTest {
@Test
public void testDataCreation() {
IBlockData nmsData = CraftMagicNumbers.getBlock(Material.CYAN_STAINED_GLASS_PANE).getBlockData();
IBlockData nmsData = CraftMagicNumbers.getBlock(Material.CYAN_STAINED_GLASS_PANE).n();
GlassPane data = (GlassPane) CraftBlockData.fromData(nmsData);
data.setFace(BlockFace.EAST, true);
@@ -1,20 +1,19 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import com.comphenix.protocol.BukkitInitialization;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class WrappedChatComponentTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
public void testText() {
WrappedChatComponent test = WrappedChatComponent.fromText("Hello.");
@@ -1,46 +1,44 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2016 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.wrappers;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import java.util.UUID;
import net.minecraft.world.entity.projectile.EntityEgg;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEgg;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEgg;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class WrappedDataWatcherTest {
@BeforeClass
@BeforeAll
public static void prepare() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -1,11 +1,8 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import java.util.UUID;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.comphenix.protocol.BukkitInitialization;
import com.google.common.base.Charsets;
@@ -13,17 +10,21 @@ import com.google.common.collect.Multimap;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import java.util.UUID;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class WrappedGameProfileTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
public void testWrapper() {
GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)), "ProtocolLib");
GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)),
"ProtocolLib");
WrappedGameProfile wrapper = WrappedGameProfile.fromHandle(profile);
assertEquals(profile.getId(), wrapper.getUUID());
@@ -34,20 +35,21 @@ public class WrappedGameProfileTest {
@SuppressWarnings("deprecation")
public void testSkinUpdate() {
final UUID uuid = UUID.nameUUIDFromBytes("123".getBytes(Charsets.UTF_8));
assertEquals(null, new WrappedGameProfile((String)null, "Test").getId());
assertNull(new WrappedGameProfile((String) null, "Test").getId());
assertEquals(uuid, new WrappedGameProfile("123", "Test").getUUID());
}
@SuppressWarnings("deprecation")
@Test(expected = RuntimeException.class)
@Test
public void testNullFailure() {
new WrappedGameProfile((String)null, null);
assertThrows(RuntimeException.class, () -> new WrappedGameProfile((String) null, null));
}
@Test
public void testGetProperties() {
GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)), "ProtocolLib");
GameProfile profile = new GameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)),
"ProtocolLib");
String name = "test";
String value = "test";
@@ -70,7 +72,8 @@ public class WrappedGameProfileTest {
String value = "test";
String signature = null;
WrappedGameProfile wrapper = new WrappedGameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)), "ProtocolLib");
WrappedGameProfile wrapper = new WrappedGameProfile(UUID.nameUUIDFromBytes("ProtocolLib".getBytes(Charsets.UTF_8)),
"ProtocolLib");
wrapper.getProperties().put(name, new WrappedSignedProperty(name, value, signature));
GameProfile profile = (GameProfile) wrapper.getHandle();
@@ -1,26 +0,0 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.junit.BeforeClass;
import org.junit.Test;
import com.comphenix.protocol.BukkitInitialization;
public class WrappedIntHashMapTest {
//@BeforeClass
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
}
//@Test
public void testIntMap() {
WrappedIntHashMap test = WrappedIntHashMap.newMap();
test.put(1, "hello");
assertNull(test.get(0));
assertEquals(test.get(1), "hello");
}
}
@@ -1,24 +1,24 @@
package com.comphenix.protocol.wrappers;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
import org.bukkit.inventory.ItemStack;
import org.junit.BeforeClass;
import org.junit.Test;
import static com.comphenix.protocol.utility.TestUtils.assertItemsEqual;
import static org.junit.Assert.assertEquals;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class WrappedParticleTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -1,22 +1,21 @@
package com.comphenix.protocol.wrappers;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.BeforeClass;
import org.junit.Test;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage;
import com.google.common.io.Resources;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
public class WrappedServerPingTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
@@ -47,8 +46,7 @@ public class WrappedServerPingTest {
// There was a global package seal for a while, but not anymore
System.err.println("Encountered a SecurityException, update your Spigot jar!");
} else {
ex.printStackTrace();
fail("Encountered an exception testing ServerPing");
fail("Encountered an exception testing ServerPing", ex);
}
}
}
@@ -2,75 +2,75 @@
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2012 Kristian S. Stangeland
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol.wrappers.nbt;
import static org.junit.Assert.assertEquals;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class NbtCompoundTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
public void testCustomTags() {
NbtCustomTag<Integer> test = new NbtCustomTag<Integer>("hello", 12);
WrappedCompound map = WrappedCompound.fromName("test");
map.put(test);
// Note that the custom tag will be cloned
assertEquals(12, map.getInteger("hello"));
}
/**
* Represents a custom NBT tag.
*
* @author Kristian
*
* @param <TValue> - the value of the tag.
* @author Kristian
*/
public static class NbtCustomTag<TValue> implements NbtBase<TValue> {
private String name;
private TValue value;
private NbtType type;
private final NbtType type;
public NbtCustomTag(String name, TValue value) {
if (value == null)
if (value == null) {
throw new IllegalArgumentException("Cannot create a custom tag from NULL.");
}
this.value = value;
this.name = name;
this.type = NbtType.getTypeFromClass(value.getClass());
}
@Override
public NbtType getType() {
return type;
return this.type;
}
@Override
public String getName() {
return name;
return this.name;
}
@Override
@@ -80,7 +80,7 @@ public class NbtCompoundTest {
@Override
public TValue getValue() {
return value;
return this.value;
}
@Override
@@ -90,12 +90,12 @@ public class NbtCompoundTest {
@Override
public NbtBase<TValue> deepClone() {
return new NbtCustomTag<TValue>(name, value);
return new NbtCustomTag<TValue>(this.name, this.value);
}
@Override
public boolean accept(NbtVisitor visitor) {
return visitor.visit(this);
}
}
}
}
@@ -17,51 +17,35 @@
package com.comphenix.protocol.wrappers.nbt;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
import com.comphenix.protocol.reflect.instances.DefaultInstances;
import com.comphenix.protocol.utility.Constants;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
//@PrepareForTest(CraftItemFactory.class)
public class NbtFactoryTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() throws IllegalAccessException {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
public void testFromStream() {
WrappedCompound compound = WrappedCompound.fromName("tag");
compound.put("name", "Test Testerson");
compound.put("age", 42);
compound.put(NbtFactory.ofList("nicknames", "a", "b", "c"));
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@@ -70,9 +54,9 @@ public class NbtFactoryTest {
ByteArrayInputStream source = new ByteArrayInputStream(buffer.toByteArray());
DataInput input = new DataInputStream(source);
NbtCompound cloned = NbtBinarySerializer.DEFAULT.deserializeCompound(input);
assertEquals(compound.getString("name"), cloned.getString("name"));
assertEquals(compound.getInteger("age"), cloned.getInteger("age"));
assertEquals(compound.getList("nicknames"), cloned.getList("nicknames"));
@@ -82,13 +66,13 @@ public class NbtFactoryTest {
public void testItemTag() {
ItemStack test = new ItemStack(Items.L);
org.bukkit.inventory.ItemStack craftTest = MinecraftReflection.getBukkitItemStack(test);
NbtCompound compound = NbtFactory.ofCompound("tag");
compound.put("name", "Test Testerson");
compound.put("age", 42);
NbtFactory.setItemTag(craftTest, compound);
assertEquals(compound, NbtFactory.fromItemTag(craftTest));
}
@@ -1,35 +1,32 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol. Copyright (C) 2016 dmulloy2
* <p>
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
* version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* <p>
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.comphenix.protocol.wrappers.nbt;
import org.bukkit.block.BlockState;
import org.junit.BeforeClass;
import org.junit.Test;
import com.comphenix.protocol.BukkitInitialization;
import org.bukkit.block.BlockState;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
/**
* @author dmulloy2
*/
public class TileEntityTest {
@BeforeClass
@BeforeAll
public static void beforeClass() {
BukkitInitialization.initializePackage();
BukkitInitialization.initializeAll();
}
@Test
@@ -1,20 +1,19 @@
package com.comphenix.protocol.wrappers.nbt.io;
import static org.junit.Assert.assertEquals;
import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class NbtConfigurationSerializerTest {
@BeforeClass
@BeforeAll
public static void initializeBukkit() {
BukkitInitialization.initializeItemMeta();
BukkitInitialization.initializeAll();
}
@Test
@@ -22,16 +21,16 @@ public class NbtConfigurationSerializerTest {
NbtCompound compound = NbtFactory.ofCompound("hello");
compound.put("age", (short) 30);
compound.put("name", "test");
compound.put("values", new int[] { 1, 2, 3 });
compound.put("values", new int[]{1, 2, 3});
compound.put(NbtFactory.ofList("telephone", "12345678", "81549300"));
compound.put(NbtFactory.ofList("lists", NbtFactory.ofList("", "a", "a", "b", "c")));
YamlConfiguration yaml = new YamlConfiguration();
NbtConfigurationSerializer.DEFAULT.serialize(compound, yaml);
NbtCompound result = NbtConfigurationSerializer.DEFAULT.deserializeCompound(yaml, "hello");
assertEquals(compound, result);
}
}
@@ -0,0 +1 @@
mock-maker-inline