From 0cc6167c407c1cf18158ca0e154a3b1cab48853d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 28 Jul 2011 03:27:26 +0300 Subject: Extract shared logic from charserverhandler and loginhandler netcode to ea namespace. --- src/CMakeLists.txt | 6 +- src/Makefile.am | 6 +- src/net/ea/charserverhandler.cpp | 183 +++++++++++++++++++++++++ src/net/ea/charserverhandler.h | 89 ++++++++++++ src/net/ea/eaprotocol.h | 5 +- src/net/ea/loginhandler.cpp | 268 +++++++++++++++++++++++++++++++++++++ src/net/ea/loginhandler.h | 107 +++++++++++++++ src/net/ea/token.h | 44 ++++++ src/net/tmwa/charserverhandler.cpp | 197 ++++++--------------------- src/net/tmwa/charserverhandler.h | 29 ++-- src/net/tmwa/gamehandler.h | 3 +- src/net/tmwa/loginhandler.cpp | 256 +++++------------------------------ src/net/tmwa/loginhandler.h | 37 +---- src/net/tmwa/token.h | 44 ------ 14 files changed, 797 insertions(+), 477 deletions(-) create mode 100644 src/net/ea/charserverhandler.cpp create mode 100644 src/net/ea/charserverhandler.h create mode 100644 src/net/ea/loginhandler.cpp create mode 100644 src/net/ea/loginhandler.h create mode 100644 src/net/ea/token.h delete mode 100644 src/net/tmwa/token.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 62f8a88fb..0c476e4d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -682,7 +682,12 @@ SET(SRCS_EVOL net/ea/beinghandler.h net/ea/buysellhandler.cpp net/ea/buysellhandler.h + net/ea/charserverhandler.cpp + net/ea/charserverhandler.h + net/ea/loginhandler.cpp + net/ea/loginhandler.h net/ea/eaprotocol.h + net/ea/token.h ) SET(SRCS_TMWA @@ -729,7 +734,6 @@ SET(SRCS_TMWA net/tmwa/protocol.h net/tmwa/specialhandler.cpp net/tmwa/specialhandler.h - net/tmwa/token.h net/tmwa/tradehandler.cpp net/tmwa/tradehandler.h ) diff --git a/src/Makefile.am b/src/Makefile.am index 832251436..f410bde31 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -666,7 +666,12 @@ manaplus_SOURCES += \ net/ea/beinghandler.h \ net/ea/buysellhandler.cpp \ net/ea/buysellhandler.h \ + net/ea/charserverhandler.cpp \ + net/ea/charserverhandler.h \ + net/ea/loginhandler.cpp \ + net/ea/loginhandler.h \ net/ea/eaprotocol.h \ + net/ea/token.h \ net/tmwa/gui/guildtab.cpp \ net/tmwa/gui/guildtab.h \ net/tmwa/gui/partytab.cpp \ @@ -710,7 +715,6 @@ manaplus_SOURCES += \ net/tmwa/protocol.h \ net/tmwa/specialhandler.cpp \ net/tmwa/specialhandler.h \ - net/tmwa/token.h \ net/tmwa/tradehandler.cpp \ net/tmwa/tradehandler.h diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp new file mode 100644 index 000000000..e1fcfda66 --- /dev/null +++ b/src/net/ea/charserverhandler.cpp @@ -0,0 +1,183 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "net/ea/charserverhandler.h" + +#include "client.h" +#include "configuration.h" +#include "game.h" +#include "log.h" + +#include "gui/charcreatedialog.h" +#include "gui/okdialog.h" + +#include "net/logindata.h" +#include "net/messageout.h" +#include "net/net.h" + +#include "net/ea/loginhandler.h" +#include "net/ea/eaprotocol.h" + +#include "resources/colordb.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include "debug.h" + +extern Net::CharHandler *charHandler; + +namespace Ea +{ + +CharServerHandler::CharServerHandler() +{ +} + +void CharServerHandler::setCharSelectDialog(CharSelectDialog *window) +{ + mCharSelectDialog = window; + updateCharSelectDialog(); +} + +void CharServerHandler::setCharCreateDialog(CharCreateDialog *window) +{ + mCharCreateDialog = window; + + if (!mCharCreateDialog) + return; + + std::vector attributes; + attributes.push_back(_("Strength:")); + attributes.push_back(_("Agility:")); + attributes.push_back(_("Vitality:")); + attributes.push_back(_("Intelligence:")); + attributes.push_back(_("Dexterity:")); + attributes.push_back(_("Luck:")); + + const Token &token = + static_cast(Net::getLoginHandler())->getToken(); + + mCharCreateDialog->setAttributes(attributes, 30, 1, 9); + mCharCreateDialog->setFixedGender(true, token.sex); +} + +void CharServerHandler::requestCharacters() +{ + connect(); +} + +unsigned int CharServerHandler::baseSprite() const +{ + return EA_SPRITE_BASE; +} + +unsigned int CharServerHandler::hairSprite() const +{ + return EA_SPRITE_HAIR; +} + +unsigned int CharServerHandler::maxSprite() const +{ + return EA_SPRITE_VECTOREND; +} + +void CharServerHandler::processCharLoginError(Net::MessageIn &msg) +{ + switch (msg.readInt8()) + { + case 0: + errorMessage = _("Access denied. Most likely, there are " + "too many players on this server."); + break; + case 1: + errorMessage = _("Cannot use this ID."); + break; + default: + errorMessage = _("Unknown char-server failure."); + break; + } + Client::setState(STATE_ERROR); +} + +void CharServerHandler::processCharCreate(Net::MessageIn &msg, bool withColors) +{ + Net::Character *character = new Net::Character; + readPlayerData(msg, character, withColors); + mCharacters.push_back(character); + + updateCharSelectDialog(); + + // Close the character create dialog + if (mCharCreateDialog) + { + mCharCreateDialog->scheduleDelete(); + mCharCreateDialog = 0; + } +} + +void CharServerHandler::processCharCreateFailed(Net::MessageIn &msg) +{ + switch (msg.readInt8()) + { + case 1: + case 0: + default: + errorMessage = _("Failed to create character. Most " + "likely the name is already taken."); + break; + case 2: + errorMessage = _("Wrong name."); + break; + case 3: + errorMessage = _("Incorrect stats."); + break; + case 4: + errorMessage = _("Incorrect hair."); + break; + case 5: + errorMessage = _("Incorrect slot."); + break; + } + new OkDialog(_("Error"), errorMessage); + if (mCharCreateDialog) + mCharCreateDialog->unlock(); +} + +void CharServerHandler::processCharDelete(Net::MessageIn &msg A_UNUSED) +{ + delete mSelectedCharacter; + mCharacters.remove(mSelectedCharacter); + mSelectedCharacter = 0; + updateCharSelectDialog(); + unlockCharSelectDialog(); + new OkDialog(_("Info"), _("Character deleted.")); +} + +void CharServerHandler::processCharDeleteFailed(Net::MessageIn &msg A_UNUSED) +{ + unlockCharSelectDialog(); + new OkDialog(_("Error"), _("Failed to delete character.")); +} + +} // namespace Ea diff --git a/src/net/ea/charserverhandler.h b/src/net/ea/charserverhandler.h new file mode 100644 index 000000000..bd39781cd --- /dev/null +++ b/src/net/ea/charserverhandler.h @@ -0,0 +1,89 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NET_EA_CHARSERVERHANDLER_H +#define NET_EA_CHARSERVERHANDLER_H + +#include "net/charhandler.h" +#include "net/messagein.h" +#include "net/net.h" +#include "net/serverinfo.h" + +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + +class LoginData; + +namespace Ea +{ + +/** + * Deals with incoming messages from the character server. + */ +class CharServerHandler : public Net::CharHandler +{ + public: + CharServerHandler(); + + virtual void setCharSelectDialog(CharSelectDialog *window); + + /** + * Sets the character create dialog. The handler will clean up this + * dialog when a new character is succesfully created, and will unlock + * the dialog when a new character failed to be created. + */ + virtual void setCharCreateDialog(CharCreateDialog *window); + + virtual void requestCharacters(); + + virtual unsigned int baseSprite() const; + + virtual unsigned int hairSprite() const; + + virtual unsigned int maxSprite() const; + + virtual void connect() = 0; + + virtual void processCharLogin(Net::MessageIn &msg) = 0; + + virtual void processCharLoginError(Net::MessageIn &msg); + + virtual void processCharCreate(Net::MessageIn &msg, bool withColors); + + virtual void processCharCreateFailed(Net::MessageIn &msg); + + virtual void processCharDelete(Net::MessageIn &msg); + + virtual void processCharDeleteFailed(Net::MessageIn &msg); + + protected: + virtual void readPlayerData(Net::MessageIn &msg, + Net::Character *character, + bool withColors) = 0; +}; + +} // namespace Ea + +#endif // NET_EA_CHARSERVERHANDLER_H diff --git a/src/net/ea/eaprotocol.h b/src/net/ea/eaprotocol.h index d72ca3515..11cc0180d 100644 --- a/src/net/ea/eaprotocol.h +++ b/src/net/ea/eaprotocol.h @@ -36,7 +36,10 @@ enum EA_SPRITE_CAPE, EA_SPRITE_GLOVES, EA_SPRITE_WEAPON, - EA_SPRITE_SHIELD + EA_SPRITE_SHIELD, + EA_SPRITE_EVOL1, + EA_SPRITE_EVOL2, + EA_SPRITE_VECTOREND }; #endif diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp new file mode 100644 index 000000000..f6d8e5cf7 --- /dev/null +++ b/src/net/ea/loginhandler.cpp @@ -0,0 +1,268 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "net/ea/loginhandler.h" + +#include "client.h" +#include "log.h" +#include "configuration.h" + +#include "net/logindata.h" +#include "net/messageout.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include "debug.h" + +namespace Ea +{ + +LoginHandler::LoginHandler(): + mVersionResponse(false), + mRegistrationEnabled(true) +{ +} + +LoginHandler::~LoginHandler() +{ + delete_all(mWorlds); +} + +bool LoginHandler::isRegistrationEnabled() +{ + return mRegistrationEnabled; +} + +void LoginHandler::getRegistrationDetails() +{ + // Not supported, so move on + Client::setState(STATE_REGISTER); +} + +void LoginHandler::loginAccount(LoginData *loginData) +{ + + if (loginData) + { + // Since we're attempting to use the tAthena protocol, + // let's reset the character slots to the good value, + // in case we just logged out a Manaserv server + // with a different config. + loginData->resetCharacterSlots(); + + sendLoginRegister(loginData->username, loginData->password); + } +} + +void LoginHandler::chooseServer(unsigned int server) +{ + if (server >= mWorlds.size() || !mWorlds[server]) + return; + + ServerInfo *charServer = getCharServer(); + if (charServer) + { + if (config.getBoolValue("usePersistentIP")) + charServer->hostname = Client::getServerName(); + else + charServer->hostname = ipToString(mWorlds[server]->address); + charServer->port = mWorlds[server]->port; + } + + Client::setState(STATE_UPDATE); +} + +void LoginHandler::registerAccount(LoginData *loginData) +{ + if (!loginData) + return; + + std::string username = loginData->username; + username.append((loginData->gender == GENDER_FEMALE) ? "_F" : "_M"); + + sendLoginRegister(username, loginData->password); +} + +Worlds LoginHandler::getWorlds() const +{ + return mWorlds; +} + +void LoginHandler::clearWorlds() +{ + delete_all(mWorlds); + mWorlds.clear(); +} + +void LoginHandler::procecessCharPasswordResponse(Net::MessageIn &msg) +{ + // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short + int errMsg = msg.readInt8(); + // Successful pass change + if (errMsg == 1) + { + Client::setState(STATE_CHANGEPASSWORD_SUCCESS); + } + // pass change failed + else + { + switch (errMsg) + { + case 0: + errorMessage = + _("Account was not found. Please re-login."); + break; + case 2: + errorMessage = _("Old password incorrect."); + break; + case 3: + errorMessage = _("New password too short."); + break; + default: + errorMessage = _("Unknown error."); + break; + } + Client::setState(STATE_ACCOUNTCHANGE_ERROR); + } +} + +void LoginHandler::processUpdateHost(Net::MessageIn &msg) +{ + int len; + + len = msg.readInt16() - 4; + mUpdateHost = msg.readString(len); + loginData.updateHost = mUpdateHost; + + logger->log("Received update host \"%s\" from login server.", + mUpdateHost.c_str()); +} + +void LoginHandler::processLoginData(Net::MessageIn &msg) +{ + // Skip the length word + msg.skip(2); + + clearWorlds(); + + int worldCount = (msg.getLength() - 47) / 32; + + mToken.session_ID1 = msg.readInt32(); + mToken.account_ID = msg.readInt32(); + mToken.session_ID2 = msg.readInt32(); + msg.skip(30); // unknown + // reserve bits for future usage + mToken.sex = (msg.readInt8() & 1) ? GENDER_MALE : GENDER_FEMALE; + + for (int i = 0; i < worldCount; i++) + { + WorldInfo *world = new WorldInfo; + + world->address = msg.readInt32(); + world->port = msg.readInt16(); + world->name = msg.readString(20); + world->online_users = msg.readInt32(); + config.setValue("updatehost", mUpdateHost); + world->updateHost = mUpdateHost; + msg.skip(2); // unknown + + logger->log("Network: Server: %s (%s:%d)", + world->name.c_str(), + ipToString(world->address), + world->port); + + mWorlds.push_back(world); + } + Client::setState(STATE_WORLD_SELECT); +} + +void LoginHandler::processLoginError(Net::MessageIn &msg) +{ + int code = msg.readInt8(); + logger->log("Login::error code: %i", code); + + switch (code) + { + case 0: + errorMessage = _("Unregistered ID."); + break; + case 1: + errorMessage = _("Wrong password."); + break; + case 2: + errorMessage = _("Account expired."); + break; + case 3: + errorMessage = _("Rejected from server."); + break; + case 4: + errorMessage = _("You have been permanently banned from " + "the game. Please contact the GM team."); + break; + case 5: + errorMessage = _("Client too old."); + break; + case 6: + errorMessage = strprintf(_("You have been temporarily " + "banned from the game until " + "%s.\nPlease contact the GM " + "team via the forums."), + msg.readString(20).c_str()); + break; + case 7: + errorMessage = _("Server overpopulated."); + break; + case 9: + errorMessage = _("This user name is already taken."); + break; + case 10: + errorMessage = _("Wrong name."); + break; + case 99: + errorMessage = _("Username permanently erased."); + break; + default: + errorMessage = _("Unknown error."); + break; + } + Client::setState(STATE_ERROR); +} + +void LoginHandler::logout() +{ + // TODO +} + +void LoginHandler::changeEmail(const std::string &email A_UNUSED) +{ + // TODO +} + +void LoginHandler::unregisterAccount(const std::string &username A_UNUSED, + const std::string &password A_UNUSED) +{ + // TODO +} + +} // namespace Ea diff --git a/src/net/ea/loginhandler.h b/src/net/ea/loginhandler.h new file mode 100644 index 000000000..3b035b530 --- /dev/null +++ b/src/net/ea/loginhandler.h @@ -0,0 +1,107 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NET_EA_LOGINHANDLER_H +#define NET_EA_LOGINHANDLER_H + +#include "net/loginhandler.h" +#include "net/net.h" +#include "net/messagein.h" + +#include "net/ea/token.h" + +#include + +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + +class LoginData; + +namespace Ea +{ + +class LoginHandler : public Net::LoginHandler +{ + public: + LoginHandler(); + + ~LoginHandler(); + + int supportedOptionalActions() const + { return SetGenderOnRegister; } + + virtual bool isRegistrationEnabled(); + + virtual void getRegistrationDetails(); + + virtual unsigned int getMaxPasswordLength() const + { return 25; } + + virtual void loginAccount(LoginData *loginData); + + virtual void chooseServer(unsigned int server); + + virtual void registerAccount(LoginData *loginData); + + virtual Worlds getWorlds() const; + + virtual void clearWorlds(); + + virtual ServerInfo *getCharServer() = 0; + + const Token &getToken() const + { return mToken; } + + virtual void logout(); + + virtual void changeEmail(const std::string &email); + + virtual void unregisterAccount(const std::string &username, + const std::string &password); + + virtual void procecessCharPasswordResponse(Net::MessageIn &msg); + + virtual void processUpdateHost(Net::MessageIn &msg); + + virtual void processLoginData(Net::MessageIn &msg); + + virtual void processLoginError(Net::MessageIn &msg); + + virtual void processServerVersion(Net::MessageIn &msg) = 0; + + protected: + virtual void sendLoginRegister(const std::string &username, + const std::string &password) = 0; + + bool mVersionResponse; + bool mRegistrationEnabled; + std::string mUpdateHost; + Worlds mWorlds; + Token mToken; +}; + +} // namespace TmwAthena + +#endif // NET_TA_LOGINHANDLER_H diff --git a/src/net/ea/token.h b/src/net/ea/token.h new file mode 100644 index 000000000..40a7058ff --- /dev/null +++ b/src/net/ea/token.h @@ -0,0 +1,44 @@ +/* + * The ManaPlus Client + * Copyright (C) 2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "being.h" + +#ifndef NET_EA_TOKEN_H +#define NET_EA_TOKEN_H + +struct Token +{ + int account_ID; + int session_ID1; + int session_ID2; + Gender sex; + + void clear() + { + account_ID = 0; + session_ID1 = 0; + session_ID2 = 0; + sex = GENDER_UNSPECIFIED; + } +}; + +#endif // NET_EA_TOKEN_H diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 0a28a9a8c..57f65cbd4 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -79,131 +79,32 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) { switch (msg.getId()) { - case SMSG_CHAR_LOGIN: - { - msg.skip(2); // Length word - int slots = msg.readInt16(); - if (slots > 0 && slots < 30) - { - loginData.characterSlots - = static_cast(slots); - } - bool version = msg.readInt8() == 1 && serverVersion > 0; - msg.skip(17); // Unused - - delete_all(mCharacters); - mCharacters.clear(); - - // Derive number of characters from message length - int count = (msg.getLength() - 24); - if (version) - count /= 120; - else - count /= 106; - - for (int i = 0; i < count; ++i) - { - Net::Character *character = new Net::Character; - readPlayerData(msg, character, version); - mCharacters.push_back(character); - logger->log("CharServer: Player: %s (%d)", - character->dummy->getName().c_str(), character->slot); - } - - Client::setState(STATE_CHAR_SELECT); - } + case SMSG_CHAR_LOGIN: + processCharLogin(msg); break; case SMSG_CHAR_LOGIN_ERROR: - switch (msg.readInt8()) - { - case 0: - errorMessage = _("Access denied. Most likely, there are " - "too many players on this server."); - break; - case 1: - errorMessage = _("Cannot use this ID."); - break; - default: - errorMessage = _("Unknown char-server failure."); - break; - } - Client::setState(STATE_ERROR); + processCharLoginError(msg); break; case SMSG_CHAR_CREATE_SUCCEEDED: - { - Net::Character *character = new Net::Character; - readPlayerData(msg, character, false); - mCharacters.push_back(character); - - updateCharSelectDialog(); - - // Close the character create dialog - if (mCharCreateDialog) - { - mCharCreateDialog->scheduleDelete(); - mCharCreateDialog = 0; - } - } + processCharCreate(msg, false); break; case SMSG_CHAR_CREATE_SUCCEEDED2: - { - Net::Character *character = new Net::Character; - readPlayerData(msg, character, true); - mCharacters.push_back(character); - - updateCharSelectDialog(); - - // Close the character create dialog - if (mCharCreateDialog) - { - mCharCreateDialog->scheduleDelete(); - mCharCreateDialog = 0; - } - } + processCharCreate(msg, true); break; case SMSG_CHAR_CREATE_FAILED: - switch (msg.readInt8()) - { - case 1: - case 0: - default: - errorMessage = _("Failed to create character. Most " - "likely the name is already taken."); - break; - case 2: - errorMessage = _("Wrong name."); - break; - case 3: - errorMessage = _("Incorrect stats."); - break; - case 4: - errorMessage = _("Incorrect hair."); - break; - case 5: - errorMessage = _("Incorrect slot."); - break; - } - new OkDialog(_("Error"), errorMessage); - if (mCharCreateDialog) - mCharCreateDialog->unlock(); + processCharCreateFailed(msg); break; case SMSG_CHAR_DELETE_SUCCEEDED: - delete mSelectedCharacter; - mCharacters.remove(mSelectedCharacter); - mSelectedCharacter = 0; - updateCharSelectDialog(); - unlockCharSelectDialog(); - new OkDialog(_("Info"), _("Character deleted.")); + processCharDelete(msg); break; case SMSG_CHAR_DELETE_FAILED: - unlockCharSelectDialog(); - new OkDialog(_("Error"), _("Failed to delete character.")); + processCharDeleteFailed(msg); break; case SMSG_CHAR_MAP_INFO: @@ -366,39 +267,6 @@ void CharServerHandler::readPlayerData(Net::MessageIn &msg, msg.readInt8(); // unknown } -void CharServerHandler::setCharSelectDialog(CharSelectDialog *window) -{ - mCharSelectDialog = window; - updateCharSelectDialog(); -} - -void CharServerHandler::setCharCreateDialog(CharCreateDialog *window) -{ - mCharCreateDialog = window; - - if (!mCharCreateDialog) - return; - - std::vector attributes; - attributes.push_back(_("Strength:")); - attributes.push_back(_("Agility:")); - attributes.push_back(_("Vitality:")); - attributes.push_back(_("Intelligence:")); - attributes.push_back(_("Dexterity:")); - attributes.push_back(_("Luck:")); - - const Token &token = - static_cast(Net::getLoginHandler())->getToken(); - - mCharCreateDialog->setAttributes(attributes, 30, 1, 9); - mCharCreateDialog->setFixedGender(true, token.sex); -} - -void CharServerHandler::requestCharacters() -{ - connect(); -} - void CharServerHandler::chooseCharacter(Net::Character *character) { mSelectedCharacter = character; @@ -444,21 +312,6 @@ void CharServerHandler::switchCharacter() outMsg.writeInt8(1); } -unsigned int CharServerHandler::baseSprite() const -{ - return SPRITE_BASE; -} - -unsigned int CharServerHandler::hairSprite() const -{ - return SPRITE_HAIR; -} - -unsigned int CharServerHandler::maxSprite() const -{ - return SPRITE_VECTOREND; -} - void CharServerHandler::connect() { const Token &token = @@ -485,4 +338,38 @@ void CharServerHandler::connect() mNetwork->skip(4); } +void CharServerHandler::processCharLogin(Net::MessageIn &msg) +{ + msg.skip(2); // Length word + int slots = msg.readInt16(); + if (slots > 0 && slots < 30) + { + loginData.characterSlots + = static_cast(slots); + } + bool version = msg.readInt8() == 1 && serverVersion > 0; + msg.skip(17); // Unused + + delete_all(mCharacters); + mCharacters.clear(); + + // Derive number of characters from message length + int count = (msg.getLength() - 24); + if (version) + count /= 120; + else + count /= 106; + + for (int i = 0; i < count; ++i) + { + Net::Character *character = new Net::Character; + readPlayerData(msg, character, version); + mCharacters.push_back(character); + logger->log("CharServer: Player: %s (%d)", + character->dummy->getName().c_str(), character->slot); + } + + Client::setState(STATE_CHAR_SELECT); +} + } // namespace TmwAthena diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h index 62ff2b4de..4bd3153e8 100644 --- a/src/net/tmwa/charserverhandler.h +++ b/src/net/tmwa/charserverhandler.h @@ -24,10 +24,14 @@ #define NET_TA_CHARSERVERHANDLER_H #include "net/charhandler.h" + +#include "net/ea/charserverhandler.h" + #include "net/serverinfo.h" #include "net/tmwa/messagehandler.h" -#include "net/tmwa/token.h" + +#include "net/ea/token.h" #ifdef __GNUC__ #define A_UNUSED __attribute__ ((unused)) @@ -43,24 +47,13 @@ namespace TmwAthena /** * Deals with incoming messages from the character server. */ -class CharServerHandler : public MessageHandler, public Net::CharHandler +class CharServerHandler : public MessageHandler, public Ea::CharServerHandler { public: CharServerHandler(); virtual void handleMessage(Net::MessageIn &msg); - void setCharSelectDialog(CharSelectDialog *window); - - /** - * Sets the character create dialog. The handler will clean up this - * dialog when a new character is succesfully created, and will unlock - * the dialog when a new character failed to be created. - */ - void setCharCreateDialog(CharCreateDialog *window); - - void requestCharacters(); - void chooseCharacter(Net::Character *character); void newCharacter(const std::string &name, int slot, @@ -72,15 +65,11 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler void switchCharacter(); - unsigned int baseSprite() const; - - unsigned int hairSprite() const; - - unsigned int maxSprite() const; - void connect(); - private: + void processCharLogin(Net::MessageIn &msg); + + protected: void readPlayerData(Net::MessageIn &msg, Net::Character *character, bool withColors); }; diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h index d6004054c..4abfd43c0 100644 --- a/src/net/tmwa/gamehandler.h +++ b/src/net/tmwa/gamehandler.h @@ -30,7 +30,8 @@ #include "net/serverinfo.h" #include "net/tmwa/messagehandler.h" -#include "net/tmwa/token.h" + +#include "net/ea/token.h" #ifdef __GNUC__ #define A_UNUSED __attribute__ ((unused)) diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 0cc1670bb..62d8833ec 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -46,9 +46,7 @@ namespace TmwAthena extern ServerInfo charServer; -LoginHandler::LoginHandler(): - mVersionResponse(false), - mRegistrationEnabled(true) +LoginHandler::LoginHandler() { static const Uint16 _messages[] = { @@ -65,172 +63,30 @@ LoginHandler::LoginHandler(): LoginHandler::~LoginHandler() { - delete_all(mWorlds); } void LoginHandler::handleMessage(Net::MessageIn &msg) { - int code, worldCount; - switch (msg.getId()) { case SMSG_CHAR_PASSWORD_RESPONSE: - { - // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short - int errMsg = msg.readInt8(); - // Successful pass change - if (errMsg == 1) - { - Client::setState(STATE_CHANGEPASSWORD_SUCCESS); - } - // pass change failed - else - { - switch (errMsg) - { - case 0: - errorMessage = - _("Account was not found. Please re-login."); - break; - case 2: - errorMessage = _("Old password incorrect."); - break; - case 3: - errorMessage = _("New password too short."); - break; - default: - errorMessage = _("Unknown error."); - break; - } - Client::setState(STATE_ACCOUNTCHANGE_ERROR); - } - } + procecessCharPasswordResponse(msg); break; case SMSG_UPDATE_HOST: - int len; - - len = msg.readInt16() - 4; - mUpdateHost = msg.readString(len); - loginData.updateHost = mUpdateHost; - - logger->log("Received update host \"%s\" from login server.", - mUpdateHost.c_str()); - break; + processUpdateHost(msg); + break; case SMSG_LOGIN_DATA: - // Skip the length word - msg.skip(2); - - clearWorlds(); - - worldCount = (msg.getLength() - 47) / 32; - - mToken.session_ID1 = msg.readInt32(); - mToken.account_ID = msg.readInt32(); - mToken.session_ID2 = msg.readInt32(); - msg.skip(30); // unknown - // reserve bits for future usage - mToken.sex = (msg.readInt8() & 1) ? GENDER_MALE : GENDER_FEMALE; - - for (int i = 0; i < worldCount; i++) - { - WorldInfo *world = new WorldInfo; - - world->address = msg.readInt32(); - world->port = msg.readInt16(); - world->name = msg.readString(20); - world->online_users = msg.readInt32(); - config.setValue("updatehost", mUpdateHost); - world->updateHost = mUpdateHost; - msg.skip(2); // unknown - - logger->log("Network: Server: %s (%s:%d)", - world->name.c_str(), - ipToString(world->address), - world->port); - - mWorlds.push_back(world); - } - Client::setState(STATE_WORLD_SELECT); + processLoginData(msg); break; case SMSG_LOGIN_ERROR: - code = msg.readInt8(); - logger->log("Login::error code: %i", code); - - switch (code) - { - case 0: - errorMessage = _("Unregistered ID."); - break; - case 1: - errorMessage = _("Wrong password."); - break; - case 2: - errorMessage = _("Account expired."); - break; - case 3: - errorMessage = _("Rejected from server."); - break; - case 4: - errorMessage = _("You have been permanently banned from " - "the game. Please contact the GM team."); - break; - case 5: - errorMessage = _("Client too old."); - break; - case 6: - errorMessage = strprintf(_("You have been temporarily " - "banned from the game until " - "%s.\nPlease contact the GM " - "team via the forums."), - msg.readString(20).c_str()); - break; - case 7: - errorMessage = _("Server overpopulated."); - break; - case 9: - errorMessage = _("This user name is already taken."); - break; - case 10: - errorMessage = _("Wrong name."); - break; - case 99: - errorMessage = _("Username permanently erased."); - break; - default: - errorMessage = _("Unknown error."); - break; - } - Client::setState(STATE_ERROR); + processLoginError(msg); break; case SMSG_SERVER_VERSION_RESPONSE: - { - // TODO: verify these! - - char b1 = msg.readInt8(); // -1 - char b2 = msg.readInt8(); // T - char b3 = msg.readInt8(); // M - char b4 = msg.readInt8(); // W - if (b1 == -1 && b2 == 'E' && b3 == 'V' && b4 == 'L') - { - unsigned int options = msg.readInt8(); - mRegistrationEnabled = options; - msg.skip(2); - serverVersion = msg.readInt8(); - } - else - { - unsigned int options = msg.readInt32(); - mRegistrationEnabled = options; - serverVersion = 0; - } - - // Leave this last - mVersionResponse = true; - } + processServerVersion(msg); break; default: @@ -261,42 +117,6 @@ void LoginHandler::disconnect() mNetwork->disconnect(); } -bool LoginHandler::isRegistrationEnabled() -{ - return mRegistrationEnabled; -} - -void LoginHandler::getRegistrationDetails() -{ - // Not supported, so move on - Client::setState(STATE_REGISTER); -} - -void LoginHandler::loginAccount(LoginData *loginData) -{ - - if (loginData) - { - // Since we're attempting to use the tAthena protocol, - // let's reset the character slots to the good value, - // in case we just logged out a Manaserv server - // with a different config. - loginData->resetCharacterSlots(); - - sendLoginRegister(loginData->username, loginData->password); - } -} - -void LoginHandler::logout() -{ - // TODO -} - -void LoginHandler::changeEmail(const std::string &email A_UNUSED) -{ - // TODO -} - void LoginHandler::changePassword(const std::string &username A_UNUSED, const std::string &oldPassword, const std::string &newPassword) @@ -306,38 +126,6 @@ void LoginHandler::changePassword(const std::string &username A_UNUSED, outMsg.writeString(newPassword, 24); } -void LoginHandler::chooseServer(unsigned int server) -{ - if (server >= mWorlds.size() || !mWorlds[server]) - return; - - charServer.clear(); - if (config.getBoolValue("usePersistentIP")) - charServer.hostname = Client::getServerName(); - else - charServer.hostname = ipToString(mWorlds[server]->address); - charServer.port = mWorlds[server]->port; - - Client::setState(STATE_UPDATE); -} - -void LoginHandler::registerAccount(LoginData *loginData) -{ - if (!loginData) - return; - - std::string username = loginData->username; - username.append((loginData->gender == GENDER_FEMALE) ? "_F" : "_M"); - - sendLoginRegister(username, loginData->password); -} - -void LoginHandler::unregisterAccount(const std::string &username A_UNUSED, - const std::string &password A_UNUSED) -{ - // TODO -} - void LoginHandler::sendLoginRegister(const std::string &username, const std::string &password) { @@ -355,15 +143,35 @@ void LoginHandler::sendLoginRegister(const std::string &username, outMsg.writeInt8(0x03); } -Worlds LoginHandler::getWorlds() const +ServerInfo *LoginHandler::getCharServer() { - return mWorlds; + return &charServer; } -void LoginHandler::clearWorlds() +void LoginHandler::processServerVersion(Net::MessageIn &msg) { - delete_all(mWorlds); - mWorlds.clear(); + // TODO: verify these! + + char b1 = msg.readInt8(); // -1 + char b2 = msg.readInt8(); // T + char b3 = msg.readInt8(); // M + char b4 = msg.readInt8(); // W + if (b1 == -1 && b2 == 'E' && b3 == 'V' && b4 == 'L') + { + unsigned int options = msg.readInt8(); + mRegistrationEnabled = options; + msg.skip(2); + serverVersion = msg.readInt8(); + } + else + { + unsigned int options = msg.readInt32(); + mRegistrationEnabled = options; + serverVersion = 0; + } + + // Leave this last + mVersionResponse = true; } } // namespace TmwAthena diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h index 8c6b48cc2..1e73d3c99 100644 --- a/src/net/tmwa/loginhandler.h +++ b/src/net/tmwa/loginhandler.h @@ -25,8 +25,11 @@ #include "net/loginhandler.h" +#include "net/ea/loginhandler.h" + #include "net/tmwa/messagehandler.h" -#include "net/tmwa/token.h" + +#include "net/ea/token.h" #include @@ -41,7 +44,7 @@ class LoginData; namespace TmwAthena { -class LoginHandler : public MessageHandler, public Net::LoginHandler +class LoginHandler : public MessageHandler, public Ea::LoginHandler { public: LoginHandler(); @@ -59,46 +62,20 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler int supportedOptionalActions() const { return SetGenderOnRegister; } - bool isRegistrationEnabled(); - - void getRegistrationDetails(); - unsigned int getMaxPasswordLength() const { return 25; } - void loginAccount(LoginData *loginData); - - void logout(); - - void changeEmail(const std::string &email); - void changePassword(const std::string &username, const std::string &oldPassword, const std::string &newPassword); - void chooseServer(unsigned int server); + ServerInfo *getCharServer(); - void registerAccount(LoginData *loginData); - - void unregisterAccount(const std::string &username, - const std::string &password); - - Worlds getWorlds() const; - - void clearWorlds(); - - const Token &getToken() const - { return mToken; } + void processServerVersion(Net::MessageIn &msg); private: void sendLoginRegister(const std::string &username, const std::string &password); - - bool mVersionResponse; - bool mRegistrationEnabled; - std::string mUpdateHost; - Worlds mWorlds; - Token mToken; }; } // namespace TmwAthena diff --git a/src/net/tmwa/token.h b/src/net/tmwa/token.h deleted file mode 100644 index ba39bb796..000000000 --- a/src/net/tmwa/token.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "being.h" - -#ifndef NET_TA_TOKEN_H -#define NET_TA_TOKEN_H - -struct Token -{ - int account_ID; - int session_ID1; - int session_ID2; - Gender sex; - - void clear() - { - account_ID = 0; - session_ID1 = 0; - session_ID2 = 0; - sex = GENDER_UNSPECIFIED; - } -}; - -#endif // NET_TA_TOKEN_H -- cgit v1.2.3-60-g2f50