mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Implement manifest based update logic
This checks the local manifest with that of the remote, and updates the game as necessary.
This commit is contained in:
parent
97dc1f646e
commit
cc3b17b342
@ -101,7 +101,7 @@ CBaseSurface::CBaseSurface()
|
||||
this->m_ExperimentalBuildsCheckbox->SetSize({ 250, 18 });
|
||||
this->m_ExperimentalBuildsCheckbox->SetLocation({ 10, 170 });
|
||||
this->m_ExperimentalBuildsCheckbox->SetTabIndex(0);
|
||||
this->m_ExperimentalBuildsCheckbox->SetText(XorStr("Also check for playtest versions updates"));
|
||||
this->m_ExperimentalBuildsCheckbox->SetText(XorStr("Check for playtest/event updates"));
|
||||
this->m_ExperimentalBuildsCheckbox->SetAnchor(Forms::AnchorStyles::Top | Forms::AnchorStyles::Left);
|
||||
|
||||
// TODO: remove this when its made public!!!
|
||||
@ -188,11 +188,9 @@ void CBaseSurface::OnUpdateClick(Forms::Control* Sender)
|
||||
}
|
||||
|
||||
CUtlVector<CUtlString> fileList;
|
||||
SDKLauncher_BeginDownload(true, false, true, fileList, pProgress);
|
||||
|
||||
pProgress->SetCanCancel(false);
|
||||
|
||||
SDKLauncher_InstallAssetList(false, fileList, pProgress);
|
||||
if (SDKLauncher_BeginInstall(true, false, fileList, pProgress))
|
||||
{
|
||||
}
|
||||
|
||||
// Close on finish.
|
||||
pProgress->Close();
|
||||
@ -218,20 +216,20 @@ void CBaseSurface::OnInstallClick(Forms::Control* Sender)
|
||||
}
|
||||
|
||||
|
||||
CBaseSurface* pSurf = (CBaseSurface*)Sender;
|
||||
const bool bPartial = pSurf->m_bPartialInstall;
|
||||
//CBaseSurface* pSurf = (CBaseSurface*)Sender;
|
||||
//const bool bPartial = pSurf->m_bPartialInstall;
|
||||
|
||||
const int minRequiredSpace = bPartial ? MIN_REQUIRED_DISK_SPACE : MIN_REQUIRED_DISK_SPACE_OPT;
|
||||
int currentDiskSpace;
|
||||
//const int minRequiredSpace = bPartial ? MIN_REQUIRED_DISK_SPACE : MIN_REQUIRED_DISK_SPACE_OPT;
|
||||
//int currentDiskSpace;
|
||||
|
||||
if (!SDKLauncher_CheckDiskSpace(minRequiredSpace, ¤tDiskSpace))
|
||||
{
|
||||
Forms::MessageBox::Show(Format("There is not enough space available on the disk to install R5Reloaded;"
|
||||
" you need at least %iGB, you currently have %iGB\n", minRequiredSpace, currentDiskSpace).c_str(),
|
||||
"Error", Forms::MessageBoxButtons::OK, Forms::MessageBoxIcon::Error);
|
||||
//if (!SDKLauncher_CheckDiskSpace(minRequiredSpace, ¤tDiskSpace))
|
||||
//{
|
||||
// Forms::MessageBox::Show(Format("There is not enough space available on the disk to install R5Reloaded;"
|
||||
// " you need at least %iGB, you currently have %iGB\n", minRequiredSpace, currentDiskSpace).c_str(),
|
||||
// "Error", Forms::MessageBoxButtons::OK, Forms::MessageBoxIcon::Error);
|
||||
|
||||
return;
|
||||
}
|
||||
// return;
|
||||
//}
|
||||
|
||||
auto downloadSurface = std::make_unique<CProgressPanel>();
|
||||
CProgressPanel* pProgress = downloadSurface.get();
|
||||
@ -249,8 +247,9 @@ void CBaseSurface::OnInstallClick(Forms::Control* Sender)
|
||||
}
|
||||
|
||||
CUtlVector<CUtlString> fileList;
|
||||
SDKLauncher_BeginDownload(true, false, false, fileList, pProgress);
|
||||
SDKLauncher_InstallAssetList(false, fileList, pProgress);
|
||||
if (SDKLauncher_BeginInstall(true, false, fileList, pProgress))
|
||||
{
|
||||
}
|
||||
|
||||
// Close on finish.
|
||||
pProgress->Close();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "tier1/utlmap.h"
|
||||
#include "tier2/curlutils.h"
|
||||
#include "zip/src/ZipFile.h"
|
||||
#include <public/tier0/binstream.h>
|
||||
|
||||
bool g_bPartialInstall = false;
|
||||
//bool g_bExperimentalBuilds = false;
|
||||
@ -100,12 +101,91 @@ bool SDKLauncher_ClearDepotDirectories()
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_ExtractZipFile(const char* pZipFile, const char* pDestPath, CProgressPanel* pProgress)
|
||||
bool GetDepotList(const nlohmann::json& manifest, nlohmann::json& outDepotList)
|
||||
{
|
||||
ZipArchive::Ptr archive = ZipFile::Open(pZipFile);
|
||||
if (manifest.contains("depot"))
|
||||
{
|
||||
const nlohmann::json& depotListArray = manifest["depot"];
|
||||
|
||||
if (!depotListArray.empty())
|
||||
{
|
||||
outDepotList = depotListArray;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool GetDepotEntry(const nlohmann::json& manifest, const char* targetDepotName, nlohmann::json& outDepotEntry)
|
||||
{
|
||||
nlohmann::json depotList;
|
||||
|
||||
if (GetDepotList(manifest, depotList))
|
||||
{
|
||||
printf("*** -<[DEPOT_LIST]>- ***\n%s\n", depotList.dump(4).c_str());
|
||||
|
||||
for (const auto& depot : depotList)
|
||||
{
|
||||
if (!depot.contains("name"))
|
||||
continue;
|
||||
|
||||
const string depotName = depot["name"].get<string>();
|
||||
|
||||
if (depotName.compare(targetDepotName) == NULL)
|
||||
{
|
||||
outDepotEntry = depot;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s: Failed on target(%s):\n%s\n", __FUNCTION__, targetDepotName, manifest.dump(4).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool GetDepotAssetList(const nlohmann::json& manifest, const char* targetDepotName, nlohmann::json& outAssetList)
|
||||
{
|
||||
nlohmann::json depotEntry;
|
||||
|
||||
if (GetDepotEntry(manifest, targetDepotName, depotEntry))
|
||||
{
|
||||
printf("*** -<[DEPOT_ENTRY]>- ***\n%s\n", depotEntry.dump(4).c_str());
|
||||
|
||||
if (depotEntry.contains("assets"))
|
||||
{
|
||||
const nlohmann::json& assetList = depotEntry["assets"];
|
||||
|
||||
if (!assetList.empty())
|
||||
{
|
||||
outAssetList = depotEntry["assets"];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s: Failed on target(%s):\n%s\n", __FUNCTION__, targetDepotName, manifest.dump(4).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_ExtractZipFile(nlohmann::json& manifest, const CUtlString& filePath, CProgressPanel* pProgress)
|
||||
{
|
||||
ZipArchive::Ptr archive = ZipFile::Open(filePath.Get());
|
||||
size_t entries = archive->GetEntriesCount();
|
||||
|
||||
CUtlMap<CUtlString, bool> fileList(UtlStringLessFunc);
|
||||
nlohmann::json assetList;
|
||||
CUtlString fileName = filePath.UnqualifiedFilename();
|
||||
|
||||
const bool assetListRet = GetDepotAssetList(manifest, fileName.String(), assetList);
|
||||
|
||||
for (size_t i = 0; i < entries; ++i)
|
||||
{
|
||||
@ -114,53 +194,48 @@ bool SDKLauncher_ExtractZipFile(const char* pZipFile, const char* pDestPath, CPr
|
||||
if (entry->IsDirectory())
|
||||
continue;
|
||||
|
||||
string fullName = entry->GetFullName();
|
||||
|
||||
// TODO: ideally there will be a list in a json
|
||||
// that the launcher downloads to determine what
|
||||
// has to be installed during the restart.
|
||||
const CUtlString fullName = entry->GetFullName().c_str();
|
||||
bool installDuringRestart = false;
|
||||
if (fullName.compare("launcher.exe") == NULL)
|
||||
|
||||
const char* const pFullName = fullName.Get();
|
||||
|
||||
// Determine whether or not the asset needs
|
||||
// to be installed during a restart.
|
||||
if (assetListRet && assetList.contains(pFullName))
|
||||
{
|
||||
installDuringRestart = true;
|
||||
const nlohmann::json& assetEntry = assetList[pFullName];
|
||||
|
||||
if (assetEntry.contains("restart"))
|
||||
{
|
||||
installDuringRestart = assetEntry["restart"].get<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
fileList.Insert(fullName.c_str(), installDuringRestart);
|
||||
printf("Added: %s\n", fullName.c_str());
|
||||
}
|
||||
|
||||
printf("Num files: %d\n", fileList.Count());
|
||||
|
||||
FOR_EACH_MAP(fileList, i)
|
||||
{
|
||||
CUtlString& fileName = fileList.Key(i);
|
||||
CUtlString absDirName = fileName.AbsPath();
|
||||
CUtlString absDirName = fullName.AbsPath();
|
||||
CUtlString dirName = absDirName.DirName();
|
||||
|
||||
CreateDirectories(absDirName.Get());
|
||||
|
||||
if (pProgress)
|
||||
{
|
||||
pProgress->SetExportLabel(Format("%s (%i of %i)", fileName.Get(), i + 1, fileList.Count()).c_str());
|
||||
pProgress->SetExportLabel(Format("%s (%llu of %llu)", pFullName, i+1, entries).c_str());
|
||||
|
||||
int percentage = (i * 100) / fileList.Count();
|
||||
pProgress->UpdateProgress(percentage, false);
|
||||
size_t percentage = (i * 100) / entries;
|
||||
pProgress->UpdateProgress((uint32_t)percentage, false);
|
||||
}
|
||||
|
||||
printf("Extracting: %s to %s\n", fileName.Get(), dirName.Get());
|
||||
printf("Extracting: %s to %s\n", pFullName, dirName.Get());
|
||||
|
||||
if (fileList[i])
|
||||
if (installDuringRestart)
|
||||
{
|
||||
printf("File %s has to be installed after a restart!\n", fileName.Get());
|
||||
|
||||
CUtlString tempDir = RESTART_DEPOT_DOWNLOAD_DIR;
|
||||
tempDir.Append(fileName);
|
||||
tempDir.Append(pFullName);
|
||||
|
||||
ZipFile::ExtractFile(pZipFile, fileName.Get(), tempDir.Get());
|
||||
ZipFile::ExtractFile(filePath.Get(), pFullName, tempDir.Get());
|
||||
}
|
||||
else
|
||||
{
|
||||
ZipFile::ExtractFile(pZipFile, fileName.Get(), fileName.Get());
|
||||
ZipFile::ExtractFile(filePath.Get(), pFullName, pFullName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,6 +253,7 @@ bool SDKLauncher_QueryServer(const char* url, string& outResponse, string& outMe
|
||||
params.writeFunction = CURLWriteStringCallback;
|
||||
params.timeout = QUERY_TIMEOUT;
|
||||
params.verifyPeer = true;
|
||||
params.followRedirect = true;
|
||||
params.verbose = 0;// IsDebug();
|
||||
|
||||
CURL* curl = CURLInitRequest(url, nullptr, outResponse, sList, params);
|
||||
@ -201,7 +277,7 @@ bool SDKLauncher_QueryServer(const char* url, string& outResponse, string& outMe
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_GetLatestReleaseManifest(const char* url, string& responseMessage,
|
||||
bool SDKLauncher_AcquireReleaseManifest(const char* url, string& responseMessage,
|
||||
nlohmann::json& outManifest, const bool preRelease)
|
||||
{
|
||||
string responseBody;
|
||||
@ -288,125 +364,199 @@ bool SDKLauncher_DownloadAsset(const char* url, const char* path, const char* fi
|
||||
|
||||
params.writeFunction = CURLWriteFileCallback;
|
||||
params.statusFunction = SDKLauncher_ProgressCallback;
|
||||
params.followRedirect = true;
|
||||
|
||||
return CURLDownloadFile(url, path, fileName, options, fileSize, pProgress, params);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
void SDKLauncher_BeginDownload(const bool bPreRelease, const bool bOptionalAssets,
|
||||
const bool bSdkOnly/*!!! REFACTOR ME MAYBE !!!*/, CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress)
|
||||
bool SDKLauncher_BuildUpdateList(const nlohmann::json& localManifest,
|
||||
const nlohmann::json& remoteManifest, CUtlVector<CUtlString>& outDepotList)
|
||||
{
|
||||
string responseMessage;
|
||||
nlohmann::json manifest;
|
||||
|
||||
// These files will NOT be downloaded from the release depots.
|
||||
std::set<string> blackList;
|
||||
blackList.insert("symbols.zip");
|
||||
|
||||
|
||||
// DEBUG CODE!!!
|
||||
//fileList.AddToTail("audio_0.zip");
|
||||
//fileList.AddToTail("audio_1.zip");
|
||||
//fileList.AddToTail("binaries.zip");
|
||||
//fileList.AddToTail("materials.zip");
|
||||
//fileList.AddToTail("media.zip");
|
||||
//fileList.AddToTail("paks.zip");
|
||||
//fileList.AddToTail("starpak_0.zip");
|
||||
//fileList.AddToTail("starpak_1.zip");
|
||||
//fileList.AddToTail("stbsp.zip");
|
||||
//fileList.AddToTail("/depot.zip");
|
||||
|
||||
//FOR_EACH_VEC(fileList, i)
|
||||
//{
|
||||
// CUtlString& filePath = fileList[i];
|
||||
// filePath = filePath.Replace("/", DEFAULT_DEPOT_DOWNLOAD_DIR);
|
||||
//}
|
||||
|
||||
if (!bSdkOnly)
|
||||
try
|
||||
{
|
||||
// Download core game files.
|
||||
if (!SDKLauncher_GetLatestReleaseManifest(XorStr(GAME_DEPOT_VENDOR), responseMessage, manifest, bPreRelease))
|
||||
const nlohmann::json& remoteDepotArray = remoteManifest["depot"];
|
||||
const nlohmann::json& localDepotArray = localManifest["depot"];
|
||||
|
||||
for (const auto& remoteDepot : remoteDepotArray)
|
||||
{
|
||||
// TODO: Error dialog.
|
||||
return;
|
||||
const string& remoteDepotName = remoteDepot["name"];
|
||||
|
||||
bool containsDepot = false;
|
||||
bool digestMatch = false;
|
||||
|
||||
for (const auto& localDepot : localDepotArray)
|
||||
{
|
||||
if (localDepot["name"] == remoteDepotName)
|
||||
{
|
||||
containsDepot = true;
|
||||
|
||||
if (remoteDepot["digest"].get<string>() == localDepot["digest"].get<string>())
|
||||
{
|
||||
digestMatch = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsDepot)
|
||||
{
|
||||
if (!digestMatch)
|
||||
{
|
||||
// Checksum mismatch, the file has been changed,
|
||||
// add it to the list so we are installing it.
|
||||
outDepotList.AddToTail(remoteDepotName.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Local manifest does not contain the asset,
|
||||
// add it to the list so we are installing it.
|
||||
outDepotList.AddToTail(remoteDepotName.c_str());
|
||||
}
|
||||
}
|
||||
SDKLauncher_DownloadAssetList(fileList, manifest, blackList, DEFAULT_DEPOT_DOWNLOAD_DIR, pProgress);
|
||||
|
||||
if (pProgress->IsCanceled())
|
||||
return;
|
||||
}
|
||||
|
||||
// Download SDK files.
|
||||
if (!SDKLauncher_GetLatestReleaseManifest(XorStr(SDK_DEPOT_VENDOR), responseMessage, manifest, bPreRelease))
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
// TODO: Error dialog.
|
||||
return;
|
||||
printf("%s - Exception while building update list:\n%s\n", __FUNCTION__, ex.what());
|
||||
return false;
|
||||
}
|
||||
SDKLauncher_DownloadAssetList(fileList, manifest, blackList, DEFAULT_DEPOT_DOWNLOAD_DIR, pProgress);
|
||||
|
||||
if (pProgress->IsCanceled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_DownloadAssetList(CUtlVector<CUtlString>& fileList, nlohmann::json& assetList,
|
||||
std::set<string>& blackList, const char* pPath, CProgressPanel* pProgress)
|
||||
bool SDKLauncher_BeginInstall(const bool bPreRelease, const bool bOptionalDepots,
|
||||
CUtlVector<CUtlString>& zipList, CProgressPanel* pProgress)
|
||||
{
|
||||
if (!assetList.contains("assets"))
|
||||
string responseMessage;
|
||||
nlohmann::json remoteManifest;
|
||||
|
||||
if (!SDKLauncher_GetRemoteManifest(XorStr(SDK_DEPOT_VENDOR), responseMessage, remoteManifest, bPreRelease))
|
||||
{
|
||||
printf("%s: Failed! %s\n", "SDKLauncher_GetRemoteManifest", responseMessage.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
CUtlVector<CUtlString> depotList;
|
||||
nlohmann::json localManifest;
|
||||
|
||||
if (SDKLauncher_GetLocalManifest(localManifest))
|
||||
{
|
||||
SDKLauncher_BuildUpdateList(localManifest, remoteManifest, depotList);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Leave the vector empty, this will download everything.
|
||||
Assert(depotList.IsEmpty());
|
||||
}
|
||||
|
||||
FOR_EACH_VEC(depotList, i)
|
||||
{
|
||||
const CUtlString& depotName = depotList[i];
|
||||
printf("CUtlVector< CUtlString >::depotList[ %d ] = %s\n", i, depotName.Get());
|
||||
}
|
||||
|
||||
if (!SDKLauncher_DownloadDepotList(remoteManifest, depotList,
|
||||
zipList, pProgress, DEFAULT_DEPOT_DOWNLOAD_DIR, bOptionalDepots))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Canceling returns true, as the function didn't fail.
|
||||
// We should however still delete all the downloaded files.
|
||||
if (pProgress->IsCanceled())
|
||||
return true;
|
||||
|
||||
|
||||
if (!SDKLauncher_InstallDepotList(remoteManifest, zipList, pProgress))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SDKLauncher_WriteLocalManifest(remoteManifest))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_DownloadDepotList(nlohmann::json& manifest, CUtlVector<CUtlString>& depotList,
|
||||
CUtlVector<CUtlString>& outZipList, CProgressPanel* pProgress, const char* pPath,
|
||||
const bool bOptionalDepots)
|
||||
{
|
||||
if (!manifest.contains("depot"))
|
||||
{
|
||||
Assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
const auto assetListArray = assetList["assets"];
|
||||
const auto depotListArray = manifest["depot"];
|
||||
|
||||
for (auto& asset : assetListArray)
|
||||
if (depotListArray.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = 1;
|
||||
|
||||
for (auto& depot : depotListArray)
|
||||
{
|
||||
if (pProgress->IsCanceled())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!asset.contains("browser_download_url") ||
|
||||
!asset.contains("name") ||
|
||||
!asset.contains("size"))
|
||||
if (!SDKLauncher_IsDepositoryValid(depot))
|
||||
{
|
||||
// Invalid manifest format.
|
||||
Assert(0);
|
||||
return false;
|
||||
}
|
||||
|
||||
const string fileName = asset["name"];
|
||||
const char* const pFileName = fileName.c_str();
|
||||
|
||||
// Asset is filtered, don't download.
|
||||
if (blackList.find(fileName) != blackList.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const string downloadLink = asset["browser_download_url"];
|
||||
const size_t fileSize = asset["size"];
|
||||
if ((!bOptionalDepots &&
|
||||
depot["optional"].get<bool>()))
|
||||
{
|
||||
// Optional depots disabled.
|
||||
continue;
|
||||
}
|
||||
|
||||
pProgress->SetText(Format("Downloading package %i of %i...", i, assetListArray.size()).c_str());
|
||||
SDKLauncher_DownloadAsset(downloadLink.c_str(), pPath, pFileName, fileSize, "wb+", pProgress);
|
||||
const string fileName = depot["name"].get<string>();
|
||||
|
||||
if (!depotList.IsEmpty())
|
||||
{
|
||||
if (!depotList.HasElement(fileName.c_str()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const size_t fileSize = depot["size"].get<size_t>();
|
||||
string downloadLink = depot["vendor"].get<string>();
|
||||
|
||||
AppendSlash(downloadLink, '/');
|
||||
downloadLink.append(fileName);
|
||||
|
||||
pProgress->SetText(Format("Downloading package %i of %i...", i, depotListArray.size()).c_str());
|
||||
SDKLauncher_DownloadAsset(downloadLink.c_str(), pPath, fileName.c_str(), fileSize, "wb+", pProgress);
|
||||
|
||||
// Check if its a zip file, as these are
|
||||
// the only files that will be installed.
|
||||
if (V_strcmp(V_GetFileExtension(pFileName), "zip") == NULL)
|
||||
if (V_strcmp(V_GetFileExtension(fileName.c_str()), "zip") == NULL)
|
||||
{
|
||||
CUtlString filePath = pPath;
|
||||
CUtlString filePath;
|
||||
|
||||
filePath.AppendSlash();
|
||||
filePath = pPath;
|
||||
filePath.AppendSlash('/');
|
||||
filePath.Append(fileName.c_str());
|
||||
|
||||
fileList.AddToTail(filePath);
|
||||
outZipList.AddToTail(filePath);
|
||||
}
|
||||
|
||||
i++;
|
||||
@ -418,8 +568,7 @@ bool SDKLauncher_DownloadAssetList(CUtlVector<CUtlString>& fileList, nlohmann::j
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//----------------------------------------------------------------------------
|
||||
bool SDKLauncher_InstallAssetList(const bool bOptionalAssets,
|
||||
CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress)
|
||||
bool SDKLauncher_InstallDepotList(nlohmann::json& manifest, CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress)
|
||||
{
|
||||
// Install process cannot be canceled.
|
||||
pProgress->SetCanCancel(false);
|
||||
@ -428,8 +577,8 @@ bool SDKLauncher_InstallAssetList(const bool bOptionalAssets,
|
||||
{
|
||||
pProgress->SetText(Format("Installing package %i of %i...", i + 1, fileList.Count()).c_str());
|
||||
|
||||
CUtlString& fileName = fileList[i];
|
||||
if (!SDKLauncher_ExtractZipFile(fileName.Get(), "", pProgress))
|
||||
CUtlString& filePath = fileList[i];
|
||||
if (!SDKLauncher_ExtractZipFile(manifest, filePath, pProgress))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -466,6 +615,87 @@ bool SDKLauncher_CheckDiskSpace(const int minRequiredSpace, int* const available
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDKLauncher_IsManifestValid(const nlohmann::json& depotManifest)
|
||||
{
|
||||
return (!depotManifest.empty() &&
|
||||
depotManifest.contains("version") &&
|
||||
depotManifest.contains("depot"));
|
||||
}
|
||||
|
||||
bool SDKLauncher_IsDepositoryValid(const nlohmann::json& depot)
|
||||
{
|
||||
return (!depot.empty() &&
|
||||
depot.contains("optional") &&
|
||||
depot.contains("vendor") &&
|
||||
depot.contains("size") &&
|
||||
depot.contains("name"));
|
||||
}
|
||||
|
||||
bool SDKLauncher_GetRemoteManifest(const char* url, string& responseMessage, nlohmann::json& remoteManifest, const bool bPreRelease)
|
||||
{
|
||||
nlohmann::json responseJson;
|
||||
|
||||
if (!SDKLauncher_AcquireReleaseManifest(url, responseMessage, responseJson, bPreRelease))
|
||||
{
|
||||
// TODO: Error dialog.
|
||||
|
||||
printf("%s: failed!\n", "SDKLauncher_AcquireReleaseManifest");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!responseJson.contains("assets"))
|
||||
{
|
||||
printf("%s: failed!\n", "responseJson.contains(\"assets\")");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string depotManifestUrl;
|
||||
|
||||
{
|
||||
nlohmann::json& assetList = responseJson["assets"];
|
||||
|
||||
for (const auto& asset : assetList)
|
||||
{
|
||||
if (asset["name"] == DEPOT_MANIFEST_FILE)
|
||||
{
|
||||
depotManifestUrl = asset["browser_download_url"];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (depotManifestUrl.empty())
|
||||
{
|
||||
printf("depotManifestUrl.empty()==true\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
string responseBody;
|
||||
CURLINFO status;
|
||||
|
||||
if (!SDKLauncher_QueryServer(depotManifestUrl.c_str(), responseBody, responseMessage, status) ||
|
||||
status != 200)
|
||||
{
|
||||
printf("%s: failed! %s, status=%d\n", "SDKLauncher_QueryServer", responseMessage.c_str(), status);
|
||||
|
||||
responseMessage = responseBody;
|
||||
return false;
|
||||
}
|
||||
|
||||
remoteManifest = nlohmann::json::parse(responseBody);
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
printf("%s - Exception while parsing response:\n%s\n", __FUNCTION__, ex.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert(!remoteManifest.empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDKLauncher_GetLocalManifest(nlohmann::json& localManifest)
|
||||
{
|
||||
if (!fs::exists(DEPOT_MANIFEST_FILE_PATH))
|
||||
@ -479,6 +709,11 @@ bool SDKLauncher_GetLocalManifest(nlohmann::json& localManifest)
|
||||
try
|
||||
{
|
||||
localManifest = nlohmann::json::parse(localFile);
|
||||
|
||||
if (!SDKLauncher_IsManifestValid(localManifest))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
@ -486,13 +721,22 @@ bool SDKLauncher_GetLocalManifest(nlohmann::json& localManifest)
|
||||
return false;
|
||||
}
|
||||
|
||||
return !localManifest.empty();
|
||||
return true;
|
||||
}
|
||||
|
||||
//bool SDKLauncher_WriteLocalManifest()
|
||||
//{
|
||||
//
|
||||
//}
|
||||
bool SDKLauncher_WriteLocalManifest(const nlohmann::json& localManifest)
|
||||
{
|
||||
CIOStream writer;
|
||||
if (!writer.Open(DEPOT_MANIFEST_FILE_PATH, CIOStream::Mode_t::WRITE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const string manifestBuf = localManifest.dump(4);
|
||||
writer.Write(manifestBuf.c_str(), manifestBuf.size());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
@ -502,10 +746,10 @@ bool SDKLauncher_CheckForUpdate(const bool bPreRelease)
|
||||
nlohmann::json remoteManifest;
|
||||
string responseMessage;
|
||||
|
||||
if (!SDKLauncher_GetLatestReleaseManifest(XorStr(SDK_DEPOT_VENDOR), responseMessage, remoteManifest, bPreRelease))
|
||||
if (!SDKLauncher_AcquireReleaseManifest(XorStr(SDK_DEPOT_VENDOR), responseMessage, remoteManifest, bPreRelease))
|
||||
{
|
||||
printf("%s: Failed to obtain remote manifest: %s\n", __FUNCTION__, responseMessage.c_str());
|
||||
return true; // Can't determine if there is an update or not; skip...
|
||||
return false; // Can't determine if there is an update or not; skip...
|
||||
}
|
||||
|
||||
nlohmann::json localManifest;
|
||||
@ -520,7 +764,7 @@ bool SDKLauncher_CheckForUpdate(const bool bPreRelease)
|
||||
if (!localManifest.contains("version"))
|
||||
{
|
||||
// No version information; assume an update is required.
|
||||
printf("%s: local manifest does not contain field '%s'!\n", __FUNCTION__, "version");
|
||||
printf("%s: Local manifest does not contain field '%s'!\n", __FUNCTION__, "version");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -8,16 +8,26 @@ void SDKLauncher_Restart();
|
||||
bool SDKLauncher_CreateDepotDirectories();
|
||||
bool SDKLauncher_ClearDepotDirectories();
|
||||
|
||||
bool SDKLauncher_ExtractZipFile(const char* pZipFile, const char* pDestPath, CProgressPanel* pProgress = nullptr);
|
||||
void SDKLauncher_BeginDownload(const bool bPreRelease, const bool bOptionalAssets, const bool bSdkOnly, CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress = nullptr);
|
||||
bool SDKLauncher_ExtractZipFile(nlohmann::json& manifest, const CUtlString& filePath, CProgressPanel* pProgress);
|
||||
bool SDKLauncher_BeginInstall(const bool bPreRelease, const bool bOptionalDepots,
|
||||
CUtlVector<CUtlString>& zipList, CProgressPanel* pProgress);
|
||||
|
||||
bool SDKLauncher_DownloadAssetList(CUtlVector<CUtlString>& fileList, nlohmann::json& assetList,
|
||||
std::set<string>& blackList, const char* pPath, CProgressPanel* pProgress);
|
||||
bool SDKLauncher_IsManifestValid(const nlohmann::json& depotManifest);
|
||||
bool SDKLauncher_IsDepositoryValid(const nlohmann::json& depotAssetList);
|
||||
|
||||
bool SDKLauncher_InstallAssetList(const bool bOptionalAssets,
|
||||
CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress);
|
||||
bool SDKLauncher_DownloadDepotList(nlohmann::json& manifest, CUtlVector<CUtlString>& depotList,
|
||||
CUtlVector<CUtlString>& outZipList, CProgressPanel* pProgress, const char* pPath,
|
||||
const bool bOptionalDepots);
|
||||
|
||||
bool SDKLauncher_InstallDepotList(nlohmann::json& manifest, CUtlVector<CUtlString>& fileList, CProgressPanel* pProgress);
|
||||
|
||||
bool SDKLauncher_GetRemoteManifest(const char* url, string& responseMessage, nlohmann::json& remoteManifest, const bool bPreRelease);
|
||||
bool SDKLauncher_GetLocalManifest(nlohmann::json& localManifest);
|
||||
bool SDKLauncher_WriteLocalManifest(const nlohmann::json& localManifest);
|
||||
|
||||
bool SDKLauncher_CheckDiskSpace(const int minRequiredSpace, int* const availableSize = nullptr);
|
||||
bool SDKLauncher_CheckForUpdate(const bool bPreRelease);
|
||||
|
||||
bool SDKLauncher_ForceExistingInstanceOnTop();
|
||||
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
char const* V_stristr(char const* pStr, char const* pSearch)
|
||||
{
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
//AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
//AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
|
||||
if (!pStr || !pSearch)
|
||||
return 0;
|
||||
@ -48,8 +48,8 @@ char const* V_stristr(char const* pStr, char const* pSearch)
|
||||
|
||||
char* V_stristr(char* pStr, char const* pSearch)
|
||||
{
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
//AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pStr));
|
||||
//AssertValidStringPtr(reinterpret_cast<const TCHAR*>(pSearch));
|
||||
|
||||
return (char*)V_stristr((char const*)pStr, pSearch);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user