Skip to content

Commit

Permalink
Remove OO wrapper from sceNetResolver, allow create to work without s…
Browse files Browse the repository at this point in the history
…ceNetResolverInit, fix json parsing issue
  • Loading branch information
hrydgard committed Jan 16, 2025
1 parent 0717135 commit fbe0ba2
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 128 deletions.
22 changes: 12 additions & 10 deletions Core/HLE/sceNet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,22 @@ bool LoadDNSForGameID(std::string_view gameID, InfraDNSConfig *dns) {
const JsonNode *workingIdsNode = game.getArray("known_working_ids");
const JsonNode *otherIdsNode = game.getArray("other_ids");
const JsonNode *notWorkingIdsNode = game.getArray("not_working_ids");
if (!workingIdsNode) {
if (!workingIdsNode && !otherIdsNode && !notWorkingIdsNode) {
// We ignore this game.
continue;
}

bool found = false;

std::vector<std::string> ids;
JsonGet(workingIdsNode->value).getStringVector(&ids);
for (auto &id : ids) {
if (id == gameID) {
found = true;
dns->state = InfraGameState::Working;
break;
if (workingIdsNode) {
JsonGet(workingIdsNode->value).getStringVector(&ids);
for (auto &id : ids) {
if (id == gameID) {
found = true;
dns->state = InfraGameState::Working;
break;
}
}
}
if (!found && notWorkingIdsNode) {
Expand All @@ -229,7 +231,7 @@ bool LoadDNSForGameID(std::string_view gameID, InfraDNSConfig *dns) {
}
}
if (!found && otherIdsNode) {
// Check the "other" array, not sure what we do with these.
// Check the "other" array, we're gonna try this, but less confidently :P
JsonGet(otherIdsNode->value).getStringVector(&ids);
for (auto &id : ids) {
if (id == gameID) {
Expand Down Expand Up @@ -405,7 +407,7 @@ void __NetShutdown() {
// Network Cleanup
Net_Term();

SceNetResolver::Shutdown();
__NetResolverShutdown();
__NetInetShutdown();
__NetApctlShutdown();
__ResetInitNetLib();
Expand Down Expand Up @@ -500,7 +502,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();
}
}

Expand Down
167 changes: 69 additions & 98 deletions Core/HLE/sceNetResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,37 @@
#define INADDR_NONE 0xFFFFFFFF
#endif

static int mCurrentNetResolverId = 1;
static std::unordered_map<u32, std::shared_ptr<NetResolver>> mNetResolvers;
static std::shared_mutex mNetResolversLock;

// NOTE: It starts as true, needed for Outrun 2006.
static bool g_netResolverInitialized = true;

static int sceNetResolverInit() {
// TODO: Move this to infra-jns.config! This isn't ok.
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);
}

void __NetResolverShutdown() {
std::unique_lock lock(mNetResolversLock);
mNetResolvers.clear();
}

static int sceNetResolverTerm() {
SceNetResolver::Shutdown();
g_netResolverInitialized = false;
__NetResolverShutdown();
return hleLogSuccessInfoI(Log::sceNet, 0);
}

// Note: timeouts are in seconds
static 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 %d", resolverId);
}

const auto resolver = sceNetResolver->GetNetResolver(resolverId);
if (resolver == nullptr) {
std::unique_lock lock(mNetResolversLock);
auto iter = mNetResolvers.find(resolverId);
if (iter == mNetResolvers.end()) {
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId);
}

Expand Down Expand Up @@ -117,14 +125,16 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr,
}

// 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;
}
Expand Down Expand Up @@ -154,11 +164,16 @@ static int NetResolver_StartNtoA(u32 resolverId, u32 hostnamePtr, u32 inAddrPtr,
}

// Flag resolver as complete
resolver->SetIsRunning(false);
iter->second->SetIsRunning(false);
return 0;
}

static int sceNetResolverStartNtoA(int resolverId, u32 hostnamePtr, u32 inAddrPtr, int timeout, int retry) {
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);
Expand All @@ -168,7 +183,11 @@ static int sceNetResolverStartNtoA(int resolverId, u32 hostnamePtr, u32 inAddrPt
}

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);
}
Expand Down Expand Up @@ -211,43 +230,58 @@ static int sceNetResolverCreate(u32 resolverIdPtr, u32 bufferPtr, int 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");

const auto resolver = sceNetResolver->CreateNetResolver(bufferPtr, bufferLen);
if (!g_netResolverInitialized) {
// Possibly don't check this? Or auto-initialized?
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped");
}

Memory::Write_U32(resolver->GetId(), resolverIdPtr);
// 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++;
mNetResolvers[currentNetResolverId] = std::make_shared<NetResolver>(
currentNetResolverId, // id
bufferPtr, // bufferPtr
bufferLen // bufferLen
);

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) {
// Possibly don't check this? Or auto-initialized?
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_STOPPED, "Resolver Subsystem Stopped");
}

const auto resolver = sceNetResolver->GetNetResolver(resolverId);
std::unique_lock lock(mNetResolversLock);

if (resolver == nullptr)
const auto resolverIter = mNetResolvers.find(resolverId);

if (resolverIter == mNetResolvers.end())
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId);

if (!resolver->GetIsRunning())
if (resolverIter->second->GetIsRunning())
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_ALREADY_STOPPED, "Resolver Already Stopped (Id: %i)", resolverId);

resolver->SetIsRunning(false);
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) {
// Possibly don't check this? Or auto-initialized?
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(mNetResolversLock);

const auto resolverIter = mNetResolvers.find(resolverId);
if (resolverIter == mNetResolvers.end()) {
return hleLogError(Log::sceNet, ERROR_NET_RESOLVER_BAD_ID, "Bad Resolver Id: %i", resolverId);
}
mNetResolvers.erase(resolverIter);

return hleLogSuccessInfoI(Log::sceNet, 0);
}
Expand All @@ -266,69 +300,6 @@ const HLEFunction sceNetResolver[] = {
{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);
}
21 changes: 1 addition & 20 deletions Core/HLE/sceNetResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

0 comments on commit fbe0ba2

Please sign in to comment.