mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(server): add block change packet handling and increase reserved threads
This commit is contained in:
@@ -25,7 +25,7 @@ constexpr float DEFAULT_G = 22.5f;
|
|||||||
constexpr int SIZE_X = CHUNK_SIZE;
|
constexpr int SIZE_X = CHUNK_SIZE;
|
||||||
constexpr int SIZE_Y = WORLD_SIZE_Y;
|
constexpr int SIZE_Y = WORLD_SIZE_Y;
|
||||||
constexpr int SIZE_Z = CHUNK_SIZE;
|
constexpr int SIZE_Z = CHUNK_SIZE;
|
||||||
constexpr int RESERVED_THREADS = 3;
|
constexpr int RESERVED_THREADS = 5;
|
||||||
|
|
||||||
constexpr float DEFAULT_CAVE_PROBABILITY = 0.035f;
|
constexpr float DEFAULT_CAVE_PROBABILITY = 0.035f;
|
||||||
|
|
||||||
|
|||||||
@@ -11,16 +11,21 @@ public:
|
|||||||
NetworkServer(int port = 25530);
|
NetworkServer(int port = 25530);
|
||||||
~NetworkServer();
|
~NetworkServer();
|
||||||
void stop();
|
void stop();
|
||||||
void run();
|
|
||||||
|
// Run in another thread after initialization is complete
|
||||||
|
void start_server();
|
||||||
|
|
||||||
int port() const;
|
int port() const;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<Session>> m_session;
|
std::unordered_map<std::string, std::shared_ptr<Session>> m_session;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asio::io_context m_io;
|
asio::io_context m_io;
|
||||||
std::thread m_server;
|
std::thread m_net_thread;
|
||||||
int m_port = 25530;
|
int m_port = 25530;
|
||||||
std::atomic<bool> m_stopped{false};
|
std::atomic<bool> m_stopped{false};
|
||||||
ServerWorld m_world;
|
ServerWorld m_world;
|
||||||
asio::awaitable<void> listen();
|
asio::awaitable<void> listen();
|
||||||
|
void net_run();
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -15,6 +15,8 @@ enum class PacketEnum {
|
|||||||
PLAYER_POS = 2002,
|
PLAYER_POS = 2002,
|
||||||
CHUNK_DATA_REQ = 3001,
|
CHUNK_DATA_REQ = 3001,
|
||||||
CHUNK_DATA_RSP = 3002,
|
CHUNK_DATA_RSP = 3002,
|
||||||
|
BLOCK_CHANGE_REQ = 3003,
|
||||||
|
BLOCK_CHANGE_RSP = 3004,
|
||||||
PING = 9001,
|
PING = 9001,
|
||||||
PONG = 9002
|
PONG = 9002
|
||||||
|
|
||||||
@@ -39,6 +41,10 @@ template <typename T> constexpr uint16_t get_packet_id() {
|
|||||||
return to_num(CHUNK_DATA_REQ);
|
return to_num(CHUNK_DATA_REQ);
|
||||||
} else if constexpr (is_same_v<U, ChunkDataRsp>) {
|
} else if constexpr (is_same_v<U, ChunkDataRsp>) {
|
||||||
return to_num(CHUNK_DATA_RSP);
|
return to_num(CHUNK_DATA_RSP);
|
||||||
|
} else if constexpr (is_same_v<U, BlockChangeReq>) {
|
||||||
|
return to_num(BLOCK_CHANGE_REQ);
|
||||||
|
} else if constexpr (is_same_v<U, BlockChangeRsp>) {
|
||||||
|
return to_num(BLOCK_CHANGE_RSP);
|
||||||
} else if constexpr (is_same_v<U, Ping>) {
|
} else if constexpr (is_same_v<U, Ping>) {
|
||||||
return to_num(PING);
|
return to_num(PING);
|
||||||
} else if (is_same_v<U, Pong>) {
|
} else if (is_same_v<U, Pong>) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "Cubed/gameplay/server_chunk.hpp"
|
#include "Cubed/gameplay/server_chunk.hpp"
|
||||||
#include "Cubed/gameplay/server_player.hpp"
|
#include "Cubed/gameplay/server_player.hpp"
|
||||||
#include "Cubed/tools/thread_pool.hpp"
|
#include "Cubed/tools/thread_pool.hpp"
|
||||||
|
#include "world/block_change.pb.h"
|
||||||
|
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
@@ -63,7 +64,7 @@ public:
|
|||||||
int chunk_load_style() const;
|
int chunk_load_style() const;
|
||||||
void set_chunk_load_style(int id);
|
void set_chunk_load_style(int id);
|
||||||
|
|
||||||
void set_block(const glm::ivec3& block_pos, unsigned id);
|
bool set_block(const glm::ivec3& block_pos, unsigned id);
|
||||||
|
|
||||||
void sync_player_pos(const std::string& uuid, float x, float y, float z);
|
void sync_player_pos(const std::string& uuid, float x, float y, float z);
|
||||||
void handle_player_login(const std::string& player_name,
|
void handle_player_login(const std::string& player_name,
|
||||||
@@ -71,6 +72,7 @@ public:
|
|||||||
glm::vec3 get_player_pos(const std::string& uuid) const;
|
glm::vec3 get_player_pos(const std::string& uuid) const;
|
||||||
|
|
||||||
void handle_chunk_req(const std::string& uuid, ChunkPos pos);
|
void handle_chunk_req(const std::string& uuid, ChunkPos pos);
|
||||||
|
void handle_block_change(const BlockChangeReq& req);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class ChunkLoadStyle { RANDOM, CENTER };
|
enum class ChunkLoadStyle { RANDOM, CENTER };
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ void NetworkServer::stop() {
|
|||||||
|
|
||||||
m_io.stop();
|
m_io.stop();
|
||||||
m_session.clear();
|
m_session.clear();
|
||||||
if (m_server.joinable()) {
|
if (m_net_thread.joinable()) {
|
||||||
m_server.join();
|
m_net_thread.join();
|
||||||
}
|
}
|
||||||
Logger::info("Server Stopped!");
|
Logger::info("Server Stopped!");
|
||||||
}
|
}
|
||||||
@@ -42,14 +42,19 @@ asio::awaitable<void> NetworkServer::listen() {
|
|||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkServer::run() {
|
void NetworkServer::net_run() {
|
||||||
m_server = std::thread([this]() {
|
m_net_thread = std::thread([this]() {
|
||||||
asio::co_spawn(m_io, listen(), asio::detached);
|
asio::co_spawn(m_io, listen(), asio::detached);
|
||||||
m_io.run();
|
m_io.run();
|
||||||
});
|
});
|
||||||
Logger::info("Server Started!");
|
Logger::info("Server Started!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkServer::start_server() {
|
||||||
|
m_world.init_world();
|
||||||
|
net_run();
|
||||||
|
}
|
||||||
|
|
||||||
int NetworkServer::port() const { return m_port; }
|
int NetworkServer::port() const { return m_port; }
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -47,17 +47,9 @@ void ServerWorld::init_world() {
|
|||||||
Logger::info("Chunk Block Init Finish, Time Consuming: {}", d);
|
Logger::info("Chunk Block Init Finish, Time Consuming: {}", d);
|
||||||
|
|
||||||
start_server_thread();
|
start_server_thread();
|
||||||
|
|
||||||
Logger::info("TestPlayer Create Finish");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::init_chunks() {
|
void ServerWorld::init_chunks() { hot_reload(); }
|
||||||
hot_reload();
|
|
||||||
while (!m_chunk_gen_finished) {
|
|
||||||
// Logger::info("World Spawn: {:.2f}%", m_chunk_gen_fraction.load());
|
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(200));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerWorld::gen_chunks_internal(std::optional<std::string> uuid) {
|
void ServerWorld::gen_chunks_internal(std::optional<std::string> uuid) {
|
||||||
// Logger::info("gen_chunks_internal");
|
// Logger::info("gen_chunks_internal");
|
||||||
@@ -304,7 +296,7 @@ void ServerWorld::need_gen(std::optional<std::string> uuid) {
|
|||||||
m_gen_cv.notify_one();
|
m_gen_cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
|
bool ServerWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
|
||||||
|
|
||||||
int world_x, world_y, world_z;
|
int world_x, world_y, world_z;
|
||||||
world_x = block_pos.x;
|
world_x = block_pos.x;
|
||||||
@@ -316,17 +308,18 @@ void ServerWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
|
|||||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||||
|
|
||||||
if (it == m_chunks.end()) {
|
if (it == m_chunks.end()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto [x, y, z] = ServerChunk::world_to_block(world_x, world_y, world_z,
|
auto [x, y, z] = ServerChunk::world_to_block(world_x, world_y, world_z,
|
||||||
chunk_x, chunk_z);
|
chunk_x, chunk_z);
|
||||||
if (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_SIZE_Y ||
|
if (x < 0 || y < 0 || z < 0 || x >= CHUNK_SIZE || y >= WORLD_SIZE_Y ||
|
||||||
z >= CHUNK_SIZE) {
|
z >= CHUNK_SIZE) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second.set_chunk_block(ServerChunk::index(x, y, z), id);
|
it->second.set_chunk_block(ServerChunk::index(x, y, z), id);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerWorld::hot_reload() {
|
void ServerWorld::hot_reload() {
|
||||||
@@ -456,6 +449,27 @@ void ServerWorld::handle_chunk_req(const std::string& uuid, ChunkPos pos) {
|
|||||||
s->send(make_packet(rsq));
|
s->send(make_packet(rsq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerWorld::handle_block_change(const BlockChangeReq& req) {
|
||||||
|
float x = req.pos().x();
|
||||||
|
float y = req.pos().y();
|
||||||
|
float z = req.pos().z();
|
||||||
|
if (!set_block(glm::ivec3(x, y, z), req.block())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BlockChangeRsp rsp;
|
||||||
|
auto* pos = rsp.mutable_pos();
|
||||||
|
pos->set_x(x);
|
||||||
|
pos->set_y(y);
|
||||||
|
pos->set_z(z);
|
||||||
|
rsp.set_block(req.block());
|
||||||
|
|
||||||
|
for (auto& [uuid, session] : m_player_session) {
|
||||||
|
if (session) {
|
||||||
|
session->send(make_packet(rsp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int ServerWorld::rendering_distance() const {
|
int ServerWorld::rendering_distance() const {
|
||||||
return m_rendering_distance.load();
|
return m_rendering_distance.load();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,12 @@ asio::awaitable<void> Session::read_loop() {
|
|||||||
req.uuid(), ChunkPos(req.pos().x(), req.pos().z()));
|
req.uuid(), ChunkPos(req.pos().x(), req.pos().z()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmd_id == to_num(PacketEnum::BLOCK_CHANGE_REQ)) {
|
||||||
|
BlockChangeReq req;
|
||||||
|
if (req.ParseFromArray(body_data.data(), body_data.size())) {
|
||||||
|
m_server_world.handle_block_change(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (const asio::system_error& e) {
|
} catch (const asio::system_error& e) {
|
||||||
Logger::warn("Catch Asio Error {}", e.what());
|
Logger::warn("Catch Asio Error {}", e.what());
|
||||||
|
|||||||
@@ -8,4 +8,5 @@ import "player/player.proto";
|
|||||||
import "auth/auth.proto";
|
import "auth/auth.proto";
|
||||||
import "system/ping.proto";
|
import "system/ping.proto";
|
||||||
import "system/pong.proto";
|
import "system/pong.proto";
|
||||||
import "world/chunk_data.proto";
|
import "world/chunk_data.proto";
|
||||||
|
import "world/block_change.proto";
|
||||||
14
src/proto/world/block_change.proto
Normal file
14
src/proto/world/block_change.proto
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "common/vector3.proto";
|
||||||
|
|
||||||
|
message BlockChangeReq {
|
||||||
|
string uuid = 1;
|
||||||
|
Vec3 pos = 2;
|
||||||
|
uint32 block = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message BlockChangeRsp {
|
||||||
|
Vec3 pos = 1;
|
||||||
|
uint32 block = 2;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user