Functionality to serialize a BlockChunk into a compressed string & back

master
aurailus 2019-01-27 14:13:40 -08:00
parent 5de395f793
commit 3fc3d84bb4
6 changed files with 105 additions and 2 deletions

View File

@ -10,6 +10,7 @@ include_directories(lib/stb_image)
include_directories(lib/cute)
include_directories(lib/sol)
include_directories(lib/asio-1.12.2/include)
include_directories(lib/gzip-hpp-master/include)
find_package(OpenGL REQUIRED)
find_package(glfw3 REQUIRED)
@ -102,4 +103,4 @@ add_executable(zeus
zeus/server/network/ConnMan.cpp
zeus/server/network/ConnMan.h)
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl)
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl z)

View File

@ -4,6 +4,14 @@
#include "BlockChunk.h"
#include <gzip/compress.hpp>
#include <gzip/decompress.hpp>
#include <gzip/utils.hpp>
BlockChunk::BlockChunk() {
this->blocks = new std::vector<int>();
}
BlockChunk::BlockChunk(std::vector<int>* blocks) {
this->blocks = blocks;
}
@ -38,3 +46,63 @@ bool BlockChunk::setBlock(glm::vec3* pos, int block) {
bool BlockChunk::allAdjacentsExist() {
return adjacent[0] && adjacent[1] && adjacent[2] && adjacent[3] && adjacent[4] && adjacent[5];
}
std::vector<int>* BlockChunk::rleEncode() {
auto rle = new std::vector<int>();
int block = (*blocks)[0];
int length = 1;
for (int i = 1; i < 4096; i++) {
if ((*blocks)[i] == block) {
length++;
}
else {
rle->push_back(block);
rle->push_back(length);
length = 1;
block = (*blocks)[i];
}
}
rle->push_back(block);
rle->push_back(length);
return rle;
}
void BlockChunk::rleDecode(std::vector<int> *blocksRle) {
auto blocks = new std::vector<int>();
blocks->reserve(4096);
for (int i = 0; i < blocksRle->size() / 2; i++) {
int block = (*blocksRle)[i*2];
int count = (*blocksRle)[i*2 + 1];
for (int j = 0; j < count; j++) {
blocks->push_back(block);
if (blocks->size() >= 4096) goto exitloop;
}
}
exitloop:
delete this->blocks;
this->blocks = blocks;
}
std::string BlockChunk::serialize() {
auto rle = rleEncode();
std::string str = Packet::intVecToString(rle);
delete rle;
return gzip::compress(str.data(), str.size());
}
void BlockChunk::deserialize(std::string gzip) {
if (gzip::is_compressed(gzip.data(), gzip.length())) {
auto str = gzip::decompress(gzip.data(), gzip.length());
auto rle = Packet::stringToIntVec(str);
rleDecode(rle);
}
}

View File

@ -9,10 +9,11 @@
#include <vector>
#include <iostream>
#include "../helpers/ArrayTrans3D.h"
#include "../network/Packet.h"
class BlockChunk {
public:
BlockChunk() = default;
BlockChunk();
explicit BlockChunk(std::vector<int>* blocks);
bool adjacent[6] = {false, false, false, false, false, false};
@ -23,6 +24,12 @@ public:
int getBlock(int x, int y, int z);
bool setBlock(glm::vec3* pos, int ind);
std::vector<int>* rleEncode();
void rleDecode(std::vector<int>* blocksRle);
std::string serialize();
void deserialize(std::string gzip);
private:
std::vector<int>* blocks;
};

View File

@ -98,6 +98,29 @@ int Packet::decodeInt(PacketByte* intStart) {
return num;
}
std::string Packet::intVecToString(std::vector<int> *vec) {
return std::string(reinterpret_cast<const char*>(&(*vec)[0]), vec->size()*4);
}
std::vector<int> *Packet::stringToIntVec(std::string str) {
auto vec = new std::vector<int>(str.size() / 4);
for (int i = 0; i < str.size() / 4; i++) {
int val = ((int)(((unsigned char)str[i*4 + 3]) << 24)
| (int)(((unsigned char)str[i*4 + 2]) << 16)
| (int)(((unsigned char)str[i*4 + 1]) << 8)
| (int)( (unsigned char)str[i*4 + 0]));
(*vec)[i] = val;
}
return vec;
}
void Packet::addIntegers(std::vector<int> &integers) {
for (int i : integers) {
encodeInt(this->data, i);

View File

@ -38,6 +38,9 @@ public:
static int decodeInt(PacketByte* intStart);
static void encodeFloat(std::vector<PacketByte> &target, float num);
static float decodeFloat(PacketByte* floatStart);
static std::string intVecToString(std::vector<int>* vec);
static std::vector<int>* stringToIntVec(std::string str);
public:
const static PacketType UNDEFINED = 0;
const static PacketType HANDSHAKE = 1;

View File

@ -3,6 +3,7 @@
//
#include "Server.h"
#include "../generic/blocks/BlockChunk.h"
Server::Server() = default;