Using PacketType as a checklist, implement most of the base outgoing packets.

Add new REMAINING_BYTES type.
Add an outline of what ItemType will be like
Add a passthrough option to PacketWrapper to make it easy to passthrough and grab the type.
By default passthrough all the bytes :)
This commit is contained in:
Myles 2016-03-13 17:01:36 +00:00
parent 81d89d3839
commit 9b28129187
17 changed files with 765 additions and 86 deletions

View File

@ -54,88 +54,90 @@ public enum PacketType {
PLAY_PLAYER_BLOCK_PLACEMENT(State.PLAY, Direction.INCOMING, 0x08, 0x1C),
PLAY_USE_ITEM(State.PLAY, Direction.INCOMING, -1, 0x1D),
/* Play clientbound */
PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00),
PLAY_SPAWN_XP_ORB(State.PLAY, Direction.OUTGOING, 0x11, 0x01),
PLAY_SPAWN_GLOBAL_ENTITY(State.PLAY, Direction.OUTGOING, 0x2C, 0x02),
PLAY_SPAWN_MOB(State.PLAY, Direction.OUTGOING, 0x0F, 0x03),
PLAY_SPAWN_PAINTING(State.PLAY, Direction.OUTGOING, 0x10, 0x04),
PLAY_SPAWN_PLAYER(State.PLAY, Direction.OUTGOING, 0x0C, 0x05),
PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00), // Mapped
PLAY_SPAWN_XP_ORB(State.PLAY, Direction.OUTGOING, 0x11, 0x01), // Mapped
PLAY_SPAWN_GLOBAL_ENTITY(State.PLAY, Direction.OUTGOING, 0x2C, 0x02), // Mapped
PLAY_SPAWN_MOB(State.PLAY, Direction.OUTGOING, 0x0F, 0x03), // Mapped
PLAY_SPAWN_PAINTING(State.PLAY, Direction.OUTGOING, 0x10, 0x04), // Mapped
PLAY_SPAWN_PLAYER(State.PLAY, Direction.OUTGOING, 0x0C, 0x05), // Mapped
PLAY_ANIMATION(State.PLAY, Direction.OUTGOING, 0x0B, 0x06), // Mapped
PLAY_STATS(State.PLAY, Direction.OUTGOING, 0x37, 0x07), // Mapped
PLAY_BLOCK_BREAK_ANIMATION(State.PLAY, Direction.OUTGOING, 0x25, 0x08), // Mapped
PLAY_UPDATE_BLOCK_ENTITY(State.PLAY, Direction.OUTGOING, 0x35, 0x09), // Mapped
PLAY_BLOCK_ACTION(State.PLAY, Direction.OUTGOING, 0x24, 0x0A), // Mapped
PLAY_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x23, 0x0B), // Mapped
PLAY_ANIMATION(State.PLAY, Direction.OUTGOING, 0x0B, 0x06),
PLAY_STATS(State.PLAY, Direction.OUTGOING, 0x37, 0x07),
PLAY_BLOCK_BREAK_ANIMATION(State.PLAY, Direction.OUTGOING, 0x25, 0x08),
PLAY_UPDATE_BLOCK_ENTITY(State.PLAY, Direction.OUTGOING, 0x35, 0x09),
PLAY_BLOCK_ACTION(State.PLAY, Direction.OUTGOING, 0x24, 0x0A),
PLAY_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x23, 0x0B),
PLAY_BOSS_BAR(State.PLAY, Direction.OUTGOING, -1, 0x0C),
PLAY_SERVER_DIFFICULTY(State.PLAY, Direction.OUTGOING, 0x41, 0x0D),
PLAY_TAB_COMPLETE(State.PLAY, Direction.OUTGOING, 0x3A, 0x0E),
PLAY_CHAT_MESSAGE(State.PLAY, Direction.OUTGOING, 0x02, 0x0F),
PLAY_MULTI_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x22, 0x10),
PLAY_CONFIRM_TRANSACTION(State.PLAY, Direction.OUTGOING, 0x32, 0x11),
PLAY_CLOSE_WINDOW(State.PLAY, Direction.OUTGOING, 0x2E, 0x12),
PLAY_OPEN_WINDOW(State.PLAY, Direction.OUTGOING, 0x2D, 0x13),
PLAY_WINDOW_ITEMS(State.PLAY, Direction.OUTGOING, 0x30, 0x14),
PLAY_WINDOW_PROPERTY(State.PLAY, Direction.OUTGOING, 0x31, 0x15),
PLAY_SET_SLOT(State.PLAY, Direction.OUTGOING, 0x2F, 0x16),
PLAY_SERVER_DIFFICULTY(State.PLAY, Direction.OUTGOING, 0x41, 0x0D), // Mapped
PLAY_TAB_COMPLETE(State.PLAY, Direction.OUTGOING, 0x3A, 0x0E), // Mapped
PLAY_CHAT_MESSAGE(State.PLAY, Direction.OUTGOING, 0x02, 0x0F), // Mapped
PLAY_MULTI_BLOCK_CHANGE(State.PLAY, Direction.OUTGOING, 0x22, 0x10), // Mapped
PLAY_CONFIRM_TRANSACTION(State.PLAY, Direction.OUTGOING, 0x32, 0x11), // Mapped
PLAY_CLOSE_WINDOW(State.PLAY, Direction.OUTGOING, 0x2E, 0x12), // Mapped
PLAY_OPEN_WINDOW(State.PLAY, Direction.OUTGOING, 0x2D, 0x13), // Mapped
PLAY_WINDOW_ITEMS(State.PLAY, Direction.OUTGOING, 0x30, 0x14), // Mapped
PLAY_WINDOW_PROPERTY(State.PLAY, Direction.OUTGOING, 0x31, 0x15), // Mapped
PLAY_SET_SLOT(State.PLAY, Direction.OUTGOING, 0x2F, 0x16), // Mapped
PLAY_SET_COOLDOWN(State.PLAY, Direction.OUTGOING, -1, 0x17),
PLAY_PLUGIN_MESSAGE(State.PLAY, Direction.OUTGOING, 0x3F, 0x18),
PLAY_NAMED_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, 0x29, 0x19),
PLAY_DISCONNECT(State.PLAY, Direction.OUTGOING, 0x40, 0x1A),
PLAY_ENTITY_STATUS(State.PLAY, Direction.OUTGOING, 0x1A, 0x1B),
PLAY_EXPLOSION(State.PLAY, Direction.OUTGOING, 0x27, 0x1C),
PLAY_PLUGIN_MESSAGE(State.PLAY, Direction.OUTGOING, 0x3F, 0x18), // Mapped
PLAY_NAMED_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, 0x29, 0x19), // Mapped
PLAY_DISCONNECT(State.PLAY, Direction.OUTGOING, 0x40, 0x1A), // Mapped
PLAY_ENTITY_STATUS(State.PLAY, Direction.OUTGOING, 0x1A, 0x1B), // Mapped
PLAY_EXPLOSION(State.PLAY, Direction.OUTGOING, 0x27, 0x1C), // Mapped
PLAY_UNLOAD_CHUNK(State.PLAY, Direction.OUTGOING, -1, 0x1D),
PLAY_CHANGE_GAME_STATE(State.PLAY, Direction.OUTGOING, 0x2B, 0x1E),
PLAY_KEEP_ALIVE(State.PLAY, Direction.OUTGOING, 0x00, 0x1F),
PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20),
PLAY_EFFECT(State.PLAY, Direction.OUTGOING, 0x28, 0x21),
PLAY_PARTICLE(State.PLAY, Direction.OUTGOING, 0x2A, 0x22),
PLAY_JOIN_GAME(State.PLAY, Direction.OUTGOING, 0x01, 0x23),
PLAY_MAP(State.PLAY, Direction.OUTGOING, 0x34, 0x24),
PLAY_ENTITY_RELATIVE_MOVE(State.PLAY, Direction.OUTGOING, 0x15, 0x25),
PLAY_ENTITY_LOOK_MOVE(State.PLAY, Direction.OUTGOING, 0x17, 0x26),
PLAY_ENTITY_LOOK(State.PLAY, Direction.OUTGOING, 0x16, 0x27),
PLAY_ENTITY(State.PLAY, Direction.OUTGOING, 0x14, 0x28),
PLAY_KEEP_ALIVE(State.PLAY, Direction.OUTGOING, 0x00, 0x1F), // Mapped
PLAY_CHUNK_DATA(State.PLAY, Direction.OUTGOING, 0x21, 0x20), // TODO
PLAY_EFFECT(State.PLAY, Direction.OUTGOING, 0x28, 0x21), // Mapped
PLAY_PARTICLE(State.PLAY, Direction.OUTGOING, 0x2A, 0x22), // Mapped
PLAY_JOIN_GAME(State.PLAY, Direction.OUTGOING, 0x01, 0x23), // Mapped
PLAY_MAP(State.PLAY, Direction.OUTGOING, 0x34, 0x24), // Mapped
PLAY_ENTITY_RELATIVE_MOVE(State.PLAY, Direction.OUTGOING, 0x15, 0x25), // Mapped
PLAY_ENTITY_LOOK_MOVE(State.PLAY, Direction.OUTGOING, 0x17, 0x26), // Mapped
PLAY_ENTITY_LOOK(State.PLAY, Direction.OUTGOING, 0x16, 0x27), // Mapped
PLAY_ENTITY(State.PLAY, Direction.OUTGOING, 0x14, 0x28), // Mapped
PLAY_VEHICLE_MOVE(State.PLAY, Direction.OUTGOING, -1, 0x29),
PLAY_OPEN_SIGN_EDITOR(State.PLAY, Direction.OUTGOING, 0x36, 0x2A),
PLAY_PLAYER_ABILITIES(State.PLAY, Direction.OUTGOING, 0x39, 0x2B),
PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C),
PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D),
PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E),
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F),
PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30),
PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31),
PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32),
PLAY_RESPAWN(State.PLAY, Direction.OUTGOING, 0x07, 0x33),
PLAY_ENTITY_HEAD_LOOK(State.PLAY, Direction.OUTGOING, 0x19, 0x34),
PLAY_WORLD_BORDER(State.PLAY, Direction.OUTGOING, 0x44, 0x35),
PLAY_CAMERA(State.PLAY, Direction.OUTGOING, 0x43, 0x36),
PLAY_HELD_ITEM_CHANGE(State.PLAY, Direction.OUTGOING, 0x09, 0x37),
PLAY_DISPLAY_SCOREBOARD(State.PLAY, Direction.OUTGOING, 0x3D, 0x38),
PLAY_ENTITY_METADATA(State.PLAY, Direction.OUTGOING, 0x1C, 0x39),
PLAY_ATTACH_ENTITY(State.PLAY, Direction.OUTGOING, 0x1B, 0x3A),
PLAY_ENTITY_VELOCITY(State.PLAY, Direction.OUTGOING, 0x12, 0x3B),
PLAY_ENTITY_EQUIPMENT(State.PLAY, Direction.OUTGOING, 0x04, 0x3C),
PLAY_SET_XP(State.PLAY, Direction.OUTGOING, 0x1F, 0x3D),
PLAY_UPDATE_HEALTH(State.PLAY, Direction.OUTGOING, 0x06, 0x3E),
PLAY_SCOREBOARD_OBJ(State.PLAY, Direction.OUTGOING, 0x3B, 0x3F),
PLAY_OPEN_SIGN_EDITOR(State.PLAY, Direction.OUTGOING, 0x36, 0x2A), // Mapped
PLAY_PLAYER_ABILITIES(State.PLAY, Direction.OUTGOING, 0x39, 0x2B), // Mapped
PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C), // Mapped
PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D), // Mapped
PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E), // Mapped
PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F), // Mapped
PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30), // Mapped
PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31), // Mapped
PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32), // Mapped
PLAY_RESPAWN(State.PLAY, Direction.OUTGOING, 0x07, 0x33), // Mapped
PLAY_ENTITY_HEAD_LOOK(State.PLAY, Direction.OUTGOING, 0x19, 0x34), // Mapped
PLAY_WORLD_BORDER(State.PLAY, Direction.OUTGOING, 0x44, 0x35), // Mapped
PLAY_CAMERA(State.PLAY, Direction.OUTGOING, 0x43, 0x36), // Mapped
PLAY_HELD_ITEM_CHANGE(State.PLAY, Direction.OUTGOING, 0x09, 0x37), // Mapped
PLAY_DISPLAY_SCOREBOARD(State.PLAY, Direction.OUTGOING, 0x3D, 0x38), // Mapped
PLAY_ENTITY_METADATA(State.PLAY, Direction.OUTGOING, 0x1C, 0x39), // Mapped
PLAY_ATTACH_ENTITY(State.PLAY, Direction.OUTGOING, 0x1B, 0x3A), // Mapped
PLAY_ENTITY_VELOCITY(State.PLAY, Direction.OUTGOING, 0x12, 0x3B), // Mapped
PLAY_ENTITY_EQUIPMENT(State.PLAY, Direction.OUTGOING, 0x04, 0x3C), // Mapped
PLAY_SET_XP(State.PLAY, Direction.OUTGOING, 0x1F, 0x3D), // Mapped
PLAY_UPDATE_HEALTH(State.PLAY, Direction.OUTGOING, 0x06, 0x3E), // Mapped
PLAY_SCOREBOARD_OBJ(State.PLAY, Direction.OUTGOING, 0x3B, 0x3F), // Mapped
PLAY_SET_PASSENGERS(State.PLAY, Direction.OUTGOING, -1, 0x40),
PLAY_TEAM(State.PLAY, Direction.OUTGOING, 0x3E, 0x41),
PLAY_UPDATE_SCORE(State.PLAY, Direction.OUTGOING, 0x3C, 0x42),
PLAY_SPAWN_POSITION(State.PLAY, Direction.OUTGOING, 0x05, 0x43),
PLAY_TIME_UPDATE(State.PLAY, Direction.OUTGOING, 0x03, 0x44),
PLAY_TITLE(State.PLAY, Direction.OUTGOING, 0x45, 0x45),
PLAY_UPDATE_SIGN(State.PLAY, Direction.OUTGOING, 0x33, 0x46),
PLAY_TEAM(State.PLAY, Direction.OUTGOING, 0x3E, 0x41), // Mapped
PLAY_UPDATE_SCORE(State.PLAY, Direction.OUTGOING, 0x3C, 0x42), // Mapped
PLAY_SPAWN_POSITION(State.PLAY, Direction.OUTGOING, 0x05, 0x43), // Mapped
PLAY_TIME_UPDATE(State.PLAY, Direction.OUTGOING, 0x03, 0x44), // Mapped
PLAY_TITLE(State.PLAY, Direction.OUTGOING, 0x45, 0x45), // Mapped
PLAY_UPDATE_SIGN(State.PLAY, Direction.OUTGOING, 0x33, 0x46), // Mapped
PLAY_SOUND_EFFECT(State.PLAY, Direction.OUTGOING, -1, 0x47),
PLAY_PLAYER_LIST_HEADER_FOOTER(State.PLAY, Direction.OUTGOING, 0x47, 0x48),
PLAY_COLLECT_ITEM(State.PLAY, Direction.OUTGOING, 0x0D, 0x49),
PLAY_ENTITY_TELEPORT(State.PLAY, Direction.OUTGOING, 0x18, 0x4A),
PLAY_ENTITY_PROPERTIES(State.PLAY, Direction.OUTGOING, 0x20, 0x4B),
PLAY_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1D, 0x4C),
PLAY_PLAYER_LIST_HEADER_FOOTER(State.PLAY, Direction.OUTGOING, 0x47, 0x48), // Mapped
PLAY_COLLECT_ITEM(State.PLAY, Direction.OUTGOING, 0x0D, 0x49), // Mapped
PLAY_ENTITY_TELEPORT(State.PLAY, Direction.OUTGOING, 0x18, 0x4A), // Mapped
PLAY_ENTITY_PROPERTIES(State.PLAY, Direction.OUTGOING, 0x20, 0x4B), // Mapped
PLAY_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1D, 0x4C), // Mapped
PLAY_MAP_CHUNK_BULK(State.PLAY, Direction.OUTGOING, 0x26, -1),
PLAY_SET_COMPRESSION(State.PLAY, Direction.OUTGOING, 0x46, -1),
PLAY_UPDATE_ENTITY_NBT(State.PLAY, Direction.OUTGOING, 0x49, -1),;
PLAY_MAP_CHUNK_BULK(State.PLAY, Direction.OUTGOING, 0x26, -1), // TODO?
PLAY_SET_COMPRESSION(State.PLAY, Direction.OUTGOING, 0x46, -1), // TODO?
PLAY_UPDATE_ENTITY_NBT(State.PLAY, Direction.OUTGOING, 0x49, -1),; // TODO?
private State state;
private Direction direction;

