From 7301a2c787316e519b85a86f9ed89487ae8c3ebf Mon Sep 17 00:00:00 2001 From: Kieran Kihn <114803508+kierankihn@users.noreply.github.com> Date: Sun, 23 Nov 2025 15:01:08 +0800 Subject: [PATCH] feat(network): enhance `Message` validation and add `EMPTY` payload type - Introduced `MessageStatus` for message validation and tracking. - Added `EMPTY` payload type to `MessagePayloadType` for invalid or empty messages. - Updated `Message` constructor to validate payload type and status. - Implemented `getMessageStatus` to retrieve the message status. --- src/network/Message.cpp | 34 ++++++++++++++++++++++++++++++++-- src/network/Message.h | 9 +++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/network/Message.cpp b/src/network/Message.cpp index 85597b3..89a230e 100644 --- a/src/network/Message.cpp +++ b/src/network/Message.cpp @@ -6,12 +6,42 @@ */ #include "Message.h" +#include #include namespace UNO::NETWORK { - Message::Message(MessagePayloadType messagePayloadType, MessagePayload messagePayload) : - messagePayloadType_(messagePayloadType), messagePayload_(std::move(messagePayload)) + Message::Message(MessageStatus messageStatus, MessagePayloadType messagePayloadType, MessagePayload messagePayload) : + status_(messageStatus), messagePayloadType_(messagePayloadType), messagePayload_(std::move(messagePayload)) { + if (this->getMessageStatus() == MessageStatus::INVALID) { + if (this->getMessagePayloadType() != MessagePayloadType::EMPTY) { + throw std::invalid_argument("Invalid message: expected 'empty' payload type"); + } + if (std::holds_alternative(this->getMessagePayload()) == false) { + throw std::invalid_argument("Invalid message: expected std::monostate payload"); + } + } + else { + if ((this->getMessagePayloadType() == MessagePayloadType::JOIN_GAME + && std::holds_alternative(this->getMessagePayload()) == false) + || (this->getMessagePayloadType() == MessagePayloadType::START_GAME + && std::holds_alternative(this->getMessagePayload()) == false) + || (this->getMessagePayloadType() == MessagePayloadType::DRAW_CARD + && std::holds_alternative(this->getMessagePayload()) == false) + || (this->getMessagePayloadType() == MessagePayloadType::PLAY_CARD + && std::holds_alternative(this->getMessagePayload()) == false) + || (this->getMessagePayloadType() == MessagePayloadType::INIT_GAME + && std::holds_alternative(this->getMessagePayload()) == false) + || (this->getMessagePayloadType() == MessagePayloadType::END_GAME + && std::holds_alternative(this->getMessagePayload()) == false)) { + throw std::invalid_argument("Invalid message: MessagePayloadType and MessagePayload do not match"); + } + } + } + + MessageStatus Message::getMessageStatus() const + { + return this->status_; } MessagePayloadType Message::getMessagePayloadType() const diff --git a/src/network/Message.h b/src/network/Message.h index 4ed4e8e..47e7f8c 100644 --- a/src/network/Message.h +++ b/src/network/Message.h @@ -16,7 +16,7 @@ namespace UNO::NETWORK { - enum class MessagePayloadType { JOIN_GAME, START_GAME, DRAW_CARD, PLAY_CARD, INIT_GAME, END_GAME }; + enum class MessagePayloadType { EMPTY, JOIN_GAME, START_GAME, DRAW_CARD, PLAY_CARD, INIT_GAME, END_GAME }; struct JoinGamePayload { std::string playerName; @@ -43,14 +43,19 @@ namespace UNO::NETWORK { using MessagePayload = std::variant; + enum class MessageStatus { OK, INVALID }; + class Message { private: + MessageStatus status_; + MessagePayloadType messagePayloadType_; MessagePayload messagePayload_; public: - Message(MessagePayloadType messagePayloadType, MessagePayload messagePayload); + Message(MessageStatus messageStatus, MessagePayloadType messagePayloadType, MessagePayload messagePayload); + [[nodiscard]] MessageStatus getMessageStatus() const; [[nodiscard]] MessagePayloadType getMessagePayloadType() const; [[nodiscard]] MessagePayload getMessagePayload() const; };