2013-12-01 06:45:59 +01:00
|
|
|
package com.comphenix.protocol;
|
|
|
|
|
|
|
|
import java.io.Serializable;
|
2013-12-04 04:17:02 +01:00
|
|
|
import java.util.Arrays;
|
2014-01-20 06:21:20 +01:00
|
|
|
import java.util.Collection;
|
2013-12-04 04:17:02 +01:00
|
|
|
import java.util.List;
|
2015-11-14 20:31:45 +01:00
|
|
|
import java.util.Map;
|
2013-12-04 04:17:02 +01:00
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.concurrent.Callable;
|
|
|
|
import java.util.concurrent.Future;
|
|
|
|
|
2015-11-14 02:05:53 +01:00
|
|
|
import org.apache.commons.lang.WordUtils;
|
2013-12-04 04:17:02 +01:00
|
|
|
import org.bukkit.Bukkit;
|
2014-11-15 19:02:03 +01:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
import com.comphenix.protocol.PacketTypeLookup.ClassLookup;
|
2013-12-05 21:27:22 +01:00
|
|
|
import com.comphenix.protocol.events.ConnectionSide;
|
2013-12-04 04:17:02 +01:00
|
|
|
import com.comphenix.protocol.injector.packet.PacketRegistry;
|
2013-12-01 06:45:59 +01:00
|
|
|
import com.comphenix.protocol.reflect.ObjectEnum;
|
2013-12-06 20:05:46 +01:00
|
|
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
2013-12-04 04:17:02 +01:00
|
|
|
import com.comphenix.protocol.utility.MinecraftVersion;
|
2013-12-01 06:45:59 +01:00
|
|
|
import com.google.common.base.Objects;
|
2013-12-04 04:17:02 +01:00
|
|
|
import com.google.common.base.Preconditions;
|
2014-01-16 04:03:59 +01:00
|
|
|
import com.google.common.collect.ComparisonChain;
|
2013-12-04 04:17:02 +01:00
|
|
|
import com.google.common.collect.Iterables;
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
import com.google.common.util.concurrent.Futures;
|
2013-12-01 06:45:59 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Represents the type of a packet in a specific protocol.
|
|
|
|
* <p>
|
2015-11-14 02:05:53 +01:00
|
|
|
* Note that vanilla Minecraft reuses packet IDs per protocol (ping, game, login) and IDs are subject to change, so they are not reliable.
|
2013-12-01 06:45:59 +01:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
2014-01-16 04:03:59 +01:00
|
|
|
public class PacketType implements Serializable, Comparable<PacketType> {
|
2013-12-01 06:45:59 +01:00
|
|
|
// Increment whenever the type changes
|
|
|
|
private static final long serialVersionUID = 1L;
|
2016-03-01 00:55:29 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Represents an unknown legacy packet ID.
|
|
|
|
*/
|
|
|
|
public static final int UNKNOWN_PACKET = -1;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Packets sent during handshake.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Handshake {
|
2013-12-04 04:17:02 +01:00
|
|
|
private static final Protocol PROTOCOL = Protocol.HANDSHAKING;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Incoming packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Client extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
2016-03-20 22:46:23 +01:00
|
|
|
|
|
|
|
public static final PacketType SET_PROTOCOL = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "SetProtocol");
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Client INSTANCE = new Client();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Client() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Client getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* An empty enum, as the server will not send any packets in this protocol.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
|
|
|
public static class Server extends ObjectEnum<PacketType> {
|
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
|
|
|
private final static Server INSTANCE = new Server();
|
|
|
|
private Server() { super(PacketType.class); }
|
|
|
|
|
|
|
|
public static Server getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Protocol getProtocol() {
|
|
|
|
return PROTOCOL;
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
2013-12-05 21:24:31 +01:00
|
|
|
* Packets sent and received when logged into the game.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
|
|
|
public static class Play {
|
2013-12-10 12:17:15 +01:00
|
|
|
private static final Protocol PROTOCOL = Protocol.PLAY;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Outgoing packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2014-11-15 22:44:58 +01:00
|
|
|
public static class Server extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.SERVER;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
public static final PacketType SPAWN_ENTITY = new PacketType(PROTOCOL, SENDER, 0x00, 0x0E, "SpawnEntity");
|
|
|
|
public static final PacketType SPAWN_ENTITY_EXPERIENCE_ORB = new PacketType(PROTOCOL, SENDER, 0x01, 0x11, "SpawnEntityExperienceOrb");
|
|
|
|
public static final PacketType SPAWN_ENTITY_WEATHER = new PacketType(PROTOCOL, SENDER, 0x02, 0x2C, "SpawnEntityWeather");
|
|
|
|
public static final PacketType SPAWN_ENTITY_LIVING = new PacketType(PROTOCOL, SENDER, 0x03, 0x0F, "SpawnEntityLiving");
|
|
|
|
public static final PacketType SPAWN_ENTITY_PAINTING = new PacketType(PROTOCOL, SENDER, 0x04, 0x10, "SpawnEntityPainting");
|
|
|
|
public static final PacketType NAMED_ENTITY_SPAWN = new PacketType(PROTOCOL, SENDER, 0x05, 0x0C, "NamedEntitySpawn");
|
|
|
|
public static final PacketType ANIMATION = new PacketType(PROTOCOL, SENDER, 0x06, 0x0B, "Animation");
|
|
|
|
public static final PacketType STATISTIC = new PacketType(PROTOCOL, SENDER, 0x07, 0x37, "Statistic");
|
|
|
|
public static final PacketType BLOCK_BREAK_ANIMATION = new PacketType(PROTOCOL, SENDER, 0x08, 0x25, "BlockBreakAnimation");
|
|
|
|
public static final PacketType TILE_ENTITY_DATA = new PacketType(PROTOCOL, SENDER, 0x09, 0x35, "TileEntityData");
|
|
|
|
public static final PacketType BLOCK_ACTION = new PacketType(PROTOCOL, SENDER, 0x0A, 0x24, "BlockAction");
|
|
|
|
public static final PacketType BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x0B, 0x23, "BlockChange");
|
|
|
|
public static final PacketType BOSS = new PacketType(PROTOCOL, SENDER, 0x0C, 0xFF, "Boss");
|
|
|
|
public static final PacketType SERVER_DIFFICULTY = new PacketType(PROTOCOL, SENDER, 0x0D, 0x41, "ServerDifficulty");
|
|
|
|
public static final PacketType TAB_COMPLETE = new PacketType(PROTOCOL, SENDER, 0x0E, 0x3A, "TabComplete");
|
|
|
|
public static final PacketType CHAT = new PacketType(PROTOCOL, SENDER, 0x0F, 0x02, "Chat");
|
|
|
|
public static final PacketType MULTI_BLOCK_CHANGE = new PacketType(PROTOCOL, SENDER, 0x10, 0x22, "MultiBlockChange");
|
|
|
|
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 0x11, 0x32, "Transaction");
|
|
|
|
public static final PacketType CLOSE_WINDOW = new PacketType(PROTOCOL, SENDER, 0x12, 0x2E, "CloseWindow");
|
|
|
|
public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x13, 0x2D, "OpenWindow");
|
|
|
|
public static final PacketType WINDOW_ITEMS = new PacketType(PROTOCOL, SENDER, 0x14, 0x30, "WindowItems");
|
|
|
|
public static final PacketType WINDOW_DATA = new PacketType(PROTOCOL, SENDER, 0x15, 0x31, "WindowData");
|
|
|
|
public static final PacketType SET_SLOT = new PacketType(PROTOCOL, SENDER, 0x16, 0x2F, "SetSlot");
|
|
|
|
public static final PacketType SET_COOLDOWN = new PacketType(PROTOCOL, SENDER, 0x17, 0xFC, "SetCooldown");
|
|
|
|
public static final PacketType CUSTOM_PAYLOAD = new PacketType(PROTOCOL, SENDER, 0x18, 0x3F, "CustomPayload");
|
|
|
|
public static final PacketType CUSTOM_SOUND_EFFECT = new PacketType(PROTOCOL, SENDER, 0x19, 0xFD, "CustomSoundEffect");
|
|
|
|
public static final PacketType KICK_DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x1A, 0x40, "KickDisconnect");
|
|
|
|
public static final PacketType ENTITY_STATUS = new PacketType(PROTOCOL, SENDER, 0x1B, 0x1A, "EntityStatus");
|
|
|
|
public static final PacketType EXPLOSION = new PacketType(PROTOCOL, SENDER, 0x1C, 0x27, "Explosion");
|
|
|
|
public static final PacketType UNLOAD_CHUNK = new PacketType(PROTOCOL, SENDER, 0x1D, 0xFA, "UnloadChunk");
|
|
|
|
public static final PacketType GAME_STATE_CHANGE = new PacketType(PROTOCOL, SENDER, 0x1E, 0x2B, "GameStateChange");
|
|
|
|
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x1F, 0x00, "KeepAlive");
|
|
|
|
public static final PacketType MAP_CHUNK = new PacketType(PROTOCOL, SENDER, 0x20, 0x21, "MapChunk");
|
|
|
|
public static final PacketType WORLD_EVENT = new PacketType(PROTOCOL, SENDER, 0x21, 0x28, "WorldEvent");
|
|
|
|
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 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");
|
|
|
|
public static final PacketType COMBAT_EVENT = new PacketType(PROTOCOL, SENDER, 0x2C, 0x42, "CombatEvent");
|
|
|
|
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");
|
|
|
|
|
2013-12-05 08:21:42 +01:00
|
|
|
/**
|
2016-03-20 22:46:23 +01:00
|
|
|
* @deprecated Replaced by {@link WINDOW_DATA}
|
2013-12-05 08:21:42 +01:00
|
|
|
*/
|
2016-03-20 22:46:23 +01:00
|
|
|
@Deprecated
|
|
|
|
public static final PacketType CRAFT_PROGRESS_BAR = WINDOW_DATA;
|
|
|
|
|
2015-11-14 02:05:53 +01:00
|
|
|
/**
|
2016-03-20 22:46:23 +01:00
|
|
|
* @deprecated Replaced by {@link REL_ENTITY_MOVE_LOOK}
|
2015-11-14 02:05:53 +01:00
|
|
|
*/
|
2016-03-20 22:46:23 +01:00
|
|
|
@Deprecated
|
|
|
|
public static final PacketType ENTITY_MOVE_LOOK = REL_ENTITY_MOVE_LOOK;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated Replaced by {@link STATISTIC}
|
|
|
|
*/
|
|
|
|
@Deprecated
|
|
|
|
public static final PacketType STATISTICS = STATISTIC;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-05-13 00:30:49 +02:00
|
|
|
/**
|
|
|
|
* @deprecated Replaced by {@link TILE_ENTITY_DATA}
|
|
|
|
*/
|
|
|
|
@Deprecated
|
|
|
|
public static final PacketType UPDATE_SIGN = TILE_ENTITY_DATA;
|
|
|
|
|
2014-11-15 22:44:58 +01:00
|
|
|
// The instance must
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Server INSTANCE = new Server();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Server() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Server getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Incoming packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Client extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
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");
|
2016-03-01 00:55:29 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Client INSTANCE = new Client();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Client() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Client getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Protocol getProtocol() {
|
|
|
|
return PROTOCOL;
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
2013-12-05 21:24:31 +01:00
|
|
|
* Packets sent and received when querying the server in the multiplayer menu.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Status {
|
2013-12-04 04:17:02 +01:00
|
|
|
private static final Protocol PROTOCOL = Protocol.STATUS;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Outgoing packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Server extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.SERVER;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
public static final PacketType SERVER_INFO = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "ServerInfo").forceAsync(true);
|
|
|
|
public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "Pong");
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated Replaced by {@link SERVER_INFO}
|
|
|
|
*/
|
|
|
|
@Deprecated
|
|
|
|
public static final PacketType OUT_SERVER_INFO = SERVER_INFO;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Server INSTANCE = new Server();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Server() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Server getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Incoming packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Client extends ObjectEnum<PacketType> {
|
2014-11-15 22:44:58 +01:00
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
|
|
|
public static final PacketType PING = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "Ping");
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Client INSTANCE = new Client();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Client() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Client getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Protocol getProtocol() {
|
|
|
|
return PROTOCOL;
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
2013-12-05 21:24:31 +01:00
|
|
|
* Packets sent and received when logging in to the server.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Login {
|
2013-12-04 04:17:02 +01:00
|
|
|
private static final Protocol PROTOCOL = Protocol.LOGIN;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Outgoing packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Server extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.SERVER;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
public static final PacketType DISCONNECT = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Disconnect");
|
|
|
|
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "EncryptionBegin");
|
|
|
|
public static final PacketType SUCCESS = new PacketType(PROTOCOL, SENDER, 0x02, 0x02, "Success");
|
|
|
|
public static final PacketType SET_COMPRESSION = new PacketType(PROTOCOL, SENDER, 0x03, 0x03, "SetCompression");
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Server INSTANCE = new Server();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Server() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Server getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Incoming packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-01 06:45:59 +01:00
|
|
|
public static class Client extends ObjectEnum<PacketType> {
|
2013-12-04 04:17:02 +01:00
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2016-03-20 22:46:23 +01:00
|
|
|
public static final PacketType START = new PacketType(PROTOCOL, SENDER, 0x00, 0x00, "Start");
|
|
|
|
public static final PacketType ENCRYPTION_BEGIN = new PacketType(PROTOCOL, SENDER, 0x01, 0x01, "EncryptionBegin");
|
2013-12-04 04:17:02 +01:00
|
|
|
|
|
|
|
private final static Client INSTANCE = new Client();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Client() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Client getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
public static Protocol getProtocol() {
|
|
|
|
return PROTOCOL;
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Contains every packet Minecraft 1.6.4 packet removed in Minecraft 1.7.2.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
|
|
|
public static class Legacy {
|
|
|
|
private static final Protocol PROTOCOL = Protocol.LEGACY;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Outgoing packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-06 20:05:46 +01:00
|
|
|
// Missing server packets: [10, 11, 12, 21, 107, 252]
|
|
|
|
public static class Server extends ObjectEnum<PacketType> {
|
|
|
|
private final static Sender SENDER = Sender.SERVER;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 21:17:05 +01:00
|
|
|
public static final PacketType PLAYER_FLYING = PacketType.newLegacy(SENDER, 10);
|
|
|
|
public static final PacketType PLAYER_POSITION = PacketType.newLegacy(SENDER, 11);
|
|
|
|
public static final PacketType PLAYER_POSITON_LOOK = PacketType.newLegacy(SENDER, 12);
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Removed in Minecraft 1.4.6.
|
|
|
|
*/
|
2013-12-06 21:17:05 +01:00
|
|
|
public static final PacketType PICKUP_SPAWN = PacketType.newLegacy(SENDER, 21);
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Removed in Minecraft 1.7.2
|
|
|
|
*/
|
2013-12-06 21:17:05 +01:00
|
|
|
public static final PacketType SET_CREATIVE_SLOT = PacketType.newLegacy(SENDER, 107);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Removed in Minecraft 1.7.2
|
|
|
|
*/
|
2013-12-06 21:17:05 +01:00
|
|
|
public static final PacketType KEY_RESPONSE = PacketType.newLegacy(SENDER, 252);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
private final static Server INSTANCE = new Server();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
// Prevent accidental construction
|
2014-11-15 22:44:58 +01:00
|
|
|
private Server() {
|
|
|
|
super(PacketType.class);
|
2013-12-06 20:05:46 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Server getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-09 13:46:41 +01:00
|
|
|
/**
|
|
|
|
* Incoming packets.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
2013-12-06 20:05:46 +01:00
|
|
|
// Missing client packets: [1, 9, 255]
|
|
|
|
public static class Client extends ObjectEnum<PacketType> {
|
|
|
|
private final static Sender SENDER = Sender.CLIENT;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 21:17:05 +01:00
|
|
|
public static final PacketType LOGIN = PacketType.newLegacy(SENDER, 1);
|
|
|
|
public static final PacketType RESPAWN = PacketType.newLegacy(SENDER, 9);
|
|
|
|
public static final PacketType DISCONNECT = PacketType.newLegacy(SENDER, 255);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
private final static Client INSTANCE = new Client();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
// Prevent accidental construction
|
|
|
|
private Client() { super(PacketType.class); }
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
public static Sender getSender() {
|
|
|
|
return SENDER;
|
|
|
|
}
|
|
|
|
public static Client getInstance() {
|
|
|
|
return INSTANCE;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
public static Protocol getProtocol() {
|
|
|
|
return PROTOCOL;
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
|
|
|
* Represents the different protocol or connection states.
|
|
|
|
* @author Kristian
|
|
|
|
*/
|
|
|
|
public enum Protocol {
|
2013-12-04 04:17:02 +01:00
|
|
|
HANDSHAKING,
|
2013-12-10 12:17:15 +01:00
|
|
|
PLAY,
|
2013-12-01 06:45:59 +01:00
|
|
|
STATUS,
|
2013-12-06 20:05:46 +01:00
|
|
|
LOGIN,
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Only for packets removed in Minecraft 1.7.2
|
|
|
|
*/
|
|
|
|
LEGACY;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the correct protocol enum from a given vanilla enum instance.
|
|
|
|
* @param vanilla - the vanilla protocol enum instance.
|
|
|
|
* @return The corresponding protocol.
|
|
|
|
*/
|
|
|
|
public static Protocol fromVanilla(Enum<?> vanilla) {
|
|
|
|
String name = vanilla.name();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
if ("HANDSHAKING".equals(name))
|
2015-11-14 02:05:53 +01:00
|
|
|
return HANDSHAKING;
|
2013-12-04 04:17:02 +01:00
|
|
|
if ("PLAY".equals(name))
|
2013-12-10 12:17:15 +01:00
|
|
|
return PLAY;
|
2013-12-04 04:17:02 +01:00
|
|
|
if ("STATUS".equals(name))
|
|
|
|
return STATUS;
|
|
|
|
if ("LOGIN".equals(name))
|
|
|
|
return LOGIN;
|
|
|
|
throw new IllegalArgumentException("Unrecognized vanilla enum " + vanilla);
|
|
|
|
}
|
2015-11-14 02:05:53 +01:00
|
|
|
|
|
|
|
public String getPacketName() {
|
|
|
|
return WordUtils.capitalize(name().toLowerCase());
|
|
|
|
}
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
2013-12-05 21:24:31 +01:00
|
|
|
* Represents the sender of this packet type.
|
2013-12-01 06:45:59 +01:00
|
|
|
* @author Kristian
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public enum Sender {
|
|
|
|
/**
|
|
|
|
* Indicates that packets of this type will be sent by connected clients.
|
|
|
|
*/
|
|
|
|
CLIENT,
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
|
|
|
* Indicate that packets of this type will be sent by the current server.
|
|
|
|
*/
|
2013-12-05 21:27:22 +01:00
|
|
|
SERVER;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-05 21:27:22 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the equivialent connection side.
|
|
|
|
* @return The connection side.
|
|
|
|
*/
|
|
|
|
public ConnectionSide toSide() {
|
|
|
|
return this == CLIENT ? ConnectionSide.CLIENT_SIDE : ConnectionSide.SERVER_SIDE;
|
|
|
|
}
|
2015-11-14 02:05:53 +01:00
|
|
|
|
|
|
|
public String getPacketName() {
|
|
|
|
return this == CLIENT ? "In" : "Out";
|
|
|
|
}
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// Lookup of packet types
|
|
|
|
private static PacketTypeLookup LOOKUP;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Protocol version of all the current IDs.
|
|
|
|
*/
|
2014-11-30 03:13:49 +01:00
|
|
|
private static final MinecraftVersion PROTOCOL_VERSION = MinecraftVersion.BOUNTIFUL_UPDATE;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
private final Protocol protocol;
|
|
|
|
private final Sender sender;
|
|
|
|
private final int currentId;
|
|
|
|
private final int legacyId;
|
2013-12-04 04:17:02 +01:00
|
|
|
private final MinecraftVersion version;
|
2015-11-14 02:05:53 +01:00
|
|
|
private final String[] classNames;
|
|
|
|
|
2015-10-17 04:36:01 +02:00
|
|
|
private boolean forceAsync;
|
|
|
|
private boolean dynamic;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the current packet/legacy lookup.
|
|
|
|
* @return The packet type lookup.
|
|
|
|
*/
|
|
|
|
private static PacketTypeLookup getLookup() {
|
|
|
|
if (LOOKUP == null) {
|
|
|
|
LOOKUP = new PacketTypeLookup().
|
|
|
|
addPacketTypes(Handshake.Client.getInstance()).
|
|
|
|
addPacketTypes(Handshake.Server.getInstance()).
|
|
|
|
addPacketTypes(Play.Client.getInstance()).
|
|
|
|
addPacketTypes(Play.Server.getInstance()).
|
|
|
|
addPacketTypes(Status.Client.getInstance()).
|
|
|
|
addPacketTypes(Status.Server.getInstance()).
|
|
|
|
addPacketTypes(Login.Client.getInstance()).
|
2013-12-06 20:05:46 +01:00
|
|
|
addPacketTypes(Login.Server.getInstance()).
|
|
|
|
addPacketTypes(Legacy.Client.getInstance()).
|
|
|
|
addPacketTypes(Legacy.Server.getInstance());
|
2013-12-04 04:17:02 +01:00
|
|
|
}
|
|
|
|
return LOOKUP;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Find every packet type known to the current version of ProtocolLib.
|
|
|
|
* @return Every packet type.
|
|
|
|
*/
|
|
|
|
public static Iterable<PacketType> values() {
|
|
|
|
List<Iterable<? extends PacketType>> sources = Lists.newArrayList();
|
|
|
|
sources.add(Handshake.Client.getInstance());
|
|
|
|
sources.add(Handshake.Server.getInstance());
|
|
|
|
sources.add(Play.Client.getInstance());
|
|
|
|
sources.add(Play.Server.getInstance());
|
|
|
|
sources.add(Status.Client.getInstance());
|
|
|
|
sources.add(Status.Server.getInstance());
|
|
|
|
sources.add(Login.Client.getInstance());
|
|
|
|
sources.add(Login.Server.getInstance());
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
// Add the missing types in earlier versions
|
|
|
|
if (!MinecraftReflection.isUsingNetty()) {
|
|
|
|
sources.add(Legacy.Client.getInstance());
|
|
|
|
sources.add(Legacy.Server.getInstance());
|
|
|
|
}
|
2013-12-04 04:17:02 +01:00
|
|
|
return Iterables.concat(sources);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve a packet type from a legacy (1.6.4 and below) packet ID.
|
|
|
|
* @param packetId - the legacy packet ID.
|
|
|
|
* @return The corresponding packet type.
|
|
|
|
* @throws IllegalArgumentException If the legacy packet could not be found.
|
|
|
|
*/
|
|
|
|
public static PacketType findLegacy(int packetId) {
|
|
|
|
PacketType type = getLookup().getFromLegacy(packetId);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
if (type != null)
|
|
|
|
return type;
|
|
|
|
throw new IllegalArgumentException("Cannot find legacy packet " + packetId);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-05 20:40:45 +01:00
|
|
|
/**
|
|
|
|
* Retrieve a packet type from a legacy (1.6.4 and below) packet ID.
|
|
|
|
* @param packetId - the legacy packet ID.
|
|
|
|
* @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.
|
|
|
|
*/
|
|
|
|
public static PacketType findLegacy(int packetId, Sender preference) {
|
|
|
|
if (preference == null)
|
|
|
|
return findLegacy(packetId);
|
|
|
|
PacketType type = getLookup().getFromLegacy(packetId, preference);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-05 20:40:45 +01:00
|
|
|
if (type != null)
|
|
|
|
return type;
|
|
|
|
throw new IllegalArgumentException("Cannot find legacy packet " + packetId);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-19 02:17:06 +01:00
|
|
|
/**
|
|
|
|
* Determine if the given legacy packet exists.
|
|
|
|
* @param packetId - the legacy packet ID.
|
|
|
|
* @return TRUE if it does, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public static boolean hasLegacy(int packetId) {
|
|
|
|
return getLookup().getFromLegacy(packetId) != null;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve a packet type from a protocol, sender and packet ID.
|
2013-12-10 12:17:15 +01:00
|
|
|
* <p>
|
|
|
|
* It is usually better to access the packet types statically, like so:
|
|
|
|
* <ul>
|
|
|
|
* <li>{@link PacketType.Play.Server#SPAWN_ENTITY}
|
|
|
|
* </ul>
|
2013-12-04 04:17:02 +01:00
|
|
|
* @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.
|
2015-11-14 20:31:45 +01:00
|
|
|
* @deprecated IDs are no longer reliable
|
2013-12-04 04:17:02 +01:00
|
|
|
*/
|
2015-11-14 20:31:45 +01:00
|
|
|
@Deprecated
|
2013-12-04 04:17:02 +01:00
|
|
|
public static PacketType findCurrent(Protocol protocol, Sender sender, int packetId) {
|
|
|
|
PacketType type = getLookup().getFromCurrent(protocol, sender, packetId);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
if (type != null)
|
|
|
|
return type;
|
2014-11-15 22:44:58 +01:00
|
|
|
throw new IllegalArgumentException("Cannot find packet " + packetId +
|
2013-12-04 04:17:02 +01:00
|
|
|
"(Protocol: " + protocol + ", Sender: " + sender + ")");
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
public static PacketType findCurrent(Protocol protocol, Sender sender, String name) {
|
|
|
|
name = format(protocol, sender, name);
|
|
|
|
PacketType type = getLookup().getFromCurrent(protocol, sender, name);
|
|
|
|
|
|
|
|
if (type != null) {
|
|
|
|
return type;
|
|
|
|
} else {
|
|
|
|
throw new IllegalArgumentException("Cannot find packet " + name +
|
|
|
|
"(Protocol: " + protocol + ", Sender: " + sender + ")");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static String format(Protocol protocol, Sender sender, String name) {
|
|
|
|
if (name.contains("Packet"))
|
|
|
|
return name;
|
|
|
|
|
|
|
|
return String.format("Packet%s%s%s", protocol.getPacketName(), sender.getPacketName(), name);
|
|
|
|
}
|
|
|
|
|
2013-12-19 02:17:06 +01:00
|
|
|
/**
|
|
|
|
* Determine if the given packet exists.
|
|
|
|
* @param protocol - the protocol.
|
|
|
|
* @param sender - the sender.
|
|
|
|
* @param packetId - the packet ID.
|
|
|
|
* @return TRUE if it exists, FALSE otherwise.
|
2015-11-14 20:31:45 +01:00
|
|
|
* @deprecated IDs are no longer reliable
|
2013-12-19 02:17:06 +01:00
|
|
|
*/
|
2015-11-14 20:31:45 +01:00
|
|
|
@Deprecated
|
2013-12-19 02:17:06 +01:00
|
|
|
public static boolean hasCurrent(Protocol protocol, Sender sender, int packetId) {
|
|
|
|
return getLookup().getFromCurrent(protocol, sender, packetId) != null;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-22 20:10:51 +01:00
|
|
|
/**
|
|
|
|
* Retrieve a packet type from a legacy ID.
|
|
|
|
* <p>
|
|
|
|
* If no associated packet type could be found, a new will be registered under LEGACY.
|
|
|
|
* @param id - the legacy ID.
|
|
|
|
* @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.
|
|
|
|
*/
|
|
|
|
public static PacketType fromLegacy(int id, Sender sender) {
|
2014-02-04 22:53:56 +01:00
|
|
|
PacketType type = getLookup().getFromLegacy(id, sender);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-22 20:10:51 +01:00
|
|
|
if (type == null) {
|
|
|
|
if (sender == null)
|
|
|
|
throw new IllegalArgumentException("Cannot find legacy packet " + id);
|
|
|
|
type = newLegacy(sender, id);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-22 20:10:51 +01:00
|
|
|
// As below
|
|
|
|
scheduleRegister(type, "Dynamic-" + UUID.randomUUID().toString());
|
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
2015-11-14 20:31:45 +01:00
|
|
|
* Retrieve a packet type from a protocol, sender and packet ID, for pre-1.8.
|
2013-12-04 04:17:02 +01:00
|
|
|
* <p>
|
|
|
|
* The packet will automatically be registered if its missing.
|
|
|
|
* @param protocol - the current protocol.
|
|
|
|
* @param sender - the sender.
|
2013-12-06 20:05:46 +01:00
|
|
|
* @param packetId - the packet ID. Can be UNKNOWN_PACKET.
|
2015-11-14 02:05:53 +01:00
|
|
|
* @param packetClass - the packet class
|
2013-12-04 04:17:02 +01:00
|
|
|
* @return The corresponding packet type.
|
|
|
|
*/
|
2015-11-14 20:31:45 +01:00
|
|
|
public static PacketType fromID(Protocol protocol, Sender sender, int packetId, Class<?> packetClass) {
|
|
|
|
PacketType type = getLookup().getFromCurrent(protocol, sender, packetId);
|
|
|
|
|
|
|
|
if (type == null) {
|
|
|
|
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, packetClass.getName());
|
|
|
|
type.dynamic = true;
|
|
|
|
|
|
|
|
// Many may be scheduled, but only the first will be executed
|
|
|
|
scheduleRegister(type, "Dynamic-" + UUID.randomUUID().toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve a packet type from a protocol, sender, ID, and class for 1.8+
|
|
|
|
* <p>
|
|
|
|
* The packet will automatically be registered if its missing.
|
|
|
|
* @param protocol - the current protocol.
|
|
|
|
* @param sender - the sender.
|
|
|
|
* @param packetId - the packet ID. Can be UNKNOWN_PACKET.
|
|
|
|
* @param packetClass - the packet class.
|
|
|
|
* @return The corresponding packet type.
|
|
|
|
*/
|
2015-11-14 02:05:53 +01:00
|
|
|
public static PacketType fromCurrent(Protocol protocol, Sender sender, int packetId, Class<?> packetClass) {
|
2015-11-14 20:31:45 +01:00
|
|
|
ClassLookup lookup = getLookup().getClassLookup();
|
|
|
|
Map<String, PacketType> map = lookup.getMap(protocol, sender);
|
|
|
|
|
|
|
|
// Check the map first
|
2015-11-14 02:05:53 +01:00
|
|
|
String className = packetClass.getSimpleName();
|
2015-11-14 20:31:45 +01:00
|
|
|
PacketType type = map.get(className);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2015-11-14 02:05:53 +01:00
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
// Guess we don't support this packet :/
|
|
|
|
type = new PacketType(protocol, sender, packetId, -1, PROTOCOL_VERSION, className);
|
|
|
|
type.dynamic = true;
|
|
|
|
|
|
|
|
// Many may be scheduled, but only the first will be executed
|
|
|
|
scheduleRegister(type, "Dynamic-" + UUID.randomUUID().toString());
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
return type;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-19 04:45:30 +01:00
|
|
|
/**
|
|
|
|
* Lookup a packet type from a packet class.
|
|
|
|
* @param packetClass - the packet class.
|
|
|
|
* @return The corresponding packet type, or NULL if not found.
|
|
|
|
*/
|
|
|
|
public static PacketType fromClass(Class<?> packetClass) {
|
|
|
|
PacketType type = PacketRegistry.getPacketType(packetClass);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-19 04:45:30 +01:00
|
|
|
if (type != null)
|
|
|
|
return type;
|
|
|
|
throw new IllegalArgumentException("Class " + packetClass + " is not a registered packet.");
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2014-01-20 06:21:20 +01:00
|
|
|
/**
|
|
|
|
* Retrieve every packet type with the given UPPER_CAMEL_CASE name.
|
|
|
|
* <p>
|
|
|
|
* Note that the collection is unmodiable.
|
|
|
|
* @param name - the name.
|
|
|
|
* @return Every packet type, or an empty collection.
|
|
|
|
*/
|
|
|
|
public static Collection<PacketType> fromName(String name) {
|
|
|
|
return getLookup().getFromName(name);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-19 04:45:30 +01:00
|
|
|
/**
|
|
|
|
* Determine if a given class represents a packet class.
|
|
|
|
* @param packetClass - the class to lookup.
|
|
|
|
* @return TRUE if this is a packet class, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public static boolean hasClass(Class<?> packetClass) {
|
|
|
|
return PacketRegistry.getPacketType(packetClass) != null;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Register a particular packet type.
|
|
|
|
* <p>
|
2014-11-15 22:44:58 +01:00
|
|
|
* Note that the registration will be performed on the main thread.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @param type - the type to register.
|
|
|
|
* @param name - the name of the packet.
|
2013-12-05 21:24:31 +01:00
|
|
|
* @return A future telling us if our instance was registered.
|
2013-12-04 04:17:02 +01:00
|
|
|
*/
|
|
|
|
public static Future<Boolean> scheduleRegister(final PacketType type, final String name) {
|
|
|
|
Callable<Boolean> callable = new Callable<Boolean>() {
|
|
|
|
@Override
|
|
|
|
public Boolean call() throws Exception {
|
|
|
|
ObjectEnum<PacketType> objEnum;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
// A bit ugly, but performance is critical
|
2013-12-30 15:25:34 +01:00
|
|
|
objEnum = getObjectEnum(type);
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
if (objEnum.registerMember(type, name)) {
|
|
|
|
getLookup().addPacketTypes(Arrays.asList(type));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Execute in the main thread if possible
|
2016-03-19 21:01:38 +01:00
|
|
|
if (Bukkit.getServer() == null || Bukkit.isPrimaryThread()) {
|
2013-12-04 04:17:02 +01:00
|
|
|
try {
|
|
|
|
return Futures.immediateFuture(callable.call());
|
|
|
|
} catch (Exception e) {
|
|
|
|
return Futures.immediateFailedFuture(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ProtocolLibrary.getExecutorSync().submit(callable);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-30 15:25:34 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the correct object enum from a specific packet type.
|
|
|
|
* @param type - the packet type.
|
|
|
|
* @return The corresponding object enum.
|
|
|
|
*/
|
|
|
|
public static ObjectEnum<PacketType> getObjectEnum(final PacketType type) {
|
|
|
|
switch (type.getProtocol()) {
|
|
|
|
case HANDSHAKING:
|
2014-11-15 22:44:58 +01:00
|
|
|
return type.isClient() ? Handshake.Client.getInstance() : Handshake.Server.getInstance();
|
2013-12-30 15:25:34 +01:00
|
|
|
case PLAY:
|
2014-11-15 22:44:58 +01:00
|
|
|
return type.isClient() ? Play.Client.getInstance() : Play.Server.getInstance();
|
2013-12-30 15:25:34 +01:00
|
|
|
case STATUS:
|
2014-11-15 22:44:58 +01:00
|
|
|
return type.isClient() ? Status.Client.getInstance() : Status.Server.getInstance();
|
2013-12-30 15:25:34 +01:00
|
|
|
case LOGIN:
|
2014-11-15 22:44:58 +01:00
|
|
|
return type.isClient() ? Login.Client.getInstance() : Login.Server.getInstance();
|
2013-12-30 15:25:34 +01:00
|
|
|
case LEGACY:
|
2014-11-15 22:44:58 +01:00
|
|
|
return type.isClient() ? Legacy.Client.getInstance() : Legacy.Server.getInstance();
|
2013-12-30 15:25:34 +01:00
|
|
|
default:
|
|
|
|
throw new IllegalStateException("Unexpected protocol: " + type.getProtocol());
|
|
|
|
}
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
|
|
|
* Construct a new packet type.
|
|
|
|
* @param protocol - the current protocol.
|
2013-12-06 20:05:46 +01:00
|
|
|
* @param sender - client or server.
|
2014-11-15 22:44:58 +01:00
|
|
|
* @param currentId - the current packet ID, or
|
2013-12-01 06:45:59 +01:00
|
|
|
* @param legacyId - the legacy packet ID.
|
|
|
|
*/
|
2015-11-14 02:05:53 +01:00
|
|
|
public PacketType(Protocol protocol, Sender sender, int currentId, int legacyId, String... names) {
|
|
|
|
this(protocol, sender, currentId, legacyId, PROTOCOL_VERSION, names);
|
2013-12-04 04:17:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct a new packet type.
|
|
|
|
* @param protocol - the current protocol.
|
2013-12-06 20:05:46 +01:00
|
|
|
* @param sender - client or server.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @param currentId - the current packet ID.
|
|
|
|
* @param legacyId - the legacy packet ID.
|
|
|
|
* @param version - the version of the current ID.
|
|
|
|
*/
|
2015-11-14 02:05:53 +01:00
|
|
|
public PacketType(Protocol protocol, Sender sender, int currentId, int legacyId, MinecraftVersion version, String... names) {
|
2013-12-04 04:17:02 +01:00
|
|
|
this.protocol = Preconditions.checkNotNull(protocol, "protocol cannot be NULL");
|
|
|
|
this.sender = Preconditions.checkNotNull(sender, "sender cannot be NULL");
|
2013-12-01 06:45:59 +01:00
|
|
|
this.currentId = currentId;
|
|
|
|
this.legacyId = legacyId;
|
2013-12-04 04:17:02 +01:00
|
|
|
this.version = version;
|
2015-11-14 02:05:53 +01:00
|
|
|
|
|
|
|
this.classNames = new String[names.length];
|
|
|
|
for (int i = 0; i < classNames.length; i++) {
|
2015-11-14 20:31:45 +01:00
|
|
|
classNames[i] = format(protocol, sender, names[i]);
|
2015-11-14 02:05:53 +01:00
|
|
|
}
|
2016-03-01 00:55:29 +01:00
|
|
|
//System.out.println(Arrays.toString(classNames));
|
2013-12-04 04:17:02 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-06 20:05:46 +01:00
|
|
|
/**
|
|
|
|
* Construct a legacy packet type.
|
|
|
|
* @param sender - client or server.
|
|
|
|
* @param legacyId - the legacy packet ID.
|
2015-06-17 20:25:39 +02:00
|
|
|
* @return Legacy packet type
|
2013-12-06 20:05:46 +01:00
|
|
|
*/
|
|
|
|
public static PacketType newLegacy(Sender sender, int legacyId) {
|
|
|
|
return new PacketType(Protocol.LEGACY, sender, PacketType.UNKNOWN_PACKET, legacyId, MinecraftVersion.WORLD_UPDATE);
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Determine if this packet is supported on the current server.
|
|
|
|
* @return Whether or not the packet is supported.
|
|
|
|
*/
|
|
|
|
public boolean isSupported() {
|
|
|
|
return PacketRegistry.isSupported(this);
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieve the protocol (the connection state) the packet type belongs.
|
|
|
|
* @return The protocol of this type.
|
|
|
|
*/
|
|
|
|
public Protocol getProtocol() {
|
|
|
|
return protocol;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
|
|
|
* Retrieve which sender will transmit packets of this type.
|
|
|
|
* @return The sender of these packets.
|
|
|
|
*/
|
|
|
|
public Sender getSender() {
|
|
|
|
return sender;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Determine if this packet was sent by the client.
|
|
|
|
* @return TRUE if it was, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isClient() {
|
|
|
|
return sender == Sender.CLIENT;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Determine if this packet was sent by the server.
|
|
|
|
* @return TRUE if it was, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isServer() {
|
|
|
|
return sender == Sender.SERVER;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the current protocol ID for this packet type.
|
|
|
|
* <p>
|
|
|
|
* This is only unique within a specific protocol and target.
|
2013-12-06 20:05:46 +01:00
|
|
|
* <p>
|
|
|
|
* It is only unknown if the packet was removed in Minecraft 1.7.2.
|
|
|
|
* @return The current ID, or {@link #UNKNOWN_PACKET} if unknown.
|
2015-11-14 02:05:53 +01:00
|
|
|
* @deprecated IDs are subject to change
|
2013-12-01 06:45:59 +01:00
|
|
|
*/
|
2015-11-14 02:05:53 +01:00
|
|
|
@Deprecated
|
2013-12-01 06:45:59 +01:00
|
|
|
public int getCurrentId() {
|
|
|
|
return currentId;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
public String[] getClassNames() {
|
|
|
|
return classNames;
|
|
|
|
}
|
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
/**
|
2013-12-04 04:17:02 +01:00
|
|
|
* Retrieve the equivalent packet class.
|
2013-12-07 19:52:02 +01:00
|
|
|
* @return The packet class, or NULL if not found.
|
2013-12-04 04:17:02 +01:00
|
|
|
*/
|
|
|
|
public Class<?> getPacketClass() {
|
2013-12-06 20:05:46 +01:00
|
|
|
try {
|
|
|
|
return PacketRegistry.getPacketClassFromType(this);
|
|
|
|
} catch (Exception e) {
|
|
|
|
return null;
|
|
|
|
}
|
2013-12-04 04:17:02 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-30 15:25:34 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the declared enum name of this packet type.
|
|
|
|
* @return The enum name.
|
|
|
|
*/
|
|
|
|
public String name() {
|
|
|
|
return getObjectEnum(this).getDeclaredName(this);
|
|
|
|
}
|
2013-12-07 19:52:02 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the Minecraft version for the current ID.
|
|
|
|
* @return The Minecraft version.
|
|
|
|
*/
|
|
|
|
public MinecraftVersion getCurrentVersion() {
|
|
|
|
return version;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the legacy (1.6.4 or below) protocol ID of the packet type.
|
2013-12-01 06:45:59 +01:00
|
|
|
* <p>
|
|
|
|
* This ID is globally unique.
|
2013-12-04 04:17:02 +01:00
|
|
|
* @return The legacy ID, or {@link #UNKNOWN_PACKET} if unknown.
|
2013-12-01 06:45:59 +01:00
|
|
|
*/
|
|
|
|
public int getLegacyId() {
|
|
|
|
return legacyId;
|
|
|
|
}
|
|
|
|
|
2015-05-31 20:42:52 +02:00
|
|
|
/**
|
2015-10-17 04:36:01 +02:00
|
|
|
* Whether or not this packet was dynamically created (i.e. we don't have it registered)
|
2015-05-31 20:42:52 +02:00
|
|
|
* @return True if dnyamic, false if not.
|
|
|
|
*/
|
|
|
|
public boolean isDynamic() {
|
|
|
|
return dynamic;
|
|
|
|
}
|
|
|
|
|
2015-10-17 04:36:01 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
2013-12-06 20:05:46 +01:00
|
|
|
return Objects.hashCode(protocol, sender, currentId, legacyId);
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (obj == this)
|
|
|
|
return true;
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
if (obj instanceof PacketType) {
|
|
|
|
PacketType other = (PacketType) obj;
|
2014-11-15 22:44:58 +01:00
|
|
|
return protocol == other.protocol &&
|
|
|
|
sender == other.sender &&
|
|
|
|
currentId == other.currentId &&
|
2013-12-06 20:05:46 +01:00
|
|
|
legacyId == other.legacyId;
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2014-01-16 04:03:59 +01:00
|
|
|
@Override
|
|
|
|
public int compareTo(PacketType other) {
|
|
|
|
return ComparisonChain.start().
|
|
|
|
compare(protocol, other.getProtocol()).
|
|
|
|
compare(sender, other.getSender()).
|
|
|
|
compare(currentId, other.getCurrentId()).
|
|
|
|
compare(legacyId, other.getLegacyId()).
|
|
|
|
result();
|
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-01 06:45:59 +01:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
2014-11-30 03:13:49 +01:00
|
|
|
Class<?> clazz = getPacketClass();
|
2014-11-15 22:44:58 +01:00
|
|
|
|
2013-12-19 02:17:06 +01:00
|
|
|
if (clazz == null)
|
2015-11-14 02:05:53 +01:00
|
|
|
return "UNREGISTERED[" + protocol + ", " + sender + ", " + currentId + ", legacy: " + legacyId + ", classNames: " + Arrays.toString(classNames) + "]";
|
2013-12-19 02:17:06 +01:00
|
|
|
else
|
|
|
|
return clazz.getSimpleName() + "[" + currentId + ", legacy: " + legacyId + "]";
|
2013-12-01 06:45:59 +01:00
|
|
|
}
|
2014-11-15 22:44:58 +01:00
|
|
|
}
|