Another quite big update:

Implement Unsigned Short
Implement Most of the Incoming Packets (Still need to implement a few, when I add some sort of packet sending / id changing and packet cancelling)
Implement a base protocol

Still need to do plugin messaging (I will probably forget)
This commit is contained in:
Myles 2016-03-14 12:40:23 +00:00
parent 9b28129187
commit 33f1a8975c
10 changed files with 360 additions and 40 deletions

View File

@ -7,52 +7,55 @@ import com.google.common.collect.Table;
public enum PacketType {
/* Handshake serverbound */
HANDSHAKE(State.HANDSHAKE, Direction.INCOMING, 0x00),
HANDSHAKE(State.HANDSHAKE, Direction.INCOMING, 0x00), // Mapped
/* Login serverbound */
LOGIN_START(State.LOGIN, Direction.INCOMING, 0x00),
LOGIN_ENCRYPTION_RESPONSE(State.LOGIN, Direction.INCOMING, 0x01),
LOGIN_START(State.LOGIN, Direction.INCOMING, 0x00), // Mapped
LOGIN_ENCRYPTION_RESPONSE(State.LOGIN, Direction.INCOMING, 0x01), // Mapped
/* Login clientbound */
LOGIN_DISCONNECT(State.LOGIN, Direction.OUTGOING, 0x00),
LOGIN_ENCRYPTION_REQUEST(State.LOGIN, Direction.OUTGOING, 0x01),
LOGIN_SUCCESS(State.LOGIN, Direction.OUTGOING, 0x02),
LOGIN_SETCOMPRESSION(State.LOGIN, Direction.OUTGOING, 0x03),
LOGIN_DISCONNECT(State.LOGIN, Direction.OUTGOING, 0x00), // Mapped
LOGIN_ENCRYPTION_REQUEST(State.LOGIN, Direction.OUTGOING, 0x01), // Mapped
LOGIN_SUCCESS(State.LOGIN, Direction.OUTGOING, 0x02), // Mapped
LOGIN_SETCOMPRESSION(State.LOGIN, Direction.OUTGOING, 0x03), // Mapped
/* Status serverbound */
STATUS_REQUEST(State.STATUS, Direction.INCOMING, 0x00),
STATUS_PING(State.STATUS, Direction.INCOMING, 0x01),
STATUS_REQUEST(State.STATUS, Direction.INCOMING, 0x00), // Mapped
STATUS_PING(State.STATUS, Direction.INCOMING, 0x01), // Mapped
/* Status clientbound */
STATUS_RESPONSE(State.STATUS, Direction.OUTGOING, 0x00),
STATUS_PONG(State.STATUS, Direction.OUTGOING, 0x01),
/* Play serverbound */
PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00),
PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01),
PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02),
PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03),
PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04),
PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05),
PLAY_ENCHANT_ITEM(State.PLAY, Direction.INCOMING, 0x11, 0x06),
PLAY_CLICK_WINDOW(State.PLAY, Direction.INCOMING, 0x0E, 0x07),
PLAY_CLOSE_WINDOW_REQUEST(State.PLAY, Direction.INCOMING, 0x0D, 0x08),
PLAY_TP_CONFIRM(State.PLAY, Direction.INCOMING, -1, 0x00), // TODO
PLAY_TAB_COMPLETE_REQUEST(State.PLAY, Direction.INCOMING, 0x14, 0x01), // Mapped
PLAY_CHAT_MESSAGE_CLIENT(State.PLAY, Direction.INCOMING, 0x01, 0x02), // Mapped
PLAY_CLIENT_STATUS(State.PLAY, Direction.INCOMING, 0x16, 0x03), // Mapped
PLAY_CLIENT_SETTINGS(State.PLAY, Direction.INCOMING, 0x15, 0x04), // Mapped
PLAY_CONFIRM_TRANS(State.PLAY, Direction.INCOMING, 0x0F, 0x05), // Mapped
PLAY_ENCHANT_ITEM(State.PLAY, Direction.INCOMING, 0x11, 0x06), // Mapped
PLAY_CLICK_WINDOW(State.PLAY, Direction.INCOMING, 0x0E, 0x07), // Mapped
PLAY_CLOSE_WINDOW_REQUEST(State.PLAY, Direction.INCOMING, 0x0D, 0x08), // Mapped
PLAY_PLUGIN_MESSAGE_REQUEST(State.PLAY, Direction.INCOMING, 0x17, 0x09),
PLAY_USE_ENTITY(State.PLAY, Direction.INCOMING, 0x02, 0x0A),
PLAY_KEEP_ALIVE_REQUEST(State.PLAY, Direction.INCOMING, 0x00, 0x0B),
PLAY_PLAYER_POSITION_REQUEST(State.PLAY, Direction.INCOMING, 0x04, 0x0C),
PLAY_PLAYER_POSITION_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x06, 0x0D),
PLAY_PLAYER_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x05, 0x0E),
PLAY_PLAYER(State.PLAY, Direction.INCOMING, 0x03, 0x0F),
PLAY_VEHICLE_MOVE_REQUEST(State.PLAY, Direction.INCOMING, -1, 0x10),
PLAY_STEER_BOAT(State.PLAY, Direction.INCOMING, -1, 0x11),
PLAY_PLAYER_ABILITIES_REQUEST(State.PLAY, Direction.INCOMING, 0x13, 0x12),
PLAY_PLAYER_DIGGING(State.PLAY, Direction.INCOMING, 0x07, 0x13),
PLAY_ENTITY_ACTION(State.PLAY, Direction.INCOMING, 0x0B, 0x14),
PLAY_STEER_VEHICLE(State.PLAY, Direction.INCOMING, 0x0C, 0x15),
PLAY_RESOURCE_PACK_STATUS(State.PLAY, Direction.INCOMING, 0x19, 0x16),
PLAY_HELD_ITEM_CHANGE_REQUEST(State.PLAY, Direction.INCOMING, 0x09, 0x17),
PLAY_CREATIVE_INVENTORY_ACTION(State.PLAY, Direction.INCOMING, 0x10, 0x18),
PLAY_UPDATE_SIGN_REQUEST(State.PLAY, Direction.INCOMING, 0x12, 0x19),
PLAY_ANIMATION_REQUEST(State.PLAY, Direction.INCOMING, 0x0A, 0x1A),
PLAY_SPECTATE(State.PLAY, Direction.INCOMING, 0x18, 0x1B),
PLAY_PLAYER_BLOCK_PLACEMENT(State.PLAY, Direction.INCOMING, 0x08, 0x1C),
PLAY_USE_ITEM(State.PLAY, Direction.INCOMING, -1, 0x1D),
PLAY_USE_ENTITY(State.PLAY, Direction.INCOMING, 0x02, 0x0A), // Mapped
PLAY_KEEP_ALIVE_REQUEST(State.PLAY, Direction.INCOMING, 0x00, 0x0B), // Mapped
PLAY_PLAYER_POSITION_REQUEST(State.PLAY, Direction.INCOMING, 0x04, 0x0C), // Mapped
PLAY_PLAYER_POSITION_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x06, 0x0D), // Mapped
PLAY_PLAYER_LOOK_REQUEST(State.PLAY, Direction.INCOMING, 0x05, 0x0E), // Mapped
PLAY_PLAYER(State.PLAY, Direction.INCOMING, 0x03, 0x0F), // Mapped
PLAY_VEHICLE_MOVE_REQUEST(State.PLAY, Direction.INCOMING, -1, 0x10), // TODO
PLAY_STEER_BOAT(State.PLAY, Direction.INCOMING, -1, 0x11), // TODO
PLAY_PLAYER_ABILITIES_REQUEST(State.PLAY, Direction.INCOMING, 0x13, 0x12), // Mapped
PLAY_PLAYER_DIGGING(State.PLAY, Direction.INCOMING, 0x07, 0x13), // Mapped
PLAY_ENTITY_ACTION(State.PLAY, Direction.INCOMING, 0x0B, 0x14), // Mapped
PLAY_STEER_VEHICLE(State.PLAY, Direction.INCOMING, 0x0C, 0x15), // Mapped
PLAY_RESOURCE_PACK_STATUS(State.PLAY, Direction.INCOMING, 0x19, 0x16), // Mapped
PLAY_HELD_ITEM_CHANGE_REQUEST(State.PLAY, Direction.INCOMING, 0x09, 0x17), // Mapped
PLAY_CREATIVE_INVENTORY_ACTION(State.PLAY, Direction.INCOMING, 0x10, 0x18), // Mapped
PLAY_UPDATE_SIGN_REQUEST(State.PLAY, Direction.INCOMING, 0x12, 0x19), // Mapped
PLAY_ANIMATION_REQUEST(State.PLAY, Direction.INCOMING, 0x0A, 0x1A), // Mapped
PLAY_SPECTATE(State.PLAY, Direction.INCOMING, 0x18, 0x1B), // Mapped
PLAY_PLAYER_BLOCK_PLACEMENT(State.PLAY, Direction.INCOMING, 0x08, 0x1C), // Mapped
PLAY_USE_ITEM(State.PLAY, Direction.INCOMING, -1, 0x1D), // TODO
/* Play clientbound */
PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00), // Mapped
PLAY_SPAWN_XP_ORB(State.PLAY, Direction.OUTGOING, 0x11, 0x01), // Mapped

