summaryrefslogtreecommitdiff
path: root/src/gui/update/UpdateActivity.cpp
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2013-03-22 14:14:17 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2013-03-22 14:14:17 (GMT)
commit9abe51526cac2634af0541c3de69834dd30e9f78 (patch)
tree6ae4deadfe00a83094b9d288d8c11d8ce823577a /src/gui/update/UpdateActivity.cpp
parent2c311b9a36a88fadd96f3d39acb1ab2590835d81 (diff)
downloadpowder-9abe51526cac2634af0541c3de69834dd30e9f78.zip
powder-9abe51526cac2634af0541c3de69834dd30e9f78.tar.gz
Move all GUI source files into gui/
Diffstat (limited to 'src/gui/update/UpdateActivity.cpp')
-rw-r--r--src/gui/update/UpdateActivity.cpp164
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..fed34d4
--- /dev/null
+++ b/src/gui/update/UpdateActivity.cpp
@@ -0,0 +1,164 @@
+#include <bzlib.h>
+#include <sstream>
+#include "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() {
+}
+