summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2008-07-17 22:52:53 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2008-07-17 22:52:53 +0000
commitea37ffc6d73bb0de686c29f8e8c6769f2a704ec5 (patch)
treefcca5b0bdca14ae694702ee4e882ba77a2a9b408 /src
parent406bac35e4c6e79b0ba8d5fe97f32516c8becb0b (diff)
downloadmana-client-ea37ffc6d73bb0de686c29f8e8c6769f2a704ec5.tar.gz
mana-client-ea37ffc6d73bb0de686c29f8e8c6769f2a704ec5.tar.bz2
mana-client-ea37ffc6d73bb0de686c29f8e8c6769f2a704ec5.tar.xz
mana-client-ea37ffc6d73bb0de686c29f8e8c6769f2a704ec5.zip
Added support for handling the custom eAthena packet that sends the update
host (patch by Sanga).
Diffstat (limited to 'src')
-rw-r--r--src/gui/char_server.cpp12
-rw-r--r--src/gui/char_server.h3
-rw-r--r--src/logindata.h1
-rw-r--r--src/main.cpp114
-rw-r--r--src/net/loginhandler.cpp14
-rw-r--r--src/net/loginhandler.h4
-rw-r--r--src/net/network.cpp2
-rw-r--r--src/net/protocol.h1
-rw-r--r--src/serverinfo.h1
9 files changed, 95 insertions, 57 deletions
diff --git a/src/gui/char_server.cpp b/src/gui/char_server.cpp
index 638c05a6..b5ce9021 100644
--- a/src/gui/char_server.cpp
+++ b/src/gui/char_server.cpp
@@ -48,8 +48,10 @@ class ServerListModel : public gcn::ListModel {
std::string getElementAt(int i);
};
-ServerSelectDialog::ServerSelectDialog(LoginData *loginData):
- Window("Select Server"), mLoginData(loginData)
+ServerSelectDialog::ServerSelectDialog(LoginData *loginData, int nextState):
+ Window("Select Server"),
+ mLoginData(loginData),
+ mNextState(nextState)
{
mServerListModel = new ServerListModel();
mServerList = new ListBox(mServerListModel);
@@ -105,10 +107,12 @@ ServerSelectDialog::action(const gcn::ActionEvent &event)
const SERVER_INFO *si = server_info[mServerList->getSelected()];
mLoginData->hostname = iptostring(si->address);
mLoginData->port = si->port;
- state = CHAR_CONNECT_STATE;
+ mLoginData->updateHost = si->updateHost;
+
+ state = mNextState;
}
else if (event.getId() == "cancel") {
- state = LOADDATA_STATE;
+ state = LOGIN_STATE;
}
}
diff --git a/src/gui/char_server.h b/src/gui/char_server.h
index 26e723f9..3e43dd55 100644
--- a/src/gui/char_server.h
+++ b/src/gui/char_server.h
@@ -46,7 +46,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
*
* @see Window::Window
*/
- ServerSelectDialog(LoginData *loginData);
+ ServerSelectDialog(LoginData *loginData, int nextState);
/**
* Destructor.
@@ -63,6 +63,7 @@ class ServerSelectDialog : public Window, public gcn::ActionListener {
ServerListModel *mServerListModel;
gcn::ListBox *mServerList;
gcn::Button *mOkButton;
+ int mNextState;
};
#endif
diff --git a/src/logindata.h b/src/logindata.h
index 8513428f..a2e3f9f1 100644
--- a/src/logindata.h
+++ b/src/logindata.h
@@ -31,6 +31,7 @@ struct LoginData
std::string username;
std::string password;
std::string hostname;
+ std::string updateHost;
short port;
int account_ID;
diff --git a/src/main.cpp b/src/main.cpp
index 7a854123..e13ee390 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -151,6 +151,48 @@ struct Options
};
/**
+ * 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");
+ }
+
+ // 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 = ERROR_STATE;
+ }
+ } 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 = ERROR_STATE;
+ }
+ }
+}
+
+/**
* Do all initialization stuff
*/
void init_engine(const Options &options)
@@ -272,44 +314,6 @@ 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;
@@ -363,7 +367,7 @@ void init_engine(const Options &options)
itemShortcut = new ItemShortcut();
gui = new Gui(graphics);
- state = UPDATE_STATE; /**< Initial game state */
+ state = LOGIN_STATE; /**< Initial game state */
// Initialize sound engine
try {
@@ -541,7 +545,14 @@ void accountLogin(Network *network, LoginData *loginData)
outMsg.writeInt32(0); // client version
outMsg.writeString(loginData->username, 24);
outMsg.writeString(loginData->password, 24);
- outMsg.writeInt8(0); // unknown
+
+ /*
+ * eAthena calls the last byte "client version 2", but it isn't used at
+ * at all. We're retasking it, with bit 0 to indicate whether the client
+ * can handle the 0x63 "update host" packet. Clients prior to 0.0.25 send
+ * 0 here.
+ */
+ outMsg.writeInt8(0x01);
// Clear the password, avoids auto login when returning to login
loginData->password = "";
@@ -648,13 +659,6 @@ int main(int argc, char *argv[])
SDL_Event event;
- if (options.skipUpdate && state != ERROR_STATE) {
- state = LOADDATA_STATE;
- }
- else {
- state = UPDATE_STATE;
- }
-
unsigned int oldstate = !state; // We start with a status change.
Game *game = NULL;
@@ -797,7 +801,7 @@ int main(int argc, char *argv[])
ItemDB::load();
MonsterDB::load();
NPCDB::load();
- state = LOGIN_STATE;
+ state = CHAR_CONNECT_STATE;
break;
case LOGIN_STATE:
@@ -818,7 +822,12 @@ int main(int argc, char *argv[])
case CHAR_SERVER_STATE:
logger->log("State: CHAR_SERVER");
- currentDialog = new ServerSelectDialog(&loginData);
+ {
+ int nextState = (options.skipUpdate) ?
+ LOADDATA_STATE : UPDATE_STATE;
+ currentDialog = new ServerSelectDialog(&loginData,
+ nextState);
+ }
if (options.chooseDefault || options.playername != "") {
((ServerSelectDialog*) currentDialog)->action(
gcn::ActionEvent(NULL, "ok"));
@@ -865,6 +874,13 @@ int main(int argc, char *argv[])
break;
case UPDATE_STATE:
+ // 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");
currentDialog = new UpdaterWindow(updateHost,
homeDir + "/" + updatesDir);
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index ab788e41..8b057afd 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -37,6 +37,7 @@ extern SERVER_INFO **server_info;
LoginHandler::LoginHandler()
{
static const Uint16 _messages[] = {
+ SMSG_UPDATE_HOST,
0x0069,
0x006a,
0
@@ -48,6 +49,16 @@ void LoginHandler::handleMessage(MessageIn *msg)
{
switch (msg->getId())
{
+ case 0x0063:
+ int len;
+
+ len = msg->readInt16() - 4;
+ mUpdateHost = msg->readString(len);
+
+ logger->log("Received update host \"%s\" from login server",
+ mUpdateHost.c_str());
+ break;
+
case 0x0069:
// Skip the length word
msg->skip(2);
@@ -70,6 +81,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
server_info[i]->port = msg->readInt16();
server_info[i]->name = msg->readString(20);
server_info[i]->online_users = msg->readInt32();
+ server_info[i]->updateHost = mUpdateHost;
msg->skip(2); // unknown
logger->log("Network: Server: %s (%s:%d)",
@@ -77,7 +89,7 @@ void LoginHandler::handleMessage(MessageIn *msg)
iptostring(server_info[i]->address),
server_info[i]->port);
}
- state = CHAR_SERVER_STATE;
+ state = CHAR_SERVER_STATE;
break;
case 0x006a:
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index 52014559..86c1b609 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -25,6 +25,7 @@
#define _TMW_NET_LOGINHANDLER_H
#include "messagehandler.h"
+#include <string>
struct LoginData;
@@ -37,8 +38,9 @@ class LoginHandler : public MessageHandler
void setLoginData(LoginData *loginData) { mLoginData = loginData; };
- protected:
+ private:
LoginData *mLoginData;
+ std::string mUpdateHost;
};
#endif
diff --git a/src/net/network.cpp b/src/net/network.cpp
index fa5964d6..375d93e0 100644
--- a/src/net/network.cpp
+++ b/src/net/network.cpp
@@ -41,7 +41,7 @@ short packet_lengths[] = {
// #0x0040
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
+ 0, 0, 0, -1, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
// #0x0080
7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
diff --git a/src/net/protocol.h b/src/net/protocol.h
index 811d5481..eb41a9ac 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -26,6 +26,7 @@
// Packets from server to client
#define SMSG_LOGIN_SUCCESS 0x0073 /**< Contains starting location */
+#define SMSG_UPDATE_HOST 0x0063 /**< Custom update host packet */
#define SMSG_PLAYER_UPDATE_1 0x01d8
#define SMSG_PLAYER_UPDATE_2 0x01d9
#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */
diff --git a/src/serverinfo.h b/src/serverinfo.h
index b317b87b..4f527128 100644
--- a/src/serverinfo.h
+++ b/src/serverinfo.h
@@ -32,6 +32,7 @@ struct SERVER_INFO
short port;
std::string name;
short online_users;
+ std::string updateHost;
};
#endif