summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-04-14 12:59:54 +0200
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-05-05 22:51:32 +0200
commitbb9a9b9b0f4ec7cc6a9ca3a6bd2dc35b0b6541e7 (patch)
tree503dcb475ece8e72e2fbef2e78e82b2a881e6d23 /src
parent05669aae551820f2183984d1c706d3a82eb37be6 (diff)
downloadmanaserv-bb9a9b9b0f4ec7cc6a9ca3a6bd2dc35b0b6541e7.tar.gz
manaserv-bb9a9b9b0f4ec7cc6a9ca3a6bd2dc35b0b6541e7.tar.bz2
manaserv-bb9a9b9b0f4ec7cc6a9ca3a6bd2dc35b0b6541e7.tar.xz
manaserv-bb9a9b9b0f4ec7cc6a9ca3a6bd2dc35b0b6541e7.zip
Added debugging mode to the protocol
Allows inspection of message data. It is off by default since it consumes additional bandwidth, but it can be turned on using the net_debugMode option in manaserv.xml. Currently the option only affects outgoing data for each host individually. In particular, enabling this debug mode for the server does not automatically make the client annotate its messages. Reviewed-by: Erik Schilling
Diffstat (limited to 'src')
-rw-r--r--src/account-server/main-account.cpp3
-rw-r--r--src/account-server/serverhandler.cpp20
-rw-r--r--src/chat-server/chathandler.cpp7
-rw-r--r--src/common/manaserv_protocol.h23
-rw-r--r--src/game-server/accountconnection.cpp2
-rw-r--r--src/game-server/main-game.cpp3
-rw-r--r--src/net/connectionhandler.cpp6
-rw-r--r--src/net/messagein.cpp166
-rw-r--r--src/net/messagein.h10
-rw-r--r--src/net/messageout.cpp78
-rw-r--r--src/net/messageout.h64
11 files changed, 283 insertions, 99 deletions
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp
index 44e65c41..65c5efd1 100644
--- a/src/account-server/main-account.cpp
+++ b/src/account-server/main-account.cpp
@@ -345,6 +345,9 @@ int main(int argc, char *argv[])
int chatClientPort = Configuration::getValue("net_chatListenToClientPort",
options.port + 2);
+ bool debugNetwork = Configuration::getBoolValue("net_debugMode", false);
+ MessageOut::setDebugModeEnabled(debugNetwork);
+
if (!AccountClientHandler::initialize(DEFAULT_ATTRIBUTEDB_FILE,
options.port, accountHost) ||
!GameServerHandler::initialize(accountGamePort, accountHost) ||
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index a7d87da9..c938324f 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -172,7 +172,6 @@ void GameServerHandler::registerClient(const std::string &token,
void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
{
- MessageOut result;
GameServer *server = static_cast<GameServer *>(comp);
switch (msg.getId())
@@ -322,11 +321,12 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
if (GameServer *s = getGameServerFromMap(mapId))
{
registerGameClient(s, magic_token, ptr);
- result.writeInt16(AGMSG_REDIRECT_RESPONSE);
+ MessageOut result(AGMSG_REDIRECT_RESPONSE);
result.writeInt32(id);
result.writeString(magic_token, MAGIC_TOKEN_LENGTH);
result.writeString(s->address);
result.writeInt16(s->port);
+ comp->send(result);
}
else
{
@@ -366,10 +366,11 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
int id = msg.readInt32();
std::string name = msg.readString();
std::string value = storage->getQuestVar(id, name);
- result.writeInt16(AGMSG_GET_VAR_CHR_RESPONSE);
+ MessageOut result(AGMSG_GET_VAR_CHR_RESPONSE);
result.writeInt32(id);
result.writeString(name);
result.writeString(value);
+ comp->send(result);
} break;
case GAMSG_SET_VAR_CHR:
@@ -463,7 +464,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
{
// Retrieve the post for user
LOG_DEBUG("GCMSG_REQUEST_POST");
- result.writeInt16(CGMSG_POST_RESPONSE);
+ MessageOut result(CGMSG_POST_RESPONSE);
// get the character id
int characterId = msg.readInt32();
@@ -505,13 +506,14 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
postalManager->clearPost(ptr);
}
+ comp->send(result);
} break;
case GCMSG_STORE_POST:
{
// Store the letter for the user
LOG_DEBUG("GCMSG_STORE_POST");
- result.writeInt16(CGMSG_STORE_POST_RESPONSE);
+ MessageOut result(CGMSG_STORE_POST_RESPONSE);
// get the sender and receiver
int senderId = msg.readInt32();
@@ -554,6 +556,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
postalManager->addLetter(letter);
result.writeInt8(ERRMSG_OK);
+ comp->send(result);
} break;
case GAMSG_TRANSACTION:
@@ -613,13 +616,10 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
default:
LOG_WARN("ServerHandler::processMessage, Invalid message type: "
<< msg.getId());
- result.writeInt16(XXMSG_INVALID);
+ MessageOut result(XXMSG_INVALID);
+ comp->send(result);
break;
}
-
- // return result
- if (result.getLength() > 0)
- comp->send(result);
}
void GameServerHandler::dumpStatistics(std::ostream &os)
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 0446fa30..63aaa43a 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -142,7 +142,6 @@ void ChatHandler::computerDisconnected(NetComputer *comp)
void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
{
ChatClient &computer = *static_cast< ChatClient * >(comp);
- MessageOut result;
if (computer.characterName.empty())
{
@@ -237,12 +236,10 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
default:
LOG_WARN("ChatHandler::processMessage, Invalid message type"
<< message.getId());
- result.writeInt16(XXMSG_INVALID);
+ MessageOut result(XXMSG_INVALID);
+ computer.send(result);
break;
}
-
- if (result.getLength() > 0)
- computer.send(result);
}
void ChatHandler::handleCommand(ChatClient &computer, const std::string &command)
diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h
index 885d7d27..747c8735 100644
--- a/src/common/manaserv_protocol.h
+++ b/src/common/manaserv_protocol.h
@@ -34,6 +34,18 @@ enum {
};
/**
+ * 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
+};
+
+/**
* Enumerated type for communicated messages:
*
* - PAMSG_*: from client to account server
@@ -47,7 +59,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
@@ -97,8 +109,8 @@ enum {
// Game
GPMSG_PLAYER_MAP_CHANGE = 0x0100, // S filename, W x, W y
GPMSG_PLAYER_SERVER_CHANGE = 0x0101, // B*32 token, S game address, W game port
- PGMSG_PICKUP = 0x0110, // W*2 position
- PGMSG_DROP = 0x0111, // B slot, B amount
+ PGMSG_PICKUP = 0x0110, // W * 2 items position
+ PGMSG_DROP = 0x0111, // W slot, W amount
PGMSG_EQUIP = 0x0112, // W inventory slot
PGMSG_UNEQUIP = 0x0113, // W item Instance id
PGMSG_MOVE_ITEM = 0x0114, // W slot1, W slot2, W amount
@@ -236,7 +248,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
@@ -267,7 +279,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
diff --git a/src/game-server/accountconnection.cpp b/src/game-server/accountconnection.cpp
index 3d37ea67..3b58e347 100644
--- a/src/game-server/accountconnection.cpp
+++ b/src/game-server/accountconnection.cpp
@@ -115,6 +115,8 @@ void AccountConnection::sendCharacterData(Character *p)
void AccountConnection::processMessage(MessageIn &msg)
{
+ LOG_DEBUG("Received message " << msg << " from account server");
+
switch (msg.getId())
{
case AGMSG_REGISTER_RESPONSE:
diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp
index 647a74ef..406e7c5b 100644
--- a/src/game-server/main-game.cpp
+++ b/src/game-server/main-game.cpp
@@ -347,6 +347,9 @@ int main(int argc, char *argv[])
options.port);
}
+ bool debugNetwork = Configuration::getBoolValue("net_debugMode", false);
+ MessageOut::setDebugModeEnabled(debugNetwork);
+
// Make an initial attempt to connect to the account server
// Try again after longer and longer intervals when connection fails.
bool isConnected = false;
diff --git a/src/net/connectionhandler.cpp b/src/net/connectionhandler.cpp
index e9ec1944..5aaf90e0 100644
--- a/src/net/connectionhandler.cpp
+++ b/src/net/connectionhandler.cpp
@@ -75,12 +75,12 @@ void ConnectionHandler::stopListen()
currentPeer < &host->peers[host->peerCount];
++currentPeer)
{
- if (currentPeer->state == ENET_PEER_STATE_CONNECTED)
- {
+ if (currentPeer->state == ENET_PEER_STATE_CONNECTED)
+ {
enet_peer_disconnect(currentPeer, 0);
enet_host_flush(host);
enet_peer_reset(currentPeer);
- }
+ }
}
enet_host_destroy(host);
// FIXME: memory leak on NetComputers
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp
index 022ac465..b797f0a0 100644
--- a/src/net/messagein.cpp
+++ b/src/net/messagein.cpp
@@ -1,6 +1,7 @@
/*
* The Mana Server
* Copyright (C) 2004-2010 The Mana World Development Team
+ * Copyright (C) 2010-2012 The Mana Developers
*
* This file is part of The Mana Server.
*
@@ -30,23 +31,47 @@
#include "net/messagein.h"
#include "utils/logger.h"
-MessageIn::MessageIn(const char *data, int length):
+// Not enabled by default since this will cause assertions on message errors,
+// which may also originate from the client.
+//#define DEBUG_NETWORK
+
+#ifdef DEBUG_NETWORK
+#include <cassert>
+#define ASSERT_IF(x) assert(x); if (x)
+#else
+#define ASSERT_IF(x) if (x)
+#endif
+
+MessageIn::MessageIn(const char *data, unsigned short 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;
}
int MessageIn::readInt8()
{
int value = -1;
- if (mPos < mLength)
+
+ if (!readValueType(ManaServ::Int8))
+ return value;
+
+ ASSERT_IF (mPos < mLength)
{
value = (unsigned char) mData[mPos];
}
- else LOG_DEBUG("Unable to read 1 byte in " << this->getId() << "!");
+ else
+ {
+ LOG_DEBUG("Unable to read 1 byte in " << mId << "!");
+ }
+
mPos += 1;
return value;
}
@@ -54,13 +79,21 @@ int MessageIn::readInt8()
int MessageIn::readInt16()
{
int value = -1;
- if (mPos + 2 <= mLength)
+
+ if (!readValueType(ManaServ::Int16))
+ return value;
+
+ ASSERT_IF (mPos + 2 <= mLength)
{
uint16_t t;
memcpy(&t, mData + mPos, 2);
- value = (unsigned short) ENET_NET_TO_HOST_16(t);
+ value = (short) ENET_NET_TO_HOST_16(t);
}
- else LOG_DEBUG("Unable to read 2 bytes in " << this->getId() << "!");
+ else
+ {
+ LOG_DEBUG("Unable to read 2 bytes in " << mId << "!");
+ }
+
mPos += 2;
return value;
}
@@ -68,20 +101,32 @@ int MessageIn::readInt16()
int MessageIn::readInt32()
{
int value = -1;
- if (mPos + 4 <= mLength)
+
+ if (!readValueType(ManaServ::Int32))
+ return value;
+
+ ASSERT_IF (mPos + 4 <= mLength)
{
uint32_t t;
memcpy(&t, mData + mPos, 4);
value = ENET_NET_TO_HOST_32(t);
}
- else LOG_DEBUG("Unable to read 4 bytes in " << this->getId() << "!");
+ else
+ {
+ LOG_DEBUG("Unable to read 4 bytes in " << mId << "!");
+ }
+
mPos += 4;
return value;
}
double MessageIn::readDouble()
{
- double value;
+ double value = -1;
+
+ if (!readValueType(ManaServ::Double))
+ return value;
+
#ifdef USE_NATIVE_DOUBLE
if (mPos + sizeof(double) <= mLength)
memcpy(&value, mData + mPos, sizeof(double));
@@ -96,6 +141,24 @@ double MessageIn::readDouble()
std::string MessageIn::readString(int length)
{
+ if (!readValueType(ManaServ::String))
+ return std::string();
+
+ if (mDebugMode)
+ {
+ int fixedLength = readInt16();
+#ifdef DEBUG_NETWORK
+ assert(fixedLength == length);
+#endif
+ if (fixedLength != length)
+ {
+ LOG_DEBUG("Expected string of length " << length <<
+ " but received length " << fixedLength);
+ mPos = mLength + 1;
+ return std::string();
+ }
+ }
+
// Get string length
if (length < 0)
{
@@ -113,17 +176,96 @@ std::string MessageIn::readString(int length)
const char *stringBeg = mData + mPos;
const char *stringEnd = (const char *)memchr(stringBeg, '\0', length);
std::string readString(stringBeg,
- stringEnd ? stringEnd - stringBeg : length);
+ stringEnd ? stringEnd - stringBeg : length);
mPos += length;
return readString;
}
+bool MessageIn::readValueType(ManaServ::ValueType type)
+{
+ if (!mDebugMode) // Verification not possible
+ return true;
+
+ ASSERT_IF (mPos < mLength)
+ {
+ int t = (unsigned char) mData[mPos];
+ ++mPos;
+
+ ASSERT_IF (t == type)
+ {
+ return true;
+ }
+ else
+ {
+ LOG_DEBUG("Attempt to read " << type << " but got " << t);
+ }
+ }
+ else
+ {
+ LOG_DEBUG("Attempt to read " << type << " but no more data available");
+ }
+
+ return false;
+}
+
std::ostream&
operator <<(std::ostream &os, const MessageIn &msg)
{
os << std::setw(6) << std::hex << std::showbase << std::internal
- << std::setfill('0') << msg.getId()
- << std::dec << " (" << msg.getLength() << " B)";
+ << std::setfill('0') << msg.getId() << std::dec;
+
+ if (!msg.mDebugMode)
+ {
+ os << " (" << msg.getLength() << " B)";
+ }
+ else
+ {
+ os << " { ";
+
+ MessageIn m(msg.mData, msg.mLength);
+
+ while (m.getUnreadLength() > 0)
+ {
+ if (m.mPos > 3)
+ os << ", ";
+
+ unsigned char valueType = m.mData[m.mPos];
+ switch (valueType)
+ {
+ case ManaServ::Int8:
+ os << "B " << m.readInt8();
+ break;
+ case ManaServ::Int16:
+ os << "W " << m.readInt16();
+ break;
+ case ManaServ::Int32:
+ os << "D " << m.readInt32();
+ break;
+ case ManaServ::String: {
+ // Peak ahead at a possible fixed length
+ unsigned short pos = m.mPos;
+ m.mPos++;
+ int length = m.readInt16();
+ m.mPos = pos;
+
+ if (length < 0)
+ os << "S " << m.readString();
+ else
+ os << "S[" << length << "] " << m.readString(length);
+ break;
+ }
+ case ManaServ::Double:
+ os << "d " << m.readDouble();
+ break;
+ default:
+ os << "??? }";
+ return os; // Stop after error
+ }
+ }
+
+ os << " }";
+ }
+
return os;
}
diff --git a/src/net/messagein.h b/src/net/messagein.h
index dd82ce51..6d9e3bd0 100644
--- a/src/net/messagein.h
+++ b/src/net/messagein.h
@@ -21,6 +21,8 @@
#ifndef MESSAGEIN_H
#define MESSAGEIN_H
+#include "common/manaserv_protocol.h"
+
#include <iosfwd>
/**
@@ -35,7 +37,7 @@ class MessageIn
* @param data the message data
* @param length the length of the data
*/
- MessageIn(const char *data, int length);
+ MessageIn(const char *data, unsigned short length);
/**
* Returns the message ID.
@@ -70,9 +72,12 @@ class MessageIn
int getUnreadLength() const { return mLength - mPos; }
private:
+ bool readValueType(ManaServ::ValueType type);
+
const char *mData; /**< Packet data */
unsigned short mLength; /**< Length of data in bytes */
unsigned short mId; /**< The message ID. */
+ bool mDebugMode; /**< Includes debugging information. */
/**
* Actual position in the packet. From 0 to packet->length. A value
@@ -82,6 +87,9 @@ class MessageIn
/**
* Streams message ID and length to the given output stream.
+ *
+ * When the message includes debugging information, prints out
+ * the message contents instead of the length.
*/
friend std::ostream& operator <<(std::ostream &os,
const MessageIn &msg);
diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp
index a5b0a53c..d39fd23e 100644
--- a/src/net/messageout.cpp
+++ b/src/net/messageout.cpp
@@ -18,6 +18,9 @@
* along with The Mana Server. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "net/messageout.h"
+#include "net/messagein.h"
+
#include <cstring>
#include <iomanip>
#include <iostream>
@@ -28,28 +31,26 @@
#include <string>
#include <enet/enet.h>
-#include "net/messageout.h"
-
/** Initial amount of bytes allocated for the messageout data buffer. */
const unsigned int INITIAL_DATA_CAPACITY = 16;
/** Factor by which the messageout data buffer is increased when too small. */
const unsigned int CAPACITY_GROW_FACTOR = 2;
-MessageOut::MessageOut():
- mPos(0)
-{
- mData = (char*) malloc(INITIAL_DATA_CAPACITY);
- mDataSize = INITIAL_DATA_CAPACITY;
-}
+static bool debugModeEnabled = false;
MessageOut::MessageOut(int id):
- mPos(0)
+ mPos(0),
+ mDebugMode(false)
{
mData = (char*) malloc(INITIAL_DATA_CAPACITY);
mDataSize = INITIAL_DATA_CAPACITY;
+ if (debugModeEnabled)
+ id |= ManaServ::XXMSG_DEBUG_FLAG;
+
writeInt16(id);
+ mDebugMode = debugModeEnabled;
}
MessageOut::~MessageOut()
@@ -57,15 +58,7 @@ MessageOut::~MessageOut()
free(mData);
}
-void MessageOut::clear()
-{
- mData = (char *) realloc(mData, INITIAL_DATA_CAPACITY);
- mDataSize = INITIAL_DATA_CAPACITY;
- mPos = 0;
-}
-
-void
-MessageOut::expand(size_t bytes)
+void MessageOut::expand(size_t bytes)
{
if (bytes > mDataSize)
{
@@ -81,6 +74,9 @@ MessageOut::expand(size_t bytes)
void MessageOut::writeInt8(int value)
{
+ if (mDebugMode)
+ writeValueType(ManaServ::Int8);
+
expand(mPos + 1);
mData[mPos] = value;
mPos += 1;
@@ -88,6 +84,9 @@ void MessageOut::writeInt8(int value)
void MessageOut::writeInt16(int value)
{
+ if (mDebugMode)
+ writeValueType(ManaServ::Int16);
+
expand(mPos + 2);
uint16_t t = ENET_HOST_TO_NET_16(value);
memcpy(mData + mPos, &t, 2);
@@ -96,6 +95,9 @@ void MessageOut::writeInt16(int value)
void MessageOut::writeInt32(int value)
{
+ if (mDebugMode)
+ writeValueType(ManaServ::Int32);
+
expand(mPos + 4);
uint32_t t = ENET_HOST_TO_NET_32(value);
memcpy(mData + mPos, &t, 4);
@@ -104,6 +106,9 @@ void MessageOut::writeInt32(int value)
void MessageOut::writeDouble(double value)
{
+ if (mDebugMode)
+ writeValueType(ManaServ::Double);
+
#ifdef USE_NATIVE_DOUBLE
expand(mPos + sizeof(double));
memcpy(mData + mPos, &value, sizeof(double));
@@ -121,19 +126,14 @@ void MessageOut::writeDouble(double value)
#endif
}
-void MessageOut::writeCoordinates(int x, int y)
+void MessageOut::writeString(const std::string &string, int length)
{
- expand(mPos + 3);
- char *p = mData + mPos;
- p[0] = x & 0x00FF;
- p[1] = ((x & 0x0700) >> 8) | ((y & 0x001F) << 3);
- p[2] = (y & 0x07E0) >> 5;
- mPos += 3;
-}
+ if (mDebugMode)
+ {
+ writeValueType(ManaServ::String);
+ writeInt16(length);
+ }
-void
-MessageOut::writeString(const std::string &string, int length)
-{
int stringLength = string.length();
if (length < 0)
{
@@ -149,7 +149,7 @@ MessageOut::writeString(const std::string &string, int length)
expand(mPos + length);
// Write the actual string
- memcpy(mData + mPos, string.c_str(), stringLength);
+ memcpy(mData + mPos, string.data(), stringLength);
if (length > stringLength)
{
@@ -159,15 +159,20 @@ MessageOut::writeString(const std::string &string, int length)
mPos += length;
}
+void MessageOut::writeValueType(ManaServ::ValueType type)
+{
+ expand(mPos + 1);
+ mData[mPos] = type;
+ mPos += 1;
+}
+
std::ostream&
operator <<(std::ostream &os, const MessageOut &msg)
{
if (msg.getLength() >= 2)
{
- unsigned short id = ENET_NET_TO_HOST_16(*(short*) msg.mData);
- os << std::setw(6) << std::hex << std::showbase << std::internal
- << std::setfill('0') << id
- << std::dec << " (" << msg.getLength() << " B)";
+ MessageIn m(msg.mData, msg.mPos);
+ os << m;
}
else
{
@@ -176,3 +181,8 @@ operator <<(std::ostream &os, const MessageOut &msg)
}
return os;
}
+
+void MessageOut::setDebugModeEnabled(bool enabled)
+{
+ debugModeEnabled = enabled;
+}
diff --git a/src/net/messageout.h b/src/net/messageout.h
index 1f071f72..a39e306b 100644
--- a/src/net/messageout.h
+++ b/src/net/messageout.h
@@ -21,6 +21,8 @@
#ifndef MESSAGEOUT_H
#define MESSAGEOUT_H
+#include "common/manaserv_protocol.h"
+
#include <iosfwd>
/**
@@ -30,27 +32,28 @@ class MessageOut
{
public:
/**
- * Default constructor.
- */
- MessageOut();
-
- /**
- * Constructor that takes a message ID.
+ * Constructor.
+ *
+ * @param id the message ID
*/
MessageOut(int id);
~MessageOut();
/**
- * Clears current message.
+ * Writes an 8-bit integer to the message.
*/
- void clear();
+ void writeInt8(int value);
- void writeInt8(int value); /**< Writes an integer on one byte. */
-
- void writeInt16(int value); /**< Writes an integer on two bytes. */
+ /**
+ * Writes an 16-bit integer to the message.
+ */
+ void writeInt16(int value);
- void writeInt32(int value); /**< Writes an integer on four bytes. */
+ /**
+ * Writes an 32-bit integer to the message.
+ */
+ void writeInt32(int value);
/**
* Writes a double. HACKY and should *not* be used for client
@@ -59,40 +62,43 @@ class MessageOut
void writeDouble(double value);
/**
- * Writes a 3-byte block containing tile-based coordinates.
- */
- void writeCoordinates(int x, int y);
-
- /**
* Writes a string. If a fixed length is not given (-1), it is stored
* as a short at the start of the string.
*/
- void
- writeString(const std::string &string, int length = -1);
+ void writeString(const std::string &string, int length = -1);
/**
* Returns the content of the message.
*/
- char*
- getData() const { return mData; }
+ char *getData() const { return mData; }
/**
* Returns the length of the data.
*/
- unsigned int
- getLength() const { return mPos; }
+ unsigned int getLength() const { return mPos; }
+
+ /**
+ * Sets whether the debug mode is enabled. In debug mode, the internal
+ * data of the message is annotated so that the message contents can
+ * be printed.
+ *
+ * Debug mode is disabled by default.
+ */
+ static void setDebugModeEnabled(bool enabled);
private:
/**
* Ensures the capacity of the data buffer is large enough to hold the
* given amount of bytes.
*/
- void
- expand(size_t size);
+ void expand(size_t size);
+
+ void writeValueType(ManaServ::ValueType type);
- char *mData; /**< Data building up. */
- unsigned int mPos; /**< Position in the data. */
- unsigned int mDataSize; /**< Allocated datasize. */
+ char *mData; /**< Data building up. */
+ unsigned int mPos; /**< Position in the data. */
+ unsigned int mDataSize; /**< Allocated datasize. */
+ bool mDebugMode; /**< Include debugging information. */
/**
* Streams message ID and length to the given output stream.
@@ -101,4 +107,4 @@ class MessageOut
const MessageOut &msg);
};
-#endif //MESSAGEOUT_H
+#endif // MESSAGEOUT_H