mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(gameplay): add Session class and UUID generation utility
This commit is contained in:
@@ -147,6 +147,7 @@ add_executable(${PROJECT_NAME}
|
||||
src/gameplay/client_chunk.cpp
|
||||
src/gameplay/server_player.cpp
|
||||
src/gameplay/client_player.cpp
|
||||
src/gameplay/session.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
33
include/Cubed/gameplay/session.hpp
Normal file
33
include/Cubed/gameplay/session.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <asio.hpp>
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
using asio::ip::tcp;
|
||||
|
||||
class Session : public std::enable_shared_from_this<Session> {
|
||||
|
||||
public:
|
||||
Session(tcp::socket socket);
|
||||
~Session();
|
||||
void start();
|
||||
void send();
|
||||
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::vector<char>> m_write_queue;
|
||||
std::mutex m_write_mutex;
|
||||
|
||||
std::string m_uuid;
|
||||
|
||||
asio::awaitable<void> read();
|
||||
asio::awaitable<void> write();
|
||||
};
|
||||
} // namespace Cubed
|
||||
42
include/Cubed/tools/uuid.hpp
Normal file
42
include/Cubed/tools/uuid.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
inline std::string generate_uuid() {
|
||||
|
||||
static std::mt19937_64 rng(
|
||||
std::chrono::steady_clock::now().time_since_epoch().count() ^
|
||||
(std::random_device{}()));
|
||||
std::uniform_int_distribution<uint64_t> dist(0, UINT64_MAX);
|
||||
|
||||
uint64_t a = dist(rng);
|
||||
uint64_t b = dist(rng);
|
||||
|
||||
std::array<uint8_t, 16> bytes{};
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
bytes[i] = (a >> (56 - 8 * i)) & 0xFF;
|
||||
bytes[8 + i] = (b >> (56 - 8 * i)) & 0xFF;
|
||||
}
|
||||
|
||||
bytes[6] = (bytes[6] & 0x0F) | 0x40;
|
||||
|
||||
bytes[8] = (bytes[8] & 0x3F) | 0x80;
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << std::hex << std::setfill('0');
|
||||
for (size_t i = 0; i < bytes.size(); ++i) {
|
||||
if (i == 4 || i == 6 || i == 8 || i == 10) {
|
||||
ss << '-';
|
||||
}
|
||||
ss << std::setw(2) << static_cast<int>(bytes[i]);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace Cubed
|
||||
59
src/gameplay/session.cpp
Normal file
59
src/gameplay/session.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "Cubed/gameplay/session.hpp"
|
||||
|
||||
#include "Cubed/tools/log.hpp"
|
||||
#include "Cubed/tools/uuid.hpp"
|
||||
using asio::ip::tcp;
|
||||
|
||||
namespace Cubed {
|
||||
Session::Session(tcp::socket socket)
|
||||
: m_socket(std::move(socket)), m_uuid(generate_uuid()) {}
|
||||
|
||||
Session::~Session() {}
|
||||
|
||||
void Session::start() {
|
||||
auto self = shared_from_this();
|
||||
asio::co_spawn(
|
||||
m_socket.get_executor(),
|
||||
[self]() -> asio::awaitable<void> { co_await self->read(); },
|
||||
asio::detached);
|
||||
}
|
||||
|
||||
const std::string& Session::uuid() const { return m_uuid; }
|
||||
|
||||
asio::awaitable<void> Session::read() {
|
||||
try {
|
||||
while (true) {
|
||||
std::array<char, HEADER_LEN> header;
|
||||
co_await asio::async_read(m_socket, asio::buffer(header),
|
||||
asio::use_awaitable);
|
||||
|
||||
uint32_t total_len_net;
|
||||
std::memcpy(&total_len_net, header.data(), sizeof(total_len_net));
|
||||
uint32_t total_len = ntohl(total_len_net);
|
||||
|
||||
uint16_t cmd_id_net;
|
||||
std::memcpy(&cmd_id_net, header.data() + 4, sizeof(cmd_id_net));
|
||||
uint16_t cmd_id = ntohs(cmd_id_net);
|
||||
if (total_len < HEADER_LEN || total_len > MAX_PACKET_SIZE) {
|
||||
|
||||
throw std::runtime_error("invalid packet length");
|
||||
}
|
||||
uint32_t body_len = total_len - HEADER_LEN;
|
||||
std::vector<char> body_data(body_len);
|
||||
if (body_len > 0) {
|
||||
co_await asio::async_read(m_socket, asio::buffer(body_data),
|
||||
asio::use_awaitable);
|
||||
}
|
||||
|
||||
if (cmd_id == 1001) {
|
||||
}
|
||||
}
|
||||
} catch (const asio::system_error& e) {
|
||||
Logger::warn("Catch Asio Error {}", e.what());
|
||||
close();
|
||||
} catch (...) {
|
||||
Logger::error("Unknow Error");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user