Add ZLIB for Windows (#768)

Added ZLIB for Windows.  Packets for character creation are now compressed on windows before sending and ZCompression can now be used on Windows.
This commit is contained in:
David Markowitz 2022-09-05 20:28:47 -07:00 committed by GitHub
parent ce2e6f595b
commit 63af2c8da7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 43 deletions

View File

@ -160,7 +160,6 @@ elseif (UNIX)
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include/bcrypt") set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "thirdparty/libbcrypt/include/bcrypt")
endif() endif()
include_directories(${ZLIB_INCLUDE_DIRS})
# Add binary directory as an include directory # Add binary directory as an include directory
include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR})

View File

@ -118,6 +118,11 @@
"execution": { "execution": {
"jobs": 2 "jobs": 2
}, },
"filter": {
"exclude": {
"name": "((example)|(minigzip))+"
}
},
"output": { "output": {
"outputOnFailure": true "outputOnFailure": true
} }

View File

@ -23,5 +23,31 @@ target_link_libraries(dCommon bcrypt)
if (UNIX) if (UNIX)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
target_link_libraries(dCommon ZLIB::ZLIB) elseif (WIN32)
include(FetchContent)
# TODO Keep an eye on the zlib repository for an update to disable testing. Don't forget to update CMakePresets
FetchContent_Declare(
zlib
URL https://github.com/madler/zlib/archive/refs/tags/v1.2.11.zip
URL_HASH MD5=9d6a627693163bbbf3f26403a3a0b0b1
)
# Disable warning about no project version.
set(CMAKE_POLICY_DEFAULT_CMP0048 NEW)
# Disable warning about the minimum version of cmake used for bcrypt being deprecated in the future
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(zlib)
set(ZLIB_INCLUDE_DIRS ${zlib_SOURCE_DIR} ${zlib_BINARY_DIR})
set_target_properties(zlib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}")
add_library(ZLIB::ZLIB ALIAS zlib)
else ()
message(
FATAL_ERROR
"This platform does not have a way to use zlib.\nCreate an issue on GitHub with your build system so it can be configured."
)
endif () endif ()
target_link_libraries(dCommon ZLIB::ZLIB)

View File

@ -1,7 +1,5 @@
#include "ZCompression.h" #include "ZCompression.h"
#ifndef _WIN32
#include <zlib.h> #include <zlib.h>
namespace ZCompression { namespace ZCompression {
@ -27,7 +25,6 @@ namespace ZCompression {
} }
deflateEnd(&zInfo); // zlib function deflateEnd(&zInfo); // zlib function
return(nRet); return(nRet);
} }
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr) { int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr) {
@ -48,26 +45,6 @@ namespace ZCompression {
} }
inflateEnd(&zInfo); // zlib function inflateEnd(&zInfo); // zlib function
return(nRet); return(nRet);
/*
z_stream zInfo = { 0 };
zInfo.total_in = zInfo.avail_in = nLenSrc;
zInfo.total_out = zInfo.avail_out = nLenDst;
zInfo.next_in = const_cast<Bytef*>(abSrc);
zInfo.next_out = const_cast<Bytef*>(abDst);
int nRet = -1;
nErr = inflateInit(&zInfo); // zlib function
if (nErr == Z_OK) {
nErr = inflate(&zInfo, Z_FINISH); // zlib function
if (nErr == Z_STREAM_END) {
nRet = zInfo.total_out;
}
}
inflateEnd(&zInfo); // zlib function
return(nRet); // -1 or len of output
*/
} }
} }
#endif

View File

@ -2,10 +2,6 @@
#include <cstdint> #include <cstdint>
#include "dPlatforms.h"
#ifndef DARKFLAME_PLATFORM_WIN32
namespace ZCompression { namespace ZCompression {
int32_t GetMaxCompressedLength(int32_t nLenSrc); int32_t GetMaxCompressedLength(int32_t nLenSrc);
@ -14,4 +10,3 @@ namespace ZCompression {
int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr); int32_t Decompress(const uint8_t* abSrc, int32_t nLenSrc, uint8_t* abDst, int32_t nLenDst, int32_t& nErr);
} }
#endif

View File

@ -164,27 +164,35 @@ void WorldPackets::SendCreateCharacter(const SystemAddress& sysAddr, Entity* ent
delete name; delete name;
delete reputation; delete reputation;
#ifdef _WIN32
bitStream.Write<uint32_t>(data.GetNumberOfBytesUsed() + 1);
bitStream.Write<uint8_t>(0);
bitStream.Write((char*)data.GetData(), data.GetNumberOfBytesUsed());
#else
//Compress the data before sending: //Compress the data before sending:
const int reservedSize = 5 * 1024 * 1024; const uint32_t reservedSize = ZCompression::GetMaxCompressedLength(data.GetNumberOfBytesUsed());
uint8_t compressedData[reservedSize]; uint8_t* compressedData = new uint8_t[reservedSize];
// TODO There should be better handling here for not enough memory...
if (!compressedData) return;
size_t size = ZCompression::Compress(data.GetData(), data.GetNumberOfBytesUsed(), compressedData, reservedSize); 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<uint32_t>(size + 9); //size of data + header bytes (8)
bitStream.Write<uint8_t>(1); //compressed boolean, true bitStream.Write<uint8_t>(1); //compressed boolean, true
bitStream.Write<uint32_t>(data.GetNumberOfBytesUsed()); bitStream.Write<uint32_t>(data.GetNumberOfBytesUsed());
bitStream.Write<uint32_t>(size); 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'.
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < size; i++)
bitStream.Write(compressedData[i]); bitStream.Write(compressedData[i]);
#endif #pragma warning(default:6385)
PacketUtils::SavePacket("chardata.bin", (const char*)bitStream.GetData(), static_cast<uint32_t>(bitStream.GetNumberOfBytesUsed())); // PacketUtils::SavePacket("chardata.bin", (const char*)bitStream.GetData(), static_cast<uint32_t>(bitStream.GetNumberOfBytesUsed()));
SEND_PACKET; SEND_PACKET;
delete[] compressedData;
Game::logger->Log("WorldPackets", "Sent CreateCharacter for ID: %llu", entity->GetObjectID()); Game::logger->Log("WorldPackets", "Sent CreateCharacter for ID: %llu", entity->GetObjectID());
} }