Imported existing sources
This commit is contained in:
+257
@@ -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!";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user