summaryrefslogtreecommitdiff
path: root/src/account-server/accounthandler.cpp
diff options
context:
space:
mode:
authorBjørn Lindeijer <bjorn@lindeijer.nl>2007-02-04 21:52:17 +0000
committerBjørn Lindeijer <bjorn@lindeijer.nl>2007-02-04 21:52:17 +0000
commitcade1ba618bd1883e044999a0cbda201f1f76dd4 (patch)
tree978d8e0d97b0f5b0eec3a77a8d25e54b870ed786 /src/account-server/accounthandler.cpp
parent9c0421f5926d22a44c978fff683c51748a19e976 (diff)
downloadmanaserv-cade1ba618bd1883e044999a0cbda201f1f76dd4.tar.gz
manaserv-cade1ba618bd1883e044999a0cbda201f1f76dd4.tar.bz2
manaserv-cade1ba618bd1883e044999a0cbda201f1f76dd4.tar.xz
manaserv-cade1ba618bd1883e044999a0cbda201f1f76dd4.zip
Added support for switching character by reconnecting to the account server and
fixed the issue where a client is not logged in after registering (patch by Rogier Polak).
Diffstat (limited to 'src/account-server/accounthandler.cpp')
-rw-r--r--src/account-server/accounthandler.cpp141
1 files changed, 133 insertions, 8 deletions
diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp
index 3b0663af..c6a086ea 100644
--- a/src/account-server/accounthandler.cpp
+++ b/src/account-server/accounthandler.cpp
@@ -21,9 +21,11 @@
* $Id$
*/
+#include "account-server/accounthandler.hpp"
+
+#include "defines.h"
#include "configuration.h"
#include "point.h"
-#include "account-server/accounthandler.hpp"
#include "account-server/account.hpp"
#include "account-server/accountclient.hpp"
#include "account-server/serverhandler.hpp"
@@ -36,6 +38,27 @@
#include "utils/logger.h"
#include "utils/stringfilter.h"
+// TODO: Implement a class to handle these tokens more generally
+
+typedef std::map< std::string, AccountClient* > AccountPendingClients;
+typedef std::map< std::string, int > AccountPendingReconnects;
+
+/**
+ * Client is faster then game server
+ */
+static AccountPendingClients pendingClients;
+
+/**
+ * Game server is faster then client
+ */
+static AccountPendingReconnects pendingReconnects;
+
+void
+registerAccountReconnect(int accountID, const std::string& magic_token);
+
+void
+handleReconnectedAccount(AccountClient &computer, int accountID);
+
bool
AccountHandler::startListen(enet_uint16 port)
{
@@ -81,23 +104,33 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
switch (message.getId())
{
case PAMSG_LOGIN:
+ LOG_DEBUG("Received msg ... PAMSG_LOGIN");
handleLoginMessage(computer, message);
break;
case PAMSG_LOGOUT:
+ LOG_DEBUG("Received msg ... PAMSG_LOGOUT");
handleLogoutMessage(computer);
break;
+ case PAMSG_RECONNECT:
+ LOG_DEBUG("Received msg ... PAMSG_RECONNECT");
+ handleReconnectMessage(computer, message);
+ break;
+
case PAMSG_REGISTER:
+ LOG_DEBUG("Received msg ... PAMSG_REGISTER");
handleRegisterMessage(computer, message);
break;
case PAMSG_UNREGISTER:
+ LOG_DEBUG("Received msg ... PAMSG_UNREGISTER");
handleUnregisterMessage(computer, message);
break;
case PAMSG_EMAIL_CHANGE:
{
+ LOG_DEBUG("Received msg ... PAMSG_EMAIL_CHANGE");
result.writeShort(APMSG_EMAIL_CHANGE_RESPONSE);
if (computer.getAccount().get() == NULL) {
@@ -128,6 +161,7 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
case PAMSG_EMAIL_GET:
{
+ LOG_DEBUG("Received msg ... PAMSG_EMAIL_GET");
result.writeShort(APMSG_EMAIL_GET_RESPONSE);
if (computer.getAccount().get() == NULL) {
result.writeByte(ERRMSG_NO_LOGIN);
@@ -142,15 +176,18 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
break;
case PAMSG_PASSWORD_CHANGE:
+ LOG_DEBUG("Received msg ... PAMSG_PASSWORD_CHANGE");
handlePasswordChangeMessage(computer, message);
break;
case PAMSG_CHAR_CREATE:
+ LOG_DEBUG("Received msg ... PAMSG_CHAR_CREATE");
handleCharacterCreateMessage(computer, message);
break;
case PAMSG_CHAR_SELECT:
{
+ LOG_DEBUG("Received msg ... PAMSG_CHAR_SELECT");
result.writeShort(APMSG_CHAR_SELECT_RESPONSE);
if (computer.getAccount().get() == NULL)
@@ -205,6 +242,7 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
case PAMSG_CHAR_DELETE:
{
+ LOG_DEBUG("Received msg ... PAMSG_CHAR_DELETE");
result.writeShort(APMSG_CHAR_DELETE_RESPONSE);
if (computer.getAccount().get() == NULL)
@@ -244,7 +282,8 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
break;
default:
- LOG_WARN("Invalid message type");
+ LOG_WARN("AccountHandler::processMessage, Invalid message type "
+ << message.getId());
result.writeShort(XXMSG_INVALID);
break;
}
@@ -340,6 +379,34 @@ AccountHandler::handleLogoutMessage(AccountClient &computer)
}
void
+AccountHandler::handleReconnectMessage(AccountClient &computer, MessageIn &msg)
+{
+ if (computer.getAccount().get() == NULL)
+ {
+ std::string magic_token = msg.readString(32);
+ AccountPendingReconnects::iterator i = pendingReconnects.find(magic_token);
+ if (i == pendingReconnects.end())
+ {
+ for (AccountPendingClients::iterator j = pendingClients.begin(),
+ j_end = pendingClients.end(); j != j_end; ++j)
+ {
+ if (j->second == &computer) return; //Allready inserted
+ }
+ pendingClients.insert(std::make_pair(magic_token, &computer));
+ return; //Waiting for the gameserver, note: using return instead of an else
+ }
+ // Gameserver communication was faster, connect the client
+ int accountID = i->second;
+ pendingReconnects.erase(i);
+ handleReconnectedAccount(computer, accountID);
+ }
+ else
+ {
+ LOG_WARN("Account tried to reconnect, but was allready logged in.");
+ }
+}
+
+void
AccountHandler::handleRegisterMessage(AccountClient &computer, MessageIn &msg)
{
unsigned long clientVersion = msg.readLong();
@@ -400,6 +467,9 @@ AccountHandler::handleRegisterMessage(AccountClient &computer, MessageIn &msg)
AccountPtr acc(new Account(username, password, email));
store.addAccount(acc);
reply.writeByte(ERRMSG_OK);
+
+ // Associate account with connection
+ computer.setAccount(acc);
}
}
@@ -410,6 +480,7 @@ void
AccountHandler::handleUnregisterMessage(AccountClient &computer,
MessageIn &msg)
{
+ LOG_DEBUG("AccountHandler::handleUnregisterMessage");
std::string username = msg.readString();
std::string password = msg.readString();
@@ -424,13 +495,18 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer,
// See if the account exists
Storage &store = Storage::instance("tmw");
AccountPtr accPtr = store.getAccount(username);
-
+ LOG_INFO("Unregister for " << username << " with passwords #" << accPtr->getPassword() << "#" << password << "#");
if (!accPtr.get() || accPtr->getPassword() != password)
{
reply.writeByte(ERRMSG_INVALID_ARGUMENT);
}
else
{
+ // Delete account and associated characters
+ LOG_DEBUG("Farewell " << username << " ...");
+ store.delAccount(accPtr);
+ reply.writeByte(ERRMSG_OK);
+
// If the account to delete is the current account we're logged in.
// Get out of it in memory.
if (computer.getAccount().get() != NULL )
@@ -440,11 +516,6 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer,
computer.unsetAccount();
}
}
-
- // Delete account and associated characters
- LOG_INFO("Farewell " << username << " ...");
- store.delAccount(accPtr);
- reply.writeByte(ERRMSG_OK);
}
}
@@ -627,3 +698,57 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer,
computer.send(reply);
}
+
+void
+registerAccountReconnect(int accountID, const std::string& magic_token)
+{
+ AccountPendingClients::iterator i = pendingClients.find(magic_token);
+ if (i == pendingClients.end())
+ {
+ pendingReconnects.insert(std::make_pair(magic_token, accountID));
+ }
+ else
+ {
+ AccountClient &computer = *(i->second);
+ handleReconnectedAccount(computer, accountID);
+ pendingClients.erase(i);
+ }
+}
+
+void
+handleReconnectedAccount(AccountClient &computer, int accountID)
+{
+ MessageOut reply(APMSG_RECONNECT_RESPONSE);
+
+ // Check if the account exists
+ Storage &store = Storage::instance("tmw");
+ AccountPtr acc = store.getAccountByID(accountID);
+
+ // Associate account with connection
+ computer.setAccount(acc);
+
+ reply.writeByte(ERRMSG_OK);
+ computer.send(reply);
+
+ // Return information about available characters
+ Players &chars = computer.getAccount()->getCharacters();
+
+ // Send characters list
+ for (unsigned int i = 0; i < chars.size(); i++)
+ {
+ MessageOut charInfo(APMSG_CHAR_INFO);
+ charInfo.writeByte(i); // Slot
+ charInfo.writeString(chars[i]->getName());
+ charInfo.writeByte((unsigned char) chars[i]->getGender());
+ charInfo.writeByte(chars[i]->getHairStyle());
+ charInfo.writeByte(chars[i]->getHairColor());
+ charInfo.writeByte(chars[i]->getLevel());
+ charInfo.writeShort(chars[i]->getMoney());
+
+ for (int j = 0; j < NB_RSTAT; ++j)
+ {
+ charInfo.writeShort(chars[i]->getRawStat(j));
+ }
+ computer.send(charInfo);
+ }
+}