diff options
-rwxr-xr-x | configure.ac | 9 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/gui/box.cpp | 1 | ||||
-rw-r--r-- | src/gui/updatewindow.cpp | 71 | ||||
-rw-r--r-- | src/gui/updatewindow.h | 71 | ||||
-rw-r--r-- | src/main.cpp | 162 | ||||
-rw-r--r-- | src/main.h | 19 |
7 files changed, 327 insertions, 12 deletions
diff --git a/configure.ac b/configure.ac index 78c2f7f6..0795d769 100755 --- a/configure.ac +++ b/configure.ac @@ -22,6 +22,13 @@ AC_MSG_ERROR([ *** Unable to find Guichan library (guichan.sf.net)])) AC_CHECK_LIB([physfs], [PHYSFS_init], , AC_MSG_ERROR([ *** Unable to find PhysFS library (icculus.org/physfs/)])) +AC_CHECK_LIB([curl], [curl_global_init], , +AC_MSG_ERROR([ *** Unable to find CURL library (http://curl.haxx.se/)])) +CURL_LIBS=" `curl-config --libs`" +CURL_CFLAGS=" `curl-config --cflags` " +AC_SUBST(CURL_LIBS) +AC_SUBST(CURL_CFLAGS) + AC_CHECK_LIB([xml2], [xmlInitParser], , AC_MSG_ERROR([ *** Unable to find libxml2 library (xmlsoft.org)])) @@ -129,7 +136,7 @@ FIND_PATH(sdl-config, LIBSDL_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/loca ]) if test -n "$LIBSDL_CONFIG"; then - LIBSDL_LIBS="`$LIBSDL_CONFIG --libs` -lSDL_image -lSDL_mixer" + LIBSDL_LIBS="`$LIBSDL_CONFIG --libs` -lSDL_image -lSDL_mixer -lpthread " LIBSDL_CFLAGS="`$LIBSDL_CONFIG --cflags`" AC_DEFINE_UNQUOTED(HAVE_LIBSDL, 1, [Defines if your system has the LIBSDL library]) diff --git a/src/Makefile.am b/src/Makefile.am index b1fe75c5..74b1383f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -99,6 +99,8 @@ tmw_SOURCES = graphic/spriteset.cpp \ gui/vbox.cpp \ gui/hbox.h \ gui/hbox.cpp \ + gui/updatewindow.h \ + gui/updatewindow.cpp \ net/network.cpp \ net/network.h \ net/protocol.cpp \ @@ -152,6 +154,6 @@ INCLUDES = \ # the library search path. tmw_LDFLAGS = $(all_libraries) $(LIBSDL_RPATH) `pkg-config --libs libxml-2.0` -tmw_CXXFLAGS = -Wall $(OPENGL_CFLAGS) $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` -tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl -lguichan $(OPENGL_LIBS) -lphysfs +tmw_CXXFLAGS = -Wall $(OPENGL_CFLAGS) $(LIBSDL_CFLAGS) `pkg-config --cflags libxml-2.0` $(CURL_CFLAGS) +tmw_LDADD = $(LIBSDL_LIBS) -lguichan_sdl -lguichan $(OPENGL_LIBS) -lphysfs $(CURL_LIBS) tmw_TARGET = tmw diff --git a/src/gui/box.cpp b/src/gui/box.cpp index f73cf276..183eabc3 100644 --- a/src/gui/box.cpp +++ b/src/gui/box.cpp @@ -27,6 +27,7 @@ Box::Box() : padding(0), gcn::Container() { + setOpaque(false); } Box::~Box() diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp new file mode 100644 index 00000000..813e6254 --- /dev/null +++ b/src/gui/updatewindow.cpp @@ -0,0 +1,71 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "updatewindow.h" +#include <sstream> + +UpdateWindow::UpdateWindow() + : 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); + + vbox->setPosition(4, 0); + vbox->setSize(getWidth() - 12, getHeight() - 24); + + vbox->add(label); + vbox->add(progressBar); + + add(vbox); +} + +UpdateWindow::~UpdateWindow() +{ + delete label; + delete progressBar; + delete vbox; +} + +void UpdateWindow::setProgress(double p) +{ + progress = p; +} + +void UpdateWindow::setLabel(const std::string &str) +{ + labelText = str; +} + +void UpdateWindow::draw(gcn::Graphics *graphics) +{ + std::stringstream ss; + ss << labelText << " (" << progress * 100 << "%)"; + + label->setCaption(ss.str()); + progressBar->setProgress(progress); + + Window::draw(graphics); +} diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h new file mode 100644 index 00000000..088d65a9 --- /dev/null +++ b/src/gui/updatewindow.h @@ -0,0 +1,71 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana World is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _UPDATEWINDOW_H +#define _UPDATEWINDOW_H + +#include "gui.h" +#include "window.h" +#include "vbox.h" +#include "progressbar.h" + +/** + * Update progress window GUI + * + * \ingroup GUI + */ +class UpdateWindow : public Window +{ + protected: + std::string labelText; /*< Text for caption label */ + double progress; /*< Progress */ + + VBox *vbox; + gcn::Label *label; /*< Progress bar caption */ + ProgressBar *progressBar; /*< Update progress bar */ + + public: + /** + * Constructor + */ + UpdateWindow(); + + /** + * Destructor + */ + ~UpdateWindow(); + + /** + * Set's progress bar status + */ + void setProgress(double); + + /** + * Set's label above progress + */ + void setLabel(const std::string &); + + void draw(gcn::Graphics *); +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp index 9d39f603..35cffbbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,17 +26,21 @@ #include "gui/char_select.h" #include "gui/inventory.h" #include "gui/ok_dialog.h" +#include "gui/updatewindow.h" #include "sound.h" #include "graphics.h" #include "resources/resourcemanager.h" #include "net/protocol.h" #include <iostream> +#include <cstdio> #include <guichan.hpp> #include <physfs.h> #include <libxml/xmlversion.h> #include <libxml/parser.h> +#include <curl/curl.h> #include <SDL.h> +#include <SDL_thread.h> #ifdef USE_OPENGL #include <SDL_opengl.h> #endif @@ -78,6 +82,8 @@ Configuration config; /**< Xml file configuration reader */ Logger *logger; /**< Log object */ ItemManager *itemDb; /**< Item database object */ +UpdateWindow *updateWindow; /**< Update window */ + /** * Allows the next frame to be drawn (part of framerate limiting) */ @@ -174,6 +180,7 @@ void init_engine() config.setValue("sfxVolume", 100); config.setValue("musicVolume", 60); config.setValue("fpslimit", 0); + config.setValue("updatehost", "http://themanaworld.org/"); // Checking if the configuration file exists... otherwise creates it with // default options ! @@ -296,7 +303,7 @@ void init_engine() hairset = new Spriteset(hairImg, 40, 40); gui = new Gui(graphics); - state = LOGIN; + state = UPDATE; /**< Initial game state */ // Initialize sound engine try { @@ -338,6 +345,153 @@ void exit_engine() delete logger; } +/** Update progress callback */ +int progressCallback(void *clientp, double dltotal, double dlnow, + double utotal, double ulnow) +{ + // update progress bar.. + updateWindow->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 << "'"; + + // init curl + curl_global_init(CURL_GLOBAL_ALL); + + // download file + CURL *curl = curl_easy_init(); + curl_easy_setopt(curl, CURLOPT_URL, location); + 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); + int ret = curl_easy_perform(curl); + curl_easy_cleanup(curl); + + // cleanup curl + curl_global_cleanup(); + + fclose(fp); + + if (ret != 0) + std::cout << " failed"; + std::cout << " (" << ret << ")" << std::endl; + + return (ret == CURLE_OK) ? true : false; +} + +/** Check to see if a file exists */ +int exists(const std::string &file) +{ + FILE *fp = NULL; + fp = fopen(file.c_str(), "r"); + if (!fp) { + return false; + } else { + fclose(fp); + return true; + } +} + +/** Update the game data */ +void update() +{ + updateWindow = new UpdateWindow(); + //guiTop->add(updateWindow); + + std::string host = config.getValue("updatehost", "http://themanaworld.org"); + + std::string fullLocation = host; + fullLocation += "/"; + fullLocation += "resources.txt"; + + std::string fullName = homeDir; + fullName += "/"; + fullName += "resources.txt"; + + updateWindow->setLabel(fullLocation); + + // get resources file + if (!download(fullLocation.c_str())) { + std::cout << "Error downloading" << std::endl; + guiTop->remove(updateWindow); + delete updateWindow; + return; + } + + std::cout << "Opening " << fullName << std::endl; + + std::ifstream in(fullName.c_str()); + if (!in.is_open()) { + std::cout << "Error opening" << std::endl; + guiTop->remove(updateWindow); + delete updateWindow; + return; + } + + char line[1024] = ""; + while (!in.eof()) { + in.getline(line, 1024); + + fullName = homeDir; + fullName += "/"; + fullName += line; + + fullLocation = host; + fullLocation += "/"; + fullLocation += line; + + updateWindow->setLabel(fullLocation); + + if (!exists(fullName)) { + if (!download(fullLocation.c_str())) { + std::cout << "Failed to download " << line << std::endl; + } + } + if (exists(fullName)) + PHYSFS_addToSearchPath(fullName.c_str(), 1); + } + + in.close(); + + guiTop->remove(updateWindow); + delete updateWindow; +} + /** Main */ int main(int argc, char *argv[]) { @@ -355,6 +509,8 @@ int main(int argc, char *argv[]) init_engine(); + + SDL_Event event; while (state != EXIT) @@ -407,6 +563,10 @@ int main(int argc, char *argv[]) gui->draw(); graphics->updateScreen(); break; + case UPDATE: + update(); + state = LOGIN; + break; default: state = EXIT; break; @@ -46,14 +46,17 @@ #undef ERROR #endif -#define EXIT 0 -#define LOGIN 1 -#define CHAR_SERVER 2 -#define CHAR_SELECT 3 -#define CHAR_NEW 4 -#define CHAR_DEL 5 -#define GAME 6 -#define ERROR 7 +enum { + EXIT, + LOGIN, + CHAR_SERVER, + CHAR_SELECT, + CHAR_NEW, + CHAR_DEL, + GAME, + ERROR, + UPDATE +}; /* length definitions for several char[]s in order * to be able to use strncpy instead of strcpy for |