Stage 1 of update process completed
This commit is contained in:
parent
8fc3325b1c
commit
550f6e28e0
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
ui::Colour Colour::InformationTitle = ui::Colour(140, 140, 255);
|
ui::Colour Colour::InformationTitle = ui::Colour(140, 140, 255);
|
||||||
ui::Colour Colour::WarningTitle = ui::Colour(255, 255, 50);
|
ui::Colour Colour::WarningTitle = ui::Colour(255, 216, 32);
|
||||||
ui::Colour Colour::ErrorTitle = ui::Colour(255, 20, 20);
|
ui::Colour Colour::ErrorTitle = ui::Colour(255, 64, 32);
|
||||||
|
|
||||||
ui::Colour Colour::ConfirmButton = ui::Colour(255, 255, 50);
|
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 "ConfirmPrompt.h"
|
||||||
|
#include "Style.h"
|
||||||
#include "interface/Textblock.h"
|
#include "interface/Textblock.h"
|
||||||
#include "interface/Button.h"
|
#include "interface/Button.h"
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial
|
|||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 15), title);
|
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.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
AddComponent(titleLabel);
|
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");
|
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.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
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));
|
okayButton->SetActionCallback(new CloseAction(this, ResultOkay));
|
||||||
AddComponent(okayButton);
|
AddComponent(okayButton);
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* Author: Simon
|
* Author: Simon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "Style.h"
|
||||||
#include "ErrorMessage.h"
|
#include "ErrorMessage.h"
|
||||||
#include "interface/Button.h"
|
#include "interface/Button.h"
|
||||||
#include "interface/Label.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::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);
|
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.HorizontalAlign = ui::Appearance::AlignLeft;
|
||||||
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
|
||||||
AddComponent(titleLabel);
|
AddComponent(titleLabel);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "dialogues/ConfirmPrompt.h"
|
#include "dialogues/ConfirmPrompt.h"
|
||||||
#include "GameModelException.h"
|
#include "GameModelException.h"
|
||||||
#include "simulation/Air.h"
|
#include "simulation/Air.h"
|
||||||
|
#include "update/UpdateActivity.h"
|
||||||
#include "Notification.h"
|
#include "Notification.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -675,5 +676,6 @@ void GameController::RemoveNotification(Notification * notification)
|
|||||||
void GameController::RunUpdater()
|
void GameController::RunUpdater()
|
||||||
{
|
{
|
||||||
Exit();
|
Exit();
|
||||||
|
new UpdateActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ SaveRenderer::SaveRenderer(){
|
|||||||
Thumbnail * SaveRenderer::Render(GameSave * save)
|
Thumbnail * SaveRenderer::Render(GameSave * save)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
|
Thumbnail * tempThumb;
|
||||||
#ifdef OGLR
|
#ifdef OGLR
|
||||||
width = save->blockWidth*CELL;
|
width = save->blockWidth*CELL;
|
||||||
height = save->blockHeight*CELL;
|
height = save->blockHeight*CELL;
|
||||||
@ -27,7 +28,7 @@ Thumbnail * SaveRenderer::Render(GameSave * save)
|
|||||||
VideoBuffer buffer(width, height);
|
VideoBuffer buffer(width, height);
|
||||||
buffer.BlendCharacter((width/2)-3, (height/2)-5, 'x', 255, 255, 255, 255);
|
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;
|
return tempThumb;
|
||||||
#else
|
#else
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include "TaskListener.h"
|
#include "TaskListener.h"
|
||||||
|
|
||||||
void Task::SetTaskListener(TaskListener * listener)
|
void Task::AddTaskListener(TaskListener * listener)
|
||||||
{
|
{
|
||||||
this->listener = listener;
|
this->listener = listener;
|
||||||
}
|
}
|
||||||
@ -37,6 +37,11 @@ std::string Task::GetStatus()
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Task::GetError()
|
||||||
|
{
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
bool Task::GetDone()
|
bool Task::GetDone()
|
||||||
{
|
{
|
||||||
return done;
|
return done;
|
||||||
@ -44,13 +49,17 @@ bool Task::GetDone()
|
|||||||
|
|
||||||
void Task::Poll()
|
void Task::Poll()
|
||||||
{
|
{
|
||||||
|
if(!done)
|
||||||
|
{
|
||||||
int newProgress;
|
int newProgress;
|
||||||
bool newDone = false;
|
bool newDone = false;
|
||||||
std::string newStatus;
|
std::string newStatus;
|
||||||
|
std::string newError;
|
||||||
pthread_mutex_lock(&taskMutex);
|
pthread_mutex_lock(&taskMutex);
|
||||||
newProgress = thProgress;
|
newProgress = thProgress;
|
||||||
newDone = thDone;
|
newDone = thDone;
|
||||||
newStatus = std::string(thStatus);
|
newStatus = std::string(thStatus);
|
||||||
|
newError = std::string(thError);
|
||||||
pthread_mutex_unlock(&taskMutex);
|
pthread_mutex_unlock(&taskMutex);
|
||||||
|
|
||||||
if(newProgress!=progress) {
|
if(newProgress!=progress) {
|
||||||
@ -58,6 +67,13 @@ void Task::Poll()
|
|||||||
if(listener)
|
if(listener)
|
||||||
listener->NotifyProgress(this);
|
listener->NotifyProgress(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(newError!=error) {
|
||||||
|
error = std::string(newError);
|
||||||
|
if(listener)
|
||||||
|
listener->NotifyError(this);
|
||||||
|
}
|
||||||
|
|
||||||
if(newStatus!=status) {
|
if(newStatus!=status) {
|
||||||
status = std::string(newStatus);
|
status = std::string(newStatus);
|
||||||
if(listener)
|
if(listener)
|
||||||
@ -77,6 +93,7 @@ void Task::Poll()
|
|||||||
if(listener)
|
if(listener)
|
||||||
listener->NotifyDone(this);
|
listener->NotifyDone(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::~Task()
|
Task::~Task()
|
||||||
@ -131,3 +148,10 @@ void Task::notifyDone()
|
|||||||
thDone = true;
|
thDone = true;
|
||||||
pthread_mutex_unlock(&taskMutex);
|
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 TaskListener;
|
||||||
class Task {
|
class Task {
|
||||||
public:
|
public:
|
||||||
void SetTaskListener(TaskListener * listener);
|
void AddTaskListener(TaskListener * listener);
|
||||||
void Start();
|
void Start();
|
||||||
int GetProgress();
|
int GetProgress();
|
||||||
bool GetDone();
|
bool GetDone();
|
||||||
|
std::string GetError();
|
||||||
std::string GetStatus();
|
std::string GetStatus();
|
||||||
void Poll();
|
void Poll();
|
||||||
Task() {}
|
Task() {}
|
||||||
@ -27,10 +28,12 @@ protected:
|
|||||||
int progress;
|
int progress;
|
||||||
bool done;
|
bool done;
|
||||||
std::string status;
|
std::string status;
|
||||||
|
std::string error;
|
||||||
|
|
||||||
int thProgress;
|
int thProgress;
|
||||||
bool thDone;
|
bool thDone;
|
||||||
std::string thStatus;
|
std::string thStatus;
|
||||||
|
std::string thError;
|
||||||
|
|
||||||
TaskListener * listener;
|
TaskListener * listener;
|
||||||
pthread_t doWorkThread;
|
pthread_t doWorkThread;
|
||||||
@ -43,9 +46,10 @@ protected:
|
|||||||
virtual void doWork();
|
virtual void doWork();
|
||||||
static void * doWork_helper(void * ref);
|
static void * doWork_helper(void * ref);
|
||||||
|
|
||||||
void notifyProgress(int progress);
|
virtual void notifyProgress(int progress);
|
||||||
void notifyStatus(std::string status);
|
virtual void notifyError(std::string error);
|
||||||
void notifyDone();
|
virtual void notifyStatus(std::string status);
|
||||||
|
virtual void notifyDone();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* TASK_H_ */
|
#endif /* TASK_H_ */
|
||||||
|
@ -12,6 +12,7 @@ class Task;
|
|||||||
class TaskListener {
|
class TaskListener {
|
||||||
public:
|
public:
|
||||||
virtual void NotifyDone(Task * task) {}
|
virtual void NotifyDone(Task * task) {}
|
||||||
|
virtual void NotifyError(Task * task) {}
|
||||||
virtual void NotifyProgress(Task * task) {}
|
virtual void NotifyProgress(Task * task) {}
|
||||||
virtual void NotifyStatus(Task * task) {}
|
virtual void NotifyStatus(Task * task) {}
|
||||||
virtual ~TaskListener() {}
|
virtual ~TaskListener() {}
|
||||||
|
@ -5,28 +5,37 @@
|
|||||||
* Author: Simon
|
* Author: Simon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
#include "interface/Label.h"
|
#include "interface/Label.h"
|
||||||
#include "TaskWindow.h"
|
#include "TaskWindow.h"
|
||||||
|
#include "dialogues/ErrorMessage.h"
|
||||||
|
#include "Style.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
|
|
||||||
TaskWindow::TaskWindow(std::string title_, Task * task_, bool closeOnDone):
|
TaskWindow::TaskWindow(std::string title_, Task * task_, bool closeOnDone):
|
||||||
task(task_),
|
task(task_),
|
||||||
title(title_),
|
title(title_),
|
||||||
ui::Window(ui::Point(-1, -1), ui::Point(300, 200)),
|
ui::Window(ui::Point(-1, -1), ui::Point(240, 60)),
|
||||||
progress(0),
|
progress(0),
|
||||||
done(false),
|
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);
|
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);
|
AddComponent(statusLabel);
|
||||||
|
|
||||||
ui::Engine::Ref().ShowWindow(this);
|
ui::Engine::Ref().ShowWindow(this);
|
||||||
|
|
||||||
task->SetTaskListener(this);
|
task->AddTaskListener(this);
|
||||||
task->Start();
|
task->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +44,11 @@ void TaskWindow::NotifyStatus(Task * task)
|
|||||||
statusLabel->SetText(task->GetStatus());
|
statusLabel->SetText(task->GetStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TaskWindow::NotifyError(Task * task)
|
||||||
|
{
|
||||||
|
new ErrorMessage("Error", task->GetError());
|
||||||
|
}
|
||||||
|
|
||||||
void TaskWindow::NotifyDone(Task * task)
|
void TaskWindow::NotifyDone(Task * task)
|
||||||
{
|
{
|
||||||
if(closeOnDone)
|
if(closeOnDone)
|
||||||
@ -53,6 +67,16 @@ void TaskWindow::Exit()
|
|||||||
void TaskWindow::NotifyProgress(Task * task)
|
void TaskWindow::NotifyProgress(Task * task)
|
||||||
{
|
{
|
||||||
progress = task->GetProgress();
|
progress = task->GetProgress();
|
||||||
|
std::stringstream pStream;
|
||||||
|
if(progress>-1)
|
||||||
|
{
|
||||||
|
pStream << progress << "%";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pStream << "Please wait...";
|
||||||
|
}
|
||||||
|
progressStatus = pStream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskWindow::OnTick(float dt)
|
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->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, 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)
|
if(progress!=-1)
|
||||||
{
|
{
|
||||||
float size = float(Size.X-40)*(float(progress)/100.0f); // TIL...
|
float size = float(Size.X-4)*(float(progress)/100.0f); // TIL...
|
||||||
g->fillrect(Position.X + 20, Position.Y + 36, size, 24, 255, 255, 255, 255);
|
g->fillrect(Position.X + 2, Position.Y + Size.Y-15, size, 13, progressBarColour.Red, progressBarColour.Green, progressBarColour.Blue, 255);
|
||||||
} else {
|
} else {
|
||||||
int size = 40, rsize = 0;
|
int size = 40, rsize = 0;
|
||||||
float position = float(Size.X-40)*(intermediatePos/100.0f);
|
float position = float(Size.X-4)*(intermediatePos/100.0f);
|
||||||
if(position + size > Size.X-40)
|
if(position + size - 1 > Size.X-4)
|
||||||
{
|
{
|
||||||
size = (Size.X-40)-position;
|
size = (Size.X-4)-position+1;
|
||||||
rsize = 40-size;
|
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)
|
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() {
|
TaskWindow::~TaskWindow() {
|
||||||
|
@ -22,11 +22,13 @@ class TaskWindow: public ui::Window, public TaskListener {
|
|||||||
bool done;
|
bool done;
|
||||||
bool closeOnDone;
|
bool closeOnDone;
|
||||||
ui::Label * statusLabel;
|
ui::Label * statusLabel;
|
||||||
|
std::string progressStatus;
|
||||||
public:
|
public:
|
||||||
TaskWindow(std::string title_, Task * task_, bool closeOnDone = true);
|
TaskWindow(std::string title_, Task * task_, bool closeOnDone = true);
|
||||||
virtual void NotifyStatus(Task * task);
|
virtual void NotifyStatus(Task * task);
|
||||||
virtual void NotifyDone(Task * task);
|
virtual void NotifyDone(Task * task);
|
||||||
virtual void NotifyProgress(Task * task);
|
virtual void NotifyProgress(Task * task);
|
||||||
|
virtual void NotifyError(Task * task);
|
||||||
virtual void OnTick(float dt);
|
virtual void OnTick(float dt);
|
||||||
virtual void OnDraw();
|
virtual void OnDraw();
|
||||||
virtual void Exit();
|
virtual void Exit();
|
||||||
|
@ -5,21 +5,148 @@
|
|||||||
* Author: Simon
|
* Author: Simon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <bzlib.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include "interface/Engine.h"
|
||||||
#include "UpdateActivity.h"
|
#include "UpdateActivity.h"
|
||||||
#include "tasks/Task.h"
|
#include "tasks/Task.h"
|
||||||
|
#include "client/HTTP.h"
|
||||||
|
#include "Update.h"
|
||||||
|
|
||||||
|
|
||||||
class UpdateDownloadTask : public Task
|
class UpdateDownloadTask : public Task
|
||||||
{
|
{
|
||||||
UpdateDownloadTask() {};
|
public:
|
||||||
/*virtual void doWork()
|
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() {
|
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() {
|
UpdateActivity::~UpdateActivity() {
|
||||||
|
@ -17,6 +17,7 @@ class UpdateActivity {
|
|||||||
public:
|
public:
|
||||||
UpdateActivity();
|
UpdateActivity();
|
||||||
virtual ~UpdateActivity();
|
virtual ~UpdateActivity();
|
||||||
|
virtual void NotifyDone(Task * sender);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* UPDATEACTIVITY_H_ */
|
#endif /* UPDATEACTIVITY_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user