From eb15f8d70197c47e97ef99a693106236c21b741e Mon Sep 17 00:00:00 2001 From: SoftCoder Date: Thu, 31 Dec 2015 13:12:26 -0800 Subject: [PATCH] - add compressed network messages for nmtLaunch and nmtBroadCastSetup (not backward compatible) --- source/glest_game/network/network_message.cpp | 84 ++++++++++++++++++- source/glest_game/network/network_message.h | 10 ++- .../include/compression/compression_utils.h | 2 + .../sources/compression/compression_utils.cpp | 35 ++++++++ 4 files changed, 124 insertions(+), 7 deletions(-) diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 032338f56..28b6b89f3 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -18,6 +18,7 @@ #include "platform_util.h" #include "config.h" #include "network_protocol.h" +#include "compression_utils.h" #include #include #include @@ -682,7 +683,8 @@ void NetworkMessageReady::fromEndian() { // ===================================================== NetworkMessageLaunch::NetworkMessageLaunch() { - messageType=-1; + messageType = -1; + compressedLength = 0; for(unsigned int i = 0; i < (unsigned int)maxFactionCRCCount; ++i) { data.factionNameList[i] = ""; data.factionCRCList[i] = 0; @@ -695,6 +697,7 @@ NetworkMessageLaunch::NetworkMessageLaunch() { NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType) { this->messageType = messageType; + compressedLength = 0; data.mapCRC = gameSettings->getMapCRC(); data.tilesetCRC = gameSettings->getTilesetCRC(); @@ -1342,7 +1345,46 @@ bool NetworkMessageLaunch::receive(Socket* socket) { //printf("Receive NetworkMessageLaunch\n"); bool result = false; if(useOldProtocol == true) { - result = NetworkMessage::receive(socket, &data, sizeof(data), true); + //printf("UnCompressed launch packet before read compressed size\n"); + result = NetworkMessage::receive(socket, &compressedLength, sizeof(compressedLength), true); + //printf("UnCompressed launch packet after read compressed size: %d\n",compressedLength); + + if(result == true && compressedLength > 0) { + //printf("UnCompressed launch packet before: %u after: %d\n",compressedLength,(int)getDataSize()); + + unsigned char *compressedMessage = new unsigned char[compressedLength+1]; + memset(compressedMessage,0,compressedLength+1); + + result = NetworkMessage::receive(socket, compressedMessage, compressedLength, true); + //printf("UnCompressed launch packet READ returned: %d\n",result); + + if(result == true) { + //printf("UnCompressed launch packet before decompress\n"); + +// printf("\n"); +// const unsigned char *buf = static_cast(compressedMessage); +// for(unsigned int index = 0; index < (unsigned int)compressedLength; ++index) { +// printf("%u[%X][%d] ",index,buf[index],buf[index]); +// if(index % 10 == 0) { +// printf("\n"); +// } +// } +// printf("\n"); + + unsigned long buffer_size = compressedLength; + std::pair decompressedBuffer = + Shared::CompressionUtil::extractMemoryToMemory(compressedMessage, buffer_size, maxNetworkMessageSize); + unsigned char *decompressed_buffer = decompressedBuffer.first; + memcpy(&data,decompressed_buffer,decompressedBuffer.second); + delete [] decompressed_buffer; + + //printf("SUCCESS UnCompressed launch packet before: %u after: %lu\n",compressedLength,decompressedBuffer.second); + } + } + else if(result == true) { + //printf("Normal launch packet detected (uncompressed)\n"); + result = NetworkMessage::receive(socket, &data, sizeof(data), true); + } } else { unsigned char *buf = new unsigned char[getPackedSize()+1]; @@ -1380,6 +1422,20 @@ bool NetworkMessageLaunch::receive(Socket* socket) { return result; } +unsigned char * NetworkMessageLaunch::getData() { + unsigned char *buffer = new unsigned char[getDataSize()]; + memcpy(buffer,&data,getDataSize()); + return buffer; +} + +std::pair NetworkMessageLaunch::getCompressedMessage() { + unsigned char *buffer = this->getData(); + std::pair result = + Shared::CompressionUtil::compressMemoryToMemory(buffer,getDataSize()); + delete [] buffer; + return result; +} + void NetworkMessageLaunch::send(Socket* socket) { //printf("Sending NetworkMessageLaunch\n"); @@ -1396,8 +1452,28 @@ void NetworkMessageLaunch::send(Socket* socket) { toEndian(); if(useOldProtocol == true) { - //NetworkMessage::send(socket, &messageType, sizeof(messageType)); - NetworkMessage::send(socket, &data, sizeof(data), messageType); + ////NetworkMessage::send(socket, &messageType, sizeof(messageType)); + //NetworkMessage::send(socket, &data, sizeof(data), messageType); + + std::pair compressionResult = getCompressedMessage(); + compressedLength = compressionResult.second; + //printf("Compressed launch packet before: %d after: %lu\n",(int)getDataSize(),compressionResult.second); + +// printf("\n"); +// const unsigned char *buf = static_cast(compressionResult.first); +// for(unsigned int index = 0; index < (unsigned int)compressionResult.second; ++index) { +// printf("%u[%X][%d] ",index,buf[index],buf[index]); +// if(index % 10 == 0) { +// printf("\n"); +// } +// } +// printf("\n"); + + NetworkMessage::send(socket, &messageType, sizeof(messageType)); + NetworkMessage::send(socket, &compressedLength, sizeof(compressedLength)); + NetworkMessage::send(socket, compressionResult.first, compressionResult.second); + delete [] compressionResult.first; + //printf("Compressed launch packet SENT\n"); } else { unsigned char *buf = packMessage(); diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 442ce7d83..e63de80ba 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -49,6 +49,7 @@ enum NetworkMessageType { nmtMarkCell, nmtUnMarkCell, nmtHighlightCell, +// nmtCompressedPacket, nmtCount }; @@ -62,6 +63,7 @@ enum NetworkGameStateType { }; static const int maxLanguageStringSize= 60; +static const int maxNetworkMessageSize= 20000; // ===================================================== // class NetworkMessage @@ -113,6 +115,7 @@ public: virtual void send(Socket* socket) = 0; virtual size_t getDataSize() const = 0; + virtual unsigned char * getData() { return NULL; } virtual NetworkMessageType getNetworkMessageType() const = 0; @@ -313,7 +316,8 @@ private: private: int8 messageType; - struct Data{ + uint32 compressedLength; + struct Data { NetworkString description; NetworkString map; NetworkString tileset; @@ -364,7 +368,7 @@ private: }; void toEndian(); void fromEndian(); - + std::pair getCompressedMessage(); private: Data data; @@ -379,6 +383,7 @@ public: NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType); virtual size_t getDataSize() const { return sizeof(Data); } + virtual unsigned char * getData(); virtual NetworkMessageType getNetworkMessageType() const { return nmtLaunch; @@ -1203,7 +1208,6 @@ public: }; #pragma pack(pop) - }}//end namespace #endif diff --git a/source/shared_lib/include/compression/compression_utils.h b/source/shared_lib/include/compression/compression_utils.h index aaec9a9dc..707a46a7d 100644 --- a/source/shared_lib/include/compression/compression_utils.h +++ b/source/shared_lib/include/compression/compression_utils.h @@ -20,6 +20,8 @@ namespace Shared{ namespace CompressionUtil{ bool compressFileToZIPFile(string inFile, string outFile, int compressionLevel=5); bool extractFileFromZIPFile(string inFile, string outFile); +std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel=5); +std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len); }}; diff --git a/source/shared_lib/sources/compression/compression_utils.cpp b/source/shared_lib/sources/compression/compression_utils.cpp index f65c49b7d..66fea29cf 100644 --- a/source/shared_lib/sources/compression/compression_utils.cpp +++ b/source/shared_lib/sources/compression/compression_utils.cpp @@ -324,4 +324,39 @@ bool extractFileFromZIPFile(string inFile, string outFile) { return(result == EXIT_SUCCESS ? true : false); } +std::pair compressMemoryToMemory(unsigned char *input, unsigned long input_len, int compressionLevel) { + // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) + unsigned long compressed_buffer_len = input_len + 100; + unsigned char *compressed_buffer = new unsigned char[compressed_buffer_len+1]; + memset(compressed_buffer,0,compressed_buffer_len+1); + + unsigned char *decompressed_buffer = new unsigned char[input_len+1]; + memcpy(decompressed_buffer,input,input_len); + + //printf("compress2 start size: %lu\n",input_len); + int result = compress2(compressed_buffer, &compressed_buffer_len, decompressed_buffer, input_len, compressionLevel); + //printf("compress2 returned: %d start size: %lu end size: %lu\n",result,input_len,compressed_buffer_len); + delete [] decompressed_buffer; + + return make_pair(compressed_buffer,compressed_buffer_len); +} + +std::pair extractMemoryToMemory(unsigned char *input, unsigned long input_len, unsigned long max_output_len) { + // Like compress() but with more control, level may range from 0 (storing) to 9 (max. compression) + unsigned long decompressed_buffer_len = max_output_len; + unsigned char *decompressed_buffer = new unsigned char[decompressed_buffer_len+1]; + memset(decompressed_buffer,0,decompressed_buffer_len+1); + //printf("#1uncompress start size: %lu\n",input_len); + + unsigned char *compressed_buffer = new unsigned char[input_len+1]; + memcpy(compressed_buffer,input,input_len); + + //printf("#2uncompress start size: %lu\n",input_len); + int result = uncompress(decompressed_buffer, &decompressed_buffer_len, compressed_buffer, input_len); + //printf("uncompress returned: %d start size: %lu end size: %lu\n",result,input_len,decompressed_buffer_len); + delete [] compressed_buffer; + + return make_pair(decompressed_buffer,decompressed_buffer_len); +} + }}