diff --git a/pcsx2-qt/Settings/DEV9SettingsWidget.cpp b/pcsx2-qt/Settings/DEV9SettingsWidget.cpp index 06034cb466..c807e986f2 100644 --- a/pcsx2-qt/Settings/DEV9SettingsWidget.cpp +++ b/pcsx2-qt/Settings/DEV9SettingsWidget.cpp @@ -160,7 +160,6 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent) m_api_valuelist.push_back(nullptr); //We replace the blank entry with one for global settings - Pcsx2Config::DEV9Options::NetApi baseAPI = Pcsx2Config::DEV9Options::NetApi::Unset; if (m_dialog->isPerGameSettings()) { const std::string valueAPI = QtHost::GetBaseStringSettingValue("DEV9/Eth", "EthApi", Pcsx2Config::DEV9Options::NetApiNames[static_cast(Pcsx2Config::DEV9Options::NetApi::Unset)]); @@ -168,12 +167,12 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent) { if (valueAPI == Pcsx2Config::DEV9Options::NetApiNames[i]) { - baseAPI = static_cast(i); + m_global_api = static_cast(i); break; } } - std::vector baseList = m_adapter_list[static_cast(baseAPI)]; + std::vector baseList = m_adapter_list[static_cast(m_global_api)]; std::string baseAdapter = " "; const std::string valueGUID = QtHost::GetBaseStringSettingValue("DEV9/Eth", "EthDevice", ""); @@ -190,7 +189,7 @@ DEV9SettingsWidget::DEV9SettingsWidget(SettingsDialog* dialog, QWidget* parent) } if (m_dialog->isPerGameSettings()) - m_ui.ethDevType->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(Pcsx2Config::DEV9Options::NetApiNames[static_cast(baseAPI)]))); + m_ui.ethDevType->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(Pcsx2Config::DEV9Options::NetApiNames[static_cast(m_global_api)]))); else m_ui.ethDevType->addItem(QString::fromUtf8(m_api_namelist[0])); @@ -358,6 +357,8 @@ void DEV9SettingsWidget::onEthDeviceTypeChanged(int index) m_ui.ethDev->clear(); } + Pcsx2Config::DEV9Options::NetApi selectedApi{Pcsx2Config::DEV9Options::NetApi ::Unset}; + if (index > 0) { std::vector list = m_adapter_list[static_cast(m_api_list[index])]; @@ -369,6 +370,8 @@ void DEV9SettingsWidget::onEthDeviceTypeChanged(int index) if (list[i].guid == value) m_ui.ethDev->setCurrentIndex(i); } + + selectedApi = m_api_list[index]; } if (m_dialog->isPerGameSettings()) @@ -379,10 +382,31 @@ void DEV9SettingsWidget::onEthDeviceTypeChanged(int index) m_ui.ethDev->addItem(tr("Use Global Setting [%1]").arg(QString::fromUtf8(list[0].name))); m_ui.ethDev->setCurrentIndex(0); m_ui.ethDev->setEnabled(false); + + selectedApi = m_global_api; } else m_ui.ethDev->setEnabled(true); } + + switch (selectedApi) + { +#ifdef _WIN32 + case Pcsx2Config::DEV9Options::NetApi::TAP: + m_adapter_options = TAPAdapter::GetAdapterOptions(); + break; +#endif + case Pcsx2Config::DEV9Options::NetApi::PCAP_Bridged: + case Pcsx2Config::DEV9Options::NetApi::PCAP_Switched: + m_adapter_options = PCAPAdapter::GetAdapterOptions(); + break; + default: + m_adapter_options = AdapterOptions::None; + break; + } + + m_ui.ethInterceptDHCP->setEnabled((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::None); + onEthDHCPInterceptChanged(m_ui.ethInterceptDHCP->checkState()); } void DEV9SettingsWidget::onEthDeviceChanged(int index) @@ -403,17 +427,24 @@ void DEV9SettingsWidget::onEthDeviceChanged(int index) void DEV9SettingsWidget::onEthDHCPInterceptChanged(int state) { - const bool enabled = state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue("DEV9/Eth", "InterceptDHCP", false) : state; + const bool enabled = (state == Qt::CheckState::PartiallyChecked ? QtHost::GetBaseBoolSettingValue("DEV9/Eth", "InterceptDHCP", false) : state) || + ((m_adapter_options & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::DHCP_ForcedOn); - m_ui.ethPS2Addr->setEnabled(enabled); - m_ui.ethPS2AddrLabel->setEnabled(enabled); + // clang-format off + const bool ipOverride = (m_adapter_options & AdapterOptions::DHCP_OverrideIP) == AdapterOptions::DHCP_OverrideIP; + const bool snOverride = (m_adapter_options & AdapterOptions::DHCP_OverideSubnet) == AdapterOptions::DHCP_OverideSubnet; + const bool gwOverride = (m_adapter_options & AdapterOptions::DHCP_OverideGateway) == AdapterOptions::DHCP_OverideGateway; + // clang-format on - m_ui.ethNetMaskLabel->setEnabled(enabled); - m_ui.ethNetMaskAuto->setEnabled(enabled); + m_ui.ethPS2Addr->setEnabled(enabled && !ipOverride); + m_ui.ethPS2AddrLabel->setEnabled(enabled && !ipOverride); + + m_ui.ethNetMaskLabel->setEnabled(enabled && !snOverride); + m_ui.ethNetMaskAuto->setEnabled(enabled && !snOverride); onEthAutoChanged(m_ui.ethNetMaskAuto, m_ui.ethNetMaskAuto->checkState(), m_ui.ethNetMask, "DEV9/Eth", "AutoMask"); - m_ui.ethGatewayAddrLabel->setEnabled(enabled); - m_ui.ethGatewayAuto->setEnabled(enabled); + m_ui.ethGatewayAddrLabel->setEnabled(enabled && !gwOverride); + m_ui.ethGatewayAuto->setEnabled(enabled && !gwOverride); onEthAutoChanged(m_ui.ethGatewayAuto, m_ui.ethGatewayAuto->checkState(), m_ui.ethGatewayAddr, "DEV9/Eth", "AutoGateway"); m_ui.ethDNS1AddrLabel->setEnabled(enabled); diff --git a/pcsx2-qt/Settings/DEV9SettingsWidget.h b/pcsx2-qt/Settings/DEV9SettingsWidget.h index a6e2683e72..844b3549eb 100644 --- a/pcsx2-qt/Settings/DEV9SettingsWidget.h +++ b/pcsx2-qt/Settings/DEV9SettingsWidget.h @@ -111,4 +111,9 @@ private: std::vector m_api_namelist; std::vector m_api_valuelist; std::vector> m_adapter_list; + + AdapterOptions m_adapter_options{AdapterOptions::None}; + + //Use by per-game ui only + Pcsx2Config::DEV9Options::NetApi m_global_api{Pcsx2Config::DEV9Options::NetApi::Unset}; }; diff --git a/pcsx2/DEV9/ConfigUI.cpp b/pcsx2/DEV9/ConfigUI.cpp index 8565c8599c..76d093e0fb 100644 --- a/pcsx2/DEV9/ConfigUI.cpp +++ b/pcsx2/DEV9/ConfigUI.cpp @@ -293,16 +293,37 @@ public: void UpdateEnable() { + AdapterOptions adapterOptions = AdapterOptions::None; + const int api = m_eth_adapter_api->GetSelection(); + if (api) + { + const Pcsx2Config::DEV9Options::NetApi netApi = m_api_list[api - 1]; + switch (netApi) + { +#ifdef _WIN32 + case Pcsx2Config::DEV9Options::NetApi::TAP: + adapterOptions = TAPAdapter::GetAdapterOptions(); + break; +#endif + case Pcsx2Config::DEV9Options::NetApi::PCAP_Bridged: + case Pcsx2Config::DEV9Options::NetApi::PCAP_Switched: + adapterOptions = PCAPAdapter::GetAdapterOptions(); + break; + default: + break; + } + } + bool eth_enable = m_eth_enable->GetValue(); bool hdd_enable = m_hdd_enable->GetValue(); - bool dhcp_enable = eth_enable && m_intercept_dhcp->GetValue(); + bool dhcp_enable = eth_enable && (m_intercept_dhcp->GetValue() || ((adapterOptions & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::DHCP_ForcedOn)); m_eth_adapter_api->Enable(eth_enable); m_eth_adapter->Enable(eth_enable); - m_intercept_dhcp->Enable(eth_enable); - m_ps2_address->Enable(dhcp_enable); - m_subnet_mask.setEnabled(dhcp_enable); - m_gateway_address.setEnabled(dhcp_enable); + m_intercept_dhcp->Enable(eth_enable && ((adapterOptions & AdapterOptions::DHCP_ForcedOn) == AdapterOptions::None)); + m_ps2_address->Enable(dhcp_enable && ((adapterOptions & AdapterOptions::DHCP_OverrideIP) == AdapterOptions::None)); + m_subnet_mask.setEnabled(dhcp_enable && ((adapterOptions & AdapterOptions::DHCP_OverideSubnet) == AdapterOptions::None)); + m_gateway_address.setEnabled(dhcp_enable && ((adapterOptions & AdapterOptions::DHCP_OverideGateway) == AdapterOptions::None)); m_dns1_address.setEnabled(dhcp_enable); m_dns2_address.setEnabled(dhcp_enable); m_hdd_file->Enable(hdd_enable); @@ -357,7 +378,10 @@ public: void OnChoice(wxCommandEvent& ev) { if (ev.GetEventObject() == m_eth_adapter_api) + { UpdateAdapters(); + UpdateEnable(); + } } void OnOK(wxCommandEvent& ev) diff --git a/pcsx2/DEV9/InternalServers/DHCP_Server.cpp b/pcsx2/DEV9/InternalServers/DHCP_Server.cpp index 3390b69852..b4ed4afb57 100644 --- a/pcsx2/DEV9/InternalServers/DHCP_Server.cpp +++ b/pcsx2/DEV9/InternalServers/DHCP_Server.cpp @@ -47,24 +47,33 @@ namespace InternalServers } #ifdef _WIN32 - void DHCP_Server::Init(PIP_ADAPTER_ADDRESSES adapter) + void DHCP_Server::Init(PIP_ADAPTER_ADDRESSES adapter, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOverride) #elif defined(__POSIX__) - void DHCP_Server::Init(ifaddrs* adapter) + void DHCP_Server::Init(ifaddrs* adapter, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOverride) #endif { - ps2IP = *(IP_Address*)&EmuConfig.DEV9.PS2IP; + ps2IP = {0}; netmask = {0}; gateway = {0}; dns1 = {0}; dns2 = {0}; broadcastIP = {0}; - if (EmuConfig.DEV9.AutoMask) + if (ipOverride.integer != 0) + ps2IP = ipOverride; + else + ps2IP = *(IP_Address*)&EmuConfig.DEV9.PS2IP; + + if (subnetOverride.integer != 0) + netmask = subnetOverride; + else if (EmuConfig.DEV9.AutoMask) AutoNetmask(adapter); else netmask = *(IP_Address*)EmuConfig.DEV9.Mask; - if (EmuConfig.DEV9.AutoGateway) + if (gatewayOverride.integer != 0) + gateway = gatewayOverride; + else if (EmuConfig.DEV9.AutoGateway) AutoGateway(adapter); else gateway = *(IP_Address*)EmuConfig.DEV9.Gateway; diff --git a/pcsx2/DEV9/InternalServers/DHCP_Server.h b/pcsx2/DEV9/InternalServers/DHCP_Server.h index ca9c5f9aa0..f204112ddb 100644 --- a/pcsx2/DEV9/InternalServers/DHCP_Server.h +++ b/pcsx2/DEV9/InternalServers/DHCP_Server.h @@ -53,9 +53,9 @@ namespace InternalServers DHCP_Server(std::function receivedcallback); #ifdef _WIN32 - void Init(PIP_ADAPTER_ADDRESSES adapter); + void Init(PIP_ADAPTER_ADDRESSES adapter, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOvveride = {0}); #elif defined(__POSIX__) - void Init(ifaddrs* adapter); + void Init(ifaddrs* adapter, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOvveride = {0}); #endif PacketReader::IP::UDP::UDP_Packet* Recv(); diff --git a/pcsx2/DEV9/Win32/tap-win32.cpp b/pcsx2/DEV9/Win32/tap-win32.cpp index c16e150ae3..b64438c670 100644 --- a/pcsx2/DEV9/Win32/tap-win32.cpp +++ b/pcsx2/DEV9/Win32/tap-win32.cpp @@ -199,6 +199,11 @@ std::vector TAPAdapter::GetAdapters() return tap_nic; } +AdapterOptions TAPAdapter::GetAdapterOptions() +{ + return AdapterOptions::None; +} + static int TAPGetMACAddress(HANDLE handle, u8* addr) { DWORD len = 0; diff --git a/pcsx2/DEV9/Win32/tap.h b/pcsx2/DEV9/Win32/tap.h index 00ee17954d..b5fc6bf452 100644 --- a/pcsx2/DEV9/Win32/tap.h +++ b/pcsx2/DEV9/Win32/tap.h @@ -38,4 +38,5 @@ public: virtual void close(); virtual ~TAPAdapter(); static std::vector GetAdapters(); + static AdapterOptions GetAdapterOptions(); }; diff --git a/pcsx2/DEV9/net.cpp b/pcsx2/DEV9/net.cpp index d0a7269f73..28d882f85d 100644 --- a/pcsx2/DEV9/net.cpp +++ b/pcsx2/DEV9/net.cpp @@ -290,16 +290,17 @@ bool NetAdapter::VerifyPkt(NetPacket* pkt, int read_size) } #ifdef _WIN32 -void NetAdapter::InitInternalServer(PIP_ADAPTER_ADDRESSES adapter) +void NetAdapter::InitInternalServer(PIP_ADAPTER_ADDRESSES adapter, bool dhcpForceEnable, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOvveride) #elif defined(__POSIX__) -void NetAdapter::InitInternalServer(ifaddrs* adapter) +void NetAdapter::InitInternalServer(ifaddrs* adapter, bool dhcpForceEnable, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOvveride) #endif { if (adapter == nullptr) Console.Error("DEV9: InitInternalServer() got nullptr for adapter"); - if (EmuConfig.DEV9.InterceptDHCP) - dhcpServer.Init(adapter); + dhcpOn = EmuConfig.DEV9.InterceptDHCP || dhcpForceEnable; + if (dhcpOn) + dhcpServer.Init(adapter, ipOverride, subnetOverride, gatewayOvveride); dnsServer.Init(adapter); @@ -311,16 +312,17 @@ void NetAdapter::InitInternalServer(ifaddrs* adapter) } #ifdef _WIN32 -void NetAdapter::ReloadInternalServer(PIP_ADAPTER_ADDRESSES adapter) +void NetAdapter::ReloadInternalServer(PIP_ADAPTER_ADDRESSES adapter, bool dhcpForceEnable, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOveride) #elif defined(__POSIX__) -void NetAdapter::ReloadInternalServer(ifaddrs* adapter) +void NetAdapter::ReloadInternalServer(ifaddrs* adapter, bool dhcpForceEnable, IP_Address ipOverride, IP_Address subnetOverride, IP_Address gatewayOveride) #endif { if (adapter == nullptr) Console.Error("DEV9: ReloadInternalServer() got nullptr for adapter"); - if (EmuConfig.DEV9.InterceptDHCP) - dhcpServer.Init(adapter); + dhcpOn = EmuConfig.DEV9.InterceptDHCP || dhcpForceEnable; + if (dhcpOn) + dhcpServer.Init(adapter, ipOverride, subnetOverride, gatewayOveride); dnsServer.Init(adapter); } @@ -376,7 +378,7 @@ bool NetAdapter::InternalServerSend(NetPacket* pkt) if (udppkt.destinationPort == 67) { //Send DHCP - if (EmuConfig.DEV9.InterceptDHCP) + if (dhcpOn) return dhcpServer.Send(&udppkt); } } diff --git a/pcsx2/DEV9/net.h b/pcsx2/DEV9/net.h index a22bb5262d..950cbf9ef5 100644 --- a/pcsx2/DEV9/net.h +++ b/pcsx2/DEV9/net.h @@ -66,6 +66,24 @@ struct AdapterEntry std::string guid; }; +enum struct AdapterOptions : int +{ + None = 0, + DHCP_ForcedOn = 1 << 0, + DHCP_OverrideIP = 1 << 1, + DHCP_OverideSubnet = 1 << 2, + DHCP_OverideGateway = 1 << 3, +}; + +constexpr enum AdapterOptions operator|(const enum AdapterOptions selfValue, const enum AdapterOptions inValue) +{ + return (enum AdapterOptions)(int(selfValue) | int(inValue)); +} +constexpr enum AdapterOptions operator&(const enum AdapterOptions selfValue, const enum AdapterOptions inValue) +{ + return (enum AdapterOptions)(int(selfValue) & int(inValue)); +} + class NetAdapter { public: @@ -86,6 +104,7 @@ private: std::condition_variable internalRxCV; bool internalRxHasData = false; + bool dhcpOn = false; InternalServers::DHCP_Server dhcpServer = InternalServers::DHCP_Server([&] { InternalSignalReceived(); }); InternalServers::DNS_Logger dnsLogger; InternalServers::DNS_Server dnsServer = InternalServers::DNS_Server([&] { InternalSignalReceived(); }); @@ -108,11 +127,11 @@ protected: void InspectSend(NetPacket* pkt); #ifdef _WIN32 - void InitInternalServer(PIP_ADAPTER_ADDRESSES adapter); - void ReloadInternalServer(PIP_ADAPTER_ADDRESSES adapter); + void InitInternalServer(PIP_ADAPTER_ADDRESSES adapter, bool dhcpForceEnable = false, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOveride = {0}); + void ReloadInternalServer(PIP_ADAPTER_ADDRESSES adapter, bool dhcpForceEnable = false, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOveride = {0}); #elif defined(__POSIX__) - void InitInternalServer(ifaddrs* adapter); - void ReloadInternalServer(ifaddrs* adapter); + void InitInternalServer(ifaddrs* adapter, bool dhcpForceEnable = false, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOveride = {0}); + void ReloadInternalServer(ifaddrs* adapter, bool dhcpForceEnable = false, PacketReader::IP::IP_Address ipOverride = {0}, PacketReader::IP::IP_Address subnetOverride = {0}, PacketReader::IP::IP_Address gatewayOveride = {0}); #endif private: diff --git a/pcsx2/DEV9/pcap_io.cpp b/pcsx2/DEV9/pcap_io.cpp index 6be196ef3c..37fad89450 100644 --- a/pcsx2/DEV9/pcap_io.cpp +++ b/pcsx2/DEV9/pcap_io.cpp @@ -410,6 +410,10 @@ PCAPAdapter::PCAPAdapter() } #endif } +AdapterOptions PCAPAdapter::GetAdapterOptions() +{ + return AdapterOptions::None; +} bool PCAPAdapter::blocks() { pxAssert(pcap_io_running); diff --git a/pcsx2/DEV9/pcap_io.h b/pcsx2/DEV9/pcap_io.h index 8dd7adc585..2a03c2e4f3 100644 --- a/pcsx2/DEV9/pcap_io.h +++ b/pcsx2/DEV9/pcap_io.h @@ -184,4 +184,5 @@ public: virtual void reloadSettings(); virtual ~PCAPAdapter(); static std::vector GetAdapters(); + static AdapterOptions GetAdapterOptions(); };