From 7339bbfd9b81d8307ea5c3ee989e245247d5ab71 Mon Sep 17 00:00:00 2001 From: Xadhoom <> Date: Fri, 1 Feb 2019 22:26:28 +0000 Subject: [PATCH] slightly refactor network layer --- CMakeLists.txt | 4 +- Stub/devilution_net.cpp | 531 ---------------------------- Stub/{devilution_net.h => dvlnet.h} | 224 +++++------- Stub/dvlnet_null.cpp | 67 ++++ Stub/dvlnet_udp.cpp | 297 ++++++++++++++++ Stub/dvlnet_udp_packet.cpp | 230 ++++++++++++ Stub/storm_net.cpp | 24 +- types.h | 2 +- 8 files changed, 699 insertions(+), 680 deletions(-) delete mode 100644 Stub/devilution_net.cpp rename Stub/{devilution_net.h => dvlnet.h} (63%) create mode 100644 Stub/dvlnet_null.cpp create mode 100644 Stub/dvlnet_udp.cpp create mode 100644 Stub/dvlnet_udp_packet.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f3c9dce07..4bac781de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,7 +140,9 @@ set(STUB_SOURCES Stub/sound.cpp Stub/storm.cpp Stub/storm_net.cpp - Stub/devilution_net.cpp + Stub/dvlnet_null.cpp + Stub/dvlnet_udp.cpp + Stub/dvlnet_udp_packet.cpp Stub/DiabloUI/credits.cpp Stub/DiabloUI/diabloui.cpp diff --git a/Stub/devilution_net.cpp b/Stub/devilution_net.cpp deleted file mode 100644 index 202569418..000000000 --- a/Stub/devilution_net.cpp +++ /dev/null @@ -1,531 +0,0 @@ -#include "../types.h" - -std::unique_ptr devilution_net::inst; -const devilution_net_udp::endpoint devilution_net_udp::none; - -static constexpr bool disable_encryption = false; - -void devilution_net_udp::packet::create(devilution_net_udp::packet_type t, - devilution_net_udp::plr_t s, - devilution_net_udp::plr_t d, - devilution_net_udp::buffer_t m) -{ - if (have_encrypted || have_decrypted) - ABORT(); - if (t != PT_MESSAGE) - ABORT(); - have_decrypted = true; - m_type = t; - m_src = s; - m_dest = d; - m_message = std::move(m); -} - -void devilution_net_udp::packet::create(devilution_net_udp::packet_type t, - devilution_net_udp::plr_t s, - devilution_net_udp::plr_t d, - devilution_net_udp::turn_t u) -{ - if (have_encrypted || have_decrypted) - ABORT(); - if (t != PT_TURN) - ABORT(); - have_decrypted = true; - m_type = t; - m_src = s; - m_dest = d; - m_turn = u; -} - -void devilution_net_udp::packet::create(devilution_net_udp::packet_type t, - devilution_net_udp::plr_t s, - devilution_net_udp::plr_t d, - devilution_net_udp::cookie_t c) -{ - if (have_encrypted || have_decrypted) - ABORT(); - if (t != PT_JOIN_REQUEST) - ABORT(); - have_decrypted = true; - m_type = t; - m_src = s; - m_dest = d; - m_cookie = c; -} - -void devilution_net_udp::packet::create(devilution_net_udp::packet_type t, - devilution_net_udp::plr_t s, - devilution_net_udp::plr_t d, - devilution_net_udp::cookie_t c, - devilution_net_udp::plr_t n, - devilution_net_udp::buffer_t i) -{ - if (have_encrypted || have_decrypted) - ABORT(); - if (t != PT_JOIN_ACCEPT) - ABORT(); - have_decrypted = true; - m_type = t; - m_src = s; - m_dest = d; - m_cookie = c; - m_newplr = n; - m_info = i; -} - -void devilution_net_udp::packet::create(devilution_net_udp::packet_type t, - devilution_net_udp::plr_t s, - devilution_net_udp::plr_t d, - devilution_net_udp::plr_t o) -{ - if (have_encrypted || have_decrypted) - ABORT(); - if (t != PT_LEAVE_GAME) - ABORT(); - have_decrypted = true; - m_type = t; - m_src = s; - m_dest = d; - m_oldplr = o; -} - -void devilution_net_udp::packet::create(devilution_net_udp::buffer_t buf) -{ - if (have_encrypted || have_decrypted) - ABORT(); - encrypted_buffer = std::move(buf); - have_encrypted = true; -} - -const devilution_net_udp::buffer_t &devilution_net_udp::packet::data() -{ - if (!have_decrypted || !have_encrypted) - ABORT(); - return encrypted_buffer; -} - -devilution_net_udp::packet_type devilution_net_udp::packet::type() -{ - if (!have_decrypted) - ABORT(); - return m_type; -} - -devilution_net_udp::plr_t devilution_net_udp::packet::src() -{ - if (!have_decrypted) - ABORT(); - return m_src; -} - -devilution_net_udp::plr_t devilution_net_udp::packet::dest() -{ - if (!have_decrypted) - ABORT(); - return m_dest; -} - -const devilution_net_udp::buffer_t &devilution_net_udp::packet::message() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_MESSAGE) - throw devilution_net_udp::packet_exception(); - return m_message; -} - -devilution_net_udp::turn_t devilution_net_udp::packet::turn() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_TURN) - throw devilution_net_udp::packet_exception(); - return m_turn; -} - -devilution_net_udp::cookie_t devilution_net_udp::packet::cookie() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_JOIN_REQUEST && m_type != PT_JOIN_ACCEPT) - throw devilution_net_udp::packet_exception(); - return m_cookie; -} - -devilution_net_udp::plr_t devilution_net_udp::packet::newplr() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_JOIN_ACCEPT) - throw devilution_net_udp::packet_exception(); - return m_newplr; -} - -devilution_net_udp::plr_t devilution_net_udp::packet::oldplr() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_LEAVE_GAME) - throw devilution_net_udp::packet_exception(); - return m_oldplr; -} - -const devilution_net_udp::buffer_t &devilution_net_udp::packet::info() -{ - if (!have_decrypted) - ABORT(); - if (m_type != PT_JOIN_ACCEPT) - throw devilution_net_udp::packet_exception(); - return m_info; -} - -void devilution_net_udp::packet::encrypt() -{ - if (!have_decrypted) - ABORT(); - if (have_encrypted) - return; - - process_data(); - - if (!disable_encryption) { - auto len_cleartext = encrypted_buffer.size(); - encrypted_buffer.insert(encrypted_buffer.begin(), crypto_secretbox_NONCEBYTES, 0); - encrypted_buffer.insert(encrypted_buffer.end(), crypto_secretbox_MACBYTES, 0); - randombytes_buf(encrypted_buffer.data(), crypto_secretbox_NONCEBYTES); - if (crypto_secretbox_easy(encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, - encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, - len_cleartext, - encrypted_buffer.data(), - key.data())) - ABORT(); - } - have_encrypted = true; -} - -void devilution_net_udp::packet::decrypt() -{ - if (!have_encrypted) - ABORT(); - if (have_decrypted) - return; - if (!disable_encryption) { - if (encrypted_buffer.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES + sizeof(packet_type) + 2 * sizeof(plr_t)) - throw devilution_net_udp::packet_exception(); - auto pktlen = encrypted_buffer.size() - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES; - decrypted_buffer.resize(pktlen); - if (crypto_secretbox_open_easy(decrypted_buffer.data(), - encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, - encrypted_buffer.size() - crypto_secretbox_NONCEBYTES, - encrypted_buffer.data(), - key.data())) - throw devilution_net_udp::packet_exception(); - } else { - if (encrypted_buffer.size() < sizeof(packet_type) + 2 * sizeof(plr_t)) - throw devilution_net_udp::packet_exception(); - decrypted_buffer = encrypted_buffer; - } - - process_data(); - - have_decrypted = true; -} - -devilution_net_udp::devilution_net_udp(buffer_t info) -{ - if (sodium_init() < 0) - abort(); - game_init_info = std::move(info); -} - -int devilution_net_udp::create(std::string addrstr, std::string passwd) -{ - sock = asio::ip::udp::socket(context); // to be removed later - setup_password(passwd); - auto ipaddr = asio::ip::make_address(addrstr); - if (ipaddr.is_v4()) - sock.open(asio::ip::udp::v4()); - else if (ipaddr.is_v6()) - sock.open(asio::ip::udp::v6()); - sock.non_blocking(true); - unsigned short port = default_port; - /* - while(port <= default_port+try_ports) { - try { - sock.bind(asio::ip::udp::endpoint(asio::ip::address_v6(), port)); - } catch (std::exception e) { - eprintf("bind: %s, %s\n", asio::ip::address_v6().to_string(), e.what()); - } - ++port; - } - */ - try { - sock.bind(endpoint(ipaddr, port)); - } catch (std::exception e) { - return -1; - } - plr_self = 0; - return plr_self; -} - -int devilution_net_udp::join(std::string addrstr, std::string passwd) -{ - setup_password(passwd); - auto ipaddr = asio::ip::make_address(addrstr); - endpoint themaster(ipaddr, default_port); - sock.connect(themaster); - master = themaster; - { // hack: try to join for 5 seconds - randombytes_buf(reinterpret_cast(&cookie_self), - sizeof(cookie_t)); - packet pkt(key); - pkt.create(PT_JOIN_REQUEST, ADDR_BROADCAST, ADDR_MASTER, cookie_self); - send(pkt); - for (auto i = 0; i < 5; ++i) { - recv(); - if (plr_self != ADDR_BROADCAST) - break; // join successful - sleep(1); - } - } - return (plr_self == ADDR_BROADCAST ? 4 : plr_self); -} - -void devilution_net_udp::setup_password(std::string pw) -{ - //pw.resize(std::min(pw.size(), crypto_pwhash_PASSWD_MAX)); - //pw.resize(std::max(pw.size(), crypto_pwhash_PASSWD_MIN), 0); - std::string salt("devilution-salt"); - salt.resize(crypto_pwhash_SALTBYTES, 0); - if (crypto_pwhash(key.data(), crypto_secretbox_KEYBYTES, - pw.data(), pw.size(), - reinterpret_cast(salt.data()), - crypto_pwhash_OPSLIMIT_INTERACTIVE, - crypto_pwhash_MEMLIMIT_INTERACTIVE, - crypto_pwhash_ALG_DEFAULT)) - ABORT(); -} - -void devilution_net_udp::recv() -{ - try { - while (1) { // read until kernel buffer is empty? - try { - endpoint sender; - buffer_t pkt_buf(max_packet_size); - size_t pkt_len; - pkt_len = sock.receive_from(asio::buffer(pkt_buf), sender); - pkt_buf.resize(pkt_len); - packet pkt(key); - pkt.create(pkt_buf); - pkt.decrypt(); - recv_decrypted(pkt, sender); - } catch (packet_exception e) { - // drop packet - } - } - } catch (std::exception e) { - return; - } -} - -void devilution_net_udp::send(devilution_net_udp::packet &pkt, endpoint sender) -{ - pkt.encrypt(); - for (auto &dest : dests_for_addr(pkt.dest(), sender)) { - sock.send_to(asio::buffer(pkt.data()), dest); - } -} - -std::set devilution_net_udp::dests_for_addr(plr_t dest, endpoint sender) -{ - auto ret = std::set(); - if (dest == plr_self) - return ret; - - if (0 <= dest && dest < MAX_PLRS) { - if (active_table[dest]) - ret.insert(nexthop_table[dest]); - } else if (dest == ADDR_BROADCAST) { - for (auto i = 0; i < MAX_PLRS; ++i) - if (i != plr_self && active_table[i]) - ret.insert(nexthop_table[i]); - ret.insert(connection_requests_pending.begin(), connection_requests_pending.end()); - } else if (dest == ADDR_MASTER) { - if (master != none) - ret.insert(master); - } - ret.erase(sender); - return ret; -} - -void devilution_net_udp::handle_join_request(packet &pkt, endpoint sender) -{ - plr_t i; - for (i = 0; i < MAX_PLRS; ++i) { - if (i != plr_self && nexthop_table[i] == none) { - nexthop_table[i] = sender; - break; - } - } - packet reply(key); - reply.create(PT_JOIN_ACCEPT, plr_self, ADDR_BROADCAST, pkt.cookie(), i, game_init_info); - send(reply); -} - -void devilution_net_udp::run_event_handler(_SNETEVENT &ev) -{ - auto f = registered_handlers[static_cast(ev.eventid)]; - if(f) { - printf("RUNNING HANDLER"); - f(&ev); - } -} - -void devilution_net_udp::handle_accept(packet &pkt) -{ - if (plr_self != ADDR_BROADCAST) - return; // already have player id - if (pkt.cookie() == cookie_self) - plr_self = pkt.newplr(); - _SNETEVENT ev; - ev.eventid = EVENT_TYPE_PLAYER_CREATE_GAME; - ev.playerid = plr_self; - ev.data = pkt.info().data(); - ev.databytes = pkt.info().size(); - printf("GOT SEED!!"); - run_event_handler(ev); -} - -void devilution_net_udp::recv_decrypted(packet &pkt, endpoint sender) -{ - // 1. route - send(pkt, sender); - // 2. handle local - if (pkt.src() == ADDR_BROADCAST && pkt.dest() == ADDR_MASTER) { - connection_requests_pending.insert(sender); - if (master == none) { - handle_join_request(pkt, sender); - } - } - // normal packets - if (pkt.src() < 0 || pkt.src() >= MAX_PLRS) - return; //drop packet - if (active_table[pkt.src()]) { //WRONG?!? - if (sender != nexthop_table[pkt.src()]) - return; //rpfilter fail: drop packet - } else { - nexthop_table[pkt.src()] = sender; // new connection: accept - } - active_table[pkt.src()] = ACTIVE; - if (pkt.dest() != plr_self && pkt.dest() != ADDR_BROADCAST) - return; //packet not for us, drop - switch (pkt.type()) { - case PT_MESSAGE: - message_queue.push(message_t(pkt.src(), pkt.message())); - break; - case PT_TURN: - turn_last[pkt.src()] = pkt.turn(); - turn_new[pkt.src()] = true; - break; - case PT_JOIN_ACCEPT: - handle_accept(pkt); - break; - case PT_LEAVE_GAME: - // todo - break; - // otherwise drop - } -} - -bool devilution_net_udp::SNetReceiveMessage(int *sender, char **data, int *size) -{ - recv(); - if (message_queue.empty()) - return false; - message_last = message_queue.front(); - message_queue.pop(); - *sender = message_last.sender; - *size = message_last.payload.size(); - *data = reinterpret_cast(message_last.payload.data()); - return true; -} - -bool devilution_net_udp::SNetSendMessage(int playerID, void *data, unsigned int size) -{ - if (playerID != SNPLAYER_ALL && playerID != SNPLAYER_OTHERS && (playerID < 0 || playerID >= MAX_PLRS)) - abort(); - auto raw_message = reinterpret_cast(data); - buffer_t message(raw_message, raw_message + size); - if (playerID == plr_self || playerID == SNPLAYER_ALL) - message_queue.push(message_t(plr_self, message)); - plr_t dest; - if (playerID == SNPLAYER_ALL || playerID == SNPLAYER_OTHERS) - dest = ADDR_BROADCAST; - else - dest = playerID; - packet pkt(key); - pkt.create(PT_MESSAGE, plr_self, dest, message); - send(pkt); - return true; -} - -bool devilution_net_udp::SNetReceiveTurns(char **data, unsigned int *size, DWORD *status) -{ - recv(); - for (auto i = 0; i < MAX_PLRS; ++i) { - status[i] = 0; - if (i == plr_self || nexthop_table[i] != none) { - status[i] |= (PS_ACTIVE | PS_CONNECTED); - } - size[i] = sizeof(turn_t); - if (turn_new[i] = true) { - status[i] |= PS_HASMSG; - data[i] = reinterpret_cast(&turn_last[i]); - turn_new[i] = false; - } - } - return true; -} - -bool devilution_net_udp::SNetSendTurn(char *data, unsigned int size) -{ - if (size != sizeof(turn_t)) - ABORT(); - packet pkt(key); - pkt.create(PT_TURN, plr_self, ADDR_BROADCAST, *reinterpret_cast(data)); - send(pkt); - return true; -} - -int devilution_net_udp::SNetGetProviderCaps(struct _SNETCAPS *caps) -{ - caps->size = 0; // engine writes only ?!? - caps->flags = 0; // unused - caps->maxmessagesize = 512; // capped to 512; underflow if < 24 - caps->maxqueuesize = 0; // unused - caps->maxplayers = MAX_PLRS; // capped to 4 - caps->bytessec = 1000000; // ? - caps->latencyms = 0; // unused - caps->defaultturnssec = 10; // ? - caps->defaultturnsintransit = 1; // maximum acceptable number of turns in queue? - return 1; -} - - -void *devilution_net_udp::SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) -{ - registered_handlers.erase(evtype); - return (void*)func; -} - -void *devilution_net_udp::SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) -{ - registered_handlers[evtype] = func; - return (void*)func; - // need to handle: - // EVENT_TYPE_PLAYER_LEAVE_GAME - // EVENT_TYPE_PLAYER_CREATE_GAME (raised during SNetCreateGame?) - // EVENT_TYPE_PLAYER_MESSAGE - // all by the same function -} diff --git a/Stub/devilution_net.h b/Stub/dvlnet.h similarity index 63% rename from Stub/devilution_net.h rename to Stub/dvlnet.h index 1d08d5db1..a871954bc 100644 --- a/Stub/devilution_net.h +++ b/Stub/dvlnet.h @@ -4,15 +4,13 @@ #include #include -class devilution_net { +class dvlnet { public: typedef std::vector buffer_t; - - static std::unique_ptr inst; + static std::unique_ptr inst; virtual int create(std::string addrstr, std::string passwd) = 0; virtual int join(std::string addrstr, std::string passwd) = 0; - virtual bool SNetReceiveMessage(int *sender, char **data, int *size) = 0; virtual bool SNetSendMessage(int dest, void *data, unsigned int size) = 0; virtual bool SNetReceiveTurns(char **data, unsigned int *size, DWORD *status) = 0; @@ -20,76 +18,25 @@ public: virtual int SNetGetProviderCaps(struct _SNETCAPS *caps) = 0; virtual void *SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) = 0; virtual void *SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) = 0; - - virtual ~devilution_net() {} + virtual ~dvlnet() {} }; -class devilution_net_single : public devilution_net { +class dvlnet_null: public dvlnet { private: std::queue message_queue; buffer_t message_last; const int plr_single = 0; public: - virtual int create(std::string addrstr, std::string passwd) - { - return plr_single; - } - - virtual int join(std::string addrstr, std::string passwd) - { - ABORT(); - } - - virtual bool SNetReceiveMessage(int *sender, char **data, int *size) - { - if (message_queue.empty()) - return false; - message_last = message_queue.front(); - message_queue.pop(); - *sender = plr_single; - *size = message_last.size(); - *data = reinterpret_cast(message_last.data()); - return true; - } - - virtual bool SNetSendMessage(int dest, void *data, unsigned int size) - { - if (dest == plr_single || dest == SNPLAYER_ALL) { - auto raw_message = reinterpret_cast(data); - buffer_t message(raw_message, raw_message + size); - message_queue.push(message); - } - return true; - } - - virtual bool SNetReceiveTurns(char **data, unsigned int *size, DWORD *status) - { - // todo: check that this is safe - return true; - } - virtual bool SNetSendTurn(char *data, unsigned int size) - { - // todo: check that this is safe - return true; - } - virtual int SNetGetProviderCaps(struct _SNETCAPS *caps) - { - // todo: check that this is safe - return true; - } - virtual void *SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) - { - // not called in real singleplayer mode - // not needed in pseudo multiplayer mode (?) - return this; - } - virtual void *SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) - { - // not called in real singleplayer mode - // not needed in pseudo multiplayer mode (?) - return this; - } + virtual int create(std::string addrstr, std::string passwd); + virtual int join(std::string addrstr, std::string passwd); + virtual bool SNetReceiveMessage(int *sender, char **data, int *size); + virtual bool SNetSendMessage(int dest, void *data, unsigned int size); + virtual bool SNetReceiveTurns(char **data, unsigned int *size, DWORD *status); + virtual bool SNetSendTurn(char *data, unsigned int size); + virtual int SNetGetProviderCaps(struct _SNETCAPS *caps); + virtual void *SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)); + virtual void *SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)); }; // exact meaning yet to be worked out @@ -97,9 +44,9 @@ public: #define PS_ACTIVE 0x40000 #define PS_CONNECTED 0x10000 -class devilution_net_udp : public devilution_net { +class dvlnet_udp : public dvlnet { public: - devilution_net_udp(buffer_t info); + dvlnet_udp(buffer_t info); virtual int create(std::string addrstr, std::string passwd); virtual int join(std::string addrstr, std::string passwd); @@ -124,23 +71,12 @@ public: typedef uint32_t cookie_t; typedef int turn_t; // change int to something else in devilution code later typedef std::array key_t; - class packet_exception : public std::exception { - }; + class packet_exception : public std::exception {}; typedef asio::ip::udp::endpoint endpoint; static const endpoint none; class packet { - private: - class encrypt_mode_t { - }; - class decrypt_mode_t { - }; - - bool have_encrypted = false; - bool have_decrypted = false; - - const key_t &key; - + protected: packet_type m_type; plr_t m_src; plr_t m_dest; @@ -151,34 +87,14 @@ public: plr_t m_oldplr; buffer_t m_info; + const key_t &key; + bool have_encrypted = false; + bool have_decrypted = false; buffer_t encrypted_buffer; buffer_t decrypted_buffer; - template - void process_data(); - template - void process_element(encrypt_mode_t, T &x); - template - void process_element(decrypt_mode_t, T &x); - void process_element(encrypt_mode_t, buffer_t &x); - void process_element(decrypt_mode_t, buffer_t &x); - template - static const unsigned char *begin(const T &x); - template - static const unsigned char *end(const T &x); - public: - packet(const key_t &k) - : key(k) - { - } - - void create(packet_type t, plr_t s, plr_t d, buffer_t m); - void create(packet_type t, plr_t s, plr_t d, turn_t u); - void create(packet_type t, plr_t s, plr_t d, cookie_t c); - void create(packet_type t, plr_t s, plr_t d, cookie_t c, plr_t n, buffer_t i); - void create(packet_type t, plr_t s, plr_t d, plr_t o); - void create(std::vector buf); + packet(const key_t &k) : key(k) {}; const buffer_t &data(); @@ -192,10 +108,37 @@ public: plr_t oldplr(); const buffer_t &info(); - void encrypt(); + template void process_data(P &self); + }; + + class packet_in : public packet { + public: + using packet::packet; + void create(buffer_t buf); + void process_element(buffer_t &x); + template void process_element(T &x); void decrypt(); }; + class packet_out : public packet { + public: + using packet::packet; + void create(packet_type t, plr_t s, plr_t d, buffer_t m); + void create(packet_type t, plr_t s, plr_t d, turn_t u); + void create(packet_type t, plr_t s, plr_t d, cookie_t c); + void create(packet_type t, plr_t s, plr_t d, cookie_t c, plr_t n, buffer_t i); + void create(packet_type t, plr_t s, plr_t d, plr_t o); + void process_element(buffer_t &x); + template void process_element(T &x); + template static const unsigned char *begin(const T &x); + template static const unsigned char *end(const T &x); + void encrypt(); + }; + + typedef std::unique_ptr upacket; + upacket make_packet(buffer_t buf); + template upacket make_packet(T t, Args... args); + private: static constexpr unsigned short default_port = 6112; static constexpr unsigned short try_ports = 512; @@ -234,54 +177,63 @@ private: unsigned short bind(); void setup_password(std::string pw); - void handle_join_request(packet &pkt, endpoint sender); - void handle_accept(packet &pkt); + void handle_join_request(upacket &pkt, endpoint sender); + void handle_accept(upacket &pkt); void recv(); - void send(packet &pkt, endpoint sender = none); - void recv_decrypted(packet &pkt, endpoint sender); + void send(upacket &pkt, endpoint sender = none); + void recv_decrypted(upacket &pkt, endpoint sender); std::set dests_for_addr(plr_t dest, endpoint sender); void run_event_handler(_SNETEVENT &ev); }; -template -void devilution_net_udp::packet::process_data() +template void dvlnet_udp::packet::process_data(P &self) { - process_element(mode(), m_type); - process_element(mode(), m_src); - process_element(mode(), m_dest); + self.process_element(m_type); + self.process_element(m_src); + self.process_element(m_dest); switch (m_type) { case PT_MESSAGE: - process_element(mode(), m_message); + self.process_element(m_message); break; case PT_TURN: - process_element(mode(), m_turn); + self.process_element(m_turn); break; case PT_JOIN_REQUEST: - process_element(mode(), m_cookie); + self.process_element(m_cookie); break; case PT_JOIN_ACCEPT: - process_element(mode(), m_cookie); - process_element(mode(), m_newplr); - process_element(mode(), m_info); + self.process_element(m_cookie); + self.process_element(m_newplr); + self.process_element(m_info); break; case PT_LEAVE_GAME: break; } } -template -void devilution_net_udp::packet::process_element(encrypt_mode_t, T &x) +inline dvlnet_udp::upacket dvlnet_udp::make_packet(buffer_t buf) { - encrypted_buffer.insert(encrypted_buffer.end(), begin(x), end(x)); + auto ret = std::make_unique(key); + ret->create(std::move(buf)); + ret->decrypt(); + return ret; } -inline void devilution_net_udp::packet::process_element(encrypt_mode_t, buffer_t &x) +template dvlnet_udp::upacket dvlnet_udp::make_packet(T t, Args... args) { - encrypted_buffer.insert(encrypted_buffer.end(), x.begin(), x.end()); + auto ret = std::make_unique(key); + ret->create(t, args...); + ret->encrypt(); + return ret; } -template -void devilution_net_udp::packet::process_element(decrypt_mode_t, T &x) +inline void dvlnet_udp::packet_in::process_element(buffer_t &x) +{ + x.insert(x.begin(), decrypted_buffer.begin(), decrypted_buffer.end()); + decrypted_buffer.resize(0); +} + +template void dvlnet_udp::packet_in::process_element(T &x) { if (decrypted_buffer.size() < sizeof(T)) throw packet_exception(); @@ -289,20 +241,22 @@ void devilution_net_udp::packet::process_element(decrypt_mode_t, T &x) decrypted_buffer.erase(decrypted_buffer.begin(), decrypted_buffer.begin() + sizeof(T)); } -inline void devilution_net_udp::packet::process_element(decrypt_mode_t, buffer_t &x) +inline void dvlnet_udp::packet_out::process_element(buffer_t &x) { - x.insert(x.begin(), decrypted_buffer.begin(), decrypted_buffer.end()); - decrypted_buffer.resize(0); + encrypted_buffer.insert(encrypted_buffer.end(), x.begin(), x.end()); +} + +template void dvlnet_udp::packet_out::process_element(T &x) +{ + encrypted_buffer.insert(encrypted_buffer.end(), begin(x), end(x)); } -template -const unsigned char *devilution_net_udp::packet::begin(const T &x) +template const unsigned char *dvlnet_udp::packet_out::begin(const T &x) { return reinterpret_cast(&x); } -template -const unsigned char *devilution_net_udp::packet::end(const T &x) +template const unsigned char *dvlnet_udp::packet_out::end(const T &x) { return reinterpret_cast(&x) + sizeof(T); } diff --git a/Stub/dvlnet_null.cpp b/Stub/dvlnet_null.cpp new file mode 100644 index 000000000..3cc36fe10 --- /dev/null +++ b/Stub/dvlnet_null.cpp @@ -0,0 +1,67 @@ +#include "../types.h" + +std::unique_ptr dvlnet::inst; + +int dvlnet_null::create(std::string addrstr, std::string passwd) +{ + return plr_single; +} + +int dvlnet_null::join(std::string addrstr, std::string passwd) +{ + ABORT(); +} + +bool dvlnet_null::SNetReceiveMessage(int *sender, char **data, int *size) +{ + if (message_queue.empty()) + return false; + message_last = message_queue.front(); + message_queue.pop(); + *sender = plr_single; + *size = message_last.size(); + *data = reinterpret_cast(message_last.data()); + return true; +} + +bool dvlnet_null::SNetSendMessage(int dest, void *data, unsigned int size) +{ + if (dest == plr_single || dest == SNPLAYER_ALL) { + auto raw_message = reinterpret_cast(data); + buffer_t message(raw_message, raw_message + size); + message_queue.push(message); + } + return true; + } + +bool dvlnet_null::SNetReceiveTurns(char **data, unsigned int *size, DWORD *status) +{ + // todo: check that this is safe + return true; +} + +bool dvlnet_null::SNetSendTurn(char *data, unsigned int size) +{ + // todo: check that this is safe + return true; +} + +int dvlnet_null::SNetGetProviderCaps(struct _SNETCAPS *caps) +{ + // todo: check that this is safe + return true; +} + +void *dvlnet_null::SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) +{ + // not called in real singleplayer mode + // not needed in pseudo multiplayer mode (?) + return this; +} + +void *dvlnet_null::SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) +{ + // not called in real singleplayer mode + // not needed in pseudo multiplayer mode (?) + return this; +} diff --git a/Stub/dvlnet_udp.cpp b/Stub/dvlnet_udp.cpp new file mode 100644 index 000000000..652dc054f --- /dev/null +++ b/Stub/dvlnet_udp.cpp @@ -0,0 +1,297 @@ +#include "../types.h" + +const dvlnet_udp::endpoint dvlnet_udp::none; + +dvlnet_udp::dvlnet_udp(buffer_t info) +{ + if (sodium_init() < 0) + abort(); + game_init_info = std::move(info); +} + +int dvlnet_udp::create(std::string addrstr, std::string passwd) +{ + sock = asio::ip::udp::socket(context); // to be removed later + setup_password(passwd); + auto ipaddr = asio::ip::make_address(addrstr); + if (ipaddr.is_v4()) + sock.open(asio::ip::udp::v4()); + else if (ipaddr.is_v6()) + sock.open(asio::ip::udp::v6()); + sock.non_blocking(true); + unsigned short port = default_port; + /* + while(port <= default_port+try_ports) { + try { + sock.bind(asio::ip::udp::endpoint(asio::ip::address_v6(), port)); + } catch (std::exception e) { + eprintf("bind: %s, %s\n", asio::ip::address_v6().to_string(), e.what()); + } + ++port; + } + */ + try { + sock.bind(endpoint(ipaddr, port)); + } catch (std::exception e) { + return -1; + } + plr_self = 0; + return plr_self; +} + +int dvlnet_udp::join(std::string addrstr, std::string passwd) +{ + setup_password(passwd); + auto ipaddr = asio::ip::make_address(addrstr); + endpoint themaster(ipaddr, default_port); + sock.connect(themaster); + master = themaster; + { // hack: try to join for 5 seconds + randombytes_buf(reinterpret_cast(&cookie_self), + sizeof(cookie_t)); + upacket pkt = make_packet(PT_JOIN_REQUEST, ADDR_BROADCAST, ADDR_MASTER, cookie_self); + send(pkt); + for (auto i = 0; i < 5; ++i) { + recv(); + if (plr_self != ADDR_BROADCAST) + break; // join successful + sleep(1); + } + } + return (plr_self == ADDR_BROADCAST ? 4 : plr_self); +} + +void dvlnet_udp::setup_password(std::string pw) +{ + //pw.resize(std::min(pw.size(), crypto_pwhash_PASSWD_MAX)); + //pw.resize(std::max(pw.size(), crypto_pwhash_PASSWD_MIN), 0); + std::string salt("devilution-salt"); + salt.resize(crypto_pwhash_SALTBYTES, 0); + if (crypto_pwhash(key.data(), crypto_secretbox_KEYBYTES, + pw.data(), pw.size(), + reinterpret_cast(salt.data()), + crypto_pwhash_OPSLIMIT_INTERACTIVE, + crypto_pwhash_MEMLIMIT_INTERACTIVE, + crypto_pwhash_ALG_DEFAULT)) + ABORT(); +} + +void dvlnet_udp::recv() +{ + try { + while (1) { // read until kernel buffer is empty? + try { + endpoint sender; + buffer_t pkt_buf(max_packet_size); + size_t pkt_len; + pkt_len = sock.receive_from(asio::buffer(pkt_buf), sender); + pkt_buf.resize(pkt_len); + upacket pkt = make_packet(pkt_buf); + recv_decrypted(pkt, sender); + } catch (packet_exception e) { + // drop packet + } + } + } catch (std::exception e) { + return; + } +} + +void dvlnet_udp::send(dvlnet_udp::upacket &pkt, endpoint sender) +{ + for (auto &dest : dests_for_addr(pkt->dest(), sender)) { + sock.send_to(asio::buffer(pkt->data()), dest); + } +} + +std::set dvlnet_udp::dests_for_addr(plr_t dest, endpoint sender) +{ + auto ret = std::set(); + if (dest == plr_self) + return ret; + + if (0 <= dest && dest < MAX_PLRS) { + if (active_table[dest]) + ret.insert(nexthop_table[dest]); + } else if (dest == ADDR_BROADCAST) { + for (auto i = 0; i < MAX_PLRS; ++i) + if (i != plr_self && active_table[i]) + ret.insert(nexthop_table[i]); + ret.insert(connection_requests_pending.begin(), connection_requests_pending.end()); + } else if (dest == ADDR_MASTER) { + if (master != none) + ret.insert(master); + } + ret.erase(sender); + return ret; +} + +void dvlnet_udp::handle_join_request(upacket &pkt, endpoint sender) +{ + plr_t i; + for (i = 0; i < MAX_PLRS; ++i) { + if (i != plr_self && nexthop_table[i] == none) { + nexthop_table[i] = sender; + break; + } + } + upacket reply = make_packet(PT_JOIN_ACCEPT, plr_self, ADDR_BROADCAST, pkt->cookie(), i, game_init_info); + send(reply); +} + +void dvlnet_udp::run_event_handler(_SNETEVENT &ev) +{ + /* disable until UI ready + auto f = registered_handlers[static_cast(ev.eventid)]; + if(f) { + printf("RUNNING HANDLER"); + f(&ev); + } + */ +} + +void dvlnet_udp::handle_accept(upacket &pkt) +{ + if (plr_self != ADDR_BROADCAST) + return; // already have player id + if (pkt->cookie() == cookie_self) + plr_self = pkt->newplr(); + _SNETEVENT ev; + ev.eventid = EVENT_TYPE_PLAYER_CREATE_GAME; + ev.playerid = plr_self; + ev.data = pkt->info().data(); + ev.databytes = pkt->info().size(); + printf("GOT SEED!!"); + run_event_handler(ev); +} + +void dvlnet_udp::recv_decrypted(upacket &pkt, endpoint sender) +{ + // 1. route + send(pkt, sender); + // 2. handle local + if (pkt->src() == ADDR_BROADCAST && pkt->dest() == ADDR_MASTER) { + connection_requests_pending.insert(sender); + if (master == none) { + handle_join_request(pkt, sender); + } + } + // normal packets + if (pkt->src() < 0 || pkt->src() >= MAX_PLRS) + return; //drop packet + if (active_table[pkt->src()]) { //WRONG?!? + if (sender != nexthop_table[pkt->src()]) + return; //rpfilter fail: drop packet + } else { + nexthop_table[pkt->src()] = sender; // new connection: accept + } + active_table[pkt->src()] = ACTIVE; + if (pkt->dest() != plr_self && pkt->dest() != ADDR_BROADCAST) + return; //packet not for us, drop + switch (pkt->type()) { + case PT_MESSAGE: + message_queue.push(message_t(pkt->src(), pkt->message())); + break; + case PT_TURN: + turn_last[pkt->src()] = pkt->turn(); + turn_new[pkt->src()] = true; + break; + case PT_JOIN_ACCEPT: + handle_accept(pkt); + break; + case PT_LEAVE_GAME: + // todo + break; + // otherwise drop + } +} + +bool dvlnet_udp::SNetReceiveMessage(int *sender, char **data, int *size) +{ + recv(); + if (message_queue.empty()) + return false; + message_last = message_queue.front(); + message_queue.pop(); + *sender = message_last.sender; + *size = message_last.payload.size(); + *data = reinterpret_cast(message_last.payload.data()); + return true; +} + +bool dvlnet_udp::SNetSendMessage(int playerID, void *data, unsigned int size) +{ + if (playerID != SNPLAYER_ALL && playerID != SNPLAYER_OTHERS && (playerID < 0 || playerID >= MAX_PLRS)) + abort(); + auto raw_message = reinterpret_cast(data); + buffer_t message(raw_message, raw_message + size); + if (playerID == plr_self || playerID == SNPLAYER_ALL) + message_queue.push(message_t(plr_self, message)); + plr_t dest; + if (playerID == SNPLAYER_ALL || playerID == SNPLAYER_OTHERS) + dest = ADDR_BROADCAST; + else + dest = playerID; + upacket pkt = make_packet(PT_MESSAGE, plr_self, dest, message); + send(pkt); + return true; +} + +bool dvlnet_udp::SNetReceiveTurns(char **data, unsigned int *size, DWORD *status) +{ + recv(); + for (auto i = 0; i < MAX_PLRS; ++i) { + status[i] = 0; + if (i == plr_self || nexthop_table[i] != none) { + status[i] |= (PS_ACTIVE | PS_CONNECTED); + } + size[i] = sizeof(turn_t); + if (turn_new[i] = true) { + status[i] |= PS_HASMSG; + data[i] = reinterpret_cast(&turn_last[i]); + turn_new[i] = false; + } + } + return true; +} + +bool dvlnet_udp::SNetSendTurn(char *data, unsigned int size) +{ + if (size != sizeof(turn_t)) + ABORT(); + upacket pkt = make_packet(PT_TURN, plr_self, ADDR_BROADCAST, *reinterpret_cast(data)); + send(pkt); + return true; +} + +int dvlnet_udp::SNetGetProviderCaps(struct _SNETCAPS *caps) +{ + caps->size = 0; // engine writes only ?!? + caps->flags = 0; // unused + caps->maxmessagesize = 512; // capped to 512; underflow if < 24 + caps->maxqueuesize = 0; // unused + caps->maxplayers = MAX_PLRS; // capped to 4 + caps->bytessec = 1000000; // ? + caps->latencyms = 0; // unused + caps->defaultturnssec = 10; // ? + caps->defaultturnsintransit = 1; // maximum acceptable number of turns in queue? + return 1; +} + + +void *dvlnet_udp::SNetUnregisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) +{ + registered_handlers.erase(evtype); + return (void*)func; +} + +void *dvlnet_udp::SNetRegisterEventHandler(event_type evtype, void(__stdcall *func)(struct _SNETEVENT *)) +{ + registered_handlers[evtype] = func; + return (void*)func; + // need to handle: + // EVENT_TYPE_PLAYER_LEAVE_GAME + // EVENT_TYPE_PLAYER_CREATE_GAME (raised during SNetCreateGame?) + // EVENT_TYPE_PLAYER_MESSAGE + // all by the same function +} diff --git a/Stub/dvlnet_udp_packet.cpp b/Stub/dvlnet_udp_packet.cpp new file mode 100644 index 000000000..c09964ea8 --- /dev/null +++ b/Stub/dvlnet_udp_packet.cpp @@ -0,0 +1,230 @@ +#include "../types.h" + +static constexpr bool disable_encryption = false; + +const dvlnet_udp::buffer_t &dvlnet_udp::packet::data() +{ + if (!have_decrypted || !have_encrypted) + ABORT(); + return encrypted_buffer; +} + +dvlnet_udp::packet_type dvlnet_udp::packet::type() +{ + if (!have_decrypted) + ABORT(); + return m_type; +} + +dvlnet_udp::plr_t dvlnet_udp::packet::src() +{ + if (!have_decrypted) + ABORT(); + return m_src; +} + +dvlnet_udp::plr_t dvlnet_udp::packet::dest() +{ + if (!have_decrypted) + ABORT(); + return m_dest; +} + +const dvlnet_udp::buffer_t &dvlnet_udp::packet::message() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_MESSAGE) + throw dvlnet_udp::packet_exception(); + return m_message; +} + +dvlnet_udp::turn_t dvlnet_udp::packet::turn() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_TURN) + throw dvlnet_udp::packet_exception(); + return m_turn; +} + +dvlnet_udp::cookie_t dvlnet_udp::packet::cookie() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_JOIN_REQUEST && m_type != PT_JOIN_ACCEPT) + throw dvlnet_udp::packet_exception(); + return m_cookie; +} + +dvlnet_udp::plr_t dvlnet_udp::packet::newplr() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_JOIN_ACCEPT) + throw dvlnet_udp::packet_exception(); + return m_newplr; +} + +dvlnet_udp::plr_t dvlnet_udp::packet::oldplr() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_LEAVE_GAME) + throw dvlnet_udp::packet_exception(); + return m_oldplr; +} + +const dvlnet_udp::buffer_t &dvlnet_udp::packet::info() +{ + if (!have_decrypted) + ABORT(); + if (m_type != PT_JOIN_ACCEPT) + throw dvlnet_udp::packet_exception(); + return m_info; +} + +void dvlnet_udp::packet_in::create(dvlnet_udp::buffer_t buf) +{ + if (have_encrypted || have_decrypted) + ABORT(); + encrypted_buffer = std::move(buf); + have_encrypted = true; +} + +void dvlnet_udp::packet_in::decrypt() +{ + if (!have_encrypted) + ABORT(); + if (have_decrypted) + return; + if (!disable_encryption) { + if (encrypted_buffer.size() < crypto_secretbox_NONCEBYTES + + crypto_secretbox_MACBYTES + sizeof(packet_type) + 2 * sizeof(plr_t)) + throw dvlnet_udp::packet_exception(); + auto pktlen = encrypted_buffer.size() - crypto_secretbox_NONCEBYTES - crypto_secretbox_MACBYTES; + decrypted_buffer.resize(pktlen); + if (crypto_secretbox_open_easy(decrypted_buffer.data(), + encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, + encrypted_buffer.size() - crypto_secretbox_NONCEBYTES, + encrypted_buffer.data(), + key.data())) + throw dvlnet_udp::packet_exception(); + } else { + if (encrypted_buffer.size() < sizeof(packet_type) + 2 * sizeof(plr_t)) + throw dvlnet_udp::packet_exception(); + decrypted_buffer = encrypted_buffer; + } + + process_data(*this); + + have_decrypted = true; +} + +void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, + dvlnet_udp::plr_t s, + dvlnet_udp::plr_t d, + dvlnet_udp::buffer_t m) +{ + if (have_encrypted || have_decrypted) + ABORT(); + if (t != PT_MESSAGE) + ABORT(); + have_decrypted = true; + m_type = t; + m_src = s; + m_dest = d; + m_message = std::move(m); +} + +void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, + dvlnet_udp::plr_t s, + dvlnet_udp::plr_t d, + dvlnet_udp::turn_t u) +{ + if (have_encrypted || have_decrypted) + ABORT(); + if (t != PT_TURN) + ABORT(); + have_decrypted = true; + m_type = t; + m_src = s; + m_dest = d; + m_turn = u; +} + +void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, + dvlnet_udp::plr_t s, + dvlnet_udp::plr_t d, + dvlnet_udp::cookie_t c) +{ + if (have_encrypted || have_decrypted) + ABORT(); + if (t != PT_JOIN_REQUEST) + ABORT(); + have_decrypted = true; + m_type = t; + m_src = s; + m_dest = d; + m_cookie = c; +} + +void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, + dvlnet_udp::plr_t s, + dvlnet_udp::plr_t d, + dvlnet_udp::cookie_t c, + dvlnet_udp::plr_t n, + dvlnet_udp::buffer_t i) +{ + if (have_encrypted || have_decrypted) + ABORT(); + if (t != PT_JOIN_ACCEPT) + ABORT(); + have_decrypted = true; + m_type = t; + m_src = s; + m_dest = d; + m_cookie = c; + m_newplr = n; + m_info = i; +} + +void dvlnet_udp::packet_out::create(dvlnet_udp::packet_type t, + dvlnet_udp::plr_t s, + dvlnet_udp::plr_t d, + dvlnet_udp::plr_t o) +{ + if (have_encrypted || have_decrypted) + ABORT(); + if (t != PT_LEAVE_GAME) + ABORT(); + have_decrypted = true; + m_type = t; + m_src = s; + m_dest = d; + m_oldplr = o; +} + +void dvlnet_udp::packet_out::encrypt() +{ + if (!have_decrypted) + ABORT(); + if (have_encrypted) + return; + + process_data(*this); + + if (!disable_encryption) { + auto len_cleartext = encrypted_buffer.size(); + encrypted_buffer.insert(encrypted_buffer.begin(), crypto_secretbox_NONCEBYTES, 0); + encrypted_buffer.insert(encrypted_buffer.end(), crypto_secretbox_MACBYTES, 0); + randombytes_buf(encrypted_buffer.data(), crypto_secretbox_NONCEBYTES); + if (crypto_secretbox_easy(encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, + encrypted_buffer.data() + crypto_secretbox_NONCEBYTES, + len_cleartext, + encrypted_buffer.data(), + key.data())) + ABORT(); + } + have_encrypted = true; +} diff --git a/Stub/storm_net.cpp b/Stub/storm_net.cpp index 6e7d032ce..5f871120d 100644 --- a/Stub/storm_net.cpp +++ b/Stub/storm_net.cpp @@ -2,7 +2,7 @@ BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes) { - if (!devilution_net::inst->SNetReceiveMessage(senderplayerid, data, databytes)) { + if (!dvlnet::inst->SNetReceiveMessage(senderplayerid, data, databytes)) { SErrSetLastError(STORM_ERROR_NO_MESSAGES_WAITING); return FALSE; } @@ -11,7 +11,7 @@ BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databyte BOOL STORMAPI SNetSendMessage(int playerID, void *data, unsigned int databytes) { - return devilution_net::inst->SNetSendMessage(playerID, data, databytes); + return dvlnet::inst->SNetSendMessage(playerID, data, databytes); } BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, @@ -21,27 +21,27 @@ BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned UNIMPLEMENTED(); if (arraysize != MAX_PLRS) UNIMPLEMENTED(); - return devilution_net::inst->SNetReceiveTurns(arraydata, arraydatabytes, arrayplayerstatus); + return dvlnet::inst->SNetReceiveTurns(arraydata, arraydatabytes, arrayplayerstatus); } BOOL STORMAPI SNetSendTurn(char *data, unsigned int databytes) { - return devilution_net::inst->SNetSendTurn(data, databytes); + return dvlnet::inst->SNetSendTurn(data, databytes); } int __stdcall SNetGetProviderCaps(struct _SNETCAPS *caps) { - return devilution_net::inst->SNetGetProviderCaps(caps); + return dvlnet::inst->SNetGetProviderCaps(caps); } void *__stdcall SNetUnregisterEventHandler(int evtype, void(__stdcall *func)(struct _SNETEVENT *)) { - return devilution_net::inst->SNetUnregisterEventHandler(evtype, func); + return dvlnet::inst->SNetUnregisterEventHandler(evtype, func); } void *__stdcall SNetRegisterEventHandler(int evtype, void(__stdcall *func)(struct _SNETEVENT *)) { - return devilution_net::inst->SNetRegisterEventHandler(evtype, func); + return dvlnet::inst->SNetRegisterEventHandler(evtype, func); } BOOL STORMAPI SNetDestroy() @@ -83,11 +83,11 @@ int __stdcall SNetInitializeProvider(unsigned long provider, struct _SNETPROGRAM struct _SNETVERSIONDATA *fileinfo) { if (provider == 'UDPN') { - devilution_net::buffer_t game_init_info((char*)client_info->initdata, + dvlnet::buffer_t game_init_info((char*)client_info->initdata, (char*)client_info->initdata + client_info->initdatabytes); - devilution_net::inst = std::make_unique(std::move(game_init_info)); + dvlnet::inst = std::make_unique(std::move(game_init_info)); } else if (provider == 'SCBL' || provider == 0) { - devilution_net::inst = std::make_unique(); + dvlnet::inst = std::make_unique(); } else { ABORT(); } @@ -108,8 +108,8 @@ BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePasswor // hack: cannot create game until UI is ready // first instance will create, second will join int ret; - if (ret = devilution_net::inst->create("0.0.0.0", "mypass") == -1) - ret = devilution_net::inst->join("127.0.0.1", "mypass"); + if (ret = dvlnet::inst->create("0.0.0.0", "mypass") == -1) + ret = dvlnet::inst->join("127.0.0.1", "mypass"); *playerID = ret; return TRUE; } diff --git a/types.h b/types.h index 2a8a66c23..cefc5c87e 100644 --- a/types.h +++ b/types.h @@ -56,7 +56,7 @@ #include "3rdParty/PKWare/pkware.h" #ifdef MINIWIN -#include "devilution_net.h" +#include "dvlnet.h" #endif // If defined, use copy protection [Default -> Defined]