2017-01-20 08:36:52 -05:00
|
|
|
#pragma once
|
2017-05-15 15:57:45 -04:00
|
|
|
#include "Game/Functions.hpp"
|
2017-01-20 08:36:52 -05:00
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
namespace Components
|
|
|
|
{
|
|
|
|
class Download : public Component
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Download();
|
|
|
|
~Download();
|
|
|
|
|
2017-01-23 16:06:50 -05:00
|
|
|
void preDestroy() override;
|
|
|
|
|
2017-04-06 16:22:47 -04:00
|
|
|
static void InitiateClientDownload(std::string mod, bool map = false);
|
|
|
|
static void InitiateMapDownload(std::string map);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
private:
|
|
|
|
class ClientDownload
|
|
|
|
{
|
|
|
|
public:
|
2017-04-06 16:22:47 -04:00
|
|
|
ClientDownload(bool _isMap = false) : running(false), valid(false), terminateThread(false), isMap(_isMap), totalBytes(0), downBytes(0), lastTimeStamp(0), timeStampBytes(0) {}
|
2017-01-19 16:23:59 -05:00
|
|
|
~ClientDownload() { this->clear(); }
|
|
|
|
|
|
|
|
bool running;
|
|
|
|
bool valid;
|
|
|
|
bool terminateThread;
|
2017-04-06 16:22:47 -04:00
|
|
|
bool isMap;
|
2017-01-19 16:23:59 -05:00
|
|
|
mg_mgr mgr;
|
|
|
|
Network::Address target;
|
|
|
|
std::string mod;
|
|
|
|
std::thread thread;
|
|
|
|
|
|
|
|
size_t totalBytes;
|
|
|
|
size_t downBytes;
|
|
|
|
|
|
|
|
int lastTimeStamp;
|
|
|
|
size_t timeStampBytes;
|
|
|
|
|
|
|
|
class File
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::string name;
|
|
|
|
std::string hash;
|
|
|
|
size_t size;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::vector<File> files;
|
|
|
|
|
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
this->terminateThread = true;
|
|
|
|
|
|
|
|
if (this->thread.joinable())
|
|
|
|
{
|
|
|
|
this->thread.join();
|
|
|
|
}
|
|
|
|
|
|
|
|
this->running = false;
|
|
|
|
this->mod.clear();
|
|
|
|
this->files.clear();
|
|
|
|
|
|
|
|
if (this->valid)
|
|
|
|
{
|
|
|
|
this->valid = false;
|
|
|
|
mg_mgr_free(&(this->mgr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class FileDownload
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ClientDownload* download;
|
|
|
|
ClientDownload::File file;
|
|
|
|
|
|
|
|
int timestamp;
|
|
|
|
bool downloading;
|
|
|
|
unsigned int index;
|
|
|
|
std::string buffer;
|
|
|
|
size_t receivedBytes;
|
|
|
|
};
|
|
|
|
|
2017-05-14 14:14:52 -04:00
|
|
|
class ScriptDownload
|
|
|
|
{
|
|
|
|
public:
|
2017-05-15 15:57:45 -04:00
|
|
|
ScriptDownload(std::string _url, unsigned int _object) : url(_url), object(_object), webIO(nullptr), done(false), notifyRequired(false), totalSize(0), currentSize(0)
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
|
|
|
Game::AddRefToObject(this->getObject());
|
|
|
|
}
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
ScriptDownload(ScriptDownload&& other) noexcept = delete;
|
|
|
|
ScriptDownload& operator=(ScriptDownload&& other) noexcept = delete;
|
2017-05-14 14:14:52 -04:00
|
|
|
|
|
|
|
~ScriptDownload()
|
|
|
|
{
|
|
|
|
if (this->getObject())
|
|
|
|
{
|
|
|
|
Game::RemoveRefToObject(this->getObject());
|
|
|
|
this->object = 0;
|
2017-05-15 15:57:45 -04:00
|
|
|
}
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-06-14 06:06:04 -04:00
|
|
|
if (this->workerThread.joinable())
|
2017-05-15 15:57:45 -04:00
|
|
|
{
|
|
|
|
this->workerThread.join();
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
2017-05-15 15:57:45 -04:00
|
|
|
|
|
|
|
this->destroyWebIO();
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void startWorking()
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-06-14 06:06:04 -04:00
|
|
|
if (!this->isWorking())
|
2017-05-15 15:57:45 -04:00
|
|
|
{
|
|
|
|
this->workerThread = std::thread(std::bind(&ScriptDownload::handler, this));
|
|
|
|
}
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
bool isWorking()
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
return this->workerThread.joinable();
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void notifyProgress()
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
if (this->notifyRequired)
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
this->notifyRequired = false;
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
if (Game::Scr_IsSystemActive())
|
|
|
|
{
|
|
|
|
Game::Scr_AddInt(static_cast<int>(this->totalSize));
|
|
|
|
Game::Scr_AddInt(static_cast<int>(this->currentSize));
|
|
|
|
Game::Scr_NotifyId(this->getObject(), Game::SL_GetString("progress", 0), 2);
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void updateProgress(size_t _currentSize, size_t _toalSize)
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
this->currentSize = _currentSize;
|
|
|
|
this->totalSize = _toalSize;
|
|
|
|
this->notifyRequired = true;
|
|
|
|
}
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void notifyDone()
|
|
|
|
{
|
|
|
|
if (!this->isDone()) return;
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
if (Game::Scr_IsSystemActive())
|
|
|
|
{
|
|
|
|
Game::Scr_AddString(this->result.data()); // No binary data supported yet
|
|
|
|
Game::Scr_AddInt(this->success);
|
|
|
|
Game::Scr_NotifyId(this->getObject(), Game::SL_GetString("done", 0), 2);
|
|
|
|
}
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isDone() { return this->done; };
|
|
|
|
|
|
|
|
std::string getUrl() { return this->url; }
|
|
|
|
unsigned int getObject() { return this->object; }
|
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void cancel()
|
|
|
|
{
|
2017-06-14 06:06:04 -04:00
|
|
|
if (this->webIO)
|
2017-05-15 15:57:45 -04:00
|
|
|
{
|
|
|
|
this->webIO->cancelDownload();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-14 14:14:52 -04:00
|
|
|
private:
|
|
|
|
std::string url;
|
2017-05-15 15:57:45 -04:00
|
|
|
std::string result;
|
2017-05-14 14:14:52 -04:00
|
|
|
unsigned int object;
|
2017-05-15 15:57:45 -04:00
|
|
|
std::thread workerThread;
|
|
|
|
Utils::WebIO* webIO;
|
2017-05-14 14:14:52 -04:00
|
|
|
|
|
|
|
bool done;
|
2017-05-15 15:57:45 -04:00
|
|
|
bool success;
|
|
|
|
bool notifyRequired;
|
|
|
|
size_t totalSize;
|
|
|
|
size_t currentSize;
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
void handler()
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
this->destroyWebIO();
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
this->webIO = new Utils::WebIO("IW4x");
|
|
|
|
this->webIO->setProgressCallback(std::bind(&ScriptDownload::updateProgress, this, std::placeholders::_1, std::placeholders::_2));
|
2017-05-14 14:14:52 -04:00
|
|
|
|
2017-05-15 15:57:45 -04:00
|
|
|
this->result = this->webIO->get(this->url, &this->success);
|
|
|
|
|
|
|
|
this->destroyWebIO();
|
|
|
|
this->done = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void destroyWebIO()
|
|
|
|
{
|
|
|
|
if (this->webIO)
|
2017-05-14 14:14:52 -04:00
|
|
|
{
|
2017-05-15 15:57:45 -04:00
|
|
|
delete this->webIO;
|
|
|
|
this->webIO = nullptr;
|
2017-05-14 14:14:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-01-19 16:23:59 -05:00
|
|
|
static mg_mgr Mgr;
|
|
|
|
static ClientDownload CLDownload;
|
2017-05-15 15:57:45 -04:00
|
|
|
static std::vector<std::shared_ptr<ScriptDownload>> ScriptDownloads;
|
2017-05-25 14:18:20 -04:00
|
|
|
static std::thread ServerThread;
|
|
|
|
static bool Terminate;
|
2017-01-19 16:23:59 -05:00
|
|
|
|
|
|
|
static void EventHandler(mg_connection *nc, int ev, void *ev_data);
|
|
|
|
static void ListHandler(mg_connection *nc, int ev, void *ev_data);
|
2017-04-06 16:22:47 -04:00
|
|
|
static void MapHandler(mg_connection *nc, int ev, void *ev_data);
|
2017-01-19 16:23:59 -05:00
|
|
|
static void FileHandler(mg_connection *nc, int ev, void *ev_data);
|
|
|
|
static void InfoHandler(mg_connection *nc, int ev, void *ev_data);
|
|
|
|
static void DownloadHandler(mg_connection *nc, int ev, void *ev_data);
|
|
|
|
|
|
|
|
static bool IsClient(mg_connection *nc);
|
|
|
|
static Game::client_t* GetClient(mg_connection *nc);
|
|
|
|
static void Forbid(mg_connection *nc);
|
|
|
|
|
|
|
|
static void ModDownloader(ClientDownload* download);
|
|
|
|
static bool ParseModList(ClientDownload* download, std::string list);
|
|
|
|
static bool DownloadFile(ClientDownload* download, unsigned int index);
|
|
|
|
};
|
|
|
|
}
|