From ab702e992748d6765fbfefb6f24aad091522039f Mon Sep 17 00:00:00 2001 From: Dan Paulat Date: Fri, 24 Dec 2021 12:08:15 -0600 Subject: [PATCH] Linked vector packet --- .../scwx/wsr88d/rpg/linked_vector_packet.hpp | 43 +++++++ wxdata/include/scwx/wsr88d/rpg/packet.hpp | 34 +++++ wxdata/include/scwx/wsr88d/rpg/vector2d.hpp | 46 +++++++ .../scwx/wsr88d/rpg/linked_vector_packet.cpp | 121 ++++++++++++++++++ wxdata/source/scwx/wsr88d/rpg/packet.cpp | 20 +++ wxdata/source/scwx/wsr88d/rpg/vector2d.cpp | 87 +++++++++++++ 6 files changed, 351 insertions(+) create mode 100644 wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp create mode 100644 wxdata/include/scwx/wsr88d/rpg/packet.hpp create mode 100644 wxdata/include/scwx/wsr88d/rpg/vector2d.hpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/packet.cpp create mode 100644 wxdata/source/scwx/wsr88d/rpg/vector2d.cpp diff --git a/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp b/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp new file mode 100644 index 00000000..fc4f8eff --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/linked_vector_packet.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class LinkedVectorPacketImpl; + +class LinkedVectorPacket : public Packet +{ +public: + explicit LinkedVectorPacket(); + ~LinkedVectorPacket(); + + LinkedVectorPacket(const LinkedVectorPacket&) = delete; + LinkedVectorPacket& operator=(const LinkedVectorPacket&) = delete; + + LinkedVectorPacket(LinkedVectorPacket&&) noexcept; + LinkedVectorPacket& operator=(LinkedVectorPacket&&) noexcept; + + uint16_t packet_code() const; + uint16_t length_of_block() const; + uint16_t value_of_vector() const; + + size_t data_size() const override; + + bool Parse(std::istream& is) override; + +private: + std::unique_ptr p; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/include/scwx/wsr88d/rpg/packet.hpp b/wxdata/include/scwx/wsr88d/rpg/packet.hpp new file mode 100644 index 00000000..f12c5d1a --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/packet.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class Packet : public Message +{ +protected: + explicit Packet(); + + Packet(const Packet&) = delete; + Packet& operator=(const Packet&) = delete; + + Packet(Packet&&) noexcept; + Packet& operator=(Packet&&) noexcept; + +public: + virtual ~Packet(); + + virtual uint16_t packet_code() const = 0; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/include/scwx/wsr88d/rpg/vector2d.hpp b/wxdata/include/scwx/wsr88d/rpg/vector2d.hpp new file mode 100644 index 00000000..87f3c4b8 --- /dev/null +++ b/wxdata/include/scwx/wsr88d/rpg/vector2d.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +class Vector2DImpl; + +class Vector2D : public Message +{ +public: + explicit Vector2D(); + ~Vector2D(); + + Vector2D(const Vector2D&) = delete; + Vector2D& operator=(const Vector2D&) = delete; + + Vector2D(Vector2D&&) noexcept; + Vector2D& operator=(Vector2D&&) noexcept; + + int16_t start_i() const; + int16_t start_j() const; + int16_t end_i() const; + int16_t end_j() const; + + size_t data_size() const override; + + bool Parse(std::istream& is) override; + + static constexpr size_t SIZE = 8u; + +private: + std::unique_ptr p; +}; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp b/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp new file mode 100644 index 00000000..07420020 --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/linked_vector_packet.cpp @@ -0,0 +1,121 @@ +#include +#include + +#include +#include +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = + "[scwx::wsr88d::rpg::linked_vector_packet] "; + +class LinkedVectorPacketImpl +{ +public: + explicit LinkedVectorPacketImpl() : + packetCode_ {}, lengthOfBlock_ {}, valueOfVector_ {}, vectorList_ {} {}; + ~LinkedVectorPacketImpl() = default; + + uint16_t packetCode_; + uint16_t lengthOfBlock_; + uint16_t valueOfVector_; + + std::vector vectorList_; +}; + +LinkedVectorPacket::LinkedVectorPacket() : + p(std::make_unique()) +{ +} +LinkedVectorPacket::~LinkedVectorPacket() = default; + +LinkedVectorPacket::LinkedVectorPacket(LinkedVectorPacket&&) noexcept = default; +LinkedVectorPacket& +LinkedVectorPacket::operator=(LinkedVectorPacket&&) noexcept = default; + +uint16_t LinkedVectorPacket::packet_code() const +{ + return p->packetCode_; +} + +uint16_t LinkedVectorPacket::length_of_block() const +{ + return p->lengthOfBlock_; +} + +uint16_t LinkedVectorPacket::value_of_vector() const +{ + return p->valueOfVector_; +} + +size_t LinkedVectorPacket::data_size() const +{ + return p->lengthOfBlock_ + 4u; +} + +bool LinkedVectorPacket::Parse(std::istream& is) +{ + bool blockValid = true; + + is.read(reinterpret_cast(&p->packetCode_), 2); + is.read(reinterpret_cast(&p->lengthOfBlock_), 2); + + p->packetCode_ = ntohs(p->packetCode_); + p->lengthOfBlock_ = ntohs(p->lengthOfBlock_); + + size_t vectorSize = p->lengthOfBlock_; + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else if (p->packetCode_ == 9) + { + is.read(reinterpret_cast(&p->valueOfVector_), 2); + p->valueOfVector_ = ntohs(p->valueOfVector_); + + vectorSize -= 2; + } + + // The number of vectors is equal to the size divided by the number of bytes + // in a vector + size_t vectorCount = Vector2D::SIZE / 8; + + for (size_t v = 0; v < vectorCount && !is.eof(); v++) + { + Vector2D vector; + vector.Parse(is); + p->vectorList_.push_back(std::move(vector)); + } + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + else + { + if (p->packetCode_ != 6 && p->packetCode_ != 9) + { + BOOST_LOG_TRIVIAL(warning) + << logPrefix_ << "Invalid packet code: " << p->packetCode_; + blockValid = false; + } + } + + return blockValid; +} + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/packet.cpp b/wxdata/source/scwx/wsr88d/rpg/packet.cpp new file mode 100644 index 00000000..aeb5b846 --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/packet.cpp @@ -0,0 +1,20 @@ +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = "[scwx::wsr88d::rpg::packet] "; + +Packet::Packet() = default; +Packet::~Packet() = default; + +Packet::Packet(Packet&&) noexcept = default; +Packet& Packet::operator=(Packet&&) noexcept = default; + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx diff --git a/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp b/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp new file mode 100644 index 00000000..9a86effa --- /dev/null +++ b/wxdata/source/scwx/wsr88d/rpg/vector2d.cpp @@ -0,0 +1,87 @@ +#include + +#include +#include +#include +#include + +#include + +namespace scwx +{ +namespace wsr88d +{ +namespace rpg +{ + +static const std::string logPrefix_ = "[scwx::wsr88d::rpg::vector2d] "; + +class Vector2DImpl +{ +public: + explicit Vector2DImpl() : startI_ {}, startJ_ {}, endI_ {}, endJ_ {} {}; + ~Vector2DImpl() = default; + + int16_t startI_; + int16_t startJ_; + int16_t endI_; + int16_t endJ_; +}; + +Vector2D::Vector2D() : p(std::make_unique()) {} +Vector2D::~Vector2D() = default; + +Vector2D::Vector2D(Vector2D&&) noexcept = default; +Vector2D& Vector2D::operator=(Vector2D&&) noexcept = default; + +int16_t Vector2D::start_i() const +{ + return p->startI_; +} + +int16_t Vector2D::start_j() const +{ + return p->startJ_; +} + +int16_t Vector2D::end_i() const +{ + return p->endI_; +} + +int16_t Vector2D::end_j() const +{ + return p->endJ_; +} + +size_t Vector2D::data_size() const +{ + return SIZE; +} + +bool Vector2D::Parse(std::istream& is) +{ + bool blockValid = true; + + is.read(reinterpret_cast(&p->startI_), 2); + is.read(reinterpret_cast(&p->startJ_), 2); + is.read(reinterpret_cast(&p->endI_), 2); + is.read(reinterpret_cast(&p->endJ_), 2); + + p->startI_ = ntohs(p->startI_); + p->startJ_ = ntohs(p->startJ_); + p->endI_ = ntohs(p->endI_); + p->endJ_ = ntohs(p->endJ_); + + if (is.eof()) + { + BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "Reached end of file"; + blockValid = false; + } + + return blockValid; +} + +} // namespace rpg +} // namespace wsr88d +} // namespace scwx