diff --git a/Src/Server/RemoteClient.cpp b/Src/Server/RemoteClient.cpp index 6509e48..76fd553 100644 --- a/Src/Server/RemoteClient.cpp +++ b/Src/Server/RemoteClient.cpp @@ -258,6 +258,15 @@ void RemoteClient::shutdown(EnumDisconnect type, const std::string reason) { void RemoteClient::NetworkAndResource_t::prepareRegionsRemove(WorldId_t worldId, std::vector regionPoses) { + auto worldIter = ChunksToSend.find(worldId); + if(worldIter != ChunksToSend.end()) { + for(const Pos::GlobalRegion ®ionPos : regionPoses) + worldIter->second.erase(regionPos); + + if(worldIter->second.empty()) + ChunksToSend.erase(worldIter); + } + for(Pos::GlobalRegion regionPos : regionPoses) { checkPacketBorder(16); NextPacket << (uint8_t) ToClient::RemoveRegion @@ -265,6 +274,60 @@ void RemoteClient::NetworkAndResource_t::prepareRegionsRemove(WorldId_t worldId, } } +void RemoteClient::NetworkAndResource_t::flushChunksToPackets() +{ + for(auto &worldPair : ChunksToSend) { + const WorldId_t worldId = worldPair.first; + auto ®ions = worldPair.second; + + for(auto ®ionPair : regions) { + const Pos::GlobalRegion regionPos = regionPair.first; + auto &voxels = regionPair.second.first; + auto &nodes = regionPair.second.second; + + for(auto &chunkPair : voxels) { + const Pos::bvec4u chunkPos = chunkPair.first; + const std::u8string &compressed = chunkPair.second; + + Pos::GlobalChunk globalPos = (Pos::GlobalChunk) regionPos; + globalPos <<= 2; + globalPos += (Pos::GlobalChunk) chunkPos; + + const size_t size = 1 + sizeof(WorldId_t) + + sizeof(Pos::GlobalChunk::Pack) + + sizeof(uint32_t) + + compressed.size(); + checkPacketBorder(static_cast(std::min(size, 64000))); + + NextPacket << (uint8_t) ToClient::ChunkVoxels + << worldId << globalPos.pack() << uint32_t(compressed.size()); + NextPacket.write((const std::byte*) compressed.data(), compressed.size()); + } + + for(auto &chunkPair : nodes) { + const Pos::bvec4u chunkPos = chunkPair.first; + const std::u8string &compressed = chunkPair.second; + + Pos::GlobalChunk globalPos = (Pos::GlobalChunk) regionPos; + globalPos <<= 2; + globalPos += (Pos::GlobalChunk) chunkPos; + + const size_t size = 1 + sizeof(WorldId_t) + + sizeof(Pos::GlobalChunk::Pack) + + sizeof(uint32_t) + + compressed.size(); + checkPacketBorder(static_cast(std::min(size, 64000))); + + NextPacket << (uint8_t) ToClient::ChunkNodes + << worldId << globalPos.pack() << uint32_t(compressed.size()); + NextPacket.write((const std::byte*) compressed.data(), compressed.size()); + } + } + } + + ChunksToSend.clear(); +} + void RemoteClient::NetworkAndResource_t::prepareEntitiesUpdate(const std::vector>& entities) { // for(auto& [entityId, entity] : entities) { @@ -337,6 +400,7 @@ ResourceRequest RemoteClient::pushPreparedPackets() { { auto lock = NetworkAndResource.lock(); + lock->flushChunksToPackets(); if(lock->NextPacket.size()) lock->SimplePackets.push_back(std::move(lock->NextPacket)); diff --git a/Src/Server/RemoteClient.hpp b/Src/Server/RemoteClient.hpp index 7fc7a7c..3dc722d 100644 --- a/Src/Server/RemoteClient.hpp +++ b/Src/Server/RemoteClient.hpp @@ -233,6 +233,8 @@ class RemoteClient { ChunksToSend[worldId][regionPos].second[chunkPos] = compressed_nodes; } + void flushChunksToPackets(); + void prepareEntitiesRemove(const std::vector& entityId); void prepareRegionsRemove(WorldId_t worldId, std::vector regionPoses); void prepareWorldRemove(WorldId_t worldId);