Commit 7bf57f80 authored by Gerhard Stein's avatar Gerhard Stein

Game Downloader added, now we require libcurl for that.

parent 90061ade
......@@ -113,6 +113,16 @@ IF (Boost_FOUND)
ADD_DEFINITIONS( "-DHAS_BOOST" )
ENDIF()
if(DOWNLOADER)
FIND_PACKAGE(CURL)
IF(CURL_FOUND)
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIR})
ELSE(CURL_FOUND)
MESSAGE(FATAL_ERROR "Could not find the CURL library and development files.")
ENDIF(CURL_FOUND)
endif()
if(USE_SDL2)
IF(WIN32)
......@@ -233,6 +243,10 @@ IF(TREMOR)
TARGET_LINK_LIBRARIES(CGeniusExe vorbisidec)
ENDIF(TREMOR)
IF(CURL_FOUND)
TARGET_LINK_LIBRARIES(CGeniusExe ${CURL_LIBRARIES})
ENDIF(CURL_FOUND)
# Set binary(executable) file name. In Windows this filename needs the exe extension
# The Windows Version has an icon in the executable
......
......@@ -33,6 +33,8 @@
#include <fstream>
#include <SDL_image.h>
#include "gamedownloader.h"
#include "keen/vorticon/VorticonEngine.h"
#include "keen/galaxy/GalaxyEngine.h"
#include "keen/dreams/dreamsengine.h"
......@@ -490,6 +492,8 @@ void CGameLauncher::setupDownloadDialog()
mFinishedDownload = 0;
mDownloadProgress = 0;
mpGameDownloader = threadPool->start(new GameDownloader(mDownloadProgress), "Game Downloader started!");
}
void CGameLauncher::setupModsDialog()
......@@ -746,13 +750,11 @@ void CGameLauncher::ponderDownloadDialog()
mFinishedDownload = true;
}
// TODO: Create and push a Thread that with curl downloads one file.
// TODO: The files are downloaded into a "Downloads" folder. Secondly they need to be extracted, if the directory does not exist yet.
// When everything is done, The launcher should be restarted, for searching new games.
if( mFinishedDownload )
if( mFinishedDownload && mpGameDownloader->finished )
{
mpDownloadDialog = nullptr;
}
......
......@@ -10,6 +10,7 @@
#include <base/GsEngine.h>
#include <base/GsVirtualinput.h>
#include <base/utils/ThreadPool.h>
#include <widgets/GsDialog.h>
#include <widgets/GsText.h>
......@@ -155,6 +156,8 @@ private:
int mDownloadProgress = 0;
ThreadPoolItem* mpGameDownloader;
bool scanSubDirectories(const std::string& path,
const size_t maxdepth,
const size_t startPermil,
......
......@@ -20,6 +20,7 @@ endif()
add_subdirectory(refkeen)
add_library(engine OBJECT CGameLauncher.cpp CGameLauncher.h)
add_library(engine OBJECT CGameLauncher.cpp CGameLauncher.h
gamedownloader.cpp gamedownloader.h)
set_property(GLOBAL APPEND PROPERTY CG_OBJ_LIBS $<TARGET_OBJECTS:engine>)
#include "gamedownloader.h"
#include <cstdio>
#include <curl/curl.h>
// Limit to max 1 GB
const curl_off_t STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES = 1024 * 1024 * 1024;
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3
struct myprogress {
double lastruntime;
CURL *curl;
};
int *progressPtr;
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
static int xferinfo(void *p,
curl_off_t dltotal, curl_off_t dlnow,
curl_off_t ultotal, curl_off_t ulnow)
{
struct myprogress *myp = (struct myprogress *)p;
CURL *curl = myp->curl;
double curtime = 0;
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &curtime);
/* under certain circumstances it may be desirable for certain functionality
to only run every N seconds, in order to do this the transaction time can
be used */
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
myp->lastruntime = curtime;
//fprintf(stderr, "TOTAL TIME: %f \r\n", curtime);
}
/*fprintf(stderr, "UP: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
" DOWN: %" CURL_FORMAT_CURL_OFF_T " of %" CURL_FORMAT_CURL_OFF_T
"\r\n",
ulnow, ultotal, dlnow, dltotal);*/
if(dltotal > 0)
{
const int newProgress = (1000*dlnow)/dltotal;
*progressPtr = newProgress;
}
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
{
return 1;
}
return 0;
}
/* for libcurl older than 7.32.0 (CURLOPT_PROGRESSFUNCTION) */
static int older_progress(void *p,
double dltotal, double dlnow,
double ultotal, double ulnow)
{
return xferinfo(p,
(curl_off_t)dltotal,
(curl_off_t)dlnow,
(curl_off_t)ultotal,
(curl_off_t)ulnow);
}
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int downloadFile(const std::string &filename, int &progress)
{
progressPtr = &progress;
const std::string urlString = "http://downloads.sourceforge.net/project/clonekeenplus/Downloads/" + filename;
CURL *curl;
CURLcode res = CURLE_OK;
struct myprogress prog;
curl = curl_easy_init();
if(curl)
{
prog.lastruntime = 0;
prog.curl = curl;
curl_easy_setopt(curl, CURLOPT_URL, urlString.c_str());
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, older_progress);
/* pass the struct pointer into the progress function */
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &prog);
FILE *fp = fopen("test.zip","wb");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
#if LIBCURL_VERSION_NUM >= 0x072000
/* xferinfo was introduced in 7.32.0, no earlier libcurl versions will
compile as they won't have the symbols around.
If built with a newer libcurl, but running with an older libcurl:
curl_easy_setopt() will fail in run-time trying to set the new
callback, making the older callback get used.
New libcurls will prefer the new callback and instead use that one even
if both callbacks are set. */
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
/* pass the struct pointer into the xferinfo function, note that this is
an alias to CURLOPT_PROGRESSDATA */
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
#endif
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "%s\n", curl_easy_strerror(res));
/* always cleanup */
curl_easy_cleanup(curl);
fclose(fp);
}
return (int)res;
}
int GameDownloader::handle()
{
int res;
res = downloadFile("KEEN4Special.zip", mProgress);
return res;
}
#ifndef GAMEDOWNLOADER_H
#define GAMEDOWNLOADER_H
#include <base/utils/ThreadPool.h>
class GameDownloader : public Action
{
public:
GameDownloader(int &progress) : mProgress(progress) {}
int handle();
private:
int &mProgress;
};
#endif // GAMEDOWNLOADER_H
#ifndef __CG__VERSION_H__
#define __CG__VERSION_H__
#define CGVERSION "1.9.3-Beta"
#define CGVERSION "1.9.4-Beta"
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment