Refactor away the unnecessary wrapper from sceNetResolver

This commit is contained in:
Henrik Rydgård 2025-01-17 09:37:40 +01:00
parent bfcef44c48
commit b94b9b077d
4 changed files with 142 additions and 201 deletions

View file

@ -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

View file

@ -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();
}
}

View file

@ -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 <iostream>
#include <shared_mutex>
#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<u32, std::shared_ptr<NetResolver>> 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<NetResolver>(
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>, "sceNetResolverStartNtoA", 'i', "ixxii"},
{0X244172AF, &WrapI_UUI<sceNetResolverCreate>, "sceNetResolverCreate", 'i', "xxi"},
{0X94523E09, &WrapI_U<sceNetResolverDelete>, "sceNetResolverDelete", 'i', "i"},
{0XF3370E61, &WrapI_V<sceNetResolverInit>, "sceNetResolverInit", 'i', ""},
{0X808F6063, &WrapI_U<sceNetResolverStop>, "sceNetResolverStop", 'i', "i"},
{0X6138194A, &WrapI_V<sceNetResolverTerm>, "sceNetResolverTerm", 'i', ""},
{0X629E2FB7, &WrapI_IUUIII<sceNetResolverStartAtoN>, "sceNetResolverStartAtoN", 'i', "ixxiii"},
{0X14C17EF9, &WrapI_IUUII<sceNetResolverStartNtoAAsync>, "sceNetResolverStartNtoAAsync", 'i', "ixxii"},
{0XAAC09184, &WrapI_IUUIII<sceNetResolverStartAtoNAsync>, "sceNetResolverStartAtoNAsync", 'i', "ixxiii"},
{0X12748EB9, &WrapI_IU<sceNetResolverWaitAsync>, "sceNetResolverWaitAsync", 'i', "ix"},
{0X4EE99358, &WrapI_IU<sceNetResolverPollAsync>, "sceNetResolverPollAsync", 'i', "ix"},
{0X224C5F44, &WrapI_IUUII<sceNetResolverStartNtoA>, "sceNetResolverStartNtoA", 'i', "ixxii"},
{0X244172AF, &WrapI_UUI<sceNetResolverCreate>, "sceNetResolverCreate", 'i', "xxi"},
{0X94523E09, &WrapI_U<sceNetResolverDelete>, "sceNetResolverDelete", 'i', "i"},
{0XF3370E61, &WrapI_V<sceNetResolverInit>, "sceNetResolverInit", 'i', ""},
{0X808F6063, &WrapI_U<sceNetResolverStop>, "sceNetResolverStop", 'i', "i"},
{0X6138194A, &WrapI_V<sceNetResolverTerm>, "sceNetResolverTerm", 'i', ""},
{0X629E2FB7, &WrapI_IUUIII<sceNetResolverStartAtoN>, "sceNetResolverStartAtoN", 'i', "ixxiii"},
{0X14C17EF9, &WrapI_IUUII<sceNetResolverStartNtoAAsync>, "sceNetResolverStartNtoAAsync", 'i', "ixxii"},
{0XAAC09184, &WrapI_IUUIII<sceNetResolverStartAtoNAsync>, "sceNetResolverStartAtoNAsync", 'i', "ixxiii"},
{0X12748EB9, &WrapI_IU<sceNetResolverWaitAsync>, "sceNetResolverWaitAsync", 'i', "ix"},
{0X4EE99358, &WrapI_IU<sceNetResolverPollAsync>, "sceNetResolverPollAsync", 'i', "ix"},
};
std::shared_ptr<SceNetResolver> SceNetResolver::gInstance;
std::shared_mutex SceNetResolver::gLock;
void SceNetResolver::Init() {
auto lock = std::unique_lock(gLock);
gInstance = std::make_shared<SceNetResolver>();
}
void SceNetResolver::Shutdown() {
auto lock = std::unique_lock(gLock);
gInstance = nullptr;
}
std::shared_ptr<SceNetResolver> SceNetResolver::Get() {
auto lock = std::shared_lock(gLock);
return gInstance;
}
std::shared_ptr<NetResolver> 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<NetResolver> 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<NetResolver>(
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);
}

View file

@ -79,25 +79,6 @@ enum {
ERROR_NET_RESOLVER_INTERNAL = 0x80410417,
};
class SceNetResolver {
public:
static void Init();
static void Shutdown();
static std::shared_ptr<SceNetResolver> Get();
std::shared_ptr<NetResolver> GetNetResolver(u32 resolverId);
std::shared_ptr<NetResolver> CreateNetResolver(u32 bufferPtr, u32 bufferLen);
bool TerminateNetResolver(u32 resolverId);
bool DeleteNetResolver(u32 resolverId);
void ClearNetResolvers();
private:
static std::shared_ptr<SceNetResolver> gInstance;
static std::shared_mutex gLock;
int mCurrentNetResolverId = 1;
std::unordered_map<u32, std::shared_ptr<NetResolver>> mNetResolvers;
std::shared_mutex mNetResolversLock;
};
void __NetResolverShutdown();
void Register_sceNetResolver();