2013-03-15 21:46:16 +01:00
|
|
|
/* 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
|
2013-03-24 22:56:57 +01:00
|
|
|
* http://www.wtfpl.net/ for more details. */
|
2013-03-15 21:46:16 +01:00
|
|
|
|
|
|
|
#ifndef DOWNLOADER_H
|
|
|
|
#define DOWNLOADER_H
|
|
|
|
|
2014-08-01 19:32:29 +02:00
|
|
|
#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
|
|
|
|
|
2013-03-15 21:46:16 +01:00
|
|
|
#include "config.h"
|
|
|
|
#include "progressbar.h"
|
2016-04-18 19:33:19 +02:00
|
|
|
#include "website.h"
|
2016-05-20 19:33:07 +02:00
|
|
|
#include "threadsafequeue.h"
|
2017-02-17 10:14:28 +01:00
|
|
|
#include "galaxyapi.h"
|
|
|
|
#include "globals.h"
|
2020-09-26 21:09:38 +02:00
|
|
|
#include "util.h"
|
2017-02-17 10:14:28 +01:00
|
|
|
|
2013-03-15 21:46:16 +01:00
|
|
|
#include <curl/curl.h>
|
2015-01-22 08:22:48 +01:00
|
|
|
#include <json/json.h>
|
2013-03-15 21:46:16 +01:00
|
|
|
#include <ctime>
|
2014-02-13 10:16:31 +01:00
|
|
|
#include <fstream>
|
2015-04-27 15:51:17 +02:00
|
|
|
#include <deque>
|
2013-03-15 21:46:16 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2016-05-20 19:33:07 +02:00
|
|
|
struct xferInfo
|
|
|
|
{
|
|
|
|
unsigned int tid;
|
|
|
|
CURL* curlhandle;
|
|
|
|
Timer timer;
|
|
|
|
std::deque< std::pair<time_t, uintmax_t> > TimeAndSize;
|
|
|
|
curl_off_t offset;
|
|
|
|
};
|
|
|
|
|
2018-05-29 07:56:29 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2020-02-19 12:49:06 +01:00
|
|
|
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;
|
2018-05-29 07:56:29 +02:00
|
|
|
} zipFileEntry;
|
|
|
|
|
2020-02-19 12:49:06 +01:00
|
|
|
typedef std::map<std::string,std::vector<zipFileEntry>> splitFilesMap;
|
|
|
|
|
2013-03-15 21:46:16 +01:00
|
|
|
class Downloader
|
|
|
|
{
|
|
|
|
public:
|
2017-02-17 10:14:28 +01:00
|
|
|
Downloader();
|
2013-03-15 21:46:16 +01:00
|
|
|
virtual ~Downloader();
|
2016-12-17 20:01:44 +01:00
|
|
|
bool isLoggedIn();
|
2013-03-15 21:46:16 +01:00
|
|
|
int init();
|
2014-07-07 14:57:07 +02:00
|
|
|
int login();
|
2016-09-23 23:20:37 +02:00
|
|
|
int listGames();
|
2018-07-21 22:59:08 +02:00
|
|
|
void checkNotifications();
|
|
|
|
void clearUpdateNotifications();
|
2013-03-15 21:46:16 +01:00
|
|
|
void repair();
|
|
|
|
void download();
|
2013-10-14 21:31:12 +02:00
|
|
|
void checkOrphans();
|
2013-11-14 14:40:59 +01:00
|
|
|
void checkStatus();
|
2014-10-16 10:05:57 +02:00
|
|
|
void updateCache();
|
2016-09-23 23:16:13 +02:00
|
|
|
int downloadFileWithId(const std::string& fileid_string, const std::string& output_filepath);
|
2015-05-13 16:13:30 +02:00
|
|
|
void showWishlist();
|
2013-03-15 21:46:16 +01:00
|
|
|
CURL* curlhandle;
|
|
|
|
Timer timer;
|
|
|
|
ProgressBar* progressbar;
|
2015-07-03 22:09:50 +02:00
|
|
|
std::deque< std::pair<time_t, uintmax_t> > TimeAndSize;
|
2017-02-17 10:14:28 +01:00
|
|
|
void saveGalaxyJSON();
|
|
|
|
|
2017-05-23 15:44:27 +02:00
|
|
|
void galaxyInstallGame(const std::string& product_id, int build_index = -1, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
|
2019-04-22 17:14:53 +02:00
|
|
|
void galaxyInstallGameById(const std::string& product_id, int build_index = -1, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
|
2017-02-17 10:14:28 +01:00
|
|
|
void galaxyShowBuilds(const std::string& product_id, int build_index = -1);
|
2019-04-22 17:14:53 +02:00
|
|
|
void galaxyShowBuildsById(const std::string& product_id, int build_index = -1);
|
2013-03-15 21:46:16 +01:00
|
|
|
protected:
|
|
|
|
private:
|
2014-02-26 14:04:16 +01:00
|
|
|
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());
|
2013-03-15 21:46:16 +01:00
|
|
|
int getGameDetails();
|
|
|
|
void getGameList();
|
2015-07-03 22:09:50 +02:00
|
|
|
uintmax_t getResumePosition();
|
2013-03-15 21:46:16 +01:00
|
|
|
CURLcode beginDownload();
|
|
|
|
std::string getResponse(const std::string& url);
|
2014-02-26 14:04:16 +01:00
|
|
|
std::string getLocalFileHash(const std::string& filepath, const std::string& gamename = std::string());
|
2019-10-24 10:20:52 +02:00
|
|
|
std::string getRemoteFileHash(const gameFile& gf);
|
2014-10-16 10:05:57 +02:00
|
|
|
int loadGameDetailsCache();
|
|
|
|
int saveGameDetailsCache();
|
|
|
|
std::vector<gameDetails> getGameDetailsFromJsonNode(Json::Value root, const int& recursion_level = 0);
|
2016-11-15 18:30:32 +01:00
|
|
|
static std::string getSerialsFromJSON(const Json::Value& json);
|
2015-03-19 08:50:50 +01:00
|
|
|
void saveSerials(const std::string& serials, const std::string& filepath);
|
2016-11-15 18:30:32 +01:00
|
|
|
static std::string getChangelogFromJSON(const Json::Value& json);
|
2016-03-06 14:45:22 +01:00
|
|
|
void saveChangelog(const std::string& changelog, const std::string& filepath);
|
2016-05-20 19:33:07 +02:00
|
|
|
static void processDownloadQueue(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);
|
2018-02-12 17:46:17 +01:00
|
|
|
template <typename T> void printProgress(const ThreadSafeQueue<T>& download_queue);
|
2016-11-15 18:30:32 +01:00
|
|
|
static void getGameDetailsThread(Config config, const unsigned int& tid);
|
2013-03-15 21:46:16 +01:00
|
|
|
|
2016-04-25 18:26:02 +02:00
|
|
|
static int progressCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow);
|
2015-07-05 15:50:16 +02:00
|
|
|
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);
|
2013-03-15 21:46:16 +01:00
|
|
|
|
2017-05-23 15:53:24 +02:00
|
|
|
std::vector<std::string> galaxyGetOrphanedFiles(const std::vector<galaxyDepotItem>& items, const std::string& install_path);
|
2018-02-12 17:46:17 +01:00
|
|
|
static void processGalaxyDownloadQueue(const std::string& install_path, Config conf, const unsigned int& tid);
|
2018-05-29 07:56:29 +02:00
|
|
|
void galaxyInstallGame_MojoSetupHack(const std::string& product_id);
|
2020-02-19 12:49:06 +01:00
|
|
|
void galaxyInstallGame_MojoSetupHack_CombineSplitFiles(const splitFilesMap& mSplitFiles, const bool& bAppendtoFirst = false);
|
2018-05-29 07:56:29 +02:00
|
|
|
static void processGalaxyDownloadQueue_MojoSetupHack(Config conf, const unsigned int& tid);
|
|
|
|
int mojoSetupGetFileVector(const gameFile& gf, std::vector<zipFileEntry>& vFiles);
|
2018-09-12 15:02:34 +02:00
|
|
|
std::string getGalaxyInstallDirectory(galaxyAPI *galaxyHandle, const Json::Value& manifest);
|
2019-04-22 17:14:53 +02:00
|
|
|
bool galaxySelectProductIdHelper(const std::string& product_id, std::string& selected_product);
|
2019-06-07 13:51:05 +02:00
|
|
|
std::vector<galaxyDepotItem> galaxyGetDepotItemVectorFromJson(const Json::Value& json, const unsigned int& iGalaxyArch = GlobalConstants::ARCH_X64);
|
2017-05-23 15:53:24 +02:00
|
|
|
|
2016-04-18 19:33:19 +02:00
|
|
|
Website *gogWebsite;
|
2017-02-17 10:14:28 +01:00
|
|
|
galaxyAPI *gogGalaxy;
|
2014-03-29 00:51:39 +01:00
|
|
|
std::vector<gameItem> gameItems;
|
2013-03-15 21:46:16 +01:00
|
|
|
std::vector<gameDetails> games;
|
|
|
|
|
2015-07-05 15:50:16 +02:00
|
|
|
off_t resume_position;
|
2014-02-26 13:59:23 +01:00
|
|
|
int retries;
|
2014-02-13 10:16:31 +01:00
|
|
|
std::ofstream report_ofs;
|
2013-03-15 21:46:16 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // DOWNLOADER_H
|