View File

@ -43,6 +43,12 @@ public class PacketWrapper {
packetValues.add(new Pair<Type, Object>(type, value));
}
public <T> T passthrough(Type<T> type) {
T value = read(type);
write(type, value);
return value;
}
public void writeToBuffer(ByteBuf buffer) {
for (Pair<Type, Object> packetValue : packetValues) {
packetValue.getKey().write(buffer, packetValue.getValue());
@ -50,6 +56,7 @@ public class PacketWrapper {
}
public void writeRemaining(ByteBuf output) {
System.out.println("Writing remaining: " + output.readableBytes());
output.writeBytes(inputBuffer);
}

View File

@ -0,0 +1,4 @@
package us.myles.ViaVersion2.api.item;
public class Item {
}

View File

@ -65,10 +65,9 @@ public abstract class Protocol {
protocolPacket.getRemapper().remap(packetWrapper);
// write to output
packetWrapper.writeToBuffer(output);
} else {
// pass through
packetWrapper.writeRemaining(output);
}
// pass through
packetWrapper.writeRemaining(output);
}
@AllArgsConstructor

View File

@ -1,4 +1,4 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8.types;
package us.myles.ViaVersion2.api.protocol1_9to1_8;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

View File

@ -1,25 +1,56 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import us.myles.ViaVersion2.api.PacketWrapper;
import us.myles.ViaVersion2.api.data.UserConnection;
import us.myles.ViaVersion2.api.metadata.Metadata;
import us.myles.ViaVersion2.api.protocol.Protocol;
import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.SpawnPackets;
import us.myles.ViaVersion2.api.protocol1_9to1_8.packets.*;
import us.myles.ViaVersion2.api.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataListType;
import us.myles.ViaVersion2.api.protocol1_9to1_8.types.MetadataType;
import us.myles.ViaVersion2.api.remapper.ValueTransformer;
import us.myles.ViaVersion2.api.type.Type;
import java.util.List;
public class Protocol1_9TO1_8 extends Protocol {
public static Type<List<Metadata>> METADATA_LIST = new MetadataListType();
public static Type<Metadata> METADATA = new MetadataType();
public static ValueTransformer<String, String> FIX_JSON = new ValueTransformer<String, String>(Type.STRING) {
@Override
public String transform(PacketWrapper wrapper, String line) {
if (line == null || line.equalsIgnoreCase("null")) {
line = "{\"text\":\"\"}";
} else {
if ((!line.startsWith("\"") || !line.endsWith("\"")) && (!line.startsWith("{") || !line.endsWith("}"))) {
JSONObject obj = new JSONObject();
obj.put("text", line);
return obj.toJSONString();
}
if (line.startsWith("\"") && line.endsWith("\"")) {
line = "{\"text\":" + line + "}";
}
}
try {
new JSONParser().parse(line);
} catch (Exception e) {
System.out.println("Invalid JSON String: \"" + line + "\" Please report this issue to the ViaVersion Github: " + e.getMessage());
return "{\"text\":\"\"}";
}
return line;
}
};
@Override
protected void registerPackets() {
// Example PLAY_SPAWN_OBJECT(State.PLAY, Direction.OUTGOING, 0x0E, 0x00),
SpawnPackets.register(this);
InventoryPackets.register(this);
EntityPackets.register(this);
PlayerPackets.register(this);
WorldPackets.register(this);
}
@Override

View File

@ -0,0 +1,150 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8.packets;
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.PacketRemapper;
import us.myles.ViaVersion2.api.remapper.ValueTransformer;
import us.myles.ViaVersion2.api.type.Type;
public class EntityPackets {
public static ValueTransformer<Byte, Short> toNewShort = new ValueTransformer<Byte, Short>(Type.SHORT) {
@Override
public Short transform(PacketWrapper wrapper, Byte inputValue) {
return (short) (inputValue * 128);
}
};
public static void register(Protocol protocol) {
// Attach Entity Packet
protocol.registerOutgoing(State.PLAY, 0x1B, 0x3A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Entity ID
map(Type.INT); // 1 - Vehicle
// Leash boolean is removed in new versions
map(Type.BOOLEAN, new ValueTransformer<Boolean, Void>(Type.NOTHING) {
@Override
public Void transform(PacketWrapper wrapper, Boolean inputValue) {
if(!inputValue){
// TODO: Write Set Passengers packet
}
return null;
}
});
}
});
// Entity Teleport Packet
protocol.registerOutgoing(State.PLAY, 0x18, 0x4A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.INT, SpawnPackets.toNewDouble); // 1 - X - Needs to be divide by 32
map(Type.INT, SpawnPackets.toNewDouble); // 2 - Y - Needs to be divide by 32
map(Type.INT, SpawnPackets.toNewDouble); // 3 - Z - Needs to be divide by 32
map(Type.BYTE); // 4 - Pitch
map(Type.BYTE); // 5 - Yaw
map(Type.BOOLEAN); // 6 - On Ground
// TODO: Move holograms up on Y by offset (*32)
}
});
// Entity Look Move Packet
protocol.registerOutgoing(State.PLAY, 0x17, 0x26, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE, toNewShort); // 1 - X
map(Type.BYTE, toNewShort); // 2 - Y
map(Type.BYTE, toNewShort); // 3 - Z
map(Type.BYTE); // 4 - Yaw
map(Type.BYTE); // 5 - Pitch
map(Type.BOOLEAN); // 6 - On Ground
// TODO: Hologram patch moves down by 1 in Y
}
});
// Entity Relative Move Packet
protocol.registerOutgoing(State.PLAY, 0x15, 0x25, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE, toNewShort); // 1 - X
map(Type.BYTE, toNewShort); // 2 - Y
map(Type.BYTE, toNewShort); // 3 - Z
map(Type.BOOLEAN); // 4 - On Ground
// TODO: Hologram patch moves down by 1 in Y
}
});
// Entity Equipment Packet
protocol.registerOutgoing(State.PLAY, 0x04, 0x3C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
// 1 - Slot ID
map(Type.SHORT, new ValueTransformer<Short, Integer>(Type.VAR_INT) {
@Override
public Integer transform(PacketWrapper wrapper, Short slot) {
return slot > 0 ? slot.intValue() + 1 : slot.intValue();
}
});
map(Type.ITEM); // 2 - Item
// TODO - Blocking patch
// TODO - ItemStack rewriter
}
});
// Entity Metadata Packet
protocol.registerOutgoing(State.PLAY, 0x1C, 0x39, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Protocol1_9TO1_8.METADATA_LIST); // 1 - Metadata List
// TODO Transform metadata
}
});
// Entity Effect Packet
protocol.registerOutgoing(State.PLAY, 0x1D, 0x4C, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Entity ID
map(Type.BYTE); // 1 - Effect ID
map(Type.BYTE); // 2 - Amplifier
map(Type.VAR_INT); // 3 - Duration
map(Type.BOOLEAN, Type.BYTE); // 4 - Hide particles
// TODO: Test particles as conversion might not work
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x20, 0x4B); // Entity Properties Packet
protocol.registerOutgoing(State.PLAY, 0x1A, 0x1B); // Entity Status Packet
protocol.registerOutgoing(State.PLAY, 0x16, 0x27); // Entity Look Packet
protocol.registerOutgoing(State.PLAY, 0x14, 0x28); // Entity Packet
protocol.registerOutgoing(State.PLAY, 0x42, 0x2C); // Combat Event Packet
protocol.registerOutgoing(State.PLAY, 0x0A, 0x2F); // Use Bed Packet
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
}
}

