diff --git a/CMakeLists.txt b/CMakeLists.txt index be92c34..ffbd28c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -158,6 +158,7 @@ protobuf_generate( TARGET ${PROJECT_NAME} LANGUAGE cpp PROTOS ${PROTO_FILES} + IMPORT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/proto ) if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "Building with AddressSanitizer enabled for target: ${PROJECT_NAME}") @@ -190,7 +191,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE ) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) - +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${PROJECT_NAME} PRIVATE ASIO_STANDALONE ASIO_NO_DEPRECATED diff --git a/include/Cubed/gameplay/packet.hpp b/include/Cubed/gameplay/packet.hpp new file mode 100644 index 0000000..a2cf541 --- /dev/null +++ b/include/Cubed/gameplay/packet.hpp @@ -0,0 +1,59 @@ +#pragma once +#include "packet.pb.h" + +#include +#include +namespace Cubed { +constexpr int HEADER_LEN = 8; +using Packet = std::shared_ptr>; +template struct always_false : std::false_type {}; // NOLINT +template constexpr uint16_t get_packet_id() { + + using std::is_same_v; + using U = std::decay_t; + if constexpr (is_same_v) { + return 1001; + } else if constexpr (is_same_v) { + return 1002; + } else if constexpr (is_same_v) { + return 2001; + } else if constexpr (is_same_v) { + return 2002; + } else if constexpr (is_same_v) { + return 3001; + } else if constexpr (is_same_v) { + return 9001; + } else if (is_same_v) { + return 9002; + } else { + static_assert(always_false::value, "Unkonw Type"); + } +} + +template Packet make_packet(const T& msg) { + std::string body; + + if (!msg.SerializeToString(&body)) { + return {}; + } + + uint16_t cmd = get_packet_id(); + + uint32_t total_len = HEADER_LEN + body.size(); + + auto packet = std::make_shared>(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 diff --git a/include/Cubed/gameplay/server_world.hpp b/include/Cubed/gameplay/server_world.hpp index d6ef653..67d089b 100644 --- a/include/Cubed/gameplay/server_world.hpp +++ b/include/Cubed/gameplay/server_world.hpp @@ -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 #include +#include #include #include #include #include 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); glm::vec3 get_player_pos(const std::string& name) const; private: @@ -119,6 +121,9 @@ private: std::optional m_request_gen_name = std::nullopt; + tbb::concurrent_hash_map> + m_player_session; + void init_chunks(); void gen_chunks_internal(); diff --git a/include/Cubed/gameplay/session.hpp b/include/Cubed/gameplay/session.hpp index b40a8c1..e402a1b 100644 --- a/include/Cubed/gameplay/session.hpp +++ b/include/Cubed/gameplay/session.hpp @@ -1,10 +1,13 @@ #pragma once +#include "Cubed/gameplay/packet.hpp" + #include #include #include #include namespace Cubed { + using asio::ip::tcp; class ServerWorld; class Session : public std::enable_shared_from_this { @@ -13,16 +16,15 @@ public: Session(tcp::socket socket, ServerWorld& server_world); ~Session(); void start(); - void send(std::shared_ptr> 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 m_read_buffer; - std::deque>> m_write_queue; + std::deque m_write_queue; asio::strand m_strand; std::string m_uuid; ServerWorld& m_server_world; diff --git a/src/gameplay/server_world.cpp b/src/gameplay/server_world.cpp index c00521a..dbbf1be 100644 --- a/src/gameplay/server_world.cpp +++ b/src/gameplay/server_world.cpp @@ -1,6 +1,8 @@ #include "Cubed/gameplay/server_world.hpp" #include "Cubed/config.hpp" +#include "Cubed/gameplay/packet.hpp" +#include "Cubed/gameplay/session.hpp" #include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/log.hpp" @@ -357,17 +359,14 @@ void ServerWorld::sync_player_pos(const std::string& name, float x, float y, it->second.update_pos(x, y, z); } -void ServerWorld::handle_player_request(const PlayerRequest& request) { - if (request.join()) { - player_join(request.name()); - } - if (request.exit()) { - player_exit(request.name()); - } - if (request.chunk_send()) { - m_request_gen_name = request.name(); - need_gen(); - } +void ServerWorld::handle_player_login(const std::string& name, + std::shared_ptr session) { + player_join(name); + m_player_session.emplace(name, session); + LoginRsp rsp; + rsp.set_success(true); + rsp.set_uuid(name); + session->send(make_packet(name)); } void ServerWorld::player_join(const std::string& name) { diff --git a/src/gameplay/session.cpp b/src/gameplay/session.cpp index 5ee9b0a..51e7f32 100644 --- a/src/gameplay/session.cpp +++ b/src/gameplay/session.cpp @@ -3,8 +3,6 @@ #include "Cubed/gameplay/server_world.hpp" #include "Cubed/tools/log.hpp" #include "Cubed/tools/uuid.hpp" -#include "proto/player_pos.pb.h" -#include "proto/player_request.pb.h" using asio::ip::tcp; namespace Cubed { @@ -61,20 +59,8 @@ asio::awaitable Session::read_loop() { } if (cmd_id == 1001) { - PlayerRequest player_request; - if (player_request.ParseFromArray(body_data.data(), - body_data.size())) { - } } if (cmd_id == 1002) { - PlayerPos player_pos; - if (player_pos.ParseFromArray(body_data.data(), - body_data.size())) { - m_server_world.sync_player_pos( - player_pos.name(), player_pos.x(), player_pos.y(), - player_pos.z()); - } else { - } } } } catch (const asio::system_error& e) { diff --git a/src/proto/packet.proto b/src/proto/packet.proto new file mode 100644 index 0000000..3ca3bf0 --- /dev/null +++ b/src/proto/packet.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +import "common/chunk_pos.proto"; +import "common/error.proto"; +import "common/player_info.proto"; +import "common/vector3.proto"; +import "player/player.proto"; +import "auth/auth.proto"; +import "system/ping.proto"; +import "system/pong.proto"; +import "world/chunk_data.proto"; \ No newline at end of file diff --git a/src/proto/player/player.proto b/src/proto/player/player.proto index e28f891..7d3450f 100644 --- a/src/proto/player/player.proto +++ b/src/proto/player/player.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -import "common/vector3.proto" +import "common/vector3.proto"; message PlayerPos { string uuid = 1; diff --git a/src/proto/world/chunk_data.proto b/src/proto/world/chunk_data.proto index 4e7a57b..090caa5 100644 --- a/src/proto/world/chunk_data.proto +++ b/src/proto/world/chunk_data.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -import "common/chunk_pos.proto" +import "common/chunk_pos.proto"; message ChunkData { ChunkPos pos = 1;