mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #2781 from janisozaur/zlib
Use zlib for muliplayer game transfer
This commit is contained in:
commit
ed1ba15163
|
@ -46,12 +46,13 @@ endif (DISABLE_NETWORK)
|
|||
|
||||
option(STATIC "Create a static build.")
|
||||
|
||||
# Not required yet
|
||||
PKG_CHECK_MODULES(PNG libpng>=1.6)
|
||||
if (NOT PNG_FOUND)
|
||||
PKG_CHECK_MODULES(PNG REQUIRED libpng16)
|
||||
endif (NOT PNG_FOUND)
|
||||
|
||||
PKG_CHECK_MODULES(ZLIB REQUIRED zlib)
|
||||
|
||||
# Handle creating the rct2 text and data files on OS X and Linux
|
||||
# See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values
|
||||
# were derived.
|
||||
|
@ -143,9 +144,9 @@ else (STATIC)
|
|||
endif (STATIC)
|
||||
|
||||
if (STATIC)
|
||||
SET(PNGLIBS ${PNG_STATIC_LIBRARIES})
|
||||
SET(REQUIREDLIBS ${PNG_STATIC_LIBRARIES} ${ZLIB_STATIC_LIBRARIES})
|
||||
else (STATIC)
|
||||
SET(PNGLIBS ${PNG_LIBRARIES})
|
||||
SET(REQUIREDLIBS ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
endif (STATIC)
|
||||
|
||||
if (NOT DISABLE_HTTP_TWITCH)
|
||||
|
@ -163,24 +164,16 @@ if (NOT DISABLE_HTTP_TWITCH)
|
|||
endif (STATIC)
|
||||
endif (NOT DISABLE_HTTP_TWITCH)
|
||||
|
||||
# speex v1.1.15 is supplied in our zipped library, but distributions provide
|
||||
# updated version, with required functions extracted out to libspeexdsp.
|
||||
# This largely takes care of the problem
|
||||
if (WIN32)
|
||||
include_directories("lib/libspeex/")
|
||||
file(GLOB_RECURSE SPEEX_SOURCES "lib/libspeex/*.c")
|
||||
else (WIN32)
|
||||
PKG_CHECK_MODULES(SPEEX REQUIRED speexdsp)
|
||||
endif (WIN32)
|
||||
PKG_CHECK_MODULES(SPEEX REQUIRED speexdsp)
|
||||
|
||||
if (UNIX)
|
||||
# Include libdl for dlopen
|
||||
set(DLLIB dl)
|
||||
endif (UNIX)
|
||||
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
|
||||
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${LIBCURL_INCLUDE_DIRS} ${JANSSON_INCLUDE_DIRS} ${SPEEX_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
|
||||
LINK_DIRECTORIES(${SDL2_LIBRARY_DIRS} ${JANSSON_LIBRARY_DIRS} ${LIBCURL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS} ${ZLIB_LIBRARY_DIRS})
|
||||
|
||||
if (WIN32)
|
||||
# build as library for now, replace with add_executable
|
||||
|
@ -213,7 +206,7 @@ endif (UNIX AND NOT APPLE)
|
|||
# libopenrct2.dll -> openrct2.dll
|
||||
set_target_properties(${PROJECT} PROPERTIES PREFIX "")
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${PNGLIBS})
|
||||
TARGET_LINK_LIBRARIES(${PROJECT} ${SDL2LIBS} ${HTTPLIBS} ${NETWORKLIBS} ${SPEEX_LIBRARIES} ${DLLIB} ${REQUIREDLIBS})
|
||||
|
||||
if (APPLE OR STATIC)
|
||||
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
D435325F1C3472E500BA219B /* libpng.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; };
|
||||
D43532601C34730200BA219B /* libpng.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */ = {isa = PBXBuildFile; fileRef = D46105CD1C38828D00DB1EE3 /* scenario_sources.c */; };
|
||||
D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D47304D41C4FF8250015C0EA /* libz.tbd */; };
|
||||
D4ABAB061C2F812B0080CAD9 /* news_options.c in Sources */ = {isa = PBXBuildFile; fileRef = D4ABAB051C2F812B0080CAD9 /* news_options.c */; };
|
||||
D4B63B8F1C43025600367A37 /* CommandLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B8A1C43025600367A37 /* CommandLine.cpp */; };
|
||||
D4B63B901C43025600367A37 /* RootCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B8C1C43025600367A37 /* RootCommands.cpp */; };
|
||||
|
@ -224,6 +225,7 @@
|
|||
D41B74721C2125E50080A7B9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = distribution/osx/Assets.xcassets; sourceTree = SOURCE_ROOT; };
|
||||
D435325E1C3472E500BA219B /* libpng.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libpng.dylib; sourceTree = "<group>"; };
|
||||
D46105CD1C38828D00DB1EE3 /* scenario_sources.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scenario_sources.c; path = src/scenario_sources.c; sourceTree = "<group>"; };
|
||||
D47304D41C4FF8250015C0EA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/osx/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
D497D0781C20FD52002BF46A /* OpenRCT2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenRCT2.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4ABAB051C2F812B0080CAD9 /* news_options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = news_options.c; sourceTree = "<group>"; };
|
||||
|
@ -567,6 +569,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */,
|
||||
D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */,
|
||||
D41B741D1C210A7A0080A7B9 /* libiconv.tbd in Frameworks */,
|
||||
D435325F1C3472E500BA219B /* libpng.dylib in Frameworks */,
|
||||
|
@ -1135,6 +1138,7 @@
|
|||
D41B73EE1C2101890080A7B9 /* libcurl.tbd */,
|
||||
D41B741C1C210A7A0080A7B9 /* libiconv.tbd */,
|
||||
D41B73F01C21018C0080A7B9 /* libssl.tbd */,
|
||||
D47304D41C4FF8250015C0EA /* libz.tbd */,
|
||||
);
|
||||
name = system;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
@ -320,14 +320,14 @@
|
|||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(IncludePath)</IncludePath>
|
||||
<IncludePath>$(SolutionDir)lib\include;$(SolutionDir)lib\include\libspeex;$(SolutionDir)lib\include\sdl;$(SolutionDir)lib\include\jansson;$(SolutionDir)lib\include\sdl_ttf;$(SolutionDir)lib\include\libpng;$(SolutionDir)lib\include\zlib;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
|
||||
<OutDir>$(SolutionDir)bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)obj\$(ProjectName)\$(Configuration)\</IntDir>
|
||||
|
|
|
@ -19,7 +19,7 @@ if [[ $TARGET != "linux" && $TARGET != "docker32" && $SYSTEM != "Darwin" ]]; the
|
|||
# keep in sync with version in Xcode project
|
||||
sha256sum=6562ce9e1f37f125e3345bfd8b961777800436bf607b30dc7c964e0e6991ad2c
|
||||
else
|
||||
sha256sum=31c5e19d9f794bd5f0e75f20c2b4c3c4664d736b0a4d50c8cde14a9a9007b62d
|
||||
sha256sum=f124c954bbd0b58c93e5fba46902806bd3637d3a1c5fb8e4b67441052f182df2
|
||||
fi
|
||||
libVFile="./libversion"
|
||||
libdir="./lib"
|
||||
|
|
|
@ -114,11 +114,6 @@ function install_pkg_config {
|
|||
cat /usr/local/bin/i686-w64-mingw32-pkg-config
|
||||
}
|
||||
|
||||
function install_local_libs {
|
||||
mkdir -p lib
|
||||
cp -rf $cachedir/orctlibs/local/* ./lib/.
|
||||
}
|
||||
|
||||
function os_x_install_mingw_32 {
|
||||
local mingw_name="mingw-w32-bin_i686-darwin"
|
||||
local mingw_tar="${mingw_name}_20130531.tar.bz2"
|
||||
|
@ -198,7 +193,6 @@ if [[ $TARGET == "windows" || $(uname -s) == "Darwin" ]]; then
|
|||
calculate_sha256 "$cachedir/orctlibs.zip" > "$libVFile"
|
||||
echo "Downloaded library with sha256sum: $(cat "$libVFile")"
|
||||
# Local libs are required for all targets
|
||||
install_local_libs
|
||||
# $TARGET == "windows" || $(uname -s) == "Darwin"
|
||||
fi
|
||||
|
||||
|
|
|
@ -988,21 +988,34 @@ void Network::Server_Send_MAP(NetworkConnection* connection)
|
|||
{
|
||||
int buffersize = 0x600000;
|
||||
std::vector<uint8> buffer(buffersize);
|
||||
bool RLEState = gUseRLE;
|
||||
gUseRLE = false;
|
||||
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffersize);
|
||||
scenario_save_network(rw);
|
||||
gUseRLE = RLEState;
|
||||
int size = (int)SDL_RWtell(rw);
|
||||
int chunksize = 1000;
|
||||
for (int i = 0; i < size; i += chunksize) {
|
||||
int datasize = (std::min)(chunksize, size - i);
|
||||
size_t chunksize = 1000;
|
||||
size_t out_size;
|
||||
unsigned char *compressed = util_zlib_deflate(&buffer[0], size, &out_size);
|
||||
unsigned char *header = (unsigned char *)strdup("open2_sv6_zlib");
|
||||
size_t header_len = strlen((char *)header) + 1; // account for null terminator
|
||||
header = (unsigned char *)realloc(header, header_len + out_size);
|
||||
memcpy(&header[header_len], compressed, out_size);
|
||||
out_size += header_len;
|
||||
free(compressed);
|
||||
log_verbose("Sending map of size %u bytes, compressed to %u bytes", size, out_size);
|
||||
for (int i = 0; i < out_size; i += chunksize) {
|
||||
int datasize = (std::min)(chunksize, out_size - i);
|
||||
std::unique_ptr<NetworkPacket> packet = std::move(NetworkPacket::Allocate());
|
||||
*packet << (uint32)NETWORK_COMMAND_MAP << (uint32)size << (uint32)i;
|
||||
packet->Write(&buffer[i], datasize);
|
||||
*packet << (uint32)NETWORK_COMMAND_MAP << (uint32)out_size << (uint32)i;
|
||||
packet->Write(&header[i], datasize);
|
||||
if (connection) {
|
||||
connection->QueuePacket(std::move(packet));
|
||||
} else {
|
||||
SendPacketToClients(*packet);
|
||||
}
|
||||
}
|
||||
free(header);
|
||||
SDL_RWclose(rw);
|
||||
}
|
||||
|
||||
|
@ -1349,8 +1362,26 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
|
|||
memcpy(&chunk_buffer[offset], (void*)packet.Read(chunksize), chunksize);
|
||||
if (offset + chunksize == size) {
|
||||
window_network_status_close();
|
||||
bool has_to_free = false;
|
||||
unsigned char *data = &chunk_buffer[0];
|
||||
size_t data_size = size;
|
||||
// zlib-compressed
|
||||
if (strcmp("open2_sv6_zlib", (char *)&chunk_buffer[0]) == 0)
|
||||
{
|
||||
log_warning("Received zlib-compressed sv6 map");
|
||||
has_to_free = true;
|
||||
size_t header_len = strlen("open2_sv6_zlib") + 1;
|
||||
data = util_zlib_inflate(&chunk_buffer[header_len], size - header_len, &data_size);
|
||||
if (data == NULL)
|
||||
{
|
||||
log_warning("Failed to decompress data sent from server.");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
log_warning("Assuming received map is in plain sv6 format");
|
||||
}
|
||||
|
||||
SDL_RWops* rw = SDL_RWFromMem(&chunk_buffer[0], size);
|
||||
SDL_RWops* rw = SDL_RWFromMem(data, data_size);
|
||||
if (game_load_network(rw)) {
|
||||
game_load_init();
|
||||
game_command_queue.clear();
|
||||
|
@ -1360,6 +1391,10 @@ int Network::Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& pac
|
|||
_desynchronised = false;
|
||||
}
|
||||
SDL_RWclose(rw);
|
||||
if (has_to_free)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../platform/platform.h"
|
||||
#include "sawyercoding.h"
|
||||
#include "../scenario.h"
|
||||
#include "util.h"
|
||||
|
||||
static size_t decode_chunk_rle(const uint8* src_buffer, uint8* dst_buffer, size_t length);
|
||||
static size_t decode_chunk_repeat(uint8 *buffer, size_t length);
|
||||
|
@ -138,6 +139,11 @@ size_t sawyercoding_read_chunk(SDL_RWops* rw, uint8 *buffer)
|
|||
size_t sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding_chunk_header chunkHeader){
|
||||
uint8 *encode_buffer, *encode_buffer2;
|
||||
|
||||
if (gUseRLE == false) {
|
||||
if (chunkHeader.encoding == CHUNK_ENCODING_RLE || chunkHeader.encoding == CHUNK_ENCODING_RLECOMPRESSED) {
|
||||
chunkHeader.encoding = CHUNK_ENCODING_NONE;
|
||||
}
|
||||
}
|
||||
switch (chunkHeader.encoding){
|
||||
case CHUNK_ENCODING_NONE:
|
||||
memcpy(dst_file, &chunkHeader, sizeof(sawyercoding_chunk_header));
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include "util.h"
|
||||
#include <SDL.h>
|
||||
#include "../platform/platform.h"
|
||||
#include "zlib.h"
|
||||
|
||||
bool gUseRLE = true;
|
||||
|
||||
int squaredmetres_to_squaredfeet(int squaredMetres)
|
||||
{
|
||||
|
@ -313,3 +316,69 @@ uint32 util_rand() {
|
|||
srand3 = srand3 ^ (srand3 >> 19) ^ temp ^ (temp >> 8);
|
||||
return srand3;
|
||||
}
|
||||
|
||||
#define CHUNK 128*1024
|
||||
#define MAX_ZLIB_REALLOC 4*1024*1024
|
||||
|
||||
/**
|
||||
* @brief Inflates zlib-compressed data
|
||||
* @param data Data to be decompressed
|
||||
* @param data_in_size Size of data to be decompressed
|
||||
* @param data_out_size Pointer to a variable where output size will be written. If not 0, it will be used to set initial output buffer size.
|
||||
* @return Returns a pointer to memory holding decompressed data or NULL on failure.
|
||||
* @note It is caller's responsibility to free() the returned pointer once done with it.
|
||||
*/
|
||||
unsigned char *util_zlib_inflate(unsigned char *data, size_t data_in_size, size_t *data_out_size)
|
||||
{
|
||||
int ret = Z_OK;
|
||||
uLongf out_size = *data_out_size;
|
||||
if (out_size == 0)
|
||||
{
|
||||
// Try to guesstimate the size needed for output data by applying the
|
||||
// same ratio it would take to compress data_in_size.
|
||||
out_size = data_in_size * data_in_size / compressBound(data_in_size);
|
||||
out_size = min(MAX_ZLIB_REALLOC, out_size);
|
||||
}
|
||||
size_t buffer_size = out_size;
|
||||
unsigned char *buffer = malloc(buffer_size);
|
||||
do {
|
||||
if (ret == Z_BUF_ERROR)
|
||||
{
|
||||
buffer_size *= 2;
|
||||
out_size = buffer_size;
|
||||
buffer = realloc(buffer, buffer_size);
|
||||
}
|
||||
ret = uncompress(buffer, &out_size, data, data_in_size);
|
||||
} while (ret != Z_OK);
|
||||
buffer = realloc(buffer, out_size);
|
||||
*data_out_size = out_size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deflates input using zlib
|
||||
* @param data Data to be compressed
|
||||
* @param data_in_size Size of data to be compressed
|
||||
* @param data_out_size Pointer to a variable where output size will be written
|
||||
* @return Returns a pointer to memory holding compressed data or NULL on failure.
|
||||
* @note It is caller's responsibility to free() the returned pointer once done with it.
|
||||
*/
|
||||
unsigned char *util_zlib_deflate(unsigned char *data, size_t data_in_size, size_t *data_out_size)
|
||||
{
|
||||
int ret = Z_OK;
|
||||
uLongf out_size = *data_out_size;
|
||||
size_t buffer_size = compressBound(data_in_size);
|
||||
unsigned char *buffer = malloc(buffer_size);
|
||||
do {
|
||||
if (ret == Z_BUF_ERROR)
|
||||
{
|
||||
buffer_size *= 2;
|
||||
out_size = buffer_size;
|
||||
buffer = realloc(buffer, buffer_size);
|
||||
}
|
||||
ret = compress(buffer, &out_size, data, data_in_size);
|
||||
} while (ret != Z_OK);
|
||||
*data_out_size = out_size;
|
||||
buffer = realloc(buffer, *data_out_size);
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "../common.h"
|
||||
|
||||
extern bool gUseRLE;
|
||||
|
||||
int squaredmetres_to_squaredfeet(int squaredMetres);
|
||||
int metres_to_feet(int metres);
|
||||
int mph_to_kmph(int mph);
|
||||
|
@ -52,4 +54,7 @@ bool str_is_null_or_empty(const char *str);
|
|||
void util_srand(int source);
|
||||
uint32 util_rand();
|
||||
|
||||
unsigned char *util_zlib_deflate(unsigned char *data, size_t data_in_size, size_t *data_out_size);
|
||||
unsigned char *util_zlib_inflate(unsigned char *data, size_t data_in_size, size_t *data_out_size);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue