Depreciate the Packets class - it is not safe to rely on integers.

This commit is contained in:
Kristian S. Stangeland 2013-12-01 06:45:59 +01:00
parent c9fd6b4b93
commit 28b4874c60
5 changed files with 471 additions and 1 deletions

View File

@ -0,0 +1,286 @@
package com.comphenix.protocol;
import java.io.Serializable;
import com.comphenix.protocol.reflect.ObjectEnum;
import com.google.common.base.Objects;
/**
* Represents the type of a packet in a specific protocol.
* <p>
* Note that vanilla Minecraft reuses packet IDs per protocol (ping, game, login), so you cannot
* rely on IDs alone.
* @author Kristian
*/
public class PacketType implements Serializable {
// Increment whenever the type changes
private static final long serialVersionUID = 1L;
public static class Handshake {
public static final Protocol PROTOCOL = Protocol.HANDSHAKE;
public static class Client extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.CLIENT;
public final static Client INSTANCE = new Client();
public static final PacketType HANDSHAKE = new PacketType(PROTOCOL, SENDER, 0x00, 2);
}
}
public static class Game {
public static final Protocol PROTOCOL = Protocol.GAME;
public static class Server extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.SERVER;
public final static Server INSTANCE = new Server();
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x00, 0);
public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x01, 1);
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x02, 3);
public static final PacketType UPDATE_TIME = new PacketType(PROTOCOL, SENDER, 0x03, 4);
public static final PacketType ENTITY_EQUIPMENT = new PacketType(PROTOCOL, SENDER, 0x04, 5);
public static final PacketType SPAWN_POSITION = new PacketType(PROTOCOL, SENDER, 0x05, 6);
public static final PacketType UPDATE_HEALTH = new PacketType(PROTOCOL, SENDER, 0x06, 8);
public static final PacketType RESPAWN = new PacketType(PROTOCOL, SENDER, 0x07, 9);
public static final PacketType PLAYER_LOOK_MOVE = new PacketType(PROTOCOL, SENDER, 0x08, 13);
public static final PacketType BLOCK_ITEM_SWITCH = new PacketType(PROTOCOL, SENDER, 0x09, 16);
public static final PacketType ENTITY_LOCATION_ACTION = new PacketType(PROTOCOL, SENDER, 0x0A, 17);
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x0B, 18);
public static final PacketType NAMED_ENTITY_SPAWN = new PacketType(PROTOCOL, SENDER, 0x0C, 20);
public static final PacketType COLLECT = new PacketType(PROTOCOL, SENDER, 0x0D, 22);
public static final PacketType VEHICLE_SPAWN = new PacketType(PROTOCOL, SENDER, 0x0E, 23);
public static final PacketType MOB_SPAWN = new PacketType(PROTOCOL, SENDER, 0x0F, 24);
public static final PacketType ENTITY_PAINTING = new PacketType(PROTOCOL, SENDER, 0x10, 25);
public static final PacketType ADD_EXP_ORB = new PacketType(PROTOCOL, SENDER, 0x11, 26);
public static final PacketType ENTITY_VELOCITY = new PacketType(PROTOCOL, SENDER, 0x12, 28);
public static final PacketType DESTROY_ENTITY = new PacketType(PROTOCOL, SENDER, 0x13, 29);
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 0x14, 30);
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x15, 31);
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x16, 32);
public static final PacketType ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x17, 33);
public static final PacketType ENTITY_TELEPORT = new PacketType(PROTOCOL, SENDER, 0x18, 34);
public static final PacketType ENTITY_HEAD_ROTATION = new PacketType(PROTOCOL, SENDER, 0x19, 35);
public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1A, 38);
public static final PacketType ATTACH_ENTITY = new PacketType(PROTOCOL, SENDER, 0x1B, 39);
public static final PacketType ENTITY_METADATA = new PacketType(PROTOCOL, SENDER, 0x1C, 40);
public static final PacketType MOB_EFFECT = new PacketType(PROTOCOL, SENDER, 0x1D, 41);
public static final PacketType REMOVE_MOB_EFFECT = new PacketType(PROTOCOL, SENDER, 0x1E, 42);
public static final PacketType SET_EXPERIENCE = new PacketType(PROTOCOL, SENDER, 0x1F, 43);
public static final PacketType UPDATE_ATTRIBUTES = new PacketType(PROTOCOL, SENDER, 0x20, 44);
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x21, 51);
public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x22, 52);
public static final PacketType BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x23, 53);
public static final PacketType PLAY_NOTE_BLOCK = new PacketType(PROTOCOL, SENDER, 0x24, 54);
public static final PacketType BLOCK_BREAK_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x25, 55);
public static final PacketType MAP_CHUNK_BULK = new PacketType(PROTOCOL, SENDER, 0x26, 56);
public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x27, 60);
public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x28, 61);
public static final PacketType NAMED_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x29, 62);
public static final PacketType WORLD_PARTICLES = new PacketType(PROTOCOL, SENDER, 0x2A, 63);
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 0x2B, 70);
public static final PacketType WEATHER = new PacketType(PROTOCOL, SENDER, 0x2C, 71);
public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x2D, 100);
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x2E, 101);
public static final PacketType SET_SLOT = new PacketType(PROTOCOL, SENDER, 0x2F, 103);
public static final PacketType WINDOW_ITEMS = new PacketType(PROTOCOL, SENDER, 0x30, 104);
public static final PacketType CRAFT_PROGRESS_BAR = new PacketType(PROTOCOL, SENDER, 0x31, 105);
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x32, 106);
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x33, 130);
public static final PacketType ITEM_DATA = new PacketType(PROTOCOL, SENDER, 0x34, 131);
public static final PacketType TILE_ENTITY_DATA = new PacketType(PROTOCOL, SENDER, 0x35, 132);
public static final PacketType OPEN_TILE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x36, 133);
public static final PacketType STATISTICS = new PacketType(PROTOCOL, SENDER, 0x37, 200);
public static final PacketType PLAYER_INFO = new PacketType(PROTOCOL, SENDER, 0x38, 201);
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x39, 202);
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x3A, 203);
public static final PacketType SET_SCOREBOARD_OBJECTIVE = new PacketType(PROTOCOL, SENDER, 0x3B, 206);
public static final PacketType SET_SCOREBOARD_SCORE = new PacketType(PROTOCOL, SENDER, 0x3C, 207);
public static final PacketType SET_SCOREBOARD_DISPLAY_OBJECTIVE =
new PacketType(PROTOCOL, SENDER, 0x3D, 208);
public static final PacketType SET_SCOREOARD_TEAM = new PacketType(PROTOCOL, SENDER, 0x3E, 209);
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x3F, 250);
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x40, 255);
}
public static class Client extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.CLIENT;
public final static Client INSTANCE = new Client();
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x00, 0);
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x01, 3);
public static final PacketType USE_ENTITY = new PacketType(PROTOCOL, SENDER, 0x02, 7);
public static final PacketType FLYING = new PacketType(PROTOCOL, SENDER, 0x03, 10);
public static final PacketType PLAYER_POSITION = new PacketType(PROTOCOL, SENDER, 0x04, 11);
public static final PacketType PLAYER_LOOK = new PacketType(PROTOCOL, SENDER, 0x05, 12);
public static final PacketType PLAYER_LOOK_MOVE = new PacketType(PROTOCOL, SENDER, 0x06, 13);
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x07, 14);
public static final PacketType PLACE = new PacketType(PROTOCOL, SENDER, 0x08, 15);
public static final PacketType BLOCK_ITEM_SWITCH = new PacketType(PROTOCOL, SENDER, 0x09, 16);
public static final PacketType ARM_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x0A, 18);
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x0B, 19);
public static final PacketType PLAYER_INPUT = new PacketType(PROTOCOL, SENDER, 0x0C, 27);
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x0D, 101);
public static final PacketType WINDOW_CLICK = new PacketType(PROTOCOL, SENDER, 0x0E, 102);
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x0F, 106);
public static final PacketType CREATIVE_SLOT = new PacketType(PROTOCOL, SENDER, 0x10, 107);
public static final PacketType BUTTON_CLICK = new PacketType(PROTOCOL, SENDER, 0x11, 108);
public static final PacketType UPDATE_SIGN = new PacketType(PROTOCOL, SENDER, 0x12, 130);
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x13, 202);
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x14, 203);
public static final PacketType LOCALE_AND_VIEW_DISTANCE = new PacketType(PROTOCOL, SENDER, 0x15, 204);
public static final PacketType CLIENT_COMMAND = new PacketType(PROTOCOL, SENDER, 0x16, 205);
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x17, 250);
}
}
public static class Status {
public static final Protocol PROTOCOL = Protocol.STATUS;
public static class Server extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.SERVER;
public final static Server INSTANCE = new Server();
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 255);
@SuppressWarnings("deprecation")
public static final PacketType PING_TIME = new PacketType(PROTOCOL, SENDER, 0x00, Packets.Server.PING_TIME);
}
public static class Client extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.CLIENT;
public final static Client INSTANCE = new Client();
public static final PacketType STATUS_REQUEST = new PacketType(PROTOCOL, SENDER, 0x00, 254);
@SuppressWarnings("deprecation")
public static final PacketType PING_TIME = new PacketType(PROTOCOL, SENDER, 0x00, Packets.Client.PING_TIME);
}
}
public static class Login {
public static final Protocol PROTOCOL = Protocol.LOGIN;
public static class Server extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.SERVER;
public final static Server INSTANCE = new Server();
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 255);
public static final PacketType KEY_REQUEST = new PacketType(PROTOCOL, SENDER, 0x01, 253);
@SuppressWarnings("deprecation")
public static final PacketType LOGIN_SUCCESS = new PacketType(PROTOCOL, SENDER, 0x02, Packets.Server.LOGIN_SUCCESS);
}
public static class Client extends ObjectEnum<PacketType> {
public final static Sender SENDER = Sender.CLIENT;
public final static Client INSTANCE = new Client();
@SuppressWarnings("deprecation")
public static final PacketType LOGIN_START = new PacketType(PROTOCOL, SENDER, 0x00, Packets.Client.LOGIN_START);
public static final PacketType KEY_RESPONSE = new PacketType(PROTOCOL, SENDER, 0x01, 252);
}
}
/**
* Represents the different protocol or connection states.
* @author Kristian
*/
public enum Protocol {
HANDSHAKE,
GAME,
STATUS,
LOGIN
}
/**
* Represens the sender of this packet type.
* @author Kristian
*
*/
public enum Sender {
/**
* Indicates that packets of this type will be sent by connected clients.
*/
CLIENT,
/**
* Indicate that packets of this type will be sent by the current server.
*/
SERVER
}
private final Protocol protocol;
private final Sender sender;
private final int currentId;
private final int legacyId;
/**
* Construct a new packet type.
* @param protocol - the current protocol.
* @param target - the target - client or server.
* @param currentId - the current packet ID.
* @param legacyId - the legacy packet ID.
*/
public PacketType(Protocol protocol, Sender sender, int currentId, int legacyId) {
this.protocol = protocol;
this.sender = sender;
this.currentId = currentId;
this.legacyId = legacyId;
}
/**
* Retrieve the protocol (the connection state) the packet type belongs.
* @return The protocol of this type.
*/
public Protocol getProtocol() {
return protocol;
}
/**
* Retrieve which sender will transmit packets of this type.
* @return The sender of these packets.
*/
public Sender getSender() {
return sender;
}
/**
* Retrieve the current protocol ID for this packet type.
* <p>
* This is only unique within a specific protocol and target.
* @return The current ID.
*/
public int getCurrentId() {
return currentId;
}
/**
* Retrieve the legacy (pre 1.7.2) protocol ID of the packet type.
* <p>
* This ID is globally unique.
* @return The legacy ID.
*/
public int getLegacyId() {
return legacyId;
}
@Override
public int hashCode() {
return Objects.hashCode(protocol, sender, legacyId, currentId);
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof PacketType) {
PacketType other = (PacketType) obj;
return protocol == other.protocol &&
sender == other.sender &&
currentId == other.currentId;
}
return false;
}
@Override
public String toString() {
return "Packet [protocol=" + protocol + ", sender=" + sender + ", legacyId=" + legacyId + ", currentId=" + currentId + "]";
}
}

