Skip to content
Permalink
Browse files

Merge pull request #7945 from spycrab/np_browser

Qt/NetPlay: Implement session/server browser
  • Loading branch information...
spycrab committed Apr 6, 2019
2 parents a7ee00a + 094bf0d commit 23986d48f731fd92e8989b32988f636118c9d2ba
@@ -36,6 +36,7 @@ class HttpRequest::Impl final

static int CurlProgressCallback(Impl* impl, double dlnow, double dltotal, double ulnow,
double ultotal);
std::string EscapeComponent(const std::string& string);

private:
static std::mutex s_curl_was_inited_mutex;
@@ -74,6 +75,11 @@ void HttpRequest::FollowRedirects(long max)
m_impl->FollowRedirects(max);
}

std::string HttpRequest::EscapeComponent(const std::string& string)
{
return m_impl->EscapeComponent(string);
}

HttpRequest::Response HttpRequest::Get(const std::string& url, const Headers& headers)
{
return m_impl->Fetch(url, Impl::Method::GET, headers, nullptr, 0);
@@ -159,6 +165,11 @@ void HttpRequest::Impl::FollowRedirects(long max)
curl_easy_setopt(m_curl.get(), CURLOPT_MAXREDIRS, max);
}

std::string HttpRequest::Impl::EscapeComponent(const std::string& string)
{
return curl_easy_escape(m_curl.get(), string.c_str(), static_cast<int>(string.size()));
}

static size_t CurlWriteCallback(char* data, size_t size, size_t nmemb, void* userdata)
{
auto* buffer = static_cast<std::vector<u8>*>(userdata);
@@ -34,6 +34,7 @@ class HttpRequest final
void SetCookies(const std::string& cookies);
void UseIPv4();
void FollowRedirects(long max = 1);
std::string EscapeComponent(const std::string& string);
Response Get(const std::string& url, const Headers& headers = {});
Response Post(const std::string& url, const std::vector<u8>& payload,
const Headers& headers = {});
@@ -19,6 +19,15 @@ const ConfigInfo<std::string> NETPLAY_TRAVERSAL_SERVER{{System::Main, "NetPlay",
const ConfigInfo<u16> NETPLAY_TRAVERSAL_PORT{{System::Main, "NetPlay", "TraversalPort"}, 6262};
const ConfigInfo<std::string> NETPLAY_TRAVERSAL_CHOICE{{System::Main, "NetPlay", "TraversalChoice"},
"direct"};
const ConfigInfo<std::string> NETPLAY_INDEX_URL{{System::Main, "NetPlay", "IndexServer"},
"https://lobby.dolphin-emu.org"};

const ConfigInfo<bool> NETPLAY_USE_INDEX{{System::Main, "NetPlay", "UseIndex"}, false};
const ConfigInfo<std::string> NETPLAY_INDEX_NAME{{System::Main, "NetPlay", "IndexName"}, ""};
const ConfigInfo<std::string> NETPLAY_INDEX_REGION{{System::Main, "NetPlay", "IndexRegion"}, ""};
const ConfigInfo<std::string> NETPLAY_INDEX_PASSWORD{{System::Main, "NetPlay", "IndexPassword"},
""};

const ConfigInfo<std::string> NETPLAY_HOST_CODE{{System::Main, "NetPlay", "HostCode"}, "00000000"};

const ConfigInfo<u16> NETPLAY_HOST_PORT{{System::Main, "NetPlay", "HostPort"}, DEFAULT_LISTEN_PORT};
@@ -19,6 +19,7 @@ extern const ConfigInfo<std::string> NETPLAY_TRAVERSAL_SERVER;
extern const ConfigInfo<u16> NETPLAY_TRAVERSAL_PORT;
extern const ConfigInfo<std::string> NETPLAY_TRAVERSAL_CHOICE;
extern const ConfigInfo<std::string> NETPLAY_HOST_CODE;
extern const ConfigInfo<std::string> NETPLAY_INDEX_URL;

extern const ConfigInfo<u16> NETPLAY_HOST_PORT;
extern const ConfigInfo<std::string> NETPLAY_ADDRESS;
@@ -30,6 +31,11 @@ extern const ConfigInfo<bool> NETPLAY_USE_UPNP;

extern const ConfigInfo<bool> NETPLAY_ENABLE_QOS;

extern const ConfigInfo<bool> NETPLAY_USE_INDEX;
extern const ConfigInfo<std::string> NETPLAY_INDEX_REGION;
extern const ConfigInfo<std::string> NETPLAY_INDEX_NAME;
extern const ConfigInfo<std::string> NETPLAY_INDEX_PASSWORD;

extern const ConfigInfo<bool> NETPLAY_ENABLE_CHUNKED_UPLOAD_LIMIT;
extern const ConfigInfo<u32> NETPLAY_CHUNKED_UPLOAD_LIMIT;

@@ -24,6 +24,7 @@
#include "Common/ENetUtil.h"
#include "Common/File.h"
#include "Common/FileUtil.h"
#include "Common/HttpRequest.h"
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Common/SFMLHelper.h"
@@ -132,6 +133,8 @@ NetPlayServer::NetPlayServer(const u16 port, const bool forward_port,
m_server = enet_host_create(&serverAddr, 10, CHANNEL_COUNT, 0, 0);
if (m_server != nullptr)
m_server->intercept = ENetUtil::InterceptCallback;

SetupIndex();
}
if (m_server != nullptr)
{
@@ -162,6 +165,45 @@ static void ClearPeerPlayerId(ENetPeer* peer)
}
}

void NetPlayServer::SetupIndex()
{
if (!Config::Get(Config::NETPLAY_USE_INDEX))
return;

NetPlaySession session;

session.name = Config::Get(Config::NETPLAY_INDEX_NAME);
session.region = Config::Get(Config::NETPLAY_INDEX_REGION);
session.has_password = !Config::Get(Config::NETPLAY_INDEX_PASSWORD).empty();
session.method = m_traversal_client ? "traversal" : "direct";
session.game_id = m_selected_game.empty() ? "UNKNOWN" : m_selected_game;
session.player_count = static_cast<int>(m_players.size());
session.in_game = m_is_running;
session.port = GetPort();

if (m_traversal_client)
{
session.server_id = std::string(g_TraversalClient->GetHostID().data(), 8);
}
else
{
Common::HttpRequest request;
// ENet does not support IPv6, so IPv4 has to be used
request.UseIPv4();
Common::HttpRequest::Response response =
request.Get("https://ip.dolphin-emu.org/", {{"X-Is-Dolphin", "1"}});

if (!response.has_value())
return;

session.server_id = std::string(response->begin(), response->end());
}

session.EncryptID(Config::Get(Config::NETPLAY_INDEX_PASSWORD));

m_index.Add(session);
}

// called from ---NETPLAY--- thread
void NetPlayServer::ThreadFunc()
{
@@ -178,6 +220,11 @@ void NetPlayServer::ThreadFunc()

m_ping_timer.Start();
SendToClients(spac);

m_index.SetPlayerCount(static_cast<int>(m_players.size()));
m_index.SetGame(m_selected_game);
m_index.SetInGame(m_is_running);

m_update_pings = false;
}

@@ -283,7 +330,7 @@ void NetPlayServer::ThreadFunc()
ClearPeerPlayerId(player_entry.second.socket);
enet_peer_disconnect(player_entry.second.socket, 0);
}
}
} // namespace NetPlay

