diff --git a/Sources/Client/NetClient.cpp b/Sources/Client/NetClient.cpp index 60e2bed0..e98f4f5c 100644 --- a/Sources/Client/NetClient.cpp +++ b/Sources/Client/NetClient.cpp @@ -43,6 +43,7 @@ #include #include #include +#include DEFINE_SPADES_SETTING(cg_unicode, "1"); @@ -497,8 +498,12 @@ namespace spades { SPRaise("Disconnected: %s", DisconnectReasonString(event.data).c_str()); } + stmp::optional readerOrNone; + if (event.type == ENET_EVENT_TYPE_RECEIVE) { - NetPacketReader reader(event.packet); + readerOrNone.reset(event.packet); + auto &reader = readerOrNone.value(); + try { if (HandleHandshakePacket(reader)) { continue; @@ -515,7 +520,7 @@ namespace spades { if (event.type == ENET_EVENT_TYPE_CONNECT) { statusString = _Tr("NetClient", "Awaiting for state"); } else if (event.type == ENET_EVENT_TYPE_RECEIVE) { - NetPacketReader reader(event.packet); + auto &reader = readerOrNone.value(); reader.DumpDebug(); if (reader.GetType() != PacketTypeMapStart) { SPRaise("Unexpected packet: %d", (int)reader.GetType()); @@ -529,7 +534,7 @@ namespace spades { } } else if (status == NetClientStatusReceivingMap) { if (event.type == ENET_EVENT_TYPE_RECEIVE) { - NetPacketReader reader(event.packet); + auto &reader = readerOrNone.value(); if (reader.GetType() == PacketTypeMapChunk) { std::vector dt = reader.GetData(); @@ -642,7 +647,7 @@ namespace spades { } } else if (status == NetClientStatusConnected) { if (event.type == ENET_EVENT_TYPE_RECEIVE) { - NetPacketReader reader(event.packet); + auto &reader = readerOrNone.value(); // reader.DumpDebug(); try { HandleGamePacket(reader); diff --git a/Sources/Core/TMPUtils.h b/Sources/Core/TMPUtils.h index 1fe3db3c..fbb1cd63 100644 --- a/Sources/Core/TMPUtils.h +++ b/Sources/Core/TMPUtils.h @@ -25,9 +25,13 @@ #include #include #include +#include #include namespace stmp { + struct bad_optional_access : public std::logic_error { + bad_optional_access() : std::logic_error{"bad optional access"} {}; + }; // creating our own version because boost is overweighted // (preproecssing optional.hpp emits 50000 lines of C++ code!) @@ -82,6 +86,7 @@ namespace stmp { const T *get_pointer() const { return has_some ? reinterpret_cast(&storage) : nullptr; } + T &get() & { assert(has_some); return *get_pointer(); @@ -98,12 +103,39 @@ namespace stmp { assert(has_some); return *get_pointer(); } + + T &value() & { + if (!has_some) { + throw bad_optional_access{}; + } + return *get_pointer(); + } + const T &value() const & { + if (!has_some) { + throw bad_optional_access{}; + } + return *get_pointer(); + } + T &&value() && { + if (!has_some) { + throw bad_optional_access{}; + } + return *get_pointer(); + } + const T &&value() const && { + if (!has_some) { + throw bad_optional_access{}; + } + return *get_pointer(); + } + template T value_or(U &&default_value) const & { return *this ? get() : static_cast(std::forward(default_value)); } template T value_or(U &&default_value) && { return *this ? std::move(get()) : static_cast(std::forward(default_value)); } + T &operator->() { assert(has_some); return get();