From fa318825ef0404816728f733484caa1bc23afa53 Mon Sep 17 00:00:00 2001 From: hovertank3d Date: Fri, 14 Nov 2025 20:05:59 +0100 Subject: george droid --- include/net/client.hpp | 2 +- include/net/conn.hpp | 90 +++++++---------------- include/net/packet.hpp | 27 +++---- include/net/server.hpp | 2 +- include/net/types.hpp | 189 +------------------------------------------------ 5 files changed, 42 insertions(+), 268 deletions(-) (limited to 'include/net') diff --git a/include/net/client.hpp b/include/net/client.hpp index 23d250b..87b0ea1 100644 --- a/include/net/client.hpp +++ b/include/net/client.hpp @@ -23,7 +23,7 @@ namespace net { class client { - struct sockaddr_in server_address { }; + struct sockaddr_in server_address {}; public: client(std::string hostname, int port) diff --git a/include/net/conn.hpp b/include/net/conn.hpp index 95992ed..6f57293 100644 --- a/include/net/conn.hpp +++ b/include/net/conn.hpp @@ -9,15 +9,17 @@ #include #include "net/packet.hpp" +#include "util/io.hpp" namespace net { class conn { - int sock_fd; + io::serialized_io rw; sockaddr_in conn_addr; socklen_t conn_addr_size; - using handler_list = std::vector)>>; + using handler = std::function)>; + using handler_list = std::vector; std::array handlers; std::map netmodule_handlers; @@ -27,72 +29,20 @@ private: uint16_t packet_size; uint8_t id; - recv(packet_size); - recv(id); + rw.read(packet_size); + rw.read(id); return { id, packet_size - 3 }; } public: conn(int sock_fd, sockaddr_in conn_addr, socklen_t conn_addr_size) - : sock_fd(sock_fd) + : rw(io::file_io(sock_fd)) , conn_addr(conn_addr) , conn_addr_size(conn_addr_size) { } - ~conn() - { - close(sock_fd); - } - - ssize_t send(std::span data) - { - auto bytes = ::send(sock_fd, data.data(), data.size_bytes(), 0); - if (bytes < 0) { - throw std::runtime_error(strerror(errno)); - } - return bytes; - } - - template - ssize_t send(T t) - { - t = to_little(t); - auto bytes = ::send(sock_fd, &t, sizeof(T), 0); - if (bytes < 0) { - throw std::runtime_error(strerror(errno)); - } - return bytes; - } - - ssize_t recv(std::span data) - { - if (data.size_bytes() == 0) { - return 0; - } - - auto bytes = ::recv(sock_fd, data.data(), data.size_bytes(), 0); - if (bytes <= 0) { - throw std::runtime_error(strerror(errno)); - } - return bytes; - } - - template - ssize_t recv(T& t) - { - auto bytes = ::recv(sock_fd, &t, sizeof(T), 0); - if (bytes <= 0) { - throw std::runtime_error(strerror(errno)); - } - t = to_little(t); - if (bytes != sizeof(T)) { - throw std::runtime_error(strerror(errno)); - } - return bytes; - } - template void expect_packet(T& t) { @@ -101,11 +51,17 @@ public: if (len > 0) { std::vector payload(len); - recv(payload); + rw.read(payload); decode_packet(payload, t); } } + template + void reg_handler(int id, H h) + { + handlers[id].push_back(h); + } + template void reg_handler(H h) { @@ -133,13 +89,21 @@ public: template void send_packet(T p) { - auto payload = encode_packet(p); + send_packet(T::packet_id, encode_packet(p)); + } - send(int16_t(payload.size() + 3)); - send(T::packet_id); + void send_packet(uint8_t id, std::span payload) + { + std::vector packet_data; + auto buffer = io::serialized_io(io::buffered_io(packet_data)); + + buffer.write(int16_t(payload.size() + 3)); + buffer.write(id); if (payload.size() > 0) { - send(payload); + buffer.write(payload); } + + rw.write(packet_data); } bool handle_netmodule(std::span payload) @@ -170,7 +134,7 @@ public: } std::vector payload(len); - recv(payload); + rw.read(payload); // got netmodule if (id == 82) { diff --git a/include/net/packet.hpp b/include/net/packet.hpp index 117fc15..950601e 100644 --- a/include/net/packet.hpp +++ b/include/net/packet.hpp @@ -17,6 +17,7 @@ #include #include "types.hpp" +#include "util/io.hpp" namespace net { @@ -27,28 +28,22 @@ using packet_header = std::tuple; template void decode_packet(std::span payload, T& t) { - std::size_t offset = 0; + std::size_t len = 0; - boost::pfr::for_each_field(t, [&payload, &offset](auto& field, int i) { - if (offset >= payload.size()) { - throw std::runtime_error("Received invalid packet"); - } - offset += decode_field(payload.subspan(offset), field); - }); + auto rd = io::serialized_io(io::buffered_io { payload }); + len = rd.read(t); - if (offset < payload.size()) { - throw std::runtime_error(std::format("{}: {}", offset, payload.size())); + if (len != payload.size()) { + throw std::runtime_error(std::format("{}: {}", len, payload.size())); } } template -std::vector encode_raw_packet(T& t) +std::vector encode_packet_impl(T& t) { std::vector payload; - - boost::pfr::for_each_field(t, [&payload](auto& field) { - encode_field(payload, field); - }); + auto wt = io::serialized_io(io::buffered_io { payload }); + wt.write(t); return payload; } @@ -56,7 +51,7 @@ std::vector encode_raw_packet(T& t) template std::vector encode_packet(T& t) { - return encode_raw_packet(t); + return encode_packet_impl(t); } template @@ -69,7 +64,7 @@ std::vector encode_packet(T& t) int ret, flush; z_stream strm; - auto raw_payload = encode_raw_packet(t); + auto raw_payload = encode_packet_impl(t); strm.zalloc = Z_NULL; strm.zfree = Z_NULL; diff --git a/include/net/server.hpp b/include/net/server.hpp index 30791fc..9b5e7c5 100644 --- a/include/net/server.hpp +++ b/include/net/server.hpp @@ -23,7 +23,7 @@ namespace net { class server { - struct sockaddr_in server_address { }; + struct sockaddr_in server_address {}; int sock_fd; public: diff --git a/include/net/types.hpp b/include/net/types.hpp index a4a8c3b..13c96e0 100644 --- a/include/net/types.hpp +++ b/include/net/types.hpp @@ -1,13 +1,11 @@ #pragma once -#include -#include #include -#include #include +#include +#include #include "util/bitset.hpp" -#include "util/endian.hpp" #include "version.hpp" namespace net { @@ -76,183 +74,6 @@ struct death_reason { std::string custom; }; -void encode_field(std::vector& data, const std::string& f) -{ - auto bytes = reinterpret_cast(f.data()); - data.insert(data.end(), uint8_t(f.size())); - data.insert(data.end(), bytes, bytes + f.size()); -} - -template -void encode_field(std::vector& data, T f) -{ - auto fixed = to_little(f); - auto* p = reinterpret_cast(&fixed); - data.insert(data.end(), p, p + sizeof(T)); -} - -template -void encode_field(std::vector& data, T f) -{ - auto x = reinterpret_cast(&f); - data.insert(data.end(), x, x + sizeof(T)); -} - -void encode_field(std::vector& data, nstring& s) -{ - data.insert(data.end(), uint8_t(s.mode)); - encode_field(data, s.s); -} - -void encode_field(std::vector& data, const rgb& f) -{ - encode_field(data, f.r); - encode_field(data, f.g); - encode_field(data, f.b); -} - -template -void encode_field(std::vector& data, std::array& f) -{ - for (auto& e : f) { - encode_field(data, e); - } -} - -template -void encode_field(std::vector& data, std::vector& f) -{ - for (auto& e : f) { - encode_field(data, e); - } -} - -template -void encode_field(std::vector& data, std::span& f) -{ - for (auto& e : f) { - encode_field(data, e); - } -} - -template -void encode_field(std::vector& data, bitset& f) -{ - for (auto& e : f) { - encode_field(data, e); - } -} - -void encode_field(std::vector& data, death_reason& f) -{ - encode_field(data, f.reasons); - if (f.reasons[death_reason::reason::Player]) { - encode_field(data, f.player_index); - } - if (f.reasons[death_reason::reason::NPC]) { - encode_field(data, f.npc_index); - } - if (f.reasons[death_reason::reason::Projectile]) { - encode_field(data, f.projectile_index); - } - if (f.reasons[death_reason::reason::Other]) { - encode_field(data, f.other_index); - } - if (f.reasons[death_reason::reason::ProjectileType]) { - encode_field(data, f.projectile_type); - } - if (f.reasons[death_reason::reason::Item]) { - encode_field(data, f.item_type); - } - if (f.reasons[death_reason::reason::ItemPrefix]) { - encode_field(data, f.item_prefix); - } - if (f.reasons[death_reason::reason::Custom]) { - encode_field(data, f.custom); - } -} - -ssize_t decode_field(std::span data, std::string& f) -{ - assert(data.size() > 0); - uint8_t size = uint8_t(data[0]); // FIXME: varint - - assert(data.size() >= std::size_t(size + 1)); - - f.resize(size); - f.assign(reinterpret_cast(data.data() + 1 /* FIXME: varint*/), size); - return size + 1; -} - -template -ssize_t decode_field(std::span data, T& f) -{ - assert(data.size() >= sizeof(T)); - std::memcpy(&f, data.data(), sizeof(T)); - f = to_little(f); - return sizeof(T); -} - -ssize_t decode_field(std::span data, std::vector& f) -{ - f.insert(f.begin(), data.begin(), data.end()); - return f.size(); -} - -template -ssize_t decode_field(std::span data, std::array& f) -{ - assert(data.size() >= sizeof(T) * sz); - - ssize_t offset = 0; - for (auto& e : f) { - offset += decode_field(data.subspan(offset), e); - } - - return offset; -} - -ssize_t decode_field(std::span data, death_reason& f) -{ - int offset = 0; - offset += decode_field(data, f.reasons); - if (f.reasons[0]) { - offset += decode_field(data.subspan(offset), f.player_index); - } - if (f.reasons[1]) { - offset += decode_field(data.subspan(offset), f.npc_index); - } - if (f.reasons[2]) { - offset += decode_field(data.subspan(offset), f.projectile_index); - } - if (f.reasons[3]) { - offset += decode_field(data.subspan(offset), f.other_index); - } - if (f.reasons[4]) { - offset += decode_field(data.subspan(offset), f.projectile_type); - } - if (f.reasons[5]) { - offset += decode_field(data.subspan(offset), f.item_type); - } - if (f.reasons[6]) { - offset += decode_field(data.subspan(offset), f.item_prefix); - } - if (f.reasons[7]) { - offset += decode_field(data.subspan(offset), f.custom); - } - - return offset; -} -ssize_t decode_field(std::span data, rgb& f) -{ - assert(data.size() >= 3); - - f.r = uint8_t(data[0]); - f.g = uint8_t(data[1]); - f.b = uint8_t(data[2]); - return 3; -} - struct conn_request { static constexpr uint8_t packet_id = 1; @@ -480,12 +301,6 @@ struct damage_player { int8_t cooldown_counter; }; -template -struct raw { - static constexpr uint8_t packet_id = id; - std::vector data; -}; - inline nstring operator""_ns(const char* str, std::size_t) { return nstring(str); -- cgit v1.2.3