summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--src/gui/updatewindow.cpp52
-rw-r--r--src/gui/updatewindow.h15
-rw-r--r--src/main.cpp135
-rw-r--r--src/resources/buddylist.cpp6
-rw-r--r--src/resources/resourcemanager.cpp3
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 <shadowmil@gmail.com>
- * 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 <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-03 Roderic Morris <roderic@ccs.neu.edu>
* 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<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 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<LocalPlayer*> 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<std::string> 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<LocalPlayer*> 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;