View File

@ -7,6 +7,7 @@ import us.myles.ViaVersion.packets.Direction;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion2.api.PacketWrapper;
import us.myles.ViaVersion2.api.data.UserConnection;
import us.myles.ViaVersion2.api.protocol.base.BaseProtocol;
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
import us.myles.ViaVersion2.api.type.Type;
import us.myles.ViaVersion2.api.util.Pair;
@ -15,6 +16,8 @@ import java.util.HashMap;
import java.util.Map;
public abstract class Protocol {
public static final Protocol BASE_PROTOCOL = new BaseProtocol();
private Map<Pair<State, Integer>, ProtocolPacket> incoming = new HashMap<>();
private Map<Pair<State, Integer>, ProtocolPacket> outgoing = new HashMap<>();

View File

@ -0,0 +1,86 @@
package us.myles.ViaVersion2.api.protocol.base;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion2.api.PacketWrapper;
import us.myles.ViaVersion2.api.data.UserConnection;
import us.myles.ViaVersion2.api.protocol.Protocol;
import us.myles.ViaVersion2.api.remapper.PacketHandler;
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
import us.myles.ViaVersion2.api.type.Type;
import java.util.UUID;
public class BaseProtocol extends Protocol {
@Override
protected void registerPackets() {
/* Outgoing Packets */
registerOutgoing(State.STATUS, 0x00, 0x00); // Status Response Packet
registerOutgoing(State.STATUS, 0x01, 0x01); // Status Pong Packet
registerOutgoing(State.LOGIN, 0x00, 0x00); // Login Disconnect Packet
registerOutgoing(State.LOGIN, 0x01, 0x01); // Encryption Request Packet
// Login Success Packet
registerOutgoing(State.LOGIN, 0x02, 0x02, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - UUID as String
map(Type.STRING); // 1 - Player Username
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
info.setState(State.PLAY);
UUID uuid = UUID.fromString(wrapper.get(Type.STRING, 0));
info.setUuid(uuid);
info.setUsername(wrapper.get(Type.STRING, 1));
}
});
}
});
registerOutgoing(State.LOGIN, 0x03, 0x03); // Login Set Compression Packet
/* Incoming Packets */
// Handshake Packet
registerIncoming(State.HANDSHAKE, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
// select right protocol
map(Type.VAR_INT); // 0 - Client Protocol Version
map(Type.STRING); // 1 - Server Address
map(Type.UNSIGNED_SHORT); // 2 - Server Port
map(Type.VAR_INT); // 3 - Next State
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
int protVer = wrapper.get(Type.VAR_INT, 0);
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
info.setProtocolVersion(protVer);
// TODO: Choose the right pipe
// Change state
int state = wrapper.get(Type.VAR_INT, 1);
if (state == 1) {
info.setState(State.STATUS);
}
if (state == 2) {
info.setState(State.LOGIN);
}
}
});
}
});
registerIncoming(State.STATUS, 0x00, 0x00); // Status Request Packet
registerIncoming(State.STATUS, 0x01, 0x01); // Status Ping Packet
registerIncoming(State.LOGIN, 0x00, 0x00); // Login Start Packet
registerIncoming(State.LOGIN, 0x01, 0x01); // Encryption Response Packet
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new ProtocolInfo());
}
}

