New MapGen class for server-client map synchronization.

master
aurailus 2019-01-29 16:41:59 -08:00
parent 3fc3d84bb4
commit a89efe9dcb
18 changed files with 216 additions and 120 deletions

View File

@ -57,8 +57,8 @@ add_executable(zeus
zeus/generic/helpers/ArrayTrans3D.h zeus/generic/helpers/ArrayTrans3D.h
zeus/client/graphics/mesh/MeshChunk.cpp zeus/client/graphics/mesh/MeshChunk.cpp
zeus/client/graphics/mesh/MeshChunk.h zeus/client/graphics/mesh/MeshChunk.h
zeus/client/graphics/scene/GameScene.cpp zeus/client/scene/GameScene.cpp
zeus/client/graphics/scene/GameScene.h zeus/client/scene/GameScene.h
zeus/client/engine/graphics/Renderer.cpp zeus/client/engine/graphics/Renderer.cpp
zeus/client/engine/graphics/Renderer.h zeus/client/engine/graphics/Renderer.h
zeus/client/lua/LuaParser.cpp zeus/client/lua/LuaParser.cpp
@ -86,8 +86,8 @@ add_executable(zeus
zeus/client/engine/scene/SceneManager.h zeus/client/engine/scene/SceneManager.h
zeus/client/engine/scene/Scene.h zeus/client/engine/scene/Scene.h
zeus/client/ClientState.h zeus/client/ClientState.h
zeus/client/graphics/scene/MenuScene.cpp zeus/client/scene/MenuScene.cpp
zeus/client/graphics/scene/MenuScene.h zeus/client/scene/MenuScene.h
zeus/server/Server.cpp zeus/server/Server.cpp
zeus/server/Server.h zeus/server/Server.h
zeus/server/network/ServerClient.cpp zeus/server/network/ServerClient.cpp
@ -101,6 +101,6 @@ add_executable(zeus
zeus/client/gameworld/WorldThreadDefs.cpp zeus/client/gameworld/WorldThreadDefs.cpp
zeus/client/gameworld/WorldThreadDefs.h zeus/client/gameworld/WorldThreadDefs.h
zeus/server/network/ConnMan.cpp zeus/server/network/ConnMan.cpp
zeus/server/network/ConnMan.h) zeus/server/network/ConnMan.h zeus/generic/gen/MapGen.cpp zeus/generic/gen/MapGen.h)
target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl z) target_link_libraries(zeus ${OPENGL_gl_LIBRARY} glfw libGLEW.so pthread lua dl z)

View File

@ -9,8 +9,8 @@
#include "ClientState.h" #include "ClientState.h"
#include "engine/scene/SceneManager.h" #include "engine/scene/SceneManager.h"
#include "graphics/scene/GameScene.h" #include "scene/GameScene.h"
#include "graphics/scene/MenuScene.h" #include "scene/MenuScene.h"
#include "engine/Timer.h" #include "engine/Timer.h"

View File

