mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(gameplay): add packet to clear all chunks on server rebuild
Add new packet S2C_ClearAllChunks (ID 3005) to notify clients when the server rebuilds its world. Clients respond by clearing their chunk cache and requesting fresh chunks. Shift UPDATE_TIME packet ID to 3006 to accommodate.
This commit is contained in:
@@ -37,6 +37,8 @@ public:
|
|||||||
bool can_pass_block(const glm::ivec3& block_pos) const;
|
bool can_pass_block(const glm::ivec3& block_pos) const;
|
||||||
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
||||||
|
|
||||||
|
void rebuild_world();
|
||||||
|
|
||||||
void push_delete_vbo(GLuint vbo);
|
void push_delete_vbo(GLuint vbo);
|
||||||
void push_delete_vao(GLuint vao);
|
void push_delete_vao(GLuint vao);
|
||||||
// void hot_reload();
|
// void hot_reload();
|
||||||
@@ -105,6 +107,7 @@ private:
|
|||||||
std::atomic<TickType> m_game_ticks{0};
|
std::atomic<TickType> m_game_ticks{0};
|
||||||
std::atomic<TickType> m_day_tick{6000};
|
std::atomic<TickType> m_day_tick{6000};
|
||||||
std::atomic<bool> m_requesting_chunk{false};
|
std::atomic<bool> m_requesting_chunk{false};
|
||||||
|
std::atomic<bool> m_is_rebuilding{false};
|
||||||
std::shared_ptr<NetworkClient> m_client;
|
std::shared_ptr<NetworkClient> m_client;
|
||||||
ChunkLoadStyle m_chunk_load_style{ChunkLoadStyle::CENTER};
|
ChunkLoadStyle m_chunk_load_style{ChunkLoadStyle::CENTER};
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ enum class PacketEnum : uint16_t {
|
|||||||
CHUNK_DATA_RSP = 3002,
|
CHUNK_DATA_RSP = 3002,
|
||||||
BLOCK_CHANGE_REQ = 3003,
|
BLOCK_CHANGE_REQ = 3003,
|
||||||
BLOCK_CHANGE_RSP = 3004,
|
BLOCK_CHANGE_RSP = 3004,
|
||||||
UPDATE_TIME = 3005,
|
S2C_CLEAR_ALL_CHUNKS = 3005,
|
||||||
|
UPDATE_TIME = 3006,
|
||||||
PING = 9001,
|
PING = 9001,
|
||||||
PONG = 9002
|
PONG = 9002
|
||||||
|
|
||||||
@@ -98,6 +99,9 @@ template <> constexpr uint16_t get_packet_id<BlockChangeReq>() {
|
|||||||
template <> constexpr uint16_t get_packet_id<BlockChangeRsp>() {
|
template <> constexpr uint16_t get_packet_id<BlockChangeRsp>() {
|
||||||
return std::to_underlying(PacketEnum::BLOCK_CHANGE_RSP);
|
return std::to_underlying(PacketEnum::BLOCK_CHANGE_RSP);
|
||||||
}
|
}
|
||||||
|
template <> constexpr uint16_t get_packet_id<S2C_ClearAllChunks>() {
|
||||||
|
return std::to_underlying(PacketEnum::S2C_CLEAR_ALL_CHUNKS);
|
||||||
|
}
|
||||||
template <> constexpr uint16_t get_packet_id<UpdateTime>() {
|
template <> constexpr uint16_t get_packet_id<UpdateTime>() {
|
||||||
return std::to_underlying(PacketEnum::UPDATE_TIME);
|
return std::to_underlying(PacketEnum::UPDATE_TIME);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,25 @@ bool ClientWorld::can_pass_block(const glm::ivec3& block_pos) const {
|
|||||||
auto id = chunk_blocks[ClientChunk::index(x, y, z)];
|
auto id = chunk_blocks[ClientChunk::index(x, y, z)];
|
||||||
return BlockManager::is_passable(id);
|
return BlockManager::is_passable(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientWorld::rebuild_world() {
|
||||||
|
if (m_is_rebuilding.exchange(true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stop_thread_pool();
|
||||||
|
{
|
||||||
|
std::lock_guard lk(m_chunks_mutex);
|
||||||
|
m_chunks.clear();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_pending_upload_queue_mutex);
|
||||||
|
m_pending_upload_queue.clear();
|
||||||
|
}
|
||||||
|
start_thread_pool();
|
||||||
|
request_chunk();
|
||||||
|
m_is_rebuilding = false;
|
||||||
|
}
|
||||||
|
|
||||||
BlockType ClientWorld::get_block_tpye(const glm::ivec3& block_pos) const {
|
BlockType ClientWorld::get_block_tpye(const glm::ivec3& block_pos) const {
|
||||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||||
std::shared_lock lk(m_chunks_mutex);
|
std::shared_lock lk(m_chunks_mutex);
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
|||||||
} break;
|
} break;
|
||||||
case to_num(PacketEnum::CHUNK_DATA_RSP): {
|
case to_num(PacketEnum::CHUNK_DATA_RSP): {
|
||||||
ChunkDataRsp rsp;
|
ChunkDataRsp rsp;
|
||||||
Logger::info("Client: Receive Chunk Data rsp, size {}mb",
|
// Logger::info("Client: Receive Chunk Data rsp, size {}mb",
|
||||||
body_data.size() / 1024.0f / 1024);
|
// body_data.size() / 1024.0f / 1024);
|
||||||
if (decode_packet(rsp, body_data, header)) {
|
if (decode_packet(rsp, body_data, header)) {
|
||||||
m_world.receive_chunk(std::move(rsp));
|
m_world.receive_chunk(std::move(rsp));
|
||||||
}
|
}
|
||||||
@@ -109,6 +109,15 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
|||||||
m_world.receive_player_logout(*rsp);
|
m_world.receive_player_logout(*rsp);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case to_num(PacketEnum::S2C_CLEAR_ALL_CHUNKS): {
|
||||||
|
auto* rsp = Arena::Create<S2C_ClearAllChunks>(&arena);
|
||||||
|
if (decode_packet(*rsp, body_data, header)) {
|
||||||
|
if (rsp->clear()) {
|
||||||
|
Logger::info("Client Clear All Chunk");
|
||||||
|
m_world.rebuild_world();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const asio::system_error& e) {
|
} catch (const asio::system_error& e) {
|
||||||
|
|||||||
@@ -392,6 +392,16 @@ void ServerWorld::rebuild_world() {
|
|||||||
start_thread_pool();
|
start_thread_pool();
|
||||||
start_gen_thread();
|
start_gen_thread();
|
||||||
need_gen(std::nullopt);
|
need_gen(std::nullopt);
|
||||||
|
Arena arena;
|
||||||
|
auto* rsp = Arena::Create<S2C_ClearAllChunks>(&arena);
|
||||||
|
rsp->set_clear(true);
|
||||||
|
{
|
||||||
|
std::lock_guard lock(m_player_mutex);
|
||||||
|
for (auto& [uuid, player] : m_players) {
|
||||||
|
player.get_session()->send(make_packet(*rsp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_is_rebuilding = false;
|
m_is_rebuilding = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,3 +17,7 @@ message ChunkDataRsp {
|
|||||||
repeated uint32 neighbor_blocks_3 = 7 [packed=true];
|
repeated uint32 neighbor_blocks_3 = 7 [packed=true];
|
||||||
repeated uint32 neighbor_blocks_4 = 8 [packed=true];
|
repeated uint32 neighbor_blocks_4 = 8 [packed=true];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message S2C_ClearAllChunks {
|
||||||
|
bool clear = 1;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user