diff options
Diffstat (limited to 'src/net/charserverhandler.cpp')
-rw-r--r-- | src/net/charserverhandler.cpp | 273 |
1 files changed, 139 insertions, 134 deletions
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp index 06ec78c1..f715b434 100644 --- a/src/net/charserverhandler.cpp +++ b/src/net/charserverhandler.cpp @@ -23,9 +23,9 @@ #include "charserverhandler.h" -#include "messagein.h" -#include "network.h" +#include "connection.h" #include "protocol.h" +#include "messagein.h" #include "../game.h" #include "../localplayer.h" @@ -35,66 +35,67 @@ #include "../gui/ok_dialog.h" +extern Net::Connection *gameServerConnection; +extern Net::Connection *chatServerConnection; + CharServerHandler::CharServerHandler() { static const Uint16 _messages[] = { - 0x006b, - 0x006c, - 0x006d, - 0x006e, - 0x006f, - 0x0070, - 0x0071, - 0x0081, + APMSG_CHAR_CREATE_RESPONSE, + APMSG_CHAR_DELETE_RESPONSE, + APMSG_CHAR_INFO, + APMSG_CHAR_SELECT_RESPONSE, 0 }; handledMessages = _messages; } -void CharServerHandler::handleMessage(MessageIn *msg) +void +CharServerHandler::handleMessage(MessageIn &msg) { int slot; LocalPlayer *tempPlayer; - logger->log("CharServerHandler: Packet ID: %x, Length: %d", - msg->getId(), msg->getLength()); - switch (msg->getId()) + switch (msg.getId()) { - case 0x006b: - // Skip length word and an additional mysterious 20 bytes - msg->skip(2 + 20); - - // Derive number of characters from message length - n_character = (msg->getLength() - 24) / 106; + case APMSG_CHAR_CREATE_RESPONSE: + handleCharCreateResponse(msg); + break; - for (int i = 0; i < n_character; i++) + case APMSG_CHAR_DELETE_RESPONSE: + { + int errMsg = msg.readByte(); + // Character deletion successful + if (errMsg == ERRMSG_OK) { - tempPlayer = readPlayerData(msg, slot); - mCharInfo->select(slot); - mCharInfo->setEntry(tempPlayer); - logger->log("CharServer: Player: %s (%d)", - tempPlayer->getName().c_str(), slot); + delete mCharInfo->getEntry(); + mCharInfo->setEntry(0); + mCharInfo->unlock(); + n_character--; + new OkDialog("Info", "Player deleted"); } - - state = CHAR_SELECT_STATE; - break; - - case 0x006c: - switch (msg->readInt8()) { - case 0: - errorMessage = "Access denied"; - break; - case 1: - errorMessage = "Cannot use this ID"; - break; - default: - errorMessage = "Unknown failure to select character"; - break; + // Character deletion failed + else + { + std::string message = ""; + switch (errMsg) + { + case ERRMSG_NO_LOGIN: + message = "Not logged in"; + break; + case ERRMSG_INVALID_ARGUMENT: + message = "Selection out of range"; + break; + default: + message = "Unknown error"; + } + mCharInfo->unlock(); + new OkDialog("Error", message); } - mCharInfo->unlock(); + } break; - case 0x006d: + case APMSG_CHAR_INFO: tempPlayer = readPlayerData(msg, slot); mCharInfo->unlock(); mCharInfo->select(slot); @@ -102,107 +103,111 @@ void CharServerHandler::handleMessage(MessageIn *msg) n_character++; break; - case 0x006e: - new OkDialog("Error", "Failed to create character"); - break; - - case 0x006f: - delete mCharInfo->getEntry(); - mCharInfo->setEntry(0); - mCharInfo->unlock(); - n_character--; - new OkDialog("Info", "Player deleted"); + case APMSG_CHAR_SELECT_RESPONSE: + handleCharSelectResponse(msg); break; + } +} - case 0x0070: - mCharInfo->unlock(); - new OkDialog("Error", "Failed to delete character."); - break; +void +CharServerHandler::handleCharCreateResponse(MessageIn &msg) +{ + int errMsg = msg.readByte(); - case 0x0071: - player_node = mCharInfo->getEntry(); - msg->skip(4); // CharID, must be the same as player_node->charID - map_path = msg->readString(16); - mLoginData->hostname = iptostring(msg->readInt32()); - mLoginData->port = msg->readInt16(); - mCharInfo->unlock(); - mCharInfo->select(0); - // Clear unselected players infos - do - { - LocalPlayer *tmp = mCharInfo->getEntry(); - if (tmp != player_node) - delete tmp; - mCharInfo->next(); - } while (mCharInfo->getPos()); + // Character creation failed + if (errMsg != ERRMSG_OK) + { + std::string message = ""; + switch (errMsg) + { + case ERRMSG_NO_LOGIN: + message = "Not logged in"; + break; + case CREATE_TOO_MUCH_CHARACTERS: + message = "No empty slot"; + break; + case ERRMSG_INVALID_ARGUMENT: + message = "Invalid name"; + break; + case CREATE_EXISTS_NAME: + message = "Character's name already exists"; + break; + case CREATE_INVALID_HAIRSTYLE: + message = "Invalid hairstyle"; + break; + case CREATE_INVALID_HAIRCOLOR: + message = "Invalid hair color"; + break; + case CREATE_INVALID_GENDER: + message = "Invalid gender"; + break; + case CREATE_RAW_STATS_TOO_HIGH: + message = "Character's stats are too high"; + break; + case CREATE_RAW_STATS_TOO_LOW: + message = "Character's stats are too low"; + break; + case CREATE_RAW_STATS_INVALID_DIFF: + message = "Character's stats difference is too high"; + break; + case CREATE_RAW_STATS_EQUAL_TO_ZERO: + message = "One stat is zero"; + break; + default: + message = "Unknown error"; + break; + } + new OkDialog("Error", message); + } +} - state = CONNECTING_STATE; - break; +void +CharServerHandler::handleCharSelectResponse(MessageIn &msg) +{ + int errMsg = msg.readByte(); - case 0x0081: - switch (msg->readInt8()) { - case 1: - errorMessage = "Map server offline"; - break; - case 3: - errorMessage = "Speed hack detected"; - break; - case 8: - errorMessage = "Duplicated login"; - break; - default: - errorMessage = "Unkown error with 0x0081"; - break; - } - mCharInfo->unlock(); - state = ERROR_STATE; - break; + if (errMsg == ERRMSG_OK) + { + token = msg.readString(32); + std::string gameServer = msg.readString(); + unsigned short gameServerPort = msg.readShort(); + std::string chatServer = msg.readString(); + unsigned short chatServerPort = msg.readShort(); + + logger->log("Game server: %s:%d", gameServer.c_str(), gameServerPort); + logger->log("Chat server: %s:%d", chatServer.c_str(), chatServerPort); + + gameServerConnection->connect(gameServer, gameServerPort); + chatServerConnection->connect(chatServer, chatServerPort); + + // Keep the selected character and delete the others + player_node = mCharInfo->getEntry(); + mCharInfo->unlock(); + mCharInfo->select(0); + do { + LocalPlayer *tmp = mCharInfo->getEntry(); + if (tmp != player_node) + delete tmp; + mCharInfo->next(); + } while (mCharInfo->getPos()); + + state = STATE_CONNECT_GAME; } } -LocalPlayer* CharServerHandler::readPlayerData(MessageIn *msg, int &slot) +LocalPlayer* +CharServerHandler::readPlayerData(MessageIn &msg, int &slot) { - LocalPlayer *tempPlayer = new LocalPlayer(mLoginData->account_ID, 0, NULL); - tempPlayer->setSex(1 - mLoginData->sex); - - tempPlayer->mCharId = msg->readInt32(); - tempPlayer->mTotalWeight = 0; - tempPlayer->mMaxWeight = 0; - tempPlayer->mLastAttackTime = 0; - tempPlayer->mXp = msg->readInt32(); - tempPlayer->mGp = msg->readInt32(); - tempPlayer->mJobXp = msg->readInt32(); - tempPlayer->mJobLevel = msg->readInt32(); - msg->skip(8); // unknown - msg->readInt32(); // option - msg->readInt32(); // karma - msg->readInt32(); // manner - msg->skip(2); // unknown - tempPlayer->mHp = msg->readInt16(); - tempPlayer->mMaxHp = msg->readInt16(); - tempPlayer->mMp = msg->readInt16(); - tempPlayer->mMaxMp = msg->readInt16(); - msg->readInt16(); // speed - msg->readInt16(); // class - tempPlayer->setHairStyle(msg->readInt16()); - Uint16 weapon = msg->readInt16(); - if (weapon == 11) - weapon = 2; - tempPlayer->setWeapon(weapon); - tempPlayer->mLevel = msg->readInt16(); - msg->readInt16(); // skill point - tempPlayer->setVisibleEquipment(3, msg->readInt16()); // head bottom - msg->readInt16(); // shield - tempPlayer->setVisibleEquipment(4, msg->readInt16()); // head option top - tempPlayer->setVisibleEquipment(5, msg->readInt16()); // head option mid - tempPlayer->setHairColor(msg->readInt16()); - msg->readInt16(); // unknown - tempPlayer->setName(msg->readString(24)); + LocalPlayer *tempPlayer = new LocalPlayer; + slot = msg.readByte(); // character slot + tempPlayer->mName = msg.readString(); + tempPlayer->setSex(msg.readByte()); + tempPlayer->setHairStyle(msg.readByte()); + tempPlayer->setHairColor(msg.readByte()); + tempPlayer->mLevel = msg.readByte(); + tempPlayer->mMoney = msg.readShort(); for (int i = 0; i < 6; i++) { - tempPlayer->mAttr[i] = msg->readInt8(); + tempPlayer->mAttr[i] = msg.readByte(); } - slot = msg->readInt8(); // character slot - msg->readInt8(); // unknown - return tempPlayer; } |