bool cMapSerializer::Load(void) { AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); if (Data.empty()) { return false; } AString Uncompressed; int res = UncompressStringGZIP(Data.data(), Data.size(), Uncompressed); if (res != Z_OK) { return false; } // Parse the NBT data: cParsedNBT NBT(Uncompressed.data(), Uncompressed.size()); if (!NBT.IsValid()) { // NBT Parsing failed return false; } return LoadMapFromNBT(NBT); }
AString cLuaTCPLink::StartTLSServer( const AString & a_OwnCertData, const AString & a_OwnPrivKeyData, const AString & a_OwnPrivKeyPassword, const AString & a_StartTLSData ) { auto link = m_Link; if (link != nullptr) { // Create the peer cert: auto OwnCert = std::make_shared<cX509Cert>(); int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size()); if (res != 0) { return Printf("Cannot parse server certificate: -0x%x", res); } auto OwnPrivKey = std::make_shared<cCryptoKey>(); res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword); if (res != 0) { return Printf("Cannot parse server private key: -0x%x", res); } return link->StartTLSServer(OwnCert, OwnPrivKey, a_StartTLSData); } return ""; }
AString cLuaTCPLink::StartTLSClient( const AString & a_OwnCertData, const AString & a_OwnPrivKeyData, const AString & a_OwnPrivKeyPassword ) { auto link = m_Link; if (link != nullptr) { cX509CertPtr ownCert; if (!a_OwnCertData.empty()) { ownCert = std::make_shared<cX509Cert>(); auto res = ownCert->Parse(a_OwnCertData.data(), a_OwnCertData.size()); if (res != 0) { return Printf("Cannot parse client certificate: -0x%x", res); } } cCryptoKeyPtr ownPrivKey; if (!a_OwnPrivKeyData.empty()) { ownPrivKey = std::make_shared<cCryptoKey>(); auto res = ownPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword); if (res != 0) { return Printf("Cannot parse client private key: -0x%x", res); } } return link->StartTLSClient(ownCert, ownPrivKey); } return ""; }
QString MainWindow::getWorldName(const AString & a_Path) { AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat"); if (levelData.empty()) { // No such file / no data return QString(); } AString uncompressed; if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK) { return QString(); } cParsedNBT nbt(uncompressed.data(), uncompressed.size()); if (!nbt.IsValid()) { return QString(); } AString name = nbt.GetName(1); int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName"); if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String)) { return QString(); } return QString::fromStdString(nbt.GetString(levelNameTag)); }
bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) { // Serialize the chunk: cJsonChunkSerializer Serializer; if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) { // Chunk not valid LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); return false; } AString Data; Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); if (Serializer.HasJsonData()) { AString JsonData; Json::StyledWriter writer; JsonData = writer.write(Serializer.GetRoot()); Data.append(JsonData); } // Compress the data: AString CompressedData; int errorcode = CompressString(Data.data(), Data.size(), CompressedData, m_CompressionFactor); if ( errorcode != Z_OK ) { LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); return false; } // Erase any existing data for the chunk: EraseChunkData(a_Chunk); // Save the header: sChunkHeader * Header = new sChunkHeader; if (Header == NULL) { LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ); return false; } Header->m_CompressedSize = (int)CompressedData.size(); Header->m_ChunkX = a_Chunk.m_ChunkX; Header->m_ChunkZ = a_Chunk.m_ChunkZ; Header->m_UncompressedSize = (int)Data.size(); m_ChunkHeaders.push_back(Header); m_DataContents.append(CompressedData.data(), CompressedData.size()); m_NumDirty++; return true; }
bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_PortsIPv6) { // Read the HTTPS cert + key: AString CertFile = cFile::ReadWholeFile("webadmin/httpscert.crt"); AString KeyFile = cFile::ReadWholeFile("webadmin/httpskey.pem"); if (!CertFile.empty() && !KeyFile.empty()) { m_Cert.reset(new cX509Cert); int res = m_Cert->Parse(CertFile.data(), CertFile.size()); if (res == 0) { m_CertPrivKey.reset(new cCryptoKey); int res2 = m_CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), ""); if (res2 != 0) { // Reading the private key failed, reset the cert: LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res2); m_Cert.reset(); } } else { LOGWARNING("WebServer: Cannot read HTTPS certificate: -0x%x", -res); } } // Notify the admin about the HTTPS / HTTP status if (m_Cert.get() == nullptr) { LOGWARNING("WebServer: The server is running in unsecured HTTP mode."); LOGINFO("Put a valid HTTPS certificate in file 'webadmin/httpscert.crt' and its corresponding private key to 'webadmin/httpskey.pem' (without any password) to enable HTTPS support"); } else { LOGINFO("WebServer: The server is running in secure HTTPS mode."); } // Open up requested ports: bool HasAnyPort; m_ListenThreadIPv4.SetReuseAddr(true); m_ListenThreadIPv6.SetReuseAddr(true); HasAnyPort = m_ListenThreadIPv4.Initialize(a_PortsIPv4); HasAnyPort = m_ListenThreadIPv6.Initialize(a_PortsIPv6) || HasAnyPort; if (!HasAnyPort) { return false; } return true; }
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce) { // Decrypt EncNonce using privkey cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey(); Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)]; int res = rsaDecryptor.Decrypt((const Byte *)a_EncNonce.data(), a_EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce)); if (res != 4) { LOGD("Bad nonce length"); m_Client->Kick("Hacked client"); return; } if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this) { LOGD("Bad nonce value"); m_Client->Kick("Hacked client"); return; } // Decrypt the symmetric encryption key using privkey: Byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt((const Byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey, sizeof(DecryptedKey)); if (res != 16) { LOGD("Bad key length"); m_Client->Kick("Hacked client"); return; } { // Send encryption key response: cCSLock Lock(m_CSPacket); WriteByte(0xfc); WriteShort(0); WriteShort(0); Flush(); } #ifdef _DEBUG AString DecryptedKeyHex; CreateHexDump(DecryptedKeyHex, DecryptedKey, res, 16); LOGD("Received encryption key, %d bytes:\n%s", res, DecryptedKeyHex.c_str()); #endif StartEncryption(DecryptedKey); return; }
AString cLuaTCPLink::StartTLSClient( const AString & a_OwnCertData, const AString & a_OwnPrivKeyData, const AString & a_OwnPrivKeyPassword ) { // Check preconditions: if (m_SslContext != nullptr) { return "TLS is already active on this link"; } if ( (a_OwnCertData.empty() && !a_OwnPrivKeyData.empty()) || (!a_OwnCertData.empty() && a_OwnPrivKeyData.empty()) ) { return "Either provide both the certificate and private key, or neither"; } // Create the SSL context: m_SslContext.reset(new cLinkSslContext(*this)); m_SslContext->Initialize(true); // Create the peer cert, if required: if (!a_OwnCertData.empty() && !a_OwnPrivKeyData.empty()) { auto OwnCert = std::make_shared<cX509Cert>(); int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size()); if (res != 0) { m_SslContext.reset(); return Printf("Cannot parse peer certificate: -0x%x", res); } auto OwnPrivKey = std::make_shared<cCryptoKey>(); res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword); if (res != 0) { m_SslContext.reset(); return Printf("Cannot parse peer private key: -0x%x", res); } m_SslContext->SetOwnCert(OwnCert, OwnPrivKey); } m_SslContext->SetSelf(cLinkSslContextWPtr(m_SslContext)); // Start the handshake: m_SslContext->Handshake(); return ""; }
void cLuaState::Push(const AString & a_String) { ASSERT(IsValid()); lua_pushlstring(m_LuaState, a_String.data(), a_String.size()); m_NumCurrentFunctionArgs += 1; }
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) { if (m_Protocol == nullptr) { if (!m_Buffer.Write(a_Data, a_Size)) { m_Client->Kick("Unsupported protocol version"); return; } if (!TryRecognizeProtocol()) { return; } // The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing: AString Dump; m_Buffer.ResetRead(); m_Buffer.ReadAll(Dump); m_Protocol->DataReceived(Dump.data(), Dump.size()); } else { m_Protocol->DataReceived(a_Data, a_Size); } }
bool cMapSerializer::Save(void) { cFastNBTWriter Writer; SaveMapToNBT(Writer); Writer.Finish(); #ifdef _DEBUG cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); ASSERT(TestParse.IsValid()); #endif // _DEBUG cFile File; if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite)) { return false; } AString Compressed; int res = CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); if (res != Z_OK) { return false; } File.Write(Compressed.data(), Compressed.size()); File.Close(); return true; }
int cFile::ReadRestOfFile(AString & a_Contents) { ASSERT(IsOpen()); if (!IsOpen()) { return -1; } long TotalSize = GetSize(); if (TotalSize < 0) { return -1; } long Position = Tell(); if (Position < 0) { return -1; } auto DataSize = static_cast<size_t>(TotalSize - Position); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly a_Contents.assign(DataSize, '\0'); return Read(reinterpret_cast<void *>(const_cast<char *>(a_Contents.data())), DataSize); }
bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data) { // Decompress the data: char Uncompressed[CHUNK_INFLATE_MAX]; z_stream strm; strm.zalloc = (alloc_func)NULL; strm.zfree = (free_func)NULL; strm.opaque = NULL; inflateInit(&strm); strm.next_out = (Bytef *)Uncompressed; strm.avail_out = sizeof(Uncompressed); strm.next_in = (Bytef *)a_Data.data(); strm.avail_in = a_Data.size(); int res = inflate(&strm, Z_FINISH); inflateEnd(&strm); if (res != Z_STREAM_END) { return false; } // Parse the NBT data: cParsedNBT NBT(Uncompressed, strm.total_out); if (!NBT.IsValid()) { // NBT Parsing failed return false; } // Load the data from NBT: return LoadChunkFromNBT(a_Chunk, NBT); }
bool cBlockArea::LoadFromSchematicFile(const AString & a_FileName) { // Un-GZip the contents: AString Contents; cGZipFile File; if (!File.Open(a_FileName, cGZipFile::fmRead)) { LOG("Cannot open the schematic file \"%s\".", a_FileName.c_str()); return false; } int NumBytesRead = File.ReadRestOfFile(Contents); if (NumBytesRead < 0) { LOG("Cannot read GZipped data in the schematic file \"%s\", error %d", a_FileName.c_str(), NumBytesRead); return false; } File.Close(); // Parse the NBT: cParsedNBT NBT(Contents.data(), Contents.size()); if (!NBT.IsValid()) { LOG("Cannot parse the NBT in the schematic file \"%s\".", a_FileName.c_str()); return false; } return LoadFromSchematicNBT(NBT); }
bool cIDCountSerializer::Load(void) { AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); if (Data.empty()) { return false; } // NOTE: idcounts.dat is not compressed (raw format) // Parse the NBT data: cParsedNBT NBT(Data.data(), Data.size()); if (!NBT.IsValid()) { // NBT Parsing failed return false; } int CurrLine = NBT.FindChildByName(0, "map"); if (CurrLine >= 0) { m_MapCount = (int)NBT.GetShort(CurrLine) + 1; } else { m_MapCount = 0; } return true; }
bool cSocketThreads::cSocketThread::SendDataThroughSocket(cSocket & a_Socket, AString & a_Data) { // Send data in smaller chunks, so that the OS send buffers aren't overflown easily while (!a_Data.empty()) { size_t NumToSend = std::min(a_Data.size(), (size_t)1024); int Sent = a_Socket.Send(a_Data.data(), NumToSend); if (Sent < 0) { int Err = cSocket::GetLastError(); if (Err == cSocket::ErrWouldBlock) { // The OS send buffer is full, leave the outgoing data for the next time return true; } // An error has occured return false; } if (Sent == 0) { a_Socket.CloseSocket(); return true; } a_Data.erase(0, Sent); } return true; }
AString cTCPLinkImpl::StartTLSServer( cX509CertPtr a_OwnCert, cCryptoKeyPtr a_OwnPrivKey, const AString & a_StartTLSData ) { // Check preconditions: if (m_TlsContext != nullptr) { return "TLS is already active on this link"; } if ((a_OwnCert == nullptr) || (a_OwnPrivKey == nullptr)) { return "Provide the server certificate and private key"; } // Create the TLS context: m_TlsContext.reset(new cLinkTlsContext(*this)); m_TlsContext->Initialize(false); m_TlsContext->SetOwnCert(a_OwnCert, a_OwnPrivKey); m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext)); // Push the initial data: m_TlsContext->StoreReceivedData(a_StartTLSData.data(), a_StartTLSData.size()); // Start the handshake: m_TlsContext->Handshake(); return ""; }
void cHTTPConnection::SendStatusAndReason(int a_StatusCode, const AString & a_Response) { SendData(Printf("HTTP/1.1 %d %s\r\n", a_StatusCode, a_Response.c_str())); SendData(Printf("Content-Length: %u\r\n\r\n", static_cast<unsigned>(a_Response.size()))); SendData(a_Response.data(), a_Response.size()); m_State = wcsRecvHeaders; }
bool cPrefabPiecePool::LoadFromString(const AString & a_Contents, const AString & a_FileName, bool a_LogWarnings) { // If the contents start with GZip signature, ungzip and retry: if (a_Contents.substr(0, 3) == "\x1f\x8b\x08") { AString Uncompressed; auto res = UncompressStringGZIP(a_Contents.data(), a_Contents.size(), Uncompressed); if (res == Z_OK) { return LoadFromString(Uncompressed, a_FileName, a_LogWarnings); } else { CONDWARNING(a_LogWarnings, "Failed to decompress Gzip data in file %s: %d", a_FileName.c_str(), res); return false; } } // Search the first 8 KiB of the file for the format auto-detection string: auto Header = a_Contents.substr(0, 8192); if (Header.find("CubesetFormatVersion =") != AString::npos) { return LoadFromCubeset(a_Contents, a_FileName, a_LogWarnings); } CONDWARNING(a_LogWarnings, "Cannot load prefabs from file %s, unknown file format", a_FileName.c_str()); return false; }
cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) : m_CurrentStack(0) { m_Stack[0].m_Type = TAG_Compound; m_Result.reserve(100 * 1024); m_Result.push_back(TAG_Compound); WriteString(a_RootTagName.data(), a_RootTagName.size()); }
AString cLuaTCPLink::StartTLSServer( const AString & a_OwnCertData, const AString & a_OwnPrivKeyData, const AString & a_OwnPrivKeyPassword, const AString & a_StartTLSData ) { // Check preconditions: if (m_SslContext != nullptr) { return "TLS is already active on this link"; } if (a_OwnCertData.empty() || a_OwnPrivKeyData.empty()) { return "Provide the server certificate and private key"; } // Create the SSL context: m_SslContext.reset(new cLinkSslContext(*this)); m_SslContext->Initialize(false); // Create the peer cert: auto OwnCert = std::make_shared<cX509Cert>(); int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size()); if (res != 0) { m_SslContext.reset(); return Printf("Cannot parse server certificate: -0x%x", res); } auto OwnPrivKey = std::make_shared<cCryptoKey>(); res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword); if (res != 0) { m_SslContext.reset(); return Printf("Cannot parse server private key: -0x%x", res); } m_SslContext->SetOwnCert(OwnCert, OwnPrivKey); m_SslContext->SetSelf(cLinkSslContextWPtr(m_SslContext)); // Push the initial data: m_SslContext->StoreReceivedData(a_StartTLSData.data(), a_StartTLSData.size()); // Start the handshake: m_SslContext->Handshake(); return ""; }
bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data) { if (!OpenFile(false)) { LOGWARNING("Cannot save chunk [%d, %d], opening file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } int LocalX = a_Chunk.m_ChunkX % 32; if (LocalX < 0) { LocalX = 32 + LocalX; } int LocalZ = a_Chunk.m_ChunkZ % 32; if (LocalZ < 0) { LocalZ = 32 + LocalZ; } unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data); // Store the chunk data: m_File.Seek(ChunkSector * 4096); unsigned ChunkSize = htonl(a_Data.size() + 1); if (m_File.Write(&ChunkSize, 4) != 4) { LOGWARNING("Cannot save chunk [%d, %d], writing(1) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } char CompressionType = 2; if (m_File.Write(&CompressionType, 1) != 1) { LOGWARNING("Cannot save chunk [%d, %d], writing(2) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size())) { LOGWARNING("Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } // Store the header: ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096; // Round data size *up* to nearest 4KB sector, make it a sector number ASSERT(ChunkSize < 256); m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize); if (m_File.Seek(0) < 0) { LOGWARNING("Cannot save chunk [%d, %d], seeking in file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header)) { LOGWARNING("Cannot save chunk [%d, %d], writing header to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str()); return false; } return true; }
void cProtocol125::SendEntityMetadata(const cEntity & a_Entity) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_METADATA); WriteInt (a_Entity.GetUniqueID()); AString MetaData = GetEntityMetaData(a_Entity); SendData(MetaData.data(), MetaData.size()); Flush(); }
void cProtocol125::SendPluginMessage(const AString & a_Channel, const AString & a_Message) { cCSLock Lock(m_CSPacket); WriteByte(PACKET_PLUGIN_MESSAGE); WriteString(a_Channel); WriteShort((short)a_Message.size()); SendData(a_Message.data(), a_Message.size()); Flush(); }
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce) { // Decrypt EncNonce using privkey RSAES<PKCS1v15>::Decryptor rsaDecryptor(cRoot::Get()->GetServer()->GetPrivateKey()); time_t CurTime = time(NULL); CryptoPP::RandomPool rng; rng.Put((const byte *)&CurTime, sizeof(CurTime)); byte DecryptedNonce[MAX_ENC_LEN]; DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce); if (!res.isValidCoding || (res.messageLength != 4)) { LOGD("Bad nonce length"); m_Client->Kick("Hacked client"); return; } if (ntohl(*((int *)DecryptedNonce)) != (unsigned)(uintptr_t)this) { LOGD("Bad nonce value"); m_Client->Kick("Hacked client"); return; } // Decrypt the symmetric encryption key using privkey: byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey); if (!res.isValidCoding || (res.messageLength != 16)) { LOGD("Bad key length"); m_Client->Kick("Hacked client"); return; } { // Send encryption key response: cCSLock Lock(m_CSPacket); WriteByte((char)0xfc); WriteShort(0); WriteShort(0); Flush(); } StartEncryption(DecryptedKey); return; }
cPublicKey::cPublicKey(const AString & a_PublicKeyDER) { pk_init(&m_Pk); if (pk_parse_public_key(&m_Pk, (const Byte *)a_PublicKeyDER.data(), a_PublicKeyDER.size()) != 0) { ASSERT(!"Cannot parse PubKey"); return; } InitRnd(); }
bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData) { // Uncompress the data: AString UngzippedData; if (UncompressStringGZIP(a_SchematicData.data(), a_SchematicData.size(), UngzippedData) != Z_OK) { LOG("%s: Cannot unGZip the schematic data.", __FUNCTION__); return false; } // Parse the NBT: cParsedNBT NBT(UngzippedData.data(), UngzippedData.size()); if (!NBT.IsValid()) { LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__); return false; } return LoadFromSchematicNBT(a_BlockArea, NBT); }
static void TestWrite(void) { cByteBuffer buf(50); buf.WriteVarInt32(5); buf.WriteVarInt32(300); buf.WriteVarInt32(0); AString All; buf.ReadAll(All); assert_test(All.size() == 4); assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0); }
bool cByteBuffer::WriteBEUTF16String16(const AString & a_Value) { CHECK_THREAD; CheckValid(); PUTBYTES(2); AString UTF16BE; UTF8ToRawBEUTF16(a_Value.data(), a_Value.size(), UTF16BE); WriteBEShort((short)(UTF16BE.size() / 2)); PUTBYTES(UTF16BE.size()); WriteBuf(UTF16BE.data(), UTF16BE.size()); return true; }
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size) { if (m_Protocol == nullptr) { if (!m_Buffer.Write(a_Data, a_Size)) { m_Client->Kick("Unsupported protocol version"); return; } if (m_InPingForUnrecognizedVersion) { // We already know the verison; handle it here. UInt32 PacketLen; UInt32 PacketID; if (!m_Buffer.ReadVarInt32(PacketLen)) { return; } if (!m_Buffer.ReadVarInt32(PacketID)) { return; } ASSERT(PacketID == 0x01); // Ping packet ASSERT(PacketLen == 9); // Payload of the packet ID and a UInt64 Int64 Data; if (!m_Buffer.ReadBEInt64(Data)) { return; } cPacketizer Pkt(*this, 0x01); // Pong packet Pkt.WriteBEInt64(Data); return; } if (!TryRecognizeProtocol()) { return; } // The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing: AString Dump; m_Buffer.ResetRead(); m_Buffer.ReadAll(Dump); m_Protocol->DataReceived(Dump.data(), Dump.size()); } else { m_Protocol->DataReceived(a_Data, a_Size); } }