#ifndef __BITSTREAMUTILS__H__ #define __BITSTREAMUTILS__H__ #include "GeneralUtils.h" #include "BitStream.h" #include "MessageIdentifiers.h" #include "eConnectionType.h" #include #include #define VALIDATE_READ(x) do { if (!x) return false; } while (0) struct LUString { std::string string; uint32_t size; LUString(uint32_t size = 33) { this->size = size; }; LUString(std::string string, uint32_t size = 33) { this->string = string; this->size = size; }; std::u16string GetAsU16String() const { return GeneralUtils::ASCIIToUTF16(this->string); }; }; struct LUWString { std::u16string string; uint32_t size; LUWString(uint32_t size = 33) { this->size = size; }; LUWString(std::u16string string, uint32_t size = 33) { this->string = string; this->size = size; }; LUWString(std::string string, uint32_t size = 33) { this->string = GeneralUtils::ASCIIToUTF16(string); this->size = size; }; std::string GetAsString() const { return GeneralUtils::UTF16ToWTF8(this->string); }; }; struct LUBitStream { eConnectionType connectionType = eConnectionType::UNKNOWN; uint32_t internalPacketID = 0xFFFFFFFF; LUBitStream() = default; template LUBitStream(eConnectionType connectionType, T internalPacketID) { this->connectionType = connectionType; this->internalPacketID = static_cast(internalPacketID); } void WriteHeader(RakNet::BitStream& bitStream) const; bool ReadHeader(RakNet::BitStream& bitStream); void Send(const SystemAddress& sysAddr) const; virtual void Serialize(RakNet::BitStream& bitStream) const {} virtual bool Deserialize(RakNet::BitStream& bitStream) { return true; } virtual void Handle() {}; }; namespace BitStreamUtils { template void WriteHeader(RakNet::BitStream& bitStream, eConnectionType connectionType, T internalPacketID) { bitStream.Write(ID_USER_PACKET_ENUM); bitStream.Write(connectionType); bitStream.Write(static_cast(internalPacketID)); bitStream.Write(0); } } namespace RakNet { #ifndef __BITSTREAM_NATIVE_END #error No definition for big endian reading of LUString #endif template <> inline bool RakNet::BitStream::Read(LUString& value) { value.string.resize(value.size); bool res = ReadBits(reinterpret_cast(value.string.data()), BYTES_TO_BITS(value.string.size()), true); if (!res) return false; value.string.erase(std::find(value.string.begin(), value.string.end(), '\0'), value.string.end()); return res; } template <> inline bool RakNet::BitStream::Read(LUWString& value) { value.string.resize(value.size); bool res = ReadBits(reinterpret_cast(value.string.data()), BYTES_TO_BITS(value.string.size()) * sizeof(std::u16string::value_type), true); if (!res) return false; value.string.erase(std::find(value.string.begin(), value.string.end(), u'\0'), value.string.end()); return res; } template <> inline void RakNet::BitStream::Write(std::string value) { this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size())); } template <> inline void RakNet::BitStream::Write(std::u16string value) { this->WriteBits(reinterpret_cast(value.data()), BYTES_TO_BITS(value.size()) * sizeof(std::u16string::value_type)); } template <> inline void RakNet::BitStream::Write(LUString value) { value.string.resize(value.size); this->Write(value.string); } template <> inline void RakNet::BitStream::Write(LUWString value) { value.string.resize(value.size); this->Write(value.string); } }; #endif //!__BITSTREAMUTILS__H__