configuration: add option to select network interface
This commit renames the "Services" tab to "Network" and adds a combobox that allows the user to select the network interface that yuzu should use. This new setting is now used to get the local IP address in Network::GetHostIPv4Address. This prevents yuzu from selecting the wrong network interface and thus using the wrong IP address. The return type of Network::GetHostIPv4Adress has also been changed.
This commit is contained in:
parent
33ebe471e8
commit
1e98e73828
16 changed files with 279 additions and 91 deletions
|
@ -701,7 +701,7 @@ if (APPLE)
|
|||
elseif (WIN32)
|
||||
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
|
||||
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
|
||||
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||
set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi)
|
||||
if (MINGW)
|
||||
# PSAPI is the Process Status API
|
||||
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
|
||||
|
|
|
@ -433,9 +433,10 @@ struct Values {
|
|||
BasicSetting<std::string> log_filter{"*:Info", "log_filter"};
|
||||
BasicSetting<bool> use_dev_keys{false, "use_dev_keys"};
|
||||
|
||||
// Services
|
||||
// Network
|
||||
BasicSetting<std::string> bcat_backend{"none", "bcat_backend"};
|
||||
BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"};
|
||||
BasicSetting<std::string> network_interface{std::string(), "network_interface"};
|
||||
|
||||
// WebService
|
||||
BasicSetting<bool> enable_telemetry{true, "enable_telemetry"};
|
||||
|
|
|
@ -636,6 +636,8 @@ add_library(core STATIC
|
|||
memory.h
|
||||
network/network.cpp
|
||||
network/network.h
|
||||
network/network_interface.cpp
|
||||
network/network_interface.h
|
||||
network/sockets.h
|
||||
perf_stats.cpp
|
||||
perf_stats.h
|
||||
|
|
|
@ -179,10 +179,10 @@ private:
|
|||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
if (Settings::values.bcat_backend.GetValue() == "none") {
|
||||
rb.PushEnum(RequestState::NotSubmitted);
|
||||
} else {
|
||||
if (Network::GetHostIPv4Address().has_value()) {
|
||||
rb.PushEnum(RequestState::Connected);
|
||||
} else {
|
||||
rb.PushEnum(RequestState::NotSubmitted);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,12 +322,15 @@ private:
|
|||
void GetCurrentIpAddress(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
const auto [ipv4, error] = Network::GetHostIPv4Address();
|
||||
UNIMPLEMENTED_IF(error != Network::Errno::SUCCESS);
|
||||
auto ipv4 = Network::GetHostIPv4Address();
|
||||
if (!ipv4) {
|
||||
LOG_CRITICAL(Service_NIFM, "Couldn't get host IPv4 address, defaulting to 0.0.0.0");
|
||||
ipv4.emplace(Network::IPv4Address{0, 0, 0, 0});
|
||||
}
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushRaw(ipv4);
|
||||
rb.PushRaw(ipv4.value());
|
||||
}
|
||||
void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_NIFM, "called");
|
||||
|
@ -354,13 +357,16 @@ private:
|
|||
static_assert(sizeof(IpConfigInfo) == sizeof(IpAddressSetting) + sizeof(DnsSetting),
|
||||
"IpConfigInfo has incorrect size.");
|
||||
|
||||
const auto [ipv4, error] = Network::GetHostIPv4Address();
|
||||
ASSERT_MSG(error == Network::Errno::SUCCESS, "Couldn't get host IPv4 address");
|
||||
auto ipv4 = Network::GetHostIPv4Address();
|
||||
if (!ipv4) {
|
||||
LOG_CRITICAL(Service_NIFM, "Couldn't get host IPv4 address, defaulting to 0.0.0.0");
|
||||
ipv4.emplace(Network::IPv4Address{0, 0, 0, 0});
|
||||
}
|
||||
|
||||
const IpConfigInfo ip_config_info{
|
||||
.ip_address_setting{
|
||||
.is_automatic{true},
|
||||
.current_address{ipv4},
|
||||
.current_address{ipv4.value()},
|
||||
.subnet_mask{255, 255, 255, 0},
|
||||
.gateway{192, 168, 1, 1},
|
||||
},
|
||||
|
@ -387,10 +393,10 @@ private:
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
if (Settings::values.bcat_backend.GetValue() == "none") {
|
||||
rb.Push<u8>(0);
|
||||
} else {
|
||||
if (Network::GetHostIPv4Address().has_value()) {
|
||||
rb.Push<u8>(1);
|
||||
} else {
|
||||
rb.Push<u8>(0);
|
||||
}
|
||||
}
|
||||
void IsAnyInternetRequestAccepted(Kernel::HLERequestContext& ctx) {
|
||||
|
@ -398,10 +404,10 @@ private:
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
if (Settings::values.bcat_backend.GetValue() == "none") {
|
||||
rb.Push<u8>(0);
|
||||
} else {
|
||||
if (Network::GetHostIPv4Address().has_value()) {
|
||||
rb.Push<u8>(1);
|
||||
} else {
|
||||
rb.Push<u8>(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include "common/common_funcs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif YUZU_UNIX
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#error "Unimplemented platform"
|
||||
|
@ -27,7 +28,9 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/network/network.h"
|
||||
#include "core/network/network_interface.h"
|
||||
#include "core/network/sockets.h"
|
||||
|
||||
namespace Network {
|
||||
|
@ -357,27 +360,27 @@ NetworkInstance::~NetworkInstance() {
|
|||
Finalize();
|
||||
}
|
||||
|
||||
std::pair<IPv4Address, Errno> GetHostIPv4Address() {
|
||||
std::array<char, 256> name{};
|
||||
if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) {
|
||||
return {IPv4Address{}, GetAndLogLastError()};
|
||||
}
|
||||
std::optional<IPv4Address> GetHostIPv4Address() {
|
||||
const std::string& selected_network_interface = Settings::values.network_interface.GetValue();
|
||||
const auto network_interfaces = Network::GetAvailableNetworkInterfaces();
|
||||
ASSERT_MSG(network_interfaces.size() > 0, "GetAvailableNetworkInterfaces returned no interfaces");
|
||||
|
||||
hostent* const ent = gethostbyname(name.data());
|
||||
if (!ent) {
|
||||
return {IPv4Address{}, GetAndLogLastError()};
|
||||
}
|
||||
if (ent->h_addr_list == nullptr) {
|
||||
UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list");
|
||||
return {IPv4Address{}, Errno::SUCCESS};
|
||||
}
|
||||
if (ent->h_length != sizeof(in_addr)) {
|
||||
UNIMPLEMENTED_MSG("Unexpected size={} in hostent->h_length", ent->h_length);
|
||||
}
|
||||
|
||||
in_addr addr;
|
||||
std::memcpy(&addr, ent->h_addr_list[0], sizeof(addr));
|
||||
return {TranslateIPv4(addr), Errno::SUCCESS};
|
||||
const auto res = std::ranges::find_if(network_interfaces,
|
||||
[&selected_network_interface](const auto& interface) {
|
||||
return interface.name == selected_network_interface;
|
||||
});
|
||||
|
||||
if (res != network_interfaces.end()) {
|
||||
char ip_addr[16];
|
||||
ASSERT(inet_ntop(AF_INET, &res->ip_address, ip_addr, sizeof(ip_addr)) != nullptr);
|
||||
LOG_INFO(Network, "IP address: {}", ip_addr);
|
||||
|
||||
return TranslateIPv4(res->ip_address);
|
||||
} else {
|
||||
LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
#include "common/common_funcs.h"
|
||||
|
@ -93,7 +94,7 @@ public:
|
|||
};
|
||||
|
||||
/// @brief Returns host's IPv4 address
|
||||
/// @return Pair of an array of human ordered IPv4 address (e.g. 192.168.0.1) and an error code
|
||||
std::pair<IPv4Address, Errno> GetHostIPv4Address();
|
||||
/// @return human ordered IPv4 address (e.g. 192.168.0.1) as an array
|
||||
std::optional<IPv4Address> GetHostIPv4Address();
|
||||
|
||||
} // namespace Network
|
||||
|
|
113
src/core/network/network_interface.cpp
Normal file
113
src/core/network/network_interface.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Copyright 2021 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/network/network_interface.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <iphlpapi.h>
|
||||
#else
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <cerrno>
|
||||
#endif
|
||||
|
||||
namespace Network {
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
|
||||
std::vector<NetworkInterface> result;
|
||||
|
||||
std::vector<u8> adapter_addresses_raw;
|
||||
auto adapter_addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_addresses_raw.data());
|
||||
DWORD ret = ERROR_BUFFER_OVERFLOW;
|
||||
DWORD buf_size = 0;
|
||||
|
||||
// retry up to 5 times
|
||||
for (int i = 0; i < 5 && ret == ERROR_BUFFER_OVERFLOW; i++) {
|
||||
ret = GetAdaptersAddresses(AF_INET, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER,
|
||||
nullptr, adapter_addresses, &buf_size);
|
||||
|
||||
if (ret == ERROR_BUFFER_OVERFLOW) {
|
||||
adapter_addresses_raw.resize(buf_size);
|
||||
adapter_addresses =
|
||||
reinterpret_cast<PIP_ADAPTER_ADDRESSES>(adapter_addresses_raw.data());
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == NO_ERROR) {
|
||||
for (auto current_address = adapter_addresses; current_address != nullptr;
|
||||
current_address = current_address->Next) {
|
||||
if (current_address->FirstUnicastAddress == nullptr ||
|
||||
current_address->FirstUnicastAddress->Address.lpSockaddr == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (current_address->OperStatus != IfOperStatusUp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto ip_addr = std::bit_cast<struct sockaddr_in>(
|
||||
*current_address->FirstUnicastAddress->Address.lpSockaddr)
|
||||
.sin_addr;
|
||||
|
||||
result.push_back(NetworkInterface{
|
||||
.name{Common::UTF16ToUTF8(std::wstring{current_address->FriendlyName})},
|
||||
.ip_address{ip_addr}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
LOG_ERROR(Network, "Failed to get network interfaces with GetAdaptersAddresses");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
|
||||
std::vector<NetworkInterface> result;
|
||||
|
||||
struct ifaddrs* ifaddr = nullptr;
|
||||
|
||||
if (getifaddrs(&ifaddr) != 0) {
|
||||
LOG_ERROR(Network, "Failed to get network interfaces with getifaddrs: {}",
|
||||
std::strerror(errno));
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ifa->ifa_addr->sa_family != AF_INET) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(ifa->ifa_flags & IFF_UP) || ifa->ifa_flags & IFF_LOOPBACK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push_back(NetworkInterface{
|
||||
.name{ifa->ifa_name},
|
||||
.ip_address{std::bit_cast<struct sockaddr_in>(*ifa->ifa_addr).sin_addr}
|
||||
});
|
||||
}
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Network
|
25
src/core/network/network_interface.h
Normal file
25
src/core/network/network_interface.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Copyright 2021 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
namespace Network {
|
||||
|
||||
struct NetworkInterface {
|
||||
std::string name;
|
||||
struct in_addr ip_address;
|
||||
};
|
||||
|
||||
std::vector<NetworkInterface> GetAvailableNetworkInterfaces();
|
||||
|
||||
} // namespace Network
|
|
@ -102,9 +102,9 @@ add_executable(yuzu
|
|||
configuration/configure_profile_manager.cpp
|
||||
configuration/configure_profile_manager.h
|
||||
configuration/configure_profile_manager.ui
|
||||
configuration/configure_service.cpp
|
||||
configuration/configure_service.h
|
||||
configuration/configure_service.ui
|
||||
configuration/configure_network.cpp
|
||||
configuration/configure_network.h
|
||||
configuration/configure_network.ui
|
||||
configuration/configure_system.cpp
|
||||
configuration/configure_system.h
|
||||
configuration/configure_system.ui
|
||||
|
|
|
@ -692,6 +692,7 @@ void Config::ReadServiceValues() {
|
|||
qt_config->beginGroup(QStringLiteral("Services"));
|
||||
ReadBasicSetting(Settings::values.bcat_backend);
|
||||
ReadBasicSetting(Settings::values.bcat_boxcat_local);
|
||||
ReadBasicSetting(Settings::values.network_interface);
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
|
@ -1144,7 +1145,7 @@ void Config::SaveValues() {
|
|||
SaveDataStorageValues();
|
||||
SaveDebuggingValues();
|
||||
SaveDisabledAddOnValues();
|
||||
SaveServiceValues();
|
||||
SaveNetworkValues();
|
||||
SaveUIValues();
|
||||
SaveWebServiceValues();
|
||||
SaveMiscellaneousValues();
|
||||
|
@ -1238,11 +1239,12 @@ void Config::SaveDebuggingValues() {
|
|||
qt_config->endGroup();
|
||||
}
|
||||
|
||||
void Config::SaveServiceValues() {
|
||||
void Config::SaveNetworkValues() {
|
||||
qt_config->beginGroup(QStringLiteral("Services"));
|
||||
|
||||
WriteBasicSetting(Settings::values.bcat_backend);
|
||||
WriteBasicSetting(Settings::values.bcat_boxcat_local);
|
||||
WriteBasicSetting(Settings::values.network_interface);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ private:
|
|||
void SaveCoreValues();
|
||||
void SaveDataStorageValues();
|
||||
void SaveDebuggingValues();
|
||||
void SaveServiceValues();
|
||||
void SaveNetworkValues();
|
||||
void SaveDisabledAddOnValues();
|
||||
void SaveMiscellaneousValues();
|
||||
void SavePathValues();
|
||||
|
|
|
@ -147,12 +147,12 @@
|
|||
<string>Web</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="ConfigureService" name="serviceTab">
|
||||
<widget class="ConfigureNetwork" name="networkTab">
|
||||
<property name="accessibleName">
|
||||
<string>Services</string>
|
||||
<string>Network</string>
|
||||
</property>
|
||||
<attribute name="title">
|
||||
<string>Services</string>
|
||||
<string>Network</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -242,9 +242,9 @@
|
|||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConfigureService</class>
|
||||
<class>ConfigureNetwork</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>configuration/configure_service.h</header>
|
||||
<header>configuration/configure_network.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
|
|
|
@ -67,7 +67,7 @@ void ConfigureDialog::ApplyConfiguration() {
|
|||
ui->audioTab->ApplyConfiguration();
|
||||
ui->debugTab->ApplyConfiguration();
|
||||
ui->webTab->ApplyConfiguration();
|
||||
ui->serviceTab->ApplyConfiguration();
|
||||
ui->networkTab->ApplyConfiguration();
|
||||
Core::System::GetInstance().ApplySettings();
|
||||
Settings::LogSettings();
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ Q_DECLARE_METATYPE(QList<QWidget*>);
|
|||
void ConfigureDialog::PopulateSelectionList() {
|
||||
const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
|
||||
{{tr("General"), {ui->generalTab, ui->hotkeysTab, ui->uiTab, ui->webTab, ui->debugTab}},
|
||||
{tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
|
||||
{tr("System"), {ui->systemTab, ui->profileManagerTab, ui->networkTab, ui->filesystemTab}},
|
||||
{tr("CPU"), {ui->cpuTab}},
|
||||
{tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
|
||||
{tr("Audio"), {ui->audioTab}},
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include <QGraphicsItem>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/bcat/backend/boxcat.h"
|
||||
#include "ui_configure_service.h"
|
||||
#include "yuzu/configuration/configure_service.h"
|
||||
#include "ui_configure_network.h"
|
||||
#include "yuzu/configuration/configure_network.h"
|
||||
|
||||
#ifdef YUZU_ENABLE_BOXCAT
|
||||
namespace {
|
||||
|
@ -35,8 +36,8 @@ QString FormatEventStatusString(const Service::BCAT::EventStatus& status) {
|
|||
} // Anonymous namespace
|
||||
#endif
|
||||
|
||||
ConfigureService::ConfigureService(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureService>()) {
|
||||
ConfigureNetwork::ConfigureNetwork(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureNetwork>()) {
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->bcat_source->addItem(QStringLiteral("None"));
|
||||
|
@ -47,29 +48,42 @@ ConfigureService::ConfigureService(QWidget* parent)
|
|||
ui->bcat_source->addItem(QStringLiteral("Boxcat"), QStringLiteral("boxcat"));
|
||||
#endif
|
||||
|
||||
ui->network_interface->addItem(QStringLiteral("None"));
|
||||
for (const auto& interface : Network::GetAvailableNetworkInterfaces()) {
|
||||
ui->network_interface->addItem(QString::fromStdString(interface.name));
|
||||
}
|
||||
|
||||
connect(ui->bcat_source, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&ConfigureService::OnBCATImplChanged);
|
||||
&ConfigureNetwork::OnBCATImplChanged);
|
||||
|
||||
this->SetConfiguration();
|
||||
}
|
||||
|
||||
ConfigureService::~ConfigureService() = default;
|
||||
ConfigureNetwork::~ConfigureNetwork() = default;
|
||||
|
||||
void ConfigureService::ApplyConfiguration() {
|
||||
void ConfigureNetwork::ApplyConfiguration() {
|
||||
Settings::values.bcat_backend = ui->bcat_source->currentText().toLower().toStdString();
|
||||
Settings::values.network_interface = ui->network_interface->currentText().toStdString();
|
||||
}
|
||||
|
||||
void ConfigureService::RetranslateUi() {
|
||||
void ConfigureNetwork::RetranslateUi() {
|
||||
ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void ConfigureService::SetConfiguration() {
|
||||
void ConfigureNetwork::SetConfiguration() {
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
const int index =
|
||||
ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend.GetValue()));
|
||||
ui->bcat_source->setCurrentIndex(index == -1 ? 0 : index);
|
||||
|
||||
const std::string& network_interface = Settings::values.network_interface.GetValue();
|
||||
|
||||
ui->network_interface->setCurrentText(QString::fromStdString(network_interface));
|
||||
ui->network_interface->setEnabled(runtime_lock);
|
||||
}
|
||||
|
||||
std::pair<QString, QString> ConfigureService::BCATDownloadEvents() {
|
||||
std::pair<QString, QString> ConfigureNetwork::BCATDownloadEvents() {
|
||||
#ifdef YUZU_ENABLE_BOXCAT
|
||||
std::optional<std::string> global;
|
||||
std::map<std::string, Service::BCAT::EventStatus> map;
|
||||
|
@ -114,7 +128,7 @@ std::pair<QString, QString> ConfigureService::BCATDownloadEvents() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ConfigureService::OnBCATImplChanged() {
|
||||
void ConfigureNetwork::OnBCATImplChanged() {
|
||||
#ifdef YUZU_ENABLE_BOXCAT
|
||||
const auto boxcat = ui->bcat_source->currentText() == QStringLiteral("Boxcat");
|
||||
ui->bcat_empty_header->setHidden(!boxcat);
|
||||
|
@ -133,7 +147,7 @@ void ConfigureService::OnBCATImplChanged() {
|
|||
#endif
|
||||
}
|
||||
|
||||
void ConfigureService::OnUpdateBCATEmptyLabel(std::pair<QString, QString> string) {
|
||||
void ConfigureNetwork::OnUpdateBCATEmptyLabel(std::pair<QString, QString> string) {
|
||||
#ifdef YUZU_ENABLE_BOXCAT
|
||||
const auto boxcat = ui->bcat_source->currentText() == QStringLiteral("Boxcat");
|
||||
if (boxcat) {
|
|
@ -8,16 +8,18 @@
|
|||
#include <QFutureWatcher>
|
||||
#include <QWidget>
|
||||
|
||||
#include "core/network/network_interface.h"
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureService;
|
||||
class ConfigureNetwork;
|
||||
}
|
||||
|
||||
class ConfigureService : public QWidget {
|
||||
class ConfigureNetwork : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureService(QWidget* parent = nullptr);
|
||||
~ConfigureService() override;
|
||||
explicit ConfigureNetwork(QWidget* parent = nullptr);
|
||||
~ConfigureNetwork() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
void RetranslateUi();
|
||||
|
@ -29,6 +31,6 @@ private:
|
|||
void OnBCATImplChanged();
|
||||
void OnUpdateBCATEmptyLabel(std::pair<QString, QString> string);
|
||||
|
||||
std::unique_ptr<Ui::ConfigureService> ui;
|
||||
std::unique_ptr<Ui::ConfigureNetwork> ui;
|
||||
QFutureWatcher<std::pair<QString, QString>> watcher{this};
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConfigureService</class>
|
||||
<widget class="QWidget" name="ConfigureService">
|
||||
<class>ConfigureNetwork</class>
|
||||
<widget class="QWidget" name="ConfigureNetwork">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -16,22 +16,38 @@
|
|||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>General</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="network_interface"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Network Interface</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>BCAT</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>260</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="bcat_empty_header">
|
||||
<property name="text">
|
||||
<string>BCAT is Nintendo's way of sending data to games to engage its community and unlock additional content.</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -51,11 +67,8 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLabel" name="bcat_empty_label">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>260</width>
|
||||
|
@ -63,10 +76,7 @@
|
|||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
<string>BCAT is Nintendo's way of sending data to games to engage its community and unlock additional content.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -86,8 +96,17 @@
|
|||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="bcat_source"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="bcat_empty_header">
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLabel" name="bcat_empty_label">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>260</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
Loading…
Reference in a new issue