Stage 1 of update process completed
This commit is contained in:
parent
8fc3325b1c
commit
550f6e28e0
@ -11,8 +11,8 @@
|
||||
|
||||
namespace style {
|
||||
ui::Colour Colour::InformationTitle = ui::Colour(140, 140, 255);
|
||||
ui::Colour Colour::WarningTitle = ui::Colour(255, 255, 50);
|
||||
ui::Colour Colour::ErrorTitle = ui::Colour(255, 20, 20);
|
||||
ui::Colour Colour::WarningTitle = ui::Colour(255, 216, 32);
|
||||
ui::Colour Colour::ErrorTitle = ui::Colour(255, 64, 32);
|
||||
|
||||
ui::Colour Colour::ConfirmButton = ui::Colour(255, 255, 50);
|
||||
|
||||
|
187
src/Update.cpp
Normal file
187
src/Update.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if !defined(MACOSX) && !defined(BSD)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef MACOSX
|
||||
#include <mach-o/dyld.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <Update.h>
|
||||
#include <Misc.h>
|
||||
|
||||
/*char *exe_name(void)
|
||||
{
|
||||
#if defined WIN32
|
||||
char *name= (char *)malloc(64);
|
||||
DWORD max=64, res;
|
||||
while ((res = GetModuleFileName(NULL, name, max)) >= max)
|
||||
{
|
||||
#elif defined MACOSX
|
||||
char *fn=malloc(64),*name=malloc(PATH_MAX);
|
||||
uint32_t max=64, res;
|
||||
if (_NSGetExecutablePath(fn, &max) != 0)
|
||||
{
|
||||
fn = realloc(fn, max);
|
||||
_NSGetExecutablePath(fn, &max);
|
||||
}
|
||||
if (realpath(fn, name) == NULL)
|
||||
{
|
||||
free(fn);
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
res = 1;
|
||||
#else
|
||||
char fn[64], *name=malloc(64);
|
||||
size_t max=64, res;
|
||||
sprintf(fn, "/proc/self/exe");
|
||||
memset(name, 0, max);
|
||||
while ((res = readlink(fn, name, max)) >= max-1)
|
||||
{
|
||||
#endif
|
||||
#ifndef MACOSX
|
||||
max *= 2;
|
||||
name = (char*)realloc(name, max);
|
||||
memset(name, 0, max);
|
||||
}
|
||||
#endif
|
||||
if (res <= 0)
|
||||
{
|
||||
free(name);
|
||||
return NULL;
|
||||
}
|
||||
return name;
|
||||
}*/
|
||||
|
||||
int update_start(char *data, int len)
|
||||
{
|
||||
char *self=exe_name(), *temp;
|
||||
#ifdef WIN32
|
||||
char *p;
|
||||
#endif
|
||||
FILE *f;
|
||||
int res = 1;
|
||||
|
||||
if (!self)
|
||||
return 1;
|
||||
|
||||
#ifdef WIN32
|
||||
temp = (char*)malloc(strlen(self)+12);
|
||||
strcpy(temp, self);
|
||||
p = temp + strlen(temp) - 4;
|
||||
if (_stricmp(p, ".exe"))
|
||||
p += 4;
|
||||
strcpy(p, "_update.exe");
|
||||
|
||||
if (!MoveFile(self, temp))
|
||||
goto fail;
|
||||
|
||||
f = fopen(self, "wb");
|
||||
if (!f)
|
||||
goto fail;
|
||||
if (fwrite(data, 1, len, f) != len)
|
||||
{
|
||||
fclose(f);
|
||||
DeleteFile(self);
|
||||
goto fail;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if ((int)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32)
|
||||
{
|
||||
DeleteFile(self);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
temp = malloc(strlen(self)+8);
|
||||
strcpy(temp, self);
|
||||
strcat(temp, "-update");
|
||||
|
||||
f = fopen(temp, "w");
|
||||
if (!f)
|
||||
goto fail;
|
||||
if (fwrite(data, 1, len, f) != len)
|
||||
{
|
||||
fclose(f);
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (chmod(temp, 0755))
|
||||
{
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(temp, self))
|
||||
{
|
||||
unlink(temp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
execl(self, "powder-update", NULL);
|
||||
#endif
|
||||
|
||||
fail:
|
||||
free(temp);
|
||||
free(self);
|
||||
return res;
|
||||
}
|
||||
|
||||
int update_finish(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *temp, *self=exe_name(), *p;
|
||||
int timeout = 60, err;
|
||||
|
||||
temp = (char*)malloc(strlen(self)+12);
|
||||
strcpy(temp, self);
|
||||
p = temp + strlen(temp) - 4;
|
||||
if (_stricmp(p, ".exe"))
|
||||
p += 4;
|
||||
strcpy(p, "_update.exe");
|
||||
|
||||
while (!DeleteFile(temp))
|
||||
{
|
||||
err = GetLastError();
|
||||
if (err == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
// just as well, then
|
||||
free(temp);
|
||||
return 0;
|
||||
}
|
||||
Sleep(500);
|
||||
timeout--;
|
||||
if (timeout <= 0)
|
||||
{
|
||||
free(temp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
free(temp);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void update_cleanup(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
update_finish();
|
||||
#endif
|
||||
}
|
16
src/Update.h
Normal file
16
src/Update.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Update.h
|
||||
*
|
||||
* Created on: Jun 21, 2012
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#ifndef UPDATE_H_
|
||||
#define UPDATE_H_
|
||||
|
||||
//char *exe_name(void);
|
||||
int update_start(char *data, int len);
|
||||
int update_finish(void);
|
||||
void update_cleanup(void);
|
||||
|
||||
#endif /* UPDATE_H_ */
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "ConfirmPrompt.h"
|
||||
#include "Style.h"
|
||||
#include "interface/Textblock.h"
|
||||
#include "interface/Button.h"
|
||||
|
||||
@ -15,7 +16,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial
|
||||
{
|
||||
int width, height;
|
||||
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), title);
|
||||
titleLabel->SetTextColour(ui::Colour(220, 220, 50));
|
||||
titleLabel->SetTextColour(style::Colour::WarningTitle);
|
||||
titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
AddComponent(titleLabel);
|
||||
@ -55,7 +56,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial
|
||||
ui::Button * okayButton = new ui::Button(ui::Point(Size.X-76, Size.Y-16), ui::Point(76, 16), "Continue");
|
||||
okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
okayButton->Appearance.TextInactive = ui::Colour(220, 220, 50);
|
||||
okayButton->Appearance.TextInactive = style::Colour::WarningTitle;
|
||||
okayButton->SetActionCallback(new CloseAction(this, ResultOkay));
|
||||
AddComponent(okayButton);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include "Style.h"
|
||||
#include "ErrorMessage.h"
|
||||
#include "interface/Button.h"
|
||||
#include "interface/Label.h"
|
||||
@ -13,7 +14,7 @@ ErrorMessage::ErrorMessage(std::string title, std::string message):
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(200, 75))
|
||||
{
|
||||
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 16), title);
|
||||
titleLabel->SetTextColour(ui::Colour(200, 100, 50));
|
||||
titleLabel->SetTextColour(style::Colour::ErrorTitle);
|
||||
titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
AddComponent(titleLabel);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "dialogues/ConfirmPrompt.h"
|
||||
#include "GameModelException.h"
|
||||
#include "simulation/Air.h"
|
||||
#include "update/UpdateActivity.h"
|
||||
#include "Notification.h"
|
||||
|
||||
using namespace std;
|
||||
@ -675,5 +676,6 @@ void GameController::RemoveNotification(Notification * notification)
|
||||
void GameController::RunUpdater()
|
||||
{
|
||||
Exit();
|
||||
new UpdateActivity();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ SaveRenderer::SaveRenderer(){
|
||||
Thumbnail * SaveRenderer::Render(GameSave * save)
|
||||
{
|
||||
int width, height;
|
||||
Thumbnail * tempThumb;
|
||||
#ifdef OGLR
|
||||
width = save->blockWidth*CELL;
|
||||
height = save->blockHeight*CELL;
|
||||
@ -27,7 +28,7 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
|
||||
VideoBuffer buffer(width, height);
|
||||
buffer.BlendCharacter((width/2)-3, (height/2)-5, 'x', 255, 255, 255, 255);
|
||||
|
||||
Thumbnail * tempThumb = new Thumbnail(0, 0, buffer.Buffer, ui::Point(width, height));
|
||||
tempThumb = new Thumbnail(0, 0, buffer.Buffer, ui::Point(width, height));
|
||||
|
||||
return tempThumb;
|
||||
#else
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "Task.h"
|
||||
#include "TaskListener.h"
|
||||
|
||||
void Task::SetTaskListener(TaskListener * listener)
|
||||
void Task::AddTaskListener(TaskListener * listener)
|
||||
{
|
||||
this->listener = listener;
|
||||
}
|
||||
@ -37,6 +37,11 @@ std::string Task::GetStatus()
|
||||
return status;
|
||||
}
|
||||
|
||||
std::string Task::GetError()
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Task::GetDone()
|
||||
{
|
||||
return done;
|
||||
@ -44,38 +49,50 @@ bool Task::GetDone()
|
||||
|
||||
void Task::Poll()
|
||||
{
|
||||
int newProgress;
|
||||
bool newDone = false;
|
||||
std::string newStatus;
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
newProgress = thProgress;
|
||||
newDone = thDone;
|
||||
newStatus = std::string(thStatus);
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
|
||||
if(newProgress!=progress) {
|
||||
progress = newProgress;
|
||||
if(listener)
|
||||
listener->NotifyProgress(this);
|
||||
}
|
||||
if(newStatus!=status) {
|
||||
status = std::string(newStatus);
|
||||
if(listener)
|
||||
listener->NotifyStatus(this);
|
||||
}
|
||||
|
||||
if(done)
|
||||
if(!done)
|
||||
{
|
||||
pthread_join(doWorkThread, NULL);
|
||||
pthread_mutex_destroy(&taskMutex);
|
||||
after();
|
||||
}
|
||||
int newProgress;
|
||||
bool newDone = false;
|
||||
std::string newStatus;
|
||||
std::string newError;
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
newProgress = thProgress;
|
||||
newDone = thDone;
|
||||
newStatus = std::string(thStatus);
|
||||
newError = std::string(thError);
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
|
||||
if(newDone!=done)
|
||||
{
|
||||
done = newDone;
|
||||
if(listener)
|
||||
listener->NotifyDone(this);
|
||||
if(newProgress!=progress) {
|
||||
progress = newProgress;
|
||||
if(listener)
|
||||
listener->NotifyProgress(this);
|
||||
}
|
||||
|
||||
if(newError!=error) {
|
||||
error = std::string(newError);
|
||||
if(listener)
|
||||
listener->NotifyError(this);
|
||||
}
|
||||
|
||||
if(newStatus!=status) {
|
||||
status = std::string(newStatus);
|
||||
if(listener)
|
||||
listener->NotifyStatus(this);
|
||||
}
|
||||
|
||||
if(done)
|
||||
{
|
||||
pthread_join(doWorkThread, NULL);
|
||||
pthread_mutex_destroy(&taskMutex);
|
||||
after();
|
||||
}
|
||||
|
||||
if(newDone!=done)
|
||||
{
|
||||
done = newDone;
|
||||
if(listener)
|
||||
listener->NotifyDone(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,3 +148,10 @@ void Task::notifyDone()
|
||||
thDone = true;
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
||||
void Task::notifyError(std::string error)
|
||||
{
|
||||
pthread_mutex_lock(&taskMutex);
|
||||
thError = std::string(error);
|
||||
pthread_mutex_unlock(&taskMutex);
|
||||
}
|
||||
|
@ -15,10 +15,11 @@
|
||||
class TaskListener;
|
||||
class Task {
|
||||
public:
|
||||
void SetTaskListener(TaskListener * listener);
|
||||
void AddTaskListener(TaskListener * listener);
|
||||
void Start();
|
||||
int GetProgress();
|
||||
bool GetDone();
|
||||
std::string GetError();
|
||||
std::string GetStatus();
|
||||
void Poll();
|
||||
Task() {}
|
||||
@ -27,10 +28,12 @@ protected:
|
||||
int progress;
|
||||
bool done;
|
||||
std::string status;
|
||||
std::string error;
|
||||
|
||||
int thProgress;
|
||||
bool thDone;
|
||||
std::string thStatus;
|
||||
std::string thError;
|
||||
|
||||
TaskListener * listener;
|
||||
pthread_t doWorkThread;
|
||||
@ -43,9 +46,10 @@ protected:
|
||||
virtual void doWork();
|
||||
static void * doWork_helper(void * ref);
|
||||
|
||||
void notifyProgress(int progress);
|
||||
void notifyStatus(std::string status);
|
||||
void notifyDone();
|
||||
virtual void notifyProgress(int progress);
|
||||
virtual void notifyError(std::string error);
|
||||
virtual void notifyStatus(std::string status);
|
||||
virtual void notifyDone();
|
||||
};
|
||||
|
||||
#endif /* TASK_H_ */
|
||||
|
@ -12,6 +12,7 @@ class Task;
|
||||
class TaskListener {
|
||||
public:
|
||||
virtual void NotifyDone(Task * task) {}
|
||||
virtual void NotifyError(Task * task) {}
|
||||
virtual void NotifyProgress(Task * task) {}
|
||||
virtual void NotifyStatus(Task * task) {}
|
||||
virtual ~TaskListener() {}
|
||||
|
@ -5,28 +5,37 @@
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include "interface/Label.h"
|
||||
#include "TaskWindow.h"
|
||||
#include "dialogues/ErrorMessage.h"
|
||||
#include "Style.h"
|
||||
#include "Task.h"
|
||||
|
||||
TaskWindow::TaskWindow(std::string title_, Task * task_, bool closeOnDone):
|
||||
task(task_),
|
||||
title(title_),
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(300, 200)),
|
||||
ui::Window(ui::Point(-1, -1), ui::Point(240, 60)),
|
||||
progress(0),
|
||||
done(false),
|
||||
closeOnDone(closeOnDone)
|
||||
closeOnDone(closeOnDone),
|
||||
progressStatus("0%")
|
||||
{
|
||||
|
||||
ui::Label * tempLabel = new ui::Label(ui::Point(3, 3), ui::Point(Size.X-6, 16), title);
|
||||
ui::Label * tempLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), title);
|
||||
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
tempLabel->SetTextColour(style::Colour::WarningTitle);
|
||||
AddComponent(tempLabel);
|
||||
|
||||
statusLabel = new ui::Label(ui::Point(3, 19), ui::Point(Size.X-6, 16), "");
|
||||
statusLabel = new ui::Label(ui::Point(4, 23), ui::Point(Size.X-8, 15), "");
|
||||
statusLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||
statusLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||
AddComponent(statusLabel);
|
||||
|
||||
ui::Engine::Ref().ShowWindow(this);
|
||||
|
||||
task->SetTaskListener(this);
|
||||
task->AddTaskListener(this);
|
||||
task->Start();
|
||||
}
|
||||
|
||||
@ -35,6 +44,11 @@ void TaskWindow::NotifyStatus(Task * task)
|
||||
statusLabel->SetText(task->GetStatus());
|
||||
}
|
||||
|
||||
void TaskWindow::NotifyError(Task * task)
|
||||
{
|
||||
new ErrorMessage("Error", task->GetError());
|
||||
}
|
||||
|
||||
void TaskWindow::NotifyDone(Task * task)
|
||||
{
|
||||
if(closeOnDone)
|
||||
@ -53,6 +67,16 @@ void TaskWindow::Exit()
|
||||
void TaskWindow::NotifyProgress(Task * task)
|
||||
{
|
||||
progress = task->GetProgress();
|
||||
std::stringstream pStream;
|
||||
if(progress>-1)
|
||||
{
|
||||
pStream << progress << "%";
|
||||
}
|
||||
else
|
||||
{
|
||||
pStream << "Please wait...";
|
||||
}
|
||||
progressStatus = pStream.str();
|
||||
}
|
||||
|
||||
void TaskWindow::OnTick(float dt)
|
||||
@ -69,26 +93,32 @@ void TaskWindow::OnDraw()
|
||||
g->clearrect(Position.X-2, Position.Y-2, Size.X+3, Size.Y+3);
|
||||
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 255, 255, 255, 255);
|
||||
|
||||
g->drawrect(Position.X + 20, Position.Y + 36, Size.X-40, 24, 255, 255, 255, 255);
|
||||
g->draw_line(Position.X, Position.Y + Size.Y-17, Position.X + Size.X - 1, Position.Y + Size.Y-17, 255, 255, 255, 255);
|
||||
|
||||
ui::Colour progressBarColour = style::Colour::WarningTitle;
|
||||
|
||||
if(progress!=-1)
|
||||
{
|
||||
float size = float(Size.X-40)*(float(progress)/100.0f); // TIL...
|
||||
g->fillrect(Position.X + 20, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
||||
float size = float(Size.X-4)*(float(progress)/100.0f); // TIL...
|
||||
g->fillrect(Position.X + 2, Position.Y + Size.Y-15, size, 13, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
|
||||
} else {
|
||||
int size = 40, rsize = 0;
|
||||
float position = float(Size.X-40)*(intermediatePos/100.0f);
|
||||
if(position + size > Size.X-40)
|
||||
float position = float(Size.X-4)*(intermediatePos/100.0f);
|
||||
if(position + size - 1 > Size.X-4)
|
||||
{
|
||||
size = (Size.X-40)-position;
|
||||
size = (Size.X-4)-position+1;
|
||||
rsize = 40-size;
|
||||
}
|
||||
g->fillrect(Position.X + 20 + position, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
||||
g->fillrect(Position.X + 2 + position, Position.Y + Size.Y-15, size, 13, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
|
||||
if(rsize)
|
||||
{
|
||||
g->fillrect(Position.X + 20, Position.Y + 36, rsize, 24, 255, 255, 255, 255);
|
||||
g->fillrect(Position.X + 2, Position.Y + Size.Y-15, rsize, 13, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
|
||||
}
|
||||
}
|
||||
if(progress<50)
|
||||
g->drawtext(Position.X + ((Size.X-Graphics::textwidth(progressStatus.c_str()))/2), Position.Y + Size.Y-13, progressStatus, 255, 255, 255, 255);
|
||||
else
|
||||
g->drawtext(Position.X + ((Size.X-Graphics::textwidth(progressStatus.c_str()))/2), Position.Y + Size.Y-13, progressStatus, 0, 0, 0, 255);
|
||||
}
|
||||
|
||||
TaskWindow::~TaskWindow() {
|
||||
|
@ -22,11 +22,13 @@ class TaskWindow: public ui::Window, public TaskListener {
|
||||
bool done;
|
||||
bool closeOnDone;
|
||||
ui::Label * statusLabel;
|
||||
std::string progressStatus;
|
||||
public:
|
||||
TaskWindow(std::string title_, Task * task_, bool closeOnDone = true);
|
||||
virtual void NotifyStatus(Task * task);
|
||||
virtual void NotifyDone(Task * task);
|
||||
virtual void NotifyProgress(Task * task);
|
||||
virtual void NotifyError(Task * task);
|
||||
virtual void OnTick(float dt);
|
||||
virtual void OnDraw();
|
||||
virtual void Exit();
|
||||
|
@ -5,21 +5,148 @@
|
||||
* Author: Simon
|
||||
*/
|
||||
|
||||
#include <bzlib.h>
|
||||
#include <sstream>
|
||||
#include "interface/Engine.h"
|
||||
#include "UpdateActivity.h"
|
||||
#include "tasks/Task.h"
|
||||
#include "client/HTTP.h"
|
||||
#include "Update.h"
|
||||
|
||||
|
||||
class UpdateDownloadTask : public Task
|
||||
{
|
||||
UpdateDownloadTask() {};
|
||||
/*virtual void doWork()
|
||||
public:
|
||||
UpdateDownloadTask(std::string updateName, UpdateActivity * a) : updateName(updateName), a(a) {};
|
||||
private:
|
||||
UpdateActivity * a;
|
||||
std::string updateName;
|
||||
virtual void notifyDone()
|
||||
{
|
||||
while(1)
|
||||
}*/
|
||||
a->NotifyDone(this);
|
||||
}
|
||||
virtual void 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
UpdateActivity::UpdateActivity() {
|
||||
// TODO Auto-generated constructor stub
|
||||
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);
|
||||
}
|
||||
|
||||
void UpdateActivity::NotifyDone(Task * sender)
|
||||
{
|
||||
updateWindow->Exit();
|
||||
ui::Engine::Ref().Exit();
|
||||
delete this;
|
||||
}
|
||||
|
||||
UpdateActivity::~UpdateActivity() {
|
||||
|
@ -17,6 +17,7 @@ class UpdateActivity {
|
||||
public:
|
||||
UpdateActivity();
|
||||
virtual ~UpdateActivity();
|
||||
virtual void NotifyDone(Task * sender);
|
||||
};
|
||||
|
||||
#endif /* UPDATEACTIVITY_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user