View File

@ -42,8 +42,11 @@ public final class Packets {
/** /**
* List of packets sent only by the server. * List of packets sent only by the server.
* <p>
* This has been superceded by PacketType.
* @author Kristian * @author Kristian
*/ */
@Deprecated
public static final class Server extends IntEnum { public static final class Server extends IntEnum {
/** /**
* The singleton instance. Can also be retrieved from the parent class. * The singleton instance. Can also be retrieved from the parent class.
@ -143,6 +146,16 @@ public final class Packets {
public static final int KEY_REQUEST = 253; public static final int KEY_REQUEST = 253;
public static final int KICK_DISCONNECT = 255; public static final int KICK_DISCONNECT = 255;
/**
* This packet was introduced in 1.7.2.
*/
public static final int PING_TIME = 230;
/**
* This packet was introduced in 1.7.2.
*/
public static final int LOGIN_SUCCESS = 232;
/** /**
* A registry that parses between names and packet IDs. * A registry that parses between names and packet IDs.
* @return The current server registry. * @return The current server registry.
@ -178,8 +191,11 @@ public final class Packets {
/** /**
* List of packets sent by the client. * List of packets sent by the client.
* <p>
* This has been superceded by PacketType.
* @author Kristian * @author Kristian
*/ */
@Deprecated
public static class Client extends IntEnum { public static class Client extends IntEnum {
/** /**
* The singleton instance. Can also be retrieved from the parent class. * The singleton instance. Can also be retrieved from the parent class.
@ -223,6 +239,16 @@ public final class Packets {
public static final int GET_INFO = 254; public static final int GET_INFO = 254;
public static final int KICK_DISCONNECT = 255; public static final int KICK_DISCONNECT = 255;
/**
* This packet was introduced in 1.7.2.
*/
public static final int PING_TIME = 230;
/**
* This packet was introduced in 1.7.2.
*/
public static final int LOGIN_START = 231;
/** /**
* A registry that parses between names and packet IDs. * A registry that parses between names and packet IDs.
* @return The current client registry. * @return The current client registry.
@ -260,6 +286,7 @@ public final class Packets {
* A registry that parses between names and packet IDs. * A registry that parses between names and packet IDs.
* @return The current client registry. * @return The current client registry.
*/ */
@Deprecated
public static Server getServerRegistry() { public static Server getServerRegistry() {
return Server.getRegistry(); return Server.getRegistry();
} }
@ -268,6 +295,7 @@ public final class Packets {
* A registry that parses between names and packet IDs. * A registry that parses between names and packet IDs.
* @return The current server registry. * @return The current server registry.
*/ */
@Deprecated
public static Client getClientRegistry() { public static Client getClientRegistry() {
return Client.INSTANCE; return Client.INSTANCE;
} }
@ -277,6 +305,7 @@ public final class Packets {
* @param name - name of packet to find. * @param name - name of packet to find.
* @return The packet ID found. * @return The packet ID found.
*/ */
@Deprecated
public static int valueOf(String name) { public static int valueOf(String name) {
Integer serverAttempt = Server.INSTANCE.valueOf(name); Integer serverAttempt = Server.INSTANCE.valueOf(name);
@ -291,6 +320,7 @@ public final class Packets {
* @param packetID - packet to retrieve name. * @param packetID - packet to retrieve name.
* @return The name, or NULL if unable to find such a packet. * @return The name, or NULL if unable to find such a packet.
*/ */
@Deprecated
public static String getDeclaredName(int packetID) { public static String getDeclaredName(int packetID) {
String serverAttempt = Server.INSTANCE.getDeclaredName(packetID); String serverAttempt = Server.INSTANCE.getDeclaredName(packetID);

View File

@ -0,0 +1,28 @@
package com.comphenix.protocol.injector.netty;
import com.comphenix.protocol.utility.MinecraftReflection;
/**
* Represents a way of accessing the new netty Protocol enum.
* @author Kristian
*/
public class NettyProtocol {
private Class<?> enumProtocol;
public NettyProtocol() {
enumProtocol = MinecraftReflection.getEnumProtocolClass();
}
/**
* Load the packet lookup tables in each protocol.
*/
private void initialize() {
for (Object protocol : enumProtocol.getEnumConstants()) {
}
}
}

View File

@ -0,0 +1,109 @@
/*
* 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.reflect;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Set;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
/**
* Represents a more modern object-based enum.
* <p>
* This is useful if you want the flexibility of a modern Java enum, but don't
* want to prevent the creation of additional members dynamically.
* @author Kristian
*/
public class ObjectEnum<T> {
// Used to convert between IDs and names
protected BiMap<T, String> members = HashBiMap.create();
/**
* Registers every declared integer field.
*/
public ObjectEnum() {
registerAll();
}
/**
* Registers every public int field as a member.
*/
@SuppressWarnings("unchecked")
protected void registerAll() {
try {
// Register every int field
for (Field entry : this.getClass().getFields()) {
if (entry.getType().equals(int.class)) {
registerMember((T) entry.get(this), entry.getName());
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Registers a member.
* @param instance - member instance.
* @param name - name of member.
*/
protected void registerMember(T instance, String name) {
members.put(instance, name);
}
/**
* Determines whether or not the given member has been registered to this enum.
* @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);
}
/**
* Retrieve a member by name,
* @param name - name of member to retrieve.
* @return The member, or NULL if not found.
*/
public T valueOf(String name) {
return members.inverse().get(name);
}
/**
* 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());
}
}

View File

@ -584,6 +584,24 @@ public class MinecraftReflection {
} }
} }
/**
* Retrieve the EnumProtocol class in 1.7.2.
* @return The Enum protocol class.
*/
public static Class<?> getEnumProtocolClass() {
try {
return getMinecraftClass("EnumProtocol");
} catch (RuntimeException e) {
Method protocolMethod = FuzzyReflection.fromClass(getNetworkManagerClass()).getMethod(
FuzzyMethodContract.newBuilder().
parameterCount(1).
parameterDerivedOf(Enum.class, 0).
build()
);
return setMinecraftClass("EnumProtocol", protocolMethod.getParameterTypes()[0]);
}
}
/** /**
* Retrieve the least derived class, except Object. * Retrieve the least derived class, except Object.
* @return Least derived super class. * @return Least derived super class.
@ -599,7 +617,6 @@ public class MinecraftReflection {
} }
} }
/** /**
* Retrieve the MinecraftServer class. * Retrieve the MinecraftServer class.
* @return MinecraftServer class. * @return MinecraftServer class.