diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2013-03-24 12:24:17 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2013-03-24 12:24:17 (GMT) |
| commit | 9b5b85f9b01cbda7ef9a7ec2a15b2a35630a5b9d (patch) | |
| tree | ac7d040253b459ce102e476cb19ab59e3cfa90d7 /src/gui/update/UpdateActivity.cpp | |
| parent | 6bf98ccdca39936a3c51367862eed7c49f8786ec (diff) | |
| parent | bdc69f31c0be94191015838886bdcc2bc67f1acb (diff) | |
| download | powder-9b5b85f9b01cbda7ef9a7ec2a15b2a35630a5b9d.zip powder-9b5b85f9b01cbda7ef9a7ec2a15b2a35630a5b9d.tar.gz | |
Merge branch 'reorganisation' of github.com:FacialTurd/The-Powder-Toy
Diffstat (limited to 'src/gui/update/UpdateActivity.cpp')
| -rw-r--r-- | src/gui/update/UpdateActivity.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/gui/update/UpdateActivity.cpp b/src/gui/update/UpdateActivity.cpp new file mode 100644 index 0000000..7eadf7f --- /dev/null +++ b/src/gui/update/UpdateActivity.cpp @@ -0,0 +1,164 @@ +#include <bzlib.h> +#include <sstream> +#include "gui/dialogues/ConfirmPrompt.h" +#include "gui/interface/Engine.h" +#include "UpdateActivity.h" +#include "tasks/Task.h" +#include "client/HTTP.h" +#include "client/Client.h" +#include "Update.h" +#include "Misc.h" + + +class UpdateDownloadTask : public Task +{ +public: + UpdateDownloadTask(std::string updateName, UpdateActivity * a) : updateName(updateName), a(a) {}; +private: + UpdateActivity * a; + std::string updateName; + virtual void notifyDoneMain(){ + a->NotifyDone(this); + } + virtual void notifyErrorMain() + { + a->NotifyError(this); + } + virtual bool doWork() + { + 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 false; + } + if (!data) + { + errorStream << "Server responded with nothing"; + notifyError("Server did not return any data"); + return false; + } + + 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); + + Client::Ref().SetPref("version.update", true); + Client::Ref().WritePrefs(); + if (update_start(res, uncompressedLength)) + { + Client::Ref().SetPref("version.update", false); + update_cleanup(); + notifyError("Update failed - try downloading a new version."); + return false; + } + + return true; + + corrupt: + notifyError("Downloaded update is corrupted\n" + errorStream.str()); + free(data); + return false; + } +}; + +UpdateActivity::UpdateActivity() { + std::stringstream file; + file << "http://" << SERVER << Client::Ref().GetUpdateInfo().File; + updateDownloadTask = new UpdateDownloadTask(file.str(), this); + updateWindow = new TaskWindow("Downloading update...", updateDownloadTask, true); +} + +void UpdateActivity::NotifyDone(Task * sender) +{ + if(sender->GetSuccess()) + { + Exit(); + } +} + +void UpdateActivity::Exit() +{ + updateWindow->Exit(); + ui::Engine::Ref().Exit(); + delete this; +} + +void UpdateActivity::NotifyError(Task * sender) +{ + class ErrorMessageCallback: public ConfirmDialogueCallback + { + UpdateActivity * a; + public: + ErrorMessageCallback(UpdateActivity * a_) { a = a_; } + virtual void ConfirmCallback(ConfirmPrompt::DialogueResult result) { + if (result == ConfirmPrompt::ResultOkay) + { + OpenURI("http://powdertoy.co.uk/Download.html"); + } + a->Exit(); + } + virtual ~ErrorMessageCallback() { } + }; + new ConfirmPrompt("Autoupdate failed", "Please visit the website to download a newer version.\nError: " + sender->GetError(), new ErrorMessageCallback(this)); +} + + +UpdateActivity::~UpdateActivity() { +} + |
