mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Avoid the HTTP request on sceNetAdhoc init by reading from cache
This commit is contained in:
1 parent
8c8dd0f0d0
commit
ae08b31573
3 files changed
+50
-22
No files matched your search
+38
-18
@@ -115,12 +115,13 @@ static const char *AdhocDataModeToString(AdhocDataMode mode) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
// TODO download the list from somewhere and probably cache it on disk
|
||||
// should also make the url configurable and support file:/ local list besides https:// online lists
|
||||
// We download the list and cache it on disk.
|
||||
// The URL can also be a local file path, in which case the download doesn't happen. This is only
|
||||
// for power users / debugging.
|
||||
std::mutex g_proAdhocServerListMutex;
|
||||
std::vector<AdhocServerListEntry> g_proAdhocServerList;
|
||||
|
||||
bool ParseServerListEntriesJSON(std::string_view json) {
|
||||
static bool ParseServerListEntriesJSON(std::string_view json) {
|
||||
using namespace json;
|
||||
|
||||
// Use our JSONReader to parse json into a list of AdhocServerListEntry.
|
||||
@@ -148,6 +149,7 @@ bool ParseServerListEntriesJSON(std::string_view json) {
|
||||
entry.location = server.getStringOr("location", "");
|
||||
entry.description = server.getStringOr("description", "");
|
||||
entry.mode = equals(server.getStringOr("data_mode", ""), "AemuPostoffice") ? AdhocDataMode::AemuPostoffice : AdhocDataMode::P2P;
|
||||
entry.statusUrl = server.getStringOr("status_url", "");
|
||||
|
||||
if (entry.host.empty()) {
|
||||
// Skipping invalid entry.
|
||||
@@ -178,7 +180,7 @@ static void LoadFallbackServerList() {
|
||||
g_serverListLoaded = true;
|
||||
}
|
||||
|
||||
void AdhocLoadServerList(bool sync) {
|
||||
void AdhocLoadServerList(AdhocLoadListMode loadMode) {
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_proAdhocServerListMutex);
|
||||
if (!g_proAdhocServerList.empty()) {
|
||||
@@ -190,6 +192,19 @@ void AdhocLoadServerList(bool sync) {
|
||||
// There's currently no file:// support, as far as I remember.
|
||||
|
||||
if (startsWith(g_Config.sAdhocServerListUrl, "http")) {
|
||||
if (loadMode == AdhocLoadListMode::CacheOnlySync) {
|
||||
std::string json;
|
||||
if (g_DownloadManager.ReadFileFromCache(g_Config.sAdhocServerListUrl, &json)) {
|
||||
if (ParseServerListEntriesJSON(std::string_view(json.data(), json.size()))) {
|
||||
g_serverListLoaded = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ERROR_LOG(Log::sceNet, "Failed to load cached adhoc server list %s from cache, falling back.", g_Config.sAdhocServerListUrl.c_str());
|
||||
LoadFallbackServerList();
|
||||
return;
|
||||
}
|
||||
|
||||
// Download the list.
|
||||
auto dl = g_DownloadManager.StartDownload(g_Config.sAdhocServerListUrl, Path(), http::RequestFlags::Cached24H, nullptr, "adhoc-servers", [url = g_Config.sAdhocServerListUrl](http::Request &request) {
|
||||
if (request.Failed()) {
|
||||
@@ -207,15 +222,6 @@ void AdhocLoadServerList(bool sync) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (sync) {
|
||||
// Unfortunate.
|
||||
do {
|
||||
sleep_ms(10, "waiting-for-adhoc-server-list");
|
||||
g_DownloadManager.Update();
|
||||
} while (!dl->HasRunCallback());
|
||||
dl.reset();
|
||||
}
|
||||
g_serverListLoaded = true;
|
||||
} else if (!g_Config.sAdhocServerListUrl.empty()) {
|
||||
// Try to read local file.
|
||||
@@ -234,11 +240,11 @@ void AdhocLoadServerList(bool sync) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AdhocServerListEntry> AdhocGetServerList(bool sync) {
|
||||
std::vector<AdhocServerListEntry> AdhocGetServerList(AdhocLoadListMode loadMode) {
|
||||
if (!g_serverListLoaded) {
|
||||
// In-game - unfortunately we have to do a synchronous load here.
|
||||
// If cached it will be fast though.
|
||||
AdhocLoadServerList(sync);
|
||||
// We're probably in-game - so we don't want to do a download and risk blocking.
|
||||
// Instead we read out of cache, it should be good enough.
|
||||
AdhocLoadServerList(loadMode);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(g_proAdhocServerListMutex);
|
||||
@@ -246,7 +252,7 @@ std::vector<AdhocServerListEntry> AdhocGetServerList(bool sync) {
|
||||
}
|
||||
|
||||
static AdhocDataMode AdhocGetServerDataMode(std::string_view server) {
|
||||
std::vector<AdhocServerListEntry> list = AdhocGetServerList(true);
|
||||
std::vector<AdhocServerListEntry> list = AdhocGetServerList(AdhocLoadListMode::CacheOnlySync);
|
||||
for (const auto &item : list) {
|
||||
if (equals(server, item.host)) {
|
||||
INFO_LOG(Log::sceNet, "server %.*s is in known list, using data mode %s", STR_VIEW(server), AdhocDataModeToString(item.mode));
|
||||
@@ -254,6 +260,20 @@ static AdhocDataMode AdhocGetServerDataMode(std::string_view server) {
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &item : g_Config.vCustomAdhocServerList) {
|
||||
if (equals(server, item)) {
|
||||
INFO_LOG(Log::sceNet, "server %.*s is in custom list without relay, using data mode %s", STR_VIEW(server), AdhocDataModeToString(AdhocDataMode::P2P));
|
||||
return AdhocDataMode::P2P;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &item : g_Config.vCustomAdhocServerListWithRelay) {
|
||||
if (equals(server, item)) {
|
||||
INFO_LOG(Log::sceNet, "server %.*s is in custom list with relay, using data mode %s", STR_VIEW(server), AdhocDataModeToString(AdhocDataMode::AemuPostoffice));
|
||||
return AdhocDataMode::AemuPostoffice;
|
||||
}
|
||||
}
|
||||
|
||||
INFO_LOG(Log::sceNet, "server %.*s is not in known list, using data mode %s", STR_VIEW(server), AdhocDataModeToString(AdhocDataMode::P2P));
|
||||
return AdhocDataMode::P2P;
|
||||
}
|
||||
|
||||
@@ -111,11 +111,17 @@ struct AdhocServerListEntry {
|
||||
std::string discord;
|
||||
std::string location;
|
||||
std::string description;
|
||||
std::string statusUrl; // Usually empty or /data.json.
|
||||
AdhocDataMode mode = AdhocDataMode::P2P;
|
||||
};
|
||||
|
||||
void AdhocLoadServerList(bool sync = false);
|
||||
std::vector<AdhocServerListEntry> AdhocGetServerList(bool sync = false);
|
||||
enum class AdhocLoadListMode {
|
||||
CacheOnlySync,
|
||||
AllSourcesAsync,
|
||||
};
|
||||
|
||||
void AdhocLoadServerList(AdhocLoadListMode loadMode);
|
||||
std::vector<AdhocServerListEntry> AdhocGetServerList(AdhocLoadListMode loadMode);
|
||||
|
||||
class PointerWrap;
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ AdhocServerScreen::AdhocServerScreen(std::string *value, std::string_view title)
|
||||
thiz->ResolverThread();
|
||||
}, this);
|
||||
editValue_ = *value;
|
||||
AdhocLoadServerList();
|
||||
AdhocLoadServerList(AdhocLoadListMode::AllSourcesAsync);
|
||||
}
|
||||
|
||||
AdhocServerScreen::~AdhocServerScreen() {
|
||||
@@ -188,7 +188,9 @@ void AdhocServerScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
auto di = GetI18NCategory(I18NCat::DIALOG);
|
||||
auto n = GetI18NCategory(I18NCat::NETWORKING);
|
||||
|
||||
auto listItems = AdhocGetServerList();
|
||||
// We already kicked off loading the server list in the constructor, so by now it should be either loaded or in the process of loading.
|
||||
// We can get the cached list immediately, and then update it when the async load finishes.
|
||||
auto listItems = AdhocGetServerList(AdhocLoadListMode::CacheOnlySync);
|
||||
|
||||
PopupTextInputChoice *textInputChoice = parent->Add(new PopupTextInputChoice(GetRequesterToken(), &editValue_, n->T("Hostname"), "", 450, screenManager()));
|
||||
parent->Add(new Spacer(5.0f));
|
||||
|
||||
Reference in new issue
Block a user