mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(protocol): add packet serialization and login handling
Introduce packet header and ID mapping for protobuf messages. Refactor session and server_world to use new packet wrapper. Fix missing semicolons in proto files.
This commit is contained in:
59
include/Cubed/gameplay/packet.hpp
Normal file
59
include/Cubed/gameplay/packet.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
#include "packet.pb.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <type_traits>
|
||||
namespace Cubed {
|
||||
constexpr int HEADER_LEN = 8;
|
||||
using Packet = std::shared_ptr<std::vector<uint8_t>>;
|
||||
template <typename> struct always_false : std::false_type {}; // NOLINT
|
||||
template <typename T> constexpr uint16_t get_packet_id() {
|
||||
|
||||
using std::is_same_v;
|
||||
using U = std::decay_t<T>;
|
||||
if constexpr (is_same_v<U, LoginReq>) {
|
||||
return 1001;
|
||||
} else if constexpr (is_same_v<U, LoginRsp>) {
|
||||
return 1002;
|
||||
} else if constexpr (is_same_v<U, PlayerInfo>) {
|
||||
return 2001;
|
||||
} else if constexpr (is_same_v<U, PlayerPos>) {
|
||||
return 2002;
|
||||
} else if constexpr (is_same_v<U, ChunkData>) {
|
||||
return 3001;
|
||||
} else if constexpr (is_same_v<U, Ping>) {
|
||||
return 9001;
|
||||
} else if (is_same_v<U, Pong>) {
|
||||
return 9002;
|
||||
} else {
|
||||
static_assert(always_false<U>::value, "Unkonw Type");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> Packet make_packet(const T& msg) {
|
||||
std::string body;
|
||||
|
||||
if (!msg.SerializeToString(&body)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
uint16_t cmd = get_packet_id<T>();
|
||||
|
||||
uint32_t total_len = HEADER_LEN + body.size();
|
||||
|
||||
auto packet = std::make_shared<std::vector<uint8_t>>(total_len);
|
||||
|
||||
uint32_t total_len_net = htonl(total_len);
|
||||
uint16_t cmd_net = htons(cmd);
|
||||
|
||||
std::memcpy(packet->data(), &total_len_net, sizeof(total_len_net));
|
||||
|
||||
std::memcpy(packet->data() + sizeof(total_len_net), &cmd_net,
|
||||
sizeof(cmd_net));
|
||||
|
||||
std::memcpy(packet->data() + HEADER_LEN, body.data(), body.size());
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -7,15 +7,16 @@
|
||||
#include "Cubed/gameplay/server_chunk.hpp"
|
||||
#include "Cubed/gameplay/server_player.hpp"
|
||||
#include "Cubed/tools/thread_pool.hpp"
|
||||
#include "proto/player_request.pb.h"
|
||||
|
||||
#include <future>
|
||||
#include <shared_mutex>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
class Session;
|
||||
class ServerWorld {
|
||||
public:
|
||||
ServerWorld();
|
||||
@@ -64,7 +65,8 @@ public:
|
||||
void set_block(const glm::ivec3& block_pos, unsigned id);
|
||||
|
||||
void sync_player_pos(const std::string& name, float x, float y, float z);
|
||||
void handle_player_request(const PlayerRequest& request);
|
||||
void handle_player_login(const std::string& player_name,
|
||||
std::shared_ptr<Session> session);
|
||||
glm::vec3 get_player_pos(const std::string& name) const;
|
||||
|
||||
private:
|
||||
@@ -119,6 +121,9 @@ private:
|
||||
|
||||
std::optional<std::string> m_request_gen_name = std::nullopt;
|
||||
|
||||
tbb::concurrent_hash_map<std::string, std::shared_ptr<Session>>
|
||||
m_player_session;
|
||||
|
||||
void init_chunks();
|
||||
|
||||
void gen_chunks_internal();
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/gameplay/packet.hpp"
|
||||
|
||||
#include <asio.hpp>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
|
||||
using asio::ip::tcp;
|
||||
class ServerWorld;
|
||||
class Session : public std::enable_shared_from_this<Session> {
|
||||
@@ -13,16 +16,15 @@ public:
|
||||
Session(tcp::socket socket, ServerWorld& server_world);
|
||||
~Session();
|
||||
void start();
|
||||
void send(std::shared_ptr<std::vector<uint8_t>> packet);
|
||||
void send(Packet packet);
|
||||
void close();
|
||||
const std::string& uuid() const;
|
||||
|
||||
private:
|
||||
static constexpr int HEADER_LEN = 8;
|
||||
static constexpr uint32_t MAX_PACKET_SIZE = 4 * 1024 * 1024;
|
||||
tcp::socket m_socket;
|
||||
std::vector<char> m_read_buffer;
|
||||
std::deque<std::shared_ptr<std::vector<uint8_t>>> m_write_queue;
|
||||
std::deque<Packet> m_write_queue;
|
||||
asio::strand<asio::io_context::executor_type> m_strand;
|
||||
std::string m_uuid;
|
||||
ServerWorld& m_server_world;
|
||||
|
||||
Reference in New Issue
Block a user