View File

@ -0,0 +1,94 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8.packets;
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.PacketRemapper;
import us.myles.ViaVersion2.api.remapper.ValueCreator;
import us.myles.ViaVersion2.api.type.Type;
public class InventoryPackets {
public static void register(Protocol protocol) {
// Window Property Packet
protocol.registerOutgoing(State.PLAY, 0x31, 0x15, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Property Key
map(Type.SHORT); // 2 - Property Value
// TODO - Enchanting patch
}
});
// Window Open Packet
protocol.registerOutgoing(State.PLAY, 0x2D, 0x13, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.STRING); // 1 - Window Type
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 2 - Window Title
map(Type.UNSIGNED_BYTE); // 3 - Slot Count
// There is a horse parameter after this, we don't handle it and let it passthrough
// TODO - Brewing patch
// TODO - Save Inventory patch
}
});
// Window Set Slot Packet
protocol.registerOutgoing(State.PLAY, 0x2F, 0x16, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
// TODO Brewing patch
// TODO - ItemStack rewriter
}
});
// Window Set Slots Packet
protocol.registerOutgoing(State.PLAY, 0x30, 0x14, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY); // 1 - Window Values
// TODO Brewing patch
// TODO - ItemStack rewriter
}
});
// Close Window Packet
protocol.registerOutgoing(State.PLAY, 0x2E, 0x12, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
// TODO Close Inventory patch
}
});
// Map Packet
protocol.registerOutgoing(State.PLAY, 0x34, 0x24, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Map ID
map(Type.BYTE); // 1 - Map Scale
create(new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) {
wrapper.write(Type.BOOLEAN, true); // 2 - Show marker
}
});
// Everything else is passed through
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x32, 0x11); // Confirm Transaction Packet
}
}

