summaryrefslogtreecommitdiff
path: root/src/net/charserverhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/charserverhandler.cpp')
-rw-r--r--src/net/charserverhandler.cpp273
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;
}