Functionality to serialize a BlockChunk into a compressed string & back
parent
5de395f793
commit
3fc3d84bb4
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
//
|
||||
|
||||
#include "Server.h"
|
||||
#include "../generic/blocks/BlockChunk.h"
|
||||
|
||||
Server::Server() = default;
|
||||
|
||||
|
|
Loading…
Reference in New Issue