Imported existing sources
This commit is contained in:
15
DbMinecraft.pro
Normal file
15
DbMinecraft.pro
Normal file
@@ -0,0 +1,15 @@
|
||||
QT = core network
|
||||
|
||||
CONFIG += c++1z
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS QT_DISABLE_DEPRECATED_BEFORE=0x060000
|
||||
|
||||
SOURCES += main.cpp \
|
||||
client.cpp \
|
||||
mcdatastream.cpp \
|
||||
packets.cpp
|
||||
|
||||
HEADERS += \
|
||||
client.h \
|
||||
mcdatastream.h \
|
||||
packets.h
|
257
client.cpp
Normal file
257
client.cpp
Normal file
@@ -0,0 +1,257 @@
|
||||
#include "client.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTcpSocket>
|
||||
#include <QUuid>
|
||||
#include <QTimer>
|
||||
|
||||
Client::Client(QTcpSocket *socket, QObject *parent) :
|
||||
QObject(parent), m_socket(socket), m_dataStream(m_socket),
|
||||
m_packetSize(0), m_state(HandshakingState)
|
||||
{
|
||||
m_socket->setParent(this);
|
||||
|
||||
connect(m_socket, &QIODevice::readyRead, this, &Client::readyRead);
|
||||
connect(m_socket, &QAbstractSocket::disconnected, this, &Client::disconnected);
|
||||
|
||||
qDebug() << m_socket->peerPort();
|
||||
}
|
||||
|
||||
void Client::readyRead()
|
||||
{
|
||||
while(m_socket->bytesAvailable())
|
||||
{
|
||||
if(!m_packetSize)
|
||||
{
|
||||
m_packetSize = m_dataStream.readVar<qint32>();
|
||||
qDebug() << "packet size" << m_packetSize;
|
||||
}
|
||||
|
||||
if(m_socket->bytesAvailable() < m_packetSize)
|
||||
{
|
||||
qWarning() << "packet not fully available" << m_socket->bytesAvailable();
|
||||
return;
|
||||
}
|
||||
|
||||
qint32 bytesRead;
|
||||
const auto type = m_dataStream.readVar<qint32>(bytesRead);
|
||||
m_packetSize -= bytesRead;
|
||||
const auto buffer = m_socket->read(m_packetSize);
|
||||
Q_ASSERT(buffer.size() == m_packetSize);
|
||||
m_packetSize = 0;
|
||||
|
||||
switch(m_state)
|
||||
{
|
||||
case HandshakingState:
|
||||
readPacketHandshaking(packets::handshaking::serverbound::PacketType(type), buffer);
|
||||
break;
|
||||
case StatusState:
|
||||
readPacketStatus(packets::status::serverbound::PacketType(type), buffer);
|
||||
break;
|
||||
case LoginState:
|
||||
readPacketLogin(packets::login::serverbound::PacketType(type), buffer);
|
||||
break;
|
||||
case PlayState:
|
||||
readPacketPlay(packets::play::serverbound::PacketType(type), buffer);
|
||||
break;
|
||||
default:
|
||||
qWarning() << "unhandled state" << m_state << type << buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::disconnected()
|
||||
{
|
||||
qDebug() << m_socket->peerPort();
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void Client::readPacketHandshaking(packets::handshaking::serverbound::PacketType type, const QByteArray &buffer)
|
||||
{
|
||||
qDebug() << type;
|
||||
|
||||
McDataStream dataStream(const_cast<QByteArray *>(&buffer), QIODevice::ReadOnly);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
using namespace packets::handshaking;
|
||||
case serverbound::PacketHandshake:
|
||||
{
|
||||
serverbound::Handshake packet(dataStream);
|
||||
m_state = packet.nextState;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qWarning() << "unknown type!";
|
||||
}
|
||||
}
|
||||
|
||||
void Client::readPacketStatus(const packets::status::serverbound::PacketType type, const QByteArray &buffer)
|
||||
{
|
||||
qDebug() << type;
|
||||
|
||||
McDataStream dataStream(const_cast<QByteArray *>(&buffer), QIODevice::ReadOnly);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
using namespace packets::status;
|
||||
case serverbound::PacketRequest:
|
||||
{
|
||||
{
|
||||
serverbound::Request packet(dataStream);
|
||||
}
|
||||
{
|
||||
clientbound::Response packet;
|
||||
packet.jsonResponse =
|
||||
"{"
|
||||
" \"version\": {"
|
||||
" \"name\": \"1.13.1\","
|
||||
" \"protocol\": 401"
|
||||
" },"
|
||||
" \"players\": {"
|
||||
" \"max\": 1000,"
|
||||
" \"online\": 2000,"
|
||||
" \"sample\": ["
|
||||
" {"
|
||||
" \"name\": \"0xFEEDC0DE64\","
|
||||
" \"id\": \"6ebf7396-b6da-40b1-b7d9-9b7961450d5a\""
|
||||
" }"
|
||||
" ]"
|
||||
" }, "
|
||||
" \"description\": {"
|
||||
" \"text\": \"Mein monster server in C++\""
|
||||
" },"
|
||||
" \"favicon\": \"\""
|
||||
"}";
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case serverbound::PacketPing:
|
||||
{
|
||||
qint64 payload;
|
||||
{
|
||||
serverbound::Ping packet(dataStream);
|
||||
payload = packet.payload;
|
||||
}
|
||||
{
|
||||
clientbound::Pong packet;
|
||||
packet.payload = payload;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qWarning() << "unknown type!";
|
||||
}
|
||||
}
|
||||
|
||||
void Client::readPacketLogin(const packets::login::serverbound::PacketType type, const QByteArray &buffer)
|
||||
{
|
||||
qDebug() << type;
|
||||
|
||||
McDataStream dataStream(const_cast<QByteArray *>(&buffer), QIODevice::ReadOnly);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
using namespace packets::login;
|
||||
case serverbound::PacketLogin:
|
||||
{
|
||||
QString name;
|
||||
{
|
||||
serverbound::Login packet(dataStream);
|
||||
name = packet.name;
|
||||
}
|
||||
qDebug() << "Name" << name;
|
||||
{
|
||||
clientbound::LoginSuccess packet;
|
||||
const auto uuid = QUuid::createUuid().toString();
|
||||
packet.uuid = uuid.mid(1, uuid.length() - 2);
|
||||
packet.username = name;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
m_state = PlayState;
|
||||
{
|
||||
packets::play::clientbound::JoinGame packet;
|
||||
packet.entityid = 1;
|
||||
packet.gamemode = 0;
|
||||
packet.dimension = 0;
|
||||
packet.difficulty = 2;
|
||||
packet.maxPlayers = 255;
|
||||
packet.levelType = QStringLiteral("default");
|
||||
packet.reducedDebugInfo = false;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
{
|
||||
packets::play::clientbound::PluginMessage packet;
|
||||
packet.channel = QStringLiteral("minecraft:brand");
|
||||
packet.data = QByteArrayLiteral("bullshit");
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
{
|
||||
packets::play::clientbound::ServerDifficulty packet;
|
||||
packet.difficulty = 2;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
{
|
||||
packets::play::clientbound::SpawnPosition packet;
|
||||
packet.location = std::make_tuple(100, 64, 100);
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
{
|
||||
packets::play::clientbound::PlayerAbilities packet;
|
||||
packet.flags = 0x0F;
|
||||
packet.flyingSpeed = 1.;
|
||||
packet.fieldOfViewModifier = 60.;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qWarning() << "unknown type!";
|
||||
}
|
||||
}
|
||||
|
||||
void Client::readPacketPlay(const packets::play::serverbound::PacketType type, const QByteArray &buffer)
|
||||
{
|
||||
qDebug() << type;
|
||||
|
||||
McDataStream dataStream(const_cast<QByteArray *>(&buffer), QIODevice::ReadOnly);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
using namespace packets::play;
|
||||
case serverbound::PacketClientSettings:
|
||||
{
|
||||
{
|
||||
serverbound::ClientSettings packet(dataStream);
|
||||
qDebug() << "locale" << packet.locale;
|
||||
qDebug() << "viewDistance" << packet.viewDistance;
|
||||
qDebug() << "chatMode" << packet.chatMode;
|
||||
qDebug() << "chatColors" << packet.chatColors;
|
||||
qDebug() << "displayedSkinParts" << packet.displayedSkinParts;
|
||||
qDebug() << "mainHand" << packet.mainHand;
|
||||
}
|
||||
{
|
||||
clientbound::PlayerPositionAndLook packet;
|
||||
packet.x = 50.;
|
||||
packet.y = 64.;
|
||||
packet.z = 50.;
|
||||
packet.yaw = 0.;
|
||||
packet.pitch = 0.;
|
||||
packet.flags = 0;
|
||||
packet.teleportId = 0;
|
||||
packet.serialize(m_dataStream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case serverbound::PacketPluginMessage:
|
||||
{
|
||||
serverbound::PluginMessage packet(dataStream);
|
||||
qDebug() << "channel" << packet.channel;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
qWarning() << "unknown type!";
|
||||
}
|
||||
}
|
33
client.h
Normal file
33
client.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "mcdatastream.h"
|
||||
#include "packets.h"
|
||||
|
||||
class QTcpSocket;
|
||||
|
||||
class Client : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Client(QTcpSocket *socket, QObject *parent = nullptr);
|
||||
|
||||
private Q_SLOTS:
|
||||
void readyRead();
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
void readPacketHandshaking(const packets::handshaking::serverbound::PacketType type, const QByteArray &buffer);
|
||||
void readPacketStatus(const packets::status::serverbound::PacketType type, const QByteArray &buffer);
|
||||
void readPacketLogin(const packets::login::serverbound::PacketType type, const QByteArray &buffer);
|
||||
void readPacketPlay(const packets::play::serverbound::PacketType type, const QByteArray &buffer);
|
||||
|
||||
QTcpSocket *m_socket;
|
||||
McDataStream m_dataStream;
|
||||
|
||||
qint32 m_packetSize;
|
||||
|
||||
SocketState m_state;
|
||||
};
|
34
main.cpp
Normal file
34
main.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <QCoreApplication>
|
||||
#include <qlogging.h>
|
||||
#include <QTcpServer>
|
||||
|
||||
#include "client.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
qSetMessagePattern(QStringLiteral("%{time dd.MM.yyyy HH:mm:ss.zzz} "
|
||||
"["
|
||||
"%{if-debug}D%{endif}"
|
||||
"%{if-info}I%{endif}"
|
||||
"%{if-warning}W%{endif}"
|
||||
"%{if-critical}C%{endif}"
|
||||
"%{if-fatal}F%{endif}"
|
||||
"] "
|
||||
"%{function}(): "
|
||||
"%{message}"));
|
||||
|
||||
QTcpServer server;
|
||||
|
||||
QObject::connect(&server, &QTcpServer::newConnection, [&server](){
|
||||
new Client(server.nextPendingConnection());
|
||||
});
|
||||
|
||||
if(!server.listen(QHostAddress::Any, 25565))
|
||||
qFatal("could not start listening %s", server.errorString().toUtf8().constData());
|
||||
|
||||
qDebug() << "started listening";
|
||||
|
||||
return a.exec();
|
||||
}
|
173
mcdatastream.cpp
Normal file
173
mcdatastream.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "mcdatastream.h"
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
#include <memory>
|
||||
|
||||
McDataStream::McDataStream() :
|
||||
QDataStream()
|
||||
{
|
||||
setByteOrder(QDataStream::BigEndian);
|
||||
}
|
||||
|
||||
McDataStream::McDataStream(QIODevice *device) :
|
||||
QDataStream(device)
|
||||
{
|
||||
setByteOrder(QDataStream::BigEndian);
|
||||
}
|
||||
|
||||
McDataStream::McDataStream(QByteArray *byteArray, QIODevice::OpenMode flags) :
|
||||
QDataStream(byteArray, flags)
|
||||
{
|
||||
setByteOrder(QDataStream::BigEndian);
|
||||
}
|
||||
|
||||
McDataStream::McDataStream(const QByteArray &byteArray) :
|
||||
QDataStream(byteArray)
|
||||
{
|
||||
setByteOrder(QDataStream::BigEndian);
|
||||
}
|
||||
|
||||
McDataStream::Position McDataStream::readPosition()
|
||||
{
|
||||
quint64 val;
|
||||
*this >> val;
|
||||
const qint32 x = val >> 38;
|
||||
const qint16 y = (val >> 26) & 0xFFF;
|
||||
const qint32 z = val << 38 >> 38;
|
||||
return std::make_tuple(x, y, z);
|
||||
}
|
||||
|
||||
void McDataStream::writePosition(const Position &position)
|
||||
{
|
||||
const quint64 val = ((quint64(std::get<0>(position)) & 0x3FFFFFF) << 38) |
|
||||
((quint64(std::get<1>(position)) & 0xFFF) << 26) |
|
||||
(quint64(std::get<2>(position)) & 0x3FFFFFF);
|
||||
*this << val;
|
||||
}
|
||||
|
||||
float McDataStream::readFloat()
|
||||
{
|
||||
const auto precision = floatingPointPrecision();
|
||||
setFloatingPointPrecision(SinglePrecision);
|
||||
float value;
|
||||
*this >> value;
|
||||
setFloatingPointPrecision(precision);
|
||||
return value;
|
||||
}
|
||||
|
||||
void McDataStream::writeFloat(float value)
|
||||
{
|
||||
const auto precision = floatingPointPrecision();
|
||||
setFloatingPointPrecision(SinglePrecision);
|
||||
*this << value;
|
||||
setFloatingPointPrecision(precision);
|
||||
}
|
||||
|
||||
float McDataStream::readDouble()
|
||||
{
|
||||
const auto precision = floatingPointPrecision();
|
||||
setFloatingPointPrecision(DoublePrecision);
|
||||
double value;
|
||||
*this >> value;
|
||||
setFloatingPointPrecision(precision);
|
||||
return value;
|
||||
}
|
||||
|
||||
void McDataStream::writeDouble(double value)
|
||||
{
|
||||
const auto precision = floatingPointPrecision();
|
||||
setFloatingPointPrecision(DoublePrecision);
|
||||
*this << value;
|
||||
setFloatingPointPrecision(precision);
|
||||
}
|
||||
|
||||
template<>
|
||||
qint32 McDataStream::readVar<qint32>(qint32 &bytesRead)
|
||||
{
|
||||
bytesRead = 0;
|
||||
qint32 result = 0;
|
||||
qint8 read;
|
||||
do {
|
||||
*this >> read;
|
||||
qint32 value = read & 0b01111111;
|
||||
result |= value << (7 * bytesRead);
|
||||
|
||||
bytesRead++;
|
||||
if (bytesRead > 5) {
|
||||
qFatal("VarInt is too big");
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
qint64 McDataStream::readVar<qint64>(qint32 &bytesRead)
|
||||
{
|
||||
bytesRead = 0;
|
||||
qint64 result = 0;
|
||||
qint8 read;
|
||||
do {
|
||||
*this >> read;
|
||||
qint32 value = read & 0b01111111;
|
||||
result |= value << (7 * bytesRead);
|
||||
|
||||
bytesRead++;
|
||||
if (bytesRead > 10) {
|
||||
qFatal("VarInt is too big");
|
||||
}
|
||||
} while ((read & 0b10000000) != 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
QString McDataStream::readVar<QString>(qint32 &bytesRead)
|
||||
{
|
||||
const auto length = readVar<qint32>(bytesRead);
|
||||
|
||||
auto data = std::unique_ptr<char[]>(new char[length]);
|
||||
|
||||
{
|
||||
const auto rawLength = readRawData(data.get(), length);
|
||||
bytesRead += rawLength;
|
||||
Q_ASSERT(length == rawLength);
|
||||
}
|
||||
|
||||
return QString::fromUtf8(data.get(), length);
|
||||
}
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(qint32 value)
|
||||
{
|
||||
do {
|
||||
qint8 temp = value & 0b01111111;
|
||||
value >>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
*this << temp;
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(qint64 value)
|
||||
{
|
||||
do {
|
||||
qint8 temp = value & 0b01111111;
|
||||
value >>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
*this << temp;
|
||||
} while (value != 0);
|
||||
}
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(QString value)
|
||||
{
|
||||
const auto bytes = value.toUtf8();
|
||||
writeVar<qint32>(bytes.length());
|
||||
writeRawData(bytes.constData(), bytes.length());
|
||||
}
|
58
mcdatastream.h
Normal file
58
mcdatastream.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDataStream>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
class McDataStream : public QDataStream
|
||||
{
|
||||
public:
|
||||
McDataStream();
|
||||
explicit McDataStream(QIODevice *device);
|
||||
McDataStream(QByteArray *byteArray, QIODevice::OpenMode flags);
|
||||
McDataStream(const QByteArray &byteArray);
|
||||
|
||||
typedef std::tuple<qint32, qint16, qint32> Position;
|
||||
Position readPosition();
|
||||
void writePosition(const Position &position);
|
||||
|
||||
float readFloat();
|
||||
void writeFloat(float value);
|
||||
|
||||
float readDouble();
|
||||
void writeDouble(double value);
|
||||
|
||||
template<typename T>
|
||||
T readVar();
|
||||
|
||||
template<typename T>
|
||||
T readVar(qint32 &bytesRead);
|
||||
|
||||
template<typename T>
|
||||
void writeVar(T value);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T McDataStream::readVar()
|
||||
{
|
||||
qint32 bytesRead;
|
||||
return readVar<T>(bytesRead);
|
||||
}
|
||||
|
||||
template<>
|
||||
qint32 McDataStream::readVar<qint32>(qint32 &bytesRead);
|
||||
|
||||
template<>
|
||||
qint64 McDataStream::readVar<qint64>(qint32 &bytesRead);
|
||||
|
||||
template<>
|
||||
QString McDataStream::readVar<QString>(qint32 &bytesRead);
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(qint32 value);
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(qint64 value);
|
||||
|
||||
template<>
|
||||
void McDataStream::writeVar(QString value);
|
150
packets.cpp
Normal file
150
packets.cpp
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "packets.h"
|
||||
|
||||
#include "mcdatastream.h"
|
||||
|
||||
packets::handshaking::serverbound::Handshake::Handshake(McDataStream &stream)
|
||||
{
|
||||
protocolVersion = stream.readVar<qint32>();
|
||||
serverAddress = stream.readVar<QString>();
|
||||
stream >> serverPort;
|
||||
const auto socketState = stream.readVar<qint32>();
|
||||
Q_ASSERT(socketState == 1 || socketState == 2);
|
||||
nextState = SocketState(socketState);
|
||||
}
|
||||
|
||||
packets::status::serverbound::Request::Request(McDataStream &stream)
|
||||
{
|
||||
Q_UNUSED(stream);
|
||||
}
|
||||
|
||||
packets::status::serverbound::Ping::Ping(McDataStream &stream)
|
||||
{
|
||||
stream >> payload;
|
||||
}
|
||||
|
||||
void packets::status::clientbound::Response::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketResponse);
|
||||
tempStream.writeVar<QString>(jsonResponse);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::status::clientbound::Pong::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketPong);
|
||||
tempStream << payload;
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
packets::login::serverbound::Login::Login(McDataStream &stream)
|
||||
{
|
||||
name = stream.readVar<QString>();
|
||||
}
|
||||
|
||||
void packets::login::clientbound::LoginSuccess::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketLoginSuccess);
|
||||
tempStream.writeVar<QString>(uuid);
|
||||
tempStream.writeVar<QString>(username);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
packets::play::serverbound::ClientSettings::ClientSettings(McDataStream &stream)
|
||||
{
|
||||
locale = stream.readVar<QString>();
|
||||
stream >> viewDistance;
|
||||
chatMode = stream.readVar<qint32>();
|
||||
stream >> chatColors
|
||||
>> displayedSkinParts;
|
||||
mainHand = stream.readVar<qint32>();
|
||||
}
|
||||
|
||||
packets::play::serverbound::PluginMessage::PluginMessage(McDataStream &stream)
|
||||
{
|
||||
channel = stream.readVar<QString>();
|
||||
//TODO read to end of buffer
|
||||
}
|
||||
|
||||
void packets::play::clientbound::ServerDifficulty::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketServerDifficulty);
|
||||
tempStream << difficulty;
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::play::clientbound::PluginMessage::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketPluginMessage);
|
||||
tempStream.writeVar<QString>(channel);
|
||||
buffer.append(data);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::play::clientbound::JoinGame::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketJoinGame);
|
||||
tempStream << entityid
|
||||
<< gamemode
|
||||
<< dimension
|
||||
<< difficulty
|
||||
<< maxPlayers;
|
||||
tempStream.writeVar<QString>(levelType);
|
||||
tempStream << reducedDebugInfo;
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::play::clientbound::PlayerAbilities::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketPlayerAbilities);
|
||||
tempStream << flags;
|
||||
tempStream.writeFloat(flyingSpeed);
|
||||
tempStream.writeFloat(fieldOfViewModifier);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::play::clientbound::PlayerPositionAndLook::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketPlayerPositionAndLook);
|
||||
tempStream.writeDouble(x);
|
||||
tempStream.writeDouble(y);
|
||||
tempStream.writeDouble(z);
|
||||
tempStream.writeFloat(yaw);
|
||||
tempStream.writeFloat(pitch);
|
||||
tempStream << flags;
|
||||
tempStream.writeVar<qint32>(teleportId);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
||||
|
||||
void packets::play::clientbound::SpawnPosition::serialize(McDataStream &stream)
|
||||
{
|
||||
QByteArray buffer;
|
||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||
tempStream.writeVar<qint32>(PacketSpawnPosition);
|
||||
tempStream.writePosition(location);
|
||||
stream.writeVar<qint32>(buffer.length());
|
||||
stream.writeRawData(buffer.constData(), buffer.length());
|
||||
}
|
165
packets.h
Normal file
165
packets.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QString>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
class McDataStream;
|
||||
|
||||
enum SocketState { HandshakingState, StatusState, LoginState, PlayState, ClosedState };
|
||||
|
||||
namespace packets {
|
||||
namespace handshaking {
|
||||
namespace serverbound {
|
||||
enum PacketType { PacketHandshake };
|
||||
|
||||
struct Handshake {
|
||||
Handshake(McDataStream &stream);
|
||||
|
||||
qint32 protocolVersion;
|
||||
QString serverAddress;
|
||||
quint16 serverPort;
|
||||
SocketState nextState;
|
||||
};
|
||||
}
|
||||
|
||||
namespace clientbound {
|
||||
}
|
||||
}
|
||||
|
||||
namespace status {
|
||||
namespace serverbound {
|
||||
enum PacketType { PacketRequest, PacketPing };
|
||||
|
||||
struct Request {
|
||||
Request(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct Ping {
|
||||
Ping(McDataStream &stream);
|
||||
|
||||
qint64 payload;
|
||||
};
|
||||
}
|
||||
|
||||
namespace clientbound {
|
||||
enum PacketType { PacketResponse, PacketPong };
|
||||
|
||||
struct Response {
|
||||
QString jsonResponse;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct Pong {
|
||||
qint64 payload;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace login {
|
||||
namespace serverbound {
|
||||
enum PacketType { PacketLogin };
|
||||
|
||||
struct Login {
|
||||
Login(McDataStream &stream);
|
||||
|
||||
QString name;
|
||||
};
|
||||
}
|
||||
|
||||
namespace clientbound {
|
||||
enum PacketType { PacketLoginSuccess = 0x02 };
|
||||
|
||||
struct LoginSuccess {
|
||||
QString uuid;
|
||||
QString username;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace play {
|
||||
namespace serverbound {
|
||||
enum PacketType { PacketClientSettings = 0x04, PacketPluginMessage = 0x0A };
|
||||
|
||||
struct ClientSettings {
|
||||
ClientSettings(McDataStream &stream);
|
||||
|
||||
QString locale;
|
||||
qint8 viewDistance;
|
||||
qint32 chatMode;
|
||||
bool chatColors;
|
||||
quint8 displayedSkinParts;
|
||||
qint32 mainHand;
|
||||
};
|
||||
|
||||
struct PluginMessage {
|
||||
PluginMessage(McDataStream &stream);
|
||||
|
||||
QString channel;
|
||||
QByteArray data;
|
||||
};
|
||||
}
|
||||
|
||||
namespace clientbound {
|
||||
enum PacketType { PacketServerDifficulty = 0x0D, PacketPluginMessage = 0x19, PacketJoinGame = 0x25, PacketPlayerAbilities = 0x2E, PacketPlayerPositionAndLook = 0x32,
|
||||
PacketSpawnPosition = 0x49 };
|
||||
|
||||
struct ServerDifficulty {
|
||||
quint8 difficulty;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct PluginMessage {
|
||||
QString channel;
|
||||
QByteArray data;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct JoinGame {
|
||||
qint32 entityid;
|
||||
quint8 gamemode;
|
||||
qint32 dimension;
|
||||
quint8 difficulty;
|
||||
quint8 maxPlayers;
|
||||
QString levelType;
|
||||
bool reducedDebugInfo;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct PlayerAbilities {
|
||||
qint8 flags;
|
||||
float flyingSpeed;
|
||||
float fieldOfViewModifier;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct PlayerPositionAndLook {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
float yaw;
|
||||
float pitch;
|
||||
qint8 flags;
|
||||
qint32 teleportId;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
|
||||
struct SpawnPosition {
|
||||
std::tuple<qint32, qint16, qint32> location;
|
||||
|
||||
void serialize(McDataStream &stream);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user