View File

@ -0,0 +1,17 @@
package us.myles.ViaVersion2.api.protocol.base;
import lombok.Getter;
import lombok.Setter;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion2.api.data.StoredObject;
import java.util.UUID;
@Getter
@Setter
public class ProtocolInfo extends StoredObject{
private State state = State.HANDSHAKE;
private int protocolVersion = -1;
private String username;
private UUID uuid;
}

View File

@ -4,6 +4,7 @@ import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion2.api.PacketWrapper;
import us.myles.ViaVersion2.api.protocol.Protocol;
import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion2.api.remapper.PacketHandler;
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
import us.myles.ViaVersion2.api.remapper.ValueTransformer;
import us.myles.ViaVersion2.api.type.Type;
@ -29,7 +30,7 @@ public class EntityPackets {
map(Type.BOOLEAN, new ValueTransformer<Boolean, Void>(Type.NOTHING) {
@Override
public Void transform(PacketWrapper wrapper, Boolean inputValue) {
if(!inputValue){
if (!inputValue) {
// TODO: Write Set Passengers packet
}
return null;
@ -146,5 +147,52 @@ public class EntityPackets {
protocol.registerOutgoing(State.PLAY, 0x1E, 0x31); // Remove Entity Effect Packet
protocol.registerOutgoing(State.PLAY, 0x19, 0x34); // Entity Head Look Packet
protocol.registerOutgoing(State.PLAY, 0x12, 0x3B); // Entity Velocity Packet
/* Incoming Packets */
// Entity Action Packet
protocol.registerIncoming(State.PLAY, 0x0B, 0x14, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Player ID
map(Type.VAR_INT); // 1 - Action
map(Type.VAR_INT); // 2 - Jump
// TODO: If action is 6 or 8 cancel
// If action is 7 change to 6
}
});
// Use Entity Packet
protocol.registerIncoming(State.PLAY, 0x02, 0x0A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID (Target)
map(Type.VAR_INT); // 1 - Action Type
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
int type = wrapper.get(Type.VAR_INT, 1);
if (type == 2) {
wrapper.passthrough(Type.FLOAT); // 2 - X
wrapper.passthrough(Type.FLOAT); // 3 - Y
wrapper.passthrough(Type.FLOAT); // 4 - Z
}
if (type == 0 || type == 2) {
wrapper.read(Type.VAR_INT); // 2/5 - Hand
}
}
});
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerIncoming(State.PLAY, 0x0C, 0x15); // Steer Vehicle Packet
protocol.registerIncoming(State.PLAY, 0x18, 0x1B); // Spectate Packet
}
}

