summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/net/manaserv/manaserv_protocol.h27
-rw-r--r--src/net/manaserv/messagein.cpp54
-rw-r--r--src/net/manaserv/messagein.h16
-rw-r--r--src/net/manaserv/messageout.cpp32
-rw-r--r--src/net/manaserv/messageout.h11
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