mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-11 01:25:07 +02:00
Fetch the public adhoc server list from metadata.ppsspp.org/adhoc-servers.json
This commit is contained in:
@@ -71,7 +71,7 @@ static std::shared_ptr<Request> CreateRequest(RequestMethod method, std::string_
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Request> RequestManager::StartDownload(std::string_view url, const Path &outfile, RequestFlags flags, const char *acceptMime) {
|
||||
std::shared_ptr<Request> RequestManager::StartDownload(std::string_view url, const Path &outfile, RequestFlags flags, const char *acceptMime, std::string_view name, std::function<void(Request &)> callback) {
|
||||
const bool enableCache = !cacheDir_.empty() && (flags & RequestFlags::Cached24H);
|
||||
|
||||
// Come up with a cache file path.
|
||||
@@ -93,6 +93,7 @@ std::shared_ptr<Request> RequestManager::StartDownload(std::string_view url, con
|
||||
// All is well, but we've indented a bit much here.
|
||||
std::shared_ptr<Request> dl(new CachedRequest(RequestMethod::GET, url, KeepAfterLast(url, '/'), nullptr, flags, contents));
|
||||
newDownloads_.push_back(dl);
|
||||
dl->SetCallback(callback);
|
||||
return dl;
|
||||
} else {
|
||||
INFO_LOG(Log::sceNet, "Failed reading from cache, proceeding with request");
|
||||
@@ -105,7 +106,7 @@ std::shared_ptr<Request> RequestManager::StartDownload(std::string_view url, con
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Request> dl = CreateRequest(RequestMethod::GET, url, "", "", outfile, flags, nullptr, "");
|
||||
std::shared_ptr<Request> dl = CreateRequest(RequestMethod::GET, url, "", "", outfile, flags, nullptr, name);
|
||||
|
||||
// OK, didn't get it from cache, so let's continue with the download, putting it in the cache.
|
||||
if (enableCache) {
|
||||
@@ -119,24 +120,6 @@ std::shared_ptr<Request> RequestManager::StartDownload(std::string_view url, con
|
||||
if (acceptMime) {
|
||||
dl->SetAccept(acceptMime);
|
||||
}
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
return dl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Request> RequestManager::StartDownloadWithCallback(
|
||||
std::string_view url,
|
||||
const Path &outfile,
|
||||
RequestFlags flags,
|
||||
std::function<void(Request &)> callback,
|
||||
std::string_view name,
|
||||
const char *acceptMime) {
|
||||
std::shared_ptr<Request> dl = CreateRequest(RequestMethod::GET, url, "", "", outfile, flags, nullptr, name);
|
||||
|
||||
if (!userAgent_.empty())
|
||||
dl->SetUserAgent(userAgent_);
|
||||
if (acceptMime)
|
||||
dl->SetAccept(acceptMime);
|
||||
dl->SetCallback(callback);
|
||||
newDownloads_.push_back(dl);
|
||||
dl->Start();
|
||||
|
||||
@@ -105,15 +105,7 @@ public:
|
||||
}
|
||||
|
||||
// NOTE: This is the only version that supports the cache flag (for now).
|
||||
std::shared_ptr<Request> StartDownload(std::string_view url, const Path &outfile, RequestFlags flags, const char *acceptMime = nullptr);
|
||||
|
||||
std::shared_ptr<Request> StartDownloadWithCallback(
|
||||
std::string_view url,
|
||||
const Path &outfile,
|
||||
RequestFlags flags,
|
||||
std::function<void(Request &)> callback,
|
||||
std::string_view name = "",
|
||||
const char *acceptMime = nullptr);
|
||||
std::shared_ptr<Request> StartDownload(std::string_view url, const Path &outfile, RequestFlags flags, const char *acceptMime = nullptr, std::string_view name = "", std::function<void(Request &)> callback = {});
|
||||
|
||||
std::shared_ptr<Request> AsyncPostWithCallback(
|
||||
std::string_view url,
|
||||
|
||||
+5
-2
@@ -1027,6 +1027,8 @@ static const ConfigSetting controlSettings[] = {
|
||||
ConfigSetting("RapidFileInterval", SETTING(g_Config, iRapidFireInterval), 5, CfgFlag::DEFAULT),
|
||||
};
|
||||
|
||||
static const std::vector<std::string_view> emptyList;
|
||||
|
||||
static const ConfigSetting networkSettings[] = {
|
||||
ConfigSetting("EnableWlan", SETTING(g_Config, bEnableWlan), false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("EnableAdhocServer", SETTING(g_Config, bEnableAdhocServer), false, CfgFlag::PER_GAME),
|
||||
@@ -1043,7 +1045,8 @@ static const ConfigSetting networkSettings[] = {
|
||||
ConfigSetting("AllowSavestateWhileConnected", SETTING(g_Config, bAllowSavestateWhileConnected), false, CfgFlag::DONT_SAVE),
|
||||
ConfigSetting("AllowSpeedControlWhileConnected", SETTING(g_Config, bAllowSpeedControlWhileConnected), false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("DontDownloadInfraJson", SETTING(g_Config, bDontDownloadInfraJson), false, CfgFlag::DONT_SAVE),
|
||||
ConfigSetting("proAdhocServerList", SETTING(g_Config, vCustomAdhocServerList), &std::vector<std::string_view>(), CfgFlag::DEFAULT), // Customizable server list.
|
||||
ConfigSetting("proAdhocServerList", SETTING(g_Config, vCustomAdhocServerList), &emptyList, CfgFlag::DEFAULT), // Customizable server list.
|
||||
ConfigSetting("AdhocServerListUrl", SETTING(g_Config, sAdhocServerListUrl), "http://metadata.ppsspp.org/adhoc-servers.json", CfgFlag::DEFAULT), // URL for the server list. Can be set to a local path too.
|
||||
ConfigSetting("EnableNetworkChat", SETTING(g_Config, bEnableNetworkChat), false, CfgFlag::PER_GAME),
|
||||
ConfigSetting("ChatButtonPosition", SETTING(g_Config, iChatButtonPosition), (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME),
|
||||
ConfigSetting("ChatScreenPosition", SETTING(g_Config, iChatScreenPosition), (int)ScreenEdgePosition::BOTTOM_LEFT, CfgFlag::PER_GAME),
|
||||
@@ -1658,7 +1661,7 @@ void Config::CheckForUpdate() {
|
||||
if (checkThisTime) {
|
||||
const char *versionUrl = "http://www.ppsspp.org/version.json";
|
||||
const char *acceptMime = "application/json, text/*; q=0.9, */*; q=0.8";
|
||||
g_DownloadManager.StartDownloadWithCallback(versionUrl, Path(), http::RequestFlags::Default, [this](http::Request &download) { VersionJsonDownloadCompleted(download); }, "version", acceptMime);
|
||||
g_DownloadManager.StartDownload(versionUrl, Path(), http::RequestFlags::Default, acceptMime, "version", [this](http::Request &download) { VersionJsonDownloadCompleted(download); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -560,6 +560,8 @@ public:
|
||||
bool bInfrastructureAutoDNS;
|
||||
bool bAllowSavestateWhileConnected; // Developer option, ini-only. No normal users need this, it's always wrong to save/load state when online.
|
||||
bool bAllowSpeedControlWhileConnected; // Useful in some games but not recommended.
|
||||
|
||||
std::string sAdhocServerListUrl;
|
||||
std::vector<std::string> vCustomAdhocServerList;
|
||||
|
||||
bool bEnableWlan;
|
||||
|
||||
+45
-16
@@ -26,6 +26,7 @@
|
||||
#include "Common/Net/SocketCompat.h"
|
||||
#include "Common/Data/Format/JSONReader.h"
|
||||
#include "Common/Data/Text/I18n.h"
|
||||
#include "Common/File/FileUtil.h"
|
||||
#include "Common/Serialize/Serializer.h"
|
||||
#include "Common/Serialize/SerializeFuncs.h"
|
||||
#include "Common/Serialize/SerializeMap.h"
|
||||
@@ -34,6 +35,7 @@
|
||||
#include "Common/File/VFS/VFS.h"
|
||||
#include "Common/Thread/ThreadUtil.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/Net/HTTPRequest.h"
|
||||
|
||||
#include "Core/MIPS/MIPSCodeUtils.h"
|
||||
#include "Core/Util/PortManager.h"
|
||||
@@ -117,7 +119,7 @@ static const char *AdhocDataModeToString(AdhocDataMode mode) {
|
||||
std::mutex g_proAdhocServerListMutex;
|
||||
std::vector<AdhocServerListEntry> g_proAdhocServerList;
|
||||
|
||||
bool ParseServerListEntriesJSON(std::string_view json, std::vector<AdhocServerListEntry> *result) {
|
||||
bool ParseServerListEntriesJSON(std::string_view json) {
|
||||
using namespace json;
|
||||
|
||||
// Use our JSONReader to parse json into a list of AdhocServerListEntry.
|
||||
@@ -132,7 +134,7 @@ bool ParseServerListEntriesJSON(std::string_view json, std::vector<AdhocServerLi
|
||||
|
||||
const JsonNode *servers = root.getArray("servers");
|
||||
|
||||
result->clear();
|
||||
std::vector<AdhocServerListEntry> newList;
|
||||
|
||||
for (const JsonNode *iter : servers->value) {
|
||||
JsonGet server = iter->value;
|
||||
@@ -149,8 +151,14 @@ bool ParseServerListEntriesJSON(std::string_view json, std::vector<AdhocServerLi
|
||||
// Skipping invalid entry.
|
||||
continue;
|
||||
}
|
||||
result->push_back(entry);
|
||||
newList.push_back(entry);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(g_proAdhocServerListMutex);
|
||||
g_proAdhocServerList = newList;
|
||||
}
|
||||
System_PostUIMessage(UIMessage::ADHOC_SERVER_LIST_CHANGED);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -162,14 +170,39 @@ void AdhocLoadServerList() {
|
||||
}
|
||||
}
|
||||
|
||||
// Do this async.
|
||||
std::thread thread([]() {
|
||||
// Pretend for now, actually load later.
|
||||
// We'll first load the default hardcoded list. Then we try:
|
||||
// 1. Cached list in PSP/SYSTEM/CACHE
|
||||
// 2. Online list from some url, and cache it in PSP/SYSTEM/CACHE for next time.
|
||||
std::lock_guard<std::mutex> guard(g_proAdhocServerListMutex);
|
||||
// NOTE: If you want to load from a local file, set g_Config.sAdhocServerListUrl directly to the local path.
|
||||
// There's currently no file:// support, as far as I remember.
|
||||
|
||||
if (startsWith(g_Config.sAdhocServerListUrl, "http")) {
|
||||
// Download the list.
|
||||
g_DownloadManager.StartDownload(g_Config.sAdhocServerListUrl, Path(), http::RequestFlags::Cached24H, nullptr, "adhoc-servers", [url = g_Config.sAdhocServerListUrl](http::Request &request) {
|
||||
if (request.Failed()) {
|
||||
INFO_LOG(Log::sceNet, "Failed to download adhoc server list from %s, falling back.", url.c_str());
|
||||
|
||||
// Fall back to the asset. Don't bother doing it on a thread.
|
||||
size_t jsonSize;
|
||||
std::unique_ptr<uint8_t[]> jsonStr(g_VFS.ReadFile("adhoc-servers.json", &jsonSize));
|
||||
if (!jsonStr) {
|
||||
_dbg_assert_(false);
|
||||
// Something went wrong. This shouldn't happen.
|
||||
return;
|
||||
}
|
||||
ParseServerListEntriesJSON(std::string_view((char*)jsonStr.get(), jsonSize));
|
||||
return;
|
||||
}
|
||||
|
||||
INFO_LOG(Log::sceNet, "Successfully downloaded adhoc server list from %s", url.c_str());
|
||||
|
||||
std::string json;
|
||||
request.buffer().TakeAll(&json);
|
||||
ParseServerListEntriesJSON(std::string_view(json.data(), json.size()));
|
||||
});
|
||||
} else if (!g_Config.sAdhocServerListUrl.empty()) {
|
||||
// Try to read local file.
|
||||
std::string json;
|
||||
File::ReadTextFileToString(Path(g_Config.sAdhocServerListUrl), &json);
|
||||
ParseServerListEntriesJSON(std::string_view(json.data(), json.size()));
|
||||
} else {
|
||||
size_t jsonSize;
|
||||
std::unique_ptr<uint8_t[]> jsonStr(g_VFS.ReadFile("adhoc-servers.json", &jsonSize));
|
||||
if (!jsonStr) {
|
||||
@@ -177,12 +210,8 @@ void AdhocLoadServerList() {
|
||||
// Something went wrong. This shouldn't happen.
|
||||
return;
|
||||
}
|
||||
|
||||
ParseServerListEntriesJSON(std::string_view((char*)jsonStr.get(), jsonSize), &g_proAdhocServerList);
|
||||
|
||||
System_PostUIMessage(UIMessage::ADHOC_SERVER_LIST_CHANGED);
|
||||
});
|
||||
thread.detach();
|
||||
ParseServerListEntriesJSON(std::string_view((char*)jsonStr.get(), jsonSize));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AdhocServerListEntry> AdhocGetServerList() {
|
||||
|
||||
@@ -298,7 +298,8 @@ static void server_call_callback(const rc_api_request_t *request,
|
||||
callback(&response, callback_data);
|
||||
}, ac->T("Contacting RetroAchievements server..."));
|
||||
} else {
|
||||
std::shared_ptr<http::Request> download = g_DownloadManager.StartDownloadWithCallback(std::string(request->url), Path(), http::RequestFlags::ProgressBar | http::RequestFlags::ProgressBarDelayed,
|
||||
std::shared_ptr<http::Request> download = g_DownloadManager.StartDownload(std::string(request->url), Path(), http::RequestFlags::ProgressBar | http::RequestFlags::ProgressBarDelayed, nullptr,
|
||||
ac->T("Contacting RetroAchievements server..."),
|
||||
[callback, callback_data](http::Request &download) {
|
||||
std::string buffer;
|
||||
download.buffer().TakeAll(&buffer);
|
||||
@@ -307,7 +308,7 @@ static void server_call_callback(const rc_api_request_t *request,
|
||||
response.body_length = buffer.size();
|
||||
response.http_status_code = download.ResultCode();
|
||||
callback(&response, callback_data);
|
||||
}, ac->T("Contacting RetroAchievements server..."));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,7 +910,7 @@ bool HasAchievementsOrLeaderboards() {
|
||||
void DownloadImageIfMissing(std::string_view url) {
|
||||
if (g_iconCache.MarkPending(url)) {
|
||||
INFO_LOG(Log::Achievements, "Downloading image: %.*s", STR_VIEW(url));
|
||||
g_DownloadManager.StartDownloadWithCallback(url, Path(), http::RequestFlags::Default, [](http::Request &download) {
|
||||
g_DownloadManager.StartDownload(url, Path(), http::RequestFlags::Default, nullptr, "", [](http::Request &download) {
|
||||
if (download.ResultCode() != 200)
|
||||
return;
|
||||
std::string data;
|
||||
|
||||
@@ -119,7 +119,7 @@ void AdhocServerScreen::CreatePopupContents(UI::ViewGroup *parent) {
|
||||
AddButtonFromEntry(publicSection, entry);
|
||||
}
|
||||
|
||||
CollapsibleSection *localSection = innerView->Add(new CollapsibleSection(n->T("Local addresses"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
CollapsibleSection *localSection = innerView->Add(new CollapsibleSection(n->T("Local network addresses"), new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
|
||||
for (const auto &entry : localEntries) {
|
||||
AddButtonFromEntry(localSection, entry);
|
||||
}
|
||||
|
||||
+13
-18
@@ -64,7 +64,7 @@ public:
|
||||
|
||||
if (useIconCache && g_iconCache.MarkPending(path_)) {
|
||||
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
|
||||
requestManager_->StartDownloadWithCallback(path_, Path(), http::RequestFlags::ProgressBar | http::RequestFlags::ProgressBarDelayed, [](http::Request &download) {
|
||||
requestManager_->StartDownload(path_, Path(), http::RequestFlags::ProgressBar | http::RequestFlags::ProgressBarDelayed, acceptMime, "", [](http::Request &download) {
|
||||
// Can't touch 'this' in this function! Don't use captures!
|
||||
std::string path = download.url();
|
||||
if (download.ResultCode() == 200) {
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
} else {
|
||||
g_iconCache.CancelPending(path);
|
||||
}
|
||||
}, acceptMime);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,8 +102,6 @@ public:
|
||||
const std::string &GetFilename() const { return path_; }
|
||||
|
||||
private:
|
||||
void DownloadCompletedCallback(http::Request &download);
|
||||
|
||||
bool canFocus_ = false;
|
||||
bool useIconCache_ = false;
|
||||
std::string path_; // or cache key
|
||||
@@ -161,26 +159,23 @@ void HttpImageFileView::SetFilename(const std::string &filename) {
|
||||
}
|
||||
}
|
||||
|
||||
void HttpImageFileView::DownloadCompletedCallback(http::Request &download) {
|
||||
if (download.IsCancelled()) {
|
||||
// We were probably destroyed. Can't touch "this" (heh).
|
||||
return;
|
||||
}
|
||||
if (download.ResultCode() == 200) {
|
||||
download.buffer().TakeAll(&textureData_);
|
||||
} else {
|
||||
textureFailed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void HttpImageFileView::Draw(UIContext &dc) {
|
||||
using namespace Draw;
|
||||
|
||||
if (!useIconCache_) {
|
||||
if (!texture_ && !textureFailed_ && !path_.empty() && !download_) {
|
||||
auto cb = std::bind(&HttpImageFileView::DownloadCompletedCallback, this, std::placeholders::_1);
|
||||
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
|
||||
requestManager_->StartDownloadWithCallback(path_, Path(), http::RequestFlags::Default, cb, acceptMime);
|
||||
requestManager_->StartDownload(path_, Path(), http::RequestFlags::Default, acceptMime, "", [this](http::Request &download) {
|
||||
if (download.IsCancelled()) {
|
||||
// We were probably destroyed. Can't touch "this" (heh).
|
||||
return;
|
||||
}
|
||||
if (download.ResultCode() == 200) {
|
||||
download.buffer().TakeAll(&textureData_);
|
||||
} else {
|
||||
textureFailed_ = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!textureData_.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user