// called from ---NETPLAY--- thread
unsigned int NetPlayServer::OnConnect(ENetPeer* socket, sf::Packet& rpac)
@@ -1067,11 +1114,14 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)

void NetPlayServer::OnTraversalStateChanged()
{
const TraversalClient::State state = m_traversal_client->GetState();

if (g_TraversalClient->GetHostID()[0] != '\0')
SetupIndex();

if (!m_dialog)
return;

const TraversalClient::State state = m_traversal_client->GetState();

if (state == TraversalClient::Failure)
m_dialog->OnTraversalError(m_traversal_client->GetFailureReason());

@@ -21,6 +21,7 @@
#include "Common/TraversalClient.h"
#include "Core/NetPlayProto.h"
#include "InputCommon/GCPadStatus.h"
#include "UICommon/NetPlayIndex.h"

namespace NetPlay
{
@@ -136,6 +137,7 @@ class NetPlayServer : public TraversalClientClient
std::vector<std::pair<std::string, std::string>> GetInterfaceListInternal() const;
void ChunkedDataThreadFunc();
void ChunkedDataSend(sf::Packet&& packet, PlayerId pid, const TargetMode target_mode);
void SetupIndex();

bool PlayerHasControllerMapped(PlayerId pid) const;

@@ -187,5 +189,6 @@ class NetPlayServer : public TraversalClientClient
ENetHost* m_server = nullptr;
TraversalClient* m_traversal_client = nullptr;
NetPlayUI* m_dialog = nullptr;
NetPlayIndex m_index;
};
} // namespace NetPlay
@@ -98,6 +98,7 @@ add_executable(dolphin-emu
NetPlay/ChunkedProgressDialog.cpp
NetPlay/GameListDialog.cpp
NetPlay/MD5Dialog.cpp
NetPlay/NetPlayBrowser.cpp
NetPlay/NetPlayDialog.cpp
NetPlay/NetPlaySetupDialog.cpp
NetPlay/PadMappingDialog.cpp
@@ -147,6 +147,7 @@
<QtMoc Include="NetPlay\ChunkedProgressDialog.h" />
<QtMoc Include="NetPlay\GameListDialog.h" />
<QtMoc Include="NetPlay\MD5Dialog.h" />
<QtMoc Include="NetPlay\NetPlayBrowser.h" />
<QtMoc Include="NetPlay\NetPlayDialog.h" />
<QtMoc Include="NetPlay\NetPlaySetupDialog.h" />
<QtMoc Include="NetPlay\PadMappingDialog.h" />
@@ -248,6 +249,7 @@
<ClCompile Include="$(QtMocOutPrefix)MemoryWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MenuBar.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ModalMessageBox.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NetPlayBrowser.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NetPlayDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NetPlaySetupDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NewBreakpointDialog.cpp" />
@@ -367,6 +369,7 @@
<ClCompile Include="NetPlay\ChunkedProgressDialog.cpp" />
<ClCompile Include="NetPlay\GameListDialog.cpp" />
<ClCompile Include="NetPlay\MD5Dialog.cpp" />
<ClCompile Include="NetPlay\NetPlayBrowser.cpp" />
<ClCompile Include="NetPlay\NetPlayDialog.cpp" />
<ClCompile Include="NetPlay\NetPlaySetupDialog.cpp" />
<ClCompile Include="NetPlay\PadMappingDialog.cpp" />
@@ -80,6 +80,7 @@
#include "DolphinQt/HotkeyScheduler.h"
#include "DolphinQt/MainWindow.h"
#include "DolphinQt/MenuBar.h"
#include "DolphinQt/NetPlay/NetPlayBrowser.h"
#include "DolphinQt/NetPlay/NetPlayDialog.h"
#include "DolphinQt/NetPlay/NetPlaySetupDialog.h"
#include "DolphinQt/QtUtils/ModalMessageBox.h"
@@ -453,6 +454,7 @@ void MainWindow::ConnectMenuBar()
connect(m_menu_bar, &MenuBar::PerformOnlineUpdate, this, &MainWindow::PerformOnlineUpdate);
connect(m_menu_bar, &MenuBar::BootWiiSystemMenu, this, &MainWindow::BootWiiSystemMenu);
connect(m_menu_bar, &MenuBar::StartNetPlay, this, &MainWindow::ShowNetPlaySetupDialog);
connect(m_menu_bar, &MenuBar::BrowseNetPlay, this, &MainWindow::ShowNetPlayBrowser);
connect(m_menu_bar, &MenuBar::ShowFIFOPlayer, this, &MainWindow::ShowFIFOPlayer);
connect(m_menu_bar, &MenuBar::ConnectWiiRemote, this, &MainWindow::OnConnectWiiRemote);

@@ -1131,6 +1133,13 @@ void MainWindow::ShowNetPlaySetupDialog()
m_netplay_setup_dialog->activateWindow();
}

