summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-03-07 22:56:05 +0300
committerAndrei Karas <akaras@inbox.ru>2012-03-09 00:29:40 +0300
commiteacf63c7a4c660b38329325c3958bbc63d10ee5c (patch)
treea06eb415526220ce0911c686dd69e9adcf848dd3
parentb384454131c7bd50ba171b1fdbad64cfc83d1ffb (diff)
downloadmv-eacf63c7a4c660b38329325c3958bbc63d10ee5c.tar.gz
mv-eacf63c7a4c660b38329325c3958bbc63d10ee5c.tar.bz2
mv-eacf63c7a4c660b38329325c3958bbc63d10ee5c.tar.xz
mv-eacf63c7a4c660b38329325c3958bbc63d10ee5c.zip
Add support for many update hosts (evol server only).
-rw-r--r--src/client.cpp16
-rw-r--r--src/client.h1
-rw-r--r--src/gui/logindialog.cpp100
-rw-r--r--src/gui/logindialog.h7
-rw-r--r--src/gui/quitdialog.cpp1
-rw-r--r--src/gui/register.cpp2
-rw-r--r--src/gui/worldselectdialog.cpp2
-rw-r--r--src/net/ea/loginhandler.cpp1
-rw-r--r--src/net/ea/loginhandler.h2
-rw-r--r--src/net/logindata.h2
-rw-r--r--src/net/tmwa/loginhandler.cpp48
-rw-r--r--src/net/tmwa/loginhandler.h4
-rw-r--r--src/net/tmwa/network.cpp2
-rw-r--r--src/net/tmwa/protocol.h3
14 files changed, 174 insertions, 17 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 95e49c6aa..98a0fa8fa 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -237,7 +237,7 @@ class LoginListener : public gcn::ActionListener
public:
void action(const gcn::ActionEvent &)
{
- Client::setState(STATE_LOGIN);
+ Client::setState(STATE_PRE_LOGIN);
}
} loginListener;
@@ -945,12 +945,12 @@ int Client::gameExec()
mOldState != STATE_CHOOSE_SERVER &&
Net::getLoginHandler()->isConnected())
{
- mState = STATE_LOGIN;
+ mState = STATE_PRE_LOGIN;
}
else if (mState == STATE_WORLD_SELECT && mOldState == STATE_UPDATE)
{
if (Net::getLoginHandler()->getWorlds().size() < 2)
- mState = STATE_LOGIN;
+ mState = STATE_PRE_LOGIN;
}
else if (mOldState == STATE_START ||
(mOldState == STATE_GAME && mState != STATE_GAME))
@@ -1038,6 +1038,9 @@ int Client::gameExec()
case STATE_CHOOSE_SERVER:
logger->log1("State: CHOOSE SERVER");
+ loginData.clear();
+ serverVersion = 0;
+
// Allow changing this using a server choice dialog
// We show the dialog box only if the command-line
// options weren't set.
@@ -1064,11 +1067,18 @@ int Client::gameExec()
case STATE_CONNECT_SERVER:
logger->log1("State: CONNECT SERVER");
+ loginData.updateHosts.clear();
mCurrentDialog = new ConnectionDialog(
_("Connecting to server"), STATE_SWITCH_SERVER);
TranslationManager::loadCurrentLang();
break;
+ case STATE_PRE_LOGIN:
+ logger->log1("State: PRE_LOGIN");
+// if (serverVersion < 5)
+// setState(STATE_LOGIN);
+ break;
+
case STATE_LOGIN:
logger->log1("State: LOGIN");
// Don't allow an alpha opacity
diff --git a/src/client.h b/src/client.h
index 54de27824..000f8749e 100644
--- a/src/client.h
+++ b/src/client.h
@@ -84,6 +84,7 @@ enum State
STATE_START = 0,
STATE_CHOOSE_SERVER,
STATE_CONNECT_SERVER,
+ STATE_PRE_LOGIN,
STATE_LOGIN,
STATE_LOGIN_ATTEMPT,
STATE_WORLD_SELECT, // 5
diff --git a/src/gui/logindialog.cpp b/src/gui/logindialog.cpp
index cafc4f72c..a139e6b37 100644
--- a/src/gui/logindialog.cpp
+++ b/src/gui/logindialog.cpp
@@ -82,6 +82,36 @@ public:
}
};
+class UpdateListModel : public gcn::ListModel
+{
+ public:
+ UpdateListModel(LoginData *data) :
+ gcn::ListModel(),
+ mLoginData(data)
+ {
+ }
+
+ virtual ~UpdateListModel()
+ { }
+
+ virtual int getNumberOfElements()
+ {
+ if (!mLoginData)
+ return 0;
+ return mLoginData->updateHosts.size();
+ }
+
+ virtual std::string getElementAt(int i)
+ {
+ if (!mLoginData || i >= getNumberOfElements() || i < 0)
+ return _("???");
+
+ return mLoginData->updateHosts[i];
+ }
+ protected:
+ LoginData *mLoginData;
+};
+
LoginDialog::LoginDialog(LoginData *data, std::string serverName,
std::string *updateHost):
Window(_("Login"), false, nullptr, "login.xml"),
@@ -89,12 +119,29 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName,
mUpdateHost(updateHost),
mServerName(serverName)
{
-
gcn::Label *serverLabel1 = new Label(_("Server:"));
gcn::Label *serverLabel2 = new Label(serverName);
serverLabel2->adjustSize();
gcn::Label *userLabel = new Label(_("Name:"));
gcn::Label *passLabel = new Label(_("Password:"));
+ if (mLoginData && mLoginData->updateHosts.size() > 1)
+ {
+ mUpdateHostLabel = new Label(strprintf(_("Update host: %s"),
+ mLoginData->updateHost.c_str()));
+ mUpdateListModel = new UpdateListModel(mLoginData);
+ mUpdateHostDropDown = new DropDown(mUpdateListModel,
+ this, "updateselect");
+ const std::string str = serverConfig.getValue("updateHost2", "");
+ if (!str.empty())
+ mUpdateHostDropDown->setSelectedString(str);
+ }
+ else
+ {
+ mUpdateHostLabel = nullptr;
+ mUpdateListModel = nullptr;
+ mUpdateHostDropDown = nullptr;
+ }
+
mCustomUpdateHost = new CheckBox(_("Custom update host"),
mLoginData->updateType & LoginData::Upd_Custom, this, "customhost");
@@ -135,20 +182,30 @@ LoginDialog::LoginDialog(LoginData *data, std::string serverName,
place(0, 0, serverLabel1);
place(1, 0, serverLabel2, 8);
place(0, 1, userLabel);
- place(0, 2, passLabel);
place(1, 1, mUserField, 8);
+ place(0, 2, passLabel);
place(1, 2, mPassField, 8);
place(0, 6, mUpdateTypeLabel, 1);
place(1, 6, mUpdateTypeDropDown, 8);
- place(0, 7, mCustomUpdateHost, 9);
- place(0, 8, mUpdateHostText, 9);
- place(0, 9, mKeepCheck, 9);
- place(0, 10, mRegisterButton).setHAlign(LayoutCell::LEFT);
- place(2, 10, mServerButton);
- place(3, 10, mLoginButton);
+ int n = 7;
+ if (mUpdateHostLabel)
+ {
+ place(0, 7, mUpdateHostLabel, 9);
+ place(0, 8, mUpdateHostDropDown, 9);
+ n += 2;
+ }
+ place(0, n, mCustomUpdateHost, 9);
+ place(0, n + 1, mUpdateHostText, 9);
+ place(0, n + 2, mKeepCheck, 9);
+ place(0, n + 3, mRegisterButton).setHAlign(LayoutCell::LEFT);
+ place(2, n + 3, mServerButton);
+ place(3, n + 3, mLoginButton);
addKeyListener(this);
- setContentSize(300, 200);
+ if (mUpdateHostLabel)
+ setContentSize(300, 250);
+ else
+ setContentSize(300, 200);
center();
setVisible(true);
@@ -196,6 +253,22 @@ void LoginDialog::action(const gcn::ActionEvent &event)
*mUpdateHost = "";
}
}
+ else if (mUpdateHostDropDown)
+ {
+ const std::string str = mUpdateHostDropDown->getSelectedString();
+ serverConfig.setValue("updateHost2", str);
+ if (!str.empty() && checkPath(str))
+ {
+ mLoginData->updateHost = str;
+ *mUpdateHost = str;
+ }
+ else
+ {
+ mLoginData->updateHost = "";
+ *mUpdateHost = "";
+ }
+ }
+
mLoginData->updateType = updateType;
serverConfig.setValue("updateType", updateType);
@@ -228,6 +301,11 @@ void LoginDialog::action(const gcn::ActionEvent &event)
{
mUpdateHostText->setVisible(mCustomUpdateHost->isSelected());
}
+ else if (event.getId() == "updateselect")
+ {
+ mCustomUpdateHost->setSelected(false);
+ mUpdateHostText->setVisible(false);
+ }
}
void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
@@ -245,6 +323,6 @@ void LoginDialog::keyPressed(gcn::KeyEvent &keyEvent)
bool LoginDialog::canSubmit() const
{
return !mUserField->getText().empty() &&
- !mPassField->getText().empty() &&
- Client::getState() == STATE_LOGIN;
+ !mPassField->getText().empty() &&
+ Client::getState() == STATE_LOGIN;
}
diff --git a/src/gui/logindialog.h b/src/gui/logindialog.h
index 08799b1c2..53149fe0d 100644
--- a/src/gui/logindialog.h
+++ b/src/gui/logindialog.h
@@ -32,7 +32,9 @@
#include <string>
#include <vector>
+class DropDown;
class LoginData;
+class UpdateListModel;
class UpdateTypeModel;
/**
@@ -78,12 +80,15 @@ class LoginDialog : public Window, public gcn::ActionListener,
gcn::TextField *mPassField;
gcn::CheckBox *mKeepCheck;
gcn::Label *mUpdateTypeLabel;
- gcn::DropDown *mUpdateTypeDropDown;
+ gcn::Label *mUpdateHostLabel;
+ DropDown *mUpdateTypeDropDown;
gcn::Button *mServerButton;
gcn::Button *mLoginButton;
gcn::Button *mRegisterButton;
gcn::CheckBox *mCustomUpdateHost;
gcn::TextField *mUpdateHostText;
+ UpdateListModel *mUpdateListModel;
+ DropDown *mUpdateHostDropDown;
LoginData *mLoginData;
std::string *mUpdateHost;
diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp
index dff5a570c..a0f734adf 100644
--- a/src/gui/quitdialog.cpp
+++ b/src/gui/quitdialog.cpp
@@ -64,6 +64,7 @@ QuitDialog::QuitDialog(QuitDialog** pointerToMe):
if (state == STATE_CHOOSE_SERVER ||
state == STATE_CONNECT_SERVER ||
state == STATE_LOGIN ||
+ state == STATE_PRE_LOGIN ||
state == STATE_LOGIN_ATTEMPT ||
state == STATE_UPDATE ||
state == STATE_LOAD_DATA)
diff --git a/src/gui/register.cpp b/src/gui/register.cpp
index bf0cb299e..4f696dc9d 100644
--- a/src/gui/register.cpp
+++ b/src/gui/register.cpp
@@ -154,7 +154,7 @@ void RegisterDialog::action(const gcn::ActionEvent &event)
{
if (event.getId() == "cancel")
{
- Client::setState(STATE_LOGIN);
+ Client::setState(STATE_PRE_LOGIN);
}
else if (event.getId() == "register" && canSubmit())
{
diff --git a/src/gui/worldselectdialog.cpp b/src/gui/worldselectdialog.cpp
index 19e6b81f7..26fd19208 100644
--- a/src/gui/worldselectdialog.cpp
+++ b/src/gui/worldselectdialog.cpp
@@ -132,7 +132,7 @@ void WorldSelectDialog::action(const gcn::ActionEvent &event)
}
else if (event.getId() == "login")
{
- Client::setState(STATE_LOGIN);
+ Client::setState(STATE_PRE_LOGIN);
}
}
diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp
index 39a920f03..560893a4f 100644
--- a/src/net/ea/loginhandler.cpp
+++ b/src/net/ea/loginhandler.cpp
@@ -151,6 +151,7 @@ void LoginHandler::processUpdateHost(Net::MessageIn &msg)
len = msg.readInt16() - 4;
mUpdateHost = msg.readString(len);
+
if (!checkPath(mUpdateHost))
{
mUpdateHost = "";
diff --git a/src/net/ea/loginhandler.h b/src/net/ea/loginhandler.h
index 555de6385..c3bd2a4e8 100644
--- a/src/net/ea/loginhandler.h
+++ b/src/net/ea/loginhandler.h
@@ -79,6 +79,8 @@ class LoginHandler : public Net::LoginHandler
virtual void processUpdateHost(Net::MessageIn &msg);
+ virtual void processUpdateHost2(Net::MessageIn &msg) = 0;
+
virtual void processLoginData(Net::MessageIn &msg);
virtual void processLoginError(Net::MessageIn &msg);
diff --git a/src/net/logindata.h b/src/net/logindata.h
index e5d3fc97a..0f41b02ae 100644
--- a/src/net/logindata.h
+++ b/src/net/logindata.h
@@ -59,6 +59,7 @@ class LoginData
std::string password;
std::string newPassword;
std::string updateHost;
+ std::vector<std::string> updateHosts;
std::string lastLogin;
int updateType;
@@ -79,6 +80,7 @@ class LoginData
password.clear();
newPassword.clear();
updateHost.clear();
+ updateHosts.clear();
updateType = Upd_Normal;
email.clear();
captchaResponse.clear();
diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp
index 3b53bbf7c..a2c5034d6 100644
--- a/src/net/tmwa/loginhandler.cpp
+++ b/src/net/tmwa/loginhandler.cpp
@@ -32,6 +32,7 @@
#include "net/tmwa/protocol.h"
#include "utils/gettext.h"
+#include "utils/paths.h"
#include "debug.h"
@@ -47,6 +48,7 @@ LoginHandler::LoginHandler()
static const Uint16 _messages[] =
{
SMSG_UPDATE_HOST,
+ SMSG_UPDATE_HOST2,
SMSG_LOGIN_DATA,
SMSG_LOGIN_ERROR,
SMSG_CHAR_PASSWORD_RESPONSE,
@@ -73,6 +75,10 @@ void LoginHandler::handleMessage(Net::MessageIn &msg)
processUpdateHost(msg);
break;
+ case SMSG_UPDATE_HOST2:
+ processUpdateHost2(msg);
+ break;
+
case SMSG_LOGIN_DATA:
processLoginData(msg);
break;
@@ -144,6 +150,13 @@ ServerInfo *LoginHandler::getCharServer()
return &charServer;
}
+void LoginHandler::requestUpdateHosts()
+{
+ MessageOut outMsg(CMSG_SEND_CLIENT_INFO);
+ outMsg.writeInt8(CLIENT_PROTOCOL_VERSION);
+ outMsg.writeInt8(0); // unused
+}
+
void LoginHandler::processServerVersion(Net::MessageIn &msg)
{
char b1 = msg.readInt8(); // -1
@@ -156,6 +169,8 @@ void LoginHandler::processServerVersion(Net::MessageIn &msg)
mRegistrationEnabled = options;
msg.skip(2); // 0 unused
serverVersion = msg.readInt8();
+ if (serverVersion >= 5)
+ requestUpdateHosts();
}
else
{
@@ -163,9 +178,42 @@ void LoginHandler::processServerVersion(Net::MessageIn &msg)
mRegistrationEnabled = options;
serverVersion = 0;
}
+ logger->log("Server version: %d", serverVersion);
+ if (serverVersion < 5)
+ {
+ if (Client::getState() != STATE_LOGIN)
+ Client::setState(STATE_LOGIN);
+ }
// Leave this last
mVersionResponse = true;
}
+void LoginHandler::processUpdateHost2(Net::MessageIn &msg)
+{
+ int len;
+
+ len = msg.readInt16() - 4;
+ std::string updateHost = msg.readString(len);
+
+ splitToStringVector(loginData.updateHosts, updateHost, '|');
+ std::vector<std::string>::iterator it = loginData.updateHosts.begin();
+ std::vector<std::string>::iterator it_end = loginData.updateHosts.end();
+ for (; it != it_end; ++ it)
+ {
+ if (!checkPath(*it))
+ {
+ logger->log1("Warning: incorrect update server name");
+ loginData.updateHosts.clear();
+ break;
+ }
+ }
+
+ logger->log("Received update hosts \"%s\" from login server.",
+ updateHost.c_str());
+
+ if (Client::getState() == STATE_PRE_LOGIN)
+ Client::setState(STATE_LOGIN);
+}
+
} // namespace TmwAthena
diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h
index e2b8beec7..b27b0af77 100644
--- a/src/net/tmwa/loginhandler.h
+++ b/src/net/tmwa/loginhandler.h
@@ -67,6 +67,10 @@ class LoginHandler : public MessageHandler, public Ea::LoginHandler
void processServerVersion(Net::MessageIn &msg);
+ void requestUpdateHosts();
+
+ void processUpdateHost2(Net::MessageIn &msg);
+
private:
void sendLoginRegister(const std::string &username,
const std::string &password);
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
index 5d5a84a64..0e0c09d5f 100644
--- a/src/net/tmwa/network.cpp
+++ b/src/net/tmwa/network.cpp
@@ -331,6 +331,8 @@ MessageIn Network::getNextMessage()
int len;
if (msgId == SMSG_SERVER_VERSION_RESPONSE)
len = 10;
+ else if (msgId == SMSG_UPDATE_HOST2)
+ len = -1;
else
len = packet_lengths[msgId];
diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h
index 256f1dce4..130268b82 100644
--- a/src/net/tmwa/protocol.h
+++ b/src/net/tmwa/protocol.h
@@ -338,4 +338,7 @@ enum
#define SMSG_NPC_COMMAND 0x0212
#define CMSG_SET_STATUS 0x0213
+#define CMSG_SEND_CLIENT_INFO 0x7533
+#define SMSG_UPDATE_HOST2 0x7534
+
#endif