View File

@ -90,5 +90,56 @@ public class InventoryPackets {
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x32, 0x11); // Confirm Transaction Packet
/* Incoming Packets */
// Creative Inventory Slot Action Packet
protocol.registerIncoming(State.PLAY, 0x10, 0x18, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.SHORT);
map(Type.ITEM);
// TODO: Transform Item Patch
}
});
// Player Click Window Packet
protocol.registerIncoming(State.PLAY, 0x0E, 0x07, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.BYTE);
map(Type.SHORT);
map(Type.BYTE);
map(Type.ITEM);
// TODO: Transform Item Patch
// TODO: Throw elytra and brewing patch
}
});
// Close Window Incoming Packet
protocol.registerIncoming(State.PLAY, 0x0D, 0x08, new PacketRemapper() {
@Override
public void registerMap() {
// TODO Close Inventory patch
}
});
// TODO Use Item
/* Packets which do not have any field remapping or handlers */
protocol.registerIncoming(State.PLAY, 0x0F, 0x05); // Confirm Transaction Packet
protocol.registerIncoming(State.PLAY, 0x11, 0x06); // Enchant Item Packet
// TODO Held Item change blocking patch
protocol.registerIncoming(State.PLAY, 0x09, 0x17); // Held Item Change Packet
}
}

View File

