The-Powder-Toy/src/update/UpdateActivity.cpp

156 lines
3.5 KiB
C++
Raw Normal View History

2012-06-20 11:51:51 -05:00
/*
* UpdateActivity.cpp
*
* Created on: Jun 20, 2012
* Author: Simon
*/
2012-06-21 09:49:32 -05:00
#include <bzlib.h>
#include <sstream>
#include "interface/Engine.h"
2012-06-20 11:51:51 -05:00
#include "UpdateActivity.h"
#include "tasks/Task.h"
2012-06-21 09:49:32 -05:00
#include "client/HTTP.h"
#include "Update.h"
2012-06-20 11:51:51 -05:00
class UpdateDownloadTask : public Task
{
2012-06-21 09:49:32 -05:00
public:
UpdateDownloadTask(std::string updateName, UpdateActivity * a) : updateName(updateName), a(a) {};
private:
UpdateActivity * a;
std::string updateName;
virtual void notifyDone()
{
a->NotifyDone(this);
}
virtual void doWork()
2012-06-20 11:51:51 -05:00
{
2012-06-21 09:49:32 -05:00
std::stringstream errorStream;
void * request = http_async_req_start(NULL, (char*)updateName.c_str(), NULL, 0, 0);
notifyStatus("Downloading update");
notifyProgress(-1);
while(!http_async_req_status(request))
{
int total, done;
http_async_get_length(request, &total, &done);
notifyProgress((float(done)/float(total))*100.0f);
}
char * data;
int dataLength, status;
data = http_async_req_stop(request, &status, &dataLength);
if (status!=200)
{
if (data)
free(data);
errorStream << "Server responded with Status " << status;
notifyError("Could not download update");
return;
}
if (!data)
{
errorStream << "Server responded with nothing";
notifyError("Server did not return any data");
return;
}
notifyStatus("Unpacking update");
notifyProgress(-1);
int uncompressedLength;
if(dataLength<16)
{
errorStream << "Unsufficient data, got " << dataLength << " bytes";
goto corrupt;
}
if (data[0]!=0x42 || data[1]!=0x75 || data[2]!=0x54 || data[3]!=0x54)
{
errorStream << "Invalid update format";
goto corrupt;
}
uncompressedLength = (unsigned char)data[4];
uncompressedLength |= ((unsigned char)data[5])<<8;
uncompressedLength |= ((unsigned char)data[6])<<16;
uncompressedLength |= ((unsigned char)data[7])<<24;
char * res;
res = (char *)malloc(uncompressedLength);
if (!res)
{
errorStream << "Unable to allocate " << uncompressedLength << " bytes of memory for decompression";
goto corrupt;
}
int dstate;
dstate = BZ2_bzBuffToBuffDecompress((char *)res, (unsigned *)&uncompressedLength, (char *)(data+8), dataLength-8, 0, 0);
if (dstate)
{
errorStream << "Unable to decompress update: " << dstate;
free(res);
goto corrupt;
}
free(data);
notifyStatus("Applying update");
notifyProgress(-1);
if (update_start(res, uncompressedLength))
{
update_cleanup();
notifyError("Update failed - try downloading a new version.");
}
return;
corrupt:
notifyError("Downloaded update is corrupted\n" + errorStream.str());
free(data);
return;
}
2012-06-20 11:51:51 -05:00
};
UpdateActivity::UpdateActivity() {
2012-06-21 09:49:32 -05:00
char my_uri[] = "http://" SERVER "/Update.api?Action=Download&Architecture="
#if defined WIN32
"Windows32"
#elif defined LIN32
"Linux32"
#elif defined LIN64
"Linux64"
#elif defined MACOSX
"MacOSX"
#else
"Unknown"
#endif
"&InstructionSet="
#if defined X86_SSE3
"SSE3"
#elif defined X86_SSE2
"SSE2"
#elif defined X86_SSE
"SSE"
#else
"SSE"
#endif
;
updateDownloadTask = new UpdateDownloadTask(my_uri, this);
updateWindow = new TaskWindow("Downloading update...", updateDownloadTask, true);
}
2012-06-20 11:51:51 -05:00
2012-06-21 09:49:32 -05:00
void UpdateActivity::NotifyDone(Task * sender)
{
updateWindow->Exit();
ui::Engine::Ref().Exit();
delete this;
2012-06-20 11:51:51 -05:00
}
UpdateActivity::~UpdateActivity() {
// TODO Auto-generated destructor stub
}