[Network] 'ChunkRequest' command added.

This commit is contained in:
Quentin Bazin 2019-01-18 01:59:26 +01:00
parent 9da2ad5f86
commit 104597a39d
18 changed files with 104 additions and 60 deletions

View File

@ -33,7 +33,8 @@ target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -DSOL_CHECK_ARGUMENTS
target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE cxx_std_17)
# target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -pg)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -pg)
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -pg)
#------------------------------------------------------------------------------
# Link options

View File

@ -46,7 +46,6 @@ class GameState : public gk::ApplicationState {
gk::Shader m_shader;
Skybox m_skybox;
ClientWorld m_world;
gk::Camera m_camera{FOV, DIST_NEAR, DIST_FAR};
Player m_player{m_camera};
@ -56,6 +55,8 @@ class GameState : public gk::ApplicationState {
Client &m_client;
HUD m_hud{m_player, m_world, m_client};
ClientWorld m_world{m_client};
};
#endif // GAMESTATE_HPP_

View File

@ -19,9 +19,11 @@
#include "ClientChunk.hpp"
#include "Network.hpp"
class Client;
class ClientWorld : public gk::IDrawable {
public:
ClientWorld();
ClientWorld(Client &client);
void update();
@ -37,13 +39,15 @@ class ClientWorld : public gk::IDrawable {
void draw(gk::RenderTarget &target, gk::RenderStates states) const override;
// FIXME: Duplicated with those in ServerWorld
const s32 m_width = 8;
const s32 m_height = 4;
const s32 m_depth = 8;
const s32 m_width = 32;
const s32 m_height = 8;
const s32 m_depth = 32;
std::vector<std::unique_ptr<ClientChunk>> m_chunks;
gk::Texture &m_texture;
Client &m_client;
};
#endif // CLIENTWORLD_HPP_

View File

@ -54,6 +54,11 @@ GameState::GameState(Client &client, int port) : m_client(client) {
packet >> x >> y >> z >> block;
m_world.setBlock(x, y, z, block);
});
// sf::Packet packet;
// packet << Network::Command::ClientSettings;
// packet << Config::renderDistance;
// m_client.send(packet);
}
void GameState::testLuaAPI() {

View File

@ -14,11 +14,14 @@
#include <gk/gl/Shader.hpp>
#include <gk/resource/ResourceHandler.hpp>
#include "Config.hpp"
#include "Client.hpp"
#include "ClientWorld.hpp"
#include "World.hpp"
ClientWorld::ClientWorld() : m_texture(gk::ResourceHandler::getInstance().get<gk::Texture>("texture-blocks")) {
ClientWorld::ClientWorld(Client &client)
: m_texture(gk::ResourceHandler::getInstance().get<gk::Texture>("texture-blocks")),
m_client(client)
{
for(s32 z = 0 ; z < m_depth ; z++) {
for(s32 y = 0 ; y < m_height ; y++) {
for(s32 x = 0 ; x < m_width ; x++) {
@ -130,10 +133,10 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
states.shader->setUniform("u_renderDistance", Config::renderDistance * CHUNK_WIDTH);
gk::Shader::bind(nullptr);
// float ud = 1000.0;
// int ux = 0;
// int uy = 0;
// int uz = 0;
float ud = 1000.0;
s32 ux = 0;
s32 uy = 0;
s32 uz = 0;
std::vector<std::pair<ClientChunk*, gk::Transform>> chunks;
for(auto &it : m_chunks) {
@ -154,7 +157,7 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
// Is this chunk on the screen?
center = target.getView()->getTransform().getMatrix() * center;
// float d = glm::length(center);
float d = glm::length(center);
center.x /= center.w;
center.y /= center.w;
@ -172,13 +175,12 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
// If this chunk is not initialized, skip it
if(!it->isInitialized()) {
// But if it is the closest to the camera, mark it for initialization
// FIXME
// if(d < ud) {
// ud = d;
// ux = it->x();
// uy = it->y();
// uz = it->z();
// }
if(d < ud) {
ud = d;
ux = it->x();
uy = it->y();
uz = it->z();
}
continue;
}
@ -186,19 +188,12 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
chunks.emplace_back(&*it, states.transform);
}
// FIXME
// if(ud < 1000) {
// m_terrainGenerator.generate(*getChunk(ux, uy, uz));
//
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Left)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Left));
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Right)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Right));
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Bottom)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Bottom));
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Top)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Top));
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Front)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Front));
// if(getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Back)) m_terrainGenerator.generate(*getChunk(ux, uy, uz)->getSurroundingChunk(Chunk::Back));
//
// getChunk(ux, uy, uz)->setInitialized(true);
// }
if(ud < 1000) {
sf::Packet packet;
packet << Network::Command::ChunkRequest;
packet << ux << uy << uz;
m_client.send(packet);
}
for (u8 i = 0 ; i < ChunkBuilder::layers ; ++i) {
for (auto &it : chunks) {

View File

@ -18,7 +18,7 @@ add_library(${CMAKE_PROJECT_NAME}_common STATIC ${SOURCE_FILES})
# Compiler flags
#------------------------------------------------------------------------------
# target_compile_options(${CMAKE_PROJECT_NAME}_common PRIVATE -O3 -ffast-math)
target_compile_options(${CMAKE_PROJECT_NAME}_common PRIVATE -g -Wall -Wextra -Wfatal-errors -Wno-variadic-macros)
target_compile_options(${CMAKE_PROJECT_NAME}_common PRIVATE -g -pg -Wall -Wextra -Wfatal-errors -Wno-variadic-macros)
target_compile_options(${CMAKE_PROJECT_NAME}_common PRIVATE -DDEBUG_ENABLED)
target_compile_options(${CMAKE_PROJECT_NAME}_common PRIVATE -DSOL_CHECK_ARGUMENTS
# -DSOL_SAFE_USERTYPE=1

View File

@ -28,7 +28,8 @@ namespace Network {
KeyState, // <UDP> [NetworkCommand][u32 timestamp][u16 client id][u32 keycode][bool isPressed]...
// Chunk commands
ChunkData, // <TCP> [NetworkCommand][s32 sx, sy, sz][u32...] (from Server only)
ChunkData, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
// Player commands
PlayerPlaceBlock, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)

View File

@ -73,6 +73,9 @@ class Chunk : public gk::NonCopyable {
static constexpr u8 height = CHUNK_HEIGHT;
static constexpr u8 depth = CHUNK_DEPTH;
using DataArray = u32[Chunk::width][Chunk::height][Chunk::depth];
const DataArray &data() const { return m_data; }
protected:
// void updateNeighbours(int x, int y, int z);
@ -80,7 +83,6 @@ class Chunk : public gk::NonCopyable {
s32 m_y;
s32 m_z;
using DataArray = u32[Chunk::width][Chunk::height][Chunk::depth];
DataArray m_data;
ChunkLightmap m_lightmap{this};

View File

@ -23,10 +23,15 @@ std::string Network::commandToString(Network::Command command) {
{Network::Command::ClientDisconnect, "ClientDisconnect"},
{Network::Command::ClientOk, "ClientOk"},
{Network::Command::ClientRefused, "ClientRefused"},
{Network::Command::KeyState, "KeyState"},
{Network::Command::ChunkData, "ChunkData"},
{Network::Command::ChunkRequest, "ChunkRequest"},
{Network::Command::PlayerPlaceBlock, "PlayerPlaceBlock"},
{Network::Command::PlayerDigBlock, "PlayerDigBlock"},
{Network::Command::BlockUpdate, "BlockUpdate"},
};
return commandNames[command];

View File

@ -25,6 +25,8 @@ Chunk::Chunk(s32 x, s32 y, s32 z) {
m_z = z;
std::memset(m_data, 0, sizeof(m_data));
// FIXME: Which one is faster?
// std::fill(std::begin(m_data), std::end(m_data), 0);
}
u16 Chunk::getBlock(int x, int y, int z) const {

View File

@ -33,7 +33,8 @@ target_compile_options(${CMAKE_PROJECT_NAME}_server PRIVATE -DSOL_CHECK_ARGUMENT
target_compile_features(${CMAKE_PROJECT_NAME}_server PRIVATE cxx_std_17)
# target_link_options(${CMAKE_PROJECT_NAME} PRIVATE -pg)
target_compile_options(${CMAKE_PROJECT_NAME}_server PRIVATE -pg)
target_link_options(${CMAKE_PROJECT_NAME}_server PRIVATE -pg)
#------------------------------------------------------------------------------
# Link options

View File

@ -25,7 +25,7 @@
class Server {
using ConnectionCallback = std::function<void(Client&)>;
using CommandCallback = std::function<void(sf::Packet &packet)>;
using CommandCallback = std::function<void(Client &, sf::Packet &packet)>;
public:
void init(u16 port = 4242);

View File

@ -25,12 +25,11 @@ class ServerChunk : public Chunk {
ServerChunk(s32 x, s32 y, s32 z) : Chunk(x, y, z) {}
void update();
void generate();
bool isGenerated() const { return m_isGenerated; }
void setGenerated(bool isGenerated) { m_isGenerated = isGenerated; } // FIXME
const DataArray &data() const { return m_data; }
private:
bool m_hasChanged = false;
bool m_isGenerated = false;

View File

@ -29,6 +29,7 @@ class ServerWorld {
void sendWorldData(Client &client);
void sendChunkData(Client &client, ServerChunk *chunk);
void sendRequestedData(Client &client, int cx, int cy, int cz);
ServerChunk *getChunk(int cx, int cy, int cz) const;
@ -38,9 +39,9 @@ class ServerWorld {
private:
// FIXME: Duplicated with those in ClientWorld
const s32 m_width = 8;
const s32 m_height = 4;
const s32 m_depth = 8;
const s32 m_width = 32;
const s32 m_height = 8;
const s32 m_depth = 32;
std::vector<std::unique_ptr<ServerChunk>> m_chunks;
};

View File

@ -35,7 +35,18 @@ void ServerApplication::init() {
m_world.sendWorldData(client);
});
m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](sf::Packet &packet) {
// m_server.setCommandCallback(Network::Command::ClientSettings, [](sf::Packet &packet) {
// packet >> Config::renderDistance;
// });
m_server.setCommandCallback(Network::Command::ChunkRequest, [this](Client &client, sf::Packet &packet) {
s32 cx, cy, cz;
packet >> cx >> cy >> cz;
m_world.sendRequestedData(client, cx, cy, cz);
});
m_server.setCommandCallback(Network::Command::PlayerPlaceBlock, [this](Client &, sf::Packet &packet) {
s32 x, y, z;
u32 block;
packet >> x >> y >> z >> block;
@ -46,7 +57,7 @@ void ServerApplication::init() {
m_server.sendToAllClients(answer);
});
m_server.setCommandCallback(Network::Command::PlayerDigBlock, [this](sf::Packet &packet) {
m_server.setCommandCallback(Network::Command::PlayerDigBlock, [this](Client &, sf::Packet &packet) {
s32 x, y, z;
packet >> x >> y >> z;
m_world.setBlock(x, y, z, 0);

View File

@ -120,14 +120,6 @@ void Server::handleClientMessages() {
// DEBUG("TCP message received:", Network::commandToString(command));
if (command == Network::Command::ClientDisconnect) {
// FIXME
// sf::Packet packet;
// packet << Network::Command::EntityDie << "Player" + std::to_string(client.id);
// for (Client &client : m_info.clients()) {
// client.tcpSocket->send(packet);
// }
--i;
m_selector.remove(*client.tcpSocket);
m_info.removeClient(client.id);
@ -135,12 +127,14 @@ void Server::handleClientMessages() {
// m_tcpListener.close();
m_isRunning = false;
}
--i;
}
if (m_isRunning)
for (auto &it : m_commands)
if (command == it.first)
it.second(packet);
it.second(client, packet);
}
}
}

View File

@ -28,15 +28,17 @@ void ServerChunk::update() {
// }
// }
if (m_hasChanged) {
m_lightmap.updateLights();
}
}
void ServerChunk::generate() {
if (!m_isGenerated) {
m_terrainGenerator.generate(*this);
m_isGenerated = true;
m_hasChanged = true;
}
if (m_hasChanged) {
m_lightmap.updateLights();
}
}

View File

@ -49,11 +49,17 @@ void ServerWorld::update() {
}
void ServerWorld::sendWorldData(Client &client) {
for (auto &it : m_chunks)
sendChunkData(client, it.get());
for(s32 z = -m_depth / 8 ; z < m_depth / 8 ; z++) {
for(s32 y = -m_height / 8 ; y < m_height / 8 ; y++) {
for(s32 x = -m_width / 8 ; x < m_width / 8 ; x++) {
sendChunkData(client, getChunk(x, y, z));
}
}
}
}
void ServerWorld::sendChunkData(Client &client, ServerChunk *chunk) {
chunk->generate();
chunk->update();
sf::Packet packet;
@ -73,6 +79,20 @@ void ServerWorld::sendChunkData(Client &client, ServerChunk *chunk) {
// std::cout << "Chunk at (" << chunk->x() << "," << chunk->y() << ", " << chunk->z() << ") sent to client" << std::endl;
}
void ServerWorld::sendRequestedData(Client &client, int cx, int cy, int cz) {
ServerChunk *chunk = getChunk(cx, cy, cz);
if (chunk) {
sendChunkData(client, chunk);
if(chunk->getSurroundingChunk(Chunk::Left)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Left));
if(chunk->getSurroundingChunk(Chunk::Right)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Right));
if(chunk->getSurroundingChunk(Chunk::Bottom)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Bottom));
if(chunk->getSurroundingChunk(Chunk::Top)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Top));
if(chunk->getSurroundingChunk(Chunk::Front)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Front));
if(chunk->getSurroundingChunk(Chunk::Back)) sendChunkData(client, (ServerChunk *)chunk->getSurroundingChunk(Chunk::Back));
}
}
ServerChunk *ServerWorld::getChunk(int cx, int cy, int cz) const {
cx += m_width / 2;
cy += m_height / 2;