summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorSepalani <sepalani@hotmail.fr>2020-04-19 23:30:50 +0400
committerSepalani <sepalani@hotmail.fr>2020-04-27 21:47:00 +0400
commit5e33cd48da132e0b2b4e459ef83388233d4e3a2f (patch)
tree62942d5550e52f3deb1e6ad37b096ac5c9d7f2da /Source
parent88ae4c7914af3a5487bdbff2920973833b77d6ce (diff)
Debugger: Add a Network widget
Display socket table, SSL context and options
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/IOS/Network/SSL.cpp24
-rw-r--r--Source/Core/Core/IOS/Network/SSL.h11
-rw-r--r--Source/Core/Core/IOS/Network/Socket.cpp4
-rw-r--r--Source/Core/Core/IOS/Network/Socket.h2
-rw-r--r--Source/Core/DolphinQt/CMakeLists.txt2
-rw-r--r--Source/Core/DolphinQt/Debugger/NetworkWidget.cpp301
-rw-r--r--Source/Core/DolphinQt/Debugger/NetworkWidget.h46
-rw-r--r--Source/Core/DolphinQt/DolphinQt.vcxproj3
-rw-r--r--Source/Core/DolphinQt/MainWindow.cpp4
-rw-r--r--Source/Core/DolphinQt/MainWindow.h2
-rw-r--r--Source/Core/DolphinQt/MenuBar.cpp9
-rw-r--r--Source/Core/DolphinQt/MenuBar.h1
-rw-r--r--Source/Core/DolphinQt/Settings.cpp14
-rw-r--r--Source/Core/DolphinQt/Settings.h3
14 files changed, 406 insertions, 20 deletions
diff --git a/Source/Core/Core/IOS/Network/SSL.cpp b/Source/Core/Core/IOS/Network/SSL.cpp
index 4cdc90b662..08bc4c244c 100644
--- a/Source/Core/Core/IOS/Network/SSL.cpp
+++ b/Source/Core/Core/IOS/Network/SSL.cpp
@@ -23,7 +23,7 @@
namespace IOS::HLE::Device
{
-WII_SSL NetSSL::_SSL[NET_SSL_MAXINSTANCES];
+WII_SSL NetSSL::_SSL[IOS::HLE::NET_SSL_MAXINSTANCES];
static constexpr mbedtls_x509_crt_profile mbedtls_x509_crt_profile_wii = {
/* Hashes from SHA-1 and above */
@@ -247,7 +247,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_SHUTDOWN:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
@@ -292,7 +292,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
int ret =
@@ -333,7 +333,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
@@ -380,7 +380,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
mbedtls_x509_crt_free(&ssl->clicert);
@@ -399,7 +399,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_SETBUILTINROOTCA:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
const std::string cert_base_path = File::GetUserPath(D_SESSION_WIIROOT_IDX);
@@ -437,7 +437,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_CONNECT:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WII_SSL* ssl = &_SSL[sslID];
mbedtls_ssl_setup(&ssl->ctx, &ssl->config);
@@ -464,7 +464,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_DOHANDSHAKE:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WiiSockMan& sm = WiiSockMan::GetInstance();
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_DOHANDSHAKE);
@@ -479,7 +479,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_WRITE:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WiiSockMan& sm = WiiSockMan::GetInstance();
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_WRITE);
@@ -503,7 +503,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
{
int ret = 0;
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WiiSockMan& sm = WiiSockMan::GetInstance();
sm.DoSock(_SSL[sslID].sockfd, request, IOCTLV_NET_SSL_READ);
@@ -526,7 +526,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
case IOCTLV_NET_SSL_SETROOTCADEFAULT:
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WriteReturnValue(SSL_OK, BufferIn);
}
@@ -554,7 +554,7 @@ IPCCommandResult NetSSL::IOCtlV(const IOCtlVRequest& request)
BufferOutSize, BufferOut2, BufferOutSize2, BufferOut3, BufferOutSize3);
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IsSSLIDValid(sslID))
{
WriteReturnValue(SSL_OK, BufferIn);
}
diff --git a/Source/Core/Core/IOS/Network/SSL.h b/Source/Core/Core/IOS/Network/SSL.h
index e8cd273f81..d1a29f253e 100644
--- a/Source/Core/Core/IOS/Network/SSL.h
+++ b/Source/Core/Core/IOS/Network/SSL.h
@@ -24,11 +24,7 @@
namespace IOS::HLE
{
-#define NET_SSL_MAXINSTANCES 4
-
-// TODO: remove this macro.
-#define SSLID_VALID(x) \
- (x >= 0 && x < NET_SSL_MAXINSTANCES && ::IOS::HLE::Device::NetSSL::_SSL[x].active)
+constexpr int NET_SSL_MAXINSTANCES = 4;
enum ssl_err_t : s32
{
@@ -103,5 +99,10 @@ public:
private:
bool m_cert_error_shown = false;
};
+
+constexpr bool IsSSLIDValid(int id)
+{
+ return (id >= 0 && id < NET_SSL_MAXINSTANCES && IOS::HLE::Device::NetSSL::_SSL[id].active);
+}
} // namespace Device
} // namespace IOS::HLE
diff --git a/Source/Core/Core/IOS/Network/Socket.cpp b/Source/Core/Core/IOS/Network/Socket.cpp
index a2b081bd5d..fa39308514 100644
--- a/Source/Core/Core/IOS/Network/Socket.cpp
+++ b/Source/Core/Core/IOS/Network/Socket.cpp
@@ -33,8 +33,6 @@
namespace IOS::HLE
{
-constexpr int WII_SOCKET_FD_MAX = 24;
-
char* WiiSockMan::DecodeError(s32 ErrorCode)
{
#ifdef _WIN32
@@ -325,7 +323,7 @@ void WiiSocket::Update(bool read, bool write, bool except)
if (it->is_ssl)
{
int sslID = Memory::Read_U32(BufferOut) - 1;
- if (SSLID_VALID(sslID))
+ if (IOS::HLE::Device::IsSSLIDValid(sslID))
{
switch (it->ssl_type)
{
diff --git a/Source/Core/Core/IOS/Network/Socket.h b/Source/Core/Core/IOS/Network/Socket.h
index 0109366fc5..615560f305 100644
--- a/Source/Core/Core/IOS/Network/Socket.h
+++ b/Source/Core/Core/IOS/Network/Socket.h
@@ -57,6 +57,8 @@ typedef struct pollfd pollfd_t;
namespace IOS::HLE
{
+constexpr int WII_SOCKET_FD_MAX = 24;
+
enum
{
SO_MSG_OOB = 0x01,
diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt
index 6a124cd03b..4589d4881f 100644
--- a/Source/Core/DolphinQt/CMakeLists.txt
+++ b/Source/Core/DolphinQt/CMakeLists.txt
@@ -176,6 +176,8 @@ add_executable(dolphin-emu
Debugger/MemoryViewWidget.h
Debugger/MemoryWidget.cpp
Debugger/MemoryWidget.h
+ Debugger/NetworkWidget.cpp
+ Debugger/NetworkWidget.h
Debugger/NewBreakpointDialog.cpp
Debugger/NewBreakpointDialog.h
Debugger/PatchInstructionDialog.cpp
diff --git a/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp b/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
new file mode 100644
index 0000000000..8adee91ca2
--- /dev/null
+++ b/Source/Core/DolphinQt/Debugger/NetworkWidget.cpp
@@ -0,0 +1,301 @@
+// Copyright 2020 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt/Debugger/NetworkWidget.h"
+
+#include <QCheckBox>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QHeaderView>
+#include <QTableWidget>
+#include <QVBoxLayout>
+
+#ifdef _WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#include <sys/types.h>
+#endif
+
+#include "Core/ConfigManager.h"
+#include "Core/IOS/Network/SSL.h"
+#include "Core/IOS/Network/Socket.h"
+#include "DolphinQt/Host.h"
+#include "DolphinQt/Settings.h"
+
+namespace
+{
+QTableWidgetItem* GetSocketDomain(s32 host_fd)
+{
+ if (host_fd < 0)
+ return new QTableWidgetItem();
+
+ sockaddr sa;
+ socklen_t sa_len = sizeof(sa);
+ const int ret = getsockname(host_fd, &sa, &sa_len);
+ if (ret != 0)
+ return new QTableWidgetItem(QTableWidget::tr("Unknown"));
+
+ switch (sa.sa_family)
+ {
+ case 2:
+ return new QTableWidgetItem(QLatin1Literal("AF_INET"));
+ case 23:
+ return new QTableWidgetItem(QLatin1Literal("AF_INET6"));
+ default:
+ return new QTableWidgetItem(QString::number(sa.sa_family));
+ }
+}
+
+QTableWidgetItem* GetSocketType(s32 host_fd)
+{
+ if (host_fd < 0)
+ return new QTableWidgetItem();
+
+ int so_type;
+ socklen_t opt_len = sizeof(so_type);
+ const int ret =
+ getsockopt(host_fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char*>(&so_type), &opt_len);
+ if (ret != 0)
+ return new QTableWidgetItem(QTableWidget::tr("Unknown"));
+
+ switch (so_type)
+ {
+ case 1:
+ return new QTableWidgetItem(QLatin1Literal("SOCK_STREAM"));
+ case 2:
+ return new QTableWidgetItem(QLatin1Literal("SOCK_DGRAM"));
+ default:
+ return new QTableWidgetItem(QString::number(so_type));
+ }
+}
+
+QTableWidgetItem* GetSocketState(s32 host_fd)
+{
+ if (host_fd < 0)
+ return new QTableWidgetItem();
+
+ sockaddr_in peer_addr;
+ socklen_t peer_addr_len = sizeof(sockaddr_in);
+ if (getpeername(host_fd, reinterpret_cast<sockaddr*>(&peer_addr), &peer_addr_len) == 0)
+ return new QTableWidgetItem(QTableWidget::tr("Connected"));
+
+ int so_accept = 0;
+ socklen_t opt_len = sizeof(so_accept);
+ const int ret =
+ getsockopt(host_fd, SOL_SOCKET, SO_ACCEPTCONN, reinterpret_cast<char*>(&so_accept), &opt_len);
+ if (ret == 0 && so_accept > 0)
+ return new QTableWidgetItem(QTableWidget::tr("Listening"));
+ return new QTableWidgetItem(QTableWidget::tr("Unbound"));
+}
+
+QTableWidgetItem* GetSocketName(s32 host_fd)
+{
+ if (host_fd < 0)
+ return new QTableWidgetItem();
+
+ sockaddr_in sock_addr;
+ socklen_t sock_addr_len = sizeof(sockaddr_in);
+ if (getsockname(host_fd, reinterpret_cast<sockaddr*>(&sock_addr), &sock_addr_len) != 0)
+ return new QTableWidgetItem(QTableWidget::tr("Unknown"));
+
+ const QString sock_name = QStringLiteral("%1:%2")
+ .arg(QString::fromLatin1(inet_ntoa(sock_addr.sin_addr)))
+ .arg(ntohs(sock_addr.sin_port));
+
+ sockaddr_in peer_addr;
+ socklen_t peer_addr_len = sizeof(sockaddr_in);
+ if (getpeername(host_fd, reinterpret_cast<sockaddr*>(&peer_addr), &peer_addr_len) != 0)
+ return new QTableWidgetItem(sock_name);
+
+ const QString peer_name = QStringLiteral("%1:%2")
+ .arg(QString::fromLatin1(inet_ntoa(peer_addr.sin_addr)))
+ .arg(ntohs(peer_addr.sin_port));
+ return new QTableWidgetItem(QStringLiteral("%1->%2").arg(sock_name).arg(peer_name));
+}
+} // namespace
+
+NetworkWidget::NetworkWidget(QWidget* parent) : QDockWidget(parent)
+{
+ setWindowTitle(tr("Network"));
+ setObjectName(QStringLiteral("network"));
+
+ setHidden(!Settings::Instance().IsNetworkVisible() || !Settings::Instance().IsDebugModeEnabled());
+
+ setAllowedAreas(Qt::AllDockWidgetAreas);
+
+ CreateWidgets();
+
+ auto& settings = Settings::GetQSettings();
+
+ restoreGeometry(settings.value(QStringLiteral("networkwidget/geometry")).toByteArray());
+ // macOS: setHidden() needs to be evaluated before setFloating() for proper window presentation
+ // according to Settings
+ setFloating(settings.value(QStringLiteral("networkwidget/floating")).toBool());
+
+ ConnectWidgets();
+
+ connect(Host::GetInstance(), &Host::UpdateDisasmDialog, this, &NetworkWidget::Update);
+
+ connect(&Settings::Instance(), &Settings::NetworkVisibilityChanged,
+ [this](bool visible) { setHidden(!visible); });
+
+ connect(&Settings::Instance(), &Settings::DebugModeToggled, [this](bool enabled) {
+ setHidden(!enabled || !Settings::Instance().IsNetworkVisible());
+ });
+}
+
+NetworkWidget::~NetworkWidget()
+{
+ auto& settings = Settings::GetQSettings();
+
+ settings.setValue(QStringLiteral("networkwidget/geometry"), saveGeometry());
+ settings.setValue(QStringLiteral("networkwidget/floating"), isFloating());
+}
+
+void NetworkWidget::closeEvent(QCloseEvent*)
+{
+ Settings::Instance().SetNetworkVisible(false);
+}
+
+void NetworkWidget::showEvent(QShowEvent* event)
+{
+ Update();
+}
+
+void NetworkWidget::CreateWidgets()
+{
+ auto* widget = new QWidget;
+ auto* layout = new QVBoxLayout;
+ widget->setLayout(layout);
+ layout->addWidget(CreateSocketTableGroup());
+ layout->addWidget(CreateSSLContextGroup());
+ layout->addWidget(CreateSSLOptionsGroup());
+ layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding));
+ setWidget(widget);
+
+ Update();
+}
+
+void NetworkWidget::ConnectWidgets()
+{
+ connect(m_dump_ssl_read_checkbox, &QCheckBox::stateChanged,
+ [](int state) { SConfig::GetInstance().m_SSLDumpRead = state == Qt::Checked; });
+ connect(m_dump_ssl_write_checkbox, &QCheckBox::stateChanged,
+ [](int state) { SConfig::GetInstance().m_SSLDumpWrite = state == Qt::Checked; });
+ connect(m_dump_root_ca_checkbox, &QCheckBox::stateChanged,
+ [](int state) { SConfig::GetInstance().m_SSLDumpRootCA = state == Qt::Checked; });
+ connect(m_dump_peer_cert_checkbox, &QCheckBox::stateChanged,
+ [](int state) { SConfig::GetInstance().m_SSLDumpPeerCert = state == Qt::Checked; });
+ connect(m_verify_certificates_checkbox, &QCheckBox::stateChanged,
+ [](int state) { SConfig::GetInstance().m_SSLVerifyCert = state == Qt::Checked; });
+}
+
+void NetworkWidget::Update()
+{
+ m_socket_table->setRowCount(0);
+ for (u32 wii_fd = 0; wii_fd < IOS::HLE::WII_SOCKET_FD_MAX; wii_fd++)
+ {
+ m_socket_table->insertRow(wii_fd);
+ const s32 host_fd = IOS::HLE::WiiSockMan::GetInstance().GetHostSocket(wii_fd);
+ m_socket_table->setItem(wii_fd, 0, new QTableWidgetItem(QString::number(wii_fd)));
+ m_socket_table->setItem(wii_fd, 1, GetSocketDomain(host_fd));
+ m_socket_table->setItem(wii_fd, 2, GetSocketType(host_fd));
+ m_socket_table->setItem(wii_fd, 3, GetSocketState(host_fd));
+ m_socket_table->setItem(wii_fd, 4, GetSocketName(host_fd));
+ }
+ m_socket_table->resizeColumnsToContents();
+
+ m_ssl_table->setRowCount(0);
+ for (u32 ssl_id = 0; ssl_id < IOS::HLE::NET_SSL_MAXINSTANCES; ssl_id++)
+ {
+ m_ssl_table->insertRow(ssl_id);
+ s32 host_fd = -1;
+ if (IOS::HLE::Device::IsSSLIDValid(ssl_id) &&
+ IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio != nullptr)
+ {
+ host_fd =
+ static_cast<mbedtls_net_context*>(IOS::HLE::Device::NetSSL::_SSL[ssl_id].ctx.p_bio)->fd;
+ }
+ m_ssl_table->setItem(ssl_id, 0, new QTableWidgetItem(QString::number(ssl_id)));
+ m_ssl_table->setItem(ssl_id, 1, GetSocketDomain(host_fd));
+ m_ssl_table->setItem(ssl_id, 2, GetSocketType(host_fd));
+ m_ssl_table->setItem(ssl_id, 3, GetSocketState(host_fd));
+ m_ssl_table->setItem(ssl_id, 4, GetSocketName(host_fd));
+ }
+ m_ssl_table->resizeColumnsToContents();
+
+ const auto& config = SConfig::GetInstance();
+ m_dump_ssl_read_checkbox->setChecked(config.m_SSLDumpRead);
+ m_dump_ssl_write_checkbox->setChecked(config.m_SSLDumpWrite);
+ m_dump_root_ca_checkbox->setChecked(config.m_SSLDumpRootCA);
+ m_dump_peer_cert_checkbox->setChecked(config.m_SSLDumpPeerCert);
+ m_verify_certificates_checkbox->setChecked(config.m_SSLVerifyCert);
+}
+
+QGroupBox* NetworkWidget::CreateSocketTableGroup()
+{
+ QGroupBox* socket_table_group = new QGroupBox(tr("Socket table"));
+ QGridLayout* socket_table_layout = new QGridLayout;
+ socket_table_group->setLayout(socket_table_layout);
+
+ m_socket_table = new QTableWidget();
+ QStringList header{tr("FD"), tr("Domain"), tr("Type"), tr("State"), tr("Name")};
+ m_socket_table->setColumnCount(header.size());
+
+ m_socket_table->setHorizontalHeaderLabels(header);
+ m_socket_table->setTabKeyNavigation(false);
+ m_socket_table->verticalHeader()->setVisible(false);
+ m_socket_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ m_socket_table->setSelectionMode(QAbstractItemView::NoSelection);
+ m_socket_table->setWordWrap(false);
+
+ socket_table_layout->addWidget(m_socket_table, 0, 0);
+ socket_table_layout->setSpacing(1);
+ return socket_table_group;
+}
+
+QGroupBox* NetworkWidget::CreateSSLContextGroup()
+{
+ QGroupBox* ssl_context_group = new QGroupBox(tr("SSL context"));
+ QGridLayout* ssl_context_layout = new QGridLayout;
+ ssl_context_group->setLayout(ssl_context_layout);
+
+ m_ssl_table = new QTableWidget();
+ QStringList header{tr("ID"), tr("Domain"), tr("Type"), tr("State"), tr("Name")};
+ m_ssl_table->setColumnCount(header.size());
+
+ m_ssl_table->setHorizontalHeaderLabels(header);
+ m_ssl_table->setTabKeyNavigation(false);
+ m_ssl_table->verticalHeader()->setVisible(false);
+ m_ssl_table->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ m_ssl_table->setSelectionMode(QAbstractItemView::NoSelection);
+ m_ssl_table->setWordWrap(false);
+
+ ssl_context_layout->addWidget(m_ssl_table, 0, 0);
+ ssl_context_layout->setSpacing(1);
+ return ssl_context_group;
+}
+
+QGroupBox* NetworkWidget::CreateSSLOptionsGroup()
+{
+ QGroupBox* ssl_options_group = new QGroupBox(tr("SSL options"));
+ QGridLayout* ssl_options_layout = new QGridLayout;
+ ssl_options_group->setLayout(ssl_options_layout);
+
+ m_dump_ssl_read_checkbox = new QCheckBox(tr("Dump SSL read"));
+ m_dump_ssl_write_checkbox = new QCheckBox(tr("Dump SSL write"));
+ m_dump_root_ca_checkbox = new QCheckBox(tr("Dump root CA"));
+ m_dump_peer_cert_checkbox = new QCheckBox(tr("Dump peer certificates"));
+ m_verify_certificates_checkbox = new QCheckBox(tr("Verify certificates"));
+
+ ssl_options_layout->addWidget(m_dump_ssl_read_checkbox, 0, 0);
+ ssl_options_layout->addWidget(m_dump_ssl_write_checkbox, 1, 0);
+ ssl_options_layout->addWidget(m_verify_certificates_checkbox, 2, 0);
+ ssl_options_layout->addWidget(m_dump_root_ca_checkbox, 0, 1);
+ ssl_options_layout->addWidget(m_dump_peer_cert_checkbox, 1, 1);
+
+ ssl_options_layout->setSpacing(1);
+ return ssl_options_group;
+}
diff --git a/Source/Core/DolphinQt/Debugger/NetworkWidget.h b/Source/Core/DolphinQt/Debugger/NetworkWidget.h
new file mode 100644
index 0000000000..735c398dc9
--- /dev/null
+++ b/Source/Core/DolphinQt/Debugger/NetworkWidget.h
@@ -0,0 +1,46 @@
+// Copyright 2020 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QDockWidget>
+
+#include "Common/CommonTypes.h"
+
+class QCheckBox;
+class QCloseEvent;
+class QGroupBox;
+class QShowEvent;
+class QTableWidget;
+class QTableWidgetItem;
+
+class NetworkWidget : public QDockWidget
+{
+ Q_OBJECT
+public:
+ explicit NetworkWidget(QWidget* parent = nullptr);
+ ~NetworkWidget();
+
+protected:
+ void closeEvent(QCloseEvent*) override;
+ void showEvent(QShowEvent* event) override;
+
+private:
+ void CreateWidgets();
+ void ConnectWidgets();
+
+ void Update();
+
+ QGroupBox* CreateSocketTableGroup();
+ QGroupBox* CreateSSLContextGroup();
+ QGroupBox* CreateSSLOptionsGroup();
+
+ QTableWidget* m_socket_table;
+ QTableWidget* m_ssl_table;
+ QCheckBox* m_dump_ssl_read_checkbox;
+ QCheckBox* m_dump_ssl_write_checkbox;
+ QCheckBox* m_dump_root_ca_checkbox;
+ QCheckBox* m_dump_peer_cert_checkbox;
+ QCheckBox* m_verify_certificates_checkbox;
+};
diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj
index 1763c06300..c6dccf12c1 100644
--- a/Source/Core/DolphinQt/DolphinQt.vcxproj
+++ b/Source/Core/DolphinQt/DolphinQt.vcxproj
@@ -147,6 +147,7 @@
<QtMoc Include="Debugger\JITWidget.h" />
<QtMoc Include="Debugger\MemoryWidget.h" />
<QtMoc Include="Debugger\MemoryViewWidget.h" />
+ <QtMoc Include="Debugger\NetworkWidget.h" />
<QtMoc Include="Debugger\NewBreakpointDialog.h" />
<QtMoc Include="Debugger\PatchInstructionDialog.h" />
<QtMoc Include="Debugger\RegisterWidget.h" />
@@ -275,6 +276,7 @@
<ClCompile Include="$(QtMocOutPrefix)MappingWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MemoryViewWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MemoryWidget.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)NetworkWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MenuBar.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ModalMessageBox.cpp" />
<ClCompile Include="$(QtMocOutPrefix)NetPlayBrowser.cpp" />
@@ -377,6 +379,7 @@
<ClCompile Include="Debugger\JITWidget.cpp" />
<ClCompile Include="Debugger\MemoryWidget.cpp" />
<ClCompile Include="Debugger\MemoryViewWidget.cpp" />
+ <ClCompile Include="Debugger\NetworkWidget.cpp" />
<ClCompile Include="DiscordHandler.cpp" />
<ClCompile Include="DiscordJoinRequestDialog.cpp" />
<ClCompile Include="FIFO\FIFOAnalyzer.cpp" />
diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp
index 89a19b42ba..270f4394c6 100644
--- a/Source/Core/DolphinQt/MainWindow.cpp
+++ b/Source/Core/DolphinQt/MainWindow.cpp
@@ -71,6 +71,7 @@
#include "DolphinQt/Debugger/CodeWidget.h"
#include "DolphinQt/Debugger/JITWidget.h"
#include "DolphinQt/Debugger/MemoryWidget.h"
+#include "DolphinQt/Debugger/NetworkWidget.h"
#include "DolphinQt/Debugger/RegisterWidget.h"
#include "DolphinQt/Debugger/WatchWidget.h"
#include "DolphinQt/DiscordHandler.h"
@@ -389,6 +390,7 @@ void MainWindow::CreateComponents()
m_log_widget = new LogWidget(this);
m_log_config_widget = new LogConfigWidget(this);
m_memory_widget = new MemoryWidget(this);
+ m_network_widget = new NetworkWidget(this);
m_register_widget = new RegisterWidget(this);
m_watch_widget = new WatchWidget(this);
m_breakpoint_widget = new BreakpointWidget(this);
@@ -643,6 +645,7 @@ void MainWindow::ConnectStack()
addDockWidget(Qt::LeftDockWidgetArea, m_watch_widget);
addDockWidget(Qt::LeftDockWidgetArea, m_breakpoint_widget);
addDockWidget(Qt::LeftDockWidgetArea, m_memory_widget);
+ addDockWidget(Qt::LeftDockWidgetArea, m_network_widget);
addDockWidget(Qt::LeftDockWidgetArea, m_jit_widget);
tabifyDockWidget(m_log_widget, m_log_config_widget);
@@ -651,6 +654,7 @@ void MainWindow::ConnectStack()
tabifyDockWidget(m_log_widget, m_watch_widget);
tabifyDockWidget(m_log_widget, m_breakpoint_widget);
tabifyDockWidget(m_log_widget, m_memory_widget);
+ tabifyDockWidget(m_log_widget, m_network_widget);
tabifyDockWidget(m_log_widget, m_jit_widget);
}
diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h
index 50fea52a24..d84edb5af7 100644
--- a/Source/Core/DolphinQt/MainWindow.h
+++ b/Source/Core/DolphinQt/MainWindow.h
@@ -34,6 +34,7 @@ class MemoryWidget;
class MenuBar;
class NetPlayDialog;
class NetPlaySetupDialog;
+class NetworkWidget;
class RegisterWidget;
class RenderWidget;
class SearchBar;
@@ -225,6 +226,7 @@ private:
LogWidget* m_log_widget;
LogConfigWidget* m_log_config_widget;
MemoryWidget* m_memory_widget;
+ NetworkWidget* m_network_widget;
RegisterWidget* m_register_widget;
WatchWidget* m_watch_widget;
CheatsManager* m_cheats_manager;
diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp
index 14b433b77b..75b01caba0 100644
--- a/Source/Core/DolphinQt/MenuBar.cpp
+++ b/Source/Core/DolphinQt/MenuBar.cpp
@@ -169,6 +169,7 @@ void MenuBar::OnDebugModeToggled(bool enabled)
m_show_watch->setVisible(enabled);
m_show_breakpoints->setVisible(enabled);
m_show_memory->setVisible(enabled);
+ m_show_network->setVisible(enabled);
m_show_jit->setVisible(enabled);
if (enabled)
@@ -469,6 +470,14 @@ void MenuBar::AddViewMenu()
connect(&Settings::Instance(), &Settings::MemoryVisibilityChanged, m_show_memory,
&QAction::setChecked);
+ m_show_network = view_menu->addAction(tr("&Network"));
+ m_show_network->setCheckable(true);
+ m_show_network->setChecked(Settings::Instance().IsNetworkVisible());
+
+ connect(m_show_network, &QAction::toggled, &Settings::Instance(), &Settings::SetNetworkVisible);
+ connect(&Settings::Instance(), &Settings::NetworkVisibilityChanged, m_show_network,
+ &QAction::setChecked);
+
m_show_jit = view_menu->addAction(tr("&JIT"));
m_show_jit->setCheckable(true);
m_show_jit->setChecked(Settings::Instance().IsJITVisible());
diff --git a/Source/Core/DolphinQt/MenuBar.h b/Source/Core/DolphinQt/MenuBar.h
index 9875888cbc..3bdf6debcb 100644
--- a/Source/Core/DolphinQt/MenuBar.h
+++ b/Source/Core/DolphinQt/MenuBar.h
@@ -235,6 +235,7 @@ private:
QAction* m_show_watch;
QAction* m_show_breakpoints;
QAction* m_show_memory;
+ QAction* m_show_network;
QAction* m_show_jit;
QMenu* m_cols_menu;
diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp
index ea7f014e94..c1a93939d9 100644
--- a/Source/Core/DolphinQt/Settings.cpp
+++ b/Source/Core/DolphinQt/Settings.cpp
@@ -422,6 +422,20 @@ bool Settings::IsMemoryVisible() const
return QSettings().value(QStringLiteral("debugger/showmemory")).toBool();
}
+void Settings::SetNetworkVisible(bool enabled)
+{
+ if (IsNetworkVisible() == enabled)
+ return;
+
+ GetQSettings().setValue(QStringLiteral("debugger/shownetwork"), enabled);
+ emit NetworkVisibilityChanged(enabled);
+}
+
+bool Settings::IsNetworkVisible() const
+{
+ return GetQSettings().value(QStringLiteral("debugger/shownetwork")).toBool();
+}
+
void Settings::SetJITVisible(bool enabled)
{
if (IsJITVisible() == enabled)
diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h
index 01712f5858..7aa169dee0 100644
--- a/Source/Core/DolphinQt/Settings.h
+++ b/Source/Core/DolphinQt/Settings.h
@@ -126,6 +126,8 @@ public:
bool IsCodeVisible() const;
void SetMemoryVisible(bool enabled);
bool IsMemoryVisible() const;
+ void SetNetworkVisible(bool enabled);
+ bool IsNetworkVisible() const;
void SetJITVisible(bool enabled);
bool IsJITVisible() const;
QFont GetDebugFont() const;
@@ -168,6 +170,7 @@ signals:
void BreakpointsVisibilityChanged(bool visible);
void CodeVisibilityChanged(bool visible);
void MemoryVisibilityChanged(bool visible);
+ void NetworkVisibilityChanged(bool visible);
void JITVisibilityChanged(bool visible);
void DebugModeToggled(bool enabled);
void DebugFontChanged(QFont font);