summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-06-05 07:33:12 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-06-05 07:33:12 +0000
commit9f35cb7602c55d43ab598145cfcd0703ec1c5059 (patch)
tree2ed8b59c11557289bfe06479687971ea6781c43a
parentef11f1b7f9c1ce48df0eff7acd3886768886449a (diff)
downloadmana-client-9f35cb7602c55d43ab598145cfcd0703ec1c5059.tar.gz
mana-client-9f35cb7602c55d43ab598145cfcd0703ec1c5059.tar.bz2
mana-client-9f35cb7602c55d43ab598145cfcd0703ec1c5059.tar.xz
mana-client-9f35cb7602c55d43ab598145cfcd0703ec1c5059.zip
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.
-rw-r--r--ChangeLog10
-rw-r--r--src/gui/updatewindow.cpp52
-rw-r--r--src/gui/updatewindow.h15
-rw-r--r--src/main.cpp117
-rw-r--r--src/resources/buddylist.cpp6
-rw-r--r--src/resources/resourcemanager.cpp3
-rw-r--r--src/resources/spritedef.cpp2
7 files changed, 142 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 11577f78..58dceb78 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)