diff options
Diffstat (limited to 'src/gui/updatewindow.cpp')
-rw-r--r-- | src/gui/updatewindow.cpp | 207 |
1 files changed, 186 insertions, 21 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; } |