diff options
author | Eugenio Favalli <elvenprogrammer@gmail.com> | 2005-07-13 19:01:22 +0000 |
---|---|---|
committer | Eugenio Favalli <elvenprogrammer@gmail.com> | 2005-07-13 19:01:22 +0000 |
commit | 1ae9c54d120338e4165d168c72ef16eb7f76ac18 (patch) | |
tree | f4f4cddad188e236ba79eb9265f372d9f923556c | |
parent | 801cd58db50ad29742939144fc799f98232959cc (diff) | |
download | Mana-1ae9c54d120338e4165d168c72ef16eb7f76ac18.tar.gz Mana-1ae9c54d120338e4165d168c72ef16eb7f76ac18.tar.bz2 Mana-1ae9c54d120338e4165d168c72ef16eb7f76ac18.tar.xz Mana-1ae9c54d120338e4165d168c72ef16eb7f76ac18.zip |
My version of the updater
(ok it needs a lot of bug fixes, a lot of checks and whaever else)
WARNING: Needs to be tested
-rw-r--r-- | src/gui/updatewindow.cpp | 207 | ||||
-rw-r--r-- | src/gui/updatewindow.h | 19 | ||||
-rw-r--r-- | src/main.cpp | 166 |
3 files changed, 202 insertions, 190 deletions
diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index b037103b..7ad9b175 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -22,50 +22,215 @@ */ #include "updatewindow.h" +#include "gui.h" +#include "../main.h" +#include "../log.h" +#include <curl/curl.h> #include <sstream> +#include <iostream> +#include <cstdio> +#include "SDL_thread.h" + +UpdaterWindow *updaterWindow; +float progress = 0.0f; +SDL_Thread *thread; +std::string updateHost = "themanaworld.org/files"; +bool downloadComplete = false; UpdaterWindow::UpdaterWindow() - : Window("Updating") + : Window("Updating...") { - setContentSize(320, 96); - - vbox = new VBox(); - label = new gcn::Label("Default text"); - progressBar = new ProgressBar(0.0, 0, 0, 0, 0, 0, 191, 63); + int h = 100; + int w = 320; + setContentSize(w, h); - vbox->setPosition(4, 0); - vbox->setSize(getWidth() - 12, getHeight() - 24); + label = new gcn::Label("Connecting..."); + label->setPosition(5,5); + progressBar = new ProgressBar(0.0, 5, 25, w - 10, 40, 37, 70, 23); + cancelButton = new Button("Cancel"); + cancelButton->setPosition(5, h - 5 - cancelButton->getHeight()); + cancelButton->setEventId("cancel"); + cancelButton->addActionListener(this); + playButton = new Button("Play"); + playButton->setPosition(cancelButton->getX() + cancelButton->getWidth() + 5, + h - 5 - playButton->getHeight()); + playButton->setEventId("play"); + playButton->setEnabled(false); + playButton->addActionListener(this); - vbox->add(label); - vbox->add(progressBar); - - add(vbox); + add(label); + add(progressBar); + add(cancelButton); + add(playButton); + + cancelButton->requestFocus(); + setLocationRelativeTo(getParent()); } UpdaterWindow::~UpdaterWindow() { delete label; delete progressBar; - delete vbox; + delete cancelButton; + delete playButton; } -void UpdaterWindow::setProgress(double p) +void UpdaterWindow::setProgress(float p) { - progress = p; + progressBar->setProgress(p); } void UpdaterWindow::setLabel(const std::string &str) { - labelText = str; + label->setCaption(str); + label->adjustSize(); +} + +void UpdaterWindow::enable() +{ + playButton->setEnabled(true); } void UpdaterWindow::draw(gcn::Graphics *graphics) { - std::stringstream ss; - ss << labelText << " (" << progress * 100 << "%)"; + Window::draw(graphics); +} - label->setCaption(ss.str()); - progressBar->setProgress(progress); +void UpdaterWindow::action(const std::string& eventId) +{ + if (eventId == "cancel") { + state = EXIT; + } + else if (eventId == "play") { + state = LOGIN; + } +} - Window::draw(graphics); +int updateProgress(void *ptr, + double t, /* dltotal */ + double d, /* dlnow */ + double ultotal, + double ulnow) +{ + std::stringstream labelString; + progress = d/t; + labelString << (char *)ptr << " (" << (int)(progress*100) << "%)"; + updaterWindow->setLabel(labelString.str()); + updaterWindow->setProgress(progress); + if(state!=UPDATE) { + // If the action was canceled return an error code to stop the thread + return -1; + } + return 0; +} + +int downloadThread(void *ptr) { + CURL *curl; + CURLcode res; + FILE *outfile; + std::string fileName((char *)ptr); + std::string url(updateHost); + url += "/" + fileName; + logger->log("Downloading: %s", url.c_str()); + + curl = curl_easy_init(); + if(curl) + { + downloadComplete = false; + progress = 0.0f; + // TODO: download in the proper folder (data?) + outfile = fopen(fileName.c_str(), "wb"); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, updateProgress); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, ptr); + + res = curl_easy_perform(curl); + + fclose(outfile); + curl_easy_cleanup(curl); + downloadComplete = true; + } +} + +int download(std::string url) { + thread = SDL_CreateThread(downloadThread, (void *)url.c_str()); + if ( thread == NULL ) { + logger->log("Unable to create thread"); + return 0; + } +} + +void updateData() { + updaterWindow = new UpdaterWindow(); + state = UPDATE; + + std::string updateHost = + config.getValue("updatehost", "themanaworld.org/files"); + // Try to download the updates list + download("resources.txt"); + std::ifstream in; + + while (state == UPDATE) + { + // Handle SDL events + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + state = EXIT; + break; + + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE) + { + state = EXIT; + } + break; + } + + guiInput->pushInput(event); + } + + // If not alredy downloading another file + if (downloadComplete) { + // Try to open resources.txt + if (!in.is_open()) + { + in.open("resources.txt"); + if (!in.is_open()) + { + logger->error("Unable to open resources.txt"); + } + // TODO: check for error 404 + } + else { + if (!in.eof()) + { + // Download each update + std::string line; + getline(in, line); + download(line); + } + else { + // All updates downloaded + updaterWindow->enable(); + updaterWindow->setLabel("Completed"); + } + } + } + + gui->logic(); + + login_wallpaper->draw(screen, 0, 0); + gui->draw(); + guiGraphics->updateScreen(); + } + + in.close(); + + SDL_WaitThread(thread, NULL); + + delete updaterWindow; } diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index b602c053..89e13610 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -27,20 +27,21 @@ #include "window.h" #include "vbox.h" #include "progressbar.h" +#include "button.h" /** * Update progress window GUI * * \ingroup GUI */ -class UpdaterWindow : public Window +class UpdaterWindow : public Window, public gcn::ActionListener { protected: std::string labelText; /**< Text for caption label */ - double progress; /**< Progress */ - VBox *vbox; gcn::Label *label; /**< Progress bar caption */ + Button *cancelButton; /**< Button to stop the update process */ + Button *playButton; /**< Button to start playing */ ProgressBar *progressBar; /**< Update progress bar */ public: @@ -57,14 +58,24 @@ class UpdaterWindow : public Window /** * Set's progress bar status */ - void setProgress(double); + void setProgress(float p); /** * Set's label above progress */ void setLabel(const std::string &); + + /** + * Enables play button + */ + void enable(); + + void action(const std::string& eventId); void draw(gcn::Graphics *); + + int updateState; }; +void updateData(); #endif diff --git a/src/main.cpp b/src/main.cpp index 5fb543fc..3c0d13a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,8 +87,6 @@ Configuration config; /**< Xml file configuration reader */ Logger *logger; /**< Log object */ ItemManager *itemDb; /**< Item database object */ -UpdaterWindow *updaterWindow; /**< Update window */ - /** * Allows the next frame to be drawn (part of framerate limiting) */ @@ -341,91 +339,6 @@ void exit_engine() delete logger; } -/** Update progress callback */ -int -progressCallback(void *clientp, double dltotal, double dlnow, - double utotal, double ulnow) -{ - // update progress bar.. - updaterWindow->setProgress(dlnow / dltotal); - - // draw - gui->logic(); - gui->draw(); - graphics->updateScreen(); - return CURLE_OK; -} - -/** Get filename from URL */ -const char *urlFilename(const char *url) -{ - for (int i = strlen(url); i > 0; i--) - { - if (url[i] == '/') { - return &url[i+1]; - } - } - return NULL; -} - -/** Download file from location */ -int download(const char *location) -{ - if (location == NULL) { - return false; - } - // find local file location - const char *name = urlFilename(location); - if (!name) { - return true; - } - - std::string dest = homeDir; - dest += "/"; - dest += name; - - FILE *fp = NULL; - fp = fopen(dest.c_str(), "w"); - if (!fp) { - return false; - } - - std::cout << "Downloading '" << location << "'" << std::endl; - - // init curl - curl_global_init(CURL_GLOBAL_WIN32); - // download file - CURL *curl = curl_easy_init(); - int ret = 0; - if (curl) - { - curl_easy_setopt(curl, CURLOPT_URL, "curl.haxx.se"); - std::cout << "Debug: setopt" << std::endl; - /*curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false); - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressCallback); - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);*/ - - //ret = curl_easy_perform(curl); - std::cout << "Debug: perform" << std::endl; - curl_easy_cleanup(curl); - std::cout << "Debug: cleanup" << std::endl; - } - else { - ret = 1; - } - - // cleanup curl - curl_global_cleanup(); - fclose(fp); - - if (ret != 0) - std::cout << "Failed!" << std::endl; - std::cout << " (" << ret << ")" << std::endl; - - return (ret == CURLE_OK) ? true : false; -} - /** Check to see if a file exists */ int exists(const std::string &file) { @@ -441,82 +354,6 @@ int exists(const std::string &file) } } -/** Update the game data */ -void update() -{ - updaterWindow = new UpdaterWindow(); - - std::string host = - config.getValue("updatehost", "http://themanaworld.org/"); - - // Add / to host if it's not there yet. - if (host.at(host.length() - 1) != '/') - { - host += "/"; - } - - std::string fullLocation = host; - fullLocation += "resources.txt"; - - std::string fullName = homeDir; - //fullName += "/"; - fullName += "resources.txt"; - - updaterWindow->setLabel(fullLocation); - - // Get resources file - if (!download(fullLocation.c_str())) - { - std::cout << "Error downloading resources.txt" << std::endl; - delete updaterWindow; - return; - } - - std::cout << "Opening " << fullName << std::endl; - - std::ifstream in(fullName.c_str()); - if (!in.is_open()) - { - std::cout << "Error opening" << std::endl; - delete updaterWindow; - return; - } - - std::string line; - - while (!in.eof()) - { - getline(in, line); - - // check for XML tag (if it is XML tag it is error) - if (line[0] == '<') { - std::cout << "Error: resources.txt download error (404)" << std::endl; - break; - } - - fullName = homeDir; - fullName += "/"; - fullName += line; - - fullLocation = host; - fullLocation += line; - - updaterWindow->setLabel(fullLocation); - - if (!exists(fullName)) { - if (!download(fullLocation.c_str())) { - std::cout << "Failed to download " << line << std::endl; - } - } - else { - PHYSFS_addToSearchPath(fullName.c_str(), 1); - } - } - in.close(); - guiTop->remove(updaterWindow); - delete updaterWindow; -} - /** Main */ int main(int argc, char *argv[]) { @@ -588,8 +425,7 @@ int main(int argc, char *argv[]) graphics->updateScreen(); break; case UPDATE: - update(); - state = LOGIN; + updateData(); break; default: state = EXIT; |