View File

@ -0,0 +1,228 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8.packets;
import org.bukkit.entity.EntityType;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
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.protocol1_9to1_8.storage.EntityTracker;
import us.myles.ViaVersion2.api.remapper.PacketHandler;
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
import us.myles.ViaVersion2.api.remapper.ValueCreator;
import us.myles.ViaVersion2.api.type.Type;
public class PlayerPackets {
public static void register(Protocol protocol) {
// Chat Message Packet
protocol.registerOutgoing(State.PLAY, 0x02, 0x0F, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 0 - Chat Message (json)
map(Type.BYTE); // 1 - Chat Positon
}
});
// Header and Footer Packet
protocol.registerOutgoing(State.PLAY, 0x47, 0x48, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 0 - Header
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 1 - Footer
}
});
// Disconnect Packet
protocol.registerOutgoing(State.PLAY, 0x40, 0x1A, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 0 - Reason
}
});
// Title Packet
protocol.registerOutgoing(State.PLAY, 0x45, 0x45, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Action
// We only handle if the title or subtitle is set then just write through.
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
int action = wrapper.get(Type.VAR_INT, 0);
if (action == 0 || action == 1) {
Protocol1_9TO1_8.FIX_JSON.write(wrapper, wrapper.read(Type.STRING));
}
}
});
// Everything else is handled.
}
});
// Player Position Packet
protocol.registerOutgoing(State.PLAY, 0x08, 0x2E, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.DOUBLE); // 0 - Player X
map(Type.DOUBLE); // 1 - Player Y
map(Type.DOUBLE); // 2 - Player Z
map(Type.FLOAT); // 3 - Player Yaw
map(Type.FLOAT); // 4 - Player Pitch
map(Type.BYTE); // 5 - Player Flags
create(new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) {
wrapper.write(Type.VAR_INT, 0); // 6 - Teleport ID was added
}
});
}
});
// Team Packet
protocol.registerOutgoing(State.PLAY, 0x3E, 0x41, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING);
map(Type.BYTE);
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
byte mode = wrapper.get(Type.BYTE, 1);
if (mode == 0 || mode == 2) {
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.BYTE);
wrapper.passthrough(Type.STRING);
wrapper.write(Type.STRING, ((ViaVersionPlugin) ViaVersion.getInstance()).isPreventCollision() ? "never" : "");
wrapper.passthrough(Type.BYTE);
}
if (mode == 0 || mode == 2) {
String[] players = wrapper.read(Type.STRING_ARRAY);
// TODO Handler for sending autoteam
wrapper.write(Type.STRING_ARRAY, players);
}
}
});
}
});
// Join Game Packet
protocol.registerOutgoing(State.PLAY, 0x01, 0x23, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Player ID
// Parse this info
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
int entityID = wrapper.get(Type.INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityID, EntityType.PLAYER);
}
});
map(Type.UNSIGNED_BYTE); // 1 - Player Gamemode
map(Type.BYTE); // 2 - Player Dimension
map(Type.UNSIGNED_BYTE); // 3 - World Difficulty
map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab)
map(Type.STRING); // 5 - Level Type
map(Type.BOOLEAN); // 6 - Reduced Debug info
// TODO Register player ID as self ID
}
});
// Player List Item Packet
protocol.registerOutgoing(State.PLAY, 0x38, 0x2D, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Action
map(Type.VAR_INT); // 1 - Player Count
// Due to this being a complex data structure we just use a handler.
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
int action = wrapper.get(Type.VAR_INT, 0);
int count = wrapper.get(Type.VAR_INT, 1);
for (int i = 0; i < count; i++) {
wrapper.passthrough(Type.UUID); // Player UUID
if (action == 0) { // add player
wrapper.passthrough(Type.STRING); // Player Name
int properties = wrapper.passthrough(Type.VAR_INT);
// loop through properties
for (int j = 0; j < properties; j++) {
wrapper.passthrough(Type.STRING); // name
wrapper.passthrough(Type.STRING); // value
boolean isSigned = wrapper.passthrough(Type.BOOLEAN);
if (isSigned) {
wrapper.passthrough(Type.STRING); // signature
}
}
wrapper.passthrough(Type.VAR_INT); // gamemode
wrapper.passthrough(Type.VAR_INT); // ping
boolean hasDisplayName = wrapper.passthrough(Type.BOOLEAN);
if (hasDisplayName) {
Protocol1_9TO1_8.FIX_JSON.write(wrapper, wrapper.read(Type.STRING)); // display name
}
} else if ((action == 1) || (action == 2)) { // update gamemode || update latency
wrapper.passthrough(Type.VAR_INT);
} else if (action == 3) { // update display name
boolean hasDisplayName = wrapper.passthrough(Type.BOOLEAN);
if (hasDisplayName) {
Protocol1_9TO1_8.FIX_JSON.write(wrapper, wrapper.read(Type.STRING)); // display name
}
} else if (action == 4) { // remove player
// no fields
}
}
}
});
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x3A, 0x0E); // Tab Complete Response Packet
protocol.registerOutgoing(State.PLAY, 0x0B, 0x06); // Animation Packet
protocol.registerOutgoing(State.PLAY, 0x37, 0x07); // Stats Packet
protocol.registerOutgoing(State.PLAY, 0x36, 0x2A); // Open Sign Editor Packet
protocol.registerOutgoing(State.PLAY, 0x39, 0x2B); // Player Abilities Packet
protocol.registerOutgoing(State.PLAY, 0x00, 0x1F); // Keep Alive Packet
protocol.registerOutgoing(State.PLAY, 0x48, 0x32); // Resource Pack Send Packet
protocol.registerOutgoing(State.PLAY, 0x07, 0x33); // Respawn Packet
protocol.registerOutgoing(State.PLAY, 0x43, 0x36); // Camera Packet
protocol.registerOutgoing(State.PLAY, 0x09, 0x37); // Held Item Change Packet
protocol.registerOutgoing(State.PLAY, 0x3D, 0x38); // Display Scoreboard Packet
protocol.registerOutgoing(State.PLAY, 0x3B, 0x3F); // Scoreboard Objective Packet
protocol.registerOutgoing(State.PLAY, 0x3C, 0x42); // Update Score Packet
protocol.registerOutgoing(State.PLAY, 0x05, 0x43); // Spawn Position Packet
protocol.registerOutgoing(State.PLAY, 0x1F, 0x3D); // Set XP Packet
protocol.registerOutgoing(State.PLAY, 0x06, 0x3E); // Update Health Packet
protocol.registerOutgoing(State.PLAY, 0x0D, 0x49); // Collect Item Packet
protocol.registerOutgoing(State.PLAY, 0x3F, 0x18); // Plugin Message
// TODO:
// Login Success - Save UUID and Username
// Server Difficulty - Activate Auto-Team
// TODO: Status Response, implement? (Might be implemented by a base protocol?)
}
}

