#pragma once #include #include #include #include #include #include #include #include #include #include "dvlnet/frame_queue.h" namespace devilution { namespace net { class protocol_exception : public std::exception { public: const char *what() const throw() override { return "Protocol error"; } }; class protocol_zt { public: class endpoint { public: std::array addr = {}; explicit operator bool() const { auto empty = std::array {}; return (addr != empty); } bool operator==(const endpoint &rhs) const { return addr == rhs.addr; } bool operator!=(const endpoint &rhs) const { return !(*this == rhs); } bool operator<(const endpoint &rhs) const { return addr < rhs.addr; } buffer_t serialize() const { return buffer_t(addr.begin(), addr.end()); } void unserialize(const buffer_t &buf) { if (buf.size() != 16) throw protocol_exception(); std::copy(buf.begin(), buf.end(), addr.begin()); } void from_string(const std::string &str); }; protocol_zt(); ~protocol_zt(); void disconnect(const endpoint &peer); bool send(const endpoint &peer, const buffer_t &data); bool send_oob(const endpoint &peer, const buffer_t &data) const; bool send_oob_mc(const buffer_t &data) const; bool recv(endpoint &peer, buffer_t &data); bool get_disconnected(endpoint &peer); bool network_online(); bool is_peer_connected(endpoint &peer); bool is_peer_relayed(const endpoint &peer) const; static std::string make_default_gamename(); private: static constexpr uint32_t PKTBUF_LEN = 65536; static constexpr uint16_t default_port = 6112; struct peer_state { int fd = -1; std::deque send_queue; frame_queue recv_queue; }; std::deque> oob_recv_queue; std::deque disconnect_queue; std::map peer_list; int fd_tcp = -1; int fd_udp = -1; static uint64_t current_ms(); void close_all(); static void set_nonblock(int fd); static void set_nodelay(int fd); static void set_reuseaddr(int fd); bool send_queued_peer(const endpoint &peer); bool recv_peer(const endpoint &peer); bool send_queued_all(); bool recv_from_peers(); bool recv_from_udp(); bool accept_all(); }; } // namespace net } // namespace devilution