lgogdownloader/include/downloader.h
Sude 97bb4d8923 Galaxy: Select build by build id
Make it possible to select by build id
Tries to find build with build id first
If no build is found with specified build id then try to use it as build index
If build id or index is not valid then default to build index 0
2024-11-15 19:28:32 +02:00

193 lines
9.0 KiB
C++

/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details. */
#ifndef DOWNLOADER_H
#define DOWNLOADER_H
#if __GNUC__
# if !(__x86_64__ || __ppc64__ || __LP64__)
# ifndef _LARGEFILE_SOURCE
# define _LARGEFILE_SOURCE
# endif
# ifndef _LARGEFILE64_SOURCE
# define _LARGEFILE64_SOURCE
# endif
# if !defined(_FILE_OFFSET_BITS) || (_FILE_OFFSET_BITS == 32)
# define _FILE_OFFSET_BITS 64
# endif
# endif
#endif
#include "config.h"
#include "progressbar.h"
#include "website.h"
#include "threadsafequeue.h"
#include "galaxyapi.h"
#include "globals.h"
#include "util.h"
#include <curl/curl.h>
#include <json/json.h>
#include <ctime>
#include <functional>
#include <fstream>
#include <deque>
class cloudSaveFile;
class Timer
{
public:
Timer() { this->reset(); };
void reset() { gettimeofday(&(this->last_update), NULL); };
double getTimeBetweenUpdates()
{ // Returns time elapsed between updates in milliseconds
struct timeval time_now;
gettimeofday(&time_now, NULL);
double time_between = ( (time_now.tv_sec+(time_now.tv_usec/1000000.0))*1000.0 - (this->last_update.tv_sec+(this->last_update.tv_usec/1000000.0))*1000.0 );
return time_between;
};
~Timer() {};
private:
struct timeval last_update;
};
struct xferInfo
{
unsigned int tid;
CURL* curlhandle;
Timer timer;
std::deque< std::pair<time_t, uintmax_t> > TimeAndSize;
curl_off_t offset;
bool isChunk = false;
curl_off_t chunk_file_total = 0;
curl_off_t chunk_file_offset = 0;
};
typedef struct
{
std::string filepath;
off_t comp_size;
off_t uncomp_size;
off_t start_offset_zip;
off_t start_offset_mojosetup;
off_t end_offset;
uint16_t file_attributes;
uint32_t crc32;
time_t timestamp;
std::string installer_url;
// For split file handling
bool isSplitFile = false;
std::string splitFileBasePath;
std::string splitFilePartExt;
off_t splitFileStartOffset;
off_t splitFileEndOffset;
} zipFileEntry;
typedef std::map<std::string,std::vector<zipFileEntry>> splitFilesMap;
class Downloader
{
public:
Downloader();
virtual ~Downloader();
bool isLoggedIn();
int init();
int login();
int listGames();
void checkNotifications();
void clearUpdateNotifications();
void repair();
void download();
void downloadCloudSaves(const std::string& product_id, const std::string& build_id = std::string());
void downloadCloudSavesById(const std::string& product_id, const std::string& build_id = std::string());
void uploadCloudSaves(const std::string& product_id, const std::string& build_id = std::string());
void uploadCloudSavesById(const std::string& product_id, const std::string& build_id = std::string());
void deleteCloudSaves(const std::string& product_id, const std::string& build_id = std::string());
void deleteCloudSavesById(const std::string& product_id, const std::string& build_id = std::string());
void checkOrphans();
void checkStatus();
void updateCache();
int downloadFileWithId(const std::string& fileid_string, const std::string& output_filepath);
void showWishlist();
CURL* curlhandle;
Timer timer;
ProgressBar* progressbar;
std::deque< std::pair<time_t, uintmax_t> > TimeAndSize;
void saveGalaxyJSON();
void galaxyInstallGame(const std::string& product_id, const std::string& build_id = std::string(), const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
void galaxyInstallGameById(const std::string& product_id, const std::string& build_id = std::string(), const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
void galaxyListCDNs(const std::string& product_id, const std::string& build_id = std::string());
void galaxyListCDNsById(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowBuilds(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowCloudSaves(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowLocalCloudSaves(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowLocalCloudSavesById(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowBuildsById(const std::string& product_id, const std::string& build_id = std::string());
void galaxyShowCloudSavesById(const std::string& product_id, const std::string& build_id = std::string());
protected:
private:
std::map<std::string, std::string> cloudSaveLocations(const std::string& product_id, const std::string& build_id = std::string());
int cloudSaveListByIdForEach(const std::string& product_id, const std::string& build_id, const std::function<void(cloudSaveFile &)> &f);
CURLcode downloadFile(const std::string& url, const std::string& filepath, const std::string& xml_data = std::string(), const std::string& gamename = std::string());
int repairFile(const std::string& url, const std::string& filepath, const std::string& xml_data = std::string(), const std::string& gamename = std::string());
int getGameDetails();
void getGameList();
uintmax_t getResumePosition();
CURLcode beginDownload();
std::string getResponse(const std::string& url);
std::string getLocalFileHash(const std::string& filepath, const std::string& gamename = std::string());
std::string getRemoteFileHash(const gameFile& gf);
void addStatusLine(const std::string& statusCode, const std::string& gamename, const std::string& filepath, const uintmax_t& filesize, const std::string& localHash);
int loadGameDetailsCache();
int saveGameDetailsCache();
std::vector<gameDetails> getGameDetailsFromJsonNode(Json::Value root, const int& recursion_level = 0);
static std::string getSerialsFromJSON(const Json::Value& json);
void saveSerials(const std::string& serials, const std::string& filepath);
static std::string getChangelogFromJSON(const Json::Value& json);
void saveJsonFile(const std::string& json, const std::string& filepath);
void saveChangelog(const std::string& changelog, const std::string& filepath);
static void processDownloadQueue(Config conf, const unsigned int& tid);
static void processCloudSaveDownloadQueue(Config conf, const unsigned int& tid);
static void processCloudSaveUploadQueue(Config conf, const unsigned int& tid);
static int progressCallbackForThread(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
template <typename T> void printProgress(const ThreadSafeQueue<T>& download_queue);
static void getGameDetailsThread(Config config, const unsigned int& tid);
void printGameDetailsAsText(gameDetails& game);
void printGameFileDetailsAsText(gameFile& gf);
static int progressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
static size_t writeData(void *ptr, size_t size, size_t nmemb, FILE *stream);
static size_t readData(void *ptr, size_t size, size_t nmemb, FILE *stream);
std::vector<std::string> galaxyGetOrphanedFiles(const std::vector<galaxyDepotItem>& items, const std::string& install_path);
static void processGalaxyDownloadQueue(const std::string& install_path, Config conf, const unsigned int& tid);
void galaxyInstallGame_MojoSetupHack(const std::string& product_id);
void galaxyInstallGame_MojoSetupHack_CombineSplitFiles(const splitFilesMap& mSplitFiles, const bool& bAppendtoFirst = false);
static void processGalaxyDownloadQueue_MojoSetupHack(Config conf, const unsigned int& tid);
int mojoSetupGetFileVector(const gameFile& gf, std::vector<zipFileEntry>& vFiles);
std::string getGalaxyInstallDirectory(galaxyAPI *galaxyHandle, const Json::Value& manifest);
bool galaxySelectProductIdHelper(const std::string& product_id, std::string& selected_product);
std::vector<galaxyDepotItem> galaxyGetDepotItemVectorFromJson(const Json::Value& json, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
int galaxyGetBuildIndexWithBuildId(Json::Value json, const std::string& build_id = std::string());
Website *gogWebsite;
galaxyAPI *gogGalaxy;
std::vector<gameItem> gameItems;
std::vector<gameDetails> games;
off_t resume_position;
int retries;
std::ofstream report_ofs;
};
#endif // DOWNLOADER_H