diff --git a/Common/Net/SocketCompat.h b/Common/Net/SocketCompat.h index 49e82df860..575815ecb5 100644 --- a/Common/Net/SocketCompat.h +++ b/Common/Net/SocketCompat.h @@ -37,6 +37,11 @@ extern "C" struct hostent *gethostbyname(const char *name); #endif // defined(HAVE_LIBNX) || PPSSPP_PLATFORM(SWITCH) +#if PPSSPP_PLATFORM(SWITCH) && !defined(INADDR_NONE) +// Missing toolchain define +#define INADDR_NONE 0xFFFFFFFF +#endif + // TODO: move this to some common set #if PPSSPP_PLATFORM(WINDOWS) #undef ESHUTDOWN diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a68b440266..d6279b1bd1 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -52,11 +52,6 @@ #include "Core/HLE/sceNetInet.h" #include "Core/HLE/sceNetResolver.h" -#if PPSSPP_PLATFORM(SWITCH) && !defined(INADDR_NONE) -// Missing toolchain define -#define INADDR_NONE 0xFFFFFFFF -#endif - bool netInited; u32 netDropRate = 0; @@ -407,7 +402,7 @@ void __NetShutdown() { // Network Cleanup Net_Term(); - SceNetResolver::Shutdown(); + __NetResolverShutdown(); __NetInetShutdown(); __NetApctlShutdown(); __ResetInitNetLib(); @@ -502,7 +497,7 @@ void __NetDoState(PointerWrap &p) { // Discard leftover events apctlEvents.clear(); // Discard created resolvers for now (since i'm not sure whether the information in the struct is sufficient or not, and we don't support multi-threading yet anyway) - SceNetResolver::Shutdown(); + __NetResolverShutdown(); } } diff --git a/Core/HLE/sceNetResolver.cpp b/Core/HLE/sceNetResolver.cpp index 316b713a33..654066e6c9 100644 --- a/Core/HLE/sceNetResolver.cpp +++ b/Core/HLE/sceNetResolver.cpp @@ -33,7 +33,6 @@ #include "Core/HLE/FunctionWrappers.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/MIPS/MIPS.h" -#include "Core/Config.h" #include "Core/MemMapHelpers.h" #include "Core/Util/PortManager.h" @@ -48,52 +47,57 @@ #include #include -#include "sceNet.h" +#include "Core/HLE/sceNet.h" #include "Core/HLE/sceNp.h" #include "Core/Reporting.h" #include "Core/Instance.h" -#if PPSSPP_PLATFORM(SWITCH) && !defined(INADDR_NONE) -// Missing toolchain define -#define INADDR_NONE 0xFFFFFFFF -#endif +static int g_currentNetResolverId = 1; +static std::unordered_map> g_netResolvers; +static std::shared_mutex g_netResolversLock; + +// NOTE: It starts as true, needed for Outrun 2006. +static bool g_netResolverInitialized = true; static int sceNetResolverInit() { - g_Config.mHostToAlias["socomftb2.psp.online.scea.com"] = "67.222.156.250"; - g_Config.mHostToAlias["socompsp-prod.muis.pdonline.scea.com"] = "67.222.156.250"; - SceNetResolver::Init(); - return hleLogSuccessInfoI(Log::sceNet, 0); + // TODO: Move this to infra-jns.config! This isn't ok. + // However obviously don't remove the mHostToAlias mechanism. + g_Config.mHostToAlias["socomftb2.psp.online.scea.com"] = "67.222.156.250"; + g_Config.mHostToAlias["socompsp-prod.muis.pdonline.scea.com"] = "67.222.156.250"; + + return hleLogSuccessInfoI(Log::sceNet, 0); +} + +void __NetResolverShutdown() { + std::unique_lock lock(g_netResolversLock); + g_netResolvers.clear(); } static int sceNetResolverTerm() { - SceNetResolver::Shutdown(); + g_netResolverInitialized = false; + __NetResolverShutdown(); return hleLogSuccessInfoI(Log::sceNet, 0); } // Note: timeouts are in seconds -int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, int timeout, int retry) { - auto sceNetResolver = SceNetResolver::Get(); - if (!sceNetResolver) { - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Net Resolver Subsystem Shutdown: Resolver %i", - resolverId); - } +static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, int timeout, int retry) { + std::unique_lock lock(g_netResolversLock); + auto iter = g_netResolvers.find(resolverId); + if (iter == g_netResolvers.end()) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); + } - const auto resolver = sceNetResolver->GetNetResolver(resolverId); - if (resolver == nullptr) { - 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))); + SockAddrIN4 addr{}; + addr.in.sin_addr.s_addr = INADDR_NONE; - addrinfo* resolved = nullptr; - std::string err, hostname = std::string(safe_string(Memory::GetCharPointer(hostnamePtr))); - SockAddrIN4 addr{}; - addr.in.sin_addr.s_addr = INADDR_NONE; - - // Resolve any aliases. First check the ini file, then check the hardcoded DNS config. + // Resolve any aliases. First check the ini file, then check the hardcoded DNS config. auto aliasIter = g_Config.mHostToAlias.find(hostname); - if (aliasIter != g_Config.mHostToAlias.end()) { - const std::string& alias = aliasIter->second; - INFO_LOG(Log::sceNet, "%s - Resolved alias %s from hostname %s", __FUNCTION__, alias.c_str(), hostname.c_str()); - hostname = alias; + if (aliasIter != g_Config.mHostToAlias.end()) { + const std::string& alias = aliasIter->second; + INFO_LOG(Log::sceNet, "%s - Resolved alias %s from hostname %s", __FUNCTION__, alias.c_str(), hostname.c_str()); + hostname = alias; } if (g_Config.bInfrastructureAutoDNS) { @@ -116,78 +120,85 @@ int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr, int ti } // Flag resolver as in-progress - not relevant for sync functions but potentially relevant for async - resolver->SetIsRunning(true); + iter->second->SetIsRunning(true); // 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; if (net::DirectDNSLookupIPV4(dnsServer.c_str(), hostname.c_str(), &resolvedAddr)) { - INFO_LOG(Log::sceNet, "Direct lookup of '%s' from '%s' succeeded: %08x", hostname.c_str(), dnsServer.c_str(), resolvedAddr); - resolver->SetIsRunning(false); + char temp[32]; + inet_ntop(AF_INET, &resolvedAddr, temp, sizeof(temp)); + INFO_LOG(Log::sceNet, "Direct lookup of '%s' from '%s' succeeded: %s (%08x)", hostname.c_str(), dnsServer.c_str(), temp, resolvedAddr); + iter->second->SetIsRunning(false); Memory::Write_U32(resolvedAddr, inAddrPtr); return 0; } 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 - 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()); - } + 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()); + } - // If successful, write to memory - if (resolved != nullptr) { - for (auto ptr = resolved; ptr != nullptr; ptr = ptr->ai_next) { - switch (ptr->ai_family) { - case AF_INET: - addr.in = *(sockaddr_in *) ptr->ai_addr; - break; - } - } - net::DNSResolveFree(resolved); + // If successful, write to memory + if (resolved != nullptr) { + for (auto ptr = resolved; ptr != nullptr; ptr = ptr->ai_next) { + switch (ptr->ai_family) { + case AF_INET: + addr.in = *(sockaddr_in *)ptr->ai_addr; + break; + } + } + net::DNSResolveFree(resolved); - Memory::Write_U32(addr.in.sin_addr.s_addr, inAddrPtr); - INFO_LOG(Log::sceNet, "%s - Hostname: %s => IPv4: %s", __FUNCTION__, hostname.c_str(), - ip2str(addr.in.sin_addr, false).c_str()); - } + Memory::Write_U32(addr.in.sin_addr.s_addr, inAddrPtr); + INFO_LOG(Log::sceNet, "%s - Hostname: %s => IPv4: %s", __FUNCTION__, hostname.c_str(), + ip2str(addr.in.sin_addr, false).c_str()); + } - // Flag resolver as complete - resolver->SetIsRunning(false); - return 0; + // Flag resolver as complete + iter->second->SetIsRunning(false); + return 0; } static int sceNetResolverStartNtoA(int resolverId, u32 hostnamePtr, u32 inAddrPtr, int timeout, int retry) { - for (int attempt = 0; attempt < retry; ++attempt) { - if (const int status = NetResolver_StartNtoA(resolverId, hostnamePtr, inAddrPtr, timeout, retry); status >= 0) { - return hleLogSuccessInfoI(Log::sceNet, status); - } - } - return -1; + if (!g_netResolverInitialized) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped (Resolver Id: %i)", resolverId); + } + + for (int attempt = 0; attempt < retry; ++attempt) { + if (const int status = NetResolver_StartNtoA(resolverId, hostnamePtr, inAddrPtr, timeout, retry); status >= 0) { + return hleLogSuccessInfoI(Log::sceNet, status); + } + } + return -1; } static int sceNetResolverStartNtoAAsync(int resolverId, u32 hostnamePtr, u32 inAddrPtr, int timeout, int retry) { - ERROR_LOG_REPORT_ONCE(sceNetResolverStartNtoAAsync, Log::sceNet, "UNIMPL %s(%d, %08x, %08x, %d, %d) at %08x", + if (!g_netResolverInitialized) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped (Resolver Id: %i)", + resolverId); + } + ERROR_LOG_REPORT_ONCE(sceNetResolverStartNtoAAsync, Log::sceNet, "UNIMPL %s(%d, %08x, %08x, %d, %d) at %08x", __FUNCTION__, resolverId, hostnamePtr, inAddrPtr, timeout, retry, currentMIPS->pc); return NetResolver_StartNtoA(resolverId, hostnamePtr, inAddrPtr, timeout, retry); } static int sceNetResolverPollAsync(int resolverId, u32 unknown) { - ERROR_LOG_REPORT_ONCE(sceNetResolverPollAsync, Log::sceNet, "UNIMPL %s(%d, %08x) at %08x", __FUNCTION__, resolverId, - unknown, currentMIPS->pc); + ERROR_LOG_REPORT_ONCE(sceNetResolverPollAsync, Log::sceNet, "UNIMPL %s(%d, %08x) at %08x", __FUNCTION__, resolverId, unknown, currentMIPS->pc); // TODO: Implement after confirming that this returns the state of resolver.isRunning return 0; } static int sceNetResolverWaitAsync(int resolverId, u32 unknown) { - ERROR_LOG_REPORT_ONCE(sceNetResolverWaitAsync, Log::sceNet, "UNIMPL %s(%d, %08x) at %08x", __FUNCTION__, resolverId, - unknown, currentMIPS->pc); + ERROR_LOG_REPORT_ONCE(sceNetResolverWaitAsync, Log::sceNet, "UNIMPL %s(%d, %08x) at %08x", __FUNCTION__, resolverId, unknown, currentMIPS->pc); // TODO: Implement after confirming that this blocks current thread until resolver.isRunning flips to false return 0; } -static int sceNetResolverStartAtoN(int resolverId, u32 inAddr, u32 hostnamePtr, int hostnameLength, int timeout, - int retry) { +static int sceNetResolverStartAtoN(int resolverId, u32 inAddr, u32 hostnamePtr, int hostnameLength, int timeout, int retry) { ERROR_LOG_REPORT_ONCE(sceNetResolverStartAtoN, Log::sceNet, "UNIMPL %s(%d, %08x[%s], %08x, %i, %i, %i) at %08x", __FUNCTION__, resolverId, inAddr, ip2str(*(in_addr*)&inAddr, false).c_str(), hostnamePtr, hostnameLength, timeout, retry, currentMIPS->pc); @@ -195,8 +206,7 @@ static int sceNetResolverStartAtoN(int resolverId, u32 inAddr, u32 hostnamePtr, return 0; } -static int sceNetResolverStartAtoNAsync(int resolverId, u32 inAddr, u32 hostnamePtr, int hostnameLength, int timeout, - int retry) { +static int sceNetResolverStartAtoNAsync(int resolverId, u32 inAddr, u32 hostnamePtr, int hostnameLength, int timeout, int retry) { ERROR_LOG_REPORT_ONCE(sceNetResolverStartAtoNAsync, Log::sceNet, "UNIMPL %s(%d, %08x[%s], %08x, %i, %i, %i) at %08x", __FUNCTION__, resolverId, inAddr, ip2str(*(in_addr*)&inAddr, false).c_str(), hostnamePtr, hostnameLength, timeout, retry, currentMIPS->pc); @@ -204,130 +214,80 @@ static int sceNetResolverStartAtoNAsync(int resolverId, u32 inAddr, u32 hostname } static int sceNetResolverCreate(u32 resolverIdPtr, u32 bufferPtr, int bufferLen) { - if (!Memory::IsValidRange(resolverIdPtr, 4)) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_PTR, "Invalid Ptr: %08x", resolverIdPtr); + if (!Memory::IsValidRange(resolverIdPtr, 4)) + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_PTR, "Invalid Ptr: %08x", resolverIdPtr); - if (Memory::IsValidRange(bufferPtr, 4) && bufferLen < 1) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_BUFLEN, "Invalid Buffer Length: %i", bufferLen); + if (Memory::IsValidRange(bufferPtr, 4) && bufferLen < 1) + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_INVALID_BUFLEN, "Invalid Buffer Length: %i", bufferLen); - auto sceNetResolver = SceNetResolver::Get(); - if (!sceNetResolver) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped"); + if (!g_netResolverInitialized) { + // Possibly don't check this? Or auto-initialized? Outrun seems to assume it's not needed. + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped"); + } - const auto resolver = sceNetResolver->CreateNetResolver(bufferPtr, bufferLen); + // TODO: Consider using SceUidManager instead of this 1-indexed id + // TODO: Implement ERROR_NET_RESOLVER_ID_MAX (possibly 32?) + std::unique_lock lock(g_netResolversLock); + int currentNetResolverId = g_currentNetResolverId++; + g_netResolvers[currentNetResolverId] = std::make_shared( + currentNetResolverId, // id + bufferPtr, // bufferPtr + bufferLen // bufferLen + ); - Memory::Write_U32(resolver->GetId(), resolverIdPtr); - return hleLogSuccessInfoI(Log::sceNet, 0, "ID: %d", Memory::Read_U32(resolverIdPtr)); + Memory::Write_U32(currentNetResolverId, resolverIdPtr); + return hleLogSuccessInfoI(Log::sceNet, 0, "ID: %d", Memory::Read_U32(resolverIdPtr)); } static int sceNetResolverStop(u32 resolverId) { - auto sceNetResolver = SceNetResolver::Get(); - if (!sceNetResolver) { - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped (Resolver Id: %i)", - resolverId); - } + if (!g_netResolverInitialized) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped"); + } - const auto resolver = sceNetResolver->GetNetResolver(resolverId); + std::unique_lock lock(g_netResolversLock); - if (resolver == nullptr) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); + const auto resolverIter = g_netResolvers.find(resolverId); - if (!resolver->GetIsRunning()) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_ALREADY_STOPPED, "Resolver Already Stopped (Id: %i)", resolverId); + if (resolverIter == g_netResolvers.end()) + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); - resolver->SetIsRunning(false); - return hleLogSuccessInfoI(Log::sceNet, 0); + if (resolverIter->second->GetIsRunning()) + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_ALREADY_STOPPED, "Resolver Already Stopped (Id: %i)", resolverId); + + resolverIter->second->SetIsRunning(false); + return hleLogSuccessInfoI(Log::sceNet, 0); } static int sceNetResolverDelete(u32 resolverId) { - auto sceNetResolver = SceNetResolver::Get(); - if (!sceNetResolver) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped (Resolver Id: %i)", - resolverId); + if (!g_netResolverInitialized) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped"); + } - if (!sceNetResolver->DeleteNetResolver(resolverId)) - return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); + std::unique_lock lock(g_netResolversLock); + + const auto resolverIter = g_netResolvers.find(resolverId); + if (resolverIter == g_netResolvers.end()) { + return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId); + } + g_netResolvers.erase(resolverIter); return hleLogSuccessInfoI(Log::sceNet, 0); } const HLEFunction sceNetResolver[] = { - {0X224C5F44, &WrapI_IUUII, "sceNetResolverStartNtoA", 'i', "ixxii"}, - {0X244172AF, &WrapI_UUI, "sceNetResolverCreate", 'i', "xxi"}, - {0X94523E09, &WrapI_U, "sceNetResolverDelete", 'i', "i"}, - {0XF3370E61, &WrapI_V, "sceNetResolverInit", 'i', ""}, - {0X808F6063, &WrapI_U, "sceNetResolverStop", 'i', "i"}, - {0X6138194A, &WrapI_V, "sceNetResolverTerm", 'i', ""}, - {0X629E2FB7, &WrapI_IUUIII, "sceNetResolverStartAtoN", 'i', "ixxiii"}, - {0X14C17EF9, &WrapI_IUUII, "sceNetResolverStartNtoAAsync", 'i', "ixxii"}, - {0XAAC09184, &WrapI_IUUIII, "sceNetResolverStartAtoNAsync", 'i', "ixxiii"}, - {0X12748EB9, &WrapI_IU, "sceNetResolverWaitAsync", 'i', "ix"}, - {0X4EE99358, &WrapI_IU, "sceNetResolverPollAsync", 'i', "ix"}, + {0X224C5F44, &WrapI_IUUII, "sceNetResolverStartNtoA", 'i', "ixxii"}, + {0X244172AF, &WrapI_UUI, "sceNetResolverCreate", 'i', "xxi"}, + {0X94523E09, &WrapI_U, "sceNetResolverDelete", 'i', "i"}, + {0XF3370E61, &WrapI_V, "sceNetResolverInit", 'i', ""}, + {0X808F6063, &WrapI_U, "sceNetResolverStop", 'i', "i"}, + {0X6138194A, &WrapI_V, "sceNetResolverTerm", 'i', ""}, + {0X629E2FB7, &WrapI_IUUIII, "sceNetResolverStartAtoN", 'i', "ixxiii"}, + {0X14C17EF9, &WrapI_IUUII, "sceNetResolverStartNtoAAsync", 'i', "ixxii"}, + {0XAAC09184, &WrapI_IUUIII, "sceNetResolverStartAtoNAsync", 'i', "ixxiii"}, + {0X12748EB9, &WrapI_IU, "sceNetResolverWaitAsync", 'i', "ix"}, + {0X4EE99358, &WrapI_IU, "sceNetResolverPollAsync", 'i', "ix"}, }; -std::shared_ptr SceNetResolver::gInstance; -std::shared_mutex SceNetResolver::gLock; - -void SceNetResolver::Init() { - auto lock = std::unique_lock(gLock); - gInstance = std::make_shared(); -} - -void SceNetResolver::Shutdown() { - auto lock = std::unique_lock(gLock); - gInstance = nullptr; -} - -std::shared_ptr SceNetResolver::Get() { - auto lock = std::shared_lock(gLock); - return gInstance; -} - -std::shared_ptr SceNetResolver::GetNetResolver(u32 resolverId) { - std::shared_lock lock(mNetResolversLock); - const auto it = mNetResolvers.find(resolverId); - return it != mNetResolvers.end() ? it->second : nullptr; -} - -std::shared_ptr SceNetResolver::CreateNetResolver(u32 bufferPtr, u32 bufferLen) { - // TODO: Consider using SceUidManager instead of this 1-indexed id - // TODO: Implement ERROR_NET_RESOLVER_ID_MAX (possibly 32?) - std::unique_lock lock(mNetResolversLock); - int currentNetResolverId = mCurrentNetResolverId++; - return mNetResolvers[currentNetResolverId] = std::make_shared( - currentNetResolverId, // id - bufferPtr, // bufferPtr - bufferLen // bufferLen - ); -} - -bool SceNetResolver::TerminateNetResolver(u32 resolverId) { - const auto netResolver = GetNetResolver(resolverId); - if (netResolver == nullptr) { - return false; - } - netResolver->SetIsRunning(false); - return true; -} - -bool SceNetResolver::DeleteNetResolver(u32 resolverId) { - std::unique_lock lock(mNetResolversLock); - const auto it = mNetResolvers.find(resolverId); - if (it == mNetResolvers.end()) { - return false; - } - mNetResolvers.erase(it); - return true; -} - -void SceNetResolver::ClearNetResolvers() { - std::unique_lock lock(mNetResolversLock); - for (auto &[first, second]: mNetResolvers) { - second->SetIsRunning(false); - } - mNetResolvers.clear(); -} - void Register_sceNetResolver() { - RegisterModule("sceNetResolver", ARRAY_SIZE(sceNetResolver), sceNetResolver); + RegisterModule("sceNetResolver", ARRAY_SIZE(sceNetResolver), sceNetResolver); } diff --git a/Core/HLE/sceNetResolver.h b/Core/HLE/sceNetResolver.h index 5e155c6adf..a85669d8f9 100644 --- a/Core/HLE/sceNetResolver.h +++ b/Core/HLE/sceNetResolver.h @@ -79,25 +79,6 @@ enum { ERROR_NET_RESOLVER_INTERNAL = 0x80410417, }; -class SceNetResolver { -public: - static void Init(); - static void Shutdown(); - static std::shared_ptr Get(); - - std::shared_ptr GetNetResolver(u32 resolverId); - std::shared_ptr CreateNetResolver(u32 bufferPtr, u32 bufferLen); - bool TerminateNetResolver(u32 resolverId); - bool DeleteNetResolver(u32 resolverId); - void ClearNetResolvers(); - -private: - static std::shared_ptr gInstance; - static std::shared_mutex gLock; - - int mCurrentNetResolverId = 1; - std::unordered_map> mNetResolvers; - std::shared_mutex mNetResolversLock; -}; +void __NetResolverShutdown(); void Register_sceNetResolver();