summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorEugenio Favalli <elvenprogrammer@gmail.com>2006-07-25 18:04:38 +0000
committerEugenio Favalli <elvenprogrammer@gmail.com>2006-07-25 18:04:38 +0000
commitc7e7b62aa94bf295ca1dc556762ad6070221e0cd (patch)
tree04f827df0df64a80e04a4115986609486d715237 /src/net
parentc0c8775271679ac4904bc0bc02a74d28fc75efd0 (diff)
downloadmana-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.gz
mana-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.bz2
mana-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.xz
mana-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.zip
Switched client to use enet and modified login sequence to work with the new protocol from tmwserv.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/beinghandler.cpp170
-rw-r--r--src/net/buysellhandler.cpp24
-rw-r--r--src/net/charserverhandler.cpp68
-rw-r--r--src/net/chathandler.cpp10
-rw-r--r--src/net/equipmenthandler.cpp41
-rw-r--r--src/net/inventoryhandler.cpp55
-rw-r--r--src/net/itemhandler.cpp13
-rw-r--r--src/net/loginhandler.cpp94
-rw-r--r--src/net/maploginhandler.cpp4
-rw-r--r--src/net/messagein.cpp171
-rw-r--r--src/net/messagein.h66
-rw-r--r--src/net/messageout.cpp102
-rw-r--r--src/net/messageout.h45
-rw-r--r--src/net/network.cpp355
-rw-r--r--src/net/network.h38
-rw-r--r--src/net/npchandler.cpp8
-rw-r--r--src/net/playerhandler.cpp104
-rw-r--r--src/net/protocol.h97
-rw-r--r--src/net/skillhandler.cpp26
-rw-r--r--src/net/tradehandler.cpp21
20 files changed, 626 insertions, 886 deletions
diff --git a/src/net/beinghandler.cpp b/src/net/beinghandler.cpp
index cd5653fc..68a46650 100644
--- a/src/net/beinghandler.cpp
+++ b/src/net/beinghandler.cpp
@@ -71,12 +71,12 @@ void BeingHandler::handleMessage(MessageIn *msg)
case SMSG_BEING_VISIBLE:
case SMSG_BEING_MOVE:
// Information about a being in range
- id = msg->readInt32();
- speed = msg->readInt16();
- msg->readInt16(); // unknown
- msg->readInt16(); // unknown
- msg->readInt16(); // option
- job = msg->readInt16(); // class
+ id = msg->readLong();
+ speed = msg->readShort();
+ msg->readShort(); // unknown
+ msg->readShort(); // unknown
+ msg->readShort(); // option
+ job = msg->readShort(); // class
dstBeing = beingManager->findBeing(id);
@@ -104,33 +104,33 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setWalkSpeed(speed);
dstBeing->mJob = job;
- dstBeing->setHairStyle(msg->readInt16());
- dstBeing->setWeapon(msg->readInt16());
- dstBeing->setVisibleEquipment(3, msg->readInt16()); // head bottom
+ dstBeing->setHairStyle(msg->readShort());
+ dstBeing->setWeapon(msg->readShort());
+ dstBeing->setVisibleEquipment(3, msg->readShort()); // head bottom
if (msg->getId() == SMSG_BEING_MOVE)
{
- msg->readInt32(); // server tick
+ msg->readLong(); // server tick
}
- msg->readInt16(); // shield
- dstBeing->setVisibleEquipment(4, msg->readInt16()); // head top
- dstBeing->setVisibleEquipment(5, msg->readInt16()); // head mid
- dstBeing->setHairColor(msg->readInt16());
- msg->readInt16(); // unknown
- msg->readInt16(); // head dir
- msg->readInt16(); // guild
- msg->readInt16(); // unknown
- msg->readInt16(); // unknown
- msg->readInt16(); // manner
- msg->readInt16(); // karma
- msg->readInt8(); // unknown
- dstBeing->setSex(1 - msg->readInt8()); // sex
+ msg->readShort(); // shield
+ dstBeing->setVisibleEquipment(4, msg->readShort()); // head top
+ dstBeing->setVisibleEquipment(5, msg->readShort()); // head mid
+ dstBeing->setHairColor(msg->readShort());
+ msg->readShort(); // unknown
+ msg->readShort(); // head dir
+ msg->readShort(); // guild
+ msg->readShort(); // unknown
+ msg->readShort(); // unknown
+ msg->readShort(); // manner
+ msg->readShort(); // karma
+ msg->readByte(); // unknown
+ dstBeing->setSex(1 - msg->readByte()); // sex
if (msg->getId() == SMSG_BEING_MOVE)
{
Uint16 srcX, srcY, dstX, dstY;
- msg->readCoordinatePair(srcX, srcY, dstX, dstY);
+ //msg->readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->setAction(Being::STAND);
dstBeing->mX = srcX;
dstBeing->mY = srcY;
@@ -138,23 +138,22 @@ void BeingHandler::handleMessage(MessageIn *msg)
}
else
{
- msg->readCoordinates(dstBeing->mX, dstBeing->mY,
- dstBeing->mDirection);
+ //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection);
}
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown / sit
+ msg->readByte(); // unknown
+ msg->readByte(); // unknown
+ msg->readByte(); // unknown / sit
break;
case SMSG_BEING_REMOVE:
// A being should be removed or has died
- dstBeing = beingManager->findBeing(msg->readInt32());
+ dstBeing = beingManager->findBeing(msg->readLong());
if (!dstBeing)
break;
- if (msg->readInt8() == 1)
+ if (msg->readByte() == 1)
{
// Death
switch (dstBeing->getType())
@@ -182,15 +181,15 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case SMSG_BEING_ACTION:
- srcBeing = beingManager->findBeing(msg->readInt32());
- dstBeing = beingManager->findBeing(msg->readInt32());
- msg->readInt32(); // server tick
- msg->readInt32(); // src speed
- msg->readInt32(); // dst speed
- param1 = msg->readInt16();
- msg->readInt16(); // param 2
- type = msg->readInt8();
- msg->readInt16(); // param 3
+ srcBeing = beingManager->findBeing(msg->readLong());
+ dstBeing = beingManager->findBeing(msg->readLong());
+ msg->readLong(); // server tick
+ msg->readLong(); // src speed
+ msg->readLong(); // dst speed
+ param1 = msg->readShort();
+ msg->readShort(); // param 2
+ type = msg->readByte();
+ msg->readShort(); // param 3
switch (type)
{
@@ -231,61 +230,61 @@ void BeingHandler::handleMessage(MessageIn *msg)
break;
case SMSG_BEING_LEVELUP:
- if ((Uint32)msg->readInt32() == player_node->getId()) {
+ if ((Uint32)msg->readLong() == player_node->getId()) {
logger->log("Level up");
sound.playSfx("sfx/levelup.ogg");
} else {
logger->log("Someone else went level up");
}
- msg->readInt32(); // type
+ msg->readLong(); // type
break;
case SMSG_BEING_EMOTION:
- if (!(dstBeing = beingManager->findBeing(msg->readInt32())))
+ if (!(dstBeing = beingManager->findBeing(msg->readLong())))
{
break;
}
- dstBeing->mEmotion = msg->readInt8();
+ dstBeing->mEmotion = msg->readByte();
dstBeing->mEmotionTime = EMOTION_TIME;
break;
case SMSG_BEING_CHANGE_LOOKS:
{
- if (!(dstBeing = beingManager->findBeing(msg->readInt32())))
+ if (!(dstBeing = beingManager->findBeing(msg->readLong())))
{
break;
}
-
- int type = msg->readInt8();
+
+ int type = msg->readByte();
switch (type) {
case 1:
- dstBeing->setHairStyle(msg->readInt8());
+ dstBeing->setHairStyle(msg->readByte());
break;
case 2:
- dstBeing->setWeapon(msg->readInt8());
+ dstBeing->setWeapon(msg->readByte());
break;
case 3:
case 4:
case 5:
// Equip/unequip head 3. Bottom 4. Top 5. Middle
- dstBeing->setVisibleEquipment(type, msg->readInt8());
+ dstBeing->setVisibleEquipment(type, msg->readByte());
// First 3 slots of mVisibleEquipments are reserved for
// later use, probably accessories.
break;
case 6:
- dstBeing->setHairColor(msg->readInt8());
+ dstBeing->setHairColor(msg->readByte());
break;
default:
- printf("c3: %i\n", msg->readInt8()); // unsupported
+ printf("c3: %i\n", msg->readByte()); // unsupported
break;
}
}
break;
case SMSG_BEING_NAME_RESPONSE:
- if ((dstBeing = beingManager->findBeing(msg->readInt32())))
+ if ((dstBeing = beingManager->findBeing(msg->readLong())))
{
dstBeing->setName(msg->readString(24));
}
@@ -295,12 +294,12 @@ void BeingHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_UPDATE_2:
case SMSG_PLAYER_MOVE:
// An update about a player, potentially including movement.
- id = msg->readInt32();
- speed = msg->readInt16();
- msg->readInt16(); // option 1
- msg->readInt16(); // option 2
- msg->readInt16(); // option
- job = msg->readInt16();
+ id = msg->readLong();
+ speed = msg->readShort();
+ msg->readShort(); // option 1
+ msg->readShort(); // option 2
+ msg->readShort(); // option
+ job = msg->readShort();
dstBeing = beingManager->findBeing(id);
@@ -311,58 +310,57 @@ void BeingHandler::handleMessage(MessageIn *msg)
dstBeing->setWalkSpeed(speed);
dstBeing->mJob = job;
- dstBeing->setHairStyle(msg->readInt16());
- dstBeing->setWeaponById(msg->readInt16()); // item id 1
- msg->readInt16(); // item id 2
- dstBeing->setVisibleEquipment(3, msg->readInt16()); // head bottom
+ dstBeing->setHairStyle(msg->readShort());
+ dstBeing->setWeaponById(msg->readShort()); // item id 1
+ msg->readShort(); // item id 2
+ dstBeing->setVisibleEquipment(3, msg->readShort()); // head bottom
if (msg->getId() == SMSG_PLAYER_MOVE)
{
- msg->readInt32(); // server tick
+ msg->readLong(); // server tick
}
- dstBeing->setVisibleEquipment(4, msg->readInt16()); // head top
- dstBeing->setVisibleEquipment(5, msg->readInt16()); // head mid
- dstBeing->setHairColor(msg->readInt16());
- msg->readInt16(); // unknown
- msg->readInt16(); // head dir
- msg->readInt32(); // guild
- msg->readInt32(); // emblem
- msg->readInt16(); // manner
- msg->readInt8(); // karma
- dstBeing->setSex(1 - msg->readInt8()); // sex
+ dstBeing->setVisibleEquipment(4, msg->readShort()); // head top
+ dstBeing->setVisibleEquipment(5, msg->readShort()); // head mid
+ dstBeing->setHairColor(msg->readShort());
+ msg->readShort(); // unknown
+ msg->readShort(); // head dir
+ msg->readLong(); // guild
+ msg->readLong(); // emblem
+ msg->readShort(); // manner
+ msg->readByte(); // karma
+ dstBeing->setSex(1 - msg->readByte()); // sex
if (msg->getId() == SMSG_PLAYER_MOVE)
{
Uint16 srcX, srcY, dstX, dstY;
- msg->readCoordinatePair(srcX, srcY, dstX, dstY);
+ //msg->readCoordinatePair(srcX, srcY, dstX, dstY);
dstBeing->mX = srcX;
dstBeing->mY = srcY;
dstBeing->setDestination(dstX, dstY);
}
else
{
- msg->readCoordinates(dstBeing->mX, dstBeing->mY,
- dstBeing->mDirection);
+ //msg->readCoordinates(dstBeing->mX, dstBeing->mY, dstBeing->mDirection);
}
- msg->readInt8(); // unknown
- msg->readInt8(); // unknown
+ msg->readByte(); // unknown
+ msg->readByte(); // unknown
if (msg->getId() == SMSG_PLAYER_UPDATE_1)
{
- if (msg->readInt8() == 2)
+ if (msg->readByte() == 2)
{
dstBeing->setAction(Being::SIT);
}
}
else if (msg->getId() == SMSG_PLAYER_MOVE)
{
- msg->readInt8(); // unknown
+ msg->readByte(); // unknown
}
- msg->readInt8(); // Lv
- msg->readInt8(); // unknown
+ msg->readByte(); // Lv
+ msg->readByte(); // unknown
dstBeing->mWalkTime = tick_time;
dstBeing->mFrame = 0;
@@ -370,9 +368,9 @@ void BeingHandler::handleMessage(MessageIn *msg)
case 0x0119:
// Change in players look
- printf("0x0119 %i %i %i %x %i\n", msg->readInt32(),
- msg->readInt16(), msg->readInt16(), msg->readInt16(),
- msg->readInt8());
+ printf("0x0119 %i %i %i %x %i\n", msg->readLong(),
+ msg->readShort(), msg->readShort(), msg->readShort(),
+ msg->readByte());
break;
}
}
diff --git a/src/net/buysellhandler.cpp b/src/net/buysellhandler.cpp
index b10c7ab9..be636d94 100644
--- a/src/net/buysellhandler.cpp
+++ b/src/net/buysellhandler.cpp
@@ -65,11 +65,11 @@ void BuySellHandler::handleMessage(MessageIn *msg)
sellDialog->setVisible(false);
sellDialog->reset();
buySellDialog->setVisible(true);
- current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readInt32()));
+ current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readLong()));
break;
case SMSG_NPC_BUY:
- msg->readInt16(); // length
+ msg->readShort(); // length
n_items = (msg->getLength() - 4) / 11;
buyDialog->reset();
buyDialog->setMoney(player_node->mGp);
@@ -77,16 +77,16 @@ void BuySellHandler::handleMessage(MessageIn *msg)
for (int k = 0; k < n_items; k++)
{
- Sint32 value = msg->readInt32();
- msg->readInt32(); // DCvalue
- msg->readInt8(); // type
- Sint16 itemId = msg->readInt16();
+ Sint32 value = msg->readLong();
+ msg->readLong(); // DCvalue
+ msg->readByte(); // type
+ Sint16 itemId = msg->readShort();
buyDialog->addItem(itemId, value);
}
break;
case SMSG_NPC_SELL:
- msg->readInt16(); // length
+ msg->readShort(); // length
n_items = (msg->getLength() - 4) / 10;
if (n_items > 0) {
sellDialog->reset();
@@ -94,9 +94,9 @@ void BuySellHandler::handleMessage(MessageIn *msg)
for (int k = 0; k < n_items; k++)
{
- Sint16 index = msg->readInt16();
- Sint32 value = msg->readInt32();
- msg->readInt32(); // OCvalue
+ Sint16 index = msg->readShort();
+ Sint32 value = msg->readLong();
+ msg->readLong(); // OCvalue
Item *item = player_node->getInvItem(index);
if (item && !(item->isEquipped())) {
@@ -111,7 +111,7 @@ void BuySellHandler::handleMessage(MessageIn *msg)
break;
case SMSG_NPC_BUY_RESPONSE:
- if (msg->readInt8() == 0) {
+ if (msg->readByte() == 0) {
chatWindow->chatLog("Thanks for buying", BY_SERVER);
} else {
chatWindow->chatLog("Unable to buy", BY_SERVER);
@@ -119,7 +119,7 @@ void BuySellHandler::handleMessage(MessageIn *msg)
break;
case SMSG_NPC_SELL_RESPONSE:
- if (msg->readInt8() == 0) {
+ if (msg->readByte() == 0) {
chatWindow->chatLog("Thanks for selling", BY_SERVER);
} else {
chatWindow->chatLog("Unable to sell", BY_SERVER);
diff --git a/src/net/charserverhandler.cpp b/src/net/charserverhandler.cpp
index 06ec78c1..932a6fbc 100644
--- a/src/net/charserverhandler.cpp
+++ b/src/net/charserverhandler.cpp
@@ -61,9 +61,6 @@ void CharServerHandler::handleMessage(MessageIn *msg)
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;
@@ -80,7 +77,7 @@ void CharServerHandler::handleMessage(MessageIn *msg)
break;
case 0x006c:
- switch (msg->readInt8()) {
+ switch (msg->readByte()) {
case 0:
errorMessage = "Access denied";
break;
@@ -121,10 +118,9 @@ void CharServerHandler::handleMessage(MessageIn *msg)
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();
+ mLoginData->hostname = iptostring(msg->readLong());
+ mLoginData->port = msg->readShort();
mCharInfo->unlock();
mCharInfo->select(0);
// Clear unselected players infos
@@ -140,7 +136,7 @@ void CharServerHandler::handleMessage(MessageIn *msg)
break;
case 0x0081:
- switch (msg->readInt8()) {
+ switch (msg->readByte()) {
case 1:
errorMessage = "Map server offline";
break;
@@ -165,44 +161,42 @@ 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->mCharId = msg->readLong();
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();
+ tempPlayer->mXp = msg->readLong();
+ tempPlayer->mGp = msg->readLong();
+ tempPlayer->mJobXp = msg->readLong();
+ tempPlayer->mJobLevel = msg->readLong();
+ msg->readLong(); // option
+ msg->readLong(); // karma
+ msg->readLong(); // manner
+ tempPlayer->mHp = msg->readShort();
+ tempPlayer->mMaxHp = msg->readShort();
+ tempPlayer->mMp = msg->readShort();
+ tempPlayer->mMaxMp = msg->readShort();
+ msg->readShort(); // speed
+ msg->readShort(); // class
+ tempPlayer->setHairStyle(msg->readShort());
+ Uint16 weapon = msg->readShort();
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->mLevel = msg->readShort();
+ msg->readShort(); // skill point
+ tempPlayer->setVisibleEquipment(3, msg->readShort()); // head bottom
+ msg->readShort(); // shield
+ tempPlayer->setVisibleEquipment(4, msg->readShort()); // head option top
+ tempPlayer->setVisibleEquipment(5, msg->readShort()); // head option mid
+ tempPlayer->setHairColor(msg->readShort());
+ msg->readShort(); // unknown
tempPlayer->setName(msg->readString(24));
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
+ slot = msg->readByte(); // character slot
+ msg->readByte(); // unknown
return tempPlayer;
}
diff --git a/src/net/chathandler.cpp b/src/net/chathandler.cpp
index 9095a4e1..d6f822f8 100644
--- a/src/net/chathandler.cpp
+++ b/src/net/chathandler.cpp
@@ -62,8 +62,8 @@ void ChatHandler::handleMessage(MessageIn *msg)
{
// Received speech from being
case SMSG_BEING_CHAT:
- chatMsgLength = msg->readInt16() - 8;
- being = beingManager->findBeing(msg->readInt32());
+ chatMsgLength = msg->readShort() - 8;
+ being = beingManager->findBeing(msg->readLong());
if (!being || chatMsgLength <= 0)
{
@@ -78,7 +78,7 @@ void ChatHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_CHAT:
case SMSG_GM_CHAT:
- chatMsgLength = msg->readInt16() - 4;
+ chatMsgLength = msg->readShort() - 4;
if (chatMsgLength <= 0)
{
@@ -105,13 +105,13 @@ void ChatHandler::handleMessage(MessageIn *msg)
break;
case SMSG_WHO_ANSWER:
- chatWindow->chatLog("Online users: " + toString(msg->readInt32()),
+ chatWindow->chatLog("Online users: " + toString(msg->readLong()),
BY_SERVER);
break;
case 0x010c:
// Display MVP player
- msg->readInt32(); // id
+ msg->readLong(); // id
chatWindow->chatLog("MVP player", BY_SERVER);
break;
}
diff --git a/src/net/equipmenthandler.cpp b/src/net/equipmenthandler.cpp
index 01760eeb..aa372961 100644
--- a/src/net/equipmenthandler.cpp
+++ b/src/net/equipmenthandler.cpp
@@ -60,20 +60,19 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
switch (msg->getId())
{
case SMSG_PLAYER_EQUIPMENT:
- msg->readInt16(); // length
+ msg->readShort(); // length
itemCount = (msg->getLength() - 4) / 20;
for (int loop = 0; loop < itemCount; loop++)
{
- index = msg->readInt16();
- itemId = msg->readInt16();
- msg->readInt8(); // type
- msg->readInt8(); // identify flag
- msg->readInt16(); // equip type
- equipPoint = msg->readInt16();
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
- msg->skip(8); // card
+ index = msg->readShort();
+ itemId = msg->readShort();
+ msg->readByte(); // type
+ msg->readByte(); // identify flag
+ msg->readShort(); // equip type
+ equipPoint = msg->readShort();
+ msg->readByte(); // attribute
+ msg->readByte(); // refine
player_node->addInvItem(index, itemId, 1, true);
@@ -93,9 +92,9 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_EQUIP:
- index = msg->readInt16();
- equipPoint = msg->readInt16();
- type = msg->readInt8();
+ index = msg->readShort();
+ equipPoint = msg->readShort();
+ type = msg->readByte();
logger->log("Equipping: %i %i %i", index, equipPoint, type);
@@ -129,10 +128,10 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
case 0x01d7:
// Equipment related
- being = beingManager->findBeing(msg->readInt32());
- msg->readInt8(); // equip point
- itemId = msg->readInt16();
- msg->readInt16(); // item id 2
+ being = beingManager->findBeing(msg->readLong());
+ msg->readByte(); // equip point
+ itemId = msg->readShort();
+ msg->readShort(); // item id 2
if (!being)
break;
@@ -141,9 +140,9 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_UNEQUIP:
- index = msg->readInt16();
- equipPoint = msg->readInt16();
- type = msg->readInt8();
+ index = msg->readShort();
+ equipPoint = msg->readShort();
+ type = msg->readByte();
if (!type) {
chatWindow->chatLog("Unable to unequip.", BY_SERVER);
@@ -193,7 +192,7 @@ void EquipmentHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_ARROW_EQUIP:
- itemId = msg->readInt16();
+ itemId = msg->readShort();
if (itemId <= 1)
break;
diff --git a/src/net/inventoryhandler.cpp b/src/net/inventoryhandler.cpp
index 3742d327..51c71f8d 100644
--- a/src/net/inventoryhandler.cpp
+++ b/src/net/inventoryhandler.cpp
@@ -57,18 +57,16 @@ void InventoryHandler::handleMessage(MessageIn *msg)
// Only called on map load / warp. First reset all items
// to not load them twice on map change.
player_node->clearInventory();
- msg->readInt16(); // length
+ msg->readShort(); // length
number = (msg->getLength() - 4) / 18;
for (int loop = 0; loop < number; loop++)
{
- index = msg->readInt16();
- itemId = msg->readInt16();
- msg->readInt8(); // type
- msg->readInt8(); // identify flag
- amount = msg->readInt16();
- msg->skip(2); // unknown
- msg->skip(8); // card (4 shorts)
+ index = msg->readShort();
+ itemId = msg->readShort();
+ msg->readByte(); // type
+ msg->readByte(); // identify flag
+ amount = msg->readShort();
player_node->addInvItem(index, itemId, amount, false);
@@ -81,17 +79,16 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_INVENTORY_ADD:
- index = msg->readInt16();
- amount = msg->readInt16();
- itemId = msg->readInt16();
- msg->readInt8(); // identify flag
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
- msg->skip(8); // card
- equipType = msg->readInt16();
- msg->readInt8(); // type
-
- if (msg->readInt8()> 0) {
+ index = msg->readShort();
+ amount = msg->readShort();
+ itemId = msg->readShort();
+ msg->readByte(); // identify flag
+ msg->readByte(); // attribute
+ msg->readByte(); // refine
+ equipType = msg->readShort();
+ msg->readByte(); // type
+
+ if (msg->readByte()> 0) {
chatWindow->chatLog("Unable to pick up item", BY_SERVER);
} else {
player_node->addInvItem(index, itemId, amount, equipType != 0);
@@ -99,26 +96,26 @@ void InventoryHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_INVENTORY_REMOVE:
- index = msg->readInt16();
- amount = msg->readInt16();
+ index = msg->readShort();
+ amount = msg->readShort();
player_node->getInvItem(index)->increaseQuantity(-amount);
break;
case SMSG_PLAYER_INVENTORY_USE:
- index = msg->readInt16();
- msg->readInt16(); // item id
- msg->readInt32(); // id
- amount = msg->readInt16();
- msg->readInt8(); // type
+ index = msg->readShort();
+ msg->readShort(); // item id
+ msg->readLong(); // id
+ amount = msg->readShort();
+ msg->readByte(); // type
player_node->getInvItem(index)->setQuantity(amount);
break;
case SMSG_ITEM_USE_RESPONSE:
- index = msg->readInt16();
- amount = msg->readInt16();
+ index = msg->readShort();
+ amount = msg->readShort();
- if (msg->readInt8() == 0) {
+ if (msg->readByte() == 0) {
chatWindow->chatLog("Failed to use item", BY_SERVER);
} else {
player_node->getInvItem(index)->setQuantity(amount);
diff --git a/src/net/itemhandler.cpp b/src/net/itemhandler.cpp
index 567a5382..23a9fa60 100644
--- a/src/net/itemhandler.cpp
+++ b/src/net/itemhandler.cpp
@@ -50,19 +50,18 @@ void ItemHandler::handleMessage(MessageIn *msg)
{
case SMSG_ITEM_VISIBLE:
case SMSG_ITEM_DROPPED:
- id = msg->readInt32();
- itemId = msg->readInt16();
- msg->readInt8(); // identify flag
- x = msg->readInt16();
- y = msg->readInt16();
- msg->skip(4); // amount,subX,subY / subX,subY,amount
+ id = msg->readLong();
+ itemId = msg->readShort();
+ msg->readByte(); // identify flag
+ x = msg->readShort();
+ y = msg->readShort();
floorItemManager->create(id, itemId, x, y, engine->getCurrentMap());
break;
case SMSG_ITEM_REMOVE:
FloorItem *item;
- item = floorItemManager->findById(msg->readInt32());
+ item = floorItemManager->findById(msg->readLong());
if (item)
floorItemManager->destroy(item);
break;
diff --git a/src/net/loginhandler.cpp b/src/net/loginhandler.cpp
index 195e54e9..d65f7001 100644
--- a/src/net/loginhandler.cpp
+++ b/src/net/loginhandler.cpp
@@ -37,8 +37,7 @@ extern SERVER_INFO **server_info;
LoginHandler::LoginHandler()
{
static const Uint16 _messages[] = {
- 0x0069,
- 0x006a,
+ APMSG_LOGIN_RESPONSE,
0
};
handledMessages = _messages;
@@ -48,68 +47,41 @@ void LoginHandler::handleMessage(MessageIn *msg)
{
switch (msg->getId())
{
- case 0x0069:
- // Skip the length word
- msg->skip(2);
-
- n_server = (msg->getLength() - 47) / 32;
- server_info = (SERVER_INFO**)malloc(sizeof(SERVER_INFO*) * n_server);
-
- mLoginData->session_ID1 = msg->readInt32();
- mLoginData->account_ID = msg->readInt32();
- mLoginData->session_ID2 = msg->readInt32();
- msg->skip(30); // unknown
- mLoginData->sex = msg->readInt8();
-
- for (int i = 0; i < n_server; i++)
+ case APMSG_LOGIN_RESPONSE:
+ int errMsg = msg->readByte();
+ // Successful login
+ if (errMsg == ERRMSG_OK)
{
- server_info[i] = new SERVER_INFO;
-
- server_info[i]->address = msg->readInt32();
- server_info[i]->port = msg->readInt16();
- server_info[i]->name = msg->readString(20);
- server_info[i]->online_users = msg->readInt32();
- msg->skip(2); // unknown
-
- logger->log("Network: Server: %s (%s:%d)",
- server_info[i]->name.c_str(),
- iptostring(server_info[i]->address),
- server_info[i]->port);
+ unsigned char charNumber;
+ charNumber = msg->readByte();
+ printf("Account has %i characters:\n", charNumber);
+ for (unsigned int i = 0; i < charNumber; i++) {
+ printf("%i) %s\n", i, msg->readString().c_str());
+ }
+ state = CHAR_SERVER_STATE;
}
- state = CHAR_SERVER_STATE;
- break;
-
- case 0x006a:
- int loginError = msg->readInt8();
- logger->log("Login::error code: %i", loginError);
-
- switch (loginError) {
- 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 blocked by the GM Team";
- break;
- case 6:
- errorMessage = "You have been banned for 5 minutes";
- break;
- case 9:
- errorMessage = "This account is already logged in";
- break;
- default:
- errorMessage = "Unknown error";
- break;
+ // Login failed
+ else
+ {
+ switch (errMsg) {
+ case LOGIN_INVALID_VERSION:
+ errorMessage = "Client has an insufficient version number to login.";
+ break;
+ case ERRMSG_INVALID_ARGUMENT:
+ errorMessage = "Wrong username or password";
+ break;
+ case ERRMSG_FAILURE:
+ errorMessage = "Already logged in";
+ break;
+ case LOGIN_SERVER_FULL:
+ errorMessage = "Server is full";
+ break;
+ default:
+ errorMessage = "Unknown error";
+ break;
+ }
+ state = ERROR_STATE;
}
- state = ERROR_STATE;
break;
}
}
diff --git a/src/net/maploginhandler.cpp b/src/net/maploginhandler.cpp
index 0afc8357..2a174c58 100644
--- a/src/net/maploginhandler.cpp
+++ b/src/net/maploginhandler.cpp
@@ -47,9 +47,7 @@ void MapLoginHandler::handleMessage(MessageIn *msg)
switch (msg->getId())
{
case SMSG_LOGIN_SUCCESS:
- msg->readInt32(); // server tick
- msg->readCoordinates(player_node->mX, player_node->mY, direction);
- msg->skip(2); // unknown
+ msg->readLong(); // server tick
logger->log("Protocol: Player start position: (%d, %d), Direction: %d",
player_node->mX, player_node->mY, direction);
state = GAME_STATE;
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index bbc0a44c..7e85a813 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -1,5 +1,5 @@
/*
- * The Mana World
+ * The Mana World Server
* Copyright 2004 The Mana World Development Team
*
* This file is part of The Mana World.
@@ -23,14 +23,11 @@
#include "messagein.h"
-#include <cassert>
-#include <SDL.h>
-#include <SDL_endian.h>
+#include <string>
-#define MAKEWORD(low,high) \
- ((unsigned short)(((unsigned char)(low)) | \
- ((unsigned short)((unsigned char)(high))) << 8))
+#include <enet/enet.h>
+#include "packet.h"
MessageIn::MessageIn(const char *data, unsigned int length):
mData(data),
@@ -38,157 +35,67 @@ MessageIn::MessageIn(const char *data, unsigned int length):
mPos(0)
{
// Read the message ID
- mId = readInt16();
+ mId = readShort();
}
-Sint8
-MessageIn::readInt8()
+MessageIn::~MessageIn()
{
- assert(mPos < mLength);
- return mData[mPos++];
}
-Sint16
-MessageIn::readInt16()
+char MessageIn::readByte()
{
- assert(mPos + 2 <= mLength);
- mPos += 2;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap16(*(Sint16*)(mData + (mPos - 2)));
-#else
- return (*(Sint16*)(mData + (mPos - 2)));
-#endif
-}
-
-Sint32
-MessageIn::readInt32()
-{
- assert(mPos + 4 <= mLength);
- mPos += 4;
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap32(*(Sint32*)(mData + (mPos - 4)));
-#else
- return (*(Sint32*)(mData + (mPos - 4)));
-#endif
-}
-
-void
-MessageIn::readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction)
-{
- assert(mPos + 3 <= mLength);
-
- const char *data = mData + mPos;
- Sint16 temp;
-
- temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff);
- x = temp >> 6;
- temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f);
- y = temp >> 4;
-
- direction = data[2] & 0x000f;
-
- // Translate from eAthena format
- switch (direction)
+ char value = -1;
+ if (mPos < mLength)
{
- case 0:
- direction = 1;
- break;
- case 1:
- direction = 3;
- break;
- case 2:
- direction = 2;
- break;
- case 3:
- direction = 6;
- break;
- case 4:
- direction = 4;
- break;
- case 5:
- direction = 12;
- break;
- case 6:
- direction = 8;
- break;
- case 7:
- direction = 9;
- break;
- default:
- // OOPSIE! Impossible or unknown
- direction = 0;
+ value = mData[mPos];
}
-
- mPos += 3;
+ mPos += 1;
+ return value;
}
-void
-MessageIn::readCoordinatePair(Uint16 &srcX, Uint16 &srcY,
- Uint16 &dstX, Uint16 &dstY)
+short MessageIn::readShort()
{
- assert(mPos + 5 <= mLength);
-
- const char *data = mData + mPos;
- Sint16 temp;
-
- temp = MAKEWORD(data[3], data[2] & 0x000f);
- dstX = temp >> 2;
-
- dstY = MAKEWORD(data[4], data[3] & 0x0003);
-
- temp = MAKEWORD(data[1], data[0]);
- srcX = temp >> 6;
-
- temp = MAKEWORD(data[2], data[1] & 0x003f);
- srcY = temp >> 4;
-
- mPos += 5;
+ short value = -1;
+ if (mPos + 2 <= mLength)
+ {
+ uint16_t t;
+ memcpy(&t, mData + mPos, 2);
+ value = ENET_NET_TO_HOST_16(t);
+ }
+ mPos += 2;
+ return value;
}
-void
-MessageIn::skip(unsigned int length)
+long MessageIn::readLong()
{
- assert(mPos + length <= mLength);
- mPos += length;
+ long value = -1;
+ if (mPos + 4 <= mLength)
+ {
+ uint32_t t;
+ memcpy(&t, mData + mPos, 4);
+ value = ENET_NET_TO_HOST_32(t);
+ }
+ mPos += 4;
+ return value;
}
-std::string
-MessageIn::readString(int length)
+std::string MessageIn::readString(int length)
{
// Get string length
if (length < 0) {
- length = readInt16();
+ length = readShort();
}
- // Make sure the string isn't erroneous
+ // Make sure the string isn't erroneus
if (length < 0 || mPos + length > mLength) {
mPos = mLength + 1;
return "";
}
- // Read the string
- char const *stringBeg = mData + mPos;
- char const *stringEnd = (char const *)memchr(stringBeg, '\0', length);
- std::string readString(stringBeg,
- stringEnd ? stringEnd - stringBeg : length);
+ // Read the string
+ char const *stringBeg = mData + mPos,
+ *stringEnd = (char const *)memchr(stringBeg, '\0', length);
+ std::string readString(stringBeg, stringEnd ? stringEnd - stringBeg : length);
mPos += length;
return readString;
}
-
-Sint8& operator<<(Sint8 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt8();
- return lhs;
-}
-
-Sint16& operator<<(Sint16 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt16();
- return lhs;
-}
-
-Sint32& operator<<(Sint32 &lhs, MessageIn &msg)
-{
- lhs = msg.readInt32();
- return lhs;
-}
diff --git a/src/net/messagein.h b/src/net/messagein.h
index d97cd8b6..d5a7593f 100644
--- a/src/net/messagein.h
+++ b/src/net/messagein.h
@@ -1,5 +1,5 @@
/*
- * The Mana World
+ * The Mana World Server
* Copyright 2004 The Mana World Development Team
*
* This file is part of The Mana World.
@@ -21,21 +21,16 @@
* $Id$
*/
-#ifndef _TMW_MESSAGEIN_
-#define _TMW_MESSAGEIN_
+#ifndef _TMWSERV_MESSAGEIN_H_
+#define _TMWSERV_MESSAGEIN_H_
#include <string>
-#include <SDL_types.h>
/**
* Used for parsing an incoming message.
*/
class MessageIn
{
- friend Sint8& operator<<(Sint8 &lhs, MessageIn &msg);
- friend Sint16& operator<<(Sint16 &lhs, MessageIn &msg);
- friend Sint32& operator<<(Sint32 &lhs, MessageIn &msg);
-
public:
/**
* Constructor.
@@ -43,55 +38,40 @@ class MessageIn
MessageIn(const char *data, unsigned int length);
/**
- * Returns the message ID.
- */
- short
- getId() { return mId; }
-
- /**
- * Returns the message length.
- */
- unsigned int
- getLength() { return mLength; }
-
- Sint8 readInt8(); /**< Reads a byte. */
- Sint16 readInt16(); /**< Reads a short. */
- Sint32 readInt32(); /**< Reads a long. */
-
- /**
- * Reads a special 3 byte block used by eAthena, containing x and y
- * coordinates and direction.
+ * Destructor.
*/
- void
- readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction);
+ ~MessageIn();
- /**
- * Reads a special 5 byte block used by eAthena, containing a source
- * and destination coordinate pair.
- */
- void
- readCoordinatePair(Uint16 &srcX, Uint16 &srcY,
- Uint16 &dstX, Uint16 &dstY);
+ short getId() { return mId; } /**< Returns the message ID. */
- /**
- * Skips a given number of bytes.
- */
- void
- skip(unsigned int length);
+ char readByte(); /**< Reads a byte. */
+ short readShort(); /**< Reads a short. */
+ long readLong(); /**< Reads a long. */
/**
* Reads a string. If a length is not given (-1), it is assumed
* that the length of the string is stored in a short at the
* start of the string.
*/
- std::string
- readString(int length = -1);
+ std::string readString(int length = -1);
+
+ /**
+ * Returns the message length.
+ */
+ unsigned int
+ getLength() { return mLength; }
private:
const char* mData; /**< The message data. */
unsigned int mLength; /**< The length of the data. */
- unsigned int mPos; /**< The position in the data. */
short mId; /**< The message ID. */
+
+ /**
+ * Actual position in the packet. From 0 to packet->length.
+ * A value bigger than packet->length means EOP was reached when
+ * reading it.
+ */
+ unsigned int mPos;
};
#endif
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index f6ed5de6..5e8a5d72 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -1,5 +1,5 @@
/*
- * The Mana World
+ * The Mana World Server
* Copyright 2004 The Mana World Development Team
*
* This file is part of The Mana World.
@@ -24,93 +24,93 @@
#include "messageout.h"
#include <string>
-#include <SDL.h>
-#include <SDL_endian.h>
-#include "network.h"
+#include <enet/enet.h>
+
#include "packet.h"
-MessageOut::MessageOut(Network *network):
- mNetwork(network),
+MessageOut::MessageOut():
mData(0),
mDataSize(0),
mPos(0)
{
- mData = mNetwork->mOutBuffer + mNetwork->mOutSize;
}
-void MessageOut::writeInt8(Sint8 value)
+MessageOut::~MessageOut()
{
- mData[mPos] = value;
- mPos += sizeof(Sint8);
- mNetwork->mOutSize+= sizeof(Sint8);
+ if (mData) {
+ free(mData);
+ }
+}
+
+void
+MessageOut::expand(size_t bytes)
+{
+ mData = (char*)realloc(mData, bytes);
+ mDataSize = bytes;
}
-void MessageOut::writeInt16(Sint16 value)
+void
+MessageOut::writeByte(char value)
{
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- (*(Sint16 *)(mData + mPos)) = SDL_Swap16(value);
-#else
- (*(Sint16 *)(mData + mPos)) = value;
-#endif
- mPos += sizeof(Sint16);
- mNetwork->mOutSize += sizeof(Sint16);
+ expand(mPos + 1);
+ mData[mPos] = value;
+ mPos += 1;
}
-void MessageOut::writeInt32(Sint32 value)
+void MessageOut::writeShort(short value)
{
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- (*(Sint32 *)(mData + mPos)) = SDL_Swap32(value);
-#else
- (*(Sint32 *)(mData + mPos)) = value;
-#endif
- mPos += sizeof(Sint32);
- mNetwork->mOutSize += sizeof(Sint32);
+ expand(mPos + 2);
+ uint16_t t = ENET_HOST_TO_NET_16(value);
+ memcpy(mData + mPos, &t, 2);
+ mPos += 2;
}
-void MessageOut::writeString(const std::string &string, int length)
+void
+MessageOut::writeLong(long value)
{
- std::string toWrite = string;
+ expand(mPos + 4);
+ uint32_t t = ENET_HOST_TO_NET_32(value);
+ memcpy(mData + mPos, &t, 4);
+ mPos += 4;
+}
+void
+MessageOut::writeString(const std::string &string, int length)
+{
+ int stringLength = string.length();
if (length < 0)
{
// Write the length at the start if not fixed
- writeInt16(string.length());
+ writeShort(stringLength);
+ length = stringLength;
}
- else
+ else if (length < stringLength)
{
// Make sure the length of the string is no longer than specified
- toWrite = string.substr(0, length);
+ stringLength = length;
}
+ expand(mPos + length);
// Write the actual string
- memcpy(&mData[mPos], (void*)toWrite.c_str(), toWrite.length());
- mPos += toWrite.length();
- mNetwork->mOutSize += toWrite.length();
+ memcpy(mData + mPos, string.c_str(), stringLength);
// Pad remaining space with zeros
- if (length > (int)toWrite.length())
+ if (length > stringLength)
{
- memset(&mData[mPos], '\0', length - toWrite.length());
- mPos += length - toWrite.length();
- mNetwork->mOutSize += length - toWrite.length();
+ memset(mData + mPos + stringLength, '\0', length - stringLength);
}
+ mPos += length;
}
-MessageOut& operator<<(MessageOut &msg, const Sint8 &rhs)
-{
- msg.writeInt8(rhs);
- return msg;
-}
-
-MessageOut& operator<<(MessageOut &msg, const Sint16 &rhs)
+char*
+MessageOut::getData()
{
- msg.writeInt16(rhs);
- return msg;
+ return mData;
}
-MessageOut& operator<<(MessageOut &msg, const Sint32 &rhs)
+unsigned int
+MessageOut::getDataSize()
{
- msg.writeInt32(rhs);
- return msg;
+ return mDataSize;
}
diff --git a/src/net/messageout.h b/src/net/messageout.h
index f6468adb..8431d887 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -1,5 +1,5 @@
/*
- * The Mana World
+ * The Mana World Server
* Copyright 2004 The Mana World Development Team
*
* This file is part of The Mana World.
@@ -21,32 +21,30 @@
* $Id$
*/
-#ifndef _TMW_MESSAGEOUT_
-#define _TMW_MESSAGEOUT_
+#ifndef _TMWSERV_MESSAGEOUT_H_
+#define _TMWSERV_MESSAGEOUT_H_
#include <iosfwd>
-#include <SDL_types.h>
-
-class Network;
/**
* Used for building an outgoing message.
*/
class MessageOut
{
- friend MessageOut& operator<<(MessageOut &msg, const Sint8 &rhs);
- friend MessageOut& operator<<(MessageOut &msg, const Sint16 &rhs);
- friend MessageOut& operator<<(MessageOut &msg, const Sint32 &rhs);
-
public:
/**
* Constructor.
*/
- MessageOut(Network *network);
+ MessageOut();
- void writeInt8(Sint8 value); /**< Writes a byte. */
- void writeInt16(Sint16 value); /**< Writes a short. */
- void writeInt32(Sint32 value); /**< Writes a long. */
+ /**
+ * Destructor.
+ */
+ ~MessageOut();
+
+ void writeByte(char value); /**< Writes a byte. */
+ void writeShort(short value); /**< Writes a short. */
+ void writeLong(long value); /**< Writes a long. */
/**
* Writes a string. If a fixed length is not given (-1), it is stored
@@ -54,8 +52,25 @@ class MessageOut
*/
void writeString(const std::string &string, int length = -1);
+ /**
+ * Returns the content of the message.
+ */
+ char *getData();
+
+ /**
+ * Returns the length of the data.
+ */
+ unsigned int getDataSize();
+
private:
- Network *mNetwork;
+ /**
+ * Expand the packet data to be able to hold more data.
+ *
+ * NOTE: For performance enhancements this method could allocate extra
+ * memory in advance instead of expanding size every time more data is
+ * added.
+ */
+ void expand(size_t size);
char *mData; /**< Data building up. */
unsigned int mDataSize; /**< Size of data. */
diff --git a/src/net/network.cpp b/src/net/network.cpp
index bd0e2444..8278e266 100644
--- a/src/net/network.cpp
+++ b/src/net/network.cpp
@@ -25,82 +25,15 @@
#include "messagehandler.h"
#include "messagein.h"
+#include "messageout.h"
#include "../log.h"
-/** Warning: buffers and other variables are shared,
- so there can be only one connection active at a time */
-
-short packet_lengths[] = {
- 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-// #0x0040
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
- 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
-// #0x0080
- 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
- 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
- 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
- 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
-// #0x00C0
- 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27,
- 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
- 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
- 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
-// #0x0100
- 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
- 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
- 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
- 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
-// #0x0140
- 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
- 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
- -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
- 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
-// #0x0180
- 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
- 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6,
- 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
- 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
-// #0x01C0
- 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28,
- 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
- 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1,
- -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10,
-// #0x200
- 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-const unsigned int BUFFER_SIZE = 65536;
-
-int networkThread(void *data)
-{
- Network *network = static_cast<Network*>(data);
-
- if (!network->realConnect())
- return -1;
-
- network->receive();
-
- return 0;
-}
-
Network::Network():
- mSocket(0),
+ mClient(0), mServer(0),
mAddress(), mPort(0),
- mInBuffer(new char[BUFFER_SIZE]),
- mOutBuffer(new char[BUFFER_SIZE]),
- mInSize(0), mOutSize(0),
- mToSkip(0),
- mState(IDLE),
- mWorkerThread(0)
+ mState(IDLE)
{
- mMutex = SDL_CreateMutex();
}
Network::~Network()
@@ -109,11 +42,6 @@ Network::~Network()
if (mState != IDLE && mState != ERROR)
disconnect();
-
- SDL_DestroyMutex(mMutex);
-
- delete mInBuffer;
- delete mOutBuffer;
}
bool Network::connect(const std::string &address, short port)
@@ -136,16 +64,26 @@ bool Network::connect(const std::string &address, short port)
mAddress = address;
mPort = port;
- // Reset to sane values
- mOutSize = 0;
- mInSize = 0;
- mToSkip = 0;
-
mState = CONNECTING;
- mWorkerThread = SDL_CreateThread(networkThread, this);
- if (!mWorkerThread)
+
+ mClient = enet_host_create (0, 1, 0, 0);
+
+ if (!mClient)
{
- logger->log("Unable to create network worker thread");
+ logger->error("An error occurred while trying to create an ENet client.");
+ }
+
+ ENetAddress enetAddress;
+
+ enet_address_set_host(&enetAddress, address.c_str());
+ enetAddress.port = port;
+
+ // Initiate the connection, allocating channel 0.
+ mServer = enet_host_connect(mClient, &enetAddress, 1);
+
+ if (mServer == 0)
+ {
+ logger->log("Unable to initiate connection to the server.");
mState = ERROR;
return false;
}
@@ -157,16 +95,12 @@ void Network::disconnect()
{
mState = IDLE;
- if (mWorkerThread)
- {
- SDL_WaitThread(mWorkerThread, NULL);
- mWorkerThread = NULL;
- }
-
- if (mSocket)
+ if (mServer)
{
- SDLNet_TCP_Close(mSocket);
- mSocket = 0;
+ enet_peer_disconnect(mServer, 0);
+ enet_host_flush(mClient);
+ enet_peer_reset(mServer);
+ mServer = 0;
}
}
@@ -205,220 +139,84 @@ void Network::clearHandlers()
void Network::dispatchMessages()
{
- while (messageReady())
+ while (!mIncomingPackets.empty())
{
- MessageIn msg = getNextMessage();
+ ENetPacket *packet = mIncomingPackets.front();
+ MessageIn msg((const char *)packet->data, packet->dataLength);
MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());
+ printf("Received packet: %x\n", msg.getId());
+
if (iter != mMessageHandlers.end())
iter->second->handleMessage(&msg);
else
logger->log("Unhandled packet: %x", msg.getId());
-
- skip(msg.getLength());
+ mIncomingPackets.pop();
+ // Clean up the packet now that we're done using it.
+ enet_packet_destroy(packet);
}
}
void Network::flush()
{
- if (!mOutSize || mState != CONNECTED)
- return;
-
- int ret;
-
-
- SDL_mutexP(mMutex);
- ret = SDLNet_TCP_Send(mSocket, mOutBuffer, mOutSize);
- if (ret < (int)mOutSize)
- {
- logger->log("Error in SDLNet_TCP_Send(): %s", SDLNet_GetError());
- mState = ERROR;
- }
- mOutSize = 0;
- SDL_mutexV(mMutex);
-}
-
-void Network::skip(int len)
-{
- SDL_mutexP(mMutex);
- mToSkip += len;
- if (!mInSize)
+ if (mState == IDLE || mState == NET_ERROR)
{
- SDL_mutexV(mMutex);
return;
}
- if (mInSize >= mToSkip)
- {
- mInSize -= mToSkip;
- memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
- mToSkip = 0;
- }
- else
- {
- mToSkip -= mInSize;
- mInSize = 0;
- }
- SDL_mutexV(mMutex);
-}
+ ENetEvent event;
-bool Network::messageReady()
-{
- int len = -1;
-
- SDL_mutexP(mMutex);
- if (mInSize >= 2)
+ // Wait up to 10 milliseconds for an event.
+ while (enet_host_service(mClient, &event, 10) > 0)
{
- len = packet_lengths[readWord(0)];
-
- if (len == -1 && mInSize > 4)
- len = readWord(2);
-
- }
-
- bool ret = (mInSize >= static_cast<unsigned int>(len));
- SDL_mutexV(mMutex);
-
- return ret;
-}
+ switch (event.type)
+ {
+ case ENET_EVENT_TYPE_CONNECT:
+ mState = CONNECTED;
+ // Store any relevant server information here.
+ event.peer->data = 0;
+ break;
-MessageIn Network::getNextMessage()
-{
- while (!messageReady())
- {
- if (mState == ERROR)
- break;
+ case ENET_EVENT_TYPE_RECEIVE:
+ mIncomingPackets.push(event.packet);
+ break;
+ case ENET_EVENT_TYPE_DISCONNECT:
+ mState = IDLE;
+ printf("Disconnected\n");
+ // Reset the server information.
+ event.peer->data = 0;
+ break;
+ default:
+ logger->log("Unhandled enet event.");
+ break;
+ }
}
- SDL_mutexP(mMutex);
- int msgId = readWord(0);
- int len = packet_lengths[msgId];
-
- if (len == -1)
- len = readWord(2);
-
-#ifdef DEBUG
- printf("Received packet 0x%x of length %d\n", msgId, length);
-#endif
-
- MessageIn msg(mInBuffer, len);
- SDL_mutexV(mMutex);
-
- return msg;
-}
-
-bool Network::realConnect()
-{
- IPaddress ipAddress;
-
- if (SDLNet_ResolveHost(&ipAddress, mAddress.c_str(), mPort) == -1)
+ // If connected, manage incoming and outcoming packets
+ if (isConnected())
{
- logger->log("Error in SDLNet_ResolveHost(): %s", SDLNet_GetError());
- mState = ERROR;
- return false;
- }
-
- mState = CONNECTING;
+ while (isConnected() && !mOutgoingPackets.empty())
+ {
+ ENetPacket *packet = mOutgoingPackets.front();
+ enet_peer_send(mServer, 0, packet);
+ mOutgoingPackets.pop();
+ }
- mSocket = SDLNet_TCP_Open(&ipAddress);
- if (!mSocket)
- {
- logger->log("Error in SDLNet_TCP_Open(): %s", SDLNet_GetError());
- mState = ERROR;
- return false;
+ dispatchMessages();
}
-
- logger->log("Network::Started session with %s:%i",
- iptostring(ipAddress.host), ipAddress.port);
-
- mState = CONNECTED;
-
- return true;
}
-void Network::receive()
+void Network::send(MessageOut *msg)
{
- SDLNet_SocketSet set;
-
- if (!(set = SDLNet_AllocSocketSet(1)))
+ if (mState == IDLE || mState == NET_ERROR)
{
- logger->log("Error in SDLNet_AllocSocketSet(): %s", SDLNet_GetError());
- mState = ERROR;
return;
}
- if (SDLNet_TCP_AddSocket(set, mSocket) == -1)
- {
- logger->log("Error in SDLNet_AddSocket(): %s", SDLNet_GetError());
- mState = ERROR;
- }
-
- while (mState == CONNECTED)
- {
- // TODO Try to get this to block all the time while still being able
- // to escape the loop
- int numReady = SDLNet_CheckSockets(set, ((Uint32)500));
- int ret;
- switch (numReady)
- {
- case -1:
- logger->log("Error: SDLNet_CheckSockets");
- // FALLTHROUGH
- case 0:
- break;
-
- case 1:
- // Receive data from the socket
- SDL_mutexP(mMutex);
- ret = SDLNet_TCP_Recv(mSocket, mInBuffer + mInSize, BUFFER_SIZE - mInSize);
-
- if (!ret)
- {
- // We got disconnected
- mState = IDLE;
- logger->log("Disconnected.");
- }
- else if (ret < 0)
- {
- logger->log("Error in SDLNet_TCP_Recv(): %s", SDLNet_GetError());
- mState = ERROR;
- }
- else {
- mInSize += ret;
- if (mToSkip)
- {
- if (mInSize >= mToSkip)
- {
- mInSize -= mToSkip;
- memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
- mToSkip = 0;
- }
- else
- {
- mToSkip -= mInSize;
- mInSize = 0;
- }
- }
- }
- SDL_mutexV(mMutex);
- break;
-
- default:
- // more than one socket is ready..
- // this should not happen since we only listen once socket.
- logger->log("Error in SDLNet_TCP_Recv(), %d sockets are ready : %s", numReady, SDLNet_GetError());
- mState = ERROR;
- break;
- }
- }
-
- if (SDLNet_TCP_DelSocket(set, mSocket) == -1)
- {
- logger->log("Error in SDLNet_DelSocket(): %s", SDLNet_GetError());
- }
-
- SDLNet_FreeSocketSet(set);
+ ENetPacket *packet = enet_packet_create(msg->getData(),
+ msg->getDataSize() + 1, ENET_PACKET_FLAG_RELIABLE);
+ mOutgoingPackets.push(packet);
}
char *iptostring(int address)
@@ -433,12 +231,3 @@ char *iptostring(int address)
return asciiIP;
}
-
-Uint16 Network::readWord(int pos)
-{
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap16((*(Uint16*)(mInBuffer+(pos))));
-#else
- return (*(Uint16*)(mInBuffer+(pos)));
-#endif
-}
diff --git a/src/net/network.h b/src/net/network.h
index f4637f73..50ee9af7 100644
--- a/src/net/network.h
+++ b/src/net/network.h
@@ -25,19 +25,22 @@
#define _TMW_NETWORK_
#include <map>
-#include <SDL_net.h>
-#include <SDL_thread.h>
+#include <queue>
#include <string>
+#include <guichan.hpp>
+
+#include <enet/enet.h>
+
class MessageHandler;
class MessageIn;
+class MessageOut;
class Network;
class Network
{
public:
- friend int networkThread(void *data);
friend class MessageOut;
Network();
@@ -53,46 +56,39 @@ class Network
int getState() const { return mState; }
bool isConnected() const { return mState == CONNECTED; }
- int getInSize() const { return mInSize; }
-
- void skip(int len);
-
- bool messageReady();
- MessageIn getNextMessage();
-
void dispatchMessages();
void flush();
- enum {
+ void send(MessageOut *msg);
+
+ enum State {
IDLE,
CONNECTED,
CONNECTING,
DATA,
- ERROR
+ NET_ERROR
};
+ ENetHost *mClient;
+ ENetPeer *mServer;
+
protected:
- Uint16 readWord(int pos);
- TCPsocket mSocket;
std::string mAddress;
short mPort;
- char *mInBuffer, *mOutBuffer;
- unsigned int mInSize, mOutSize;
-
unsigned int mToSkip;
int mState;
- SDL_Thread *mWorkerThread;
- SDL_mutex *mMutex;
-
- typedef std::map<Uint16, MessageHandler*> MessageHandlers;
+ typedef std::map<unsigned short, MessageHandler*> MessageHandlers;
typedef MessageHandlers::iterator MessageHandlerIterator;
MessageHandlers mMessageHandlers;
+ std::queue<ENetPacket *> mOutgoingPackets;
+ std::queue<ENetPacket *> mIncomingPackets;
+
bool realConnect();
void receive();
};
diff --git a/src/net/npchandler.cpp b/src/net/npchandler.cpp
index a803710e..62355180 100644
--- a/src/net/npchandler.cpp
+++ b/src/net/npchandler.cpp
@@ -52,15 +52,15 @@ void NPCHandler::handleMessage(MessageIn *msg)
switch (msg->getId())
{
case SMSG_NPC_CHOICE:
- msg->readInt16(); // length
- current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readInt32()));
+ msg->readShort(); // length
+ current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readLong()));
npcListDialog->parseItems(msg->readString(msg->getLength() - 8));
npcListDialog->setVisible(true);
break;
case SMSG_NPC_MESSAGE:
- msg->readInt16(); // length
- current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readInt32()));
+ msg->readShort(); // length
+ current_npc = dynamic_cast<NPC*>(beingManager->findBeing(msg->readLong()));
npcTextDialog->addText(msg->readString(msg->getLength() - 8));
npcListDialog->setVisible(false);
npcTextDialog->setVisible(true);
diff --git a/src/net/playerhandler.cpp b/src/net/playerhandler.cpp
index 94788333..5453eae4 100644
--- a/src/net/playerhandler.cpp
+++ b/src/net/playerhandler.cpp
@@ -94,8 +94,8 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_WARP:
{
std::string mapPath = msg->readString(16);
- Uint16 x = msg->readInt16();
- Uint16 y = msg->readInt16();
+ Uint16 x = msg->readShort();
+ Uint16 y = msg->readShort();
logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);
@@ -114,13 +114,13 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_STAT_UPDATE_1:
{
- Sint16 type = msg->readInt16();
- Uint32 value = msg->readInt32();
+ Sint16 type = msg->readShort();
+ Uint32 value = msg->readLong();
switch (type)
{
//case 0x0000:
- // player_node->setWalkSpeed(msg->readInt32());
+ // player_node->setWalkSpeed(msg->readLong());
// break;
case 0x0005: player_node->mHp = value; break;
case 0x0006: player_node->mMaxHp = value; break;
@@ -169,30 +169,30 @@ void PlayerHandler::handleMessage(MessageIn *msg)
break;
case SMSG_PLAYER_STAT_UPDATE_2:
- switch (msg->readInt16()) {
+ switch (msg->readShort()) {
case 0x0001:
- player_node->mXp = msg->readInt32();
+ player_node->mXp = msg->readLong();
break;
case 0x0002:
- player_node->mJobXp = msg->readInt32();
+ player_node->mJobXp = msg->readLong();
break;
case 0x0014:
- player_node->mGp = msg->readInt32();
+ player_node->mGp = msg->readLong();
break;
case 0x0016:
- player_node->mXpForNextLevel = msg->readInt32();
+ player_node->mXpForNextLevel = msg->readLong();
break;
case 0x0017:
- player_node->mJobXpForNextLevel = msg->readInt32();
+ player_node->mJobXpForNextLevel = msg->readLong();
break;
}
break;
case SMSG_PLAYER_STAT_UPDATE_3:
{
- Sint32 type = msg->readInt32();
- Sint32 base = msg->readInt32();
- Sint32 bonus = msg->readInt32();
+ Sint32 type = msg->readLong();
+ Sint32 base = msg->readLong();
+ Sint32 bonus = msg->readLong();
Sint32 total = base + bonus;
switch (type) {
@@ -214,9 +214,9 @@ void PlayerHandler::handleMessage(MessageIn *msg)
case SMSG_PLAYER_STAT_UPDATE_4:
{
- Sint16 type = msg->readInt16();
- Sint8 fail = msg->readInt8();
- Sint8 value = msg->readInt8();
+ Sint16 type = msg->readShort();
+ Sint8 fail = msg->readByte();
+ Sint8 value = msg->readByte();
if (fail != 1)
break;
@@ -240,60 +240,60 @@ void PlayerHandler::handleMessage(MessageIn *msg)
// Updates stats and status points
case SMSG_PLAYER_STAT_UPDATE_5:
- player_node->mStatsPointsToAttribute = msg->readInt16();
- player_node->mAttr[LocalPlayer::STR] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::STR] = msg->readInt8();
- player_node->mAttr[LocalPlayer::AGI] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::AGI] = msg->readInt8();
- player_node->mAttr[LocalPlayer::VIT] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::VIT] = msg->readInt8();
- player_node->mAttr[LocalPlayer::INT] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::INT] = msg->readInt8();
- player_node->mAttr[LocalPlayer::DEX] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::DEX] = msg->readInt8();
- player_node->mAttr[LocalPlayer::LUK] = msg->readInt8();
- player_node->mAttrUp[LocalPlayer::LUK] = msg->readInt8();
- player_node->ATK = msg->readInt16(); // ATK
- player_node->ATK_BONUS = msg->readInt16(); // ATK bonus
- player_node->MATK = msg->readInt16(); // MATK max
- player_node->MATK_BONUS = msg->readInt16(); // MATK min
- player_node->DEF = msg->readInt16(); // DEF
- player_node->DEF_BONUS = msg->readInt16(); // DEF bonus
- player_node->MDEF = msg->readInt16(); // MDEF
- player_node->MDEF_BONUS = msg->readInt16(); // MDEF bonus
- player_node->HIT = msg->readInt16(); // HIT
- player_node->FLEE = msg->readInt16(); // FLEE
- player_node->FLEE_BONUS = msg->readInt16(); // FLEE bonus
- msg->readInt16(); // critical
- msg->readInt16(); // unknown
+ player_node->mStatsPointsToAttribute = msg->readShort();
+ player_node->mAttr[LocalPlayer::STR] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::STR] = msg->readByte();
+ player_node->mAttr[LocalPlayer::AGI] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::AGI] = msg->readByte();
+ player_node->mAttr[LocalPlayer::VIT] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::VIT] = msg->readByte();
+ player_node->mAttr[LocalPlayer::INT] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::INT] = msg->readByte();
+ player_node->mAttr[LocalPlayer::DEX] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::DEX] = msg->readByte();
+ player_node->mAttr[LocalPlayer::LUK] = msg->readByte();
+ player_node->mAttrUp[LocalPlayer::LUK] = msg->readByte();
+ player_node->ATK = msg->readShort(); // ATK
+ player_node->ATK_BONUS = msg->readShort(); // ATK bonus
+ player_node->MATK = msg->readShort(); // MATK max
+ player_node->MATK_BONUS = msg->readShort(); // MATK min
+ player_node->DEF = msg->readShort(); // DEF
+ player_node->DEF_BONUS = msg->readShort(); // DEF bonus
+ player_node->MDEF = msg->readShort(); // MDEF
+ player_node->MDEF_BONUS = msg->readShort(); // MDEF bonus
+ player_node->HIT = msg->readShort(); // HIT
+ player_node->FLEE = msg->readShort(); // FLEE
+ player_node->FLEE_BONUS = msg->readShort(); // FLEE bonus
+ msg->readShort(); // critical
+ msg->readShort(); // unknown
break;
case SMSG_PLAYER_STAT_UPDATE_6:
- switch (msg->readInt16()) {
+ switch (msg->readShort()) {
case 0x0020:
- player_node->mAttrUp[LocalPlayer::STR] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::STR] = msg->readByte();
break;
case 0x0021:
- player_node->mAttrUp[LocalPlayer::AGI] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::AGI] = msg->readByte();
break;
case 0x0022:
- player_node->mAttrUp[LocalPlayer::VIT] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::VIT] = msg->readByte();
break;
case 0x0023:
- player_node->mAttrUp[LocalPlayer::INT] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::INT] = msg->readByte();
break;
case 0x0024:
- player_node->mAttrUp[LocalPlayer::DEX] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::DEX] = msg->readByte();
break;
case 0x0025:
- player_node->mAttrUp[LocalPlayer::LUK] = msg->readInt8();
+ player_node->mAttrUp[LocalPlayer::LUK] = msg->readByte();
break;
}
break;
case SMSG_PLAYER_ARROW_MESSAGE:
{
- Sint16 type = msg->readInt16();
+ Sint16 type = msg->readShort();
switch (type) {
case 0:
@@ -309,7 +309,7 @@ void PlayerHandler::handleMessage(MessageIn *msg)
//Stop walking
//case 0x0088: // Disabled because giving some problems
- //if (being = beingManager->findBeing(readInt32(2))) {
+ //if (being = beingManager->findBeing(readLong(2))) {
// if (being->getId() != player_node->getId()) {
// being->action = STAND;
// being->mFrame = 0;
diff --git a/src/net/protocol.h b/src/net/protocol.h
index 72b459ed..0db4dfb0 100644
--- a/src/net/protocol.h
+++ b/src/net/protocol.h
@@ -104,6 +104,103 @@
#define CMSG_PLAYER_EQUIP 0x00a9
#define CMSG_PLAYER_UNEQUIP 0x00ab
+/**
+ * Enumerated type for communicated messages
+ * - PAMSG_*: from client to account server
+ * - APMSG_*: from account server to client
+ * - PCMSG_*: from client to chat server
+ * - CPMSG_*: from chat server to client
+ * - PGMSG_*: from client to game server
+ * - GPMSG_*: from game server to client
+ * Components: B byte, W word, D double word, S variable-size string
+ */
+enum {
+ // Login/Register
+ PAMSG_REGISTER = 0x0000, // S version, S username, S password, S email
+ APMSG_REGISTER_RESPONSE = 0x0002, // B error
+ PAMSG_UNREGISTER = 0x0003, // -
+ APMSG_UNREGISTER_RESPONSE = 0x0004, // B error
+ PAMSG_LOGIN = 0x0010, // S version, S username, S password
+ APMSG_LOGIN_RESPONSE = 0x0012, // B error
+ PAMSG_LOGOUT = 0x0013, // -
+ APMSG_LOGOUT_RESPONSE = 0x0014, // B error
+ PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, W*6 stats
+ APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error
+ PAMSG_CHAR_DELETE = 0x0022, // B index
+ APMSG_CHAR_DELETE_RESPONSE = 0x0023, // B error
+ PAMSG_CHAR_LIST = 0x0024, // -
+ APMSG_CHAR_LIST_RESPONSE = 0x0025, // B number, { B index, S name, B gender, B hair style, B hair color, B level, W money, W*6 stats, S mapname, W*2 position }*
+ PAMSG_CHAR_SELECT = 0x0026, // B index
+ APMSG_CHAR_SELECT_RESPONSE = 0x0027, // B error, S mapname, W*2 position
+ PAMSG_EMAIL_CHANGE = 0x0030, // S email
+ APMSG_EMAIL_CHANGE_RESPONSE = 0x0031, // B error
+ PAMSG_EMAIL_GET = 0x0032, // -
+ APMSG_EMAIL_GET_RESPONSE = 0x0033, // B error, S email
+ PAMSG_PASSWORD_CHANGE = 0x0034, // S old password, S new password
+ APMSG_PASSWORD_CHANGE_RESPONSE = 0x0035, // B error
+ PAMSG_ENTER_WORLD = 0x0040, // -
+ APMSG_ENTER_WORLD_RESPONSE = 0x0041, // B error, S address, W port, B*32 token
+ PAMSG_ENTER_CHAT = 0x0042, // -
+ APMSG_ENTER_CHAT_RESPONSE = 0x0043, // B error, S address, W port, B*32 token
+ PGMSG_CONNECT = 0x0050, // B*32 token
+ GPMSG_CONNECT_RESPONSE = 0x0051, // B error
+ PCMSG_CONNECT = 0x0053, // B*32 token
+ CPMSG_CONNECT_RESPONSE = 0x0054, // B error
+
+ // Game
+ PGMSG_PICKUP = 0x0110,
+ GPMSG_PICKUP_RESPONSE = 0x0111,
+ GPMSG_BEING_ENTER = 0x0200, // B type, L being id
+ // player: S name, B hair style, B hair color, B gender
+ GPMSG_BEING_LEAVE = 0x0201, // B type, L being id
+ PGMSG_WALK = 0x0260, // L*2 destination
+ PGMSG_SAY = 0x02A0, // S text
+ GPMSG_SAY = 0x02A1, // S being, S text
+ PGMSG_USE_ITEM = 0x0300, // L item id
+ GPMSG_USE_RESPONSE = 0x0301, // B error
+ PGMSG_EQUIP = 0x0302, // L item id, B slot
+ GPMSG_EQUIP_RESPONSE = 0x0303, // B error
+
+ // Chat
+ CPMSG_ERROR = 0x0401, // B error
+ CPMSG_ANNOUNCEMENT = 0x0402, // S text
+ CPMSG_PRIVMSG = 0x0403, // S user, S text
+ CPMSG_PUBMSG = 0x0404, // W channel, S user, S text
+ PCMSG_CHAT = 0x0410, // S text, W channel
+ PCMSG_ANNOUNCE = 0x0411, // S text
+ PCMSG_PRIVMSG = 0x0412, // S user, S text
+ // -- Channeling
+ PCMSG_REGISTER_CHANNEL = 0x0413, // B pub/priv, S name, S announcement, S password
+ CPMSG_REGISTER_CHANNEL_RESPONSE = 0x0414, // B error
+ PCMSG_UNREGISTER_CHANNEL = 0x0415, // W channel
+ CPMSG_UNREGISTER_CHANNEL_RESPONSE = 0x0416, // B error
+ CPMSG_CHANNEL_EVENT = 0x0418, // W channel, B event, S user
+ PCMSG_ENTER_CHANNEL = 0x0419, // W channel, S password
+ CPMSG_ENTER_CHANNEL_RESPONSE = 0x0420, // B error
+ PCMSG_QUIT_CHANNEL = 0x0421, // W channel
+ CPMSG_QUIT_CHANNEL_RESPONSE = 0x0422, // B error
+
+ XXMSG_INVALID = 0x7FFF
+};
+
+// Generic return values
+
+enum {
+ ERRMSG_OK = 0, // everything is fine
+ ERRMSG_FAILURE, // the action failed
+ ERRMSG_NO_LOGIN, // the user is not yet logged
+ ERRMSG_NO_CHARACTER_SELECTED, // the user needs a character
+ ERRMSG_INSUFFICIENT_RIGHTS, // the user is not privileged
+ ERRMSG_INVALID_ARGUMENT, // part of the received message was invalid
+};
+
+// Login specific return values
+enum {
+ LOGIN_INVALID_VERSION = 0x40, // the user is using an incompatible protocol
+ LOGIN_SERVER_FULL // the server is overloaded
+};
+
+
/** Encodes coords and direction in 3 bytes data */
void set_coordinates(char *data, unsigned short x, unsigned short y, unsigned char direction);
diff --git a/src/net/skillhandler.cpp b/src/net/skillhandler.cpp
index e9dc9c19..89009e47 100644
--- a/src/net/skillhandler.cpp
+++ b/src/net/skillhandler.cpp
@@ -46,20 +46,20 @@ void SkillHandler::handleMessage(MessageIn *msg)
switch (msg->getId())
{
case SMSG_PLAYER_SKILLS:
- msg->readInt16(); // length
+ msg->readShort(); // length
skillCount = (msg->getLength() - 4) / 37;
skillDialog->cleanList();
for (int k = 0; k < skillCount; k++)
{
- Sint16 skillId = msg->readInt16();
- msg->readInt16(); // target type
- msg->readInt16(); // unknown
- Sint16 level = msg->readInt16();
- Sint16 sp = msg->readInt16();
- msg->readInt16(); // range
+ Sint16 skillId = msg->readShort();
+ msg->readShort(); // target type
+ msg->readShort(); // unknown
+ Sint16 level = msg->readShort();
+ Sint16 sp = msg->readShort();
+ msg->readShort(); // range
std::string skillName = msg->readString(24);
- Sint8 up = msg->readInt8();
+ Sint8 up = msg->readByte();
if (level != 0 || up != 0)
{
@@ -77,11 +77,11 @@ void SkillHandler::handleMessage(MessageIn *msg)
// Action failed (ex. sit because you have not reached the
// right level)
CHATSKILL action;
- action.skill = msg->readInt16();
- action.bskill = msg->readInt16();
- action.unused = msg->readInt16(); // unknown
- action.success = msg->readInt8();
- action.reason = msg->readInt8();
+ action.skill = msg->readShort();
+ action.bskill = msg->readShort();
+ action.unused = msg->readShort(); // unknown
+ action.success = msg->readByte();
+ action.reason = msg->readByte();
if (action.success != SKILL_FAILED &&
action.bskill == BSKILL_EMOTE)
{
diff --git a/src/net/tradehandler.cpp b/src/net/tradehandler.cpp
index 5bce0574..0f5bdcdc 100644
--- a/src/net/tradehandler.cpp
+++ b/src/net/tradehandler.cpp
@@ -90,7 +90,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
break;
case SMSG_TRADE_RESPONSE:
- switch (msg->readInt8())
+ switch (msg->readByte())
{
case 0: // Too far away
chatWindow->chatLog("Trading isn't possible. "
@@ -126,12 +126,11 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_ITEM_ADD:
{
- Sint32 amount = msg->readInt32();
- Sint16 type = msg->readInt16();
- msg->readInt8(); // identified flag
- msg->readInt8(); // attribute
- msg->readInt8(); // refine
- msg->skip(8); // card (4 shorts)
+ Sint32 amount = msg->readLong();
+ Sint16 type = msg->readShort();
+ msg->readByte(); // identified flag
+ msg->readByte(); // attribute
+ msg->readByte(); // refine
// TODO: handle also identified, etc
if (type == 0) {
@@ -145,10 +144,10 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_ITEM_ADD_RESPONSE:
// Trade: New Item add response (was 0x00ea, now 01b1)
{
- Item *item = player_node->getInvItem(msg->readInt16());
- Sint16 quantity = msg->readInt16();
+ Item *item = player_node->getInvItem(msg->readShort());
+ Sint16 quantity = msg->readShort();
- switch (msg->readInt8())
+ switch (msg->readByte())
{
case 0:
// Successfully added item
@@ -176,7 +175,7 @@ void TradeHandler::handleMessage(MessageIn *msg)
case SMSG_TRADE_OK:
// 0 means ok from myself, 1 means ok from other;
- tradeWindow->receivedOk(msg->readInt8() == 0);
+ tradeWindow->receivedOk(msg->readByte() == 0);
break;
case SMSG_TRADE_CANCEL: