From 4d7b1da29e0957ac798ee8e6da8288cbd4ae5c79 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Thu, 18 May 2017 19:03:05 +0500 Subject: 2017-05-18 --- src/packet/Field.cpp | 304 +++++++++++++++++++++++++++++++++++++++++++ src/packet/Field.hpp | 119 +++++++++++++++++ src/packet/FieldParser.cpp | 106 +++++++++++++++ src/packet/FieldParser.hpp | 30 +++++ src/packet/Packet.cpp | 100 ++++++++++++++ src/packet/Packet.hpp | 130 ++++++++++++++++++ src/packet/PacketBuilder.cpp | 65 +++++++++ src/packet/PacketBuilder.hpp | 17 +++ src/packet/PacketParser.cpp | 147 +++++++++++++++++++++ src/packet/PacketParser.hpp | 38 ++++++ 10 files changed, 1056 insertions(+) create mode 100644 src/packet/Field.cpp create mode 100644 src/packet/Field.hpp create mode 100644 src/packet/FieldParser.cpp create mode 100644 src/packet/FieldParser.hpp create mode 100644 src/packet/Packet.cpp create mode 100644 src/packet/Packet.hpp create mode 100644 src/packet/PacketBuilder.cpp create mode 100644 src/packet/PacketBuilder.hpp create mode 100644 src/packet/PacketParser.cpp create mode 100644 src/packet/PacketParser.hpp (limited to 'src/packet') diff --git a/src/packet/Field.cpp b/src/packet/Field.cpp new file mode 100644 index 0000000..69402f1 --- /dev/null +++ b/src/packet/Field.cpp @@ -0,0 +1,304 @@ +#include +#include "Field.hpp" + +Field::Field() { +} + +Field::Field(const Field &other) : m_dataLength(other.m_dataLength), m_type(other.m_type) { + + m_data = new byte[m_dataLength]; + std::copy(other.m_data,other.m_data+m_dataLength,m_data); +} + +void Field::swap(Field &other) { + std::swap(other.m_dataLength, m_dataLength); + std::swap(other.m_data, m_data); + std::swap(other.m_type, m_type); +} + +Field &Field::operator=(Field other) { + other.swap(*this); + return *this; +} + +Field::~Field() { + Clear(); +} + +size_t Field::GetLength() { + if (m_data != nullptr && m_dataLength == 0) + throw 102; + return m_dataLength; +} + +void Field::Clear() { + m_dataLength = 0; + delete[] m_data; + m_data = nullptr; +} + +void Field::CopyToBuff(byte *ptr) { + if (m_dataLength > 0) + std::copy(m_data,m_data+m_dataLength,ptr); +} + +void Field::SetRaw(byte *ptr, size_t len, FieldType type) { + Clear(); + m_dataLength = len; + m_type = type; + m_data = new byte[m_dataLength]; + std::copy(ptr,ptr+m_dataLength,m_data); +} + +int Field::GetVarInt() { + + size_t readed; + return VarIntRead(m_data, readed); + +} + +void Field::SetVarInt(int value) { + Clear(); + m_type = VarInt; + m_data = new byte[5]; + m_dataLength = VarIntWrite(value, m_data); +} + +int Field::GetInt() { + int value = *(reinterpret_cast(m_data)); + endswap(&value); + return value; +} + +void Field::SetInt(int value) { + Clear(); + m_type = Int; + m_data = new byte[4]; + m_dataLength = 4; + int *p = reinterpret_cast(m_data); + *p = value; + endswap(p); +} + +bool Field::GetBool() { + return *m_data != 0x00; +} + +void Field::SetBool(bool value) { + Clear(); + m_type = Boolean; + m_data = new byte[1]; + m_dataLength = 1; + *m_data = value ? 0x01 : 0x00; +} + +unsigned short Field::GetUShort() { + unsigned short *p = reinterpret_cast(m_data); + unsigned short t = *p; + endswap(&t); + return t; +} + +void Field::SetUShort(unsigned short value) { + Clear(); + m_type = UnsignedShort; + m_dataLength = 2; + m_data = new byte[2]; + unsigned short *p = reinterpret_cast(m_data); + *p = value; + endswap(p); +} + +std::string Field::GetString() { + Field fLen; + byte *ptr = m_data; + size_t l; + int val = VarIntRead(ptr, l); + ptr += l; + std::string s((char *) ptr, val); + return s; +} + +void Field::SetString(std::string value) { + Clear(); + m_type = String; + Field fLen; + fLen.SetVarInt(value.size()); + m_dataLength = value.size() + fLen.GetLength(); + m_data = new byte[m_dataLength]; + byte *p = m_data; + fLen.CopyToBuff(p); + p += fLen.GetLength(); + std::copy(value.begin(),value.end(),p); +} + +long long Field::GetLong() { + long long t = *reinterpret_cast(m_data); + endswap(&t); + return t; +} + +void Field::SetLong(long long value) { + Clear(); + m_type = Long; + m_dataLength = 8; + m_data = new byte[m_dataLength]; + long long *p = reinterpret_cast(m_data); + *p = value; + endswap(p); +} + +FieldType Field::GetType() { + return m_type; +} + +byte Field::GetUByte() { + byte t = *reinterpret_cast(m_data); + endswap(&t); + return t; +} + +void Field::SetUByte(byte value) { + Clear(); + m_type = UnsignedByte; + endswap(&value); + m_dataLength = 1; + m_data = new byte[m_dataLength]; + byte *p = reinterpret_cast(m_data); + *p = value; +} + +sbyte Field::GetByte() { + sbyte t = *reinterpret_cast(m_data); + endswap(&t); + return t; +} + +void Field::SetByte(sbyte value) { + Clear(); + m_type = Byte8_t; + endswap(&value); + m_dataLength = 1; + m_data = new byte[m_dataLength]; + sbyte *p = reinterpret_cast(m_data); + *p = value; +} + +float Field::GetFloat() { + float t = *reinterpret_cast(m_data); + endswap(&t); + return t; +} + +void Field::SetFloat(float value) { + Clear(); + m_type = Float; + endswap(&value); + m_dataLength = 4; + m_data = new byte[m_dataLength]; + float *p = reinterpret_cast(m_data); + *p = value; +} + +Vector Field::GetPosition() { + unsigned long long t = *reinterpret_cast(m_data); + endswap(&t); + int x = t >> 38; + int y = (t >> 26) & 0xFFF; + int z = t << 38 >> 38; + if (x >= pow(2, 25)) { + x -= pow(2, 26); + } + if (y >= pow(2, 11)) { + y -= pow(2, 12); + } + if (z >= pow(2, 25)) { + z -= pow(2, 26); + } + Vector val(x,y,z); + return val; +} + +void Field::SetPosition(Vector value) { + Clear(); + m_type = Position; + m_dataLength = 8; + m_data = new byte[m_dataLength]; + unsigned long long *t = reinterpret_cast(m_data); + unsigned long long x = ((unsigned long long) value.GetX()) << 38; + unsigned long long y = ((unsigned long long) value.GetY()) << 26; + unsigned long long z = value.GetZ(); + endswap(&x); + endswap(&z); + endswap(&y); + *t = x | y | z; +} + +double Field::GetDouble() { + double t = *reinterpret_cast(m_data); + endswap(&t); + return t; +} + +void Field::SetDouble(double value) { + Clear(); + m_type = Double; + endswap(&value); + m_dataLength = 8; + m_data = new byte[m_dataLength]; + double *p = reinterpret_cast(m_data); + *p = value; +} + +size_t Field::GetFieldLength(FieldType type) { + switch (type) { + case Unknown: + return 0; + case Boolean: + return 1; + case Byte8_t: + return 1; + case UnsignedByte: + return 1; + case Short: + return 2; + case UnsignedShort: + return 2; + case Int: + return 4; + case Long: + return 8; + case Float: + return 4; + case Double: + return 8; + case Position: + return 8; + case Angle: + return 4; + case Uuid: + return 16; + default: + return 0; + } +} + +std::vector Field::GetArray() { + /*std::vector vec; + if (m_type<20){ + size_t fieldLen=GetFieldLength(m_type); + byte* ptr = m_data; + for (int i=0;i +#include +#include +#include +#include "../utility/utility.h" +#include "../utility/Vector.hpp" + +typedef unsigned char byte; +typedef signed char sbyte; + +enum FieldType { + Unknown = 0, + Boolean, //Bool + Byte8_t, //int8_t + UnsignedByte, //uint8_t + Short, //int16_t + UnsignedShort, //uint16_t + Int, //int32_t + Long, //int64_t + Float, //float + Double, //double + Position, //PositionI + Angle, //uint8_t + Uuid, //byte* (2 bytes) + //Unknown-length data + + String = 100, //std::string + Chat, //std::string + VarInt, //int32_t + VarLong, //int64_t + ChunkSection, //byte* + EntityMetadata, //byte* + Slot, //byte* + NbtTag, //byte* + ByteArray, //byte* +}; + +class Field { +public: + Field(); + + Field(const Field &other); + + void swap(Field &other); + + Field &operator=(Field other); + + ~Field(); + + size_t GetLength(); + + void Clear(); + + void CopyToBuff(byte *ptr); + + void SetRaw(byte *ptr, size_t len = 0, FieldType type = Unknown); + + FieldType GetType(); + + void Attach(Field field); + + static size_t GetFieldLength(FieldType type); + + //Cpp-types setters/getters for binary content of MC's data types + + int GetVarInt(); + + void SetVarInt(int value); + + int GetInt(); + + void SetInt(int value); + + bool GetBool(); + + void SetBool(bool value); + + unsigned short GetUShort(); + + void SetUShort(unsigned short value); + + std::string GetString(); + + void SetString(std::string value); + + long long GetLong(); + + void SetLong(long long value); + + byte GetUByte(); + + void SetUByte(byte value); + + sbyte GetByte(); + + void SetByte(sbyte value); + + float GetFloat(); + + void SetFloat(float value); + + Vector GetPosition(); + + void SetPosition(Vector value); + + double GetDouble(); + + void SetDouble(double value); + + std::vector GetArray(); + +private: + size_t m_dataLength = 0; + byte *m_data = nullptr; + FieldType m_type = Unknown; + std::vector m_childs; +}; diff --git a/src/packet/FieldParser.cpp b/src/packet/FieldParser.cpp new file mode 100644 index 0000000..500a973 --- /dev/null +++ b/src/packet/FieldParser.cpp @@ -0,0 +1,106 @@ +#include "FieldParser.hpp" + +Field FieldParser::Parse(FieldType type, byte *data, size_t len) { + switch (type) { + case VarInt: + return ParseVarInt(data, len); + case Boolean: + return ParseBool(data, len); + case String: + return ParseString(data, len); + case Long: + return ParseLong(data, len); + case Int: + return ParseInt(data, len); + case UnsignedByte: + return ParseUByte(data, len); + case Byte8_t: + return ParseByte(data, len); + case Float: + return ParseFloat(data, len); + case Position: + return ParsePosition(data, len); + case Double: + return ParseDouble(data, len); + case ByteArray: + return ParseByteArray(data, len); + default: + throw 105; + } +} + +Field FieldParser::ParseString(byte *data, size_t len) { + Field fLen = ParseVarInt(data, 0); + Field f; + f.SetRaw(data, fLen.GetLength() + fLen.GetVarInt(), String); + return f; +} + +Field FieldParser::ParseBool(byte *data, size_t len) { + Field f; + f.SetRaw(data,1,Boolean); + return f; +} + +Field FieldParser::ParseVarInt(byte *data, size_t len) { + if (len != 0) { + Field f; + f.SetRaw(data, len, VarInt); + return f; + } + int val = VarIntRead(data, len); + Field f; + f.SetVarInt(val); + return f; +} + +Field FieldParser::ParseLong(byte *data, size_t len) { + Field f; + f.SetRaw(data, 8, Long); + return f; +} + +Field FieldParser::ParseInt(byte *data, size_t len) { + Field f; + f.SetRaw(data, 4, Int); + return f; +} + +Field FieldParser::ParseUByte(byte *data, size_t len) { + Field f; + f.SetRaw(data, 1, UnsignedByte); + return f; +} + +Field FieldParser::ParseByte(byte *data, size_t len) { + Field f; + f.SetRaw(data, 1, Byte8_t); + return f; +} + +Field FieldParser::ParseFloat(byte *data, size_t len) { + Field f; + f.SetRaw(data, 4, Float); + return f; +} + +Field FieldParser::ParsePosition(byte *data, size_t len) { + Field f; + f.SetRaw(data, 8, Position); + return f; +} + +Field FieldParser::ParseDouble(byte *data, size_t len) { + Field f; + f.SetRaw(data, 8, Double); + return f; +} + +Field FieldParser::ParseByteArray(byte *data, size_t len) { + if (len == 0) + throw 119; + Field f; + f.SetRaw(data, len, Byte8_t); + //f.SetRaw(data, len, ByteArray); + return f; +} diff --git a/src/packet/FieldParser.hpp b/src/packet/FieldParser.hpp new file mode 100644 index 0000000..274ab9e --- /dev/null +++ b/src/packet/FieldParser.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "Field.hpp" + +class FieldParser { +public: + static Field ParseVarInt(byte *data, size_t len); + + static Field ParseBool(byte *data, size_t len); + + static Field ParseString(byte *data, size_t len); + + static Field Parse(FieldType type, byte* data, size_t len=0); + + static Field ParseLong(byte *data, size_t len); + + static Field ParseInt(byte *data, size_t len); + + static Field ParseUByte(byte *data, size_t len); + + static Field ParseByte(byte *data, size_t len); + + static Field ParseFloat(byte *data, size_t len); + + static Field ParsePosition(byte *data, size_t len); + + static Field ParseDouble(byte *data, size_t len); + + static Field ParseByteArray(byte *data, size_t len); +}; \ No newline at end of file diff --git a/src/packet/Packet.cpp b/src/packet/Packet.cpp new file mode 100644 index 0000000..695e371 --- /dev/null +++ b/src/packet/Packet.cpp @@ -0,0 +1,100 @@ +#include "Packet.hpp" + +Packet::Packet(int id) { + Field fLen; + fLen.SetVarInt(0); + m_fields.push_back(fLen); + Field fId; + fId.SetVarInt(id); + m_fields.push_back(fId); +} + +Packet Packet::operator=(Packet other) { + other.swap(*this); + return *this; +} + +void Packet::swap(Packet &other) { + std::swap(m_fields, other.m_fields); + std::swap(m_data, other.m_data); + std::swap(m_parsePtr, other.m_parsePtr); + std::swap(m_dataLength, other.m_dataLength); +} + +void Packet::CopyToBuff(byte *ptr) { + m_fields[0].SetVarInt(GetLength() - m_fields[0].GetLength()); + for (int i = 0; i < m_fields.size(); i++) { + m_fields[i].CopyToBuff(ptr); + ptr += m_fields[i].GetLength(); + } +} + +void Packet::ParseField(FieldType type, size_t len) { + if (type == ByteArray && len == 0) + throw 118; + Field f = FieldParser::Parse(type, m_parsePtr, len); + m_fields.push_back(f); + m_parsePtr += f.GetLength(); + if (m_parsePtr == m_data + m_dataLength) { + delete[] m_data; + m_data = nullptr; + m_dataLength = 0; + m_parsePtr = nullptr; + } +} + +Packet::Packet(byte *data) { + Field fLen = FieldParser::Parse(VarInt, data); + data += fLen.GetLength(); + Field fId = FieldParser::Parse(VarInt, data); + data += fId.GetLength(); + m_dataLength = fLen.GetVarInt() - fId.GetLength(); + m_data = new byte[m_dataLength]; + std::copy(data,data+m_dataLength,m_data); + m_parsePtr = m_data; + m_fields.push_back(fLen); + m_fields.push_back(fId); +} + +Field &Packet::GetField(int id) { + if (id < -2 || id >= m_fields.size() - 2) + throw 111; + return m_fields[id + 2]; +} + +size_t Packet::GetLength() { + size_t len = 0; + for (int i = 0; i < m_fields.size(); i++) + len += m_fields[i].GetLength(); + return len + m_dataLength; +} + +void Packet::AddField(Field field) { + m_fields.push_back(field); +} + +int Packet::GetId() { + return m_fields[1].GetVarInt(); +} + +Packet::Packet(const Packet &other) { + if (other.m_dataLength > 0) { + m_dataLength = other.m_dataLength; + m_data = new byte[m_dataLength]; + m_parsePtr = m_data + (other.m_data - other.m_parsePtr); + std::copy(other.m_data, other.m_data + m_dataLength, m_data); + } + m_fields = other.m_fields; +} + +void Packet::ParseFieldArray(Field &field, FieldType type, size_t len) { + Field f = FieldParser::Parse(type, m_parsePtr, len); + field.Attach(f); + m_parsePtr += f.GetLength(); + if (m_parsePtr == m_data + m_dataLength) { + delete[] m_data; + m_data = nullptr; + m_dataLength = 0; + m_parsePtr = nullptr; + } +} diff --git a/src/packet/Packet.hpp b/src/packet/Packet.hpp new file mode 100644 index 0000000..67e95e5 --- /dev/null +++ b/src/packet/Packet.hpp @@ -0,0 +1,130 @@ +#pragma once + +#include +#include "Field.hpp" +#include "FieldParser.hpp" + +enum ConnectionState { + Login, + Handshaking, + Play, + Status, +}; + +enum PacketsClientBound{ + SpawnObject=0x00, + SpawnExperienceOrb, + SpawnGlobalEntity, + SpawnMob, + SpawnPainting, + SpawnPlayer, + Animation, + Statistics, + BlockBreakAnimation, + UpdateBlockEntity, + BlockAction, + BlockChange, + BossBar, + ServerDifficulty, + Tab, + ChatMessage, + MultiBlockChange, + ConfirmTransaction, + CloseWindow, + OpenWindow, + WindowItems, + WindowProperty, + SetSlot, + SetCooldown, + PluginMessage, + NamedSoundEffect, + Disconnect, + EntityStatus, + Explosion, + UnloadChunk, + ChangeGameState, + KeepAlive, + ChunkData, + Effect, + Particle, + JoinGame, + Map, + EntityRelativeMove, + EntityLookAndRelativeMove, + EntityLook, + Entity, + VehicleMove, + OpenSignEditor, + PlayerAbilities, + CombatEvent, + PlayerListItem, + PlayerPositionAndLook, + UseBed, + DestroyEntities, + RemoveEntityEffect, + ResourcePackSend, + Respawn, + EntityHeadLook, + WorldBorder, + Camera, + HeldItemChange, + DisplayScoreboard, + EntityMetadata_, + AttachEntity, + EntityVelocity, + EntityEquipment, + SetExperience, + UpdateHealth, + ScoreboardObjective, + SetPassengers, + Teams, + UpdateScore, + SpawnPosition, + TimeUpdate, + Title, + SoundEffect, + PlayerListHeaderAndFooter, + CollectItem, + EntityTeleport, + EntityProperties, + EntityEffect, +}; + +class Packet { +public: + Packet(int id); + + Packet(byte *data); + + Packet(const Packet &other); + + ~Packet() { + delete[] m_data; + } + + int GetId(); + + void AddField(Field field); + + void ParseField(FieldType type, size_t len = 0); + + void ParseFieldArray(Field &field, FieldType type, size_t len); + + Field & GetField(int id); + + size_t GetLength(); + + void CopyToBuff(byte *ptr); + + void swap(Packet &other); + + Packet operator=(Packet other); + +private: + Packet(); + + std::vector m_fields; + byte *m_data = nullptr; + byte *m_parsePtr = nullptr; + size_t m_dataLength = 0; +}; \ No newline at end of file diff --git a/src/packet/PacketBuilder.cpp b/src/packet/PacketBuilder.cpp new file mode 100644 index 0000000..4083ea3 --- /dev/null +++ b/src/packet/PacketBuilder.cpp @@ -0,0 +1,65 @@ +#include "PacketBuilder.hpp" + +Packet PacketBuilder::CHandshaking0x00(int protocolVerison, std::string address, unsigned short port, int nextState) { + Packet handshakePacket(0); + Field fProtocol; + fProtocol.SetVarInt(protocolVerison); + Field fAddress; + fAddress.SetString(address); + Field fPort; + fPort.SetUShort(port); + Field fNextState; + fNextState.SetVarInt(nextState); + handshakePacket.AddField(fProtocol); + handshakePacket.AddField(fAddress); + handshakePacket.AddField(fPort); + handshakePacket.AddField(fNextState); + return handshakePacket; +} + +Packet PacketBuilder::CPlay0x0B(int keepAliveId) { + Packet keepAlivePacket(0x0B); + Field fKeepAlive; + fKeepAlive.SetVarInt(keepAliveId); + keepAlivePacket.AddField(fKeepAlive); + return keepAlivePacket; +} + +Packet PacketBuilder::CPlay0x03(int actionId) { + Packet clientStatusPacket(0x03); + Field fActionId; + fActionId.SetVarInt(actionId); + clientStatusPacket.AddField(fActionId); + return clientStatusPacket; +} + +Packet PacketBuilder::CPlay0x00(int teleportId) { + Packet teleportConfirmPacket(0x00); + Field fTeleportId; + fTeleportId.SetVarInt(teleportId); + teleportConfirmPacket.AddField(fTeleportId); + return teleportConfirmPacket; +} + +Packet PacketBuilder::CPlay0x0D(double x, double y, double z, float yaw, float pitch, bool onGround) { + Packet playerPositionAndLookPacket(0x0D); + Field fX; + Field fY; + Field fZ; + Field fYaw; + Field fPitch; + Field fOnGround; + fX.SetDouble(x); + fY.SetDouble(y); + fZ.SetDouble(z); + fYaw.SetFloat(yaw); + fPitch.SetFloat(pitch); + fOnGround.SetBool(onGround); + playerPositionAndLookPacket.AddField(fX); + playerPositionAndLookPacket.AddField(fY); + playerPositionAndLookPacket.AddField(fZ); + playerPositionAndLookPacket.AddField(fYaw); + playerPositionAndLookPacket.AddField(fPitch); + playerPositionAndLookPacket.AddField(fOnGround); + return playerPositionAndLookPacket; +} diff --git a/src/packet/PacketBuilder.hpp b/src/packet/PacketBuilder.hpp new file mode 100644 index 0000000..2fcb737 --- /dev/null +++ b/src/packet/PacketBuilder.hpp @@ -0,0 +1,17 @@ +#pragma once + + +#include "Packet.hpp" + +class PacketBuilder { +public: + static Packet CHandshaking0x00(int protocolVerison, std::string address, unsigned short port, int nextState); + static Packet CPlay0x0B(int keepAliveId); + + static Packet CPlay0x03(int actionId); + + static Packet CPlay0x00(int teleportId); + + static Packet CPlay0x0D(double x, double y, double z, float yaw, float pitch, bool onGround); +}; + diff --git a/src/packet/PacketParser.cpp b/src/packet/PacketParser.cpp new file mode 100644 index 0000000..488c812 --- /dev/null +++ b/src/packet/PacketParser.cpp @@ -0,0 +1,147 @@ +#include "PacketParser.hpp" + +void PacketParser::Parse(Packet &packet, ConnectionState state, bool ClientBound) { + if (ClientBound) { + switch (state) { + case Login: + ParseLogin(packet); + break; + case Handshaking: + break; + case Play: + ParsePlay(packet); + break; + case Status: + + break; + } + } else { + ParseServerBound(packet, state); + } +} + +void PacketParser::ParseServerBound(Packet &packet, ConnectionState state) { + throw 107; +} + +void PacketParser::ParseLogin(Packet &packet) { + switch (packet.GetId()) { + case 0x00: + ParseLogin0x00(packet); + break; + case 0x02: + ParseLogin0x02(packet); + break; + default: + { + int i = packet.GetId(); + //throw 112; + } + } +} + +void PacketParser::ParsePlay(Packet &packet) { + switch (packet.GetId()) { + case 0x23: + ParsePlay0x23(packet); + break; + case 0x1F: + ParsePlay0x1F(packet); + break; + case 0x0D: + ParsePlay0x0D(packet); + break; + case 0x2B: + ParsePlay0x2B(packet); + break; + case 0x43: + ParsePlay0x43(packet); + break; + case 0x2E: + ParsePlay0x2E(packet); + break; + case 0x1A: + ParsePlay0x1A(packet); + break; + case 0x20: + ParsePlay0x20(packet); + break; + case 0x07: + ParsePlay0x07(packet); + default: + //throw 113; + break; + } +} + +void PacketParser::ParseLogin0x00(Packet &packet) { + packet.ParseField(String); +} + +void PacketParser::ParseLogin0x02(Packet &packet) { + packet.ParseField(String); + packet.ParseField(String); +} + +void PacketParser::ParsePlay0x23(Packet &packet) { + packet.ParseField(Int); + packet.ParseField(UnsignedByte); + packet.ParseField(Int); + packet.ParseField(UnsignedByte); + packet.ParseField(UnsignedByte); + packet.ParseField(String); + packet.ParseField(Boolean); +} + +void PacketParser::ParsePlay0x1F(Packet &packet) { + packet.ParseField(VarInt); +} + +void PacketParser::ParsePlay0x0D(Packet &packet) { + packet.ParseField(UnsignedByte); +} + +void PacketParser::ParsePlay0x2B(Packet &packet) { + packet.ParseField(Byte8_t); + packet.ParseField(Float); + packet.ParseField(Float); +} + +void PacketParser::ParsePlay0x43(Packet &packet) { + packet.ParseField(Position); +} + +void PacketParser::ParsePlay0x2E(Packet &packet) { + packet.ParseField(Double); + packet.ParseField(Double); + packet.ParseField(Double); + packet.ParseField(Float); + packet.ParseField(Float); + packet.ParseField(Byte8_t); + packet.ParseField(VarInt); +} + +void PacketParser::ParsePlay0x1A(Packet &packet) { + packet.ParseField(String); +} + +void PacketParser::ParsePlay0x20(Packet &packet) { + packet.ParseField(Int); + packet.ParseField(Int); + packet.ParseField(Boolean); + packet.ParseField(VarInt); + packet.ParseField(VarInt); + packet.ParseField(ByteArray, packet.GetField(4).GetVarInt()); + packet.ParseField(VarInt); + //packet.ParseField(NbtTag); + //packet.GetField(7).SetArray(packet.GetField(6).GetVarInt()); +} + +void PacketParser::ParsePlay0x07(Packet &packet) { + packet.ParseField(VarInt); + packet.AddField(Field()); + for (int i=0;i