@ -9,9 +9,10 @@
World::World(BlockAtlas *atlas) { World::World(BlockAtlas *atlas) {
blockAtlas = atlas; blockAtlas = atlas;
mapGen = new MapGen(0);
for (int i = 0; i < GEN_THREADS; i++) { for (int i = 0; i < GEN_THREADS; i++) {
genThreads.push_back(new ChunkThreadDef()); genThreads.push_back(new ChunkThreadDef(mapGen));
} }
for (int i = 0; i < MESH_THREADS; i++) { for (int i = 0; i < MESH_THREADS; i++) {
@ -25,9 +26,22 @@ void World::genNewChunk(glm::vec3 pos) {
} }
} }
void World::loadChunkPacket(Packet *p) {
auto b = new BlockChunk();
int len = Packet::decodeInt(&p->data[12]);
std::string data(p->data.begin() + 16, p->data.begin() + 16 + len);
b->deserialize(data);
commitChunk(glm::vec3(0, 0, 0), b);
}
void World::commitChunk(glm::vec3 pos, BlockChunk *c) { void World::commitChunk(glm::vec3 pos, BlockChunk *c) {
blockChunks.insert(std::pair<glm::vec3, BlockChunk*>(pos, c)); if (!blockChunks.count(pos)) {
attemptMeshChunk(pos); blockChunks.insert(std::pair<glm::vec3, BlockChunk *>(pos, c));
attemptMeshChunk(pos);
}
} }
void World::remeshChunk(glm::vec3 pos) { void World::remeshChunk(glm::vec3 pos) {
@ -183,7 +197,9 @@ void World::handleChunkGenQueue() {
Timer t("Chunk Initialization"); Timer t("Chunk Initialization");
int genUpdates = 0; int genUpdates = 0;
for (auto iter = finishedGen.begin(); iter != finishedGen.end(); ) { for (auto iter = finishedGen.begin(); iter != finishedGen.end(); ) {
if (t.elapsedNs() > 4000000) break; if (t.elapsedNs() > 4000000) {
break;
}
ChunkThreadData* threadData = *iter; ChunkThreadData* threadData = *iter;
@ -201,9 +217,6 @@ void World::handleChunkGenQueue() {
//Takes a threadDef object which contains a vector of tasks to do, and infinitely loops, completing tasks and //Takes a threadDef object which contains a vector of tasks to do, and infinitely loops, completing tasks and
//re-inserting them into the vector to be further manipulated by the main thread. //re-inserting them into the vector to be further manipulated by the main thread.
void World::chunkGenThread(ChunkThreadDef* threadDef) { void World::chunkGenThread(ChunkThreadDef* threadDef) {
PerlinNoise p(9);
PerlinNoise p2(9);
//Infinite loop //Infinite loop
while (true) { while (true) {
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock); std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
@ -223,43 +236,7 @@ void World::chunkGenThread(ChunkThreadDef* threadDef) {
lock.unlock(); lock.unlock();
if (data != nullptr) { if (data != nullptr) {
auto *blocks = new std::vector<int>(); data->chunk = threadDef->mapGen->generate(data->pos);
blocks->reserve(4096);
glm::vec3 innerPos, pos;
for (int ind = 0; ind < 4096; ind++) {
ArrayTrans3D::indAssignVec(ind, &innerPos);
pos.x = innerPos.x + data->pos.x * CHUNK_SIZE;
pos.y = innerPos.y + data->pos.y * CHUNK_SIZE;
pos.z = innerPos.z + data->pos.z * CHUNK_SIZE;
double val = p.noise(pos.x / (double) 32, pos.z / (double) 32, 0) * 16;
val *= p2.noise((pos.x + 16) / (double) 48, (pos.z + 16) / (double) 48, 0) * 8;
val /= 16;
val *= pow(p.noise(pos.x / (double) 64, pos.z / (double) 64, 0), 2) * 40 + 1;
val -= pos.y;
int block = 0;
if (val > 0) block = 6 + rand() % 4;
if (val > 1) block = 1;
if (val > 2) block = 2;
if (val > 3) block = 3;
blocks->push_back(block);
}
// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 8)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 8)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(7, 8, 7)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(8, 8, 7)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 8)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 8)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(7, 7, 7)] = 4;
// (*blocks)[ArrayTrans3D::vecToInd(8, 7, 7)] = 4;
data->chunk = new BlockChunk(blocks);
data->done = true; data->done = true;
lock.lock(); lock.lock();
@ -331,7 +308,6 @@ void World::handleMeshGenQueue() {
//Function that runs on each MeshGenThread in the mesh generation threadpool. //Function that runs on each MeshGenThread in the mesh generation threadpool.
//Processes tasks and returns meshes in the same vector to be handled by the main thread. //Processes tasks and returns meshes in the same vector to be handled by the main thread.
void World::meshGenThread(MeshThreadDef* threadDef) { void World::meshGenThread(MeshThreadDef* threadDef) {
//Infinite loop //Infinite loop
while (true) { while (true) {
std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock); std::unique_lock<std::mutex> lock(threadDef->lock, std::defer_lock);
@ -365,4 +341,4 @@ void World::meshGenThread(MeshThreadDef* threadDef) {
std::unordered_map<glm::vec3, MeshChunk*, World::vec3cmp>* World::getMeshChunks() { std::unordered_map<glm::vec3, MeshChunk*, World::vec3cmp>* World::getMeshChunks() {
return &meshChunks; return &meshChunks;
} }

View File

@ -18,6 +18,7 @@
#include "../../generic/helpers/ArrayTrans3D.h" #include "../../generic/helpers/ArrayTrans3D.h"
#include "../../generic/blocks/BlockAtlas.h" #include "../../generic/blocks/BlockAtlas.h"
#include "../../generic/blocks/BlockChunk.h" #include "../../generic/blocks/BlockChunk.h"
#include "../../generic/gen/MapGen.h"
#include "../graphics/mesh/MeshChunk.h" #include "../graphics/mesh/MeshChunk.h"
class World { class World {
@ -39,6 +40,8 @@ public:
void commitChunk(glm::vec3 pos, BlockChunk *c); void commitChunk(glm::vec3 pos, BlockChunk *c);
void remeshChunk(glm::vec3 pos); void remeshChunk(glm::vec3 pos);
void loadChunkPacket(Packet* p);
void attemptMeshChunk(glm::vec3 pos); void attemptMeshChunk(glm::vec3 pos);
//This function also updates the chunk that is being checked's adjacent data, so maybe a rename is in order. //This function also updates the chunk that is being checked's adjacent data, so maybe a rename is in order.
bool getAdjacentExists(glm::vec3 pos, glm::vec3 myPos); bool getAdjacentExists(glm::vec3 pos, glm::vec3 myPos);
@ -94,7 +97,7 @@ private:
void handleMeshGenQueue(); void handleMeshGenQueue();
const int GEN_THREADS = 8; const int GEN_THREADS = 8;
const int GEN_QUEUE_SIZE = 4; const int GEN_QUEUE_SIZE = 8;
const int GEN_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE; const int GEN_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE;
std::unordered_set<glm::vec3, vec3cmp> pendingGen; std::unordered_set<glm::vec3, vec3cmp> pendingGen;
@ -102,7 +105,7 @@ private:
std::vector<ChunkThreadData*> finishedGen; std::vector<ChunkThreadData*> finishedGen;
const int MESH_THREADS = 4; const int MESH_THREADS = 4;
const int MESH_QUEUE_SIZE = 32; const int MESH_QUEUE_SIZE = 64;
const int MESH_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE; const int MESH_FINISHED_SIZE = GEN_THREADS * GEN_QUEUE_SIZE;
std::unordered_set<glm::vec3, vec3cmp> pendingMesh; std::unordered_set<glm::vec3, vec3cmp> pendingMesh;
@ -110,6 +113,7 @@ private:
std::vector<MeshThreadData*> finishedMesh; std::vector<MeshThreadData*> finishedMesh;
BlockAtlas* blockAtlas; BlockAtlas* blockAtlas;
MapGen* mapGen;
}; };
#endif //GLPROJECT_WORLD_H #endif //GLPROJECT_WORLD_H

View File

@ -12,7 +12,9 @@ ChunkThreadData::ChunkThreadData(glm::vec3 pos, BlockAtlas *atlas) {
this->chunk = nullptr; this->chunk = nullptr;
} }
ChunkThreadDef::ChunkThreadDef() { ChunkThreadDef::ChunkThreadDef(MapGen *mapGen) {
this->mapGen = mapGen;
thread = new std::thread(World::chunkGenThread, this); thread = new std::thread(World::chunkGenThread, this);
sched_param sch_params{}; sched_param sch_params{};

View File

@ -11,6 +11,7 @@
#include "../../generic/blocks/BlockChunk.h" #include "../../generic/blocks/BlockChunk.h"
#include "../../generic/blocks/BlockAtlas.h" #include "../../generic/blocks/BlockAtlas.h"
#include "../../generic/gen/MapGen.h"
//Structs for storing the threads used in World, and passing data to and from them. //Structs for storing the threads used in World, and passing data to and from them.
@ -51,12 +52,14 @@ struct ChunkThreadData {
}; };
struct ChunkThreadDef { struct ChunkThreadDef {
ChunkThreadDef(); explicit ChunkThreadDef(MapGen *mapGen);
std::thread* thread; std::thread* thread;
std::mutex lock; std::mutex lock;
std::vector<ChunkThreadData*> tasks; std::vector<ChunkThreadData*> tasks;
MapGen* mapGen;
~ChunkThreadDef(); ~ChunkThreadDef();
}; };

View File

@ -6,7 +6,7 @@
#define ZEUS_LUAAPI_H #define ZEUS_LUAAPI_H
#include "LuaParser.h" #include "LuaParser.h"
#include "../graphics/scene/GameScene.h" #include "../scene/GameScene.h"
class LuaApi { class LuaApi {
public: public:

View File

@ -67,6 +67,9 @@ ServerConfig* ServerConnection::connect() {
.playerPos = glm::vec3(x, y, z) .playerPos = glm::vec3(x, y, z)
}; };
} }
else {
inPackets.push_back(packet);
}
} }
} }
if (!connected) { if (!connected) {
@ -80,48 +83,50 @@ ServerConfig* ServerConnection::connect() {
} }
void ServerConnection::update() { void ServerConnection::update() {
Timer t("Loop time");
//Collect incoming packets //Collect incoming packets
while (socket.available() > 0) { while (socket.available() > 0) {
size_t pendingSize = socket.available(); size_t pendingSize = socket.available();
std::vector<Packet::PacketByte> recv_buf((unsigned long)pendingSize); std::vector<Packet::PacketByte> recv_buf((unsigned long) pendingSize);
auto remote_endpoint = new asio::ip::udp::endpoint(); auto remote_endpoint = new asio::ip::udp::endpoint();
socket.receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint); socket.receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint);
auto packet = Packet::deserialize(recv_buf); auto packet = Packet::deserialize(recv_buf);
if (packet->length > 0) handlePacket(*packet, remote_endpoint); if (packet->length > 0) inPackets.push_back(packet);
} }
long sleep_for = 16L*1000000L - t.elapsedNs(); // handleInPackets();
std::this_thread::sleep_for(std::chrono::nanoseconds(sleep_for));
} }
void ServerConnection::handlePacket(Packet &packet, asio::ip::udp::endpoint* endpoint) { bool ServerConnection::hasInPacket() {
return !inPackets.empty();
} }
Packet *ServerConnection::getPacket() {
auto it = inPackets.begin();
inPackets.erase(it);
return *it;
}
//void ServerConnection::handleInPackets() {
// while (!inPackets.empty()) {
// auto it = inPackets.begin();
// inPackets.erase(it);
// Packet* packet = *it;
//
// handlePacket(packet);
//
// delete packet;
// }
//}
//
//void ServerConnection::handlePacket(Packet* packet) {
// std::cout << packet->type << std::endl;
//}
void ServerConnection::sendPacket(Packet &p, asio::ip::udp::endpoint &e) { void ServerConnection::sendPacket(Packet &p, asio::ip::udp::endpoint &e) {
auto data = p.serialize(); auto data = p.serialize();
socket.send_to(asio::buffer(data, data.size()), e); socket.send_to(asio::buffer(data, data.size()), e);
} }
void ServerConnection::reqChunks(glm::vec3 a, glm::vec3 b) {
Packet p(Packet::REQCHUNKS);
for (int i = (int)a.x; i < (int)b.x; i++) {
for (int j = (int)a.y; j < (int)b.y; j++) {
for (int k = (int)a.z; k < (int)b.z; k++) {
p.addInt(i);
p.addInt(j);
p.addInt(k);
}
}
}
sendPacket(p, remote_endpoint);
}
ServerConnection::~ServerConnection() = default; ServerConnection::~ServerConnection() = default;

View File

@ -25,13 +25,17 @@ public:
void sendPacket(Packet& p, asio::ip::udp::endpoint& e); void sendPacket(Packet& p, asio::ip::udp::endpoint& e);
void update(); void update();
void handlePacket(Packet &packet, asio::ip::udp::endpoint* endpoint); // void handleInPackets();
void reqChunks(glm::vec3 a, glm::vec3 b); // void handlePacket(Packet* packet);
bool hasInPacket();
Packet* getPacket();
~ServerConnection(); ~ServerConnection();
private: private:
bool connected; bool connected;
std::vector<Packet*> inPackets;
asio::io_context io_context; asio::io_context io_context;
asio::ip::udp::socket socket; asio::ip::udp::socket socket;

View File

@ -5,8 +5,8 @@
#include "GameScene.h" #include "GameScene.h"
//TODO: Fix this //TODO: Fix this
#include "../../lua/l_register_block.h" #include "../lua/l_register_block.h"
#include "../../lua/l_register_blockmodel.h" #include "../lua/l_register_blockmodel.h"
GameScene::GameScene(ClientState* state) : Scene(state) { GameScene::GameScene(ClientState* state) : Scene(state) {
server = new ServerConnection("127.0.0.1", 12345); server = new ServerConnection("127.0.0.1", 12345);
@ -29,7 +29,7 @@ GameScene::GameScene(ClientState* state) : Scene(state) {
int SIZE = 12; int SIZE = 12;
for (int i = -SIZE; i < SIZE; i++) { for (int i = -SIZE; i < SIZE; i++) {
for (int j = -1; j < 12; j++) { for (int j = -12; j < 12; j++) {
for (int k = -SIZE; k < SIZE; k++) { for (int k = -SIZE; k < SIZE; k++) {
world->genNewChunk(glm::vec3(i, j, k)); world->genNewChunk(glm::vec3(i, j, k));
} }
@ -73,12 +73,19 @@ GameScene::GameScene(ClientState* state) : Scene(state) {
crosshair->setScale(22); crosshair->setScale(22);
guiEntities.push_back(crosshair); guiEntities.push_back(crosshair);
server->reqChunks(glm::vec3(-4, -4, -4), glm::vec3(4, 4, 4));
} }
void GameScene::update() { void GameScene::update() {
server->update();
while (server->hasInPacket()) {
auto packet = server->getPacket();
if (packet->type == Packet::CHUNKINFO) world->loadChunkPacket(packet);
delete packet;
}
auto window = state->renderer->getWindow(); auto window = state->renderer->getWindow();
player->update(window->getKeysArray(), state->deltaTime, window->getDeltaX(), window->getDeltaY()); player->update(window->getKeysArray(), state->deltaTime, window->getDeltaX(), window->getDeltaY());

View File

@ -6,19 +6,19 @@
#define SRC_GAMEWORLD_H #define SRC_GAMEWORLD_H
#include "../../engine/scene/Scene.h" #include "../engine/scene/Scene.h"
#include "../../engine/graphics/Renderer.h" #include "../engine/graphics/Renderer.h"
#include "../gui/DebugGui.h" #include "../graphics/gui/DebugGui.h"
#include "../../lua/LuaParser.h" #include "../lua/LuaParser.h"
#include "../../gameworld/World.h" #include "../gameworld/World.h"
#include "../../gameworld/Player.h" #include "../gameworld/Player.h"
#include "../../network/ServerConnection.h" #include "../network/ServerConnection.h"
#include "../../../generic/blocks/TextureAtlas.h" #include "../../generic/blocks/TextureAtlas.h"
#include "../../../generic/blocks/BlockAtlas.h" #include "../../generic/blocks/BlockAtlas.h"
class GameScene : public Scene { class GameScene : public Scene {
public: public:

View File

@ -6,9 +6,9 @@
#define ZEUS_MENUSCENE_H #define ZEUS_MENUSCENE_H
#include "../../ClientState.h" #include "../ClientState.h"
#include "../../engine/scene/Scene.h" #include "../engine/scene/Scene.h"
#include "../../engine/graphics/HudText.h" #include "../engine/graphics/HudText.h"
class MenuScene : public Scene { class MenuScene : public Scene {
public: public:

View File

@ -0,0 +1,45 @@
//
// Created by aurailus on 28/01/19.
//
#include "MapGen.h"
void MapGen::init(unsigned int seed) {
}
BlockChunk* MapGen::generate(glm::vec3 pos) {
MapGenJob j(pos);
getElevation(j);
getBiome(j);
fillBlocks(j);
return new BlockChunk(j.blocks);
}
void MapGen::getElevation(MapGen::MapGenJob &j) {
glm::vec3* localPos;
glm::vec3 globalPos;
for (int i = 0; i < 4096; i++) {
localPos = ArrayTrans3D::indToVec(i);
globalPos = glm::vec3(j.pos.x * 16 + localPos->x, j.pos.y * 16 + localPos->y, j.pos.z * 16 + localPos->z);
int val = (int)floor(p.noise(globalPos.x / 16, 0, globalPos.z / 16) * 32) - (int)globalPos.y;
j.elevation[i] = val;
}
}
void MapGen::getBiome(MapGen::MapGenJob &j) {
//TODO: Biome Voronoi calculation
}
void MapGen::fillBlocks(MapGen::MapGenJob &j) {
glm::vec3* localPos;
glm::vec3 globalPos;
for (int i = 0; i < 4096; i++) {
int ev = j.elevation[i];
(*(j.blocks))[i] = ev < 0 ? 0 : ev < 1 ? 1 : ev < 2 ? 2 : 3;
}
}

47
zeus/generic/gen/MapGen.h Normal file
View File

@ -0,0 +1,47 @@
//
// Created by aurailus on 28/01/19.
//
#ifndef ZEUS_MAPGEN_H
#define ZEUS_MAPGEN_H
#include <vec3.hpp>
#include <vector>
#include "../blocks/BlockChunk.h"
#include "../helpers/PerlinNoise.h"
class MapGen {
public:
MapGen() : p(1) { init(1); }
explicit MapGen(unsigned int seed) : p(seed) { init(seed); }
BlockChunk* generate(glm::vec3 pos);
private:
struct MapGenJob {
std::vector<int>
elevation,
biome,
*blocks;
glm::vec3 pos;
explicit MapGenJob(glm::vec3 pos) {
this->pos = pos;
elevation.reserve(4096);
biome.reserve(4096);
blocks = new std::vector<int>(4096);
}
};
void getElevation(MapGenJob& j);
void getBiome(MapGenJob& j);
void fillBlocks(MapGenJob& j);
void init(unsigned int seed);
PerlinNoise p;
};
#endif //ZEUS_MAPGEN_H

View File

@ -15,12 +15,7 @@ Packet* Packet::deserialize(std::vector<PacketByte> data) {
//Seperate the packet header from the body, //Seperate the packet header from the body,
//This can be changed to support more header values in the future. //This can be changed to support more header values in the future.
//Determine Packet Type int num = decodeInt(&data[0]);
int num = 0;
for (int i = 0; i < 4; i++) {
num <<= 8;
num |= data[i];
}
//Get body of the packet //Get body of the packet
std::vector<PacketByte> dataBody; std::vector<PacketByte> dataBody;

View File

@ -46,7 +46,7 @@ public:
const static PacketType HANDSHAKE = 1; const static PacketType HANDSHAKE = 1;
const static PacketType AUTHENTICATE = 2; const static PacketType AUTHENTICATE = 2;
const static PacketType PLAYERINFO = 3; const static PacketType PLAYERINFO = 3;
const static PacketType REQCHUNKS = 4; const static PacketType CHUNKINFO = 4;
}; };

View File

@ -3,6 +3,7 @@
// //
#include "ConnMan.h" #include "ConnMan.h"
#include "../../generic/blocks/BlockChunk.h"
ConnMan::ConnMan() = default; ConnMan::ConnMan() = default;
@ -58,18 +59,7 @@ void ConnMan::handlePacket(Packet* packet, udp::endpoint* endpoint) {
} }
else { else {
//TODO: Push to the packet vector //TODO: Push to the packet vector
// if (packet->type == Packet::REQCHUNKS) {
// for (int i = 0; i < packet->length / 12; i++) {
// int offsetBase = i * 12;
// int x = Packet::decodeInt(&packet->data[0 + offsetBase]);
// int y = Packet::decodeInt(&packet->data[0 + offsetBase + 4]);
// int z = Packet::decodeInt(&packet->data[0 + offsetBase + 8]);
// printf("%i, %i, %i\n", x, y, z);
// }
// std::cout << packet->length << std::endl;
// }
} }
} }
ServerClient* ConnMan::addClient(std::string uuid, udp::endpoint* endpoint) { ServerClient* ConnMan::addClient(std::string uuid, udp::endpoint* endpoint) {
@ -94,6 +84,24 @@ void ConnMan::addPlayer(ServerClient* client, std::string username) {
p.addFloat(player->pos.z); p.addFloat(player->pos.z);
send(&p, client); send(&p, client);
p = Packet(Packet::CHUNKINFO);
p.addInt(0);
p.addInt(0);
p.addInt(0);
auto blocks = new std::vector<int>();
for (int i = 0; i < 4096; i++) {
blocks->push_back(i < 2048 ? 0 : 1);
}
auto originalChunk = new BlockChunk(blocks);
auto gzip = originalChunk->serialize();
p.addString(gzip);
send(&p, client);
} }
//Create a IP + Port combo that can be used as a UUID for an endpoint. //Create a IP + Port combo that can be used as a UUID for an endpoint.