diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/gui/updatewindow.cpp | 52 | ||||
-rw-r--r-- | src/gui/updatewindow.h | 15 | ||||
-rw-r--r-- | src/main.cpp | 117 | ||||
-rw-r--r-- | src/resources/buddylist.cpp | 6 | ||||
-rw-r--r-- | src/resources/resourcemanager.cpp | 3 | ||||
-rw-r--r-- | src/resources/spritedef.cpp | 2 |
7 files changed, 142 insertions, 63 deletions
@@ -1,3 +1,13 @@ +2008-06-05 Bjørn Lindeijer <bjorn@lindeijer.nl> + + * src/gui/updatewindow.cpp, src/gui/updatewindow.h, src/main.cpp, + src/resources/buddylist.cpp, src/resources/spritedef.cpp, + src/resources/resourcemanager.cpp: Added command line argument to + specify the update host (-H). Also, to avoid problems when files with + the same name are served by different update hosts, the updates are + now stored in an update host specific directory. Based on a patch by + Sanga. + 2008-06-04 Lloyd Bryant <lloyd_bryant@netzero.net> * src/net/charserverhandler.cpp: Display shield sprite also in diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index f115238d..42b6e9bc 100644 --- a/src/gui/updatewindow.cpp +++ b/src/gui/updatewindow.cpp @@ -46,8 +46,6 @@ #include "../resources/resourcemanager.h" -extern std::string homeDir; - /** * Calculates the Alder-32 checksum for the given file. */ @@ -68,14 +66,38 @@ unsigned long fadler32(FILE *file) return adler; } -UpdaterWindow::UpdaterWindow(): +/** + * Load the given file into a vector of strings. + */ +std::vector<std::string> +loadTextFile(const std::string &fileName) +{ + std::vector<std::string> lines; + std::ifstream fin(fileName.c_str()); + + if (!fin) { + logger->log("Couldn't load text file: %s", fileName.c_str()); + return lines; + } + + std::string line; + + while (getline(fin, line)) + lines.push_back(line); + + return lines; +} + + +UpdaterWindow::UpdaterWindow(const std::string &updateHost, + const std::string &updatesDir): Window("Updating..."), mThread(NULL), mDownloadStatus(UPDATE_NEWS), - mUpdateHost(""), + mUpdateHost(updateHost), + mUpdatesDir(updatesDir), mCurrentFile("news.txt"), mCurrentChecksum(0), - mBasePath(""), mStoreInMemory(true), mDownloadComplete(true), mUserCancel(false), @@ -119,10 +141,6 @@ UpdaterWindow::UpdaterWindow(): setVisible(true); mCancelButton->requestFocus(); - mUpdateHost = - config.getValue("updatehost", "http://updates.themanaworld.org"); - mBasePath = homeDir; - // Try to download the updates list download(); } @@ -141,7 +159,7 @@ UpdaterWindow::~UpdaterWindow() } // Remove possibly leftover temporary download - ::remove((mBasePath + "/updates/download.temp").c_str()); + ::remove((mUpdatesDir + "/download.temp").c_str()); delete[] mCurlError; } @@ -280,9 +298,7 @@ int UpdaterWindow::downloadThread(void *ptr) } else { - // Download in the proper folder : ./updates under win, - // /home/user/.tmw/updates for unices - outFilename = uw->mBasePath + "/updates/download.temp"; + outFilename = uw->mUpdatesDir + "/download.temp"; outfile = fopen(outFilename.c_str(), "w+b"); curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); } @@ -349,8 +365,8 @@ int UpdaterWindow::downloadThread(void *ptr) fclose(outfile); // Give the file the proper name - std::string newName(uw->mBasePath + "/updates/" + - uw->mCurrentFile.c_str()); + const std::string newName = + uw->mUpdatesDir + "/" + uw->mCurrentFile; // Any existing file with this name is deleted first, otherwise // the rename will fail on Windows. @@ -438,8 +454,7 @@ void UpdaterWindow::logic() case UPDATE_LIST: if (mDownloadComplete) { - ResourceManager *resman = ResourceManager::getInstance(); - mLines = resman->loadTextFile("updates/resources2.txt"); + mLines = loadTextFile(mUpdatesDir + "/resources2.txt"); mStoreInMemory = false; mDownloadStatus = UPDATE_RESOURCES; } @@ -463,7 +478,8 @@ void UpdaterWindow::logic() ss >> std::hex >> mCurrentChecksum; std::ifstream temp( - (mBasePath + "/updates/" + mCurrentFile).c_str()); + (mUpdatesDir + "/" + mCurrentFile).c_str()); + if (!temp.is_open()) { temp.close(); diff --git a/src/gui/updatewindow.h b/src/gui/updatewindow.h index b5f6a6df..61ea4a27 100644 --- a/src/gui/updatewindow.h +++ b/src/gui/updatewindow.h @@ -49,9 +49,14 @@ class UpdaterWindow : public Window, public gcn::ActionListener { public: /** - * Constructor + * Constructor. + * + * @param updateHost Host where to get the updated files. + * @param updatesDir Directory where to store updates (should be absolute + * and already created). */ - UpdaterWindow(); + UpdaterWindow(const std::string &updateHost, + const std::string &updatesDir); /** * Destructor @@ -124,15 +129,15 @@ class UpdaterWindow : public Window, public gcn::ActionListener /** Host where we get the updated files. */ std::string mUpdateHost; + /** Place where the updates are stored (absolute path). */ + std::string mUpdatesDir; + /** The file currently downloading. */ std::string mCurrentFile; /** The Adler32 checksum of the file currently downloading. */ unsigned long mCurrentChecksum; - /** Absolute path to locally save downloaded files. */ - std::string mBasePath; - /** A flag to indicate whether to use a memory buffer or a regular file. */ bool mStoreInMemory; diff --git a/src/main.cpp b/src/main.cpp index 1c4895fa..7a854123 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -88,8 +88,6 @@ #include <SDL_syswm.h> #endif -std::string homeDir; - // Account infos char n_server, n_character; @@ -110,6 +108,21 @@ Configuration config; /**< XML file configuration reader */ Logger *logger; /**< Log object */ KeyboardConfig keyboard; +CharServerHandler charServerHandler; +LoginData loginData; +LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1); + + +// This anonymous namespace hides whatever is inside from other modules. +namespace { + +std::string homeDir; +std::string updateHost; +std::string updatesDir; + +LoginHandler loginHandler; +MapLoginHandler mapLoginHandler; + /** * A structure holding the values of various options that can be passed from * the command line. @@ -134,6 +147,7 @@ struct Options std::string password; std::string playername; std::string configPath; + std::string updateHost; }; /** @@ -195,15 +209,6 @@ void init_engine(const Options &options) // Add the user's homedir to PhysicsFS search path resman->addToSearchPath(homeDir, false); - // Creating and checking the updates folder existence and rights. - if (!resman->isDirectory("/updates")) { - if (!resman->mkdir("/updates")) { - std::cout << homeDir << "/updates " - << "can't be made, but it doesn't exist! Exiting." - << std::endl; - exit(1); - } - } // Add the main data directory to our PhysicsFS search path resman->addToSearchPath("data", true); @@ -248,9 +253,10 @@ void init_engine(const Options &options) // default options ! FILE *tmwFile = 0; std::string configPath = options.configPath; - if (configPath == "") { + + if (configPath.empty()) configPath = homeDir + "/config.xml"; - } + tmwFile = fopen(configPath.c_str(), "r"); // If we can't read it, it doesn't exist ! @@ -266,6 +272,44 @@ void init_engine(const Options &options) config.init(configPath); } + + // Take host for updates from config if it wasn't set on the command line + if (options.updateHost.empty()) { + updateHost = + config.getValue("updatehost", "http://updates.thanaworld.org"); + } else { + updateHost = options.updateHost; + } + + // Parse out any "http://" or "ftp://", and set the updates directory + size_t pos; + pos = updateHost.find("//"); + if (pos != updateHost.npos) { + if (pos + 2 < updateHost.length()) { + updatesDir = + "updates/" + updateHost.substr(pos + 2); + } else { + std::cout << "The updates host - " << updateHost + << " does not appear to be valid!" << std::endl + << "Please fix the \"updatehost\" in your configuration" + << " file. Exiting." << std::endl; + exit(1); + } + } else { + logger->log("Warning: no protocol was specified for the update host"); + updatesDir = "updates/" + updateHost; + } + + // Verify that the updates directory exists. Create if necessary. + if (!resman->isDirectory("/" + updatesDir)) { + if (!resman->mkdir("/" + updatesDir)) { + std::cout << homeDir << "/" << updatesDir + << " can't be made, but it doesn't exist! Exiting." + << std::endl; + exit(1); + } + } + SDL_WM_SetCaption("The Mana World", NULL); #ifdef WIN32 static SDL_SysWMinfo pInfo; @@ -382,8 +426,8 @@ void printHelp() << " -P --password : Login with this password" << std::endl << " -D --default : Bypass the login process with default settings" << std::endl << " -p --playername : Login with this player" << std::endl - << " -C --configfile : Configuration file to use" - << std::endl; + << " -C --configfile : Configuration file to use" << std::endl + << " -H --updatehost : Use this update host" << std::endl; } void printVersion() @@ -395,9 +439,10 @@ void printVersion() "(local build?, PACKAGE_VERSION is not defined)" << std::endl; #endif } + void parseOptions(int argc, char *argv[], Options &options) { - const char *optstring = "hvuU:P:Dp:C:"; + const char *optstring = "hvuU:P:Dp:C:H:"; const struct option long_options[] = { { "help", no_argument, 0, 'h' }, @@ -408,10 +453,12 @@ void parseOptions(int argc, char *argv[], Options &options) { "default", no_argument, 0, 'D' }, { "playername", required_argument, 0, 'p' }, { "configfile", required_argument, 0, 'C' }, + { "updatehost", required_argument, 0, 'H' }, { 0 } }; while (optind < argc) { + int result = getopt_long(argc, argv, optstring, long_options, NULL); if (result == -1) { @@ -444,17 +491,20 @@ void parseOptions(int argc, char *argv[], Options &options) case 'C': options.configPath = optarg; break; + case 'H': + options.updateHost = optarg; + break; } } } /** - * Reads the file "updates/resources2.txt" and attempts to load each update - * mentioned in it. + * Reads the file "{Updates Directory}/resources2.txt" and attempts to load + * each update mentioned in it. */ void loadUpdates() { - const std::string updatesFile = "updates/resources2.txt"; + const std::string updatesFile = "/" + updatesDir + "/resources2.txt"; ResourceManager *resman = ResourceManager::getInstance(); std::vector<std::string> lines = resman->loadTextFile(updatesFile); @@ -463,25 +513,18 @@ void loadUpdates() std::stringstream line(lines[i]); std::string filename; line >> filename; - resman->addToSearchPath(homeDir + "/updates/" + filename, false); + resman->addToSearchPath(homeDir + "/" + updatesDir + "/" + + filename, false); } } -CharServerHandler charServerHandler; -LoginData loginData; -LoginHandler loginHandler; -LockedArray<LocalPlayer*> charInfo(MAX_SLOT + 1); -MapLoginHandler mapLoginHandler; - -namespace { - struct ErrorListener : public gcn::ActionListener +struct ErrorListener : public gcn::ActionListener +{ + void action(const gcn::ActionEvent &event) { - void action(const gcn::ActionEvent &event) - { - state = loginData.registerLogin ? REGISTER_STATE : LOGIN_STATE; - } - } errorListener; -} + state = loginData.registerLogin ? REGISTER_STATE : LOGIN_STATE; + } +} errorListener; // TODO Find some nice place for these functions void accountLogin(Network *network, LoginData *loginData) @@ -567,6 +610,9 @@ void mapLogin(Network *network, LoginData *loginData) network->skip(4); } +} // namespace + + /** Main */ int main(int argc, char *argv[]) { @@ -820,7 +866,8 @@ int main(int argc, char *argv[]) case UPDATE_STATE: logger->log("State: UPDATE"); - currentDialog = new UpdaterWindow(); + currentDialog = new UpdaterWindow(updateHost, + homeDir + "/" + updatesDir); break; case ERROR_STATE: diff --git a/src/resources/buddylist.cpp b/src/resources/buddylist.cpp index 2f85825a..32d8d9f4 100644 --- a/src/resources/buddylist.cpp +++ b/src/resources/buddylist.cpp @@ -33,8 +33,12 @@ BuddyList::BuddyList() { + // TODO: A buddy list would have to use the Configuration class to store + // the buddies. Also, there is now a player relationship manager + // which probably makes this buddy list kind of obsolete. + // Find saved buddy list file - mFilename = config.getValue("homeDir", "") + "/buddy.txt"; + //mFilename = homeDir + "/buddy.txt"; // Load buddy from file loadFile(); diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 59202ad8..9c109257 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -446,9 +446,8 @@ ResourceManager::loadTextFile(const std::string &fileName) std::istringstream iss(std::string(fileContents, contentsLength)); std::string line; - while (getline(iss, line, '\n')) { + while (getline(iss, line)) lines.push_back(line); - } free(fileContents); return lines; diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index 3f95b3ec..334474d7 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -51,8 +51,6 @@ SpriteDef::getAction(SpriteAction action) const SpriteDef *SpriteDef::load(std::string const &animationFile, int variant) { - ResourceManager *resman = ResourceManager::getInstance(); - std::string::size_type pos = animationFile.find('|'); std::string palettes; if (pos != std::string::npos) |