From 86ea4ef67a3a4ee16ad41bdd2a5e8a0a19635068 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 25 Aug 2015 17:00:29 +0300 Subject: Move receive code from charserverhandler into separate file. --- src/CMakeLists.txt | 6 + src/Makefile.am | 6 + src/net/charserverhandler.h | 21 +- src/net/ea/charserverhandler.cpp | 99 ------- src/net/ea/charserverhandler.h | 11 - src/net/ea/charserverrecv.cpp | 145 ++++++++++ src/net/ea/charserverrecv.h | 43 +++ src/net/eathena/charserverhandler.cpp | 499 ++------------------------------ src/net/eathena/charserverhandler.h | 47 +--- src/net/eathena/charserverrecv.cpp | 515 ++++++++++++++++++++++++++++++++++ src/net/eathena/charserverrecv.h | 61 ++++ src/net/eathena/network.h | 4 +- src/net/tmwa/charserverhandler.cpp | 247 +--------------- src/net/tmwa/charserverhandler.h | 15 - src/net/tmwa/charserverrecv.cpp | 292 +++++++++++++++++++ src/net/tmwa/charserverrecv.h | 44 +++ src/net/tmwa/network.h | 4 +- 17 files changed, 1168 insertions(+), 891 deletions(-) create mode 100644 src/net/ea/charserverrecv.cpp create mode 100644 src/net/ea/charserverrecv.h create mode 100644 src/net/eathena/charserverrecv.cpp create mode 100644 src/net/eathena/charserverrecv.h create mode 100644 src/net/tmwa/charserverrecv.cpp create mode 100644 src/net/tmwa/charserverrecv.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ebbaf146..85aca5225 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1353,6 +1353,8 @@ SET(SRCS_EVOL net/ea/buysellrecv.h net/ea/charserverhandler.cpp net/ea/charserverhandler.h + net/ea/charserverrecv.cpp + net/ea/charserverrecv.h net/ea/chathandler.cpp net/ea/chathandler.h net/ea/eaprotocol.h @@ -1399,6 +1401,8 @@ SET(SRCS_TMWA net/tmwa/buysellrecv.h net/tmwa/charserverhandler.cpp net/tmwa/charserverhandler.h + net/tmwa/charserverrecv.cpp + net/tmwa/charserverrecv.h net/tmwa/chathandler.cpp net/tmwa/chathandler.h net/tmwa/gamehandler.cpp @@ -1557,6 +1561,8 @@ SET(SRCS_EATHENA net/eathena/buysellrecv.h net/eathena/charserverhandler.cpp net/eathena/charserverhandler.h + net/eathena/charserverrecv.cpp + net/eathena/charserverrecv.h net/eathena/chathandler.cpp net/eathena/chathandler.h net/eathena/elementalhandler.cpp diff --git a/src/Makefile.am b/src/Makefile.am index fdf9611da..b206fa8f8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1195,6 +1195,8 @@ manaplus_SOURCES += main.cpp \ net/ea/buysellrecv.h \ net/ea/charserverhandler.cpp \ net/ea/charserverhandler.h \ + net/ea/charserverrecv.cpp \ + net/ea/charserverrecv.h \ net/ea/chathandler.cpp \ net/ea/chathandler.h \ net/ea/eaprotocol.h \ @@ -1242,6 +1244,8 @@ manaplus_SOURCES += \ net/tmwa/buysellrecv.h \ net/tmwa/charserverhandler.cpp \ net/tmwa/charserverhandler.h \ + net/tmwa/charserverrecv.cpp \ + net/tmwa/charserverrecv.h \ net/tmwa/chathandler.cpp \ net/tmwa/chathandler.h \ net/tmwa/gamehandler.cpp \ @@ -1403,6 +1407,8 @@ manaplus_SOURCES += gui/windows/bankwindow.cpp \ net/eathena/buysellrecv.h \ net/eathena/charserverhandler.cpp \ net/eathena/charserverhandler.h \ + net/eathena/charserverrecv.cpp \ + net/eathena/charserverrecv.h \ net/eathena/chathandler.cpp \ net/eathena/chathandler.h \ net/eathena/elementalhandler.cpp \ diff --git a/src/net/charserverhandler.h b/src/net/charserverhandler.h index 2495cf6c1..d663db093 100644 --- a/src/net/charserverhandler.h +++ b/src/net/charserverhandler.h @@ -86,14 +86,20 @@ class CharServerHandler notfinal virtual void changeSlot(const int oldSlot, const int newSlot) = 0; - virtual void readPlayerData(Net::MessageIn &msg, - Net::Character *const character) const = 0; - virtual void ping() const = 0; /** The list of available characters. */ static Net::Characters mCharacters; + static CharSelectDialog *mCharSelectDialog; + static CharCreateDialog *mCharCreateDialog; + + /** The selected character. */ + static Net::Character *mSelectedCharacter; + + static void updateCharSelectDialog(); + static void unlockCharSelectDialog(); + protected: CharServerHandler() { @@ -102,15 +108,6 @@ class CharServerHandler notfinal mCharSelectDialog = nullptr; mCharCreateDialog = nullptr; } - - static void updateCharSelectDialog(); - static void unlockCharSelectDialog(); - - /** The selected character. */ - static Net::Character *mSelectedCharacter; - - static CharSelectDialog *mCharSelectDialog; - static CharCreateDialog *mCharCreateDialog; }; } // namespace Net diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index eafdaff34..e46562085 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -77,105 +77,6 @@ unsigned int CharServerHandler::maxSprite() const return EA_SPRITE_VECTOREND; } -void CharServerHandler::processCharLoginError(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharLoginError") - switch (msg.readUInt8("error")) - { - case 0: - // TRANSLATORS: error message - errorMessage = _("Access denied. Most likely, there are " - "too many players on this server."); - break; - case 1: - // TRANSLATORS: error message - errorMessage = _("Cannot use this ID."); - break; - default: - // TRANSLATORS: error message - errorMessage = _("Unknown char-server failure."); - break; - } - client->setState(STATE_ERROR); - BLOCK_END("CharServerHandler::processCharLoginError") -} - -void CharServerHandler::processCharCreateFailed(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharCreateFailed") - switch (msg.readUInt8("error")) - { - case 1: - case 0: - default: - // TRANSLATORS: error message - errorMessage = _("Failed to create character. Most " - "likely the name is already taken."); - break; - case 2: - // TRANSLATORS: error message - errorMessage = _("Wrong name."); - break; - case 3: - // TRANSLATORS: error message - errorMessage = _("Incorrect stats."); - break; - case 4: - // TRANSLATORS: error message - errorMessage = _("Incorrect hair."); - break; - case 5: - // TRANSLATORS: error message - errorMessage = _("Incorrect slot."); - break; - case 6: - // TRANSLATORS: error message - errorMessage = _("Incorrect race."); - break; - case 7: - // TRANSLATORS: error message - errorMessage = _("Incorrect look."); - break; - } - CREATEWIDGET(OkDialog, - // TRANSLATORS: error message header - _("Error"), - errorMessage, - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::ERROR, - Modal_true, - ShowCenter_true, - nullptr, - 260); - if (mCharCreateDialog) - mCharCreateDialog->unlock(); - BLOCK_END("CharServerHandler::processCharCreateFailed") -} - -void CharServerHandler::processCharDelete(Net::MessageIn &msg A_UNUSED) -{ - BLOCK_START("CharServerHandler::processCharDelete") - delete mSelectedCharacter; - mCharacters.remove(mSelectedCharacter); - mSelectedCharacter = nullptr; - updateCharSelectDialog(); - unlockCharSelectDialog(); - CREATEWIDGET(OkDialog, - // TRANSLATORS: info message header - _("Info"), - // TRANSLATORS: info message - _("Character deleted."), - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::OK, - Modal_true, - ShowCenter_true, - nullptr, - 260); - BLOCK_END("CharServerHandler::processCharDelete") -} - void CharServerHandler::clear() { delete_all(mCharacters); diff --git a/src/net/ea/charserverhandler.h b/src/net/ea/charserverhandler.h index 99fb84c35..72a7baff8 100644 --- a/src/net/ea/charserverhandler.h +++ b/src/net/ea/charserverhandler.h @@ -25,11 +25,6 @@ #include "net/charserverhandler.h" -namespace Net -{ - class MessageIn; -} - namespace Ea { @@ -54,12 +49,6 @@ class CharServerHandler notfinal : public Net::CharServerHandler virtual void connect() = 0; - static void processCharLoginError(Net::MessageIn &msg); - - static void processCharCreateFailed(Net::MessageIn &msg); - - static void processCharDelete(Net::MessageIn &msg); - void clear() override final; protected: diff --git a/src/net/ea/charserverrecv.cpp b/src/net/ea/charserverrecv.cpp new file mode 100644 index 000000000..8435f0caf --- /dev/null +++ b/src/net/ea/charserverrecv.cpp @@ -0,0 +1,145 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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/charserverrecv.h" + +#include "client.h" + +#include "gui/windows/charcreatedialog.h" +#include "gui/windows/okdialog.h" + +#include "gui/widgets/createwidget.h" + +#include "net/ea/eaprotocol.h" + +#include "net/character.h" +#include "net/messagein.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" + +#include "debug.h" + +namespace Ea +{ + +void CharServerRecv::processCharLoginError(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharLoginError") + switch (msg.readUInt8("error")) + { + case 0: + // TRANSLATORS: error message + errorMessage = _("Access denied. Most likely, there are " + "too many players on this server."); + break; + case 1: + // TRANSLATORS: error message + errorMessage = _("Cannot use this ID."); + break; + default: + // TRANSLATORS: error message + errorMessage = _("Unknown char-server failure."); + break; + } + client->setState(STATE_ERROR); + BLOCK_END("CharServerRecv::processCharLoginError") +} + +void CharServerRecv::processCharCreateFailed(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharCreateFailed") + switch (msg.readUInt8("error")) + { + case 1: + case 0: + default: + // TRANSLATORS: error message + errorMessage = _("Failed to create character. Most " + "likely the name is already taken."); + break; + case 2: + // TRANSLATORS: error message + errorMessage = _("Wrong name."); + break; + case 3: + // TRANSLATORS: error message + errorMessage = _("Incorrect stats."); + break; + case 4: + // TRANSLATORS: error message + errorMessage = _("Incorrect hair."); + break; + case 5: + // TRANSLATORS: error message + errorMessage = _("Incorrect slot."); + break; + case 6: + // TRANSLATORS: error message + errorMessage = _("Incorrect race."); + break; + case 7: + // TRANSLATORS: error message + errorMessage = _("Incorrect look."); + break; + } + CREATEWIDGET(OkDialog, + // TRANSLATORS: error message header + _("Error"), + errorMessage, + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::ERROR, + Modal_true, + ShowCenter_true, + nullptr, + 260); + if (charServerHandler->mCharCreateDialog) + charServerHandler->mCharCreateDialog->unlock(); + BLOCK_END("CharServerRecv::processCharCreateFailed") +} + +void CharServerRecv::processCharDelete(Net::MessageIn &msg A_UNUSED) +{ + BLOCK_START("CharServerRecv::processCharDelete") + delete charServerHandler->mSelectedCharacter; + charServerHandler->mCharacters.remove( + charServerHandler->mSelectedCharacter); + charServerHandler->mSelectedCharacter = nullptr; + charServerHandler->updateCharSelectDialog(); + charServerHandler->unlockCharSelectDialog(); + CREATEWIDGET(OkDialog, + // TRANSLATORS: info message header + _("Info"), + // TRANSLATORS: info message + _("Character deleted."), + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::OK, + Modal_true, + ShowCenter_true, + nullptr, + 260); + BLOCK_END("CharServerRecv::processCharDelete") +} + +} // namespace Ea diff --git a/src/net/ea/charserverrecv.h b/src/net/ea/charserverrecv.h new file mode 100644 index 000000000..8f5d233c5 --- /dev/null +++ b/src/net/ea/charserverrecv.h @@ -0,0 +1,43 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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_CHARSERVERRECV_H +#define NET_EA_CHARSERVERRECV_H + +#include "net/charserverhandler.h" + +namespace Net +{ + class MessageIn; +} + +namespace Ea +{ + namespace CharServerRecv + { + void processCharLoginError(Net::MessageIn &msg); + void processCharCreateFailed(Net::MessageIn &msg); + void processCharDelete(Net::MessageIn &msg); + } // namespace CharServerRecv +} // namespace Ea + +#endif // NET_EA_CHARSERVERRECV_H diff --git a/src/net/eathena/charserverhandler.cpp b/src/net/eathena/charserverhandler.cpp index 960acf44d..83c3c7c4c 100644 --- a/src/net/eathena/charserverhandler.cpp +++ b/src/net/eathena/charserverhandler.cpp @@ -38,6 +38,9 @@ #include "net/ea/token.h" +#include "net/ea/charserverrecv.h" + +#include "net/eathena/charserverrecv.h" #include "net/eathena/gamehandler.h" #include "net/eathena/loginhandler.h" #include "net/eathena/messageout.h" @@ -62,21 +65,15 @@ namespace EAthena extern ServerInfo charServer; extern ServerInfo mapServer; -std::string CharServerHandler::mNewName; -uint32_t CharServerHandler::mPinSeed = 0; -BeingId CharServerHandler::mPinAccountId = BeingId_zero; -BeingId CharServerHandler::mRenameId = BeingId_zero; -bool CharServerHandler::mNeedCreatePin = false; - CharServerHandler::CharServerHandler() : MessageHandler(), Ea::CharServerHandler() { - mNewName.clear(); - mPinSeed = 0; - mPinAccountId = BeingId_zero; - mRenameId = BeingId_zero; - mNeedCreatePin = false; + CharServerRecv::mNewName.clear(); + CharServerRecv::mPinSeed = 0; + CharServerRecv::mPinAccountId = BeingId_zero; + CharServerRecv::mRenameId = BeingId_zero; + CharServerRecv::mNeedCreatePin = false; static const uint16_t _messages[] = { @@ -110,79 +107,79 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) switch (msg.getId()) { case SMSG_CHAR_LOGIN: - processCharLogin(msg); + CharServerRecv::processCharLogin(msg); break; case SMSG_CHAR_LOGIN2: - processCharLogin2(msg); + CharServerRecv::processCharLogin2(msg); break; case SMSG_CHAR_LOGIN_ERROR: - processCharLoginError(msg); + Ea::CharServerRecv::processCharLoginError(msg); break; case SMSG_CHAR_CREATE_SUCCEEDED: - processCharCreate(msg); + CharServerRecv::processCharCreate(msg); break; case SMSG_CHAR_CREATE_FAILED: - processCharCreateFailed(msg); + Ea::CharServerRecv::processCharCreateFailed(msg); break; case SMSG_CHAR_DELETE_SUCCEEDED: - processCharDelete(msg); + Ea::CharServerRecv::processCharDelete(msg); break; case SMSG_CHAR_DELETE_FAILED: - processCharDeleteFailed(msg); + CharServerRecv::processCharDeleteFailed(msg); break; case SMSG_CHAR_MAP_INFO: - processCharMapInfo(msg); + CharServerRecv::processCharMapInfo(msg); break; case SMSG_CHANGE_MAP_SERVER: - processChangeMapServer(msg); + CharServerRecv::processChangeMapServer(msg); break; case SMSG_CHAR_PINCODE_STATUS: - processPincodeStatus(msg); + CharServerRecv::processPincodeStatus(msg); break; case SMSG_CHAR_CHECK_RENAME: - processCharCheckRename(msg); + CharServerRecv::processCharCheckRename(msg); break; case SMSG_CHAR_RENAME: - processCharRename(msg); + CharServerRecv::processCharRename(msg); break; case SMSG_CHAR_CHANGE_SLOT: - processCharChangeSlot(msg); + CharServerRecv::processCharChangeSlot(msg); break; case SMSG_CHAR_CAPTCHA_NOT_SUPPORTED: - processCharCaptchaNotSupported(msg); + CharServerRecv::processCharCaptchaNotSupported(msg); break; case SMSG_CHAR_DELETE2_ACK: - processCharDelete2Ack(msg); + CharServerRecv::processCharDelete2Ack(msg); break; case SMSG_CHAR_DELETE2_ACCEPT_ACTUAL_ACK: - processCharDelete2AcceptActual(msg); + CharServerRecv::processCharDelete2AcceptActual(msg); break; case SMSG_CHAR_DELETE2_CANCEL_ACK: - processCharDelete2CancelAck(msg); + CharServerRecv::processCharDelete2CancelAck(msg); break; case SMSG_CHAR_CHARACTERS: - processCharCharacters(msg); + CharServerRecv::processCharCharacters(msg); break; case SMSG_CHAR_BAN_CHAR_LIST: - processCharBanCharList(msg); + CharServerRecv::processCharBanCharList(msg); break; default: @@ -190,105 +187,6 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) } } -void CharServerHandler::readPlayerData(Net::MessageIn &msg, - Net::Character *const character) const -{ - if (!character) - return; - - const Token &token = - static_cast(loginHandler)->getToken(); - - LocalPlayer *const tempPlayer = new LocalPlayer( - msg.readBeingId("player id"), BeingTypeId_zero); - tempPlayer->setGender(token.sex); - - PlayerInfoBackend &data = character->data; - data.mAttributes[Attributes::EXP] = msg.readInt32("exp"); - data.mAttributes[Attributes::MONEY] = msg.readInt32("money"); - Stat &jobStat = data.mStats[Attributes::JOB]; - jobStat.exp = msg.readInt32("job"); - - const int temp = msg.readInt32("job level"); - jobStat.base = temp; - jobStat.mod = temp; - - msg.readInt16("shoes?"); - const int gloves = msg.readInt16("gloves"); - const int cape = msg.readInt16("cape"); - const int misc1 = msg.readInt16("misc1"); - - msg.readInt32("option"); - tempPlayer->setKarma(msg.readInt32("karma")); - tempPlayer->setManner(msg.readInt32("manner")); - msg.readInt16("left points"); - - data.mAttributes[Attributes::HP] = msg.readInt32("hp"); - data.mAttributes[Attributes::MAX_HP] = msg.readInt32("max hp"); - data.mAttributes[Attributes::MP] = msg.readInt16("mp/sp"); - data.mAttributes[Attributes::MAX_MP] = msg.readInt16("max mp/sp"); - - msg.readInt16("speed"); - const uint16_t race = msg.readInt16("class"); -// tempPlayer->setSubtype(race, 0); - const int hairStyle = msg.readInt32("hair style"); - const int option A_UNUSED = (msg.readInt16("weapon") | 1) ^ 1; - const int weapon = 0; - - tempPlayer->setSprite(SPRITE_BODY, weapon, "", ItemColor_one, true); - - data.mAttributes[Attributes::LEVEL] = msg.readInt16("level"); - - msg.readInt16("skill points"); - const int bottomClothes = msg.readInt16("head bottom"); - const int shield = msg.readInt16("shild"); - const int hat = msg.readInt16("head top"); - const int topClothes = msg.readInt16("head mid"); - - const ItemColor color = fromInt(msg.readInt16("hair color"), ItemColor); - tempPlayer->setHairColor(color); - tempPlayer->setSprite(SPRITE_HAIR_COLOR, hairStyle * -1, - ItemDB::get(-hairStyle).getDyeColorsString( - color)); - - const uint16_t look = msg.readInt16("clothes color"); - tempPlayer->setSubtype(fromInt(race, BeingTypeId), look); - tempPlayer->setName(msg.readString(24, "name")); - - character->dummy = tempPlayer; - - character->data.mStats[Attributes::STR].base = msg.readUInt8("str"); - character->data.mStats[Attributes::AGI].base = msg.readUInt8("agi"); - character->data.mStats[Attributes::VIT].base = msg.readUInt8("vit"); - character->data.mStats[Attributes::INT].base = msg.readUInt8("int"); - character->data.mStats[Attributes::DEX].base = msg.readUInt8("dex"); - character->data.mStats[Attributes::LUK].base = msg.readUInt8("luk"); - - character->slot = msg.readInt16("character slot id"); - msg.readInt16("rename"); - msg.readString(16, "map name"); - msg.readInt32("delete date"); - const int shoes = msg.readInt32("robe"); - if (!serverFeatures->haveAdvancedSprites()) - { - tempPlayer->setSprite(SPRITE_HAIR, shoes); - tempPlayer->setSprite(SPRITE_SHOES, gloves); - tempPlayer->setSprite(SPRITE_SHIELD, cape); - tempPlayer->setSprite(SPRITE_HEAD_TOP, misc1); - tempPlayer->setSprite(SPRITE_WEAPON, bottomClothes); - tempPlayer->setSprite(SPRITE_FLOOR, shield); - tempPlayer->setSprite(SPRITE_CLOTHES_COLOR, hat); - tempPlayer->setSprite(SPRITE_HEAD_BOTTOM, topClothes); -// tempPlayer->setSprite(SPRITE_HEAD_MID, misc2); - } - msg.readInt32("slot change"); - tempPlayer->setRename(msg.readInt32("rename (inverse)")); - - const uint8_t gender = static_cast(msg.readUInt8("gender")); - if (gender != 99) - tempPlayer->setGender(Being::intToGender(gender)); -} - void CharServerHandler::chooseCharacter(Net::Character *const character) { if (!character) @@ -390,154 +288,6 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *const window) mCharCreateDialog->setDefaultGender(token.sex); } -void CharServerHandler::processCharLogin(Net::MessageIn &msg) -{ - msg.skip(2, "packet len"); - const int slots = msg.readInt8("MAX_CHARS"); - msg.readInt8("sd->char_slots"); - msg.readInt8("MAX_CHARS"); - loginData.characterSlots = static_cast(slots); - - msg.skip(20, "unused 0"); - - delete_all(mCharacters); - mCharacters.clear(); - - // Derive number of characters from message length - const int count = (msg.getLength() - 27) - / (106 + 4 + 2 + 16 + 4 + 4 + 4 + 4); - - for (int i = 0; i < count; ++i) - { - Net::Character *const character = new Net::Character; - readPlayerData(msg, character); - mCharacters.push_back(character); - if (character->dummy) - { - logger->log("CharServer: Player: %s (%d)", - character->dummy->getName().c_str(), character->slot); - } - } - - client->setState(STATE_CHAR_SELECT); -} - -void CharServerHandler::processCharLogin2(Net::MessageIn &msg) -{ - // ignored - msg.readInt16("len"); - msg.readUInt8("char slots"); - msg.readUInt8("left slots"); - msg.readUInt8("left slots"); - msg.readUInt8("char slots"); - msg.readUInt8("char slots"); - msg.skip(20, "unused"); -} - -void CharServerHandler::processCharMapInfo(Net::MessageIn &restrict msg) -{ - Network *const network = mNetwork; - ServerInfo &server = mapServer; - BLOCK_START("CharServerHandler::processCharMapInfo") - PlayerInfo::setCharId(msg.readInt32("char id")); - GameHandler *const gh = static_cast(gameHandler); - gh->setMap(msg.readString(16, "map name")); - if (config.getBoolValue("usePersistentIP") || settings.persistentIp) - { - msg.readInt32("map ip address"); - server.hostname = settings.serverName; - } - else - { - server.hostname = ipToString(msg.readInt32("map ip address")); - } - server.port = msg.readInt16("map ip port"); - - // Prevent the selected local player from being deleted - localPlayer = mSelectedCharacter->dummy; - PlayerInfo::setBackend(mSelectedCharacter->data); - PlayerInfo::setStatBase(Attributes::WALK_SPEED, - playerHandler->getDefaultWalkSpeed().x); - - mSelectedCharacter->dummy = nullptr; - - charServerHandler->clear(); - updateCharSelectDialog(); - - if (network) - network->disconnect(); - client->setState(STATE_CONNECT_GAME); - BLOCK_END("CharServerHandler::processCharMapInfo") -} - -void CharServerHandler::processChangeMapServer(Net::MessageIn &msg) -{ - Network *const network = mNetwork; - ServerInfo &server = mapServer; - BLOCK_START("CharServerHandler::processChangeMapServer") - GameHandler *const gh = static_cast(gameHandler); - if (!gh || !network) - { - BLOCK_END("CharServerHandler::processChangeMapServer") - return; - } - gh->setMap(msg.readString(16, "map name")); - const int x = msg.readInt16("x"); - const int y = msg.readInt16("y"); - if (config.getBoolValue("usePersistentIP") || settings.persistentIp) - { - msg.readInt32("host"); - server.hostname = settings.serverName; - } - else - { - server.hostname = ipToString(msg.readInt32("host")); - } - server.port = msg.readInt16("port"); - - network->disconnect(); - client->setState(STATE_CHANGE_MAP); - if (localPlayer) - { - localPlayer->setTileCoords(x, y); - localPlayer->setMap(nullptr); - } - BLOCK_END("CharServerHandler::processChangeMapServer") -} - -void CharServerHandler::processPincodeStatus(Net::MessageIn &msg) -{ - mPinSeed = msg.readInt32("pincode seed"); - mPinAccountId = msg.readBeingId("account id"); - const uint16_t state = static_cast(msg.readInt16("state")); - switch (state) - { - case 0: // pin ok - break; - case 1: // ask for pin - break; - case 2: // create new pin - case 4: // create new pin? - { - mNeedCreatePin = true; - break; - } - case 3: // pin must be changed - break; - case 5: // client show error? - break; - case 6: // Unable to use your KSSN number - break; - case 7: // char select window shows a button - break; - case 8: // pincode was incorrect - break; - default: - UNIMPLIMENTEDPACKET; - break; - } -} - void CharServerHandler::setNewPincode(const std::string &pin A_UNUSED) { // here need ecript pin with mPinSeed and pin values. @@ -547,114 +297,16 @@ void CharServerHandler::setNewPincode(const std::string &pin A_UNUSED) // outMsg.writeString(pin, 4, "encrypted pin"); } -void CharServerHandler::processCharCreate(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharCreate") - Net::Character *const character = new Net::Character; - charServerHandler->readPlayerData(msg, character); - mCharacters.push_back(character); - - updateCharSelectDialog(); - - // Close the character create dialog - if (mCharCreateDialog) - { - mCharCreateDialog->scheduleDelete(); - mCharCreateDialog = nullptr; - } - BLOCK_END("CharServerHandler::processCharCreate") -} - void CharServerHandler::renameCharacter(const BeingId id, const std::string &newName) { createOutPacket(CMSG_CHAR_CHECK_RENAME); - mRenameId = id; - mNewName = newName; + CharServerRecv::mRenameId = id; + CharServerRecv::mNewName = newName; outMsg.writeBeingId(id, "char id"); outMsg.writeString(newName, 24, "name"); } -void CharServerHandler::processCharCheckRename(Net::MessageIn &msg) -{ - if (msg.readInt16("flag")) - { - createOutPacket(CMSG_CHAR_RENAME); - outMsg.writeBeingId(mRenameId, "char id"); - } - else - { - CREATEWIDGET(OkDialog, - // TRANSLATORS: error header - _("Error"), - // TRANSLATORS: error message - _("Character rename error."), - // TRANSLATORS: ok dialog button - _("Error"), - DialogType::ERROR, - Modal_true, - ShowCenter_true, - nullptr, - 260); - } -} - -void CharServerHandler::processCharRename(Net::MessageIn &msg) -{ - const int flag = msg.readInt16("flag"); - if (!flag) - { - mCharSelectDialog->setName(mRenameId, mNewName); - CREATEWIDGET(OkDialog, - // TRANSLATORS: info header - _("Info"), - // TRANSLATORS: info message - _("Character renamed."), - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::OK, - Modal_true, - ShowCenter_true, - nullptr, - 260); - } - else - { - std::string message; - switch (flag) - { - case 1: - // TRANSLATORS: char rename error - message = _("Rename not allowed."); - break; - case 2: - // TRANSLATORS: char rename error - message = _("New name is not set."); - break; - case 3: - default: - // TRANSLATORS: char rename error - message = _("Character rename error."); - break; - case 4: - // TRANSLATORS: char rename error - message = _("Character not found."); - break; - } - CREATEWIDGET(OkDialog, - // TRANSLATORS: info message - _("Info"), - message, - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::OK, - Modal_true, - ShowCenter_true, - nullptr, - 260); - } -} - void CharServerHandler::changeSlot(const int oldSlot, const int newSlot) { createOutPacket(CMSG_CHAR_CHANGE_SLOT); @@ -663,89 +315,6 @@ void CharServerHandler::changeSlot(const int oldSlot, const int newSlot) outMsg.writeInt16(0, "unused"); } -void CharServerHandler::processCharChangeSlot(Net::MessageIn &msg) -{ - UNIMPLIMENTEDPACKET; - msg.readInt16("len"); - msg.readInt16("flag"); // 0 - ok, 1 - error - msg.readInt16("unused"); -} - -void CharServerHandler::processCharDeleteFailed(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharDeleteFailed") - unlockCharSelectDialog(); - msg.readUInt8("error"); - CREATEWIDGET(OkDialog, - // TRANSLATORS: error header - _("Error"), - // TRANSLATORS: error message - _("Failed to delete character."), - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::ERROR, - Modal_true, - ShowCenter_true, - nullptr, - 260); - BLOCK_END("CharServerHandler::processCharDeleteFailed") -} - -void CharServerHandler::processCharCaptchaNotSupported(Net::MessageIn &msg) -{ - UNIMPLIMENTEDPACKET; - msg.readInt16("5"); - msg.readUInt8("1"); -} - -void CharServerHandler::processCharDelete2Ack(Net::MessageIn &msg) -{ - UNIMPLIMENTEDPACKET; - msg.readInt32("char id"); - msg.readInt32("result"); - msg.readInt32("time"); -} - -void CharServerHandler::processCharDelete2AcceptActual(Net::MessageIn &msg) -{ - UNIMPLIMENTEDPACKET; - msg.readInt32("char id"); - msg.readInt32("result"); -} - -void CharServerHandler::processCharDelete2CancelAck(Net::MessageIn &msg) -{ - UNIMPLIMENTEDPACKET; - msg.readInt32("char id"); - msg.readInt32("result"); -} - -void CharServerHandler::processCharCharacters(Net::MessageIn &msg) -{ - msg.skip(2, "packet len"); - - delete_all(mCharacters); - mCharacters.clear(); - - // Derive number of characters from message length - const int count = (msg.getLength() - 4) - / (106 + 4 + 2 + 16 + 4 + 4 + 4 + 4); - - for (int i = 0; i < count; ++i) - { - Net::Character *const character = new Net::Character; - charServerHandler->readPlayerData(msg, character); - mCharacters.push_back(character); - if (character->dummy) - { - logger->log("CharServer: Player: %s (%d)", - character->dummy->getName().c_str(), character->slot); - } - } - - client->setState(STATE_CHAR_SELECT); -} - void CharServerHandler::ping() const { createOutPacket(CMSG_CHAR_PING); @@ -757,15 +326,9 @@ unsigned int CharServerHandler::hatSprite() const return 7; } -void CharServerHandler::processCharBanCharList(Net::MessageIn &msg) +bool CharServerHandler::isNeedCreatePin() const { - UNIMPLIMENTEDPACKET; - const int count = (msg.readInt16("len") - 4) / 24; - for (int f = 0; f < count; f ++) - { - msg.readInt32("char id"); - msg.readString(20, "unbun time"); - } + return CharServerRecv::mNeedCreatePin; } } // namespace EAthena diff --git a/src/net/eathena/charserverhandler.h b/src/net/eathena/charserverhandler.h index 1b0b602ae..20086c965 100644 --- a/src/net/eathena/charserverhandler.h +++ b/src/net/eathena/charserverhandler.h @@ -64,14 +64,7 @@ class CharServerHandler final : public MessageHandler, void connect() override final; - void processCharLogin(Net::MessageIn &msg); - - void processCharMapInfo(Net::MessageIn &msg); - - void processChangeMapServer(Net::MessageIn &msg); - - bool isNeedCreatePin() const override final A_WARN_UNUSED - { return mNeedCreatePin; } + bool isNeedCreatePin() const override final A_WARN_UNUSED; void setNewPincode(const std::string &pin) override final; @@ -85,47 +78,9 @@ class CharServerHandler final : public MessageHandler, void changeSlot(const int oldSlot, const int newSlot) override final; - void readPlayerData(Net::MessageIn &msg, - Net::Character *const character) - const override final; - void ping() const override final; unsigned int hatSprite() const override final A_WARN_UNUSED; - - protected: - static void processPincodeStatus(Net::MessageIn &msg); - - static void processCharLogin2(Net::MessageIn &msg); - - static void processCharCreate(Net::MessageIn &msg); - - static void processCharCheckRename(Net::MessageIn &msg); - - static void processCharRename(Net::MessageIn &msg); - - static void processCharChangeSlot(Net::MessageIn &msg); - - static void processCharDeleteFailed(Net::MessageIn &msg); - - static void processCharCaptchaNotSupported(Net::MessageIn &msg); - - static void processCharDelete2Ack(Net::MessageIn &msg); - - static void processCharDelete2AcceptActual(Net::MessageIn &msg); - - static void processCharDelete2CancelAck(Net::MessageIn &msg); - - static void processCharCharacters(Net::MessageIn &msg); - - static void processCharBanCharList(Net::MessageIn &msg); - - private: - static std::string mNewName; - static uint32_t mPinSeed; - static BeingId mPinAccountId; - static BeingId mRenameId; - static bool mNeedCreatePin; }; } // namespace EAthena diff --git a/src/net/eathena/charserverrecv.cpp b/src/net/eathena/charserverrecv.cpp new file mode 100644 index 000000000..62be4a694 --- /dev/null +++ b/src/net/eathena/charserverrecv.cpp @@ -0,0 +1,515 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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/eathena/charserverrecv.h" + +#include "client.h" +#include "configuration.h" +#include "settings.h" + +#include "gui/windows/charcreatedialog.h" +#include "gui/windows/charselectdialog.h" +#include "gui/windows/okdialog.h" + +#include "gui/widgets/createwidget.h" + +#include "net/character.h" +#include "net/playerhandler.h" +#include "net/serverfeatures.h" + +#include "net/ea/token.h" + +#include "net/eathena/gamehandler.h" +#include "net/eathena/loginhandler.h" +#include "net/eathena/messageout.h" +#include "net/eathena/network.h" +#include "net/eathena/protocol.h" +#include "net/eathena/sprite.h" + +#include "resources/iteminfo.h" + +#include "resources/db/itemdb.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" + +#include "debug.h" + +extern Net::CharServerHandler *charServerHandler; + +namespace EAthena +{ + +extern ServerInfo charServer; +extern ServerInfo mapServer; + +namespace CharServerRecv +{ + std::string mNewName; + uint32_t mPinSeed = 0; + BeingId mPinAccountId = BeingId_zero; + BeingId mRenameId = BeingId_zero; + bool mNeedCreatePin = false; +} + +void CharServerRecv::readPlayerData(Net::MessageIn &msg, + Net::Character *const character) +{ + if (!character) + return; + + const Token &token = + static_cast(loginHandler)->getToken(); + + LocalPlayer *const tempPlayer = new LocalPlayer( + msg.readBeingId("player id"), BeingTypeId_zero); + tempPlayer->setGender(token.sex); + + PlayerInfoBackend &data = character->data; + data.mAttributes[Attributes::EXP] = msg.readInt32("exp"); + data.mAttributes[Attributes::MONEY] = msg.readInt32("money"); + Stat &jobStat = data.mStats[Attributes::JOB]; + jobStat.exp = msg.readInt32("job"); + + const int temp = msg.readInt32("job level"); + jobStat.base = temp; + jobStat.mod = temp; + + msg.readInt16("shoes?"); + const int gloves = msg.readInt16("gloves"); + const int cape = msg.readInt16("cape"); + const int misc1 = msg.readInt16("misc1"); + + msg.readInt32("option"); + tempPlayer->setKarma(msg.readInt32("karma")); + tempPlayer->setManner(msg.readInt32("manner")); + msg.readInt16("left points"); + + data.mAttributes[Attributes::HP] = msg.readInt32("hp"); + data.mAttributes[Attributes::MAX_HP] = msg.readInt32("max hp"); + data.mAttributes[Attributes::MP] = msg.readInt16("mp/sp"); + data.mAttributes[Attributes::MAX_MP] = msg.readInt16("max mp/sp"); + + msg.readInt16("speed"); + const uint16_t race = msg.readInt16("class"); +// tempPlayer->setSubtype(race, 0); + const int hairStyle = msg.readInt32("hair style"); + const int option A_UNUSED = (msg.readInt16("weapon") | 1) ^ 1; + const int weapon = 0; + + tempPlayer->setSprite(SPRITE_BODY, weapon, "", ItemColor_one, true); + + data.mAttributes[Attributes::LEVEL] = msg.readInt16("level"); + + msg.readInt16("skill points"); + const int bottomClothes = msg.readInt16("head bottom"); + const int shield = msg.readInt16("shild"); + const int hat = msg.readInt16("head top"); + const int topClothes = msg.readInt16("head mid"); + + const ItemColor color = fromInt(msg.readInt16("hair color"), ItemColor); + tempPlayer->setHairColor(color); + tempPlayer->setSprite(SPRITE_HAIR_COLOR, hairStyle * -1, + ItemDB::get(-hairStyle).getDyeColorsString( + color)); + + const uint16_t look = msg.readInt16("clothes color"); + tempPlayer->setSubtype(fromInt(race, BeingTypeId), look); + tempPlayer->setName(msg.readString(24, "name")); + + character->dummy = tempPlayer; + + character->data.mStats[Attributes::STR].base = msg.readUInt8("str"); + character->data.mStats[Attributes::AGI].base = msg.readUInt8("agi"); + character->data.mStats[Attributes::VIT].base = msg.readUInt8("vit"); + character->data.mStats[Attributes::INT].base = msg.readUInt8("int"); + character->data.mStats[Attributes::DEX].base = msg.readUInt8("dex"); + character->data.mStats[Attributes::LUK].base = msg.readUInt8("luk"); + + character->slot = msg.readInt16("character slot id"); + msg.readInt16("rename"); + msg.readString(16, "map name"); + msg.readInt32("delete date"); + const int shoes = msg.readInt32("robe"); + if (!serverFeatures->haveAdvancedSprites()) + { + tempPlayer->setSprite(SPRITE_HAIR, shoes); + tempPlayer->setSprite(SPRITE_SHOES, gloves); + tempPlayer->setSprite(SPRITE_SHIELD, cape); + tempPlayer->setSprite(SPRITE_HEAD_TOP, misc1); + tempPlayer->setSprite(SPRITE_WEAPON, bottomClothes); + tempPlayer->setSprite(SPRITE_FLOOR, shield); + tempPlayer->setSprite(SPRITE_CLOTHES_COLOR, hat); + tempPlayer->setSprite(SPRITE_HEAD_BOTTOM, topClothes); +// tempPlayer->setSprite(SPRITE_HEAD_MID, misc2); + } + msg.readInt32("slot change"); + tempPlayer->setRename(msg.readInt32("rename (inverse)")); + + const uint8_t gender = static_cast(msg.readUInt8("gender")); + if (gender != 99) + tempPlayer->setGender(Being::intToGender(gender)); +} + +void CharServerRecv::processCharLogin(Net::MessageIn &msg) +{ + msg.skip(2, "packet len"); + const int slots = msg.readInt8("MAX_CHARS"); + msg.readInt8("sd->char_slots"); + msg.readInt8("MAX_CHARS"); + loginData.characterSlots = static_cast(slots); + + msg.skip(20, "unused 0"); + + delete_all(charServerHandler->mCharacters); + charServerHandler->mCharacters.clear(); + + // Derive number of characters from message length + const int count = (msg.getLength() - 27) + / (106 + 4 + 2 + 16 + 4 + 4 + 4 + 4); + + for (int i = 0; i < count; ++i) + { + Net::Character *const character = new Net::Character; + readPlayerData(msg, character); + charServerHandler->mCharacters.push_back(character); + if (character->dummy) + { + logger->log("CharServer: Player: %s (%d)", + character->dummy->getName().c_str(), character->slot); + } + } + + client->setState(STATE_CHAR_SELECT); +} + +void CharServerRecv::processCharLogin2(Net::MessageIn &msg) +{ + // ignored + msg.readInt16("len"); + msg.readUInt8("char slots"); + msg.readUInt8("left slots"); + msg.readUInt8("left slots"); + msg.readUInt8("char slots"); + msg.readUInt8("char slots"); + msg.skip(20, "unused"); +} + +void CharServerRecv::processCharMapInfo(Net::MessageIn &restrict msg) +{ + Network *const network = Network::mInstance; + ServerInfo &server = mapServer; + BLOCK_START("CharServerRecv::processCharMapInfo") + PlayerInfo::setCharId(msg.readInt32("char id")); + GameHandler *const gh = static_cast(gameHandler); + gh->setMap(msg.readString(16, "map name")); + if (config.getBoolValue("usePersistentIP") || settings.persistentIp) + { + msg.readInt32("map ip address"); + server.hostname = settings.serverName; + } + else + { + server.hostname = ipToString(msg.readInt32("map ip address")); + } + server.port = msg.readInt16("map ip port"); + + // Prevent the selected local player from being deleted + localPlayer = charServerHandler->mSelectedCharacter->dummy; + PlayerInfo::setBackend(charServerHandler->mSelectedCharacter->data); + PlayerInfo::setStatBase(Attributes::WALK_SPEED, + playerHandler->getDefaultWalkSpeed().x); + + charServerHandler->mSelectedCharacter->dummy = nullptr; + + charServerHandler->clear(); + charServerHandler->updateCharSelectDialog(); + + if (network) + network->disconnect(); + client->setState(STATE_CONNECT_GAME); + BLOCK_END("CharServerRecv::processCharMapInfo") +} + +void CharServerRecv::processChangeMapServer(Net::MessageIn &msg) +{ + Network *const network = Network::mInstance; + ServerInfo &server = mapServer; + BLOCK_START("CharServerRecv::processChangeMapServer") + GameHandler *const gh = static_cast(gameHandler); + if (!gh || !network) + { + BLOCK_END("CharServerRecv::processChangeMapServer") + return; + } + gh->setMap(msg.readString(16, "map name")); + const int x = msg.readInt16("x"); + const int y = msg.readInt16("y"); + if (config.getBoolValue("usePersistentIP") || settings.persistentIp) + { + msg.readInt32("host"); + server.hostname = settings.serverName; + } + else + { + server.hostname = ipToString(msg.readInt32("host")); + } + server.port = msg.readInt16("port"); + + network->disconnect(); + client->setState(STATE_CHANGE_MAP); + if (localPlayer) + { + localPlayer->setTileCoords(x, y); + localPlayer->setMap(nullptr); + } + BLOCK_END("CharServerRecv::processChangeMapServer") +} + +void CharServerRecv::processPincodeStatus(Net::MessageIn &msg) +{ + mPinSeed = msg.readInt32("pincode seed"); + mPinAccountId = msg.readBeingId("account id"); + const uint16_t state = static_cast(msg.readInt16("state")); + switch (state) + { + case 0: // pin ok + break; + case 1: // ask for pin + break; + case 2: // create new pin + case 4: // create new pin? + { + mNeedCreatePin = true; + break; + } + case 3: // pin must be changed + break; + case 5: // client show error? + break; + case 6: // Unable to use your KSSN number + break; + case 7: // char select window shows a button + break; + case 8: // pincode was incorrect + break; + default: + UNIMPLIMENTEDPACKET; + break; + } +} + +void CharServerRecv::processCharCreate(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharCreate") + Net::Character *const character = new Net::Character; + readPlayerData(msg, character); + charServerHandler->mCharacters.push_back(character); + + charServerHandler->updateCharSelectDialog(); + + // Close the character create dialog + if (charServerHandler->mCharCreateDialog) + { + charServerHandler->mCharCreateDialog->scheduleDelete(); + charServerHandler->mCharCreateDialog = nullptr; + } + BLOCK_END("CharServerRecv::processCharCreate") +} + +void CharServerRecv::processCharCheckRename(Net::MessageIn &msg) +{ + if (msg.readInt16("flag")) + { + createOutPacket(CMSG_CHAR_RENAME); + outMsg.writeBeingId(mRenameId, "char id"); + } + else + { + CREATEWIDGET(OkDialog, + // TRANSLATORS: error header + _("Error"), + // TRANSLATORS: error message + _("Character rename error."), + // TRANSLATORS: ok dialog button + _("Error"), + DialogType::ERROR, + Modal_true, + ShowCenter_true, + nullptr, + 260); + } +} + +void CharServerRecv::processCharRename(Net::MessageIn &msg) +{ + const int flag = msg.readInt16("flag"); + if (!flag) + { + charServerHandler->mCharSelectDialog->setName( + mRenameId, + mNewName); + CREATEWIDGET(OkDialog, + // TRANSLATORS: info header + _("Info"), + // TRANSLATORS: info message + _("Character renamed."), + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::OK, + Modal_true, + ShowCenter_true, + nullptr, + 260); + } + else + { + std::string message; + switch (flag) + { + case 1: + // TRANSLATORS: char rename error + message = _("Rename not allowed."); + break; + case 2: + // TRANSLATORS: char rename error + message = _("New name is not set."); + break; + case 3: + default: + // TRANSLATORS: char rename error + message = _("Character rename error."); + break; + case 4: + // TRANSLATORS: char rename error + message = _("Character not found."); + break; + } + CREATEWIDGET(OkDialog, + // TRANSLATORS: info message + _("Info"), + message, + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::OK, + Modal_true, + ShowCenter_true, + nullptr, + 260); + } +} + +void CharServerRecv::processCharChangeSlot(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + msg.readInt16("len"); + msg.readInt16("flag"); // 0 - ok, 1 - error + msg.readInt16("unused"); +} + +void CharServerRecv::processCharDeleteFailed(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharDeleteFailed") + charServerHandler->unlockCharSelectDialog(); + msg.readUInt8("error"); + CREATEWIDGET(OkDialog, + // TRANSLATORS: error header + _("Error"), + // TRANSLATORS: error message + _("Failed to delete character."), + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::ERROR, + Modal_true, + ShowCenter_true, + nullptr, + 260); + BLOCK_END("CharServerRecv::processCharDeleteFailed") +} + +void CharServerRecv::processCharCaptchaNotSupported(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + msg.readInt16("5"); + msg.readUInt8("1"); +} + +void CharServerRecv::processCharDelete2Ack(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + msg.readInt32("char id"); + msg.readInt32("result"); + msg.readInt32("time"); +} + +void CharServerRecv::processCharDelete2AcceptActual(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + msg.readInt32("char id"); + msg.readInt32("result"); +} + +void CharServerRecv::processCharDelete2CancelAck(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + msg.readInt32("char id"); + msg.readInt32("result"); +} + +void CharServerRecv::processCharCharacters(Net::MessageIn &msg) +{ + msg.skip(2, "packet len"); + + delete_all(charServerHandler->mCharacters); + charServerHandler->mCharacters.clear(); + + // Derive number of characters from message length + const int count = (msg.getLength() - 4) + / (106 + 4 + 2 + 16 + 4 + 4 + 4 + 4); + + for (int i = 0; i < count; ++i) + { + Net::Character *const character = new Net::Character; + readPlayerData(msg, character); + charServerHandler->mCharacters.push_back(character); + if (character->dummy) + { + logger->log("CharServer: Player: %s (%d)", + character->dummy->getName().c_str(), character->slot); + } + } + + client->setState(STATE_CHAR_SELECT); +} + +void CharServerRecv::processCharBanCharList(Net::MessageIn &msg) +{ + UNIMPLIMENTEDPACKET; + const int count = (msg.readInt16("len") - 4) / 24; + for (int f = 0; f < count; f ++) + { + msg.readInt32("char id"); + msg.readString(20, "unbun time"); + } +} + +} // namespace EAthena diff --git a/src/net/eathena/charserverrecv.h b/src/net/eathena/charserverrecv.h new file mode 100644 index 000000000..1df9a7e5e --- /dev/null +++ b/src/net/eathena/charserverrecv.h @@ -0,0 +1,61 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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_EATHENA_CHARSERVERRECV_H +#define NET_EATHENA_CHARSERVERRECV_H + +#include "net/ea/charserverhandler.h" + +#include "net/eathena/messagehandler.h" + +namespace EAthena +{ + namespace CharServerRecv + { + extern std::string mNewName; + extern uint32_t mPinSeed; + extern BeingId mPinAccountId; + extern BeingId mRenameId; + extern bool mNeedCreatePin; + + void readPlayerData(Net::MessageIn &msg, + Net::Character *const character); + void processPincodeStatus(Net::MessageIn &msg); + void processCharLogin2(Net::MessageIn &msg); + void processCharCreate(Net::MessageIn &msg); + void processCharCheckRename(Net::MessageIn &msg); + void processCharRename(Net::MessageIn &msg); + void processCharChangeSlot(Net::MessageIn &msg); + void processCharDeleteFailed(Net::MessageIn &msg); + void processCharCaptchaNotSupported(Net::MessageIn &msg); + void processCharDelete2Ack(Net::MessageIn &msg); + void processCharDelete2AcceptActual(Net::MessageIn &msg); + void processCharDelete2CancelAck(Net::MessageIn &msg); + void processCharCharacters(Net::MessageIn &msg); + void processCharBanCharList(Net::MessageIn &msg); + void processCharLogin(Net::MessageIn &msg); + void processCharMapInfo(Net::MessageIn &msg); + void processChangeMapServer(Net::MessageIn &msg); + } // namespace CharServerRecv +} // namespace EAthena + +#endif // NET_EATHENA_CHARSERVERRECV_H diff --git a/src/net/eathena/network.h b/src/net/eathena/network.h index 6e794d36d..acfb9dd59 100644 --- a/src/net/eathena/network.h +++ b/src/net/eathena/network.h @@ -54,14 +54,14 @@ class Network final : public Ea::Network void dispatchMessages(); + static Network *mInstance; + protected: friend class MessageOut; static Network *instance() A_WARN_UNUSED; MessageHandler **mMessageHandlers; - - static Network *mInstance; }; } // namespace EAthena diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 229339ef4..2be2f1250 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -35,6 +35,9 @@ #include "net/ea/token.h" +#include "net/ea/charserverrecv.h" + +#include "net/tmwa/charserverrecv.h" #include "net/tmwa/gamehandler.h" #include "net/tmwa/loginhandler.h" #include "net/tmwa/messageout.h" @@ -87,35 +90,35 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) switch (msg.getId()) { case SMSG_CHAR_LOGIN: - processCharLogin(msg); + CharServerRecv::processCharLogin(msg); break; case SMSG_CHAR_LOGIN_ERROR: - processCharLoginError(msg); + Ea::CharServerRecv::processCharLoginError(msg); break; case SMSG_CHAR_CREATE_SUCCEEDED: - processCharCreate(msg); + CharServerRecv::processCharCreate(msg); break; case SMSG_CHAR_CREATE_FAILED: - processCharCreateFailed(msg); + Ea::CharServerRecv::processCharCreateFailed(msg); break; case SMSG_CHAR_DELETE_SUCCEEDED: - processCharDelete(msg); + Ea::CharServerRecv::processCharDelete(msg); break; case SMSG_CHAR_DELETE_FAILED: - processCharDeleteFailed(msg); + CharServerRecv::processCharDeleteFailed(msg); break; case SMSG_CHAR_MAP_INFO: - processCharMapInfo(msg); + CharServerRecv::processCharMapInfo(msg); break; case SMSG_CHANGE_MAP_SERVER: - processChangeMapServer(msg); + CharServerRecv::processChangeMapServer(msg); break; default: @@ -124,94 +127,6 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) BLOCK_END("CharServerHandler::handleMessage") } -void CharServerHandler::readPlayerData(Net::MessageIn &msg, - Net::Character *const character) const -{ - if (!character) - return; - - const Token &token = - static_cast(loginHandler)->getToken(); - - LocalPlayer *const tempPlayer = new LocalPlayer( - msg.readBeingId("account id"), BeingTypeId_zero); - tempPlayer->setGender(token.sex); - - PlayerInfoBackend &data = character->data; - data.mAttributes[Attributes::EXP] = msg.readInt32("exp"); - data.mAttributes[Attributes::MONEY] = msg.readInt32("money"); - Stat &jobStat = data.mStats[Attributes::JOB]; - jobStat.exp = msg.readInt32("job"); - - const int temp = msg.readInt32("job level"); - jobStat.base = temp; - jobStat.mod = temp; - - const int shoes = msg.readInt16("shoes"); - const int gloves = msg.readInt16("gloves"); - const int cape = msg.readInt16("cape"); - const int misc1 = msg.readInt16("misc1"); - - msg.readInt32("option"); - tempPlayer->setKarma(msg.readInt32("karma")); - tempPlayer->setManner(msg.readInt32("manner")); - msg.readInt16("character points left"); - - data.mAttributes[Attributes::HP] = msg.readInt16("hp"); - data.mAttributes[Attributes::MAX_HP] = msg.readInt16("max hp"); - data.mAttributes[Attributes::MP] = msg.readInt16("mp"); - data.mAttributes[Attributes::MAX_MP] = msg.readInt16("max mp"); - - msg.readInt16("speed"); - const uint16_t race = msg.readInt16("class"); - const uint8_t hairStyle = msg.readUInt8("hair style"); - const uint16_t look = msg.readUInt8("look"); - tempPlayer->setSubtype(fromInt(race, BeingTypeId), look); - const uint16_t weapon = msg.readInt16("weapon"); - tempPlayer->setSprite(SPRITE_BODY, weapon, "", ItemColor_one, true); - - data.mAttributes[Attributes::LEVEL] = msg.readInt16("level"); - - msg.readInt16("skill point"); - const int bottomClothes = msg.readInt16("bottom clothes"); - const int shield = msg.readInt16("shield"); - - const int hat = msg.readInt16("hat"); - const int topClothes = msg.readInt16("top clothes"); - - const ItemColor hairColor = fromInt( - msg.readUInt8("hair color"), ItemColor); - msg.readUInt8("unused"); - tempPlayer->setSprite(SPRITE_HAIR_COLOR, hairStyle * -1, - ItemDB::get(-hairStyle).getDyeColorsString(hairColor)); - tempPlayer->setHairColor(hairColor); - - const int misc2 = msg.readInt16("misc2"); - tempPlayer->setName(msg.readString(24, "name")); - - character->dummy = tempPlayer; - - character->data.mStats[Attributes::STR].base = msg.readUInt8("str"); - character->data.mStats[Attributes::AGI].base = msg.readUInt8("agi"); - character->data.mStats[Attributes::VIT].base = msg.readUInt8("vit"); - character->data.mStats[Attributes::INT].base = msg.readUInt8("int"); - character->data.mStats[Attributes::DEX].base = msg.readUInt8("dex"); - character->data.mStats[Attributes::LUK].base = msg.readUInt8("luk"); - - tempPlayer->setSprite(SPRITE_HAIR, shoes); - tempPlayer->setSprite(SPRITE_SHOES, gloves); - tempPlayer->setSprite(SPRITE_SHIELD, cape); - tempPlayer->setSprite(SPRITE_HEAD_TOP, misc1); - tempPlayer->setSprite(SPRITE_WEAPON, bottomClothes); - tempPlayer->setSprite(SPRITE_FLOOR, shield); - tempPlayer->setSprite(SPRITE_CLOTHES_COLOR, hat); // head option top - tempPlayer->setSprite(SPRITE_HEAD_BOTTOM, topClothes); - tempPlayer->setSprite(SPRITE_HEAD_MID, misc2); - - character->slot = msg.readUInt8("slot"); - msg.readUInt8("unused"); -} - void CharServerHandler::chooseCharacter(Net::Character *const character) { if (!character) @@ -333,126 +248,6 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *const window) mCharCreateDialog->setDefaultGender(token.sex); } -void CharServerHandler::processCharLogin(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharLogin") - - msg.readInt16("len"); - const int slots = msg.readInt16("slots"); - if (slots > 0 && slots < 30) - loginData.characterSlots = static_cast(slots); - - msg.skip(18, "unused"); - - delete_all(mCharacters); - mCharacters.clear(); - - // Derive number of characters from message length - const int count = (msg.getLength() - 24) / 106; - - for (int i = 0; i < count; ++i) - { - Net::Character *const character = new Net::Character; - readPlayerData(msg, character); - mCharacters.push_back(character); - if (character->dummy) - { - logger->log("CharServer: Player: %s (%d)", - character->dummy->getName().c_str(), character->slot); - } - } - - client->setState(STATE_CHAR_SELECT); - BLOCK_END("CharServerHandler::processCharLogin") -} - -void CharServerHandler::processCharMapInfo(Net::MessageIn &restrict msg) -{ - Network *const network = mNetwork; - ServerInfo &server = mapServer; - BLOCK_START("CharServerHandler::processCharMapInfo") - PlayerInfo::setCharId(msg.readInt32("char id?")); - GameHandler *const gh = static_cast(gameHandler); - gh->setMap(msg.readString(16, "map name")); - if (config.getBoolValue("usePersistentIP") || settings.persistentIp) - { - msg.readInt32("ip address"); - server.hostname = settings.serverName; - } - else - { - server.hostname = ipToString(msg.readInt32("ip address")); - } - server.port = msg.readInt16("port"); - - // Prevent the selected local player from being deleted - localPlayer = mSelectedCharacter->dummy; - PlayerInfo::setBackend(mSelectedCharacter->data); - - mSelectedCharacter->dummy = nullptr; - - charServerHandler->clear(); - updateCharSelectDialog(); - - if (network) - network->disconnect(); - client->setState(STATE_CONNECT_GAME); - BLOCK_END("CharServerHandler::processCharMapInfo") -} - -void CharServerHandler::processChangeMapServer(Net::MessageIn &msg) -{ - Network *const network = mNetwork; - ServerInfo &server = mapServer; - BLOCK_START("CharServerHandler::processChangeMapServer") - GameHandler *const gh = static_cast(gameHandler); - if (!gh || !network) - { - BLOCK_END("CharServerHandler::processChangeMapServer") - return; - } - gh->setMap(msg.readString(16, "map name")); - const int x = msg.readInt16("x"); - const int y = msg.readInt16("y"); - if (config.getBoolValue("usePersistentIP") || settings.persistentIp) - { - msg.readInt32("ip address"); - server.hostname = settings.serverName; - } - else - { - server.hostname = ipToString(msg.readInt32("ip address")); - } - server.port = msg.readInt16("port"); - - network->disconnect(); - client->setState(STATE_CHANGE_MAP); - if (localPlayer) - { - localPlayer->setTileCoords(x, y); - localPlayer->setMap(nullptr); - } - BLOCK_END("CharServerHandler::processChangeMapServer") -} - -void CharServerHandler::processCharCreate(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharCreate") - Net::Character *const character = new Net::Character; - charServerHandler->readPlayerData(msg, character); - mCharacters.push_back(character); - - updateCharSelectDialog(); - - // Close the character create dialog - if (mCharCreateDialog) - { - mCharCreateDialog->scheduleDelete(); - mCharCreateDialog = nullptr; - } - BLOCK_END("CharServerHandler::processCharCreate") -} - void CharServerHandler::renameCharacter(const BeingId id A_UNUSED, const std::string &newName A_UNUSED) { @@ -463,26 +258,6 @@ void CharServerHandler::changeSlot(const int oldSlot A_UNUSED, { } -void CharServerHandler::processCharDeleteFailed(Net::MessageIn &msg) -{ - BLOCK_START("CharServerHandler::processCharDeleteFailed") - unlockCharSelectDialog(); - msg.readUInt8("error"); - CREATEWIDGET(OkDialog, - // TRANSLATORS: error header - _("Error"), - // TRANSLATORS: error message - _("Failed to delete character."), - // TRANSLATORS: ok dialog button - _("OK"), - DialogType::ERROR, - Modal_true, - ShowCenter_true, - nullptr, - 260); - BLOCK_END("CharServerHandler::processCharDeleteFailed") -} - void CharServerHandler::ping() const { } diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h index 11667481f..39c561213 100644 --- a/src/net/tmwa/charserverhandler.h +++ b/src/net/tmwa/charserverhandler.h @@ -64,12 +64,6 @@ class CharServerHandler final : public MessageHandler, void connect() override final; - void processCharLogin(Net::MessageIn &msg); - - void processCharMapInfo(Net::MessageIn &msg); - - void processChangeMapServer(Net::MessageIn &msg); - bool isNeedCreatePin() const override final { return false; } @@ -86,18 +80,9 @@ class CharServerHandler final : public MessageHandler, void changeSlot(const int oldSlot, const int newSlot) override final; - void readPlayerData(Net::MessageIn &msg, - Net::Character *const character) - const override final; - void ping() const override final; unsigned int hatSprite() const override final A_WARN_UNUSED; - - protected: - static void processCharCreate(Net::MessageIn &msg); - - static void processCharDeleteFailed(Net::MessageIn &msg); }; } // namespace TmwAthena diff --git a/src/net/tmwa/charserverrecv.cpp b/src/net/tmwa/charserverrecv.cpp new file mode 100644 index 000000000..fb8ef6f8e --- /dev/null +++ b/src/net/tmwa/charserverrecv.cpp @@ -0,0 +1,292 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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/tmwa/charserverrecv.h" + +#include "client.h" +#include "configuration.h" +#include "settings.h" + +#include "gui/windows/charcreatedialog.h" +#include "gui/windows/okdialog.h" + +#include "gui/widgets/createwidget.h" + +#include "net/character.h" + +#include "net/ea/token.h" + +#include "net/tmwa/gamehandler.h" +#include "net/tmwa/loginhandler.h" +#include "net/tmwa/messageout.h" +#include "net/tmwa/network.h" +#include "net/tmwa/protocol.h" +#include "net/tmwa/sprite.h" + +#include "resources/iteminfo.h" + +#include "resources/db/chardb.h" +#include "resources/db/itemdb.h" + +#include "utils/dtor.h" +#include "utils/gettext.h" + +#include "debug.h" + +extern Net::CharServerHandler *charServerHandler; + +namespace TmwAthena +{ + +extern ServerInfo mapServer; + +extern ServerInfo charServer; + +void CharServerRecv::readPlayerData(Net::MessageIn &msg, + Net::Character *const character) +{ + if (!character) + return; + + const Token &token = + static_cast(loginHandler)->getToken(); + + LocalPlayer *const tempPlayer = new LocalPlayer( + msg.readBeingId("account id"), BeingTypeId_zero); + tempPlayer->setGender(token.sex); + + PlayerInfoBackend &data = character->data; + data.mAttributes[Attributes::EXP] = msg.readInt32("exp"); + data.mAttributes[Attributes::MONEY] = msg.readInt32("money"); + Stat &jobStat = data.mStats[Attributes::JOB]; + jobStat.exp = msg.readInt32("job"); + + const int temp = msg.readInt32("job level"); + jobStat.base = temp; + jobStat.mod = temp; + + const int shoes = msg.readInt16("shoes"); + const int gloves = msg.readInt16("gloves"); + const int cape = msg.readInt16("cape"); + const int misc1 = msg.readInt16("misc1"); + + msg.readInt32("option"); + tempPlayer->setKarma(msg.readInt32("karma")); + tempPlayer->setManner(msg.readInt32("manner")); + msg.readInt16("character points left"); + + data.mAttributes[Attributes::HP] = msg.readInt16("hp"); + data.mAttributes[Attributes::MAX_HP] = msg.readInt16("max hp"); + data.mAttributes[Attributes::MP] = msg.readInt16("mp"); + data.mAttributes[Attributes::MAX_MP] = msg.readInt16("max mp"); + + msg.readInt16("speed"); + const uint16_t race = msg.readInt16("class"); + const uint8_t hairStyle = msg.readUInt8("hair style"); + const uint16_t look = msg.readUInt8("look"); + tempPlayer->setSubtype(fromInt(race, BeingTypeId), look); + const uint16_t weapon = msg.readInt16("weapon"); + tempPlayer->setSprite(SPRITE_BODY, weapon, "", ItemColor_one, true); + + data.mAttributes[Attributes::LEVEL] = msg.readInt16("level"); + + msg.readInt16("skill point"); + const int bottomClothes = msg.readInt16("bottom clothes"); + const int shield = msg.readInt16("shield"); + + const int hat = msg.readInt16("hat"); + const int topClothes = msg.readInt16("top clothes"); + + const ItemColor hairColor = fromInt( + msg.readUInt8("hair color"), ItemColor); + msg.readUInt8("unused"); + tempPlayer->setSprite(SPRITE_HAIR_COLOR, hairStyle * -1, + ItemDB::get(-hairStyle).getDyeColorsString(hairColor)); + tempPlayer->setHairColor(hairColor); + + const int misc2 = msg.readInt16("misc2"); + tempPlayer->setName(msg.readString(24, "name")); + + character->dummy = tempPlayer; + + character->data.mStats[Attributes::STR].base = msg.readUInt8("str"); + character->data.mStats[Attributes::AGI].base = msg.readUInt8("agi"); + character->data.mStats[Attributes::VIT].base = msg.readUInt8("vit"); + character->data.mStats[Attributes::INT].base = msg.readUInt8("int"); + character->data.mStats[Attributes::DEX].base = msg.readUInt8("dex"); + character->data.mStats[Attributes::LUK].base = msg.readUInt8("luk"); + + tempPlayer->setSprite(SPRITE_HAIR, shoes); + tempPlayer->setSprite(SPRITE_SHOES, gloves); + tempPlayer->setSprite(SPRITE_SHIELD, cape); + tempPlayer->setSprite(SPRITE_HEAD_TOP, misc1); + tempPlayer->setSprite(SPRITE_WEAPON, bottomClothes); + tempPlayer->setSprite(SPRITE_FLOOR, shield); + tempPlayer->setSprite(SPRITE_CLOTHES_COLOR, hat); // head option top + tempPlayer->setSprite(SPRITE_HEAD_BOTTOM, topClothes); + tempPlayer->setSprite(SPRITE_HEAD_MID, misc2); + + character->slot = msg.readUInt8("slot"); + msg.readUInt8("unused"); +} + +void CharServerRecv::processCharLogin(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharLogin") + + msg.readInt16("len"); + const int slots = msg.readInt16("slots"); + if (slots > 0 && slots < 30) + loginData.characterSlots = static_cast(slots); + + msg.skip(18, "unused"); + + delete_all(charServerHandler->mCharacters); + charServerHandler->mCharacters.clear(); + + // Derive number of characters from message length + const int count = (msg.getLength() - 24) / 106; + + for (int i = 0; i < count; ++i) + { + Net::Character *const character = new Net::Character; + readPlayerData(msg, character); + charServerHandler->mCharacters.push_back(character); + if (character->dummy) + { + logger->log("CharServer: Player: %s (%d)", + character->dummy->getName().c_str(), character->slot); + } + } + + client->setState(STATE_CHAR_SELECT); + BLOCK_END("CharServerRecv::processCharLogin") +} + +void CharServerRecv::processCharMapInfo(Net::MessageIn &restrict msg) +{ + Network *const network = Network::mInstance; + ServerInfo &server = mapServer; + BLOCK_START("CharServerRecv::processCharMapInfo") + PlayerInfo::setCharId(msg.readInt32("char id?")); + GameHandler *const gh = static_cast(gameHandler); + gh->setMap(msg.readString(16, "map name")); + if (config.getBoolValue("usePersistentIP") || settings.persistentIp) + { + msg.readInt32("ip address"); + server.hostname = settings.serverName; + } + else + { + server.hostname = ipToString(msg.readInt32("ip address")); + } + server.port = msg.readInt16("port"); + + // Prevent the selected local player from being deleted + localPlayer = charServerHandler->mSelectedCharacter->dummy; + PlayerInfo::setBackend(charServerHandler->mSelectedCharacter->data); + + charServerHandler->mSelectedCharacter->dummy = nullptr; + + charServerHandler->clear(); + charServerHandler->updateCharSelectDialog(); + + if (network) + network->disconnect(); + client->setState(STATE_CONNECT_GAME); + BLOCK_END("CharServerRecv::processCharMapInfo") +} + +void CharServerRecv::processChangeMapServer(Net::MessageIn &msg) +{ + Network *const network = Network::mInstance; + ServerInfo &server = mapServer; + BLOCK_START("CharServerRecv::processChangeMapServer") + GameHandler *const gh = static_cast(gameHandler); + if (!gh || !network) + { + BLOCK_END("CharServerRecv::processChangeMapServer") + return; + } + gh->setMap(msg.readString(16, "map name")); + const int x = msg.readInt16("x"); + const int y = msg.readInt16("y"); + if (config.getBoolValue("usePersistentIP") || settings.persistentIp) + { + msg.readInt32("ip address"); + server.hostname = settings.serverName; + } + else + { + server.hostname = ipToString(msg.readInt32("ip address")); + } + server.port = msg.readInt16("port"); + + network->disconnect(); + client->setState(STATE_CHANGE_MAP); + if (localPlayer) + { + localPlayer->setTileCoords(x, y); + localPlayer->setMap(nullptr); + } + BLOCK_END("CharServerRecv::processChangeMapServer") +} + +void CharServerRecv::processCharCreate(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharCreate") + Net::Character *const character = new Net::Character; + readPlayerData(msg, character); + charServerHandler->mCharacters.push_back(character); + + charServerHandler->updateCharSelectDialog(); + + // Close the character create dialog + if (charServerHandler->mCharCreateDialog) + { + charServerHandler->mCharCreateDialog->scheduleDelete(); + charServerHandler->mCharCreateDialog = nullptr; + } + BLOCK_END("CharServerRecv::processCharCreate") +} + +void CharServerRecv::processCharDeleteFailed(Net::MessageIn &msg) +{ + BLOCK_START("CharServerRecv::processCharDeleteFailed") + charServerHandler->unlockCharSelectDialog(); + msg.readUInt8("error"); + CREATEWIDGET(OkDialog, + // TRANSLATORS: error header + _("Error"), + // TRANSLATORS: error message + _("Failed to delete character."), + // TRANSLATORS: ok dialog button + _("OK"), + DialogType::ERROR, + Modal_true, + ShowCenter_true, + nullptr, + 260); + BLOCK_END("CharServerRecv::processCharDeleteFailed") +} + +} // namespace TmwAthena diff --git a/src/net/tmwa/charserverrecv.h b/src/net/tmwa/charserverrecv.h new file mode 100644 index 000000000..fa01d8f95 --- /dev/null +++ b/src/net/tmwa/charserverrecv.h @@ -0,0 +1,44 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2015 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_TMWA_CHARSERVERRECV_H +#define NET_TMWA_CHARSERVERRECV_H + +#include "net/ea/charserverhandler.h" + +#include "net/tmwa/messagehandler.h" + +namespace TmwAthena +{ + namespace CharServerRecv + { + void readPlayerData(Net::MessageIn &msg, + Net::Character *const character); + void processCharCreate(Net::MessageIn &msg); + void processCharDeleteFailed(Net::MessageIn &msg); + void processCharLogin(Net::MessageIn &msg); + void processCharMapInfo(Net::MessageIn &msg); + void processChangeMapServer(Net::MessageIn &msg); + } // namespace CharServerRecv +} // namespace TmwAthena + +#endif // NET_TMWA_CHARSERVERRECV_H diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h index 0a6134e0f..046314c88 100644 --- a/src/net/tmwa/network.h +++ b/src/net/tmwa/network.h @@ -55,14 +55,14 @@ class Network final : public Ea::Network void dispatchMessages(); + static Network *mInstance; + protected: friend class MessageOut; static Network *instance() A_WARN_UNUSED; MessageHandler **mMessageHandlers; - - static Network *mInstance; }; } // namespace TmwAthena -- cgit v1.2.3-70-g09d2