diff options
author | Eugenio Favalli <elvenprogrammer@gmail.com> | 2006-07-25 18:04:38 +0000 |
---|---|---|
committer | Eugenio Favalli <elvenprogrammer@gmail.com> | 2006-07-25 18:04:38 +0000 |
commit | c7e7b62aa94bf295ca1dc556762ad6070221e0cd (patch) | |
tree | 04f827df0df64a80e04a4115986609486d715237 /src/net | |
parent | c0c8775271679ac4904bc0bc02a74d28fc75efd0 (diff) | |
download | mana-client-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.gz mana-client-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.bz2 mana-client-c7e7b62aa94bf295ca1dc556762ad6070221e0cd.tar.xz mana-client-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.cpp | 170 | ||||
-rw-r--r-- | src/net/buysellhandler.cpp | 24 | ||||
-rw-r--r-- | src/net/charserverhandler.cpp | 68 | ||||
-rw-r--r-- | src/net/chathandler.cpp | 10 | ||||
-rw-r--r-- | src/net/equipmenthandler.cpp | 41 | ||||
-rw-r--r-- | src/net/inventoryhandler.cpp | 55 | ||||
-rw-r--r-- | src/net/itemhandler.cpp | 13 | ||||
-rw-r--r-- | src/net/loginhandler.cpp | 94 | ||||
-rw-r--r-- | src/net/maploginhandler.cpp | 4 | ||||
-rw-r--r-- | src/net/messagein.cpp | 171 | ||||
-rw-r--r-- | src/net/messagein.h | 66 | ||||
-rw-r--r-- | src/net/messageout.cpp | 102 | ||||
-rw-r--r-- | src/net/messageout.h | 45 | ||||
-rw-r--r-- | src/net/network.cpp | 355 | ||||
-rw-r--r-- | src/net/network.h | 38 | ||||
-rw-r--r-- | src/net/npchandler.cpp | 8 | ||||
-rw-r--r-- | src/net/playerhandler.cpp | 104 | ||||
-rw-r--r-- | src/net/protocol.h | 97 | ||||
-rw-r--r-- | src/net/skillhandler.cpp | 26 | ||||
-rw-r--r-- | src/net/tradehandler.cpp | 21 |
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: |