18 first block data, 32bit
22 second block index...
Length: 16 + multiple of 6, max 484
+
+
+Message
+-------
+
+Sent by the client when the user submits a line on the chat input.
+Sent by the server on various events like player chat, server status, command output, etc.
+
+Code: 12
+Payload:
+ 0 message type, 8bit unsigned int: 0 = notification, 1 = chat
+ 1 referral, 32bit unsigned int, entity ID if type = 1
+ 5 message, max 450 byte UTF-8 string, should be zero terminated if shorter
+Length: 6-455
virtual void On(const Packet::ChunkBegin &) { }
virtual void On(const Packet::ChunkData &) { }
virtual void On(const Packet::BlockUpdate &) { }
+ virtual void On(const Packet::Message &) { }
private:
unsigned int packets_lost;
void ReadBlock(Block &, std::uint32_t) const noexcept;
};
+ struct Message : public Payload {
+ static constexpr std::uint8_t TYPE = 12;
+ static constexpr std::size_t MAX_LEN = 455;
+
+ static constexpr std::size_t MAX_MESSAGE_LEN = 450;
+ static std::size_t GetSize(const std::string &msg) noexcept {
+ return 5 + std::min(msg.size() + 1, MAX_MESSAGE_LEN);
+ }
+
+ void WriteType(std::uint8_t) noexcept;
+ void ReadType(std::uint8_t &) const noexcept;
+ void WriteReferral(std::uint32_t) noexcept;
+ void ReadReferral(std::uint32_t &) const noexcept;
+ void WriteMessage(const std::string &) noexcept;
+ void ReadMessage(std::string &) const noexcept;
+ };
+
template<class PayloadType>
PayloadType As() {
constexpr size_t Packet::ChunkBegin::MAX_LEN;
constexpr size_t Packet::ChunkData::MAX_LEN;
constexpr size_t Packet::BlockUpdate::MAX_LEN;
+constexpr size_t Packet::Message::MAX_LEN;
+constexpr size_t Packet::Message::MAX_MESSAGE_LEN;
Connection::Connection(const IPaddress &addr)
: handler(nullptr)
return "ChunkData";
case BlockUpdate::TYPE:
return "BlockUpdate";
+ case Message::TYPE:
+ return "Message";
default:
return "Unknown";
}
Read(block, off);
}
+void Packet::Message::WriteType(uint8_t type) noexcept {
+ Write(type, 0);
+}
+
+void Packet::Message::ReadType(uint8_t &type) const noexcept {
+ Read(type, 0);
+}
+
+void Packet::Message::WriteReferral(uint32_t ref) noexcept {
+ Write(ref, 1);
+}
+
+void Packet::Message::ReadReferral(uint32_t &ref) const noexcept {
+ Read(ref, 1);
+}
+
+void Packet::Message::WriteMessage(const string &msg) noexcept {
+ WriteString(msg, 5, MAX_MESSAGE_LEN);
+}
+
+void Packet::Message::ReadMessage(string &msg) const noexcept {
+ ReadString(msg, 5, MAX_MESSAGE_LEN);
+}
+
void ConnectionHandler::Handle(const UDPpacket &udp_pack) {
const Packet &pack = *reinterpret_cast<const Packet *>(udp_pack.data);
case Packet::BlockUpdate::TYPE:
On(Packet::As<Packet::BlockUpdate>(udp_pack));
break;
+ case Packet::Message::TYPE:
+ On(Packet::As<Packet::Message>(udp_pack));
+ break;
default:
// drop unknown or unhandled packets
break;
);
}
+void PacketTest::testMessage() {
+ auto pack = Packet::Make<Packet::Message>(udp_pack);
+ AssertPacket("Message", 12, 6, 455, pack);
+
+ const uint8_t write_type = 1;
+ const uint32_t write_ref = 6433235;
+ const string write_msg("hello, world");
+
+ pack.length = Packet::Message::GetSize(write_msg);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "length not correctly set in BlockUpdate packet",
+ size_t(5 + write_msg.size() + 1), pack.length
+ );
+
+ pack.WriteType(write_type);
+ pack.WriteReferral(write_ref);
+ pack.WriteMessage(write_msg);
+
+ uint8_t read_type = 5;
+ uint32_t read_ref = 884373;
+ string read_msg;
+
+ pack.ReadType(read_type);
+ pack.ReadReferral(read_ref);
+ pack.ReadMessage(read_msg);
+
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "type not correctly transported in Message packet",
+ write_type, read_type
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "referral not correctly transported in Message packet",
+ write_ref, read_ref
+ );
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(
+ "message not correctly transported in Message packet",
+ write_msg, read_msg
+ );
+}
+
void PacketTest::AssertPacket(
const string &name,
CPPUNIT_TEST(testChunkBegin);
CPPUNIT_TEST(testChunkData);
CPPUNIT_TEST(testBlockUpdate);
+CPPUNIT_TEST(testMessage);
CPPUNIT_TEST_SUITE_END();
void testChunkBegin();
void testChunkData();
void testBlockUpdate();
+ void testMessage();
private:
static void AssertPacket(