/* * Darkflame Universe * Copyright 2018 */ #include "ClientPackets.h" #include "dCommonVars.h" #include "LDFFormat.h" #include "ZCompression.h" namespace ClientPackets { void LoadStaticZone::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint16_t>(zoneID.GetMapID()); bitStream.Write<uint16_t>(zoneID.GetInstanceID()); bitStream.Write<uint32_t>(checksum); bitStream.Write<uint8_t>(editorEnabled); bitStream.Write<uint8_t>(editorLevel); bitStream.Write(position.x); bitStream.Write(position.y); bitStream.Write(position.z); bitStream.Write<uint32_t>(instanceType); } void CharacterCreationResponse::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write(response); } void CharacterRenameResponse::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write(response); } void CharacterDeleteResponse::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint8_t>(success); } void TransferToWorld::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write(LUString(serverIP)); bitStream.Write<uint16_t>(serverPort); bitStream.Write<uint8_t>(mythranShift); } void ServerState::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint8_t>(serverReady); } void CreateCharacter::Serialize(RakNet::BitStream &bitStream) const { RakNet::BitStream data; data.Write<uint32_t>(7); //LDF key count std::unique_ptr<LDFData<LWOOBJID>> objidLDF(new LDFData<LWOOBJID>(u"objid", objid)); objidLDF->WriteToPacket(data); std::unique_ptr<LDFData<LOT>> templateIDLDF(new LDFData<LOT>(u"template", templateID)); templateIDLDF->WriteToPacket(data); std::unique_ptr<LDFData<std::u16string>> nameLDF(new LDFData<std::u16string>(u"name", name)); nameLDF->WriteToPacket(data); std::unique_ptr<LDFData<int32_t>> gmlevelLDF(new LDFData<int32_t>(u"gmlevel", static_cast<int32_t>(gmLevel))); gmlevelLDF->WriteToPacket(data); std::unique_ptr<LDFData<int32_t>> chatModeLDF(new LDFData<int32_t>(u"chatmode", static_cast<int32_t>(chatMode))); chatModeLDF->WriteToPacket(data); std::unique_ptr<LDFData<std::string>> xmlConfigData(new LDFData<std::string>(u"xmlData", xmlData)); xmlConfigData->WriteToPacket(data); std::unique_ptr<LDFData<int64_t>> reputationLdf(new LDFData<int64_t>(u"reputation", reputation)); reputationLdf->WriteToPacket(data); //Compress the data before sending: const uint32_t reservedSize = ZCompression::GetMaxCompressedLength(data.GetNumberOfBytesUsed()); uint8_t* compressedData = new uint8_t[reservedSize]; if (!compressedData) { throw std::runtime_error("Failed to allocate memory for compressed data"); } size_t size = ZCompression::Compress(data.GetData(), data.GetNumberOfBytesUsed(), compressedData, reservedSize); assert(size <= reservedSize); bitStream.Write<uint32_t>(size + 9); //size of data + header bytes (8) bitStream.Write<uint8_t>(1); //compressed boolean, true bitStream.Write<uint32_t>(data.GetNumberOfBytesUsed()); bitStream.Write<uint32_t>(size); /** * In practice, this warning serves no purpose for us. We allocate the max memory needed on the heap * and then compress the data. In the off chance that the compression actually increases the size, * an assertion is done to prevent bad data from being saved or sent. */ #pragma warning(disable:6385) // C6385 Reading invalid data from 'compressedData'. bitStream.WriteAlignedBytes(compressedData, size); #pragma warning(default:6385) delete[] compressedData; }; void ChatModerationString::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint8_t>(rejectedWords.empty()); // Accepted bitStream.Write<uint16_t>(0); // padding bitStream.Write(chatChannel); bitStream.Write(chatMode); bitStream.Write(LUWString(receiver, 42)); for (auto it : rejectedWords) { bitStream.Write<uint8_t>(it.first); // start index bitStream.Write<uint8_t>(it.second); // length } // Pad out the rest of the packet // The client expects 64 items, so we need to write 64 - rejectedWords.size() empty items for (int i = rejectedWords.size(); 64 > i; i++) { bitStream.Write<uint16_t>(0); } } void GMLevelChange::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint8_t>(success); bitStream.Write(static_cast<uint16_t>(highestLevel)); bitStream.Write(static_cast<uint16_t>(prevLevel)); bitStream.Write(static_cast<uint16_t>(newLevel)); } void DebugOutput::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint32_t>(data.size()); bitStream.Write(data); } void HTTPMonitorInfoResponse::Serialize(RakNet::BitStream &bitStream) const { bitStream.Write<uint16_t>(port); bitStream.Write<uint8_t>(openWeb); bitStream.Write<uint8_t>(supportsSum); bitStream.Write<uint8_t>(supportsDetail); bitStream.Write<uint8_t>(supportsWho); bitStream.Write<uint8_t>(supportsObjects); } }