From 222db257d7de12f1077eb43d448d6b357d4642e7 Mon Sep 17 00:00:00 2001 From: Bjørn Lindeijer Date: Tue, 4 Nov 2008 21:50:17 +0000 Subject: Merged revisions 4332 via svnmerge from https://themanaworld.svn.sourceforge.net/svnroot/themanaworld/tmw/branches/0.0 ........ r4332 | b_lindeijer | 2008-06-05 09:33:12 +0200 (Thu, 05 Jun 2008) | 5 lines 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. ........ --- ChangeLog | 17 ++++- src/gui/updatewindow.cpp | 52 ++++++++++----- src/gui/updatewindow.h | 15 +++-- src/main.cpp | 135 ++++++++++++++++++++++++++------------ src/resources/buddylist.cpp | 6 +- src/resources/resourcemanager.cpp | 3 +- 6 files changed, 156 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cad0bd5..245cc590 100644 --- a/ChangeLog +++ b/ChangeLog @@ -25,9 +25,10 @@ 2008-10-27 Chuck Miller - * src/game.h, src/game.cpp, src/net/protocol.h, src/net/effecthandler.h, - src/net/effecthandler.cpp: Added a handler for handling effects sent - from the server, you'll need the latest server patch for them too work + * src/game.h, src/game.cpp, src/net/protocol.h, + src/net/effecthandler.h, src/net/effecthandler.cpp: Added a handler + for handling effects sent from the server, you'll need the latest + server patch for them too work. * src/effectmanager.cpp: Removed some debugging code left in by mistake. @@ -392,6 +393,16 @@ * src/channel.cpp, src/channel.h: Don't store channel users, its handled with packets. +2008-06-05 Bjørn Lindeijer + + * 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-03 Roderic Morris * src/gui/chat.cpp, src/gui/chat.h, src/net/guildhandler.cpp: Get rid diff --git a/src/gui/updatewindow.cpp b/src/gui/updatewindow.cpp index 10d0c826..22bf8c13 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 +loadTextFile(const std::string &fileName) +{ + std::vector 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 bf389d81..59d21ef7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -102,8 +102,6 @@ Graphics *graphics; unsigned char state; std::string errorMessage; -std::string homeDir; -unsigned char screen_mode; Sound sound; Music *bgm; @@ -112,10 +110,24 @@ Configuration config; /**< XML file configuration reader */ Logger *logger; /**< Log object */ KeyboardConfig keyboard; -Net::Connection *accountServerConnection = 0; Net::Connection *gameServerConnection = 0; Net::Connection *chatServerConnection = 0; +CharServerHandler charServerHandler; +LoginData loginData; +LoginHandler loginHandler; +LogoutHandler logoutHandler; +LockedArray charInfo(maxSlot + 1); + +// This anonymous namespace hides whatever is inside from other modules. +namespace { + +Net::Connection *accountServerConnection = 0; + +std::string homeDir; +std::string updateHost; +std::string updatesDir; + /** * A structure holding the values of various options that can be passed from * the command line. @@ -140,12 +152,15 @@ struct Options std::string playername; std::string password; std::string configPath; + std::string updateHost; std::string dataPath; std::string serverName; short serverPort; }; +} // anonymous namespace + /** * Initializes the home directory. On UNIX and FreeBSD, ~/.tmw is used. On * Windows and other systems we use the current working directory. @@ -205,9 +220,10 @@ void initConfiguration(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 ! @@ -268,18 +284,46 @@ void initEngine(const Options &options) exit(1); } - // 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! Exitting." + // 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); } } + // Add the user's homedir to PhysicsFS search path + resman->addToSearchPath(homeDir, false); + // Add the main data directories to our PhysicsFS search path if (!options.dataPath.empty()) { resman->addToSearchPath(options.dataPath, true); @@ -398,7 +442,8 @@ void printHelp() " -s --server : Login Server name or IP\n" " -o --port : Login Server Port\n" " -p --playername : Login with this player\n" - " -C --configfile : Configuration file to use\n"; + " -C --configfile : Configuration file to use\n" + " -H --updatehost : Use this update host\n"; } void printVersion() @@ -413,7 +458,7 @@ void printVersion() void parseOptions(int argc, char *argv[], Options &options) { - const char *optstring = "hvud:U:P:Dp:s:o:C:"; + const char *optstring = "hvud:U:P:Dp:s:o:C:H:"; const struct option long_options[] = { { "help", no_argument, 0, 'h' }, @@ -427,10 +472,12 @@ void parseOptions(int argc, char *argv[], Options &options) { "port", required_argument, 0, 'o' }, { "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) @@ -471,17 +518,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 lines = resman->loadTextFile(updatesFile); @@ -490,41 +540,39 @@ 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; -LogoutHandler logoutHandler; -LockedArray charInfo(maxSlot + 1); namespace { - struct ErrorListener : public gcn::ActionListener + +struct ErrorListener : public gcn::ActionListener +{ + void action(const gcn::ActionEvent &event) { - void action(const gcn::ActionEvent &event) - { - state = STATE_CHOOSE_SERVER; - } - } errorListener; + state = STATE_CHOOSE_SERVER; + } +} errorListener; - struct AccountListener : public gcn::ActionListener +struct AccountListener : public gcn::ActionListener +{ + void action(const gcn::ActionEvent &event) { - void action(const gcn::ActionEvent &event) - { - state = STATE_CHAR_SELECT; - } - } accountListener; + state = STATE_CHAR_SELECT; + } +} accountListener; - struct LoginListener : public gcn::ActionListener +struct LoginListener : public gcn::ActionListener +{ + void action(const gcn::ActionEvent &event) { - void action(const gcn::ActionEvent &event) - { - state = STATE_LOGIN; - } - } loginListener; -} + state = STATE_LOGIN; + } +} loginListener; + +} // anonymous namespace // TODO Find some nice place for these functions void accountLogin(LoginData *loginData) @@ -928,7 +976,8 @@ int main(int argc, char *argv[]) case STATE_UPDATE: logger->log("State: UPDATE"); // TODO: Revive later - //currentDialog = new UpdaterWindow(); + //currentDialog = new UpdaterWindow(updateHost, + // homeDir + "/" + updatesDir); state = STATE_LOADDATA; break; 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; -- cgit v1.2.3-70-g09d2