diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 7d2950d570..5019159b23 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -6,6 +6,9 @@ set(SRCS Config/Config.cpp Config/Layer.cpp Config/Section.cpp + Crypto/AES.cpp + Crypto/bn.cpp + Crypto/ec.cpp ENetUtil.cpp File.cpp FileSearch.cpp @@ -15,7 +18,9 @@ set(SRCS HttpRequest.cpp IniFile.cpp JitRegister.cpp + Logging/LogManager.cpp MathUtil.cpp + MD5.cpp MemArena.cpp MemoryUtil.cpp MsgHandler.cpp @@ -32,14 +37,10 @@ set(SRCS Thread.cpp Timer.cpp TraversalClient.cpp + UPnP.cpp Version.cpp x64ABI.cpp x64Emitter.cpp - MD5.cpp - Crypto/AES.cpp - Crypto/bn.cpp - Crypto/ec.cpp - Logging/LogManager.cpp ) set(LIBS ${LIBS} ${MBEDTLS_LIBRARIES}) diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj index 9466fda774..651808e5f7 100644 --- a/Source/Core/Common/Common.vcxproj +++ b/Source/Core/Common/Common.vcxproj @@ -151,6 +151,7 @@ + @@ -202,6 +203,7 @@ + diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters index 4b48650ec1..c7ceb7adcb 100644 --- a/Source/Core/Common/Common.vcxproj.filters +++ b/Source/Core/Common/Common.vcxproj.filters @@ -94,6 +94,7 @@ + GL @@ -307,6 +308,7 @@ + Logging diff --git a/Source/Core/Common/UPnP.cpp b/Source/Core/Common/UPnP.cpp new file mode 100644 index 0000000000..47c4cf8337 --- /dev/null +++ b/Source/Core/Common/UPnP.cpp @@ -0,0 +1,169 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#ifdef USE_UPNP + +#include "Common/UPnP.h" + +#include "Common/Logging/Log.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static UPNPUrls s_urls; +static IGDdatas s_data; +static std::array s_our_ip; +static u16 s_mapped = 0; +static std::thread s_thread; + +// called from ---UPnP--- thread +// discovers the IGD +static bool InitUPnP() +{ + static bool s_inited = false; + static bool s_error = false; + + // Don't init if already inited + if (s_inited) + return true; + + // Don't init if it failed before + if (s_error) + return false; + + s_urls = {}; + s_data = {}; + + // Find all UPnP devices + int upnperror = 0; + std::unique_ptr devlist(nullptr, freeUPNPDevlist); +#if MINIUPNPC_API_VERSION >= 14 + devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror)); +#else + devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, &upnperror)); +#endif + if (!devlist) + { + WARN_LOG(NETPLAY, "An error occurred trying to discover UPnP devices."); + + s_error = true; + + return false; + } + + // Look for the IGD + for (UPNPDev* dev = devlist.get(); dev; dev = dev->pNext) + { + if (!std::strstr(dev->st, "InternetGatewayDevice")) + continue; + + int desc_xml_size = 0; + std::unique_ptr desc_xml(nullptr, std::free); + int statusCode = 200; +#if MINIUPNPC_API_VERSION >= 16 + desc_xml.reset( + static_cast(miniwget_getaddr(dev->descURL, &desc_xml_size, s_our_ip.data(), + static_cast(s_our_ip.size()), 0, &statusCode))); +#else + desc_xml.reset(static_cast(miniwget_getaddr( + dev->descURL, &desc_xml_size, s_our_ip.data(), static_cast(s_our_ip.size()), 0))); +#endif + if (desc_xml && statusCode == 200) + { + parserootdesc(desc_xml.get(), desc_xml_size, &s_data); + GetUPNPUrls(&s_urls, &s_data, dev->descURL, 0); + + NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL); + break; + } + else + { + WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL); + } + } + + s_inited = true; + + return true; +} + +// called from ---UPnP--- thread +// Attempt to stop portforwarding. +// -- +// NOTE: It is important that this happens! A few very crappy routers +// apparently do not delete UPnP mappings on their own, so if you leave them +// hanging, the NVRAM will fill with portmappings, and eventually all UPnP +// requests will fail silently, with the only recourse being a factory reset. +// -- +static bool UnmapPort(const u16 port) +{ + std::string port_str = std::to_string(port); + UPNP_DeletePortMapping(s_urls.controlURL, s_data.first.servicetype, port_str.c_str(), "UDP", + nullptr); + + return true; +} + +// called from ---UPnP--- thread +// Attempt to portforward! +static bool MapPort(const char* addr, const u16 port) +{ + if (s_mapped > 0) + UnmapPort(s_mapped); + + std::string port_str = std::to_string(port); + int result = UPNP_AddPortMapping( + s_urls.controlURL, s_data.first.servicetype, port_str.c_str(), port_str.c_str(), addr, + (std::string("dolphin-emu UDP on ") + addr).c_str(), "UDP", nullptr, nullptr); + + if (result != 0) + return false; + + s_mapped = port; + + return true; +} + +// UPnP thread: try to map a port +static void MapPortThread(const u16 port) +{ + if (InitUPnP() && MapPort(s_our_ip.data(), port)) + { + NOTICE_LOG(NETPLAY, "Successfully mapped port %d to %s.", port, s_our_ip.data()); + return; + } + + WARN_LOG(NETPLAY, "Failed to map port %d to %s.", port, s_our_ip.data()); +} + +// UPnP thread: try to unmap a port +static void UnmapPortThread() +{ + if (s_mapped > 0) + UnmapPort(s_mapped); +} + +void UPnP::TryPortmapping(u16 port) +{ + if (s_thread.joinable()) + s_thread.join(); + s_thread = std::thread(&MapPortThread, port); +} + +void UPnP::StopPortmapping() +{ + if (s_thread.joinable()) + s_thread.join(); + s_thread = std::thread(&UnmapPortThread); + s_thread.join(); +} + +#endif diff --git a/Source/Core/Common/UPnP.h b/Source/Core/Common/UPnP.h new file mode 100644 index 0000000000..d4d9191fb1 --- /dev/null +++ b/Source/Core/Common/UPnP.h @@ -0,0 +1,17 @@ +// Copyright 2017 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#ifdef USE_UPNP + +#include "Common/CommonTypes.h" + +namespace UPnP +{ +void TryPortmapping(u16 port); +void StopPortmapping(); +} + +#endif diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index b0c7f6fd16..2c98e18721 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -74,13 +74,12 @@ NetPlayClient::~NetPlayClient() // called from ---GUI--- thread NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, - const std::string& name, bool traversal, - const std::string& centralServer, u16 centralPort) + const std::string& name, const NetTraversalConfig& traversal_config) : m_dialog(dialog), m_player_name(name) { ClearBuffers(); - if (!traversal) + if (!traversal_config.use_traversal) { // Direct Connection m_client = enet_host_create(nullptr, 1, 3, 0, 0); @@ -124,7 +123,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlay return; } - if (!EnsureTraversalClient(centralServer, centralPort)) + if (!EnsureTraversalClient(traversal_config.traversal_host, traversal_config.traversal_port)) return; m_client = g_MainNetHost.get(); diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index 00decb8093..978cec9cb4 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -67,8 +67,7 @@ public: void SendAsync(sf::Packet&& packet); NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, - const std::string& name, bool traversal, const std::string& centralServer, - u16 centralPort); + const std::string& name, const NetTraversalConfig& traversal_config); ~NetPlayClient(); void GetPlayerList(std::string& list, std::vector& pid_list); diff --git a/Source/Core/Core/NetPlayProto.h b/Source/Core/Core/NetPlayProto.h index deb8d073c2..3172c7a1c8 100644 --- a/Source/Core/Core/NetPlayProto.h +++ b/Source/Core/Core/NetPlayProto.h @@ -27,6 +27,20 @@ struct NetSettings ExpansionInterface::TEXIDevices m_EXIDevice[2]; }; +struct NetTraversalConfig +{ + NetTraversalConfig() = default; + NetTraversalConfig(bool use_traversal_, std::string traversal_host_, u16 traversal_port_) + : use_traversal{use_traversal_}, traversal_host{std::move(traversal_host_)}, + traversal_port{traversal_port_} + { + } + + bool use_traversal = false; + std::string traversal_host; + u16 traversal_port = 0; +}; + extern NetSettings g_NetPlaySettings; extern u64 g_netplay_initial_rtc; diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 5eaddab1e2..238d1b48e9 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -18,6 +18,7 @@ #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/StringUtil.h" +#include "Common/UPnP.h" #include "Core/ConfigManager.h" #include "Core/HW/Sram.h" #include "Core/NetPlayClient.h" //for NetPlayUI @@ -57,16 +58,13 @@ NetPlayServer::~NetPlayServer() } #ifdef USE_UPNP - if (m_upnp_thread.joinable()) - m_upnp_thread.join(); - m_upnp_thread = std::thread(&NetPlayServer::unmapPortThread); - m_upnp_thread.join(); + UPnP::StopPortmapping(); #endif } // called from ---GUI--- thread -NetPlayServer::NetPlayServer(const u16 port, bool traversal, const std::string& centralServer, - u16 centralPort) +NetPlayServer::NetPlayServer(const u16 port, const bool forward_port, + const NetTraversalConfig& traversal_config) { //--use server time if (enet_initialize() != 0) @@ -77,9 +75,10 @@ NetPlayServer::NetPlayServer(const u16 port, bool traversal, const std::string& m_pad_map.fill(-1); m_wiimote_map.fill(-1); - if (traversal) + if (traversal_config.use_traversal) { - if (!EnsureTraversalClient(centralServer, centralPort, port)) + if (!EnsureTraversalClient(traversal_config.traversal_host, traversal_config.traversal_port, + port)) return; g_TraversalClient->m_Client = this; @@ -105,6 +104,11 @@ NetPlayServer::NetPlayServer(const u16 port, bool traversal, const std::string& m_do_loop = true; m_thread = std::thread(&NetPlayServer::ThreadFunc, this); m_target_buffer_size = 5; + +#ifdef USE_UPNP + if (forward_port) + UPnP::TryPortmapping(port); +#endif } } @@ -933,155 +937,3 @@ std::vector> NetPlayServer::GetInterfaceList result.emplace_back(std::make_pair("!local!", "127.0.0.1")); return result; } - -#ifdef USE_UPNP -#include -#include -#include - -struct UPNPUrls NetPlayServer::m_upnp_urls; -struct IGDdatas NetPlayServer::m_upnp_data; -std::string NetPlayServer::m_upnp_ourip; -u16 NetPlayServer::m_upnp_mapped = 0; -std::thread NetPlayServer::m_upnp_thread; - -// called from ---GUI--- thread -void NetPlayServer::TryPortmapping(u16 port) -{ - if (m_upnp_thread.joinable()) - m_upnp_thread.join(); - m_upnp_thread = std::thread(&NetPlayServer::mapPortThread, port); -} - -// UPnP thread: try to map a port -void NetPlayServer::mapPortThread(const u16 port) -{ - if (initUPnP() && UPnPMapPort(m_upnp_ourip, port)) - { - NOTICE_LOG(NETPLAY, "Successfully mapped port %d to %s.", port, m_upnp_ourip.c_str()); - return; - } - - WARN_LOG(NETPLAY, "Failed to map port %d to %s.", port, m_upnp_ourip.c_str()); -} - -// UPnP thread: try to unmap a port -void NetPlayServer::unmapPortThread() -{ - if (m_upnp_mapped > 0) - UPnPUnmapPort(m_upnp_mapped); -} - -// called from ---UPnP--- thread -// discovers the IGD -bool NetPlayServer::initUPnP() -{ - static bool s_inited = false; - static bool s_error = false; - - std::vector igds; - int descXMLsize = 0, upnperror = 0; - char cIP[20]; - - // Don't init if already inited - if (s_inited) - return true; - - // Don't init if it failed before - if (s_error) - return false; - - memset(&m_upnp_urls, 0, sizeof(UPNPUrls)); - memset(&m_upnp_data, 0, sizeof(IGDdatas)); - - // Find all UPnP devices - std::unique_ptr devlist(nullptr, freeUPNPDevlist); -#if MINIUPNPC_API_VERSION >= 14 - devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, 2, &upnperror)); -#else - devlist.reset(upnpDiscover(2000, nullptr, nullptr, 0, 0, &upnperror)); -#endif - if (!devlist) - { - WARN_LOG(NETPLAY, "An error occurred trying to discover UPnP devices."); - - s_error = true; - - return false; - } - - // Look for the IGD - for (UPNPDev* dev = devlist.get(); dev; dev = dev->pNext) - { - if (strstr(dev->st, "InternetGatewayDevice")) - igds.push_back(dev); - } - - for (const UPNPDev* dev : igds) - { - std::unique_ptr descXML(nullptr, std::free); - int statusCode = 200; -#if MINIUPNPC_API_VERSION >= 16 - descXML.reset(static_cast( - miniwget_getaddr(dev->descURL, &descXMLsize, cIP, sizeof(cIP), 0, &statusCode))); -#else - descXML.reset( - static_cast(miniwget_getaddr(dev->descURL, &descXMLsize, cIP, sizeof(cIP), 0))); -#endif - if (descXML && statusCode == 200) - { - parserootdesc(descXML.get(), descXMLsize, &m_upnp_data); - GetUPNPUrls(&m_upnp_urls, &m_upnp_data, dev->descURL, 0); - - m_upnp_ourip = cIP; - - NOTICE_LOG(NETPLAY, "Got info from IGD at %s.", dev->descURL); - break; - } - else - { - WARN_LOG(NETPLAY, "Error getting info from IGD at %s.", dev->descURL); - } - } - - s_inited = true; - return true; -} - -// called from ---UPnP--- thread -// Attempt to portforward! -bool NetPlayServer::UPnPMapPort(const std::string& addr, const u16 port) -{ - if (m_upnp_mapped > 0) - UPnPUnmapPort(m_upnp_mapped); - - std::string port_str = StringFromFormat("%d", port); - int result = UPNP_AddPortMapping( - m_upnp_urls.controlURL, m_upnp_data.first.servicetype, port_str.c_str(), port_str.c_str(), - addr.c_str(), (std::string("dolphin-emu UDP on ") + addr).c_str(), "UDP", nullptr, nullptr); - - if (result != 0) - return false; - - m_upnp_mapped = port; - - return true; -} - -// called from ---UPnP--- thread -// Attempt to stop portforwarding. -// -- -// NOTE: It is important that this happens! A few very crappy routers -// apparently do not delete UPnP mappings on their own, so if you leave them -// hanging, the NVRAM will fill with portmappings, and eventually all UPnP -// requests will fail silently, with the only recourse being a factory reset. -// -- -bool NetPlayServer::UPnPUnmapPort(const u16 port) -{ - std::string port_str = StringFromFormat("%d", port); - UPNP_DeletePortMapping(m_upnp_urls.controlURL, m_upnp_data.first.servicetype, port_str.c_str(), - "UDP", nullptr); - - return true; -} -#endif diff --git a/Source/Core/Core/NetPlayServer.h b/Source/Core/Core/NetPlayServer.h index a4adacdcba..84bb2fba6e 100644 --- a/Source/Core/Core/NetPlayServer.h +++ b/Source/Core/Core/NetPlayServer.h @@ -28,7 +28,7 @@ public: void ThreadFunc(); void SendAsyncToClients(sf::Packet&& packet); - NetPlayServer(const u16 port, bool traversal, const std::string& centralServer, u16 centralPort); + NetPlayServer(u16 port, bool forward_port, const NetTraversalConfig& traversal_config); ~NetPlayServer(); bool ChangeGame(const std::string& game); @@ -58,10 +58,6 @@ public: bool is_connected = false; -#ifdef USE_UPNP - void TryPortmapping(u16 port); -#endif - private: class Client { @@ -123,19 +119,4 @@ private: ENetHost* m_server = nullptr; TraversalClient* m_traversal_client = nullptr; NetPlayUI* m_dialog = nullptr; - -#ifdef USE_UPNP - static void mapPortThread(const u16 port); - static void unmapPortThread(); - - static bool initUPnP(); - static bool UPnPMapPort(const std::string& addr, const u16 port); - static bool UPnPUnmapPort(const u16 port); - - static struct UPNPUrls m_upnp_urls; - static struct IGDdatas m_upnp_data; - static std::string m_upnp_ourip; - static u16 m_upnp_mapped; - static std::thread m_upnp_thread; -#endif }; diff --git a/Source/Core/DolphinQt2/MainWindow.cpp b/Source/Core/DolphinQt2/MainWindow.cpp index 6797c6296b..6dc3ff4ec9 100644 --- a/Source/Core/DolphinQt2/MainWindow.cpp +++ b/Source/Core/DolphinQt2/MainWindow.cpp @@ -663,9 +663,8 @@ bool MainWindow::NetPlayJoin() } // Settings - std::string host_ip, traversal_host, nickname; - int host_port, traversal_port; - bool is_traversal; + std::string host_ip; + u16 host_port; if (Settings::Instance().GetNetPlayServer() != nullptr) { host_ip = "127.0.0.1"; @@ -677,18 +676,18 @@ bool MainWindow::NetPlayJoin() host_port = Config::Get(Config::NETPLAY_HOST_PORT); } - std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); - is_traversal = traversal_choice == "traversal"; + const std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); + const bool is_traversal = traversal_choice == "traversal"; - traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); - traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); - nickname = Config::Get(Config::NETPLAY_NICKNAME); + const std::string traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); + const u16 traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); + const std::string nickname = Config::Get(Config::NETPLAY_NICKNAME); // Create Client - Settings::Instance().ResetNetPlayClient( - new NetPlayClient(host_ip, host_port, m_netplay_dialog, nickname, - Settings::Instance().GetNetPlayServer() != nullptr ? false : is_traversal, - traversal_host, traversal_port)); + Settings::Instance().ResetNetPlayClient(new NetPlayClient( + host_ip, host_port, m_netplay_dialog, nickname, + NetTraversalConfig{Settings::Instance().GetNetPlayServer() != nullptr ? false : is_traversal, + traversal_host, traversal_port})); if (!Settings::Instance().GetNetPlayClient()->IsConnected()) { @@ -721,26 +720,21 @@ bool MainWindow::NetPlayHost(const QString& game_id) } // Settings - std::string traversal_host, nickname; - int host_port, traversal_port; - bool is_traversal, use_upnp; + u16 host_port = Config::Get(Config::NETPLAY_HOST_PORT); + const std::string traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); + const bool is_traversal = traversal_choice == "traversal"; + const bool use_upnp = Config::Get(Config::NETPLAY_USE_UPNP); - host_port = Config::Get(Config::NETPLAY_HOST_PORT); - std::string traversal_choice; - traversal_choice = Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE); - is_traversal = traversal_choice == "traversal"; - use_upnp = Config::Get(Config::NETPLAY_USE_UPNP); - - traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); - traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); - nickname = Config::Get(Config::NETPLAY_NICKNAME); + const std::string traversal_host = Config::Get(Config::NETPLAY_TRAVERSAL_SERVER); + const u16 traversal_port = Config::Get(Config::NETPLAY_TRAVERSAL_PORT); + const std::string nickname = Config::Get(Config::NETPLAY_NICKNAME); if (is_traversal) host_port = Config::Get(Config::NETPLAY_LISTEN_PORT); // Create Server - Settings::Instance().ResetNetPlayServer( - new NetPlayServer(host_port, is_traversal, traversal_host, traversal_port)); + Settings::Instance().ResetNetPlayServer(new NetPlayServer( + host_port, use_upnp, NetTraversalConfig{is_traversal, traversal_host, traversal_port})); if (!Settings::Instance().GetNetPlayServer()->is_connected) { @@ -754,11 +748,6 @@ bool MainWindow::NetPlayHost(const QString& game_id) Settings::Instance().GetNetPlayServer()->ChangeGame(game_id.toStdString()); -#ifdef USE_UPNP - if (use_upnp) - Settings::Instance().GetNetPlayServer()->TryPortmapping(host_port); -#endif - // Join our local server return NetPlayJoin(); } diff --git a/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.cpp b/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.cpp index 307a03385e..e10375812e 100644 --- a/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.cpp +++ b/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.cpp @@ -23,8 +23,9 @@ bool NetPlayLauncher::Host(const NetPlayHostConfig& config) return false; } - netplay_server = new NetPlayServer(config.listen_port, config.use_traversal, - config.traversal_host, config.traversal_port); + netplay_server = new NetPlayServer( + config.listen_port, config.forward_port, + NetTraversalConfig{config.use_traversal, config.traversal_host, config.traversal_port}); if (!netplay_server->is_connected) { @@ -35,19 +36,11 @@ bool NetPlayLauncher::Host(const NetPlayHostConfig& config) netplay_server->ChangeGame(config.game_name); -#ifdef USE_UPNP - if (config.forward_port) - { - netplay_server->TryPortmapping(config.listen_port); - } -#endif - npd = new NetPlayDialog(config.parent_window, config.game_list_ctrl, config.game_name, true); NetPlayClient*& netplay_client = NetPlayDialog::GetNetPlayClient(); - netplay_client = - new NetPlayClient("127.0.0.1", netplay_server->GetPort(), npd, config.player_name, false, - config.traversal_host, config.traversal_port); + netplay_client = new NetPlayClient("127.0.0.1", netplay_server->GetPort(), npd, + config.player_name, NetTraversalConfig{}); if (netplay_client->IsConnected()) { @@ -76,9 +69,9 @@ bool NetPlayLauncher::Join(const NetPlayJoinConfig& config) else host = config.connect_host; - netplay_client = - new NetPlayClient(host, config.connect_port, npd, config.player_name, config.use_traversal, - config.traversal_host, config.traversal_port); + netplay_client = new NetPlayClient( + host, config.connect_port, npd, config.player_name, + NetTraversalConfig{config.use_traversal, config.traversal_host, config.traversal_port}); if (netplay_client->IsConnected()) { npd->SetSize(config.window_pos); diff --git a/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.h b/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.h index ddc92f6f34..6ce2b69df4 100644 --- a/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.h +++ b/Source/Core/DolphinWX/NetPlay/NetPlayLauncher.h @@ -34,9 +34,7 @@ public: std::string game_name; u16 listen_port = 0; -#ifdef USE_UPNP - bool forward_port; -#endif + bool forward_port = false; }; class NetPlayJoinConfig : public NetPlayLaunchConfig