View File

@ -14,7 +14,7 @@ import us.myles.ViaVersion2.api.remapper.ValueTransformer;
import us.myles.ViaVersion2.api.type.Type;
public class SpawnPackets {
private static ValueTransformer<Integer, Double> toNewDouble = new ValueTransformer<Integer, Double>(Type.DOUBLE) {
public static ValueTransformer<Integer, Double> toNewDouble = new ValueTransformer<Integer, Double>(Type.DOUBLE) {
@Override
public Double transform(PacketWrapper wrapper, Integer inputValue) {
return inputValue / 32D;
@ -224,5 +224,26 @@ public class SpawnPackets {
map(Protocol1_9TO1_8.METADATA_LIST);
}
});
// Entity Destroy Packet
protocol.registerOutgoing(State.PLAY, 0x13, 0x30, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT_ARRAY); // 0 - Entities to destroy
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) {
Integer[] entities = wrapper.get(Type.VAR_INT_ARRAY, 0);
for (Integer entity : entities) {
// EntityTracker
wrapper.user().get(EntityTracker.class).removeEntity(entity);
// TODO: When holograms added and bossbars, remove too
}
}
});
}
});
}
}

View File

@ -0,0 +1,63 @@
package us.myles.ViaVersion2.api.protocol1_9to1_8.packets;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion2.api.protocol.Protocol;
import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8;
import us.myles.ViaVersion2.api.remapper.PacketRemapper;
import us.myles.ViaVersion2.api.type.Type;
public class WorldPackets {
public static void register(Protocol protocol) {
// Sign Update Packet
protocol.registerOutgoing(State.PLAY, 0x33, 0x46, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.LONG); // 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)
}
});
// Play Effect Packet
protocol.registerOutgoing(State.PLAY, 0x28, 0x21, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Effect ID
// Everything else get's written through
// TODO: Effect canceller patch
}
});
// Play Named Sound Effect Packet
protocol.registerOutgoing(State.PLAY, 0x29, 0x19, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING); // 0 - Sound Name
// 1 - Sound Category ID
// Everything else get's written through
// TODO: Sound Effect translator patch
}
});
/* Packets which do not have any field remapping or handlers */
protocol.registerOutgoing(State.PLAY, 0x25, 0x08); // Block Break Animation Packet
protocol.registerOutgoing(State.PLAY, 0x35, 0x09); // Update Block Entity Packet
// TODO: Update_Block_Entity actually implement
protocol.registerOutgoing(State.PLAY, 0x24, 0x0A); // Block Action Packet
protocol.registerOutgoing(State.PLAY, 0x23, 0x0B); // Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x22, 0x10); // Multi Block Change Packet
protocol.registerOutgoing(State.PLAY, 0x27, 0x1C); // Explosion Packet
protocol.registerOutgoing(State.PLAY, 0x2A, 0x22); // Particle Packet
protocol.registerOutgoing(State.PLAY, 0x41, 0x0D); // Server Difficulty Packet
protocol.registerOutgoing(State.PLAY, 0x03, 0x44); // Update Time Packet
protocol.registerOutgoing(State.PLAY, 0x44, 0x35); // World Border Packet
// TODO: Chunk Data, Bulk Chunk :)
}
}