void MainWindow::ShowNetPlayBrowser()
{
auto* browser = new NetPlayBrowser(this);
connect(browser, &NetPlayBrowser::Join, this, &MainWindow::NetPlayJoin);
browser->exec();
}

void MainWindow::ShowFIFOPlayer()
{
if (!m_fifo_window)
@@ -148,6 +148,7 @@ class MainWindow final : public QMainWindow
void ShowAboutDialog();
void ShowHotkeyDialog();
void ShowNetPlaySetupDialog();
void ShowNetPlayBrowser();
void ShowFIFOPlayer();
void ShowMemcardManager();
void ShowResourcePackManager();
@@ -241,6 +241,7 @@ void MenuBar::AddToolsMenu()
gc_ipl->addAction(tr("PAL"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::PAL); });

tools_menu->addAction(tr("Start &NetPlay..."), this, &MenuBar::StartNetPlay);
tools_menu->addAction(tr("Browse &NetPlay Sessions...."), this, &MenuBar::BrowseNetPlay);
tools_menu->addAction(tr("FIFO Player"), this, &MenuBar::ShowFIFOPlayer);

tools_menu->addSeparator();
@@ -61,6 +61,7 @@ class MenuBar final : public QMenuBar
void FrameAdvance();
void Screenshot();
void StartNetPlay();
void BrowseNetPlay();
void StateLoad();
void StateSave();
void StateLoadSlot();

0 comments on commit 23986d4

Please sign in to comment.
You can’t perform that action at this time.