@ -224,5 +224,51 @@ public class PlayerPackets {
// Login Success - Save UUID and Username
// Server Difficulty - Activate Auto-Team
// TODO: Status Response, implement? (Might be implemented by a base protocol?)
/* Incoming Packets */
// Tab Complete Request Packet
protocol.registerIncoming(State.PLAY, 0x14, 0x01, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Requested Command
map(Type.BOOLEAN, Type.NOTHING); // 1 - Is Command Block
}
});
// Client Settings Packet
protocol.registerIncoming(State.PLAY, 0x15, 0x04, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - locale
map(Type.BYTE); // 1 - View Distance
map(Type.VAR_INT, Type.BYTE); // 2 - Chat Mode
map(Type.BOOLEAN); // 3 - If Chat Colours on
map(Type.UNSIGNED_BYTE); // 4 - Skin Parts
map(Type.VAR_INT, Type.NOTHING); // 5 - Main Hand
}
});
// Animation Request Packet
protocol.registerIncoming(State.PLAY, 0x0A, 0x1A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT, Type.NOTHING); // 0 - Hand
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerIncoming(State.PLAY, 0x01, 0x02); // Chat Message Packet
protocol.registerIncoming(State.PLAY, 0x16, 0x03); // Client Status Packet
protocol.registerIncoming(State.PLAY, 0x13, 0x12); // Player Abilities Request Packet
protocol.registerIncoming(State.PLAY, 0x19, 0x16); // Resource Pack Status Packet
protocol.registerIncoming(State.PLAY, 0x00, 0x0B); // Keep Alive Request Packet
protocol.registerIncoming(State.PLAY, 0x04, 0x0C); // Player Position Packet
protocol.registerIncoming(State.PLAY, 0x06, 0x0D); // Player Move & Look Packet
protocol.registerIncoming(State.PLAY, 0x05, 0x0E); // Player Look Packet
protocol.registerIncoming(State.PLAY, 0x03, 0x0F); // Player Packet
}
}

View File

@ -12,7 +12,7 @@ public class WorldPackets {
protocol.registerOutgoing(State.PLAY, 0x33, 0x46, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.LONG); // 0 - Sign Position
map(Type.POSITION); // 0 - Sign Position
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 1 - Sign Line (json)
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 2 - Sign Line (json)
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 3 - Sign Line (json)
@ -59,5 +59,48 @@ public class WorldPackets {
protocol.registerOutgoing(State.PLAY, 0x44, 0x35); // World Border Packet
// TODO: Chunk Data, Bulk Chunk :)
/* Incoming Packets */
// Sign Update Request Packet
protocol.registerIncoming(State.PLAY, 0x12, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Sign Position
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 1 - Sign Line (json)
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 2 - Sign Line (json)
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 3 - Sign Line (json)
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 4 - Sign Line (json)
}
});
// Player Digging Packet
protocol.registerIncoming(State.PLAY, 0x07, 0x13, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Status
map(Type.POSITION); // 1 - Position
map(Type.UNSIGNED_BYTE); // 2 - Face
// TODO: Cancel if status == 6
// TODO: Blocking patch stopped if blocking and 5
}
});
// Block Placement Packet
protocol.registerIncoming(State.PLAY, 0x08, 0x1C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.POSITION); // 0 - Position
map(Type.VAR_INT, Type.BYTE); // 1 - Block Face
map(Type.VAR_INT, Type.NOTHING); // 2 - Hand
// TODO: Insert hand item here
// Did have item rewriter but its not needed
map(Type.UNSIGNED_BYTE); // 4 - X
map(Type.UNSIGNED_BYTE); // 5 - Y
map(Type.UNSIGNED_BYTE); // 6 - Z
}
});
}
}

View File

@ -39,6 +39,9 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Short> SHORT = new ShortType();
public static final Type<Short[]> SHORT_ARRAY = new ArrayType<>(Type.SHORT);
public static final Type<Integer> UNSIGNED_SHORT = new UnsignedShortType();
public static final Type<Integer[]> UNSIGNED_SHORT_ARRAY = new ArrayType<>(Type.UNSIGNED_SHORT);
/* Other Types */
public static final Type<String> STRING = new StringType();
public static final Type<String[]> STRING_ARRAY = new ArrayType<>(Type.STRING);

View File

@ -0,0 +1,20 @@
package us.myles.ViaVersion2.api.type.types;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion2.api.type.Type;
public class UnsignedShortType extends Type<Integer> {
public UnsignedShortType() {
super(Integer.class);
}
@Override
public Integer read(ByteBuf buffer) {
return buffer.readUnsignedShort();
}
@Override
public void write(ByteBuf buffer, Integer object) {
buffer.writeShort(object);
}
}