Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adb3c5392c | ||
|
|
cd2f56d7c7 | ||
|
|
7c9bbc3f6c | ||
|
|
52e396b25d | ||
|
|
aeb2cfb65e | ||
|
|
7f5ea6e493 | ||
|
|
1be94aad78 | ||
|
|
6bb169ac01 | ||
|
|
ea7900d64f | ||
|
|
123abdff30 | ||
|
|
11247f1c01 | ||
|
|
f093c9196d | ||
|
|
81daa62071 | ||
|
|
f99b977888 | ||
|
|
b00ae2ff15 | ||
|
|
b4f9c501b3 | ||
|
|
1738c6f243 | ||
|
|
abea7441a4 | ||
|
|
3887ba27d2 | ||
|
|
76a3af84a1 | ||
|
|
be5d42ee19 | ||
|
|
790711c16e | ||
|
|
8c3127dee1 | ||
|
|
5ec87c9d76 | ||
|
|
2205ce639e | ||
|
|
2844d75607 | ||
|
|
a6810ea874 | ||
|
|
aaf1af8e41 | ||
|
|
b8dd43aeed | ||
|
|
e959efc5af | ||
|
|
73ce01bbde | ||
|
|
b30628f6db | ||
|
|
9289825d87 | ||
|
|
57cfbc4f81 | ||
|
|
3ab2026d62 | ||
|
|
e439c778a6 | ||
|
|
98413c917e | ||
|
|
540a5e53c4 | ||
|
|
27047f83a5 | ||
|
|
222b535c15 | ||
|
|
3f31af6b70 | ||
|
|
b6a054b766 | ||
|
|
3b7b692e80 | ||
|
|
c6788addeb | ||
|
|
5b38bc7f38 | ||
|
|
33bb12713d | ||
|
|
d175a7655e | ||
|
|
4afb38aae1 | ||
|
|
36b5670b3d | ||
|
|
7b61796506 | ||
|
|
684b687e42 | ||
|
|
7a9b9afe2e | ||
|
|
7d382279ad | ||
|
|
b4f5f18283 | ||
|
|
17e150393a | ||
|
|
b5ecfb9c5f |
No files matched your search
+1
-1
@@ -8,7 +8,7 @@
|
||||
.settings/
|
||||
bin/
|
||||
.idea/
|
||||
.iml
|
||||
*.iml
|
||||
.ipr
|
||||
.iws
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk7
|
||||
script: mvn clean test
|
||||
#before_install: cd ProtocolLib
|
||||
install: true
|
||||
|
||||
+12
-62
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ProtocolLib-API</artifactId>
|
||||
<name>ProtocolLib-API</name>
|
||||
<version>4.1.0</version>
|
||||
<version>${minorVersion}</version>
|
||||
|
||||
<description>Provides read/write access to the Minecraft protocol.</description>
|
||||
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
|
||||
@@ -19,6 +19,8 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number></project.build.number>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
<spigotVersion>1.12-pre2-SNAPSHOT</spigotVersion>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -40,8 +42,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -54,7 +56,7 @@
|
||||
<manifestEntries>
|
||||
<Main-Class>com.comphenix.protocol.Application</Main-Class>
|
||||
<Implementation-Title>ProtocolLib</Implementation-Title>
|
||||
<Implementation-Version>${project.version}${project.build.number}</Implementation-Version>
|
||||
<Implementation-Version>${project.fullVersion}</Implementation-Version>
|
||||
<Implementation-Vendor>dmulloy2</Implementation-Vendor>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
@@ -88,6 +90,7 @@
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.number>-b${env.BUILD_NUMBER}</project.build.number>
|
||||
<project.fullVersion>${project.version}${project.build.number}</project.fullVersion>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
@@ -99,6 +102,9 @@
|
||||
<value>true</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -129,6 +135,7 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- TODO: Look into signing releases
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
@@ -143,6 +150,7 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -184,62 +192,4 @@
|
||||
<timezone>1</timezone>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<dependencies>
|
||||
<!-- Included with Minecraft
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.23.Final</version>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.10.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.10.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.8.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-module-junit4</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-api-mockito</artifactId>
|
||||
<version>1.5</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -16,7 +20,6 @@ import org.bukkit.Bukkit;
|
||||
import com.comphenix.protocol.PacketTypeLookup.ClassLookup;
|
||||
import com.comphenix.protocol.events.ConnectionSide;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
import com.comphenix.protocol.reflect.ObjectEnum;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.google.common.base.Objects;
|
||||
@@ -37,7 +40,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Represents an unknown legacy packet ID.
|
||||
* Represents an unknown packet ID.
|
||||
*/
|
||||
public static final int UNKNOWN_PACKET = -1;
|
||||
|
||||
@@ -52,7 +55,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Incoming packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
public static class Client extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType SET_PROTOCOL = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "SetProtocol");
|
||||
@@ -60,7 +63,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Client() { super(PacketType.class); }
|
||||
private Client() { super(); }
|
||||
|
||||
public static Client getInstance() {
|
||||
return INSTANCE;
|
||||
@@ -74,10 +77,10 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* An empty enum, as the server will not send any packets in this protocol.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
public static class Server extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
private final static Server INSTANCE = new Server();
|
||||
private Server() { super(PacketType.class); }
|
||||
private Server() { super(); }
|
||||
|
||||
public static Server getInstance() {
|
||||
return INSTANCE;
|
||||
@@ -103,7 +106,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Outgoing packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
public static class Server extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType SPAWN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x00, 0x0E, "SpawnEntity");
|
||||
@@ -143,10 +146,10 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x22, 0x2A, "WorldParticles");
|
||||
public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x23, 0x01, "Login");
|
||||
public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x24, 0x34, "Map");
|
||||
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x25, 0x15, "RelEntityMove");
|
||||
public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x26, 0x17, "RelEntityMoveLook");
|
||||
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x27, 0x16, "EntityLook");
|
||||
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 0x28, 0x14, "Entity");
|
||||
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 0x25, 0x14, "Entity");
|
||||
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x26, 0x15, "RelEntityMove");
|
||||
public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x27, 0x17, "RelEntityMoveLook");
|
||||
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x28, 0x16, "EntityLook");
|
||||
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x29, 0xFE, "VehicleMove");
|
||||
public static final PacketType OPEN_SIGN_EDITOR = new PacketType(PROTOCOL, SENDER, 0x2A, 0x36, "OpenSignEditor");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x2B, 0x39, "Abilities");
|
||||
@@ -154,34 +157,37 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x2D, 0x38, "PlayerInfo");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x2E, 0x08, "Position");
|
||||
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 0x2F, 0x0A, "Bed");
|
||||
public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x30, 0x13, "EntityDestroy");
|
||||
public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x31, 0x1E, "RemoveEntityEffect");
|
||||
public static final PacketType RESOURCE_PACK_SEND = new PacketType(PROTOCOL, SENDER, 0x32, 0x48, "ResourcePackSend");
|
||||
public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x33, 0x07, "Respawn");
|
||||
public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x34, 0x19, "EntityHeadRotation");
|
||||
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 0x35, 0x44, "WorldBorder");
|
||||
public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x36, 0x43, "Camera");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x37, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x38, 0x3D, "ScoreboardDisplayObjective");
|
||||
public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x39, 0x1C, "EntityMetadata");
|
||||
public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x3A, 0x1B, "AttachEntity");
|
||||
public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x3B, 0x12, "EntityVelocity");
|
||||
public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x3C, 0x04, "EntityEquipment");
|
||||
public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x3D, 0x1F, "Experience");
|
||||
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x3E, 0x06, "UpdateHealth");
|
||||
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x3F, 0x3B, "ScoreboardObjective");
|
||||
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x40, 0xFB, "Mount");
|
||||
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x41, 0x3E, "ScoreboardTeam");
|
||||
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x42, 0x3C, "ScoreboardScore");
|
||||
public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x43, 0x05, "SpawnPosition");
|
||||
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x44, 0x03, "UpdateTime");
|
||||
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 0x45, 0x45, "Title");
|
||||
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x47, 0x29, "NamedSoundEffect");
|
||||
public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x48, 0x47, "PlayerListHeaderFooter");
|
||||
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x49, 0x0D, "Collect");
|
||||
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x4A, 0x18, "EntityTeleport");
|
||||
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x4B, 0x20, "UpdateAttributes");
|
||||
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x4C, 0x1D, "EntityEffect");
|
||||
public static final PacketType RECIPES = new PacketType(PROTOCOL, SENDER, 0x30, -1, "Recipes");
|
||||
public static final PacketType ENTITY_DESTROY = new PacketType(PROTOCOL, SENDER, 0x31, 0x13, "EntityDestroy");
|
||||
public static final PacketType REMOVE_ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x32, 0x1E, "RemoveEntityEffect");
|
||||
public static final PacketType RESOURCE_PACK_SEND = new PacketType(PROTOCOL, SENDER, 0x33, 0x48, "ResourcePackSend");
|
||||
public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x34, 0x07, "Respawn");
|
||||
public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x35, 0x19, "EntityHeadRotation");
|
||||
public static final PacketType SELECT_ADVANCEMENT_TAB = new PacketType(PROTOCOL, SENDER, 0x36, -1, "SelectAdvancementTab");
|
||||
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 0x37, 0x44, "WorldBorder");
|
||||
public static final PacketType CAMERA = new PacketType(PROTOCOL, SENDER, 0x38, 0x43, "Camera");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x39, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SCOREBOARD_DISPLAY_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x3A, 0x3D, "ScoreboardDisplayObjective");
|
||||
public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x3B, 0x1C, "EntityMetadata");
|
||||
public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x3C, 0x1B, "AttachEntity");
|
||||
public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x3D, 0x12, "EntityVelocity");
|
||||
public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x3E, 0x04, "EntityEquipment");
|
||||
public static final PacketType EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x3F, 0x1F, "Experience");
|
||||
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x40, 0x06, "UpdateHealth");
|
||||
public static final PacketType SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x41, 0x3B, "ScoreboardObjective");
|
||||
public static final PacketType MOUNT = new PacketType(PROTOCOL, SENDER, 0x42, 0xFB, "Mount");
|
||||
public static final PacketType SCOREBOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x43, 0x3E, "ScoreboardTeam");
|
||||
public static final PacketType SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x44, 0x3C, "ScoreboardScore");
|
||||
public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x45, 0x05, "SpawnPosition");
|
||||
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x46, 0x03, "UpdateTime");
|
||||
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 0x47, 0x45, "Title");
|
||||
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x48, 0x29, "NamedSoundEffect");
|
||||
public static final PacketType PLAYER_LIST_HEADER_FOOTER = new PacketType(PROTOCOL, SENDER, 0x49, 0x47, "PlayerListHeaderFooter");
|
||||
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x4A, 0x0D, "Collect");
|
||||
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x4B, 0x18, "EntityTeleport");
|
||||
public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x4C, -1, "Advancements");
|
||||
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x4D, 0x20, "UpdateAttributes");
|
||||
public static final PacketType ENTITY_EFFECT = new PacketType(PROTOCOL, SENDER, 0x4E, 0x1D, "EntityEffect");
|
||||
|
||||
// ---- Removed in 1.9
|
||||
|
||||
@@ -189,59 +195,59 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType MAP_CHUNK_BULK = new PacketType(PROTOCOL, SENDER, 255, 255, "MapChunkBulk").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
public static final PacketType MAP_CHUNK_BULK = new PacketType(PROTOCOL, SENDER, 255, 255, "MapChunkBulk");
|
||||
|
||||
/**
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 254, 254, "SetCompression").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 254, 254, "SetCompression");
|
||||
|
||||
/**
|
||||
* @deprecated Removed in 1.9
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType UPDATE_ENTITY_NBT = new PacketType(PROTOCOL, SENDER, 253, 253, "UpdateEntityNBT").deprecatedIn(MinecraftVersion.COMBAT_UPDATE);
|
||||
public static final PacketType UPDATE_ENTITY_NBT = new PacketType(PROTOCOL, SENDER, 253, 253, "UpdateEntityNBT");
|
||||
|
||||
// ----- Renamed packets
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link WINDOW_DATA}
|
||||
* @deprecated Renamed to {@link #WINDOW_DATA}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType CRAFT_PROGRESS_BAR = WINDOW_DATA.deprecated();
|
||||
public static final PacketType CRAFT_PROGRESS_BAR = WINDOW_DATA.clone();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link REL_ENTITY_MOVE_LOOK}
|
||||
* @deprecated Renamed to {@link #REL_ENTITY_MOVE_LOOK}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType ENTITY_MOVE_LOOK = REL_ENTITY_MOVE_LOOK.deprecated();
|
||||
public static final PacketType ENTITY_MOVE_LOOK = REL_ENTITY_MOVE_LOOK.clone();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link STATISTIC}
|
||||
* @deprecated Renamed to {@link #STATISTIC}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType STATISTICS = STATISTIC.deprecated();
|
||||
public static final PacketType STATISTICS = STATISTIC.clone();
|
||||
|
||||
/**
|
||||
* @deprecated Renamed to {@link OPEN_SIGN_EDITOR}
|
||||
* @deprecated Renamed to {@link #OPEN_SIGN_EDITOR}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType OPEN_SIGN_ENTITY = OPEN_SIGN_EDITOR.deprecated();
|
||||
public static final PacketType OPEN_SIGN_ENTITY = OPEN_SIGN_EDITOR.clone();
|
||||
|
||||
// ----- Replaced in 1.9.4
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link TILE_ENTITY_DATA}
|
||||
* @deprecated Replaced by {@link #TILE_ENTITY_DATA}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType UPDATE_SIGN = MinecraftReflection.signUpdateExists() ? new PacketType(PROTOCOL, SENDER, 252, 252, "UpdateSign") :
|
||||
TILE_ENTITY_DATA.deprecated();
|
||||
TILE_ENTITY_DATA.clone();
|
||||
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Server() { super(PacketType.class); }
|
||||
private Server() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -255,44 +261,47 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Incoming packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
public static class Client extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType TELEPORT_ACCEPT = new PacketType(PROTOCOL, SENDER, 0x00, 0xF9, "TeleportAccept");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x01, 0x14, "TabComplete");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x02, 0x01, "Chat");
|
||||
public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x03, 0x16, "ClientCommand");
|
||||
public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x04, 0x15, "Settings");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x05, 0x0F, "Transaction");
|
||||
public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x06, 0x11, "EnchantItem");
|
||||
public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x07, 0x0E, "WindowClick");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x08, 0x0D, "CloseWindow");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x09, 0x17, "CustomPayload");
|
||||
public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x0A, 0x02, "UseEntity");
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x0B, 0x00, "KeepAlive");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x0C, 0x04, "Position");
|
||||
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x0D, 0x06, "PositionLook");
|
||||
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x0E, 0x05, "Look");
|
||||
public static final PacketType FLYING = new PacketType(PROTOCOL, SENDER, 0x0F, 0x03, "Flying");
|
||||
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x10, 0xF8, "VehicleMove");
|
||||
public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x11, 0xF7, "BoatMove");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x12, 0x13, "Abilities");
|
||||
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x13, 0x07, "BlockDig");
|
||||
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x14, 0x0B, "EntityAction");
|
||||
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x15, 0x0C, "SteerVehicle");
|
||||
public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x16, 0x19, "ResourcePackStatus");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x17, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x18, 0x10, "SetCreativeSlot");
|
||||
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x19, 0x12, "UpdateSign");
|
||||
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x1A, 0x0A, "ArmAnimation");
|
||||
public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x1B, 0x18, "Spectate");
|
||||
public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x1C, 0xF6, "UseItem");
|
||||
public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x1D, 0x08, "BlockPlace");
|
||||
public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x01, -1, "AutoRecipe");
|
||||
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x02, 0x14, "TabComplete");
|
||||
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x03, 0x01, "Chat");
|
||||
public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x04, 0x16, "ClientCommand");
|
||||
public static final PacketType SETTINGS = new PacketType(PROTOCOL, SENDER, 0x05, 0x15, "Settings");
|
||||
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x06, 0x0F, "Transaction");
|
||||
public static final PacketType ENCHANT_ITEM = new PacketType(PROTOCOL, SENDER, 0x07, 0x11, "EnchantItem");
|
||||
public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x08, 0x0E, "WindowClick");
|
||||
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x09, 0x0D, "CloseWindow");
|
||||
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x0A, 0x17, "CustomPayload");
|
||||
public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x0B, 0x02, "UseEntity");
|
||||
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x0C, 0x00, "KeepAlive");
|
||||
public static final PacketType FLYING = new PacketType(PROTOCOL, SENDER, 0x0D, 0x03, "Flying");
|
||||
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x0E, 0x04, "Position");
|
||||
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x0F, 0x06, "PositionLook");
|
||||
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x10, 0x05, "Look");
|
||||
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x11, 0xF8, "VehicleMove");
|
||||
public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x12, 0xF7, "BoatMove");
|
||||
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x13, 0x13, "Abilities");
|
||||
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x14, 0x07, "BlockDig");
|
||||
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x15, 0x0B, "EntityAction");
|
||||
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x16, 0x0C, "SteerVehicle");
|
||||
public static final PacketType RECIPE_DISPLAYED = new PacketType(PROTOCOL, SENDER, 0x17, -1, "RecipeDisplayed");
|
||||
public static final PacketType RESOURCE_PACK_STATUS = new PacketType(PROTOCOL, SENDER, 0x18, 0x19, "ResourcePackStatus");
|
||||
public static final PacketType ADVANCEMENTS = new PacketType(PROTOCOL, SENDER, 0x19, -1, "Advancements");
|
||||
public static final PacketType HELD_ITEM_SLOT = new PacketType(PROTOCOL, SENDER, 0x1A, 0x09, "HeldItemSlot");
|
||||
public static final PacketType SET_CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x1B, 0x10, "SetCreativeSlot");
|
||||
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x1C, 0x12, "UpdateSign");
|
||||
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x1D, 0x0A, "ArmAnimation");
|
||||
public static final PacketType SPECTATE = new PacketType(PROTOCOL, SENDER, 0x1E, 0x18, "Spectate");
|
||||
public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x1F, 0xF6, "UseItem");
|
||||
public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x20, 0x08, "BlockPlace");
|
||||
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Client() { super(PacketType.class); }
|
||||
private Client() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -318,22 +327,24 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Outgoing packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
public static class Server extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "ServerInfo").forceAsync(true);
|
||||
@ForceAsync
|
||||
public static final PacketType SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "ServerInfo");
|
||||
public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "Pong");
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link SERVER_INFO}
|
||||
* @deprecated Renamed to {@link #SERVER_INFO}
|
||||
*/
|
||||
@Deprecated
|
||||
public static final PacketType OUT_SERVER_INFO = SERVER_INFO.deprecated();
|
||||
@ForceAsync
|
||||
public static final PacketType OUT_SERVER_INFO = SERVER_INFO.clone();
|
||||
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Server() { super(PacketType.class); }
|
||||
private Server() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -347,7 +358,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Incoming packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
public static class Client extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
||||
@@ -356,7 +367,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Client() { super(PacketType.class); }
|
||||
private Client() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -382,7 +393,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Outgoing packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
public static class Server extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Disconnect");
|
||||
@@ -393,7 +404,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final static Server INSTANCE = new Server();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Server() { super(PacketType.class); }
|
||||
private Server() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -407,7 +418,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Incoming packets.
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
public static class Client extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
||||
@@ -416,7 +427,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Client() { super(PacketType.class); }
|
||||
private Client() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -443,7 +454,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @author Kristian
|
||||
*/
|
||||
// Missing server packets: [10, 11, 12, 21, 107, 252]
|
||||
public static class Server extends ObjectEnum<PacketType> {
|
||||
public static class Server extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.SERVER;
|
||||
|
||||
public static final PacketType PLAYER_FLYING = PacketType.newLegacy(SENDER, 10);
|
||||
@@ -467,7 +478,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
|
||||
// Prevent accidental construction
|
||||
private Server() {
|
||||
super(PacketType.class);
|
||||
super();
|
||||
}
|
||||
|
||||
public static Sender getSender() {
|
||||
@@ -483,7 +494,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @author Kristian
|
||||
*/
|
||||
// Missing client packets: [1, 9, 255]
|
||||
public static class Client extends ObjectEnum<PacketType> {
|
||||
public static class Client extends PacketTypeEnum {
|
||||
private final static Sender SENDER = Sender.CLIENT;
|
||||
|
||||
public static final PacketType LOGIN = PacketType.newLegacy(SENDER, 1);
|
||||
@@ -493,7 +504,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final static Client INSTANCE = new Client();
|
||||
|
||||
// Prevent accidental construction
|
||||
private Client() { super(PacketType.class); }
|
||||
private Client() { super(); }
|
||||
|
||||
public static Sender getSender() {
|
||||
return SENDER;
|
||||
@@ -576,13 +587,20 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not packets of this type must be handled asynchronously.
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ForceAsync { }
|
||||
|
||||
// Lookup of packet types
|
||||
private static PacketTypeLookup LOOKUP;
|
||||
|
||||
/**
|
||||
* Protocol version of all the current IDs.
|
||||
*/
|
||||
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.FROSTBURN_UPDATE;
|
||||
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.EXPLORATION_UPDATE;
|
||||
|
||||
private final Protocol protocol;
|
||||
private final Sender sender;
|
||||
@@ -591,9 +609,11 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
private final MinecraftVersion version;
|
||||
private final String[] classNames;
|
||||
|
||||
private boolean forceAsync;
|
||||
private boolean dynamic;
|
||||
private String name;
|
||||
private boolean deprecated;
|
||||
private boolean forceAsync;
|
||||
|
||||
private boolean dynamic;
|
||||
|
||||
/**
|
||||
* Retrieve the current packet/legacy lookup.
|
||||
@@ -644,7 +664,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @param packetId - the legacy packet ID.
|
||||
* @return The corresponding packet type.
|
||||
* @throws IllegalArgumentException If the legacy packet could not be found.
|
||||
* @deprecated Legacy IDs haven't functioned properly for some time
|
||||
*/
|
||||
@Deprecated
|
||||
public static PacketType findLegacy(int packetId) {
|
||||
PacketType type = getLookup().getFromLegacy(packetId);
|
||||
|
||||
@@ -659,7 +681,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @param preference - the preferred sender, or NULL for any arbitrary sender.
|
||||
* @return The corresponding packet type.
|
||||
* @throws IllegalArgumentException If the legacy packet could not be found.
|
||||
* @deprecated Legacy IDs haven't functioned properly for some time
|
||||
*/
|
||||
@Deprecated
|
||||
public static PacketType findLegacy(int packetId, Sender preference) {
|
||||
if (preference == null)
|
||||
return findLegacy(packetId);
|
||||
@@ -674,7 +698,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* Determine if the given legacy packet exists.
|
||||
* @param packetId - the legacy packet ID.
|
||||
* @return TRUE if it does, FALSE otherwise.
|
||||
* @deprecated Legacy IDs haven't functioned properly for some time
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasLegacy(int packetId) {
|
||||
return getLookup().getFromLegacy(packetId) != null;
|
||||
}
|
||||
@@ -682,18 +708,19 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
/**
|
||||
* Retrieve a packet type from a protocol, sender and packet ID.
|
||||
* <p>
|
||||
* It is usually better to access the packet types statically, like so:
|
||||
* It is almost always better to access the packet types statically, like so:
|
||||
* <ul>
|
||||
* <li>{@link PacketType.Play.Server#SPAWN_ENTITY}
|
||||
* </ul>
|
||||
* However there are some valid uses for packet IDs. Please note that IDs
|
||||
* change almost every Minecraft version.
|
||||
*
|
||||
* @param protocol - the current protocol.
|
||||
* @param sender - the sender.
|
||||
* @param packetId - the packet ID.
|
||||
* @return The corresponding packet type.
|
||||
* @throws IllegalArgumentException If the current packet could not be found.
|
||||
* @deprecated IDs are no longer reliable
|
||||
*/
|
||||
@Deprecated
|
||||
public static PacketType findCurrent(Protocol protocol, Sender sender, int packetId) {
|
||||
PacketType type = getLookup().getFromCurrent(protocol, sender, packetId);
|
||||
|
||||
@@ -719,7 +746,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
if (name.contains("Packet"))
|
||||
return name;
|
||||
|
||||
return String.format("Packet%s%s%s", protocol.getPacketName(), sender.getPacketName(), name);
|
||||
return String.format("Packet%s%s%s", protocol.getPacketName(), sender.getPacketName(), WordUtils.capitalize(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -728,9 +755,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @param sender - the sender.
|
||||
* @param packetId - the packet ID.
|
||||
* @return TRUE if it exists, FALSE otherwise.
|
||||
* @deprecated IDs are no longer reliable
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean hasCurrent(Protocol protocol, Sender sender, int packetId) {
|
||||
return getLookup().getFromCurrent(protocol, sender, packetId) != null;
|
||||
}
|
||||
@@ -743,7 +768,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @param sender - the sender of the packet, or NULL if unknown.
|
||||
* @return The packet type.
|
||||
* @throws IllegalArgumentException If the sender is NULL and the packet doesn't exist.
|
||||
* @deprecated Legacy IDs haven't functioned properly for some time
|
||||
*/
|
||||
@Deprecated
|
||||
public static PacketType fromLegacy(int id, Sender sender) {
|
||||
PacketType type = getLookup().getFromLegacy(id, sender);
|
||||
|
||||
@@ -797,24 +824,11 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
Map<String, PacketType> map = lookup.getMap(protocol, sender);
|
||||
|
||||
// Check the map first
|
||||
String className = packetClass.getSimpleName();
|
||||
PacketType type = map.get(className);
|
||||
String clazz = packetClass.getSimpleName();
|
||||
PacketType type = find(map, clazz);
|
||||
if (type == null) {
|
||||
// Then check any aliases
|
||||
for (PacketType check : map.values()) {
|
||||
String[] aliases = check.getClassNames();
|
||||
if (aliases.length > 1) {
|
||||
for (String alias : aliases) {
|
||||
if (alias.equals(className)) {
|
||||
// We have a match!
|
||||
type = check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guess we don't support this packet :/
|
||||
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, className);
|
||||
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, clazz);
|
||||
type.dynamic = true;
|
||||
|
||||
// Many may be scheduled, but only the first will be executed
|
||||
@@ -824,6 +838,28 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
return type;
|
||||
}
|
||||
|
||||
private static PacketType find(Map<String, PacketType> map, String clazz) {
|
||||
PacketType ret = map.get(clazz);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check any aliases
|
||||
for (PacketType check : map.values()) {
|
||||
String[] aliases = check.getClassNames();
|
||||
if (aliases.length > 1) {
|
||||
for (String alias : aliases) {
|
||||
if (alias.equals(clazz)) {
|
||||
// We have a match!
|
||||
return check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a packet type from a packet class.
|
||||
* @param packetClass - the packet class.
|
||||
@@ -869,7 +905,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
ObjectEnum<PacketType> objEnum;
|
||||
PacketTypeEnum objEnum;
|
||||
|
||||
// A bit ugly, but performance is critical
|
||||
objEnum = getObjectEnum(type);
|
||||
@@ -898,7 +934,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* @param type - the packet type.
|
||||
* @return The corresponding object enum.
|
||||
*/
|
||||
public static ObjectEnum<PacketType> getObjectEnum(final PacketType type) {
|
||||
public static PacketTypeEnum getObjectEnum(final PacketType type) {
|
||||
switch (type.getProtocol()) {
|
||||
case HANDSHAKING:
|
||||
return type.isClient() ? Handshake.Client.getInstance() : Handshake.Server.getInstance();
|
||||
@@ -945,7 +981,6 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
for (int i = 0; i < classNames.length; i++) {
|
||||
classNames[i] = format(protocol, sender, names[i]);
|
||||
}
|
||||
//System.out.println(Arrays.toString(classNames));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1003,11 +1038,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* <p>
|
||||
* This is only unique within a specific protocol and target.
|
||||
* <p>
|
||||
* It is only unknown if the packet was removed in Minecraft 1.7.2.
|
||||
* It is unknown if the packet was removed at any point.
|
||||
* @return The current ID, or {@link #UNKNOWN_PACKET} if unknown.
|
||||
* @deprecated IDs are subject to change
|
||||
*/
|
||||
@Deprecated
|
||||
public int getCurrentId() {
|
||||
return currentId;
|
||||
}
|
||||
@@ -1028,12 +1061,47 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
}
|
||||
}
|
||||
|
||||
// Only used by Enum processor
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the declared enum name of this packet type.
|
||||
* @return The enum name.
|
||||
*/
|
||||
public String name() {
|
||||
return getObjectEnum(this).getDeclaredName(this);
|
||||
return name;
|
||||
}
|
||||
|
||||
// Only used by enum processor
|
||||
void setDeprecated() {
|
||||
this.deprecated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this packet is deprecated. Deprecated packet types have either been renamed, replaced, or removed.
|
||||
* Kind of like the thing they use to tell children to recycle except with packets you probably shouldn't be using.
|
||||
*
|
||||
* @return True if the type is deprecated, false if not
|
||||
*/
|
||||
public boolean isDeprecated() {
|
||||
return deprecated;
|
||||
}
|
||||
|
||||
// Only used by enum processor
|
||||
void forceAsync() {
|
||||
this.forceAsync = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the processing of this packet must take place on a thread different than the main thread. You don't
|
||||
* get a choice. If this is false it's up to you.
|
||||
*
|
||||
* @return True if async processing is forced, false if not.
|
||||
*/
|
||||
public boolean isAsyncForced() {
|
||||
return forceAsync;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1049,7 +1117,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
* <p>
|
||||
* This ID is globally unique.
|
||||
* @return The legacy ID, or {@link #UNKNOWN_PACKET} if unknown.
|
||||
* @deprecated Legacy IDs haven't functioned properly for some time
|
||||
*/
|
||||
@Deprecated
|
||||
public int getLegacyId() {
|
||||
return legacyId;
|
||||
}
|
||||
@@ -1062,40 +1132,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
private PacketType forceAsync(boolean forceAsync) {
|
||||
this.forceAsync = forceAsync;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this packet must be processed asynchronously.
|
||||
* @return True if it must be, false if not.
|
||||
*/
|
||||
public boolean forceAsync() {
|
||||
return forceAsync;
|
||||
}
|
||||
|
||||
private PacketType deprecatedIn(MinecraftVersion version) {
|
||||
try {
|
||||
return MinecraftVersion.getCurrentVersion().isAtLeast(version) ? deprecated() : this;
|
||||
} catch (Throwable ex) {
|
||||
return deprecated();
|
||||
}
|
||||
}
|
||||
|
||||
private PacketType deprecated() {
|
||||
PacketType ret = clone();
|
||||
ret.deprecated = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean isDeprecated() {
|
||||
return deprecated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(protocol, sender, currentId, legacyId);
|
||||
return Objects.hashCode(protocol, sender, currentId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1107,8 +1146,7 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
PacketType other = (PacketType) obj;
|
||||
return protocol == other.protocol &&
|
||||
sender == other.sender &&
|
||||
currentId == other.currentId &&
|
||||
legacyId == other.legacyId;
|
||||
currentId == other.currentId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1119,7 +1157,6 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
compare(protocol, other.getProtocol()).
|
||||
compare(sender, other.getSender()).
|
||||
compare(currentId, other.getCurrentId()).
|
||||
compare(legacyId, other.getLegacyId()).
|
||||
result();
|
||||
}
|
||||
|
||||
@@ -1128,9 +1165,9 @@ public class PacketType implements Serializable, Cloneable, Comparable<PacketTyp
|
||||
Class<?> clazz = getPacketClass();
|
||||
|
||||
if (clazz == null)
|
||||
return name() + "[" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + ", classNames: " + Arrays.toString(classNames) + " (unregistered)]";
|
||||
return name() + "[" + protocol + ", " + sender + ", " + currentId + ", classNames: " + Arrays.toString(classNames) + " (unregistered)]";
|
||||
else
|
||||
return clazz.getSimpleName() + "[" + currentId + ", legacy: " + legacyId + "]";
|
||||
return name() + "[class=" + clazz.getSimpleName() + ", id=" + currentId + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+57
-41
@@ -15,7 +15,7 @@
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.reflect;
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -23,8 +23,10 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Represents a more modern object-based enum.
|
||||
@@ -33,40 +35,53 @@ import com.google.common.collect.HashBiMap;
|
||||
* want to prevent the creation of additional members dynamically.
|
||||
* @author Kristian
|
||||
*/
|
||||
public class ObjectEnum<T> implements Iterable<T> {
|
||||
public class PacketTypeEnum implements Iterable<PacketType> {
|
||||
// Used to convert between IDs and names
|
||||
protected BiMap<T, String> members = HashBiMap.create();
|
||||
protected Set<PacketType> members = Sets.newHashSet();
|
||||
|
||||
/**
|
||||
* Registers every declared integer field.
|
||||
* @param fieldType Field type
|
||||
* Registers every declared PacketType field.
|
||||
*/
|
||||
public ObjectEnum(Class<T> fieldType) {
|
||||
registerAll(fieldType);
|
||||
public PacketTypeEnum() {
|
||||
registerAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers every public assignable static field as a member.
|
||||
* @param fieldType Field type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void registerAll(Class<T> fieldType) {
|
||||
protected void registerAll() {
|
||||
try {
|
||||
// Register every non-deprecated field
|
||||
for (Field entry : this.getClass().getFields()) {
|
||||
if (Modifier.isStatic(entry.getModifiers()) && fieldType.isAssignableFrom(entry.getType())) {
|
||||
T value = (T) entry.get(null);
|
||||
|
||||
if (value == null)
|
||||
throw new IllegalArgumentException("Field " + entry + " was NULL. Remember to " +
|
||||
"construct the object after the field has been declared.");
|
||||
registerMember(value, entry.getName());
|
||||
if (Modifier.isStatic(entry.getModifiers()) && PacketType.class.isAssignableFrom(entry.getType())) {
|
||||
PacketType value = (PacketType) entry.get(null);
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("Field " + entry.getName() + " was null!");
|
||||
}
|
||||
|
||||
value.setName(entry.getName());
|
||||
|
||||
if (entry.getAnnotation(PacketType.ForceAsync.class) != null) {
|
||||
value.forceAsync();
|
||||
}
|
||||
|
||||
boolean deprecated = entry.getAnnotation(Deprecated.class) != null;
|
||||
if (deprecated) value.setDeprecated();
|
||||
|
||||
if (members.contains(value)) {
|
||||
// Replace potentially deprecated packet types with non-deprecated ones
|
||||
if (!deprecated) {
|
||||
members.remove(value);
|
||||
members.add(value);
|
||||
}
|
||||
} else {
|
||||
members.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,11 +91,14 @@ public class ObjectEnum<T> implements Iterable<T> {
|
||||
* @param name - name of member.
|
||||
* @return TRUE if the member was registered, FALSE otherwise.
|
||||
*/
|
||||
public boolean registerMember(T instance, String name) {
|
||||
if (!members.containsKey(instance)) {
|
||||
members.put(instance, name);
|
||||
public boolean registerMember(PacketType instance, String name) {
|
||||
instance.setName(name);
|
||||
|
||||
if (!members.contains(instance)) {
|
||||
members.add(instance);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -89,38 +107,36 @@ public class ObjectEnum<T> implements Iterable<T> {
|
||||
* @param member - the member to check.
|
||||
* @return TRUE if the given member has been registered, FALSE otherwise.
|
||||
*/
|
||||
public boolean hasMember(T member) {
|
||||
return members.containsKey(member);
|
||||
public boolean hasMember(PacketType member) {
|
||||
return members.contains(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a member by name,
|
||||
* @param name - name of member to retrieve.
|
||||
* @return The member, or NULL if not found.
|
||||
* @deprecated Don't use this
|
||||
*/
|
||||
public T valueOf(String name) {
|
||||
return members.inverse().get(name);
|
||||
@Deprecated
|
||||
public PacketType valueOf(String name) {
|
||||
for (PacketType member : members) {
|
||||
if (member.name().equals(name))
|
||||
return member;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the name of the given member.
|
||||
* @param member - the member to retrieve.
|
||||
* @return Declared name of the member, or NULL if not found.
|
||||
*/
|
||||
public String getDeclaredName(T member) {
|
||||
return members.get(member);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve every registered member.
|
||||
* @return Enumeration of every value.
|
||||
*/
|
||||
public Set<T> values() {
|
||||
return new HashSet<T>(members.keySet());
|
||||
public Set<PacketType> values() {
|
||||
return new HashSet<>(members);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return members.keySet().iterator();
|
||||
public Iterator<PacketType> iterator() {
|
||||
return members.iterator();
|
||||
}
|
||||
}
|
||||
@@ -39,12 +39,12 @@ public class ProtocolLibrary {
|
||||
/**
|
||||
* The maximum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.10.2";
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.12";
|
||||
|
||||
/**
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.10.2) was released.
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.12) was released.
|
||||
*/
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-06-23";
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2017-06-07";
|
||||
|
||||
/**
|
||||
* Plugins that are currently incompatible with ProtocolLib.
|
||||
|
||||
@@ -73,4 +73,10 @@ public class ProtocolLogger {
|
||||
log("[Debug] " + message, args);
|
||||
}
|
||||
}
|
||||
|
||||
public static void debug(String message, Throwable ex) {
|
||||
if (isDebugEnabled()) {
|
||||
plugin.getLogger().log(Level.WARNING, "[Debug] " + message, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
@@ -36,10 +34,11 @@ import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.timing.TimedListenerManager;
|
||||
import com.comphenix.protocol.timing.TimedListenerManager.ListenerType;
|
||||
import com.comphenix.protocol.timing.TimedTracker;
|
||||
import com.comphenix.protocol.utility.WrappedScheduler;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents a handler for an asynchronous event.
|
||||
* <p>
|
||||
@@ -345,8 +344,7 @@ public class AsyncListenerHandler {
|
||||
}
|
||||
|
||||
private void scheduleAsync(Runnable runnable) {
|
||||
// Handle deprecation
|
||||
WrappedScheduler.runAsynchronouslyRepeat(listener.getPlugin(), filterManager.getScheduler(), runnable, 0L, -1L);
|
||||
listener.getPlugin().getServer().getScheduler().runTaskAsynchronously(listener.getPlugin(), runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -238,12 +238,7 @@ public class ListeningWhitelist {
|
||||
if (this == EMPTY_WHITELIST)
|
||||
return "EMPTY_WHITELIST";
|
||||
else
|
||||
return Objects.toStringHelper(this).
|
||||
add("priority", priority).
|
||||
add("packets", types).
|
||||
add("gamephase", gamePhase).
|
||||
add("options", options).
|
||||
toString();
|
||||
return "ListeningWhitelist[priority=" + priority + ", packets=" + types + ", gamephase=" + gamePhase + ", options=" + options + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,6 +74,7 @@ import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
|
||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatType;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.CombatEventType;
|
||||
@@ -401,7 +402,25 @@ public class PacketContainer implements Serializable {
|
||||
MinecraftReflection.getItemStackArrayClass(),
|
||||
BukkitConverters.getIgnoreNull(new ItemStackArrayConverter()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for lists of ItemStacks.
|
||||
* <p>
|
||||
* This modifier will automatically marshal between the Bukkit ItemStack and the
|
||||
* internal Minecraft ItemStack.
|
||||
* @return A modifier for ItemStack list fields.
|
||||
*/
|
||||
public StructureModifier<List<ItemStack>> getItemListModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.withType(
|
||||
List.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getItemStackClass(),
|
||||
BukkitConverters.getItemStackConverter()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for maps of statistics.
|
||||
* <p>
|
||||
@@ -937,6 +956,15 @@ public class PacketContainer implements Serializable {
|
||||
return structureModifier.<Direction>withType(
|
||||
EnumWrappers.getDirectionClass(), EnumWrappers.getDirectionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the ChatType enum in 1.12.
|
||||
* @return A modifier for ChatType enum fields.
|
||||
*/
|
||||
public StructureModifier<ChatType> getChatTypes() {
|
||||
return structureModifier.<ChatType>withType(
|
||||
EnumWrappers.getChatTypeClass(), EnumWrappers.getChatTypeConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for an enum. This allows for the use of
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.bukkit.entity.Player;
|
||||
import com.comphenix.protocol.PacketStream;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
@@ -138,10 +137,6 @@ public class ScheduledPacket {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("packet", packet)
|
||||
.add("target", target)
|
||||
.add("filtered", filtered)
|
||||
.toString();
|
||||
return "ScheduledPacket[packet=" + packet + ", target=" + target + ", filtered=" + filtered + "]";
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,6 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable {
|
||||
return banned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBanned(boolean banned) {
|
||||
this.banned = banned;
|
||||
}
|
||||
|
||||
@@ -67,9 +67,11 @@ public class StructureCache {
|
||||
// TODO: Optimize DefaultInstances
|
||||
Object result = DefaultInstances.DEFAULT.create(clazz);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException("Failed to create packet for type: " + type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
throw new IllegalArgumentException("Cannot find associated packet class: " + type);
|
||||
}
|
||||
|
||||
+47
-1
@@ -28,6 +28,7 @@ import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.GatheringByteChannel;
|
||||
import java.nio.channels.ScatteringByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
@@ -44,6 +45,7 @@ import com.google.common.io.ByteStreams;
|
||||
* all indexing in the byte buffer.
|
||||
* @author Kristian
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class NettyByteBufAdapter extends AbstractByteBuf {
|
||||
private DataInputStream input;
|
||||
private DataOutputStream output;
|
||||
@@ -214,7 +216,7 @@ public class NettyByteBufAdapter extends AbstractByteBuf {
|
||||
|
||||
@Override
|
||||
public ByteBufAllocator alloc() {
|
||||
return null;
|
||||
return ByteBufAllocator.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -389,4 +391,48 @@ public class NettyByteBufAdapter extends AbstractByteBuf {
|
||||
public ByteBuf retain() {
|
||||
return this;
|
||||
}
|
||||
|
||||
protected int _getIntLE(int arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected long _getLongLE(int arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected short _getShortLE(int arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected int _getUnsignedMediumLE(int arg0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void _setIntLE(int arg0, int arg1) {
|
||||
}
|
||||
|
||||
protected void _setLongLE(int arg0, long arg1) {
|
||||
}
|
||||
|
||||
protected void _setMediumLE(int arg0, int arg1) {
|
||||
}
|
||||
|
||||
protected void _setShortLE(int arg0, int arg1) {
|
||||
}
|
||||
|
||||
public int getBytes(int arg0, FileChannel arg1, long arg2, int arg3) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int setBytes(int arg0, FileChannel arg1, long arg2, int arg3) throws IOException {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public ByteBuf touch() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ByteBuf touch(Object arg0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+3
-6
@@ -40,8 +40,6 @@ public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
ProtocolLogger.debug("Initializing the Netty protocol registry"); // Debug for issue #202
|
||||
|
||||
Object[] protocols = enumProtocol.getEnumConstants();
|
||||
|
||||
// ID to Packet class maps
|
||||
@@ -75,8 +73,7 @@ public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Object protocol = protocols[i];
|
||||
for (Object protocol : protocols) {
|
||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
@@ -103,8 +100,8 @@ public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
} catch (Exception ex) {
|
||||
ProtocolLogger.debug("Encountered an exception associating packet " + type, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,20 +149,53 @@ public class WirePacket {
|
||||
* @return The resulting WirePacket
|
||||
*/
|
||||
public static WirePacket fromPacket(PacketContainer packet) {
|
||||
checkNotNull(packet, "packet cannot be null!");
|
||||
|
||||
int id = packet.getType().getCurrentId();
|
||||
return new WirePacket(id, bytesFromPacket(packet));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a byte array from an existing PacketContainer containing all the
|
||||
* bytes from that packet
|
||||
*
|
||||
* @param packet Existing packet
|
||||
* @return The ByteBuf
|
||||
*/
|
||||
public static byte[] bytesFromPacket(PacketContainer packet) {
|
||||
checkNotNull(packet, "packet cannot be null!");
|
||||
|
||||
ByteBuf buffer = PacketContainer.createPacketBuffer();
|
||||
ByteBuf store = PacketContainer.createPacketBuffer();
|
||||
|
||||
// Read the bytes once
|
||||
Method write = MinecraftMethods.getPacketWriteByteBufMethod();
|
||||
|
||||
try {
|
||||
write.invoke(packet.getHandle(), buffer);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to serialize packet contents.", ex);
|
||||
throw new RuntimeException("Failed to read packet contents.", ex);
|
||||
}
|
||||
|
||||
return new WirePacket(id, getBytes(buffer));
|
||||
byte[] bytes = getBytes(buffer);
|
||||
|
||||
// Rewrite them to the packet to avoid issues with certain packets
|
||||
if (packet.getType() == PacketType.Play.Server.CUSTOM_PAYLOAD
|
||||
|| packet.getType() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
|
||||
// Make a copy of the array before writing
|
||||
byte[] ret = Arrays.copyOf(bytes, bytes.length);
|
||||
store.writeBytes(bytes);
|
||||
|
||||
Method read = MinecraftMethods.getPacketReadByteBufMethod();
|
||||
|
||||
try {
|
||||
read.invoke(packet.getHandle(), store);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to rewrite packet contents.", ex);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-20
@@ -171,16 +171,7 @@ public class PacketRegistry {
|
||||
initialize();
|
||||
NETTY.synchronize();
|
||||
|
||||
Set<PacketType> types = new HashSet<>();
|
||||
|
||||
// Filter out unsupported packets
|
||||
for (PacketType type : NETTY.getServerPackets()) {
|
||||
if (!type.isDeprecated()) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
return NETTY.getServerPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,16 +198,7 @@ public class PacketRegistry {
|
||||
initialize();
|
||||
NETTY.synchronize();
|
||||
|
||||
Set<PacketType> types = new HashSet<>();
|
||||
|
||||
// Filter out unsupported packets
|
||||
for (PacketType type : NETTY.getClientPackets()) {
|
||||
if (!type.isDeprecated()) {
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
return NETTY.getClientPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
|
||||
package com.comphenix.protocol.reflect;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -421,6 +418,30 @@ public class FuzzyReflection {
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a field with a given type and parameters. This is most useful
|
||||
* when dealing with Collections.
|
||||
*
|
||||
* @param fieldType Type of the field
|
||||
* @param params Variable length array of type parameters
|
||||
* @return The field
|
||||
*
|
||||
* @throws IllegalArgumentException If the field cannot be found
|
||||
*/
|
||||
public Field getParameterizedField(Class<?> fieldType, Class<?>... params) {
|
||||
for (Field field : getFields()) {
|
||||
if (field.getType().equals(fieldType)) {
|
||||
Type type = field.getGenericType();
|
||||
if (type instanceof ParameterizedType) {
|
||||
if (Arrays.equals(((ParameterizedType) type).getActualTypeArguments(), params))
|
||||
return field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unable to find a field with type " + fieldType + " and params " + Arrays.toString(params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the first field that matches.
|
||||
|
||||
@@ -17,7 +17,6 @@ import com.google.common.collect.Lists;
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
@SuppressWarnings("unused") // Java 8 compat
|
||||
public abstract class MethodInfo implements GenericDeclaration, Member {
|
||||
/**
|
||||
* Wraps a method as a MethodInfo object.
|
||||
|
||||
@@ -453,6 +453,17 @@ public class StructureModifier<TField> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> StructureModifier<T> withType(Class fieldType, EquivalentConverter<T> converter) {
|
||||
if (fieldType == null) {
|
||||
// It's not supported in this version, so return an empty modifier
|
||||
return new StructureModifier<T>() {
|
||||
@Override
|
||||
public T read(int index) { return null; }
|
||||
|
||||
@Override
|
||||
public StructureModifier<T> write(int index, T value) { return this; }
|
||||
};
|
||||
}
|
||||
|
||||
StructureModifier<T> result = subtypeCache.get(fieldType);
|
||||
|
||||
// Do we need to update the cache?
|
||||
@@ -462,7 +473,7 @@ public class StructureModifier<TField> {
|
||||
int index = 0;
|
||||
|
||||
for (Field field : data) {
|
||||
if (fieldType != null && fieldType.isAssignableFrom(field.getType())) {
|
||||
if (fieldType.isAssignableFrom(field.getType())) {
|
||||
filtered.add(field);
|
||||
|
||||
// Don't use the original index
|
||||
@@ -476,14 +487,12 @@ public class StructureModifier<TField> {
|
||||
|
||||
// Cache structure modifiers
|
||||
result = withFieldType(fieldType, filtered, defaults);
|
||||
|
||||
if (fieldType != null) {
|
||||
subtypeCache.put(fieldType, result);
|
||||
|
||||
subtypeCache.put(fieldType, result);
|
||||
|
||||
// Automatically compile the structure modifier
|
||||
if (useStructureCompiler && BackgroundCompiler.getInstance() != null)
|
||||
BackgroundCompiler.getInstance().scheduleCompilation(subtypeCache, fieldType);
|
||||
}
|
||||
// Automatically compile the structure modifier
|
||||
if (useStructureCompiler && BackgroundCompiler.getInstance() != null)
|
||||
BackgroundCompiler.getInstance().scheduleCompilation(subtypeCache, fieldType);
|
||||
}
|
||||
|
||||
// Add the target too
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
*/
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||
@@ -67,6 +71,11 @@ public class BukkitCloner implements Cloner {
|
||||
addClass(7, MinecraftReflection.getIBlockDataClass());
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
try {
|
||||
addClass(8, MinecraftReflection.getNonNullListClass());
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private void addClass(int id, Class<?> clazz) {
|
||||
@@ -122,8 +131,43 @@ public class BukkitCloner implements Cloner {
|
||||
case 7:
|
||||
EquivalentConverter<WrappedBlockData> blockDataConverter = BukkitConverters.getWrappedBlockDataConverter();
|
||||
return blockDataConverter.getGeneric(clonableClasses.get(7), blockDataConverter.getSpecific(source).deepClone());
|
||||
case 8:
|
||||
return nonNullListCloner().clone(source);
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
private static Constructor<?> nonNullList = null;
|
||||
|
||||
private static final Cloner nonNullListCloner() {
|
||||
return new Cloner() {
|
||||
@Override
|
||||
public boolean canClone(Object source) {
|
||||
return MinecraftReflection.is(MinecraftReflection.getNonNullListClass(), source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone(Object source) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<>(source.getClass(), true).withTarget(source);
|
||||
List<?> list = (List<?>) modifier.read(0);
|
||||
Object empty = modifier.read(1);
|
||||
|
||||
if (nonNullList == null) {
|
||||
try {
|
||||
nonNullList = source.getClass().getDeclaredConstructor(List.class, Object.class);
|
||||
nonNullList.setAccessible(true);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Could not find NonNullList constructor", ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return nonNullList.newInstance(new ArrayList<>(list), empty);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Could not create new NonNullList", ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
/**
|
||||
* 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.utility;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Maps;
|
||||
@@ -29,10 +29,10 @@ import com.google.common.collect.Maps;
|
||||
* @author Kristian
|
||||
*/
|
||||
class CachedPackage {
|
||||
private final Map<String, Class<?>> cache;
|
||||
private final Map<String, Optional<Class<?>>> cache;
|
||||
private final String packageName;
|
||||
private final ClassSource source;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new cached package.
|
||||
* @param packageName - the name of the current package.
|
||||
@@ -43,16 +43,20 @@ class CachedPackage {
|
||||
this.cache = Maps.newConcurrentMap();
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Associate a given class with a class name.
|
||||
* @param className - class name.
|
||||
* @param clazz - type of class.
|
||||
*/
|
||||
public void setPackageClass(String className, Class<?> clazz) {
|
||||
cache.put(className, clazz);
|
||||
if (clazz != null) {
|
||||
cache.put(className, Optional.<Class<?>> of(clazz));
|
||||
} else {
|
||||
cache.remove(className);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the class object of a specific class in the current package.
|
||||
* @param className - the specific class.
|
||||
@@ -60,23 +64,30 @@ class CachedPackage {
|
||||
* @throws RuntimeException If we are unable to find the given class.
|
||||
*/
|
||||
public Class<?> getPackageClass(String className) {
|
||||
try {
|
||||
Class<?> result = cache.get(Preconditions.checkNotNull(className, "className cannot be NULL"));
|
||||
Preconditions.checkNotNull(className, "className cannot be null!");
|
||||
|
||||
// Concurrency is not a problem - we don't care if we look up a class twice
|
||||
if (result == null) {
|
||||
// Look up the class dynamically
|
||||
result = source.loadClass(combine(packageName, className));
|
||||
if (result == null)
|
||||
throw new IllegalArgumentException("Source " + source + " returned NULL for " + className);
|
||||
|
||||
cache.put(className, result);
|
||||
// See if we've already looked it up
|
||||
if (cache.containsKey(className)) {
|
||||
Optional<Class<?>> result = cache.get(className);
|
||||
if (!result.isPresent()) {
|
||||
throw new RuntimeException("Cannot find class " + className);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (ClassNotFoundException e) {
|
||||
setPackageClass(className, null);
|
||||
throw new RuntimeException("Cannot find class " + combine(packageName, className), e);
|
||||
return result.get();
|
||||
}
|
||||
|
||||
try {
|
||||
// Try looking it up
|
||||
Class<?> clazz = source.loadClass(combine(packageName, className));
|
||||
if (clazz == null) {
|
||||
throw new IllegalArgumentException("Source " + source + " returned null for " + className);
|
||||
}
|
||||
|
||||
cache.put(className, Optional.<Class<?>> of(clazz));
|
||||
return clazz;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
cache.put(className, Optional.<Class<?>> absent());
|
||||
throw new RuntimeException("Cannot find class " + className, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ package com.comphenix.protocol.utility;
|
||||
*/
|
||||
|
||||
public final class Constants {
|
||||
public static final String PACKAGE_VERSION = "v1_10_R1";
|
||||
public static final String PACKAGE_VERSION = "v1_12_R1";
|
||||
public static final String NMS = "net.minecraft.server." + PACKAGE_VERSION;
|
||||
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import net.sf.cglib.proxy.MethodProxy;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
|
||||
/**
|
||||
* Static methods for accessing Minecraft methods.
|
||||
@@ -43,7 +44,13 @@ public class MinecraftMethods {
|
||||
Class<?> serverHandlerClass = MinecraftReflection.getPlayerConnectionClass();
|
||||
|
||||
try {
|
||||
sendPacketMethod = FuzzyReflection.fromClass(serverHandlerClass).getMethodByName("sendPacket.*");
|
||||
sendPacketMethod = FuzzyReflection
|
||||
.fromClass(serverHandlerClass)
|
||||
.getMethod(FuzzyMethodContract.newBuilder()
|
||||
.nameRegex("sendPacket.*")
|
||||
.returnTypeVoid()
|
||||
.parameterCount(1)
|
||||
.build());
|
||||
} catch (IllegalArgumentException e) {
|
||||
// We can't use the method below on Netty
|
||||
if (MinecraftReflection.isUsingNetty()) {
|
||||
|
||||
@@ -42,6 +42,9 @@ public class MinecraftProtocolVersion {
|
||||
map.put(new MinecraftVersion(1, 9, 2), 109);
|
||||
map.put(new MinecraftVersion(1, 9, 4), 110);
|
||||
map.put(new MinecraftVersion(1, 10, 0), 210);
|
||||
map.put(new MinecraftVersion(1, 11, 0), 315);
|
||||
map.put(new MinecraftVersion(1, 11, 1), 316);
|
||||
map.put(new MinecraftVersion(1, 12, 0), 335);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
+116
-112
@@ -41,6 +41,7 @@ import java.util.regex.Pattern;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -62,8 +63,8 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyClassContract;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException.Reason;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException.Reason;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtType;
|
||||
import com.google.common.base.Joiner;
|
||||
@@ -128,13 +129,13 @@ public class MinecraftReflection {
|
||||
private static String packageVersion;
|
||||
|
||||
// Item stacks
|
||||
private static Method craftNMSMethod;
|
||||
/* private static Method craftNMSMethod;
|
||||
private static Method craftBukkitNMS;
|
||||
private static Method craftBukkitOBC;
|
||||
private static boolean craftItemStackFailed;
|
||||
|
||||
private static Constructor<?> craftNMSConstructor;
|
||||
private static Constructor<?> craftBukkitConstructor;
|
||||
private static Constructor<?> craftBukkitConstructor; */
|
||||
|
||||
// net.minecraft.server
|
||||
private static Class<?> itemStackArrayClass;
|
||||
@@ -933,6 +934,9 @@ public class MinecraftReflection {
|
||||
return getMinecraftClass("MinecraftServer");
|
||||
} catch (RuntimeException e) {
|
||||
useFallbackServer();
|
||||
|
||||
// Reset cache and try again
|
||||
setMinecraftClass("MinecraftServer", null);
|
||||
return getMinecraftClass("MinecraftServer");
|
||||
}
|
||||
}
|
||||
@@ -981,8 +985,10 @@ public class MinecraftReflection {
|
||||
try {
|
||||
return getMinecraftClass("ServerConfigurationManager", "PlayerList");
|
||||
} catch (RuntimeException e) {
|
||||
// Try again
|
||||
useFallbackServer();
|
||||
|
||||
// Reset cache and try again
|
||||
setMinecraftClass("ServerConfigurationManager", null);
|
||||
return getMinecraftClass("ServerConfigurationManager");
|
||||
}
|
||||
}
|
||||
@@ -1627,8 +1633,10 @@ public class MinecraftReflection {
|
||||
try {
|
||||
return getMinecraftClass("AttributeModifier");
|
||||
} catch (RuntimeException e) {
|
||||
// Initialize first
|
||||
getAttributeSnapshotClass();
|
||||
|
||||
// Reset cache and try again
|
||||
setMinecraftClass("AttributeModifier", null);
|
||||
return getMinecraftClass("AttributeModifier");
|
||||
}
|
||||
}
|
||||
@@ -1835,119 +1843,115 @@ public class MinecraftReflection {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a CraftItemStack from a given ItemStack.
|
||||
* @param bukkitItemStack - the Bukkit ItemStack to convert.
|
||||
* @return A CraftItemStack as an ItemStack.
|
||||
*/
|
||||
public static ItemStack getBukkitItemStack(ItemStack bukkitItemStack) {
|
||||
// Delegate this task to the method that can execute it
|
||||
if (craftBukkitNMS != null)
|
||||
return getBukkitItemByMethod(bukkitItemStack);
|
||||
|
||||
if (craftBukkitConstructor == null) {
|
||||
try {
|
||||
craftBukkitConstructor = getCraftItemStackClass().getConstructor(ItemStack.class);
|
||||
} catch (Exception e) {
|
||||
// See if this method works
|
||||
if (!craftItemStackFailed)
|
||||
return getBukkitItemByMethod(bukkitItemStack);
|
||||
|
||||
throw new RuntimeException("Cannot find CraftItemStack(org.bukkit.inventory.ItemStack).", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to create the CraftItemStack
|
||||
try {
|
||||
return (ItemStack) craftBukkitConstructor.newInstance(bukkitItemStack);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct CraftItemStack.", e);
|
||||
}
|
||||
public static Class<?> getNonNullListClass() {
|
||||
return getMinecraftClass("NonNullList");
|
||||
}
|
||||
|
||||
private static ItemStack getBukkitItemByMethod(ItemStack bukkitItemStack) {
|
||||
if (craftBukkitNMS == null) {
|
||||
try {
|
||||
craftBukkitNMS = getCraftItemStackClass().getMethod("asNMSCopy", ItemStack.class);
|
||||
craftBukkitOBC = getCraftItemStackClass().getMethod("asCraftMirror", MinecraftReflection.getItemStackClass());
|
||||
} catch (Exception e) {
|
||||
craftItemStackFailed = true;
|
||||
throw new RuntimeException("Cannot find CraftItemStack.asCraftCopy(org.bukkit.inventory.ItemStack).", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Next, construct it
|
||||
try {
|
||||
Object nmsItemStack = craftBukkitNMS.invoke(null, bukkitItemStack);
|
||||
return (ItemStack) craftBukkitOBC.invoke(null, nmsItemStack);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct CraftItemStack.", e);
|
||||
}
|
||||
public static Class<?> getCraftSoundClass() {
|
||||
return getCraftBukkitClass("CraftSound");
|
||||
}
|
||||
|
||||
// ---- ItemStack conversions
|
||||
|
||||
private static Method asNMSCopy = null;
|
||||
private static Method asCraftMirror = null;
|
||||
|
||||
private static Boolean nullEnforced = null;
|
||||
private static Method isEmpty = null;
|
||||
|
||||
/**
|
||||
* Retrieve the Bukkit ItemStack from a given net.minecraft.server ItemStack.
|
||||
* @param minecraftItemStack - the NMS ItemStack to wrap.
|
||||
* @return The wrapped ItemStack.
|
||||
*/
|
||||
public static ItemStack getBukkitItemStack(Object minecraftItemStack) {
|
||||
// Delegate this task to the method that can execute it
|
||||
if (craftNMSMethod != null)
|
||||
return getBukkitItemByMethod(minecraftItemStack);
|
||||
|
||||
if (craftNMSConstructor == null) {
|
||||
try {
|
||||
craftNMSConstructor = getCraftItemStackClass().getConstructor(minecraftItemStack.getClass());
|
||||
} catch (Exception e) {
|
||||
// Give it a try
|
||||
if (!craftItemStackFailed)
|
||||
return getBukkitItemByMethod(minecraftItemStack);
|
||||
|
||||
throw new RuntimeException("Cannot find CraftItemStack(net.minecraft.server.ItemStack).", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to create the CraftItemStack
|
||||
try {
|
||||
return (ItemStack) craftNMSConstructor.newInstance(minecraftItemStack);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct CraftItemStack.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static ItemStack getBukkitItemByMethod(Object minecraftItemStack) {
|
||||
if (craftNMSMethod == null) {
|
||||
try {
|
||||
craftNMSMethod = getCraftItemStackClass().getMethod("asCraftMirror", minecraftItemStack.getClass());
|
||||
} catch (Exception e) {
|
||||
craftItemStackFailed = true;
|
||||
throw new RuntimeException("Cannot find CraftItemStack.asCraftMirror(net.minecraft.server.ItemStack).", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Next, construct it
|
||||
try {
|
||||
return (ItemStack) craftNMSMethod.invoke(null, minecraftItemStack);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct CraftItemStack.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the net.minecraft.server ItemStack from a Bukkit ItemStack.
|
||||
* <p>
|
||||
* By convention, item stacks that contain air are usually represented as NULL.
|
||||
* Retrieves the Bukkit equivalent of a NMS ItemStack. This method should
|
||||
* preserve NBT data and will never return null when supplied with a valid
|
||||
* ItemStack. Empty ItemStacks are treated as AIR.
|
||||
*
|
||||
* @param stack - the Bukkit ItemStack to convert.
|
||||
* @return The NMS ItemStack, or NULL if the stack represents air.
|
||||
* @param generic NMS ItemStack
|
||||
* @return The Bukkit equivalent
|
||||
*/
|
||||
public static Object getMinecraftItemStack(ItemStack stack) {
|
||||
// Make sure this is a CraftItemStack
|
||||
if (!isCraftItemStack(stack))
|
||||
stack = getBukkitItemStack(stack);
|
||||
public static ItemStack getBukkitItemStack(Object generic) {
|
||||
if (generic == null) {
|
||||
// Convert null to AIR - 1.11 behavior
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
|
||||
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
|
||||
return unwrapper.unwrapItem(stack);
|
||||
if (generic instanceof ItemStack) {
|
||||
ItemStack bukkit = (ItemStack) generic;
|
||||
|
||||
// They're probably looking for the CraftItemStack
|
||||
// If it's one already our work is done
|
||||
if (is(getCraftItemStackClass(), generic)) {
|
||||
return bukkit;
|
||||
}
|
||||
|
||||
// If not, convert it to one
|
||||
Object nmsStack = getMinecraftItemStack((ItemStack) generic);
|
||||
return getBukkitItemStack(nmsStack);
|
||||
}
|
||||
|
||||
if (!is(getItemStackClass(), generic)) {
|
||||
// We can't do anything with non-ItemStacks
|
||||
throw new IllegalArgumentException(generic + " is not an ItemStack!");
|
||||
}
|
||||
|
||||
try {
|
||||
// Check null enforcement - 1.11 behavior
|
||||
if (nullEnforced == null) {
|
||||
isEmpty = getItemStackClass().getMethod("isEmpty");
|
||||
nullEnforced = true;
|
||||
}
|
||||
|
||||
if (nullEnforced) {
|
||||
if ((boolean) isEmpty.invoke(generic)) {
|
||||
return new ItemStack(Material.AIR);
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
nullEnforced = false;
|
||||
}
|
||||
|
||||
if (asCraftMirror == null) {
|
||||
try {
|
||||
asCraftMirror = getCraftItemStackClass().getMethod("asCraftMirror", getItemStackClass());
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to obtain CraftItemStack.asCraftMirror", ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Convert to a craft mirror to preserve NBT data
|
||||
return (ItemStack) asCraftMirror.invoke(nullEnforced, generic);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to obtain craft mirror of " + generic, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the NMS equivalent of a Bukkit ItemStack. This method will
|
||||
* never return null and should preserve NBT data. Null inputs are treated
|
||||
* as empty (AIR) ItemStacks.
|
||||
*
|
||||
* @param specific Bukkit ItemStack
|
||||
* @return The NMS equivalent
|
||||
*/
|
||||
public static Object getMinecraftItemStack(ItemStack specific) {
|
||||
if (asNMSCopy == null) {
|
||||
try {
|
||||
asNMSCopy = getCraftItemStackClass().getMethod("asNMSCopy", ItemStack.class);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to obtain CraftItemStack.asNMSCopy", ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (is(getCraftItemStackClass(), specific)) {
|
||||
// If it's already a CraftItemStack, use its handle
|
||||
return new BukkitUnwrapper().unwrapItem(specific);
|
||||
}
|
||||
|
||||
try {
|
||||
// If not, grab a NMS copy
|
||||
return asNMSCopy.invoke(null, specific);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException("Failed to make NMS copy of " + specific, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2012,7 +2016,7 @@ public class MinecraftReflection {
|
||||
// Attempt to use MCPC
|
||||
try {
|
||||
return classSource = new RemappedClassSource().initialize();
|
||||
} catch (RemapperUnavaibleException e) {
|
||||
} catch (RemapperUnavailableException e) {
|
||||
if (e.getReason() != Reason.MCPC_NOT_PRESENT)
|
||||
reporter.reportWarning(MinecraftReflection.class, Report.newBuilder(REPORT_CANNOT_FIND_MCPC_REMAPPER));
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -44,6 +44,16 @@ public class MinecraftVersion implements Comparable<MinecraftVersion>, Serializa
|
||||
*/
|
||||
private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-\\.]+)\\s*\\)");
|
||||
|
||||
/**
|
||||
* Version 1.12 - the world of color update.
|
||||
*/
|
||||
public static final MinecraftVersion COLOR_UPDATE = new MinecraftVersion("1.12");
|
||||
|
||||
/**
|
||||
* Version 1.11 - the exploration update.
|
||||
*/
|
||||
public static final MinecraftVersion EXPLORATION_UPDATE = new MinecraftVersion("1.11");
|
||||
|
||||
/**
|
||||
* Version 1.10 - the frostburn update.
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.bukkit.Server;
|
||||
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.MethodUtils;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavaibleException.Reason;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException.Reason;
|
||||
|
||||
class RemappedClassSource extends ClassSource {
|
||||
private Object classRemapper;
|
||||
@@ -53,7 +53,7 @@ class RemappedClassSource extends ClassSource {
|
||||
/**
|
||||
* Attempt to load the MCPC remapper.
|
||||
* @return TRUE if we succeeded, FALSE otherwise.
|
||||
* @throws RemapperUnavaibleException If the remapper is not present.
|
||||
* @throws RemapperUnavailableException If the remapper is not present.
|
||||
*/
|
||||
public RemappedClassSource initialize() {
|
||||
try {
|
||||
@@ -64,14 +64,14 @@ class RemappedClassSource extends ClassSource {
|
||||
|
||||
String version = server.getVersion();
|
||||
if (!version.contains("MCPC") && !version.contains("Cauldron")) {
|
||||
throw new RemapperUnavaibleException(Reason.MCPC_NOT_PRESENT);
|
||||
throw new RemapperUnavailableException(Reason.MCPC_NOT_PRESENT);
|
||||
}
|
||||
|
||||
// Obtain the Class remapper used by MCPC+/Cauldron
|
||||
this.classRemapper = FieldUtils.readField(getClass().getClassLoader(), "remapper", true);
|
||||
|
||||
if (this.classRemapper == null) {
|
||||
throw new RemapperUnavaibleException(Reason.REMAPPER_DISABLED);
|
||||
throw new RemapperUnavailableException(Reason.REMAPPER_DISABLED);
|
||||
}
|
||||
|
||||
// Initialize some fields and methods used by the Jar Remapper
|
||||
@@ -82,7 +82,7 @@ class RemappedClassSource extends ClassSource {
|
||||
|
||||
return this;
|
||||
|
||||
} catch (RemapperUnavaibleException e) {
|
||||
} catch (RemapperUnavailableException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
// Damn it
|
||||
@@ -115,7 +115,7 @@ class RemappedClassSource extends ClassSource {
|
||||
}
|
||||
}
|
||||
|
||||
public static class RemapperUnavaibleException extends RuntimeException {
|
||||
public static class RemapperUnavailableException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public enum Reason {
|
||||
@@ -139,7 +139,7 @@ class RemappedClassSource extends ClassSource {
|
||||
|
||||
private final Reason reason;
|
||||
|
||||
public RemapperUnavaibleException(Reason reason) {
|
||||
public RemapperUnavailableException(Reason reason) {
|
||||
super(reason.getMessage());
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package com.comphenix.protocol.utility;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
/**
|
||||
* Allows us to stay backwards compatible with older versions of Bukkit.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class WrappedScheduler {
|
||||
/**
|
||||
* Represents a backwards compatible Bukkit task.
|
||||
*/
|
||||
public static interface TaskWrapper {
|
||||
/**
|
||||
* Cancel the current task.
|
||||
*/
|
||||
public void cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a given task for a single asynchronous execution.
|
||||
* @param plugin - the owner plugin.
|
||||
* @param runnable - the task to run.
|
||||
* @param firstDelay - the amount of time to wait until executing the task.
|
||||
* @return A cancel token.
|
||||
*/
|
||||
public static TaskWrapper runAsynchronouslyOnce(final Plugin plugin, Runnable runnable, long firstDelay) {
|
||||
return runAsynchronouslyRepeat(plugin, plugin.getServer().getScheduler(), runnable, firstDelay, -1L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a given task for multiple asynchronous executions.
|
||||
* @param plugin - the owner plugin.
|
||||
* @param runnable - the task to run.
|
||||
* @param firstDelay - the amount of time to wait until executing the task for the first time.
|
||||
* @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once.
|
||||
* @return A cancel token.
|
||||
*/
|
||||
public static TaskWrapper runAsynchronouslyRepeat(final Plugin plugin, Runnable runnable, long firstDelay, long repeatDelay) {
|
||||
return runAsynchronouslyRepeat(plugin, plugin.getServer().getScheduler(), runnable, firstDelay, repeatDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a given task for asynchronous execution.
|
||||
* @param plugin - the owner plugin.
|
||||
* @param scheduler - the current Bukkit scheduler.
|
||||
* @param runnable - the task to run.
|
||||
* @param firstDelay - the amount of time to wait until executing the task for the first time.
|
||||
* @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once.
|
||||
* @return A cancel token.
|
||||
*/
|
||||
public static TaskWrapper runAsynchronouslyRepeat(final Plugin plugin, final BukkitScheduler scheduler, Runnable runnable, long firstDelay, long repeatDelay) {
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
final int taskID = scheduler.scheduleAsyncRepeatingTask(plugin, runnable, firstDelay, repeatDelay);
|
||||
|
||||
// Return the cancellable object
|
||||
return new TaskWrapper() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
scheduler.cancelTask(taskID);
|
||||
}
|
||||
};
|
||||
|
||||
} catch (NoSuchMethodError e) {
|
||||
return tryUpdatedVersion(plugin, scheduler, runnable, firstDelay, repeatDelay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to do the same with the updated scheduling method.
|
||||
* @param plugin - the owner plugin.
|
||||
* @param scheduler - the current Bukkit scheduler.
|
||||
* @param runnable - the task to run.
|
||||
* @param firstDelay - the amount of time to wait until executing the task for the first time.
|
||||
* @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once.
|
||||
* @return A cancel token.
|
||||
*/
|
||||
private static TaskWrapper tryUpdatedVersion(final Plugin plugin, final BukkitScheduler scheduler, Runnable runnable, long firstDelay, long repeatDelay) {
|
||||
final BukkitTask task = scheduler.runTaskTimerAsynchronously(plugin, runnable, firstDelay, repeatDelay);
|
||||
|
||||
return new TaskWrapper() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
task.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@
|
||||
* 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.lang.ref.WeakReference;
|
||||
@@ -22,23 +21,9 @@ import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
@@ -65,6 +50,16 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Contains several useful equivalent converters for normal Bukkit types.
|
||||
*
|
||||
@@ -122,7 +117,7 @@ public class BukkitConverters {
|
||||
* Represents a typical equivalence converter.
|
||||
*
|
||||
* @author Kristian
|
||||
* @param <T> - type that can be converted.
|
||||
* @param <TType> - type that can be converted.
|
||||
*/
|
||||
public static abstract class IgnoreNullConverter<TType> implements EquivalentConverter<TType> {
|
||||
@Override
|
||||
@@ -713,24 +708,24 @@ public class BukkitConverters {
|
||||
* @return Item stack converter.
|
||||
*/
|
||||
public static EquivalentConverter<ItemStack> getItemStackConverter() {
|
||||
return new IgnoreNullConverter<ItemStack>() {
|
||||
return new EquivalentConverter<ItemStack>() {
|
||||
@Override
|
||||
protected Object getGenericValue(Class<?> genericType, ItemStack specific) {
|
||||
return MinecraftReflection.getMinecraftItemStack(specific);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getSpecificValue(Object generic) {
|
||||
public ItemStack getSpecific(Object generic) {
|
||||
return MinecraftReflection.getBukkitItemStack(generic);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, ItemStack specific) {
|
||||
return MinecraftReflection.getMinecraftItemStack(specific);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ItemStack> getSpecificType() {
|
||||
return ItemStack.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the converter for the ServerPing packet in {@link PacketType.Status.Server#OUT_SERVER_INFO}.
|
||||
* @return Server ping converter.
|
||||
@@ -964,10 +959,21 @@ public class BukkitConverters {
|
||||
};
|
||||
}
|
||||
|
||||
private static MethodAccessor soundGetter = null;
|
||||
private static MethodAccessor getSound = null;
|
||||
private static MethodAccessor getSoundEffect = null;
|
||||
private static FieldAccessor soundKey = null;
|
||||
|
||||
private static Map<String, Sound> soundIndex = null;
|
||||
|
||||
public static EquivalentConverter<Sound> getSoundConverter() {
|
||||
if (getSound == null || getSoundEffect == null) {
|
||||
Class<?> craftSound = MinecraftReflection.getCraftSoundClass();
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(craftSound, true);
|
||||
getSound = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", String.class, new Class<?>[] { Sound.class }));
|
||||
getSoundEffect = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSoundEffect",
|
||||
MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
|
||||
}
|
||||
|
||||
return new IgnoreNullConverter<Sound>() {
|
||||
|
||||
@Override
|
||||
@@ -977,26 +983,42 @@ public class BukkitConverters {
|
||||
|
||||
@Override
|
||||
protected Object getGenericValue(Class<?> genericType, Sound specific) {
|
||||
if (soundGetter == null) {
|
||||
Class<?> soundEffects = MinecraftReflection.getMinecraftClass("SoundEffects");
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffects, true);
|
||||
soundGetter = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getSound", MinecraftReflection.getSoundEffectClass(), new Class<?>[] { String.class }));
|
||||
}
|
||||
|
||||
MinecraftKey key = MinecraftKey.fromEnum(specific);
|
||||
return soundGetter.invoke(null, key.getFullKey());
|
||||
// Getting the SoundEffect is easy, Bukkit provides us the methods
|
||||
String key = (String) getSound.invoke(null, specific);
|
||||
return getSoundEffect.invoke(null, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sound getSpecificValue(Object generic) {
|
||||
// Getting the Sound is a bit more complicated...
|
||||
if (soundKey == null) {
|
||||
Class<?> soundEffect = generic.getClass();
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(soundEffect, true);
|
||||
soundKey = Accessors.getFieldAccessor(fuzzy.getFieldByType("key", MinecraftReflection.getMinecraftKeyClass()));
|
||||
}
|
||||
|
||||
MinecraftKey key = MinecraftKey.fromHandle(soundKey.get(generic));
|
||||
return Sound.valueOf(key.getEnumFormat());
|
||||
MinecraftKey minecraftKey = MinecraftKey.fromHandle(soundKey.get(generic));
|
||||
String key = minecraftKey.getKey();
|
||||
|
||||
// Use our index if it already exists
|
||||
if (soundIndex != null) {
|
||||
return soundIndex.get(key);
|
||||
}
|
||||
|
||||
// If it doesn't, try to guess the enum name
|
||||
try {
|
||||
return Sound.valueOf(minecraftKey.getEnumFormat());
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
|
||||
// Worst case we index all the sounds and use it later
|
||||
soundIndex = new ConcurrentHashMap<>();
|
||||
for (Sound sound : Sound.values()) {
|
||||
String index = (String) getSound.invoke(null, sound);
|
||||
soundIndex.put(index, sound);
|
||||
}
|
||||
|
||||
return soundIndex.get(key);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@@ -45,8 +46,8 @@ public class ComponentParser {
|
||||
private static Object deserializeLegacy(Object gson, Class<?> component, StringReader str) {
|
||||
try {
|
||||
Class<?> readerClass = Class.forName("org.bukkit.craftbukkit.libs.com.google.gson.stream.JsonReader");
|
||||
Object reader = readerClass.getConstructor(StringReader.class).newInstance(str);
|
||||
Method setLenient = readerClass.getMethod("setLenienent", boolean.class);
|
||||
Object reader = readerClass.getConstructor(Reader.class).newInstance(str);
|
||||
Method setLenient = readerClass.getMethod("setLenient", boolean.class);
|
||||
setLenient.invoke(reader, true);
|
||||
Method getAdapter = gson.getClass().getMethod("getAdapter", Class.class);
|
||||
Object adapter = getAdapter.invoke(gson, component);
|
||||
@@ -56,4 +57,4 @@ public class ComponentParser {
|
||||
throw new RuntimeException("Failed to read JSON", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,7 +217,10 @@ public abstract class EnumWrappers {
|
||||
DRAGON_BREATH("dragonbreath", 42, false),
|
||||
END_ROD("endRod", 43, false),
|
||||
DAMAGE_INDICATOR("damageIndicator", 44, true),
|
||||
SWEEP_ATTACK("sweepAttack", 45, true);
|
||||
SWEEP_ATTACK("sweepAttack", 45, true),
|
||||
FALLING_DUST("fallingdust", 46, false, 1),
|
||||
TOTEM("totem", 47, false),
|
||||
SPIT("spit", 48, true);
|
||||
|
||||
private static final Map<String, Particle> BY_NAME;
|
||||
private static final Map<Integer, Particle> BY_ID;
|
||||
@@ -322,12 +325,28 @@ public abstract class EnumWrappers {
|
||||
}
|
||||
|
||||
public enum Direction {
|
||||
DOWN(),
|
||||
UP(),
|
||||
NORTH(),
|
||||
SOUTH(),
|
||||
WEST(),
|
||||
EAST();
|
||||
DOWN,
|
||||
UP,
|
||||
NORTH,
|
||||
SOUTH,
|
||||
WEST,
|
||||
EAST;
|
||||
}
|
||||
|
||||
public enum ChatType {
|
||||
CHAT(0),
|
||||
SYSTEM(1),
|
||||
GAME_INFO(2);
|
||||
|
||||
private byte id;
|
||||
|
||||
ChatType(int id) {
|
||||
this.id = (byte) id;
|
||||
}
|
||||
|
||||
public byte getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> PROTOCOL_CLASS = null;
|
||||
@@ -349,6 +368,7 @@ public abstract class EnumWrappers {
|
||||
private static Class<?> ITEM_SLOT_CLASS = null;
|
||||
private static Class<?> HAND_CLASS = null;
|
||||
private static Class<?> DIRECTION_CLASS = null;
|
||||
private static Class<?> CHAT_TYPE_CLASS = null;
|
||||
|
||||
private static boolean INITIALIZED = false;
|
||||
private static Map<Class<?>, EquivalentConverter<?>> FROM_NATIVE = Maps.newHashMap();
|
||||
@@ -385,6 +405,7 @@ public abstract class EnumWrappers {
|
||||
ITEM_SLOT_CLASS = getEnum(PacketType.Play.Server.ENTITY_EQUIPMENT.getPacketClass(), 0);
|
||||
HAND_CLASS = getEnum(PacketType.Play.Client.USE_ENTITY.getPacketClass(), 1);
|
||||
DIRECTION_CLASS = getEnum(PacketType.Play.Client.USE_ITEM.getPacketClass(), 0);
|
||||
CHAT_TYPE_CLASS = getEnum(PacketType.Play.Server.CHAT.getPacketClass(), 0);
|
||||
|
||||
associate(PROTOCOL_CLASS, Protocol.class, getClientCommandConverter());
|
||||
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());
|
||||
@@ -405,6 +426,7 @@ public abstract class EnumWrappers {
|
||||
associate(ITEM_SLOT_CLASS, ItemSlot.class, getItemSlotConverter());
|
||||
associate(HAND_CLASS, Hand.class, getHandConverter());
|
||||
associate(DIRECTION_CLASS, Direction.class, getDirectionConverter());
|
||||
associate(CHAT_TYPE_CLASS, ChatType.class, getChatTypeConverter());
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
@@ -532,6 +554,11 @@ public abstract class EnumWrappers {
|
||||
initialize();
|
||||
return DIRECTION_CLASS;
|
||||
}
|
||||
|
||||
public static Class<?> getChatTypeClass() {
|
||||
initialize();
|
||||
return CHAT_TYPE_CLASS;
|
||||
}
|
||||
|
||||
// Get the converters
|
||||
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
||||
@@ -609,6 +636,10 @@ public abstract class EnumWrappers {
|
||||
public static EquivalentConverter<Direction> getDirectionConverter() {
|
||||
return new EnumConverter<Direction>(Direction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ChatType> getChatTypeConverter() {
|
||||
return new EnumConverter<ChatType>(ChatType.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a generic enum converter for use with StructureModifiers.
|
||||
|
||||
@@ -69,7 +69,9 @@ public class MinecraftKey {
|
||||
* is lower case, with underscores replaced by periods.
|
||||
* @param value The value
|
||||
* @return The resulting key
|
||||
* @deprecated This isn't accurate in all cases
|
||||
*/
|
||||
@Deprecated
|
||||
public static MinecraftKey fromEnum(Enum<?> value) {
|
||||
return new MinecraftKey(value.name().toLowerCase(Locale.ENGLISH).replace("_", "."));
|
||||
}
|
||||
@@ -103,7 +105,9 @@ public class MinecraftKey {
|
||||
* Returns this key back into Enum format, upper case with periods replaced
|
||||
* by underscores.
|
||||
* @return The enum format
|
||||
* @deprecated This isn't accurate in all cases
|
||||
*/
|
||||
@Deprecated
|
||||
public String getEnumFormat() {
|
||||
return key.toUpperCase(Locale.ENGLISH).replace(".", "_");
|
||||
}
|
||||
|
||||
@@ -195,16 +195,16 @@ public class WrappedAttribute extends AbstractWrapper {
|
||||
if (obj instanceof WrappedAttribute) {
|
||||
WrappedAttribute other = (WrappedAttribute) obj;
|
||||
|
||||
return getBaseValue() == other.getBaseValue() &&
|
||||
Objects.equal(getAttributeKey(), other.getAttributeKey()) &&
|
||||
Sets.symmetricDifference(
|
||||
getModifiers(),
|
||||
other.getModifiers()
|
||||
).isEmpty();
|
||||
if (getBaseValue() == other.getBaseValue() &&
|
||||
Objects.equal(getAttributeKey(), other.getAttributeKey())) {
|
||||
return getModifiers().stream()
|
||||
.filter((elem) -> !other.getModifiers().contains(elem))
|
||||
.count() == 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (attributeModifiers == null)
|
||||
@@ -251,12 +251,7 @@ public class WrappedAttribute extends AbstractWrapper {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper("WrappedAttribute").
|
||||
add("key", getAttributeKey()).
|
||||
add("baseValue", getBaseValue()).
|
||||
add("finalValue", getFinalValue()).
|
||||
add("modifiers", getModifiers()).
|
||||
toString();
|
||||
return "WrappedAttribute[key=" + getAttributeKey() + ", base=" + getBaseValue() + ", final=" + getFinalValue() + ", modifiers=" + getModifiers() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,21 +16,8 @@
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
@@ -47,6 +34,10 @@ import com.comphenix.protocol.wrappers.collection.ConvertedMap;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableBiMap;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* Represents a DataWatcher in 1.8 thru 1.10
|
||||
*
|
||||
@@ -419,7 +410,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
|
||||
* Sets the DataWatcher Item at a given index to a new value.
|
||||
*
|
||||
* @param index Index of the object to set
|
||||
* @param Serializer Serializer from {@link Serializer#get(Class)}
|
||||
* @param serializer Serializer from {@link Registry#get(Class)}
|
||||
* @param value New value
|
||||
* @param update Whether or not to inform the client
|
||||
*
|
||||
@@ -463,7 +454,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
|
||||
* @param value Wrapped value
|
||||
* @param update Whether or not to inform the client
|
||||
*
|
||||
* @see {@link #setObject(WrappedDataWatcherObject, Object)}
|
||||
* @see #setObject(WrappedDataWatcherObject, Object)
|
||||
*/
|
||||
public void setObject(WrappedDataWatcherObject object, WrappedWatchableObject value, boolean update) {
|
||||
setObject(object, value.getRawValue(), update);
|
||||
@@ -893,7 +884,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
|
||||
* <li>Float</li>
|
||||
* <li>String</li>
|
||||
* <li>IChatBaseComponent</li>
|
||||
* <li>Optional<ItemStack></li>
|
||||
* <li>ItemStack</li>
|
||||
* <li>Optional<IBlockData></li>
|
||||
* <li>Boolean</li>
|
||||
* <li>Vector3f</li>
|
||||
@@ -901,6 +892,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
|
||||
* <li>Optional<BlockPosition></li>
|
||||
* <li>EnumDirection</li>
|
||||
* <li>Optional<UUID></li>
|
||||
* <li>NBTTagCompound</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author dmulloy2
|
||||
@@ -1078,5 +1070,13 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
|
||||
public static Serializer getUUIDSerializer(boolean optional) {
|
||||
return get(UUID.class, optional);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the serializer for NBT Compound tags
|
||||
* @return The serializer
|
||||
*/
|
||||
public static Serializer getNBTCompoundSerializer() {
|
||||
return get(MinecraftReflection.getNBTCompoundClass(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-5
@@ -147,10 +147,6 @@ public class WrappedSignedProperty extends AbstractWrapper {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Objects.toStringHelper(this)
|
||||
.add("name", getName())
|
||||
.add("value", getValue())
|
||||
.add("signature", getSignature())
|
||||
.toString();
|
||||
return "WrappedSignedProperty[name=" + getName() + ", value=" + getValue() + ", signature=" + getSignature() + "]";
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Direction;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
@@ -235,6 +238,8 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
return BlockPosition.getConverter().getSpecific(value);
|
||||
} else if (is(EnumWrappers.getDirectionClass(), value)) {
|
||||
return EnumWrappers.getDirectionConverter().getSpecific(value);
|
||||
} else if (is(MinecraftReflection.getNBTCompoundClass(), value)) {
|
||||
return NbtFactory.fromNMSCompound(value);
|
||||
}
|
||||
|
||||
// Legacy classes
|
||||
@@ -277,6 +282,8 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
} else if (wrapped instanceof Direction) {
|
||||
return EnumWrappers.getDirectionConverter().getGeneric(EnumWrappers.getDirectionClass(), (Direction) wrapped);
|
||||
} else if (wrapped instanceof NbtCompound) {
|
||||
return NbtFactory.fromBase((NbtCompound) wrapped).getHandle();
|
||||
}
|
||||
|
||||
// Legacy classes
|
||||
|
||||
@@ -133,7 +133,7 @@ public class NbtFactory {
|
||||
* Set the NBT compound tag of a given item stack.
|
||||
* <p>
|
||||
* The item stack must be a wrapper for a CraftItemStack. Use
|
||||
* {@link MinecraftReflection#getCraftItemStack(ItemStack)} if not.
|
||||
* {@link MinecraftReflection#getBukkitItemStack(Object)} if not.
|
||||
* @param stack - the item stack, cannot be air.
|
||||
* @param compound - the new NBT compound, or NULL to remove it.
|
||||
* @throws IllegalArgumentException If the stack is not a CraftItemStack, or it represents air.
|
||||
@@ -151,7 +151,7 @@ public class NbtFactory {
|
||||
* material, damage value or count.
|
||||
* <p>
|
||||
* The item stack must be a wrapper for a CraftItemStack. Use
|
||||
* {@link MinecraftReflection#getCraftItemStack(ItemStack)} if not.
|
||||
* {@link MinecraftReflection#getBukkitItemStack(Object)} if not.
|
||||
* @param stack - the item stack.
|
||||
* @return A wrapper for its NBT tag.
|
||||
*/
|
||||
|
||||
+15
-35
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<name>ProtocolLib</name>
|
||||
<version>4.1.0</version>
|
||||
<version>${minorVersion}</version>
|
||||
|
||||
<description>Provides read/write access to the Minecraft protocol.</description>
|
||||
<url>http://www.spigotmc.org/resources/protocollib.1997/</url>
|
||||
@@ -19,6 +19,7 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.build.number></project.build.number>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -62,6 +63,7 @@
|
||||
<exclude>org.spigotmc:spigot</exclude>
|
||||
<exclude>org.spigotmc:spigot-api</exclude>
|
||||
<exclude>junit:junit</exclude>
|
||||
<exclude>io.netty:*</exclude>
|
||||
</excludes>
|
||||
</artifactSet>
|
||||
</configuration>
|
||||
@@ -73,8 +75,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -87,11 +89,11 @@
|
||||
<manifestEntries>
|
||||
<Main-Class>com.comphenix.protocol.Application</Main-Class>
|
||||
<Implementation-Title>ProtocolLib</Implementation-Title>
|
||||
<Implementation-Version>${project.version}${project.build.number}</Implementation-Version>
|
||||
<Implementation-Version>${project.fullVersion}</Implementation-Version>
|
||||
<Implementation-Vendor>dmulloy2</Implementation-Vendor>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
<finalName>ProtocolLib</finalName>
|
||||
<finalName>${project.name}</finalName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -121,6 +123,7 @@
|
||||
</activation>
|
||||
<properties>
|
||||
<project.build.number>-b${env.BUILD_NUMBER}</project.build.number>
|
||||
<project.fullVersion>${project.version}${project.build.number}</project.fullVersion>
|
||||
</properties>
|
||||
</profile>
|
||||
|
||||
@@ -132,6 +135,9 @@
|
||||
<value>true</value>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<project.fullVersion>${project.version}</project.fullVersion>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
@@ -162,6 +168,7 @@
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- TODO: Look into signing releases
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
@@ -176,6 +183,7 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -223,38 +231,10 @@
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-API</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<!-- Included with Minecraft
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.23.Final</version>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.10.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.10.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Testing dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
/**
|
||||
* Ignore this class.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class Application {
|
||||
private static Thread mainThread;
|
||||
private static boolean primaryMethod = true;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// For now, though we might consider making a proper application
|
||||
System.out.println("This is a Bukkit library. Place it in the plugin-folder and restart the server!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if we are running on the main thread.
|
||||
* @return TRUE if we are, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isPrimaryThread() {
|
||||
if (primaryMethod) {
|
||||
try {
|
||||
return Bukkit.isPrimaryThread();
|
||||
} catch (LinkageError e) {
|
||||
primaryMethod = false;
|
||||
}
|
||||
}
|
||||
// Fallback method
|
||||
return Thread.currentThread().equals(mainThread);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the calling thread as the primary thread.
|
||||
*/
|
||||
static void registerPrimaryThread() {
|
||||
mainThread = Thread.currentThread();
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
@@ -252,16 +253,34 @@ class CommandProtocol extends CommandBase {
|
||||
pw.println();
|
||||
|
||||
Set<PacketListener> listeners = manager.getPacketListeners();
|
||||
if (listeners.size() > 0) {
|
||||
Set<Plugin> plugins = new HashSet<>();
|
||||
|
||||
if (!listeners.isEmpty()) {
|
||||
pw.println("Listeners:");
|
||||
|
||||
for (PacketListener listener : listeners) {
|
||||
pw.println(DetailedErrorReporter.getStringDescription(listener));
|
||||
|
||||
Plugin plugin = listener.getPlugin();
|
||||
if (plugin != null) {
|
||||
plugins.add(plugin);
|
||||
} else {
|
||||
pw.println("(Missing plugin!)");
|
||||
}
|
||||
}
|
||||
|
||||
pw.println();
|
||||
} else {
|
||||
pw.println("No listeners");
|
||||
}
|
||||
|
||||
if (!plugins.isEmpty()) {
|
||||
pw.println("Plugins Using ProtocolLib:");
|
||||
for (Plugin plugin : plugins) {
|
||||
pw.println(plugin.getName() + " by " + plugin.getDescription().getAuthors());
|
||||
}
|
||||
}
|
||||
|
||||
sender.sendMessage("Data dump written to " + file.getAbsolutePath());
|
||||
} catch (IOException ex) {
|
||||
ProtocolLogger.log(Level.SEVERE, "Failed to create dump:", ex);
|
||||
|
||||
@@ -0,0 +1,268 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2017 Dan Mulloy
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
package com.comphenix.protocol;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.*;
|
||||
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
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.google.common.base.Charsets;
|
||||
|
||||
import org.apache.commons.io.HexDump;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Logs packets to a given stream
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class PacketLogging implements CommandExecutor, PacketListener {
|
||||
public static final String NAME = "packetlog";
|
||||
|
||||
private List<PacketType> sendingTypes = new ArrayList<>();
|
||||
private List<PacketType> receivingTypes = new ArrayList<>();
|
||||
|
||||
private ListeningWhitelist sendingWhitelist;
|
||||
private ListeningWhitelist receivingWhitelist;
|
||||
|
||||
private Logger fileLogger;
|
||||
private LogLocation location = LogLocation.FILE;
|
||||
|
||||
private final ProtocolManager manager;
|
||||
private final Plugin plugin;
|
||||
|
||||
PacketLogging(Plugin plugin, ProtocolManager manager) {
|
||||
this.plugin = plugin;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
PacketType type = null;
|
||||
|
||||
try {
|
||||
if (args.length > 2) {
|
||||
Protocol protocol;
|
||||
|
||||
try {
|
||||
protocol = Protocol.valueOf(args[0].toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Unknown protocol " + args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
Sender pSender;
|
||||
|
||||
try {
|
||||
pSender = Sender.valueOf(args[1].toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Unknown sender: " + args[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
try { // Try IDs first
|
||||
int id = Integer.parseInt(args[2]);
|
||||
type = PacketType.findCurrent(protocol, pSender, id);
|
||||
} catch (NumberFormatException ex) { // Check packet names
|
||||
String name = args[2];
|
||||
for (PacketType packet : PacketType.values()) {
|
||||
if (packet.getProtocol() == protocol && packet.getSender() == pSender) {
|
||||
if (packet.name().equalsIgnoreCase(name)) {
|
||||
type = packet;
|
||||
break;
|
||||
}
|
||||
for (String className : packet.getClassNames()) {
|
||||
if (className.equalsIgnoreCase(name)) {
|
||||
type = packet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException ex) { // RIP
|
||||
type = null;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
sender.sendMessage(ChatColor.RED + "Unknown packet: " + args[2]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length > 3) {
|
||||
if (args[3].equalsIgnoreCase("console")) {
|
||||
this.location = LogLocation.CONSOLE;
|
||||
} else {
|
||||
this.location = LogLocation.FILE;
|
||||
}
|
||||
}
|
||||
|
||||
if (pSender == Sender.CLIENT) {
|
||||
if (receivingTypes.contains(type)) {
|
||||
receivingTypes.remove(type);
|
||||
} else {
|
||||
receivingTypes.add(type);
|
||||
}
|
||||
} else {
|
||||
if (sendingTypes.contains(type)) {
|
||||
sendingTypes.remove(type);
|
||||
} else {
|
||||
sendingTypes.add(type);
|
||||
}
|
||||
}
|
||||
|
||||
startLogging();
|
||||
sender.sendMessage(ChatColor.GREEN + "Now logging " + type.getPacketClass().getSimpleName());
|
||||
return true;
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.RED + "Invalid syntax: /packetlog <protocol> <sender> <packet> [location]");
|
||||
return true;
|
||||
} catch (Throwable ex) {
|
||||
sender.sendMessage(ChatColor.RED + "Failed to parse command: " + ex.toString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void startLogging() {
|
||||
manager.removePacketListener(this);
|
||||
|
||||
if (sendingTypes.isEmpty() && receivingTypes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.sendingWhitelist = ListeningWhitelist.newBuilder().types(sendingTypes).build();
|
||||
this.receivingWhitelist = ListeningWhitelist.newBuilder().types(receivingTypes).build();
|
||||
|
||||
// Setup the file logger if it hasn't been already
|
||||
if (location == LogLocation.FILE && fileLogger == null) {
|
||||
fileLogger = Logger.getLogger("ProtocolLib-FileLogging");
|
||||
|
||||
for (Handler handler : fileLogger.getHandlers())
|
||||
fileLogger.removeHandler(handler);
|
||||
fileLogger.setUseParentHandlers(false);
|
||||
|
||||
try {
|
||||
File logFile = new File(plugin.getDataFolder(), "log.log");
|
||||
FileHandler handler = new FileHandler(logFile.getAbsolutePath(), true);
|
||||
handler.setFormatter(new LogFormatter());
|
||||
fileLogger.addHandler(handler);
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to obtain log file:", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
manager.addPacketListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
log(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
log(event);
|
||||
}
|
||||
|
||||
// Here's where the magic happens
|
||||
|
||||
private static String hexDump(byte[] bytes) throws IOException {
|
||||
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||||
HexDump.dump(bytes, 0, output, 0);
|
||||
return new String(output.toByteArray(), Charsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
private void log(PacketEvent event) {
|
||||
try {
|
||||
byte[] bytes = WirePacket.bytesFromPacket(event.getPacket());
|
||||
String hexDump = hexDump(bytes);
|
||||
|
||||
if (location == LogLocation.FILE) {
|
||||
fileLogger.log(Level.INFO, event.getPacketType() + ":");
|
||||
fileLogger.log(Level.INFO, hexDump);
|
||||
fileLogger.log(Level.INFO, "");
|
||||
} else {
|
||||
System.out.println(event.getPacketType() + ":");
|
||||
System.out.println(hexDump);
|
||||
System.out.println();
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to log packet " + event.getPacketType() + ":", ex);
|
||||
plugin.getLogger().log(Level.WARNING, "Clearing packet logger...");
|
||||
|
||||
sendingTypes.clear();
|
||||
receivingTypes.clear();
|
||||
startLogging();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListeningWhitelist getSendingWhitelist() {
|
||||
return sendingWhitelist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListeningWhitelist getReceivingWhitelist() {
|
||||
return receivingWhitelist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
private enum LogLocation {
|
||||
CONSOLE, FILE
|
||||
}
|
||||
|
||||
private static class LogFormatter extends Formatter {
|
||||
private static final SimpleDateFormat DATE = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
private static final String FORMAT = "[{0}] {1}";
|
||||
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
String string = formatMessage(record);
|
||||
if (string.isEmpty()) {
|
||||
return LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
message.append(MessageFormat.format(FORMAT, DATE.format(record.getMillis()), string));
|
||||
message.append(LINE_SEPARATOR);
|
||||
return message.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,8 @@ public class ProtocolLib extends JavaPlugin {
|
||||
private enum ProtocolCommand {
|
||||
FILTER,
|
||||
PACKET,
|
||||
PROTOCOL
|
||||
PROTOCOL,
|
||||
LOGGING;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,6 +143,7 @@ public class ProtocolLib extends JavaPlugin {
|
||||
private CommandProtocol commandProtocol;
|
||||
private CommandPacket commandPacket;
|
||||
private CommandFilter commandFilter;
|
||||
private PacketLogging packetLogging;
|
||||
|
||||
// Whether or not disable is not needed
|
||||
private boolean skipDisable;
|
||||
@@ -149,11 +151,9 @@ public class ProtocolLib extends JavaPlugin {
|
||||
@Override
|
||||
public void onLoad() {
|
||||
// Logging
|
||||
logger = getLoggerSafely();
|
||||
logger = getLogger();
|
||||
ProtocolLogger.init(this);
|
||||
|
||||
Application.registerPrimaryThread();
|
||||
|
||||
// Initialize enhancer factory
|
||||
EnhancerFactory.getInstance().setClassLoader(getClassLoader());
|
||||
|
||||
@@ -237,8 +237,6 @@ public class ProtocolLib extends JavaPlugin {
|
||||
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
reporter.reportDetailed(this, Report.newBuilder(REPORT_PLUGIN_LOAD_ERROR).error(e).callerParam(protocolManager));
|
||||
disablePlugin();
|
||||
@@ -262,11 +260,12 @@ public class ProtocolLib extends JavaPlugin {
|
||||
case PACKET:
|
||||
commandPacket = new CommandPacket(reporter, this, logger, commandFilter, protocolManager);
|
||||
break;
|
||||
case LOGGING:
|
||||
packetLogging = new PacketLogging(this, protocolManager);
|
||||
break;
|
||||
}
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (LinkageError e) {
|
||||
logger.warning("Failed to register command " + command.name() + ": " + e);
|
||||
} catch (Throwable e) {
|
||||
@@ -397,6 +396,7 @@ public class ProtocolLib extends JavaPlugin {
|
||||
registerCommand(CommandProtocol.NAME, commandProtocol);
|
||||
registerCommand(CommandPacket.NAME, commandPacket);
|
||||
registerCommand(CommandFilter.NAME, commandFilter);
|
||||
registerCommand(PacketLogging.NAME, packetLogging);
|
||||
|
||||
// Player login and logout events
|
||||
protocolManager.registerEvents(manager, this);
|
||||
@@ -406,8 +406,6 @@ public class ProtocolLib extends JavaPlugin {
|
||||
createPacketTask(server);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
reporter.reportDetailed(this, Report.newBuilder(REPORT_PLUGIN_ENABLE_ERROR).error(e));
|
||||
disablePlugin();
|
||||
@@ -421,8 +419,6 @@ public class ProtocolLib extends JavaPlugin {
|
||||
}
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
reporter.reportDetailed(this, Report.newBuilder(REPORT_METRICS_IO_ERROR).error(e).callerParam(statistics));
|
||||
} catch (Throwable e) {
|
||||
@@ -489,7 +485,7 @@ public class ProtocolLib extends JavaPlugin {
|
||||
|
||||
File[] candidates = pluginFolder.listFiles();
|
||||
if (candidates != null) {
|
||||
for (File candidate : pluginFolder.listFiles()) {
|
||||
for (File candidate : candidates) {
|
||||
if (candidate.isFile() && !candidate.equals(loadedFile)) {
|
||||
Matcher match = ourPlugin.matcher(candidate.getName());
|
||||
if (match.matches()) {
|
||||
@@ -572,8 +568,6 @@ public class ProtocolLib extends JavaPlugin {
|
||||
}, ASYNC_MANAGER_DELAY, ASYNC_MANAGER_DELAY);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
if (packetTask == -1) {
|
||||
reporter.reportDetailed(this, Report.newBuilder(REPORT_CANNOT_CREATE_TIMEOUT_TASK).error(e));
|
||||
@@ -650,26 +644,6 @@ public class ProtocolLib extends JavaPlugin {
|
||||
reporter = new BasicErrorReporter();
|
||||
}
|
||||
|
||||
// Get the Bukkit logger first, before we try to create our own
|
||||
private Logger getLoggerSafely() {
|
||||
Logger log = null;
|
||||
|
||||
try {
|
||||
log = getLogger();
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Use the default logger instead
|
||||
if (log == null)
|
||||
log = Logger.getLogger("Minecraft");
|
||||
return log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the metrics instance used to measure users of this library.
|
||||
* <p>
|
||||
|
||||
+10
-3
@@ -63,10 +63,14 @@ class EntityUtilities {
|
||||
*/
|
||||
|
||||
public static void updateEntity(Entity entity, List<Player> observers) throws FieldAccessException {
|
||||
if (entity == null || !entity.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
|
||||
if (trackerEntry == null) {
|
||||
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + (entity.isDead() ? " - entity is dead." : "."));
|
||||
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + ".");
|
||||
}
|
||||
|
||||
if (trackedPlayersField == null) {
|
||||
@@ -106,12 +110,16 @@ class EntityUtilities {
|
||||
* @throws FieldAccessException If reflection failed.
|
||||
*/
|
||||
public static List<Player> getEntityTrackers(Entity entity) {
|
||||
if (entity == null || !entity.isValid()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
try {
|
||||
List<Player> result = new ArrayList<Player>();
|
||||
|
||||
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
|
||||
if (trackerEntry == null) {
|
||||
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + (entity.isDead() ? " - entity is dead." : "."));
|
||||
throw new IllegalArgumentException("Cannot find entity trackers for " + entity + ".");
|
||||
}
|
||||
|
||||
if (trackedPlayersField == null) {
|
||||
@@ -230,7 +238,6 @@ class EntityUtilities {
|
||||
}
|
||||
|
||||
private static List<Object> unwrapBukkit(List<Player> players) {
|
||||
|
||||
List<Object> output = Lists.newArrayList();
|
||||
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
|
||||
|
||||
|
||||
+49
-183
@@ -17,22 +17,46 @@
|
||||
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
import com.comphenix.protocol.AsynchronousManager;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.async.AsyncFilterManager;
|
||||
import com.comphenix.protocol.async.AsyncMarker;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.events.*;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolInjector;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
import com.comphenix.protocol.injector.packet.InterceptWritePacket;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjector;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjectorBuilder;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler.ConflictStrategy;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjector.ServerHandlerNull;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectorBuilder;
|
||||
import com.comphenix.protocol.injector.spigot.SpigotPacketInjector;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.utility.Util;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
@@ -50,46 +74,6 @@ import org.bukkit.event.server.PluginDisableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import com.comphenix.protocol.AsynchronousManager;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.async.AsyncFilterManager;
|
||||
import com.comphenix.protocol.async.AsyncMarker;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.events.ConnectionSide;
|
||||
import com.comphenix.protocol.events.ListenerOptions;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||
import com.comphenix.protocol.events.NetworkMarker;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolInjector;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
import com.comphenix.protocol.injector.packet.InterceptWritePacket;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjector;
|
||||
import com.comphenix.protocol.injector.packet.PacketInjectorBuilder;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler.ConflictStrategy;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjector.ServerHandlerNull;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectorBuilder;
|
||||
import com.comphenix.protocol.injector.spigot.SpigotPacketInjector;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.utility.EnhancerFactory;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.utility.Util;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
public final class PacketFilterManager implements ListenerInvoker, InternalManager {
|
||||
|
||||
public static final ReportType REPORT_CANNOT_LOAD_PACKET_LIST = new ReportType("Cannot load server and client packet list.");
|
||||
@@ -99,8 +83,8 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
new ReportType("%s doesn't depend on ProtocolLib. Check that its plugin.yml has a 'depend' directive.");
|
||||
|
||||
// Registering packet IDs that are not supported
|
||||
public static final ReportType REPORT_UNSUPPORTED_SERVER_PACKET_ID = new ReportType("[%s] Unsupported server packet ID in current Minecraft version: %s");
|
||||
public static final ReportType REPORT_UNSUPPORTED_CLIENT_PACKET_ID = new ReportType("[%s] Unsupported client packet ID in current Minecraft version: %s");
|
||||
public static final ReportType REPORT_UNSUPPORTED_SERVER_PACKET = new ReportType("[%s] Unsupported server packet in current Minecraft version: %s");
|
||||
public static final ReportType REPORT_UNSUPPORTED_CLIENT_PACKET = new ReportType("[%s] Unsupported client packet in current Minecraft version: %s");
|
||||
|
||||
// Problems injecting and uninjecting players
|
||||
public static final ReportType REPORT_CANNOT_UNINJECT_PLAYER = new ReportType("Unable to uninject net handler for player.");
|
||||
@@ -226,8 +210,6 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
this.pluginVerifier = new PluginVerifier(builder.getLibrary());
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw e;
|
||||
} catch (ThreadDeath e) {
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
reporter.reportWarning(this, Report.newBuilder(REPORT_PLUGIN_VERIFIER_ERROR).
|
||||
messageParam(e.getMessage()).error(e));
|
||||
@@ -453,9 +435,7 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
|
||||
// We only check the recieving whitelist
|
||||
if (whitelist.getOptions().contains(ListenerOptions.INTERCEPT_INPUT_BUFFER)) {
|
||||
for (PacketType type : whitelist.getTypes()) {
|
||||
updated.add(type);
|
||||
}
|
||||
updated.addAll(whitelist.getTypes());
|
||||
}
|
||||
}
|
||||
// Update it
|
||||
@@ -630,7 +610,6 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
* Note that all packets are disabled by default.
|
||||
*
|
||||
* @param listener - the listener that requested to enable these filters.
|
||||
* @param side - which side the event will arrive from.
|
||||
* @param packets - the packet id(s).
|
||||
*/
|
||||
private void enablePacketFilters(PacketListener listener, Iterable<PacketType> packets) {
|
||||
@@ -645,7 +624,7 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
playerInjection.addPacketHandler(type, listener.getSendingWhitelist().getOptions());
|
||||
else
|
||||
reporter.reportWarning(this,
|
||||
Report.newBuilder(REPORT_UNSUPPORTED_SERVER_PACKET_ID).messageParam(PacketAdapter.getPluginName(listener), type)
|
||||
Report.newBuilder(REPORT_UNSUPPORTED_SERVER_PACKET).messageParam(PacketAdapter.getPluginName(listener), type)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -655,7 +634,7 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
packetInjector.addPacketHandler(type, listener.getReceivingWhitelist().getOptions());
|
||||
else
|
||||
reporter.reportWarning(this,
|
||||
Report.newBuilder(REPORT_UNSUPPORTED_CLIENT_PACKET_ID).messageParam(PacketAdapter.getPluginName(listener), type)
|
||||
Report.newBuilder(REPORT_UNSUPPORTED_CLIENT_PACKET).messageParam(PacketAdapter.getPluginName(listener), type)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -781,7 +760,7 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
|
||||
if (!filters) {
|
||||
// We may have to delay the packet due to non-asynchronous monitor listeners
|
||||
if (!filters && !Bukkit.isPrimaryThread() && playerInjection.hasMainThreadListener(packet.getType())) {
|
||||
if (!Bukkit.isPrimaryThread() && playerInjection.hasMainThreadListener(packet.getType())) {
|
||||
final NetworkMarker copy = marker;
|
||||
|
||||
server.getScheduler().scheduleSyncDelayedTask(library, new Runnable() {
|
||||
@@ -990,40 +969,34 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
if (nettyInjector != null)
|
||||
nettyInjector.inject();
|
||||
|
||||
try {
|
||||
manager.registerEvents(new Listener() {
|
||||
manager.registerEvents(new Listener() {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent event) {
|
||||
PacketFilterManager.this.onPlayerLogin(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPrePlayerJoin(PlayerJoinEvent event) {
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPrePlayerJoin(PlayerJoinEvent event) {
|
||||
PacketFilterManager.this.onPrePlayerJoin(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
PacketFilterManager.this.onPlayerJoin(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
PacketFilterManager.this.onPlayerQuit(event);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPluginDisabled(PluginDisableEvent event) {
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPluginDisabled(PluginDisableEvent event) {
|
||||
PacketFilterManager.this.onPluginDisabled(event, plugin);
|
||||
}
|
||||
|
||||
}, plugin);
|
||||
|
||||
} catch (NoSuchMethodError e) {
|
||||
// Oh wow! We're running on 1.0.0 or older.
|
||||
registerOld(manager, plugin);
|
||||
}
|
||||
}, plugin);
|
||||
}
|
||||
|
||||
private void onPlayerLogin(PlayerLoginEvent event) {
|
||||
@@ -1132,113 +1105,6 @@ public final class PacketFilterManager implements ListenerInvoker, InternalManag
|
||||
return PacketRegistry.getPacketClassFromID(packetID, forceVanilla);
|
||||
}
|
||||
|
||||
// Yes, this is crazy.
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void registerOld(PluginManager manager, final Plugin plugin) {
|
||||
try {
|
||||
ClassLoader loader = manager.getClass().getClassLoader();
|
||||
|
||||
// The different enums we are going to need
|
||||
Class eventTypes = loader.loadClass("org.bukkit.event.Event$Type");
|
||||
Class eventPriority = loader.loadClass("org.bukkit.event.Event$Priority");
|
||||
|
||||
// Get the priority
|
||||
Object priorityLowest = Enum.valueOf(eventPriority, "Lowest");
|
||||
Object priorityMonitor = Enum.valueOf(eventPriority, "Monitor");
|
||||
|
||||
// Get event types
|
||||
Object playerJoinType = Enum.valueOf(eventTypes, "PLAYER_JOIN");
|
||||
Object playerQuitType = Enum.valueOf(eventTypes, "PLAYER_QUIT");
|
||||
Object pluginDisabledType = Enum.valueOf(eventTypes, "PLUGIN_DISABLE");
|
||||
|
||||
// The player listener! Good times.
|
||||
Class<?> playerListener = loader.loadClass("org.bukkit.event.player.PlayerListener");
|
||||
Class<?> serverListener = loader.loadClass("org.bukkit.event.server.ServerListener");
|
||||
|
||||
// Find the register event method
|
||||
Method registerEvent = FuzzyReflection.fromObject(manager).getMethodByParameters("registerEvent",
|
||||
eventTypes, Listener.class, eventPriority, Plugin.class);
|
||||
|
||||
Enhancer playerLow = EnhancerFactory.getInstance().createEnhancer();
|
||||
Enhancer playerEx = EnhancerFactory.getInstance().createEnhancer();
|
||||
Enhancer serverEx = EnhancerFactory.getInstance().createEnhancer();
|
||||
|
||||
playerLow.setSuperclass(playerListener);
|
||||
playerLow.setClassLoader(classLoader);
|
||||
playerLow.setCallback(new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
|
||||
throws Throwable {
|
||||
// Must have a parameter
|
||||
if (args.length == 1) {
|
||||
Object event = args[0];
|
||||
|
||||
if (event instanceof PlayerJoinEvent) {
|
||||
onPrePlayerJoin((PlayerJoinEvent) event);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
playerEx.setSuperclass(playerListener);
|
||||
playerEx.setClassLoader(classLoader);
|
||||
playerEx.setCallback(new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
if (args.length == 1) {
|
||||
Object event = args[0];
|
||||
|
||||
// Check for the correct event
|
||||
if (event instanceof PlayerJoinEvent) {
|
||||
onPlayerJoin((PlayerJoinEvent) event);
|
||||
} else if (event instanceof PlayerQuitEvent) {
|
||||
onPlayerQuit((PlayerQuitEvent) event);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
serverEx.setSuperclass(serverListener);
|
||||
serverEx.setClassLoader(classLoader);
|
||||
serverEx.setCallback(new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args,
|
||||
MethodProxy proxy) throws Throwable {
|
||||
// Must have a parameter
|
||||
if (args.length == 1) {
|
||||
Object event = args[0];
|
||||
|
||||
if (event instanceof PluginDisableEvent)
|
||||
onPluginDisabled((PluginDisableEvent) event, plugin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
// Create our listener
|
||||
Object playerProxyLow = playerLow.create();
|
||||
Object playerProxy = playerEx.create();
|
||||
Object serverProxy = serverEx.create();
|
||||
|
||||
registerEvent.invoke(manager, playerJoinType, playerProxyLow, priorityLowest, plugin);
|
||||
registerEvent.invoke(manager, playerJoinType, playerProxy, priorityMonitor, plugin);
|
||||
registerEvent.invoke(manager, playerQuitType, playerProxy, priorityMonitor, plugin);
|
||||
registerEvent.invoke(manager, pluginDisabledType, serverProxy, priorityMonitor, plugin);
|
||||
|
||||
// A lot can go wrong
|
||||
} catch (ClassNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet.
|
||||
* @return An immutable set of every known server packet.
|
||||
|
||||
+38
-30
@@ -16,19 +16,6 @@
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import io.netty.util.internal.TypeParameterMatcher;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
@@ -55,7 +42,6 @@ import com.comphenix.protocol.events.ConnectionSide;
|
||||
import com.comphenix.protocol.events.NetworkMarker;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.NetworkProcessor;
|
||||
import com.comphenix.protocol.injector.netty.WirePacket;
|
||||
import com.comphenix.protocol.injector.server.SocketInjector;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.VolatileField;
|
||||
@@ -70,6 +56,20 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.MapMaker;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.MessageToByteEncoder;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
import io.netty.util.internal.TypeParameterMatcher;
|
||||
|
||||
/**
|
||||
* Represents a channel injector.
|
||||
* @author Kristian
|
||||
@@ -90,6 +90,10 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
private static Class<?> PACKET_LOGIN_CLIENT = null;
|
||||
private static FieldAccessor LOGIN_GAME_PROFILE = null;
|
||||
|
||||
// Versioning
|
||||
private static Class<?> PACKET_SET_PROTOCOL = null;
|
||||
private static AttributeKey<Integer> PROTOCOL_KEY = AttributeKey.valueOf("PROTOCOL");
|
||||
|
||||
// Saved accessors
|
||||
private static MethodAccessor DECODE_BUFFER;
|
||||
private static MethodAccessor ENCODE_BUFFER;
|
||||
@@ -98,9 +102,6 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
// For retrieving the protocol
|
||||
private static FieldAccessor PROTOCOL_ACCESSOR;
|
||||
|
||||
// For retrieving the protocol version
|
||||
private static MethodAccessor PROTOCOL_VERSION;
|
||||
|
||||
// The factory that created this injector
|
||||
private InjectionFactory factory;
|
||||
|
||||
@@ -185,19 +186,8 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
*/
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
MethodAccessor accessor = PROTOCOL_VERSION;
|
||||
if (accessor == null) {
|
||||
try {
|
||||
accessor = Accessors.getMethodAccessor(networkManager.getClass(), "getVersion");
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
}
|
||||
|
||||
if (accessor != null) {
|
||||
return (Integer) accessor.invoke(networkManager);
|
||||
} else {
|
||||
return MinecraftProtocolVersion.getCurrentVersion();
|
||||
}
|
||||
Integer value = originalChannel.attr(PROTOCOL_KEY).get();
|
||||
return value != null ? value : MinecraftProtocolVersion.getCurrentVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -603,6 +593,24 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
|
||||
// Save the channel injector
|
||||
factory.cacheInjector(profile.getName(), this);
|
||||
}
|
||||
|
||||
if (PACKET_SET_PROTOCOL == null) {
|
||||
try {
|
||||
PACKET_SET_PROTOCOL = PacketType.Handshake.Client.SET_PROTOCOL.getPacketClass();
|
||||
} 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);
|
||||
originalChannel.attr(PROTOCOL_KEY).set(protocol);
|
||||
} catch (Throwable ex) {
|
||||
// Oh well
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+27
-9
@@ -16,6 +16,15 @@
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelConfig;
|
||||
@@ -28,15 +37,6 @@ import io.netty.channel.EventLoop;
|
||||
import io.netty.util.Attribute;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
public abstract class ChannelProxy implements Channel {
|
||||
// Mark that a certain object does not contain a message field
|
||||
private static final FieldAccessor MARK_NO_MESSAGE = new FieldAccessor() {
|
||||
@@ -331,4 +331,22 @@ public abstract class ChannelProxy implements Channel {
|
||||
public int compareTo(Channel o) {
|
||||
return delegate.compareTo(o);
|
||||
}
|
||||
|
||||
/* Added in Netty 4.1, seem to be unused
|
||||
public long bytesBeforeUnwritable() {
|
||||
return delegate.bytesBeforeUnwritable();
|
||||
}
|
||||
|
||||
public long bytesBeforeWritable() {
|
||||
return delegate.bytesBeforeWritable();
|
||||
}
|
||||
|
||||
public ChannelId id() {
|
||||
return delegate.id();
|
||||
}
|
||||
|
||||
public <T> boolean hasAttr(AttributeKey<T> key) {
|
||||
return delegate.hasAttr(key);
|
||||
}
|
||||
*/
|
||||
}
|
||||
+6
@@ -256,4 +256,10 @@ abstract class EventLoopProxy implements EventLoop {
|
||||
public List<Runnable> shutdownNow() {
|
||||
return getDelegate().shutdownNow();
|
||||
}
|
||||
|
||||
/*
|
||||
public ChannelFuture register(ChannelPromise promise) {
|
||||
return getDelegate().register(promise);
|
||||
}
|
||||
*/
|
||||
}
|
||||
+28
-6
@@ -16,6 +16,12 @@
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@@ -24,12 +30,6 @@ import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* A pipeline proxy.
|
||||
* @author Kristian
|
||||
@@ -368,4 +368,26 @@ public class PipelineProxy implements ChannelPipeline {
|
||||
public ChannelFuture writeAndFlush(Object arg0) {
|
||||
return pipeline.writeAndFlush(arg0);
|
||||
}
|
||||
|
||||
/* Added in Netty 4.1, seem to be unused
|
||||
public ChannelFuture newFailedFuture(Throwable ex) {
|
||||
return pipeline.newFailedFuture(ex);
|
||||
}
|
||||
|
||||
public ChannelProgressivePromise newProgressivePromise() {
|
||||
return pipeline.newProgressivePromise();
|
||||
}
|
||||
|
||||
public ChannelPromise newPromise() {
|
||||
return pipeline.newPromise();
|
||||
}
|
||||
|
||||
public ChannelFuture newSucceededFuture() {
|
||||
return pipeline.newSucceededFuture();
|
||||
}
|
||||
|
||||
public ChannelPromise voidPromise() {
|
||||
return pipeline.voidPromise();
|
||||
}
|
||||
*/
|
||||
}
|
||||
+49
-20
@@ -16,18 +16,11 @@
|
||||
*/
|
||||
package com.comphenix.protocol.injector.netty;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -36,6 +29,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.concurrency.PacketTypeSet;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
@@ -55,8 +49,17 @@ import com.comphenix.protocol.injector.spigot.AbstractPlayerHandler;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.VolatileField;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
|
||||
public class ProtocolInjector implements ChannelListener {
|
||||
public static final ReportType REPORT_CANNOT_INJECT_INCOMING_CHANNEL = new ReportType("Unable to inject incoming channel %s.");
|
||||
|
||||
@@ -130,23 +133,32 @@ public class ProtocolInjector implements ChannelListener {
|
||||
if (serverConnection != null) {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Try the next though
|
||||
e.printStackTrace();
|
||||
} catch (Exception ex) {
|
||||
ProtocolLogger.debug("Encountered an exception invoking " + method, ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (serverConnection == null) {
|
||||
throw new ReflectiveOperationException("Failed to obtain server connection");
|
||||
}
|
||||
|
||||
// Handle connected channels
|
||||
final ChannelInboundHandler endInitProtocol = new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
protected void initChannel(Channel channel) throws Exception {
|
||||
protected void initChannel(final Channel channel) throws Exception {
|
||||
try {
|
||||
// This can take a while, so we need to stop the main thread from interfering
|
||||
synchronized (networkManagers) {
|
||||
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject();
|
||||
// For some reason it needs to be delayed on 1.12, but the delay breaks 1.11 and below
|
||||
// TODO I see this more as a temporary hotfix than a permanent solution
|
||||
if (MinecraftVersion.getCurrentVersion().getMinor() >= 12) {
|
||||
channel.eventLoop().submit(() ->
|
||||
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject());
|
||||
} else {
|
||||
injectionFactory.fromChannel(channel, ProtocolInjector.this, playerFactory).inject();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(e));
|
||||
} catch (Exception ex) {
|
||||
reporter.reportDetailed(ProtocolInjector.this, Report.newBuilder(REPORT_CANNOT_INJECT_INCOMING_CHANNEL).messageParam(channel).error(ex));
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -171,9 +183,27 @@ public class ProtocolInjector implements ChannelListener {
|
||||
ctx.fireChannelRead(msg);
|
||||
}
|
||||
};
|
||||
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromObject(serverConnection, true);
|
||||
|
||||
// Get the current NetworkMananger list
|
||||
networkManagers = (List<Object>) FuzzyReflection.fromObject(serverConnection, true).invokeMethod(null, "getNetworkManagers", List.class, serverConnection);
|
||||
try {
|
||||
Field field = fuzzy.getParameterizedField(List.class, MinecraftReflection.getNetworkManagerClass());
|
||||
field.setAccessible(true);
|
||||
|
||||
networkManagers = (List<Object>) field.get(serverConnection);
|
||||
} catch (Exception ex) {
|
||||
ProtocolLogger.debug("Encountered an exception checking list fields", ex);
|
||||
|
||||
Method method = fuzzy.getMethodByParameters("getNetworkManagers", List.class,
|
||||
new Class<?>[] { serverConnection.getClass() });
|
||||
method.setAccessible(true);
|
||||
|
||||
networkManagers = (List<Object>) method.invoke(null, serverConnection);
|
||||
}
|
||||
|
||||
if (networkManagers == null) {
|
||||
throw new ReflectiveOperationException("Failed to obtain list of network managers");
|
||||
}
|
||||
|
||||
// Insert ProtocolLib's connection interceptor
|
||||
bootstrapFields = getBootstrapFields(serverConnection);
|
||||
@@ -191,7 +221,6 @@ public class ProtocolInjector implements ChannelListener {
|
||||
}
|
||||
|
||||
injected = true;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Unable to inject channel futures.", e);
|
||||
}
|
||||
@@ -352,7 +381,7 @@ public class ProtocolInjector implements ChannelListener {
|
||||
|
||||
@Override
|
||||
public void addPacketHandler(PacketType type, Set<ListenerOptions> options) {
|
||||
if (options != null && !type.forceAsync() && !options.contains(ListenerOptions.ASYNC))
|
||||
if (!type.isAsyncForced() && (options == null || !options.contains(ListenerOptions.ASYNC)))
|
||||
mainThreadFilters.addType(type);
|
||||
super.addPacketHandler(type, options);
|
||||
}
|
||||
|
||||
@@ -27,34 +27,24 @@
|
||||
*/
|
||||
package com.comphenix.protocol.metrics;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.*;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.comphenix.protocol.utility.Util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
|
||||
import com.comphenix.protocol.utility.Util;
|
||||
import com.comphenix.protocol.utility.WrappedScheduler;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
@@ -116,7 +106,7 @@ public class Metrics {
|
||||
/**
|
||||
* The scheduled task
|
||||
*/
|
||||
private volatile WrappedScheduler.TaskWrapper task = null;
|
||||
private volatile BukkitTask task;
|
||||
|
||||
public Metrics(final Plugin plugin) throws IOException {
|
||||
if (plugin == null) {
|
||||
@@ -200,8 +190,7 @@ public class Metrics {
|
||||
}
|
||||
|
||||
// Begin hitting the server with glorious data
|
||||
task = WrappedScheduler.runAsynchronouslyRepeat(plugin, new Runnable() {
|
||||
|
||||
task = new BukkitRunnable() {
|
||||
private boolean firstPost = true;
|
||||
|
||||
@Override
|
||||
@@ -234,8 +223,7 @@ public class Metrics {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, PING_INTERVAL * 1200);
|
||||
|
||||
}.runTaskTimerAsynchronously(plugin, 0, PING_INTERVAL * 1200);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,11 +354,12 @@ public class BukkitUpdater extends Updater {
|
||||
this.plugin.getLogger().warning("Please double-check your configuration to ensure it is correct.");
|
||||
this.result = UpdateResult.FAIL_APIKEY;
|
||||
} else {
|
||||
this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
|
||||
this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||
// People don't care
|
||||
// this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
|
||||
// this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||
this.result = UpdateResult.FAIL_DBO;
|
||||
}
|
||||
e.printStackTrace();
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
@@ -75,7 +74,8 @@ public final class SpigotUpdater extends Updater {
|
||||
ProtocolLibrary.getErrorReporter().reportDetailed(
|
||||
SpigotUpdater.this, Report.newBuilder(REPORT_CANNOT_UPDATE_PLUGIN).error(ex).callerParam(this));
|
||||
} else {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to check for updates: " + ex);
|
||||
// People don't care
|
||||
// plugin.getLogger().log(Level.WARNING, "Failed to check for updates: " + ex);
|
||||
}
|
||||
|
||||
ProtocolLibrary.disableUpdates();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
name: ProtocolLib
|
||||
#version: ${project.version}${project.build.number}
|
||||
version: ${project.version}
|
||||
version: ${project.fullVersion}
|
||||
description: Provides read/write access to the Minecraft protocol.
|
||||
authors: [dmulloy2, comphenix]
|
||||
|
||||
@@ -25,6 +24,11 @@ commands:
|
||||
aliases: [packet_filter]
|
||||
permission: protocol.admin
|
||||
permission-message: You don't have <permission>
|
||||
packetlog:
|
||||
description: Logs hex representations of packets to a file or console
|
||||
usage: /<command> <protocol> <sender> <packet> [location]
|
||||
permission: protocol.admin
|
||||
permission-message: You don't have <permission>
|
||||
|
||||
permissions:
|
||||
protocol.*:
|
||||
|
||||
@@ -5,18 +5,18 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.DispenserRegistry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.inventory.CraftItemFactory;
|
||||
import org.bukkit.craftbukkit.v1_10_R1.util.Versioning;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemFactory;
|
||||
import org.bukkit.craftbukkit.v1_12_R1.util.Versioning;
|
||||
|
||||
import com.comphenix.protocol.utility.Constants;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.DispenserRegistry;
|
||||
|
||||
/**
|
||||
* Used to ensure that ProtocolLib and Bukkit is prepared to be tested.
|
||||
*
|
||||
@@ -52,8 +52,6 @@ public class BukkitInitialization {
|
||||
|
||||
// Inject this fake server
|
||||
Bukkit.setServer(mockedServer);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +63,7 @@ public class BukkitInitialization {
|
||||
packaged = true;
|
||||
|
||||
MinecraftReflection.setMinecraftPackage(Constants.NMS, Constants.OBC);
|
||||
MinecraftVersion.setCurrentVersion(MinecraftVersion.FROSTBURN_UPDATE);
|
||||
MinecraftVersion.setCurrentVersion(MinecraftVersion.COLOR_UPDATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +1,38 @@
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.EnumProtocol;
|
||||
import net.minecraft.server.v1_12_R1.EnumProtocolDirection;
|
||||
import net.minecraft.server.v1_12_R1.PacketLoginInStart;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.PacketLoginInStart;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
@@ -54,22 +56,41 @@ public class PacketTypeTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ensureAllExist() {
|
||||
boolean missing = false;
|
||||
ProtocolRegistry registry = new NettyProtocolRegistry();
|
||||
Map<PacketType, Class<?>> lookup = registry.getPacketTypeLookup();
|
||||
for (Entry<PacketType, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = entry.getKey();
|
||||
Class<?> clazz = entry.getValue();
|
||||
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);
|
||||
}
|
||||
|
||||
if (type.isDynamic()) {
|
||||
System.err.println("Packet " + clazz + " does not have a corresponding PacketType!");
|
||||
missing = true;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void ensureTypesAreCorrect() throws Exception {
|
||||
boolean fail = false;
|
||||
|
||||
EnumProtocol[] protocols = EnumProtocol.values();
|
||||
for (EnumProtocol protocol : protocols) {
|
||||
Field field = EnumProtocol.class.getDeclaredField("h");
|
||||
field.setAccessible(true);
|
||||
|
||||
Map<EnumProtocolDirection, Map<Integer, Class<?>>> map = (Map<EnumProtocolDirection, Map<Integer, Class<?>>>) field.get(protocol);
|
||||
for (Entry<EnumProtocolDirection, Map<Integer, Class<?>>> entry : map.entrySet()) {
|
||||
Map<Integer, Class<?>> treeMap = new TreeMap<>(entry.getValue());
|
||||
for (Entry<Integer, Class<?>> entry1 : treeMap.entrySet()) {
|
||||
try {
|
||||
PacketType type = PacketType.fromClass(entry1.getValue());
|
||||
if (type.getCurrentId() != entry1.getKey())
|
||||
throw new IllegalStateException("Packet ID for " + type + " is incorrect. Expected " + entry1.getKey() + ", but got " + type.getCurrentId());
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
fail = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//assertFalse("Packet " + clazz + " does not have a corresponding PacketType!", type.isDynamic());
|
||||
}
|
||||
|
||||
assertFalse("There are packets that aren\'t accounted for!", missing);
|
||||
assertTrue("Packet type(s) were incorrect!", !fail);
|
||||
}
|
||||
}
|
||||
+23
-36
@@ -24,10 +24,21 @@ import static org.junit.Assert.fail;
|
||||
|
||||
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.UUID;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.AttributeModifier;
|
||||
import net.minecraft.server.v1_12_R1.DataWatcher;
|
||||
import net.minecraft.server.v1_12_R1.Entity;
|
||||
import net.minecraft.server.v1_12_R1.EntityLightning;
|
||||
import net.minecraft.server.v1_12_R1.MobEffect;
|
||||
import net.minecraft.server.v1_12_R1.MobEffectList;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutBoss;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
|
||||
import org.apache.commons.lang.SerializationUtils;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -66,16 +77,6 @@ import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.AttributeModifier;
|
||||
import net.minecraft.server.v1_10_R1.DataWatcher;
|
||||
import net.minecraft.server.v1_10_R1.Entity;
|
||||
import net.minecraft.server.v1_10_R1.EntityLightning;
|
||||
import net.minecraft.server.v1_10_R1.MobEffect;
|
||||
import net.minecraft.server.v1_10_R1.MobEffectList;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutBoss;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
|
||||
// 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.*" })
|
||||
@@ -203,7 +204,7 @@ public class PacketContainerTest {
|
||||
ItemStack item = itemWithData();
|
||||
|
||||
StructureModifier<ItemStack> items = windowClick.getItemModifier();
|
||||
assertNull(items.read(0));
|
||||
// assertNull(items.read(0));
|
||||
|
||||
// Insert the item and check if it's there
|
||||
items.write(0, item);
|
||||
@@ -220,31 +221,22 @@ public class PacketContainerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetItemArrayModifier() {
|
||||
public void testGetItemListModifier() {
|
||||
PacketContainer windowItems = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);
|
||||
StructureModifier<ItemStack[]> itemAccess = windowItems.getItemArrayModifier();
|
||||
StructureModifier<List<ItemStack>> itemAccess = windowItems.getItemListModifier();
|
||||
|
||||
ItemStack[] itemArray = new ItemStack[] {
|
||||
itemWithData(),
|
||||
new ItemStack(Material.DIAMOND_AXE)
|
||||
};
|
||||
List<ItemStack> items = new ArrayList<>();
|
||||
items.add(itemWithData());
|
||||
items.add(new ItemStack(Material.DIAMOND_AXE));
|
||||
|
||||
assertNull(itemAccess.read(0));
|
||||
|
||||
// Insert and check that it was succesful
|
||||
itemAccess.write(0, itemArray);
|
||||
itemAccess.write(0, items);
|
||||
|
||||
// Read back array
|
||||
ItemStack[] comparison = itemAccess.read(0);
|
||||
assertEquals(itemArray.length, comparison.length);
|
||||
|
||||
// Check that it is equivalent
|
||||
for (int i = 0; i < itemArray.length; i++) {
|
||||
ItemStack original = itemArray[i];
|
||||
ItemStack written = comparison[i];
|
||||
|
||||
assertTrue(String.format("Array element %s is not the same: %s != %s", i, original, written), equivalentItem(original, written));
|
||||
}
|
||||
List<ItemStack> comparison = itemAccess.read(0);
|
||||
assertEquals(items, comparison);
|
||||
}
|
||||
|
||||
private boolean equivalentItem(ItemStack first, ItemStack second) {
|
||||
@@ -553,7 +545,7 @@ public class PacketContainerTest {
|
||||
PacketContainer constructed = new PacketContainer(type);
|
||||
|
||||
if (!registered) {
|
||||
fail("Expected IllegalArgumentException(Packet " + type + " not registered");
|
||||
fail("Expected IllegalArgumentException(Packet " + type + " not registered)");
|
||||
}
|
||||
|
||||
// Initialize default values
|
||||
@@ -593,17 +585,12 @@ public class PacketContainerTest {
|
||||
// Something is very wrong
|
||||
throw e;
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
throw new RuntimeException("Failed to serialize packet " + type, e);
|
||||
} catch (Throwable ex) {
|
||||
throw new RuntimeException("Failed to serialize packet " + type, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPacketType() {
|
||||
assertEquals(PacketType.Legacy.Server.SET_CREATIVE_SLOT, PacketType.findLegacy(107, Sender.SERVER));
|
||||
}
|
||||
|
||||
// Convert to objects that support equals()
|
||||
private void testEquality(Object a, Object b) {
|
||||
if (a != null && b != null) {
|
||||
|
||||
@@ -13,6 +13,7 @@ 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;
|
||||
|
||||
@@ -29,6 +30,8 @@ public class WirePacketTest {
|
||||
@Test
|
||||
public void testPackets() {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.CHAT);
|
||||
packet.getChatTypes().write(0, ChatType.CHAT);
|
||||
|
||||
WirePacket wire = WirePacket.fromPacket(packet);
|
||||
WirePacket handle = WirePacket.fromPacket(packet.getHandle());
|
||||
assertEquals(wire, handle);
|
||||
|
||||
+22
@@ -1,14 +1,20 @@
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.ItemStack;
|
||||
import net.minecraft.server.v1_12_R1.NonNullList;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
|
||||
public class AggregateClonerTest {
|
||||
|
||||
@@ -22,4 +28,20 @@ public class AggregateClonerTest {
|
||||
List<Integer> input = Arrays.asList(1, 2, 3);
|
||||
assertEquals(input, AggregateCloner.DEFAULT.clone(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonNullList() {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);
|
||||
|
||||
NonNullList<ItemStack> list = NonNullList.a(16, ItemStack.a);
|
||||
packet.getModifier().write(1, list);
|
||||
|
||||
PacketContainer cloned = packet.deepClone();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
NonNullList<ItemStack> list1 = (NonNullList<ItemStack>) cloned.getModifier().read(1);
|
||||
|
||||
assertEquals(list.size(), list1.size());
|
||||
assertArrayEquals(list.toArray(), list1.toArray());
|
||||
}
|
||||
}
|
||||
@@ -23,21 +23,21 @@ public class UpdaterTest {
|
||||
private static final int BUKKIT_DEV_ID = 45564;
|
||||
private static Plugin plugin;
|
||||
|
||||
//@BeforeClass
|
||||
// @BeforeClass
|
||||
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.0.1-SNAPSHOT-b281";
|
||||
if (version == null) version = "4.2.1";
|
||||
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 testSpigotUpdater() {
|
||||
SpigotUpdater updater = new SpigotUpdater(plugin, UpdateType.NO_DOWNLOAD, true);
|
||||
|
||||
@@ -54,7 +54,7 @@ public class UpdaterTest {
|
||||
System.out.println("Update available: " + updater.versionCheck(remote));
|
||||
}
|
||||
|
||||
//@Test
|
||||
// @Test
|
||||
public void testBukkitUpdater() {
|
||||
BukkitUpdater updater = new BukkitUpdater(plugin, BUKKIT_DEV_ID, null, UpdateType.NO_DOWNLOAD, true);
|
||||
if (! updater.read()) {
|
||||
|
||||
+13
-13
@@ -5,6 +5,19 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.ChatComponentText;
|
||||
import net.minecraft.server.v1_12_R1.ChunkCoordIntPair;
|
||||
import net.minecraft.server.v1_12_R1.DataWatcher;
|
||||
import net.minecraft.server.v1_12_R1.IBlockData;
|
||||
import net.minecraft.server.v1_12_R1.IChatBaseComponent;
|
||||
import net.minecraft.server.v1_12_R1.IChatBaseComponent.ChatSerializer;
|
||||
import net.minecraft.server.v1_12_R1.NBTCompressedStreamTools;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
import net.minecraft.server.v1_12_R1.PlayerConnection;
|
||||
import net.minecraft.server.v1_12_R1.ServerPing;
|
||||
import net.minecraft.server.v1_12_R1.ServerPing.ServerData;
|
||||
import net.minecraft.server.v1_12_R1.ServerPing.ServerPingPlayerSample;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
@@ -18,19 +31,6 @@ import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.ChatComponentText;
|
||||
import net.minecraft.server.v1_10_R1.ChunkCoordIntPair;
|
||||
import net.minecraft.server.v1_10_R1.DataWatcher;
|
||||
import net.minecraft.server.v1_10_R1.IBlockData;
|
||||
import net.minecraft.server.v1_10_R1.IChatBaseComponent;
|
||||
import net.minecraft.server.v1_10_R1.IChatBaseComponent.ChatSerializer;
|
||||
import net.minecraft.server.v1_10_R1.NBTCompressedStreamTools;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
import net.minecraft.server.v1_10_R1.PlayerConnection;
|
||||
import net.minecraft.server.v1_10_R1.ServerPing;
|
||||
import net.minecraft.server.v1_10_R1.ServerPing.ServerData;
|
||||
import net.minecraft.server.v1_10_R1.ServerPing.ServerPingPlayerSample;
|
||||
|
||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||
public class MinecraftReflectionTest {
|
||||
|
||||
+2
-2
@@ -8,6 +8,8 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.IntHashMap;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
@@ -22,8 +24,6 @@ import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.IntHashMap;
|
||||
|
||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||
//@PrepareForTest(CraftItemFactory.class)
|
||||
|
||||
+4
-4
@@ -16,15 +16,15 @@ public class ChunkCoordIntPairTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
net.minecraft.server.v1_10_R1.ChunkCoordIntPair pair = new net.minecraft.server.v1_10_R1.ChunkCoordIntPair(1, 2);
|
||||
net.minecraft.server.v1_12_R1.ChunkCoordIntPair pair = new net.minecraft.server.v1_12_R1.ChunkCoordIntPair(1, 2);
|
||||
ChunkCoordIntPair specific = ChunkCoordIntPair.getConverter().getSpecific(pair);
|
||||
|
||||
assertEquals(1, specific.getChunkX());
|
||||
assertEquals(2, specific.getChunkZ());
|
||||
|
||||
net.minecraft.server.v1_10_R1.ChunkCoordIntPair roundtrip =
|
||||
(net.minecraft.server.v1_10_R1.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
|
||||
getGeneric(net.minecraft.server.v1_10_R1.ChunkCoordIntPair.class, specific);
|
||||
net.minecraft.server.v1_12_R1.ChunkCoordIntPair roundtrip =
|
||||
(net.minecraft.server.v1_12_R1.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
|
||||
getGeneric(net.minecraft.server.v1_12_R1.ChunkCoordIntPair.class, specific);
|
||||
|
||||
assertEquals(1, roundtrip.x);
|
||||
assertEquals(2, roundtrip.z);
|
||||
|
||||
+7
-7
@@ -2,6 +2,13 @@ package com.comphenix.protocol.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.EntityHuman.EnumChatVisibility;
|
||||
import net.minecraft.server.v1_12_R1.EnumDifficulty;
|
||||
import net.minecraft.server.v1_12_R1.EnumGamemode;
|
||||
import net.minecraft.server.v1_12_R1.EnumProtocol;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayInClientCommand.EnumClientCommand;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayInUseEntity.EnumEntityUseAction;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -10,13 +17,6 @@ import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.EntityHuman.EnumChatVisibility;
|
||||
import net.minecraft.server.v1_10_R1.EnumDifficulty;
|
||||
import net.minecraft.server.v1_10_R1.EnumGamemode;
|
||||
import net.minecraft.server.v1_10_R1.EnumProtocol;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayInClientCommand.EnumClientCommand;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayInUseEntity.EnumEntityUseAction;
|
||||
|
||||
public class EnumWrappersTest {
|
||||
private static class EnumClass {
|
||||
public EnumProtocol protocol;
|
||||
|
||||
+4
-4
@@ -6,6 +6,10 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.AttributeModifier;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes;
|
||||
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@@ -16,10 +20,6 @@ import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.WrappedAttributeModifier.Operation;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.AttributeModifier;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes;
|
||||
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot;
|
||||
|
||||
public class WrappedAttributeTest {
|
||||
private WrappedAttributeModifier doubleModifier;
|
||||
private WrappedAttributeModifier constantModifier;
|
||||
|
||||
+6
-8
@@ -19,12 +19,13 @@ package com.comphenix.protocol.wrappers;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftLightningStrike;
|
||||
import net.minecraft.server.v1_12_R1.EntityLightning;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftLightningStrike;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
@@ -34,9 +35,6 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.EntityLightning;
|
||||
import net.minecraft.server.v1_10_R1.ItemStack;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
@@ -92,11 +90,11 @@ public class WrappedDataWatcherTest {
|
||||
|
||||
@Test
|
||||
public void testSerializers() {
|
||||
Serializer blockPos = Registry.get(net.minecraft.server.v1_10_R1.BlockPosition.class, false);
|
||||
Serializer optionalBlockPos = Registry.get(net.minecraft.server.v1_10_R1.BlockPosition.class, true);
|
||||
Serializer blockPos = Registry.get(net.minecraft.server.v1_12_R1.BlockPosition.class, false);
|
||||
Serializer optionalBlockPos = Registry.get(net.minecraft.server.v1_12_R1.BlockPosition.class, true);
|
||||
assertNotSame(blockPos, optionalBlockPos);
|
||||
|
||||
assertNull(Registry.get(ItemStack.class, false));
|
||||
// assertNull(Registry.get(ItemStack.class, false));
|
||||
assertNotNull(Registry.get(UUID.class, true));
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -26,6 +26,9 @@ import java.io.DataInputStream;
|
||||
import java.io.DataOutput;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
import net.minecraft.server.v1_12_R1.ItemStack;
|
||||
import net.minecraft.server.v1_12_R1.Items;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -35,9 +38,6 @@ import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
|
||||
|
||||
import net.minecraft.server.v1_10_R1.ItemStack;
|
||||
import net.minecraft.server.v1_10_R1.Items;
|
||||
|
||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||
//@PrepareForTest(CraftItemFactory.class)
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
<parent>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib-Parent</artifactId>
|
||||
<version>v3-SNAPSHOT</version>
|
||||
<relativePath>../</relativePath>
|
||||
<version>v4-SNAPSHOT</version>
|
||||
<relativePath>../../</relativePath>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
@@ -42,8 +42,8 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.0</version>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@@ -77,20 +77,6 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>release-sign-artifacts</id>
|
||||
|
||||
@@ -178,7 +178,7 @@ public final class Reflection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined method of the given name and parameter count.
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param className - lookup name of the class, see {@link #getClass(String)}.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
@@ -191,7 +191,7 @@ public final class Reflection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined method of the given name and parameter count.
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
@@ -204,7 +204,7 @@ public final class Reflection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publically and privately defined method of the given name and parameter count.
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
* @param clazz - a class to start with.
|
||||
* @param methodName - the method name, or NULL to skip.
|
||||
|
||||
@@ -105,8 +105,7 @@ public abstract class TinyProtocol {
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Damn you, late bind
|
||||
plugin.getLogger().info("[TinyProtocol] Delaying server channel injection due to late bind.");
|
||||
|
||||
// Damn you, late bind
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -129,7 +128,7 @@ public abstract class TinyProtocol {
|
||||
synchronized (networkManagers) {
|
||||
// Stop injecting channels
|
||||
if (!closed) {
|
||||
injectChannelInternal(channel);
|
||||
channel.eventLoop().submit(() -> injectChannelInternal(channel));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@@ -256,13 +255,12 @@ public abstract class TinyProtocol {
|
||||
* <p>
|
||||
* Note that this is not executed on the main thread.
|
||||
*
|
||||
* @param reciever - the receiving player, NULL for early login/status packets.
|
||||
* @param receiver - the receiving player, NULL for early login/status packets.
|
||||
* @param channel - the channel that received the packet. Never NULL.
|
||||
* @param remoteAddress - remote address of the sending client. Never NULL.
|
||||
* @param packet - the packet being sent.
|
||||
* @return The packet to send instead, or NULL to cancel the transmission.
|
||||
*/
|
||||
public Object onPacketOutAsync(Player reciever, Channel channel, Object packet) {
|
||||
public Object onPacketOutAsync(Player receiver, Channel channel, Object packet) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -283,7 +281,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Send a packet to a particular player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Object)} will be invoked with this packet.
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the destination player.
|
||||
* @param packet - the packet to send.
|
||||
@@ -295,7 +293,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Send a packet to a particular client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketOutAsync(Player, Object)} will be invoked with this packet.
|
||||
* Note that {@link #onPacketOutAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet to send.
|
||||
@@ -307,7 +305,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Pretend that a given packet has been received from a player.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Object)} will be invoked with this packet.
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param player - the player that sent the packet.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
@@ -319,7 +317,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Pretend that a given packet has been received from a given client.
|
||||
* <p>
|
||||
* Note that {@link #onPacketInAsync(Player, Object)} will be invoked with this packet.
|
||||
* Note that {@link #onPacketInAsync(Player, Channel, Object)} will be invoked with this packet.
|
||||
*
|
||||
* @param channel - client identified by a channel.
|
||||
* @param packet - the packet that will be received by the server.
|
||||
@@ -353,7 +351,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param player - the channel to inject.
|
||||
* @param channel - the channel to inject.
|
||||
* @return The intercepted channel, or NULL if it has already been injected.
|
||||
*/
|
||||
public void injectChannel(Channel channel) {
|
||||
@@ -363,7 +361,7 @@ public abstract class TinyProtocol {
|
||||
/**
|
||||
* Add a custom channel handler to the given channel.
|
||||
*
|
||||
* @param player - the channel to inject.
|
||||
* @param channel - the channel to inject.
|
||||
* @return The packet interceptor.
|
||||
*/
|
||||
private PacketInterceptor injectChannelInternal(Channel channel) {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<minorVersion>4.3.0</minorVersion>
|
||||
<spigotVersion>1.12-R0.1-SNAPSHOT</spigotVersion>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
@@ -41,6 +43,40 @@
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Compile with the old version of Netty -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.0.23.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>${spigotVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>${spigotVersion}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cglib</groupId>
|
||||
<artifactId>cglib-nodep</artifactId>
|
||||
<version>2.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.comphenix.executors</groupId>
|
||||
<artifactId>BukkitExecutors</artifactId>
|
||||
<version>1.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package install</defaultGoal>
|
||||
|
||||
Reference in new issue
Block a user