Implemented more packets for keepAlive, chat and disconnect
This commit is contained in:
79
client.cpp
79
client.cpp
File diff suppressed because one or more lines are too long
12
client.h
12
client.h
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
#include "mcdatastream.h"
|
#include "mcdatastream.h"
|
||||||
#include "packets.h"
|
#include "packets.h"
|
||||||
@@ -14,6 +15,12 @@ class Client : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit Client(QTcpSocket *socket, QObject *parent = nullptr);
|
explicit Client(QTcpSocket *socket, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
SocketState state() const { return m_state; }
|
||||||
|
|
||||||
|
void keepAlive();
|
||||||
|
void sendChatMessage();
|
||||||
|
void trialDisconnect();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void readyRead();
|
void readyRead();
|
||||||
void disconnected();
|
void disconnected();
|
||||||
@@ -30,4 +37,9 @@ private:
|
|||||||
qint32 m_packetSize;
|
qint32 m_packetSize;
|
||||||
|
|
||||||
SocketState m_state;
|
SocketState m_state;
|
||||||
|
|
||||||
|
const QDateTime m_connectedSince;
|
||||||
|
QDateTime m_lastKeepAliveSent;
|
||||||
|
QDateTime m_lastKeepAliveReceived;
|
||||||
|
QDateTime m_lastChatMessage;
|
||||||
};
|
};
|
||||||
|
34
main.cpp
34
main.cpp
@@ -1,6 +1,9 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <qlogging.h>
|
#include <qlogging.h>
|
||||||
#include <QTcpServer>
|
#include <QTcpServer>
|
||||||
|
#include <QList>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
@@ -19,10 +22,37 @@ int main(int argc, char *argv[])
|
|||||||
"%{function}(): "
|
"%{function}(): "
|
||||||
"%{message}"));
|
"%{message}"));
|
||||||
|
|
||||||
|
QList<QPointer<Client>> clients;
|
||||||
|
|
||||||
|
QTimer timer;
|
||||||
|
timer.setInterval(100);
|
||||||
|
QObject::connect(&timer, &QTimer::timeout, [&clients](){
|
||||||
|
const auto now = QDateTime::currentDateTime();
|
||||||
|
for (auto iter = std::begin(clients); iter != std::end(clients); )
|
||||||
|
{
|
||||||
|
if ((*iter).isNull())
|
||||||
|
{
|
||||||
|
iter = clients.erase(iter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &client = **iter;
|
||||||
|
if (client.state() == PlayState)
|
||||||
|
{
|
||||||
|
client.keepAlive();
|
||||||
|
client.sendChatMessage();
|
||||||
|
client.trialDisconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
timer.start();
|
||||||
|
|
||||||
QTcpServer server;
|
QTcpServer server;
|
||||||
|
|
||||||
QObject::connect(&server, &QTcpServer::newConnection, [&server](){
|
QObject::connect(&server, &QTcpServer::newConnection, [&server,&clients](){
|
||||||
new Client(server.nextPendingConnection());
|
clients.append(new Client(server.nextPendingConnection()));
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!server.listen(QHostAddress::Any, 25565))
|
if(!server.listen(QHostAddress::Any, 25565))
|
||||||
|
@@ -82,6 +82,20 @@ void McDataStream::writeDouble(double value)
|
|||||||
setFloatingPointPrecision(precision);
|
setFloatingPointPrecision(precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUuid McDataStream::readUuid()
|
||||||
|
{
|
||||||
|
char buf[16];
|
||||||
|
readRawData(buf, 16);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void McDataStream::writeUuid(const QUuid &uuid)
|
||||||
|
{
|
||||||
|
Q_UNUSED(uuid)
|
||||||
|
|
||||||
|
writeRawData("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
||||||
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
qint32 McDataStream::readVar<qint32>(qint32 &bytesRead)
|
qint32 McDataStream::readVar<qint32>(qint32 &bytesRead)
|
||||||
{
|
{
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
@@ -30,6 +31,9 @@ public:
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void writeVar(T value);
|
void writeVar(T value);
|
||||||
|
|
||||||
|
QUuid readUuid();
|
||||||
|
void writeUuid(const QUuid &uuid);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
69
packets.cpp
69
packets.cpp
@@ -26,7 +26,7 @@ void packets::status::clientbound::Response::serialize(McDataStream &stream)
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketResponse);
|
tempStream.writeVar<qint32>(qint32(PacketType::Response));
|
||||||
tempStream.writeVar<QString>(jsonResponse);
|
tempStream.writeVar<QString>(jsonResponse);
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
stream.writeRawData(buffer.constData(), buffer.length());
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
@@ -36,7 +36,7 @@ void packets::status::clientbound::Pong::serialize(McDataStream &stream)
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketPong);
|
tempStream.writeVar<qint32>(qint32(PacketType::Pong));
|
||||||
tempStream << payload;
|
tempStream << payload;
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
stream.writeRawData(buffer.constData(), buffer.length());
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
@@ -51,7 +51,8 @@ void packets::login::clientbound::LoginSuccess::serialize(McDataStream &stream)
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketLoginSuccess);
|
tempStream.writeVar<qint32>(qint32(PacketType::LoginSuccess));
|
||||||
|
//tempStream.writeUuid(uuid);
|
||||||
tempStream.writeVar<QString>(uuid);
|
tempStream.writeVar<QString>(uuid);
|
||||||
tempStream.writeVar<QString>(username);
|
tempStream.writeVar<QString>(username);
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
@@ -68,6 +69,21 @@ packets::play::serverbound::ClientSettings::ClientSettings(McDataStream &stream)
|
|||||||
mainHand = stream.readVar<qint32>();
|
mainHand = stream.readVar<qint32>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packets::play::serverbound::InteractEntity::InteractEntity(McDataStream &stream)
|
||||||
|
{
|
||||||
|
entityId = stream.readVar<qint32>();
|
||||||
|
type = Type(stream.readVar<qint32>());
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case InteractAt:
|
||||||
|
targetX = stream.readFloat();
|
||||||
|
targetY = stream.readFloat();
|
||||||
|
targetZ = stream.readFloat();
|
||||||
|
case Interact:
|
||||||
|
hand = Hand(stream.readVar<qint32>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
packets::play::serverbound::PluginMessage::PluginMessage(McDataStream &stream)
|
packets::play::serverbound::PluginMessage::PluginMessage(McDataStream &stream)
|
||||||
{
|
{
|
||||||
channel = stream.readVar<QString>();
|
channel = stream.readVar<QString>();
|
||||||
@@ -78,31 +94,52 @@ void packets::play::clientbound::ServerDifficulty::serialize(McDataStream &strea
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketServerDifficulty);
|
tempStream.writeVar<qint32>(qint32(PacketType::ServerDifficulty));
|
||||||
tempStream << difficulty;
|
tempStream << difficulty;
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
stream.writeRawData(buffer.constData(), buffer.length());
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void packets::play::clientbound::ChatMessage::serialize(McDataStream &stream)
|
||||||
|
{
|
||||||
|
QByteArray buffer;
|
||||||
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
|
tempStream.writeVar<qint32>(qint32(PacketType::ChatMessage));
|
||||||
|
tempStream.writeVar<QString>(jsonData);
|
||||||
|
tempStream << qint8(position);
|
||||||
|
stream.writeVar<qint32>(buffer.length());
|
||||||
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
|
}
|
||||||
|
|
||||||
void packets::play::clientbound::PluginMessage::serialize(McDataStream &stream)
|
void packets::play::clientbound::PluginMessage::serialize(McDataStream &stream)
|
||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketPluginMessage);
|
tempStream.writeVar<qint32>(qint32(PacketType::PluginMessage));
|
||||||
tempStream.writeVar<QString>(channel);
|
tempStream.writeVar<QString>(channel);
|
||||||
buffer.append(data);
|
buffer.append(data);
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
stream.writeRawData(buffer.constData(), buffer.length());
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void packets::play::clientbound::Disconnect::serialize(McDataStream &stream)
|
||||||
|
{
|
||||||
|
QByteArray buffer;
|
||||||
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
|
tempStream.writeVar<qint32>(qint32(PacketType::Disconnect));
|
||||||
|
tempStream.writeVar<QString>(reason);
|
||||||
|
stream.writeVar<qint32>(buffer.length());
|
||||||
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
|
}
|
||||||
|
|
||||||
void packets::play::clientbound::JoinGame::serialize(McDataStream &stream)
|
void packets::play::clientbound::JoinGame::serialize(McDataStream &stream)
|
||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketJoinGame);
|
tempStream.writeVar<qint32>(qint32(PacketType::JoinGame));
|
||||||
tempStream << entityid
|
tempStream << entityid
|
||||||
<< gamemode
|
<< quint8(gamemode)
|
||||||
<< dimension
|
<< qint32(dimension)
|
||||||
<< difficulty
|
<< difficulty
|
||||||
<< maxPlayers;
|
<< maxPlayers;
|
||||||
tempStream.writeVar<QString>(levelType);
|
tempStream.writeVar<QString>(levelType);
|
||||||
@@ -115,7 +152,7 @@ void packets::play::clientbound::PlayerAbilities::serialize(McDataStream &stream
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketPlayerAbilities);
|
tempStream.writeVar<qint32>(qint32(PacketType::PlayerAbilities));
|
||||||
tempStream << flags;
|
tempStream << flags;
|
||||||
tempStream.writeFloat(flyingSpeed);
|
tempStream.writeFloat(flyingSpeed);
|
||||||
tempStream.writeFloat(fieldOfViewModifier);
|
tempStream.writeFloat(fieldOfViewModifier);
|
||||||
@@ -127,7 +164,7 @@ void packets::play::clientbound::PlayerPositionAndLook::serialize(McDataStream &
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketPlayerPositionAndLook);
|
tempStream.writeVar<qint32>(qint32(PacketType::PlayerPositionAndLook));
|
||||||
tempStream.writeDouble(x);
|
tempStream.writeDouble(x);
|
||||||
tempStream.writeDouble(y);
|
tempStream.writeDouble(y);
|
||||||
tempStream.writeDouble(z);
|
tempStream.writeDouble(z);
|
||||||
@@ -143,8 +180,18 @@ void packets::play::clientbound::SpawnPosition::serialize(McDataStream &stream)
|
|||||||
{
|
{
|
||||||
QByteArray buffer;
|
QByteArray buffer;
|
||||||
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
tempStream.writeVar<qint32>(PacketSpawnPosition);
|
tempStream.writeVar<qint32>(qint32(PacketType::SpawnPosition));
|
||||||
tempStream.writePosition(location);
|
tempStream.writePosition(location);
|
||||||
stream.writeVar<qint32>(buffer.length());
|
stream.writeVar<qint32>(buffer.length());
|
||||||
stream.writeRawData(buffer.constData(), buffer.length());
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void packets::play::clientbound::KeepAlive::serialize(McDataStream &stream)
|
||||||
|
{
|
||||||
|
QByteArray buffer;
|
||||||
|
McDataStream tempStream(&buffer, QIODevice::WriteOnly);
|
||||||
|
tempStream.writeVar<qint32>(qint32(PacketType::KeepAlive));
|
||||||
|
tempStream << keepAliveId;
|
||||||
|
stream.writeVar<qint32>(buffer.length());
|
||||||
|
stream.writeRawData(buffer.constData(), buffer.length());
|
||||||
|
}
|
||||||
|
78
packets.h
78
packets.h
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QtCore>
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
@@ -12,7 +14,10 @@ enum SocketState { HandshakingState, StatusState, LoginState, PlayState, ClosedS
|
|||||||
namespace packets {
|
namespace packets {
|
||||||
namespace handshaking {
|
namespace handshaking {
|
||||||
namespace serverbound {
|
namespace serverbound {
|
||||||
enum PacketType { PacketHandshake };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { Handshake };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct Handshake {
|
struct Handshake {
|
||||||
Handshake(McDataStream &stream);
|
Handshake(McDataStream &stream);
|
||||||
@@ -30,7 +35,10 @@ namespace packets {
|
|||||||
|
|
||||||
namespace status {
|
namespace status {
|
||||||
namespace serverbound {
|
namespace serverbound {
|
||||||
enum PacketType { PacketRequest, PacketPing };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { Request, Ping };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct Request {
|
struct Request {
|
||||||
Request(McDataStream &stream);
|
Request(McDataStream &stream);
|
||||||
@@ -44,7 +52,10 @@ namespace packets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace clientbound {
|
namespace clientbound {
|
||||||
enum PacketType { PacketResponse, PacketPong };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { Response, Pong };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct Response {
|
struct Response {
|
||||||
QString jsonResponse;
|
QString jsonResponse;
|
||||||
@@ -62,7 +73,10 @@ namespace packets {
|
|||||||
|
|
||||||
namespace login {
|
namespace login {
|
||||||
namespace serverbound {
|
namespace serverbound {
|
||||||
enum PacketType { PacketLogin };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { Login };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct Login {
|
struct Login {
|
||||||
Login(McDataStream &stream);
|
Login(McDataStream &stream);
|
||||||
@@ -72,7 +86,10 @@ namespace packets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace clientbound {
|
namespace clientbound {
|
||||||
enum PacketType { PacketLoginSuccess = 0x02 };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { LoginSuccess = 0x02 };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct LoginSuccess {
|
struct LoginSuccess {
|
||||||
QString uuid;
|
QString uuid;
|
||||||
@@ -85,7 +102,10 @@ namespace packets {
|
|||||||
|
|
||||||
namespace play {
|
namespace play {
|
||||||
namespace serverbound {
|
namespace serverbound {
|
||||||
enum PacketType { PacketClientSettings = 0x04, PacketPluginMessage = 0x0A };
|
Q_NAMESPACE
|
||||||
|
|
||||||
|
enum class PacketType { ClientSettings = 0x04, InteractEntity = 0x0E, PluginMessage = 0x0A };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct ClientSettings {
|
struct ClientSettings {
|
||||||
ClientSettings(McDataStream &stream);
|
ClientSettings(McDataStream &stream);
|
||||||
@@ -98,6 +118,19 @@ namespace packets {
|
|||||||
qint32 mainHand;
|
qint32 mainHand;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InteractEntity {
|
||||||
|
InteractEntity(McDataStream &stream);
|
||||||
|
|
||||||
|
qint32 entityId;
|
||||||
|
enum Type : qint32 { Interact, Attack, InteractAt };
|
||||||
|
Type type;
|
||||||
|
std::optional<float> targetX;
|
||||||
|
std::optional<float> targetY;
|
||||||
|
std::optional<float> targetZ;
|
||||||
|
enum Hand : qint32 { MainHand, OffHand };
|
||||||
|
std::optional<Hand> hand;
|
||||||
|
};
|
||||||
|
|
||||||
struct PluginMessage {
|
struct PluginMessage {
|
||||||
PluginMessage(McDataStream &stream);
|
PluginMessage(McDataStream &stream);
|
||||||
|
|
||||||
@@ -107,8 +140,11 @@ namespace packets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace clientbound {
|
namespace clientbound {
|
||||||
enum PacketType { PacketServerDifficulty = 0x0D, PacketPluginMessage = 0x19, PacketJoinGame = 0x25, PacketPlayerAbilities = 0x2E, PacketPlayerPositionAndLook = 0x32,
|
Q_NAMESPACE
|
||||||
PacketSpawnPosition = 0x49 };
|
|
||||||
|
enum class PacketType { ServerDifficulty = 0x0D, ChatMessage = 0x0E, PluginMessage = 0x19, Disconnect = 0x1B, KeepAlive = 0x21,
|
||||||
|
JoinGame = 0x25, PlayerAbilities = 0x2E, PlayerPositionAndLook = 0x32, SpawnPosition = 0x49 };
|
||||||
|
Q_ENUM_NS(PacketType)
|
||||||
|
|
||||||
struct ServerDifficulty {
|
struct ServerDifficulty {
|
||||||
quint8 difficulty;
|
quint8 difficulty;
|
||||||
@@ -116,6 +152,14 @@ namespace packets {
|
|||||||
void serialize(McDataStream &stream);
|
void serialize(McDataStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ChatMessage {
|
||||||
|
QString jsonData;
|
||||||
|
enum Position : qint8 { Chat, SystemMessage, GameInfo };
|
||||||
|
Position position;
|
||||||
|
|
||||||
|
void serialize(McDataStream &stream);
|
||||||
|
};
|
||||||
|
|
||||||
struct PluginMessage {
|
struct PluginMessage {
|
||||||
QString channel;
|
QString channel;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
@@ -123,10 +167,18 @@ namespace packets {
|
|||||||
void serialize(McDataStream &stream);
|
void serialize(McDataStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Disconnect {
|
||||||
|
QString reason;
|
||||||
|
|
||||||
|
void serialize(McDataStream &stream);
|
||||||
|
};
|
||||||
|
|
||||||
struct JoinGame {
|
struct JoinGame {
|
||||||
qint32 entityid;
|
qint32 entityid;
|
||||||
quint8 gamemode;
|
enum Gamemode : quint8 { Survival, Creative, Adventure, Spectator, Hardcore = 0x08 };
|
||||||
qint32 dimension;
|
Gamemode gamemode;
|
||||||
|
enum Dimension : qint32 { Nether=-1, Overworld=0, End=1 };
|
||||||
|
Dimension dimension;
|
||||||
quint8 difficulty;
|
quint8 difficulty;
|
||||||
quint8 maxPlayers;
|
quint8 maxPlayers;
|
||||||
QString levelType;
|
QString levelType;
|
||||||
@@ -160,6 +212,12 @@ namespace packets {
|
|||||||
|
|
||||||
void serialize(McDataStream &stream);
|
void serialize(McDataStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeepAlive {
|
||||||
|
qint64 keepAliveId;
|
||||||
|
|
||||||
|
void serialize(McDataStream &stream);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user