diff --git a/packets.cpp b/packets.cpp index 3787872..7a692a6 100644 --- a/packets.cpp +++ b/packets.cpp @@ -135,6 +135,21 @@ void packets::play::clientbound::ChatMessage::serialize(McDataStream &stream) stream.writeRawData(buffer.constData(), buffer.length()); } +void packets::play::clientbound::OpenWindow::serialize(McDataStream &stream) +{ + QByteArray buffer; + McDataStream tempStream(&buffer, QIODevice::WriteOnly); + tempStream.writeVar(qint32(PacketType::OpenWindow)); + tempStream << windowId; + tempStream.writeVar(windowType); + tempStream.writeVar(windowTitle); + tempStream << numberOfSlots; + if (entityId.has_value()) + tempStream << *entityId; + stream.writeVar(buffer.length()); + stream.writeRawData(buffer.constData(), buffer.length()); +} + void packets::play::clientbound::PluginMessage::serialize(McDataStream &stream) { QByteArray buffer; diff --git a/packets.h b/packets.h index 6c951f3..00d38f0 100644 --- a/packets.h +++ b/packets.h @@ -160,9 +160,9 @@ namespace packets { namespace clientbound { Q_NAMESPACE - enum class PacketType { SpawnMob = 0x03, ServerDifficulty = 0x0D, ChatMessage = 0x0E, PluginMessage = 0x19, Disconnect = 0x1B, - KeepAlive = 0x21, ChunkData = 0x22, JoinGame = 0x25, PlayerAbilities = 0x2E, PlayerPositionAndLook = 0x32, - SetExperience = 0x43, UpdateHealth = 0x44, SpawnPosition = 0x49 }; + enum class PacketType { SpawnMob = 0x03, ServerDifficulty = 0x0D, ChatMessage = 0x0E, OpenWindow = 0x14, PluginMessage = 0x19, + Disconnect = 0x1B, KeepAlive = 0x21, ChunkData = 0x22, JoinGame = 0x25, PlayerAbilities = 0x2E, + PlayerPositionAndLook = 0x32, SetExperience = 0x43, UpdateHealth = 0x44, SpawnPosition = 0x49 }; Q_ENUM_NS(PacketType) // does not work yet, client shows exception @@ -197,6 +197,16 @@ namespace packets { void serialize(McDataStream &stream); }; + struct OpenWindow { + quint8 windowId; + QString windowType; + QString windowTitle; + quint8 numberOfSlots; + std::optional entityId; + + void serialize(McDataStream &stream); + }; + struct PluginMessage { QString channel; QByteArray data; diff --git a/playclient.cpp b/playclient.cpp index 0614102..63ffcae 100644 --- a/playclient.cpp +++ b/playclient.cpp @@ -106,12 +106,6 @@ void PlayClient::tick() m_lastKeepAliveSent = now; } - if (!m_lastChatMessage.isValid() || m_lastChatMessage.secsTo(now) >= 2) - { - sendChatMessage(ChatPart{.text=tr("Time chaged to %0").arg(QTime::currentTime().toString())}.toString()); - m_lastChatMessage = now; - } - if (!m_lastStats.isValid() || m_lastStats.msecsTo(now) >= 500) { { @@ -131,17 +125,6 @@ void PlayClient::tick() m_lastStats = now; } - - if (m_connectedSince.secsTo(now) >= 30) - { - packets::play::clientbound::Disconnect packet; - packet.reason = ChatPart{.text="Your trial has ended.",.bold=true}.toString(); - packet.serialize(m_dataStream); - m_socket->flush(); - m_dataStream.setDevice({}); - new ClosedClient{std::move(m_socket), m_server}; - deleteLater(); - } } void PlayClient::sendChatMessage(const QString &message) @@ -152,6 +135,17 @@ void PlayClient::sendChatMessage(const QString &message) packet.serialize(m_dataStream); } +void PlayClient::disconnectClient(const QString &reason) +{ + packets::play::clientbound::Disconnect packet; + packet.reason = reason; + packet.serialize(m_dataStream); + m_socket->flush(); + m_dataStream.setDevice({}); + new ClosedClient{std::move(m_socket), m_server}; + deleteLater(); +} + void PlayClient::readyRead() { while(m_socket && m_socket->bytesAvailable()) @@ -193,9 +187,34 @@ void PlayClient::readPacket(packets::play::serverbound::PacketType type, const Q { serverbound::ChatMessage packet{dataStream}; qDebug() << "message" << packet.message; - const auto formatted = ChatPart{.extra={ChatPart{.text=m_name,.color="red"},ChatPart{.text=": " + packet.message}}}.toString(); - emit distributeChatMessage(formatted); - sendChatMessage(formatted); + if (packet.message.startsWith('/')) + { + auto args = packet.message.split(' ', Qt::SkipEmptyParts); + if (args.first() == "/help") + { + sendChatMessage(ChatPart{.text=tr("Help:")}.toString()); + sendChatMessage(ChatPart{.text=tr(" * /help")}.toString()); + sendChatMessage(ChatPart{.text=tr(" * /disconnect")}.toString()); + sendChatMessage(ChatPart{.text=tr(" * /menu")}.toString()); + } + else if (args.first() == "/disconnect") + { + disconnectClient(ChatPart{.text="Your trial has ended.",.bold=true}.toString()); + } + else if (args.first() == "/menu") + { + } + else + { + sendChatMessage(ChatPart{.text=tr("Unknown command %0").arg(args.first()),.color="red"}.toString()); + } + } + else + { + const auto formatted = ChatPart{.extra={ChatPart{.text=m_name,.color="red"},ChatPart{.text=": " + packet.message}}}.toString(); + sendChatMessage(formatted); + emit distributeChatMessage(formatted); + } } break; } diff --git a/playclient.h b/playclient.h index 82126b4..d9e85db 100644 --- a/playclient.h +++ b/playclient.h @@ -25,6 +25,7 @@ signals: public slots: void sendChatMessage(const QString &message); + void disconnectClient(const QString &reason); private slots: void readyRead(); @@ -43,6 +44,4 @@ private: const QDateTime m_connectedSince{QDateTime::currentDateTime()}; QDateTime m_lastKeepAliveSent; QDateTime m_lastKeepAliveReceived; - QDateTime m_lastChatMessage; - QDateTime m_lastStats; }; diff --git a/server.cpp b/server.cpp index d3172c1..8839ab6 100644 --- a/server.cpp +++ b/server.cpp @@ -48,5 +48,4 @@ void Server::newConnection() auto connection = std::unique_ptr(m_server.nextPendingConnection()); if (connection) new HandshakingClient{std::move(connection), *this}; - //clients.push_back(); }