summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/manaserv.xml.example3
-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
12 files changed, 286 insertions, 99 deletions
diff --git a/docs/manaserv.xml.example b/docs/manaserv.xml.example
index 17dc490..4a203d1 100644
--- a/docs/manaserv.xml.example
+++ b/docs/manaserv.xml.example
@@ -180,6 +180,9 @@
<!-- Max connected clients allowed. -->
<option name="net_maxClients" value="1000"/>
+ <!-- Debug mode for network messages (increases bandwidth usage) -->
+ <option name="net_debugMode" value="false"/>
+
<!-- end of network options configuration ********************************* -->
<!-- Accounts configuration ***************************************************
diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp
index 44e65c4..65c5efd 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 a7d87da..c938324 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 0446fa3..63aaa43 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 885d7d2..747c873 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 3d37ea6..3b58e34 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 647a74e..406e7c5 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 e9ec194..5aaf90e 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 022ac46..b797f0a 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 dd82ce5..6d9e3bd 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 a5b0a53..d39fd23 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 1f071f7..a39e306 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