diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2012-11-17 19:44:09 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2012-11-17 19:44:09 (GMT) |
| commit | 058a2edd75debbd0297f92572316daa704bd379f (patch) | |
| tree | ad303f091f9a08b209b91eb34a9fcad996a3de69 /src/update/UpdateActivity.cpp | |
| parent | e3594aba9e05c6865d396418c028049cda92c2f3 (diff) | |
| parent | 7a21ae192fe19868539956f3fe28e62b2c7c4429 (diff) | |
| download | powder-058a2edd75debbd0297f92572316daa704bd379f.zip powder-058a2edd75debbd0297f92572316daa704bd379f.tar.gz | |
Merge branch 'master' of github.com:FacialTurd/PowderToypp
Diffstat (limited to 'src/update/UpdateActivity.cpp')
| -rw-r--r-- | src/update/UpdateActivity.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/update/UpdateActivity.cpp b/src/update/UpdateActivity.cpp new file mode 100644 index 0000000..0f22df7 --- /dev/null +++ b/src/update/UpdateActivity.cpp @@ -0,0 +1,172 @@ +/* + * UpdateActivity.cpp + * + * Created on: Jun 20, 2012 + * Author: Simon + */ + +#include <bzlib.h> +#include <sstream> +#include "dialogues/ConfirmPrompt.h" +#include "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() { + // TODO Auto-generated destructor stub +} + |
