From a23119ae1c5961bd44239f201a0fdac708566fbd Mon Sep 17 00:00:00 2001 From: staphen Date: Fri, 17 Nov 2023 23:36:47 -0500 Subject: [PATCH] Get rid of protocol_exception --- Source/dvlnet/abstract_net.h | 8 ------- Source/dvlnet/base_protocol.h | 40 +++++++++++++++++++++++++++-------- Source/dvlnet/protocol_zt.cpp | 19 +++++++++++------ Source/dvlnet/protocol_zt.h | 21 +++++++++--------- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/Source/dvlnet/abstract_net.h b/Source/dvlnet/abstract_net.h index ea38b6f3a..67c5b0c13 100644 --- a/Source/dvlnet/abstract_net.h +++ b/Source/dvlnet/abstract_net.h @@ -14,14 +14,6 @@ namespace devilution::net { using buffer_t = std::vector; using provider_t = unsigned long; -class dvlnet_exception : public std::exception { -public: - const char *what() const throw() override - { - return "Network error"; - } -}; - class abstract_net { public: virtual int create(std::string addrstr) = 0; diff --git a/Source/dvlnet/base_protocol.h b/Source/dvlnet/base_protocol.h index 7ea9fe298..8a4702a4f 100644 --- a/Source/dvlnet/base_protocol.h +++ b/Source/dvlnet/base_protocol.h @@ -64,7 +64,7 @@ private: tl::expected recv_ingame(packet &pkt, endpoint_t sender); bool is_recognized(endpoint_t sender); - bool wait_network(); + tl::expected wait_network(); bool wait_firstpeer(); tl::expected wait_join(); }; @@ -80,15 +80,18 @@ plr_t base_protocol

::get_master() } template -bool base_protocol

::wait_network() +tl::expected base_protocol

