From 5f7b698012feff577a517dbd7e6fb7b396304aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 7 Apr 2025 21:40:01 +0200 Subject: [PATCH] Lots of logging and cleanup. --- Common/Data/Text/Parsers.h | 6 ++ Common/Net/HTTPRequest.cpp | 7 +++ Core/Dialog/PSPNetconfDialog.cpp | 2 + Core/HLE/sceNet.cpp | 98 +++++++++++++++++++++++--------- Core/HLE/sceNet.h | 4 +- Core/HLE/sceNetResolver.cpp | 27 ++++++--- UI/ImDebugger/ImDebugger.cpp | 21 ++++--- UI/PauseScreen.cpp | 28 ++++----- 8 files changed, 135 insertions(+), 58 deletions(-) diff --git a/Common/Data/Text/Parsers.h b/Common/Data/Text/Parsers.h index b429bcabba..defe17ff40 100644 --- a/Common/Data/Text/Parsers.h +++ b/Common/Data/Text/Parsers.h @@ -114,6 +114,12 @@ public: p_ += T - 1; return *this; } + // Assumes the input is zero-terminated. + // C: Copies a string literal (which always are zero-terminated, the count includes the zero) directly to the stream. + StringWriter &B(bool b) { + return W(b ? "true" : "false"); + } + // W: Writes a string_view to the stream. StringWriter &W(std::string_view text) { const size_t remainder = bufSize_ - (p_ - start_); diff --git a/Common/Net/HTTPRequest.cpp b/Common/Net/HTTPRequest.cpp index befd47c02b..4a5a62f281 100644 --- a/Common/Net/HTTPRequest.cpp +++ b/Common/Net/HTTPRequest.cpp @@ -89,12 +89,19 @@ std::shared_ptr RequestManager::StartDownload(std::string_view url, con // to modify the calling code. std::string contents; if (File::ReadBinaryFileToString(cacheFile, &contents)) { + INFO_LOG(Log::sceNet, "Returning cached file for %.*s: %s", (int)url.size(), url.data(), cacheFile.c_str()); // All is well, but we've indented a bit much here. dl.reset(new CachedRequest(RequestMethod::GET, url, "", nullptr, flags, contents)); newDownloads_.push_back(dl); return dl; + } else { + INFO_LOG(Log::sceNet, "Failed reading from cache, proceeding with request"); } + } else { + INFO_LOG(Log::sceNet, "Cached file too old, proceeding with request"); } + } else { + INFO_LOG(Log::sceNet, "Failed to check time modified. Proceeding with request."); } // OK, didn't get it from cache, so let's continue with the download, putting it in the cache. diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp index 3b4b1972d0..73f52066b6 100644 --- a/Core/Dialog/PSPNetconfDialog.cpp +++ b/Core/Dialog/PSPNetconfDialog.cpp @@ -59,6 +59,7 @@ int PSPNetconfDialog::Init(u32 paramAddr) { if (ReadStatus() != SCE_UTILITY_STATUS_NONE) return SCE_ERROR_UTILITY_INVALID_STATUS; + NOTICE_LOG(Log::sceNet, "PSPNetConfDialog Init"); // Kick off a request to the infra-dns.json since we'll need it later. StartInfraJsonDownload(); @@ -114,6 +115,7 @@ int PSPNetconfDialog::Update(int animSpeed) { std::string json; if (!jsonReady_ && PollInfraJsonDownload(&json)) { if (!json.empty()) { + INFO_LOG(Log::sceNet, "PollInfraJsonDownload returned a string"); if (!LoadAutoDNS(json)) { // If the JSON parse fails, throw away the cache file at least. ERROR_LOG(Log::sceNet, "Failed to parse bad json. Deleting cache file."); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index c03ecbc555..1fb0df5ed1 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -55,42 +55,82 @@ #include "Core/HLE/sceNetInet.h" #include "Core/HLE/sceNetResolver.h" +// Should probably add accessors around these. bool g_netInited; +bool g_netApctlInited; +SceNetApctlInfoInternal netApctlInfo; +u32 netApctlState; -u32 netDropRate = 0; -u32 netDropDuration = 0; -u32 netPoolAddr = 0; -u32 netThread1Addr = 0; -u32 netThread2Addr = 0; +static u32 netDropRate = 0; +static u32 netDropDuration = 0; +static u32 netPoolAddr = 0; +static u32 netThread1Addr = 0; +static u32 netThread2Addr = 0; static struct SceNetMallocStat netMallocStat; static std::map apctlHandlers; -const char * const defaultNetConfigName = "NetConf"; -const char * const defaultNetSSID = "Wifi"; // fake AP/hotspot +static const char *const defaultNetConfigName = "NetConf"; +static const char *const defaultNetSSID = "Wifi"; // fake AP/hotspot -int netApctlInfoId = 0; -SceNetApctlInfoInternal netApctlInfo; +static int netApctlInfoId = 0; -bool g_netApctlInited; -u32 netApctlState; -u32 apctlProdCodeAddr = 0; -u32 apctlThreadHackAddr = 0; -u32_le apctlThreadCode[3]; -SceUID apctlThreadID = 0; -int apctlStateEvent = -1; -int actionAfterApctlMipsCall; -std::recursive_mutex apctlEvtMtx; -std::deque apctlEvents; +static u32 apctlProdCodeAddr = 0; +static u32 apctlThreadHackAddr = 0; +static u32_le apctlThreadCode[3]; +static SceUID apctlThreadID = 0; +static int apctlStateEvent = -1; +static int actionAfterApctlMipsCall; +static std::recursive_mutex apctlEvtMtx; +static std::deque apctlEvents; -// Loaded auto-config -InfraDNSConfig g_infraDNSConfig; +// Currently loaded auto-config +static InfraDNSConfig g_infraDNSConfig; + +static u32 Net_Term(); +static int NetApctl_Term(); +static void NetApctl_InitDefaultInfo(); +static void NetApctl_InitInfo(int confId); + +const InfraDNSConfig &GetInfraDNSConfig() { + return g_infraDNSConfig; +} + +std::string InfraDNSConfig::ToString() const { + char temp[2000]; + StringWriter w(temp); + + if (!loaded) { + return "InfraDNSConfig not loaded."; + } + if (!gameName.empty()) { + w.C("Game: ").W(gameName).endl(); + } + w.C("State: "); + switch (state) { + case InfraGameState::NotWorking: w.C("Not working").endl(); break; + case InfraGameState::Working: w.C("Working").endl(); break; + case InfraGameState::Unknown: w.C("Unknown").endl(); break; + } + w.C("connectAdhocForGrouping: ").B(connectAdHocForGrouping).endl(); + w.C("DNS: ").W(dns).endl(); + if (!dyn_dns.empty()) { + w.C("DynDNS: ").W(dyn_dns).endl(); + } + if (!fixedDNS.empty()) { + w.C("Fixed DNS").endl(); + for (auto iter : fixedDNS) { + w.F("%s -> %s", iter.first.c_str(), iter.second.c_str()).endl(); + } + } + if (!revivalTeam.empty()) { + w.F("Revival team: ").W(revivalTeam).C(" (").W(revivalTeamURL).C(")").endl(); + } + w.F("Comment: ").W(comment).endl(); + return std::string(w.as_view()); +} -u32 Net_Term(); -int NetApctl_Term(); -void NetApctl_InitDefaultInfo(); -void NetApctl_InitInfo(int confId); bool IsNetworkConnected() { // TODO: Tweak this. @@ -271,6 +311,8 @@ bool LoadDNSForGameID(std::string_view gameID, std::string_view jsonStr, InfraDN } dns->loaded = true; + + NOTICE_LOG(Log::sceNet, "Loaded DNS config from JSON: %s", dns->ToString().c_str()); return true; } @@ -346,11 +388,13 @@ void StartInfraJsonDownload() { bool PollInfraJsonDownload(std::string *jsonOutput) { if (!g_Config.bInfrastructureAutoDNS) { + INFO_LOG(Log::sceNet, "Auto DNS disabled, returning success"); + jsonOutput->clear(); return true; } if (g_Config.bDontDownloadInfraJson) { - NOTICE_LOG(Log::sceNet, "As specified by the ini setting DontDownloadInfraJson, using infra-dns.json from /assets"); + NOTICE_LOG(Log::sceNet, "As specified by the ini setting DontDownloadInfraJson, using infra-dns.json directly from /assets"); size_t jsonSize = 0; std::unique_ptr jsonStr(g_VFS.ReadFile("infra-dns.json", &jsonSize)); if (!jsonStr) { @@ -478,6 +522,8 @@ void __NetCallbackInit() { } void __NetInit() { + g_infraDNSConfig = InfraDNSConfig(); + // Windows: Assuming WSAStartup already called beforehand portOffset = g_Config.iPortOffset; isOriPort = g_Config.bEnableUPnP && g_Config.bUPnPUseOriginalPort; diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index c3410cc283..e53782f609 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -159,6 +159,8 @@ struct InfraDNSConfig { std::vector workingIDs; bool connectAdHocForGrouping; + + std::string ToString() const; }; -extern InfraDNSConfig g_infraDNSConfig; +const InfraDNSConfig &GetInfraDNSConfig(); diff --git a/Core/HLE/sceNetResolver.cpp b/Core/HLE/sceNetResolver.cpp index ed83fd58ba..d6ba8de9ac 100644 --- a/Core/HLE/sceNetResolver.cpp +++ b/Core/HLE/sceNetResolver.cpp @@ -91,8 +91,11 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); } - addrinfo* resolved = nullptr; - std::string err, hostname = std::string(safe_string(Memory::GetCharPointer(hostnamePtr))); + addrinfo *resolved = nullptr; + + std::string err; + std::string hostname = std::string(safe_string(Memory::GetCharPointer(hostnamePtr))); + SockAddrIN4 addr{}; addr.in.sin_addr.s_addr = INADDR_NONE; @@ -106,8 +109,8 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, if (g_Config.bInfrastructureAutoDNS) { // Also look up into the preconfigured fixed DNS JSON. - auto fixedDNSIter = g_infraDNSConfig.fixedDNS.find(hostname); - if (fixedDNSIter != g_infraDNSConfig.fixedDNS.end()) { + auto fixedDNSIter = GetInfraDNSConfig().fixedDNS.find(hostname); + if (fixedDNSIter != GetInfraDNSConfig().fixedDNS.end()) { const std::string& domainIP = fixedDNSIter->second; INFO_LOG(Log::sceNet, "%s - Resolved IP %s from fixed DNS lookup with '%s'", __FUNCTION__, domainIP.c_str(), hostname.c_str()); hostname = domainIP; @@ -128,7 +131,13 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, // Now use the configured primary DNS server to do a lookup. // If auto DNS, use the server from that config. - const std::string &dnsServer = (g_Config.bInfrastructureAutoDNS && !g_infraDNSConfig.dns.empty()) ? g_infraDNSConfig.dns : g_Config.sInfrastructureDNSServer; + std::string dnsServer; + if (g_Config.bInfrastructureAutoDNS && !GetInfraDNSConfig().dns.empty()) { + dnsServer = GetInfraDNSConfig().dns; + } else { + dnsServer = g_Config.sInfrastructureDNSServer; + } + if (net::DirectDNSLookupIPV4(dnsServer.c_str(), hostname.c_str(), &resolvedAddr)) { char temp[32]; inet_ntop(AF_INET, &resolvedAddr, temp, sizeof(temp)); @@ -140,15 +149,15 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, WARN_LOG(Log::sceNet, "Direct DNS lookup of '%s' at DNS server '%s' failed. Trying OS DNS...", hostname.c_str(), g_Config.sInfrastructureDNSServer.c_str()); - // Attempt to execute a DNS resolution + // Attempt to execute an OS DNS resolution if (!net::DNSResolve(hostname, "", &resolved, err)) { // TODO: Return an error based on the outputted "err" (unfortunately it's already converted to string) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_HOST, "OS DNS Error Resolving %s (%s)\n", hostname.c_str(), - err.c_str()); + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_HOST, + "OS DNS Error Resolving %s (%s)\n", hostname.c_str(), err.c_str()); } // If successful, write to memory - if (resolved != nullptr) { + if (resolved) { for (auto ptr = resolved; ptr != nullptr; ptr = ptr->ai_next) { switch (ptr->ai_family) { case AF_INET: diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 681d40e29b..48a8d767d3 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -595,21 +595,24 @@ static void DrawApctl(ImConfig &cfg) { } if (g_Config.bInfrastructureAutoDNS) { - if (g_infraDNSConfig.loaded) { - if (!g_infraDNSConfig.gameName.empty()) { - ImGui::Text("Known game: %s", g_infraDNSConfig.gameName.c_str()); + const InfraDNSConfig &dnsConfig = GetInfraDNSConfig(); + if (dnsConfig.loaded) { + if (!dnsConfig.gameName.empty()) { + ImGui::Text("Known game: %s", dnsConfig.gameName.c_str()); } - ImGui::Text("connectAdhocForGrouping: %s", BoolStr(g_infraDNSConfig.connectAdHocForGrouping)); - ImGui::Text("DNS: %s", g_infraDNSConfig.dns.c_str()); - if (!g_infraDNSConfig.dyn_dns.empty()) { - ImGui::Text("DynDNS: %s", g_infraDNSConfig.dyn_dns.c_str()); + ImGui::Text("connectAdhocForGrouping: %s", BoolStr(dnsConfig.connectAdHocForGrouping)); + ImGui::Text("DNS: %s", dnsConfig.dns.c_str()); + if (!dnsConfig.dyn_dns.empty()) { + ImGui::Text("DynDNS: %s", dnsConfig.dyn_dns.c_str()); } - if (!g_infraDNSConfig.fixedDNS.empty()) { + if (!dnsConfig.fixedDNS.empty()) { ImGui::TextUnformatted("Fixed DNS"); - for (auto iter : g_infraDNSConfig.fixedDNS) { + for (auto iter : dnsConfig.fixedDNS) { ImGui::Text("%s -> %s", iter.first.c_str(), iter.second.c_str()); } } + } else { + ImGui::TextUnformatted("(InfraDNSConfig not loaded)"); } } diff --git a/UI/PauseScreen.cpp b/UI/PauseScreen.cpp index 609f332d34..01d647d02b 100644 --- a/UI/PauseScreen.cpp +++ b/UI/PauseScreen.cpp @@ -281,14 +281,15 @@ void GamePauseScreen::update() { } const bool networkConnected = IsNetworkConnected(); - if (g_netInited != lastNetInited_ || netInetInited != lastNetInetInited_ || lastAdhocServerConnected_ != g_adhocServerConnected || lastOnline_ != networkConnected || lastDNSConfigLoaded_ != g_infraDNSConfig.loaded) { + const InfraDNSConfig &dnsConfig = GetInfraDNSConfig(); + if (g_netInited != lastNetInited_ || netInetInited != lastNetInetInited_ || lastAdhocServerConnected_ != g_adhocServerConnected || lastOnline_ != networkConnected || lastDNSConfigLoaded_ != dnsConfig.loaded) { INFO_LOG(Log::sceNet, "Network status changed, recreating views"); RecreateViews(); lastNetInetInited_ = netInetInited; lastNetInited_ = g_netInited; lastAdhocServerConnected_ = g_adhocServerConnected; lastOnline_ = networkConnected; - lastDNSConfigLoaded_ = g_infraDNSConfig.loaded; + lastDNSConfigLoaded_ = dnsConfig.loaded; } const bool mustRunBehind = MustRunBehind(); @@ -394,29 +395,30 @@ void GamePauseScreen::CreateViews() { if (IsNetworkConnected()) { leftColumnItems->Add(new NoticeView(NoticeLevel::INFO, nw->T("Network connected"), "")); - if (g_infraDNSConfig.loaded && __NetApctlConnected()) { + const InfraDNSConfig &dnsConfig = GetInfraDNSConfig(); + if (dnsConfig.loaded && __NetApctlConnected()) { leftColumnItems->Add(new NoticeView(NoticeLevel::INFO, nw->T("Infrastructure"), "")); - if (g_infraDNSConfig.state == InfraGameState::NotWorking) { + if (dnsConfig.state == InfraGameState::NotWorking) { leftColumnItems->Add(new NoticeView(NoticeLevel::WARN, nw->T("Some network functionality in this game is not working"), "")); - if (!g_infraDNSConfig.workingIDs.empty()) { + if (!dnsConfig.workingIDs.empty()) { std::string str(nw->T("Other versions of this game that should work:")); - for (auto &id : g_infraDNSConfig.workingIDs) { + for (auto &id : dnsConfig.workingIDs) { str.append("\n - "); str += id; } leftColumnItems->Add(new TextView(str)); } - } else if (g_infraDNSConfig.state == InfraGameState::Unknown) { + } else if (dnsConfig.state == InfraGameState::Unknown) { leftColumnItems->Add(new NoticeView(NoticeLevel::WARN, nw->T("Network functionality in this game is not guaranteed"), "")); } - if (!g_infraDNSConfig.revivalTeam.empty()) { + if (!dnsConfig.revivalTeam.empty()) { leftColumnItems->Add(new TextView(std::string(nw->T("Infrastructure server provided by:")))); - leftColumnItems->Add(new TextView(g_infraDNSConfig.revivalTeam)); - if (!g_infraDNSConfig.revivalTeamURL.empty()) { - leftColumnItems->Add(new Button(g_infraDNSConfig.revivalTeamURL))->OnClick.Add([](UI::EventParams &e) { - if (!g_infraDNSConfig.revivalTeamURL.empty()) { - System_LaunchUrl(LaunchUrlType::BROWSER_URL, g_infraDNSConfig.revivalTeamURL.c_str()); + leftColumnItems->Add(new TextView(dnsConfig.revivalTeam)); + if (!dnsConfig.revivalTeamURL.empty()) { + leftColumnItems->Add(new Button(dnsConfig.revivalTeamURL))->OnClick.Add([&dnsConfig](UI::EventParams &e) { + if (!dnsConfig.revivalTeamURL.empty()) { + System_LaunchUrl(LaunchUrlType::BROWSER_URL, dnsConfig.revivalTeamURL.c_str()); } return UI::EVENT_DONE; });