summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-11-20 23:26:11 +0100
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-11-20 23:37:24 +0100
commitb5963ec28aa76b1a19699a3d06247af93aae6bf5 (patch)
tree9a56c7408a8f3b7c66f785a775c93f793c934178 /src
parenta05fad5acd9c0ff78a4ecd8bd213dd411b062f91 (diff)
downloadmana-client-b5963ec28aa76b1a19699a3d06247af93aae6bf5.tar.gz
mana-client-b5963ec28aa76b1a19699a3d06247af93aae6bf5.tar.bz2
mana-client-b5963ec28aa76b1a19699a3d06247af93aae6bf5.tar.xz
mana-client-b5963ec28aa76b1a19699a3d06247af93aae6bf5.zip
Renabled the dynamic updates
The update host can be optionally received from the server in a succesful login response or register response message. This change also merged Subversion commits 4425 and 4426: ........ r4425 | b_lindeijer | 2008-07-18 00:52:53 +0200 (Fri, 18 Jul 2008) | 3 lines -- Added support for handling the custom eAthena packet that sends the update host (patch by Sanga). ........ r4426 | b_lindeijer | 2008-07-18 01:08:17 +0200 (Fri, 18 Jul 2008) | 3 lines -- Remove possible trailing slash at the end of the update host, since otherwise there'll be two of them.
Diffstat (limited to 'src')
-rw-r--r--src/logindata.h16
-rw-r--r--src/main.cpp122
-rw-r--r--src/net/loginhandler.cpp141
-rw-r--r--src/net/loginhandler.h14
-rw-r--r--src/net/protocol.h13
-rw-r--r--src/serverinfo.h1
6 files changed, 184 insertions, 123 deletions
diff --git a/src/logindata.h b/src/logindata.h
index 3d959ad4..c386f490 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -30,6 +30,7 @@ struct LoginData
std::string password;
std::string newPassword;
std::string hostname;
+ std::string updateHost;
std::string email;
std::string newEmail;
short port;
@@ -39,14 +40,15 @@ struct LoginData
void clear()
{
- username = "";
- password = "";
- newPassword = "";
- hostname = "";
- email = "";
- newEmail = "";
+ username.clear();
+ password.clear();
+ newPassword.clear();
+ hostname.clear();
+ updateHost.clear();
+ email.clear();
+ newEmail.clear();
port = 0;
};
};
-#endif
+#endif // _TMW_LOGINDATA_H
diff --git a/src/main.cpp b/src/main.cpp
index 33900d5d..700e5676 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -161,6 +161,52 @@ struct Options
} // anonymous namespace
/**
+ * Parse the update host and determine the updates directory
+ * Then verify that the directory exists (creating if needed).
+ */
+void setUpdatesDir()
+{
+ // If updatesHost is currently empty, fill it from config file
+ if (updateHost.empty()) {
+ updateHost =
+ config.getValue("updatehost", "http://updates.thanaworld.org");
+ }
+
+ // Remove any trailing slash at the end of the update host
+ if (updateHost.at(updateHost.size() - 1) == '/')
+ updateHost.resize(updateHost.size() - 1);
+
+ // Parse out any "http://" or "ftp://", and set the updates directory
+ size_t pos;
+ pos = updateHost.find("://");
+ if (pos != updateHost.npos) {
+ if (pos + 3 < updateHost.length()) {
+ updatesDir =
+ "updates/" + updateHost.substr(pos + 3);
+ } else {
+ logger->log("Error: Invalid update host: %s", updateHost.c_str());
+ errorMessage = "Invalid update host: " + updateHost;
+ state = STATE_ERROR;
+ }
+ } else {
+ logger->log("Warning: no protocol was specified for the update host");
+ updatesDir = "updates/" + updateHost;
+ }
+
+ ResourceManager *resman = ResourceManager::getInstance();
+
+ // Verify that the updates directory exists. Create if necessary.
+ if (!resman->isDirectory("/" + updatesDir)) {
+ if (!resman->mkdir("/" + updatesDir)) {
+ logger->log("Error: %s/%s can't be made, but doesn't exist!",
+ homeDir.c_str(), updatesDir.c_str());
+ errorMessage = "Error creating updates directory!";
+ state = STATE_ERROR;
+ }
+ }
+}
+
+/**
* Initializes the home directory. On UNIX and FreeBSD, ~/.tmw is used. On
* Windows and other systems we use the current working directory.
*/
@@ -275,43 +321,6 @@ void initEngine(const Options &options)
exit(1);
}
- // 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);
@@ -587,14 +596,17 @@ void accountLogin(LoginData *loginData)
{
logger->log("Username is %s", loginData->username.c_str());
+ loginHandler.setLoginData(loginData);
Net::registerHandler(&loginHandler);
charServerHandler.setCharInfo(&charInfo);
Net::registerHandler(&charServerHandler);
// Send login infos
- Net::AccountServer::login(accountServerConnection, 0,
- loginData->username,loginData->password);
+ Net::AccountServer::login(accountServerConnection,
+ 0, // client version
+ loginData->username,
+ loginData->password);
// Clear the password, avoids auto login when returning to login
loginData->password = "";
@@ -618,8 +630,11 @@ void accountRegister(LoginData *loginData)
charServerHandler.setCharInfo(&charInfo);
Net::registerHandler(&charServerHandler);
- Net::AccountServer::registerAccount(accountServerConnection, 0,
- loginData->username, loginData->password, loginData->email);
+ Net::AccountServer::registerAccount(accountServerConnection,
+ 0, // client version
+ loginData->username,
+ loginData->password,
+ loginData->email);
}
void accountUnRegister(LoginData *loginData)
@@ -939,8 +954,7 @@ int main(int argc, char *argv[])
// Load updates after exiting the update state
if (oldstate == STATE_UPDATE)
{
- // TODO: Revive later
- //loadUpdates();
+ loadUpdates();
// Reload the wallpaper in case that it was updated
login_wallpaper->decRef();
login_wallpaper = ResourceManager::getInstance()->getImage(
@@ -989,11 +1003,16 @@ int main(int argc, char *argv[])
break;
case STATE_UPDATE:
+ // Determine which source to use for the update host
+ if (!options.updateHost.empty())
+ updateHost = options.updateHost;
+ else
+ updateHost = loginData.updateHost;
+
+ setUpdatesDir();
logger->log("State: UPDATE");
- // TODO: Revive later
- //currentDialog = new UpdaterWindow(updateHost,
- // homeDir + "/" + updatesDir);
- state = STATE_LOADDATA;
+ currentDialog = new UpdaterWindow(updateHost,
+ homeDir + "/" + updatesDir);
break;
case STATE_LOGIN:
@@ -1168,7 +1187,7 @@ int main(int argc, char *argv[])
game->logic();
delete game;
- //If the quitdialog didn't set the next state
+ // If the quitdialog didn't set the next state
if (state == STATE_GAME)
{
state = STATE_EXIT;
@@ -1183,12 +1202,13 @@ int main(int argc, char *argv[])
case STATE_RECONNECT_ACCOUNT:
logger->log("State: RECONNECT_ACCOUNT");
- //done with game&chat
+ // Done with game & chat
gameServerConnection->disconnect();
chatServerConnection->disconnect();
- accountServerConnection->connect(loginData.hostname,
- loginData.port);
+ accountServerConnection->connect(
+ loginData.hostname,
+ loginData.port);
break;
case STATE_WAIT:
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index f1898fb5..37c3608a 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -24,6 +24,7 @@
#include "messagein.h"
#include "protocol.h"
+#include "../logindata.h"
#include "../main.h"
LoginHandler::LoginHandler()
@@ -39,73 +40,20 @@ LoginHandler::LoginHandler()
handledMessages = _messages;
}
+void LoginHandler::setLoginData(LoginData *loginData)
+{
+ mLoginData = loginData;
+}
+
void LoginHandler::handleMessage(MessageIn &msg)
{
switch (msg.getId())
{
case APMSG_LOGIN_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Successful login
- if (errMsg == ERRMSG_OK)
- {
- state = STATE_CHAR_SELECT;
- }
- // Login failed
- else
- {
- switch (errMsg) {
- case LOGIN_INVALID_VERSION:
- errorMessage = "Client has an insufficient version number to login.";
- break;
- case ERRMSG_INVALID_ARGUMENT:
- errorMessage = "Wrong username or password";
- break;
- case ERRMSG_FAILURE:
- errorMessage = "Already logged in";
- break;
- case LOGIN_SERVER_FULL:
- errorMessage = "Server is full";
- break;
- default:
- errorMessage = "Unknown error";
- break;
- }
- state = STATE_LOGIN_ERROR;
- }
- }
+ handleLoginResponse(msg);
break;
case APMSG_REGISTER_RESPONSE:
- {
- int errMsg = msg.readInt8();
- // Successful registration
- if (errMsg == ERRMSG_OK)
- {
- state = STATE_CHAR_SELECT;
- }
- // Registration failed
- else
- {
- switch (errMsg) {
- case REGISTER_INVALID_VERSION:
- errorMessage = "Client has an insufficient version number to login.";
- break;
- case ERRMSG_INVALID_ARGUMENT:
- errorMessage = "Wrong username, password or email address";
- break;
- case REGISTER_EXISTS_USERNAME:
- errorMessage = "Username already exists";
- break;
- case REGISTER_EXISTS_EMAIL:
- errorMessage = "Email address already exists";
- break;
- default:
- errorMessage = "Unknown error";
- break;
- }
- state = STATE_LOGIN_ERROR;
- }
- }
+ handleRegisterResponse(msg);
break;
case APMSG_RECONNECT_RESPONSE:
{
@@ -202,3 +150,76 @@ void LoginHandler::handleMessage(MessageIn &msg)
}
}
+
+void LoginHandler::handleLoginResponse(MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readUpdateHost(msg);
+ state = STATE_CHAR_SELECT;
+ }
+ else
+ {
+ switch (errMsg) {
+ case LOGIN_INVALID_VERSION:
+ errorMessage = "Client version is too old";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong username or password";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Already logged in";
+ break;
+ case LOGIN_SERVER_FULL:
+ errorMessage = "Server is full";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_LOGIN_ERROR;
+ }
+}
+
+void LoginHandler::handleRegisterResponse(MessageIn &msg)
+{
+ const int errMsg = msg.readInt8();
+
+ if (errMsg == ERRMSG_OK)
+ {
+ readUpdateHost(msg);
+ state = STATE_CHAR_SELECT;
+ }
+ else
+ {
+ switch (errMsg) {
+ case REGISTER_INVALID_VERSION:
+ errorMessage = "Client version is too old";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong username, password or email address";
+ break;
+ case REGISTER_EXISTS_USERNAME:
+ errorMessage = "Username already exists";
+ break;
+ case REGISTER_EXISTS_EMAIL:
+ errorMessage = "Email address already exists";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = STATE_LOGIN_ERROR;
+ }
+}
+
+void LoginHandler::readUpdateHost(MessageIn &msg)
+{
+ // Set the update host when included in the message
+ if (msg.getUnreadLength() > 0)
+ {
+ mLoginData->updateHost = msg.readString();
+ }
+}
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index f557c97b..015d6383 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -24,12 +24,24 @@
#include "messagehandler.h"
+class LoginData;
+
class LoginHandler : public MessageHandler
{
public:
LoginHandler();
+ void setLoginData(LoginData *loginData);
+
void handleMessage(MessageIn &msg);
+
+ private:
+ void handleLoginResponse(MessageIn &msg);
+ void handleRegisterResponse(MessageIn &msg);
+
+ void readUpdateHost(MessageIn &msg);
+
+ LoginData *mLoginData;
};
-#endif
+#endif // _TMW_NET_LOGINHANDLER_H
diff --git a/src/net/protocol.h b/src/net/protocol.h
index 5dfa78da..5406f248 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -23,24 +23,29 @@
#define _TMW_PROTOCOL_
/**
- * Enumerated type for communicated messages
+ * Enumerated type for communicated messages:
+ *
* - PAMSG_*: from client to account server
* - APMSG_*: from account server to client
* - PCMSG_*: from client to chat server
* - CPMSG_*: from chat server to client
* - PGMSG_*: from client to game server
* - GPMSG_*: from game server to client
+ *
* Components: B byte, W word, D double word, S variable-size string
* C tile-based coordinates (B*3)
+ *
+ * Hosts: P (player's client), A (account server), C (char server),
+ * G (game server)
*/
enum {
// Login/Register
- PAMSG_REGISTER = 0x0000, // L version, S username, S password, S email
- APMSG_REGISTER_RESPONSE = 0x0002, // B error
+ PAMSG_REGISTER = 0x0001, // L version, S username, S password, S email
+ APMSG_REGISTER_RESPONSE = 0x0002, // B error [, S updatehost]
PAMSG_UNREGISTER = 0x0003, // -
APMSG_UNREGISTER_RESPONSE = 0x0004, // B error
PAMSG_LOGIN = 0x0010, // L version, S username, S password
- APMSG_LOGIN_RESPONSE = 0x0012, // B error
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error [, S updatehost]
PAMSG_LOGOUT = 0x0013, // -
APMSG_LOGOUT_RESPONSE = 0x0014, // B error
PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, W*6 stats
diff --git a/src/serverinfo.h b/src/serverinfo.h
index 6522da61..4d2bb525 100644
--- a/src/serverinfo.h
+++ b/src/serverinfo.h
@@ -30,6 +30,7 @@ struct SERVER_INFO
short port;
std::string name;
short online_users;
+ std::string updateHost;
};
#endif