diff options
-rw-r--r-- | src/net/manaserv/manaserv_protocol.h | 27 | ||||
-rw-r--r-- | src/net/manaserv/messagein.cpp | 54 | ||||
-rw-r--r-- | src/net/manaserv/messagein.h | 16 | ||||
-rw-r--r-- | src/net/manaserv/messageout.cpp | 32 | ||||
-rw-r--r-- | src/net/manaserv/messageout.h | 11 |
5 files changed, 119 insertions, 21 deletions
diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index c8b16593..5f94b726 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -26,7 +26,19 @@ namespace ManaServ { enum { PROTOCOL_VERSION = 1, - SUPPORTED_DB_VERSION = 19 + SUPPORTED_DB_VERSION = 21 +}; + +/** + * The type of a value in a message. Prepended before each value when the + * protocol is running in debug mode. + */ +enum ValueType { + Int8, + Int16, + Int32, + String, + Double }; /** @@ -43,7 +55,7 @@ enum { * Components: B byte, W word, D double word, S variable-size string * C tile-based coordinates (B*3) * - * Hosts: P (player's client), A (account server), C (char server), + * Hosts: P (player's client), A (account server), C (chat server), * G (game server) * * TODO - Document specific error codes for each packet @@ -232,7 +244,7 @@ enum { // Inter-server GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }* - AGMSG_REGISTER_RESPONSE = 0x0501, // C item version, C password response, { S globalvar_key, S globalvar_value } + AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value } AGMSG_ACTIVE_MAP = 0x0502, // W map id, W Number of mapvar_key mapvar_value sent, { S mapvar_key, S mapvar_value }, W Number of map items, { D item Id, W amount, W posX, W posY } AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data GAMSG_PLAYER_DATA = 0x0520, // D id, serialised character data @@ -252,7 +264,7 @@ enum { GAMSG_BAN_PLAYER = 0x0550, // D id, W duration GAMSG_CHANGE_PLAYER_LEVEL = 0x0555, // D id, W level GAMSG_CHANGE_ACCOUNT_LEVEL = 0x0556, // D id, W level - GAMSG_STATISTICS = 0x0560, // { W map id, W thing nb, W monster nb, W player nb, { D character id }* }* + GAMSG_STATISTICS = 0x0560, // { W map id, W entity nb, W monster nb, W player nb, { D character id }* }* CGMSG_CHANGED_PARTY = 0x0590, // D character id, D party id GCMSG_REQUEST_POST = 0x05A0, // D character id CGMSG_POST_RESPONSE = 0x05A1, // D receiver id, { S sender name, S letter, W num attachments { W attachment item id, W quantity } } @@ -263,7 +275,8 @@ enum { GAMSG_REMOVE_ITEM_ON_MAP = 0x0602, // D map id, D item id, W amount, W pos x, W pos y GAMSG_ANNOUNCE = 0x0603, // S text, W senderid, S sendername - XXMSG_INVALID = 0x7FFF + XXMSG_DEBUG_FLAG = 0x8000, // Message in debug mode + XXMSG_INVALID = 0x7FFF }; // Generic return values @@ -340,8 +353,8 @@ enum AttribmodResponseCode { ATTRIBMOD_DENIED }; -// Object type enumeration -enum ThingType +// Entity type enumeration +enum EntityType { // A simple item. OBJECT_ITEM = 0, diff --git a/src/net/manaserv/messagein.cpp b/src/net/manaserv/messagein.cpp index aeb02b8d..8065d313 100644 --- a/src/net/manaserv/messagein.cpp +++ b/src/net/manaserv/messagein.cpp @@ -29,15 +29,24 @@ namespace ManaServ { MessageIn::MessageIn(const char *data, unsigned int length): mData(data), mLength(length), + mDebugMode(false), mPos(0) { // Read the message ID mId = readInt16(); + + // Read and clear the debug flag + mDebugMode = mId & ManaServ::XXMSG_DEBUG_FLAG; + mId &= ~ManaServ::XXMSG_DEBUG_FLAG; } uint8_t MessageIn::readInt8() { uint8_t value = 0; + + if (!readValueType(ManaServ::Int8)) + return value; + if (mPos < mLength) { value = mData[mPos]; @@ -49,6 +58,10 @@ uint8_t MessageIn::readInt8() uint16_t MessageIn::readInt16() { uint16_t value = 0; + + if (!readValueType(ManaServ::Int16)) + return value; + if (mPos + 2 <= mLength) { uint16_t t; @@ -62,6 +75,10 @@ uint16_t MessageIn::readInt16() uint32_t MessageIn::readInt32() { uint32_t value = 0; + + if (!readValueType(ManaServ::Int32)) + return value; + if (mPos + 4 <= mLength) { uint32_t t; @@ -74,24 +91,55 @@ uint32_t MessageIn::readInt32() std::string MessageIn::readString(int length) { + if (!readValueType(ManaServ::String)) + return std::string(); + + if (mDebugMode) + { + int fixedLength = (int16_t) readInt16(); + if (fixedLength != length) + { + // String does not have the expected length + mPos = mLength + 1; + return std::string(); + } + } + // Get string length if (length < 0) + { length = readInt16(); + } // Make sure the string isn't erroneous if (length < 0 || mPos + length > mLength) { mPos = mLength + 1; - return ""; + return std::string(); } // Read the string - char const *stringBeg = mData + mPos; - char const *stringEnd = (char const *)memchr(stringBeg, '\0', length); + const char *stringBeg = mData + mPos; + const char *stringEnd = (const char *)memchr(stringBeg, '\0', length); std::string readString(stringBeg, stringEnd ? stringEnd - stringBeg : length); mPos += length; + return readString; } +bool MessageIn::readValueType(ManaServ::ValueType type) +{ + if (!mDebugMode) // Verification not possible + return true; + + if (mPos >= mLength) + return false; + + uint8_t t = mData[mPos]; + ++mPos; + + return t == type; +} + } // ManaServ diff --git a/src/net/manaserv/messagein.h b/src/net/manaserv/messagein.h index ef0c29bf..89ae5ed8 100644 --- a/src/net/manaserv/messagein.h +++ b/src/net/manaserv/messagein.h @@ -22,6 +22,8 @@ #ifndef NET_MANASERV_MESSAGEIN_H #define NET_MANASERV_MESSAGEIN_H +#include "net/manaserv/manaserv_protocol.h" + #include <cstdint> #include <string> @@ -75,14 +77,16 @@ class MessageIn std::string readString(int length = -1); private: - const char *mData; /**< The message data. */ - unsigned int mLength; /**< The length of the data. */ - unsigned short mId; /**< The message ID. */ + bool readValueType(ManaServ::ValueType type); + + const char *mData; /**< The message data. */ + unsigned int mLength; /**< The length of the data. */ + unsigned short mId; /**< The message ID. */ + bool mDebugMode; /**< Includes debugging information. */ /** - * Actual position in the packet. From 0 to packet->length. - * A value bigger than packet->length means EOP was reached when - * reading it. + * 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; }; diff --git a/src/net/manaserv/messageout.cpp b/src/net/manaserv/messageout.cpp index 7cecc03d..1197176f 100644 --- a/src/net/manaserv/messageout.cpp +++ b/src/net/manaserv/messageout.cpp @@ -29,10 +29,16 @@ namespace ManaServ { MessageOut::MessageOut(uint16_t id): mData(0), + mPos(0), mDataSize(0), - mPos(0) + mDebugMode(false) { + bool debug = true; + if (debug) + id |= ManaServ::XXMSG_DEBUG_FLAG; + writeInt16(id); + mDebugMode = debug; } MessageOut::~MessageOut() @@ -48,6 +54,9 @@ void MessageOut::expand(size_t bytes) void MessageOut::writeInt8(uint8_t value) { + if (mDebugMode) + writeValueType(ManaServ::Int8); + expand(1); mData[mPos] = value; mPos += 1; @@ -55,6 +64,9 @@ void MessageOut::writeInt8(uint8_t value) void MessageOut::writeInt16(uint16_t value) { + if (mDebugMode) + writeValueType(ManaServ::Int16); + expand(2); uint16_t t = ENET_HOST_TO_NET_16(value); memcpy(mData + mPos, &t, 2); @@ -63,6 +75,9 @@ void MessageOut::writeInt16(uint16_t value) void MessageOut::writeInt32(uint32_t value) { + if (mDebugMode) + writeValueType(ManaServ::Int32); + expand(4); uint32_t t = ENET_HOST_TO_NET_32(value); memcpy(mData + mPos, &t, 4); @@ -71,6 +86,12 @@ void MessageOut::writeInt32(uint32_t value) void MessageOut::writeString(const std::string &string, int length) { + if (mDebugMode) + { + writeValueType(ManaServ::String); + writeInt16(length); + } + int stringLength = string.length(); if (length < 0) { @@ -88,12 +109,19 @@ void MessageOut::writeString(const std::string &string, int length) // Write the actual string memcpy(mData + mPos, string.data(), stringLength); - // Pad remaining space with zeros if (length > stringLength) { + // Pad remaining space with zeros memset(mData + mPos + stringLength, '\0', length - stringLength); } mPos += length; } +void MessageOut::writeValueType(ManaServ::ValueType type) +{ + expand(1); + mData[mPos] = type; + mPos += 1; +} + } // namespace ManaServ diff --git a/src/net/manaserv/messageout.h b/src/net/manaserv/messageout.h index 9a87cf1c..d452f784 100644 --- a/src/net/manaserv/messageout.h +++ b/src/net/manaserv/messageout.h @@ -22,6 +22,8 @@ #ifndef NET_MANASERV_MESSAGEOUT_H #define NET_MANASERV_MESSAGEOUT_H +#include "net/manaserv/manaserv_protocol.h" + #include <cstdint> #include <string> @@ -80,9 +82,12 @@ class MessageOut */ void expand(size_t size); - char *mData; /**< Data building up. */ - unsigned int mDataSize; /**< Size of data. */ - unsigned int mPos; /**< Position in the data. */ + void writeValueType(ManaServ::ValueType type); + + char *mData; /**< Data building up. */ + unsigned int mPos; /**< Position in the data. */ + unsigned int mDataSize; /**< Size of data. */ + bool mDebugMode; /**< Include debugging information. */ }; } // namespace ManaServ |