From 2b28b126daf62294aed85caf9939bf3813269edb Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Sat, 26 Jul 2014 19:00:56 +0200 Subject: [PATCH] refs #241 Generic FS9 multiplayer packet parser --- .../fs9/multiplayer_packet_parser.cpp | 38 +++++ .../simulator/fs9/multiplayer_packet_parser.h | 145 ++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 src/plugins/simulator/fs9/multiplayer_packet_parser.cpp create mode 100644 src/plugins/simulator/fs9/multiplayer_packet_parser.h diff --git a/src/plugins/simulator/fs9/multiplayer_packet_parser.cpp b/src/plugins/simulator/fs9/multiplayer_packet_parser.cpp new file mode 100644 index 000000000..624a2999e --- /dev/null +++ b/src/plugins/simulator/fs9/multiplayer_packet_parser.cpp @@ -0,0 +1,38 @@ +/* Copyright (C) 2014 + * swift project community / contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ +#include "multiplayer_packet_parser.h" + +namespace BlackSimPlugin +{ + namespace Fs9 + { + namespace Private + { + QByteArray readValue(const QByteArray &data, QString &val) + { + val = QString(data); + + // Up to know all packets with string data, had the string payload at the end + // of the packet. Therefore there should not be any data after the string. + // Remove the assert, if this will change in the future. + QByteArray leftOver = data.mid(val.size() + 1); + Q_ASSERT(leftOver.isEmpty()); + + return leftOver; + } + + QByteArray writeValue(QByteArray data, const QString &value) + { + data.append(qPrintable(value)); + return data; + } + + } + } +} diff --git a/src/plugins/simulator/fs9/multiplayer_packet_parser.h b/src/plugins/simulator/fs9/multiplayer_packet_parser.h new file mode 100644 index 000000000..ac0958945 --- /dev/null +++ b/src/plugins/simulator/fs9/multiplayer_packet_parser.h @@ -0,0 +1,145 @@ +/* Copyright (C) 2014 + * swift project community / contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of Swift Project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +#ifndef BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H +#define BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H + +#include "fs9.h" +#include +#include +#include +#include +#include + +//! \file + +namespace BlackSimPlugin +{ + namespace Fs9 + { + namespace Private + { + // Inhibit doxygen warnings about missing documentation + //! \cond PRIVATE + + // overload the following two for types that need special treatment + template + QByteArray readValue(const QByteArray &data, Value &val) + { + static_assert(std::is_arithmetic::value || + std::is_same::value, + "Unsupported type"); + + val = *reinterpret_cast(data.constData()); + return data.mid(sizeof(Value)); + } + + template + QByteArray writeValue(QByteArray data, const Value &value) + { + static_assert(std::is_arithmetic::value || + std::is_same::value, + "Unsupported type"); + + data.append(reinterpret_cast(&value), sizeof(Value)); + return data; + } + + QByteArray readValue(const QByteArray &data, QString &val); + + QByteArray writeValue(QByteArray data, const QString &value); + + template< typename MessageTuple, quint32 Size = std::tuple_size::value > + struct Serializer; + + template< typename MsgTuple > + struct Serializer + { + static const QByteArray &read(const QByteArray &data, MsgTuple &) { return data; } + static QByteArray write(QByteArray &data, const MsgTuple &) { return data; } + }; + + template< typename MessageTuple, quint32 Size > + struct Serializer + { + static QByteArray read(const QByteArray &data, MessageTuple &messageTuple) + { + return readValue(Serializer < MessageTuple, Size - 1 >::read(data, messageTuple), std::get < Size - 1 > (messageTuple)); + } + static QByteArray write(QByteArray &data, const MessageTuple &messageTuple) + { + return writeValue(Serializer < MessageTuple, Size - 1 >::write(data, messageTuple), std::get < Size - 1 > (messageTuple)); + } + }; + + template< class MessageTuple > + inline QByteArray doReadMessage(const QByteArray &data, MessageTuple messageTuple) + { + return Serializer::read(data, messageTuple); + } + + template< class MessageTuple > + inline QByteArray doWriteMessage(QByteArray &data, const MessageTuple &messageTuple) + { + return Serializer::write(data, messageTuple); + + } + + //! \endcond + } // namespace Private + + //! FS9 multiplayer protocol packet parser + class MultiPlayerPacketParser + { + public: + + //! Read message from byte stream + template< class Message > + static QByteArray readMessage(const QByteArray &data, Message &message) + { + return Private::doReadMessage(data.mid(2 * sizeof(qint32)), message.getTuple()); + } + + //! Write message to byte stream + template< class Message > + static QByteArray writeMessage(QByteArray &data, const Message &message) + { + return Private::doWriteMessage(data, message.getTuple()); + } + + //! Read the multiplayer packet type + static CFs9Sdk::MULTIPLAYER_PACKET_ID readType(const QByteArray &data) + { + QByteArray type = data.left(sizeof(CFs9Sdk::MULTIPLAYER_PACKET_ID)); + const quint32 *val = reinterpret_cast(type.constData()); + return static_cast(*val); + } + + //! Read the multiplayer packet size + static qint32 readSize(const QByteArray &data) + { + return *reinterpret_cast(data.mid(sizeof(qint32), sizeof(qint32)).constData()); + } + + //! Write the multiplayer packet type + static void writeType(QByteArray &data, CFs9Sdk::MULTIPLAYER_PACKET_ID type) + { + data.append(reinterpret_cast(&type), sizeof(CFs9Sdk::MULTIPLAYER_PACKET_ID)); + } + + //! Write the multiplayer packet size + static void writeSize(QByteArray &data, qint32 size) + { + data.append(reinterpret_cast(&size), sizeof(qint32)); + } + }; + } +} + +#endif //BLACKSIMPLUGIN_FS9_MP_PACKET_PARSER_H