::wait_network() { // wait for ZeroTier for 5 seconds for (auto i = 0; i < 500; ++i) { - if (proto.network_online()) - break; + tl::expected status = proto.network_online(); + if (!status.has_value()) + return status; + if (*status) + return true; SDL_Delay(10); } - return proto.network_online(); + return false; } template @@ -118,7 +121,12 @@ bool base_protocol

::wait_firstpeer() template bool base_protocol

::send_info_request() { - if (!proto.network_online()) + tl::expected status = proto.network_online(); + if (!status.has_value()) { + LogError("network_online: {}", status.error().what()); + return false; + } + if (!*status) return false; tl::expected, PacketError> pkt = pktfty->make_packet(PLR_BROADCAST, PLR_MASTER); @@ -158,7 +166,12 @@ int base_protocol

::create(std::string addrstr) gamename = addrstr; isGameHost_ = true; - if (wait_network()) { + tl::expected isReady = wait_network(); + if (!isReady.has_value()) { + LogError("wait_network: {}", isReady.error().what()); + return -1; + } + if (*isReady) { plr_self = 0; if (tl::expected result = Connect(plr_self); !result.has_value()) { @@ -175,7 +188,13 @@ int base_protocol

::join(std::string addrstr) gamename = addrstr; isGameHost_ = false; - if (wait_network()) { + tl::expected isReady = wait_network(); + if (!isReady.has_value()) { + const std::string_view message = isReady.error().what(); + SDL_SetError("wait_join: %.*s", static_cast(message.size()), message.data()); + return -1; + } + if (*isReady) { if (wait_firstpeer()) { tl::expected result = wait_join(); if (!result.has_value()) { @@ -413,7 +432,10 @@ tl::expected base_protocol

::recv_ingame(packet &pkt, endpo tl::expected pktInfo = pkt.Info(); if (!pktInfo.has_value()) return tl::make_unexpected(pktInfo.error()); - peer.endpoint.unserialize(**pktInfo); + if (tl::expected result = peer.endpoint.unserialize(**pktInfo); + !result.has_value()) { + return result; + } peer.sendQueue = std::make_unique>(); if (tl::expected result = Connect(*newPlayer); !result.has_value()) { diff --git a/Source/dvlnet/protocol_zt.cpp b/Source/dvlnet/protocol_zt.cpp index eabbddc43..0da1f152c 100644 --- a/Source/dvlnet/protocol_zt.cpp +++ b/Source/dvlnet/protocol_zt.cpp @@ -47,7 +47,7 @@ void protocol_zt::set_reuseaddr(int fd) lwip_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes)); } -bool protocol_zt::network_online() +tl::expected protocol_zt::network_online() { if (!zerotier_network_ready()) return false; @@ -65,7 +65,7 @@ bool protocol_zt::network_online() if (ret < 0) { Log("lwip, (udp) bind: {}", strerror(errno)); SDL_SetError("lwip, (udp) bind: %s", strerror(errno)); - throw protocol_exception(); + return tl::make_unexpected(ProtocolError()); } set_nonblock(fd_udp); } @@ -76,13 +76,13 @@ bool protocol_zt::network_online() if (r1 < 0) { Log("lwip, (tcp) bind: {}", strerror(errno)); SDL_SetError("lwip, (udp) bind: %s", strerror(errno)); - throw protocol_exception(); + return tl::make_unexpected(ProtocolError()); } auto r2 = lwip_listen(fd_tcp, 10); if (r2 < 0) { Log("lwip, listen: {}", strerror(errno)); SDL_SetError("lwip, listen: %s", strerror(errno)); - throw protocol_exception(); + return tl::make_unexpected(ProtocolError()); } set_nonblock(fd_tcp); set_nodelay(fd_tcp); @@ -117,7 +117,7 @@ bool protocol_zt::send_oob_mc(const buffer_t &data) const return send_oob(mc, data); } -bool protocol_zt::send_queued_peer(const endpoint &peer) +tl::expected protocol_zt::send_queued_peer(const endpoint &peer) { if (peer_list[peer].fd == -1) { peer_list[peer].fd = lwip_socket(AF_INET6, SOCK_STREAM, 0); @@ -146,7 +146,7 @@ bool protocol_zt::send_queued_peer(const endpoint &peer) if (decltype(len)(r) == len) { peer_list[peer].send_queue.pop_front(); } else { - throw protocol_exception(); + return tl::make_unexpected(ProtocolError()); } } return true; @@ -168,7 +168,12 @@ bool protocol_zt::recv_peer(const endpoint &peer) bool protocol_zt::send_queued_all() { for (const auto &[endpoint, _] : peer_list) { - if (!send_queued_peer(endpoint)) { + tl::expected result = send_queued_peer(endpoint); + if (!result.has_value()) { + LogError("send_queued_peer: {}", result.error().what()); + continue; + } + if (!*result) { // handle error? } } diff --git a/Source/dvlnet/protocol_zt.h b/Source/dvlnet/protocol_zt.h index 214a2d797..f625acfff 100644 --- a/Source/dvlnet/protocol_zt.h +++ b/Source/dvlnet/protocol_zt.h @@ -11,17 +11,15 @@ #include #include "dvlnet/frame_queue.h" +#include "dvlnet/packet.h" namespace devilution { namespace net { -class protocol_exception : public std::exception { -public: - const char *what() const throw() override - { - return "Protocol error"; - } -}; +inline PacketError ProtocolError() +{ + return PacketError("Protocol error"); +} class protocol_zt { public: @@ -55,11 +53,12 @@ public: return buffer_t(addr.begin(), addr.end()); } - void unserialize(const buffer_t &buf) + tl::expected unserialize(const buffer_t &buf) { if (buf.size() != 16) - throw protocol_exception(); + return tl::make_unexpected(ProtocolError()); std::copy(buf.begin(), buf.end(), addr.begin()); + return {}; } void from_string(const std::string &str); @@ -73,7 +72,7 @@ public: bool send_oob_mc(const buffer_t &data) const; bool recv(endpoint &peer, buffer_t &data); bool get_disconnected(endpoint &peer); - bool network_online(); + tl::expected network_online(); bool is_peer_connected(endpoint &peer); bool is_peer_relayed(const endpoint &peer) const; static std::string make_default_gamename(); @@ -102,7 +101,7 @@ private: static void set_nodelay(int fd); static void set_reuseaddr(int fd); - bool send_queued_peer(const endpoint &peer); + tl::expected send_queued_peer(const endpoint &peer); bool recv_peer(const endpoint &peer); bool send_queued_all(); bool recv_from_peers();