View File

@ -23,4 +23,8 @@ public class EntityTracker extends StoredObject{
return uuid;
}
}
public void removeEntity(Integer entityID) {
clientEntityTypes.remove(entityID);
}
}

View File

@ -3,6 +3,7 @@ package us.myles.ViaVersion2.api.protocol1_9to1_8.types;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion2.api.metadata.Metadata;
import us.myles.ViaVersion2.api.protocol1_9to1_8.MetadataTypes;
import us.myles.ViaVersion2.api.type.Type;
public class MetadataType extends Type<Metadata> {

View File

@ -4,10 +4,9 @@ package us.myles.ViaVersion2.api.type;
import lombok.Getter;
import org.bukkit.util.EulerAngle;
import org.bukkit.util.Vector;
import us.myles.ViaVersion2.api.item.Item;
import us.myles.ViaVersion2.api.type.types.*;
import us.myles.ViaVersion2.api.type.types.minecraft.EulerAngleType;
import us.myles.ViaVersion2.api.type.types.minecraft.PositionType;
import us.myles.ViaVersion2.api.type.types.minecraft.VectorType;
import us.myles.ViaVersion2.api.type.types.minecraft.*;
import us.myles.ViaVersion2.api.util.Position;
import java.util.UUID;
@ -18,6 +17,8 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Byte> BYTE = new ByteType();
public static final Type<Byte[]> BYTE_ARRAY = new ArrayType<>(Type.BYTE);
public static final Type<byte[]> REMAINING_BYTES = new RemainingBytesType();
public static final Type<Short> UNSIGNED_BYTE = new UnsignedByteType();
public static final Type<Short[]> UNSIGNED_BYTE_ARRAY = new ArrayType<>(Type.UNSIGNED_BYTE);
@ -53,8 +54,8 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
public static final Type<Position> POSITION = new PositionType();
public static final Type<EulerAngle> ROTATION = new EulerAngleType();
public static final Type<Vector> VECTOR = new VectorType();
public static final Type<Object> ITEM = null; // TODO
public static final Type<Item> ITEM = new ItemType(); // TODO
public static final Type<Item[]> ITEM_ARRAY = new ItemArrayType();
/* Actual Class */
private final Class<? super T> outputClass;

View File

@ -0,0 +1,22 @@
package us.myles.ViaVersion2.api.type.types;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion2.api.type.Type;
public class RemainingBytesType extends Type<byte[]> {
public RemainingBytesType() {
super(byte[].class);
}
@Override
public byte[] read(ByteBuf buffer) {
byte[] array = new byte[buffer.readableBytes()];
buffer.readBytes(array);
return array;
}
@Override
public void write(ByteBuf buffer, byte[] object) {
buffer.writeBytes(object);
}
}

View File

@ -0,0 +1,30 @@
package us.myles.ViaVersion2.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion2.api.item.Item;
import us.myles.ViaVersion2.api.type.Type;
public class ItemArrayType extends Type<Item[]> {
public ItemArrayType() {
super("Item Array", Item[].class);
}
@Override
public Item[] read(ByteBuf buffer) {
int amount = Type.SHORT.read(buffer);
Item[] array = new Item[amount];
for (int i = 0; i < amount; i++) {
array[i] = Type.ITEM.read(buffer);
}
return array;
}
@Override
public void write(ByteBuf buffer, Item[] object) {
Type.VAR_INT.write(buffer, object.length);
for (Item o : object) {
Type.ITEM.write(buffer, o);
}
}
}

View File

@ -0,0 +1,22 @@
package us.myles.ViaVersion2.api.type.types.minecraft;
import io.netty.buffer.ByteBuf;
import us.myles.ViaVersion2.api.item.Item;
import us.myles.ViaVersion2.api.type.Type;
// TODO: Implement this class
public class ItemType extends Type<Item> {
public ItemType() {
super(Item.class);
}
@Override
public Item read(ByteBuf buffer) {
return null;
}
@Override
public void write(ByteBuf buffer, Item object) {
}
}