Added a new base class 'BareNetworkString' for NetworkString,

used it for some of the messages exchanged before the ProtocolManager
is started (i.e. establishment of initia connection).
This commit is contained in:
hiker
2016-02-24 20:32:11 +11:00
parent 98ba11d9ba
commit 2e8ddb1c50
16 changed files with 269 additions and 752 deletions

View File

@@ -82,10 +82,9 @@ ENetPeer *Network::connectTo(const TransportAddress &address)
/** \brief Sends a packet whithout ENet adding its headers.
* This function is used in particular to achieve the STUN protocol.
* \param data : Data to send.
* \param length : Length of the sent data.
* \param dst : Destination of the packet.
*/
void Network::sendRawPacket(uint8_t* data, int length,
void Network::sendRawPacket(const BareNetworkString &buffer,
const TransportAddress& dst)
{
struct sockaddr_in to;
@@ -96,10 +95,11 @@ void Network::sendRawPacket(uint8_t* data, int length,
to.sin_port = htons(dst.getPort());
to.sin_addr.s_addr = htonl(dst.getIP());
sendto(m_host->socket, (char*)data, length, 0,(sockaddr*)&to, to_len);
sendto(m_host->socket, buffer.getData(), buffer.size(), 0,
(sockaddr*)&to, to_len);
Log::verbose("Network", "Raw packet sent to %s",
dst.toString().c_str());
Network::logPacket(NewNetworkString(data, length), false);
Network::logPacket(buffer, false);
} // sendRawPacket
// ----------------------------------------------------------------------------
@@ -145,7 +145,7 @@ int Network::receiveRawPacket(char *buffer, int buf_len,
if(len<0)
return -1;
Network::logPacket(NewNetworkString((uint8_t*)buffer, len), true);
Network::logPacket(BareNetworkString(buffer, len), true);
sender->setIP(ntohl((uint32_t)(addr.sin_addr.s_addr)) );
sender->setPort( ntohs(addr.sin_port) );
if (addr.sin_family == AF_INET)
@@ -188,7 +188,7 @@ void Network::openLog()
* \param incoming : True if the packet comes from a peer.
* False if it's sent to a peer.
*/
void Network::logPacket(const NewNetworkString &ns, bool incoming)
void Network::logPacket(const BareNetworkString &ns, bool incoming)
{
if (m_log_file.getData() == NULL) // read only access, no need to lock
return;
@@ -198,12 +198,8 @@ void Network::logPacket(const NewNetworkString &ns, bool incoming)
m_log_file.lock();
fprintf(m_log_file.getData(), "[%d\t] %s ",
(int)(StkTime::getRealTime()), arrow);
for (int i = 0; i < ns.size(); i++)
{
fprintf(m_log_file.getData(), "%d.", ns[i]);
}
fprintf(m_log_file.getData(), "\n");
fprintf(m_log_file.getData(), ns.getLogMessage().c_str());
m_log_file.unlock();
} // logPacket
// ----------------------------------------------------------------------------

View File

@@ -33,6 +33,7 @@
#include <stdio.h>
class BareNetworkString;
class NewNetworkString;
class TransportAddress;
@@ -57,10 +58,10 @@ public:
virtual ~Network();
static void openLog();
static void logPacket(const NewNetworkString &ns, bool incoming);
static void logPacket(const BareNetworkString &ns, bool incoming);
static void closeLog();
ENetPeer *connectTo(const TransportAddress &address);
void sendRawPacket(uint8_t* data, int length,
void sendRawPacket(const BareNetworkString &buffer,
const TransportAddress& dst);
int receiveRawPacket(char *buffer, int buf_len,
TransportAddress* sender, int max_tries = -1);

View File

@@ -14,71 +14,17 @@
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network/network_string.hpp"
#include "utils/string_utils.hpp"
NetworkString operator+(NetworkString const& a, NetworkString const& b)
{
NetworkString ns(a);
ns += b;
return ns;
} // operator+
// ----------------------------------------------------------------------------
/** Adds one byte for the length of the string, and then (up to 255 of)
* the characters of the given string. */
NetworkString& NetworkString::encodeString(const std::string &value)
{
int len = value.size();
if(len<=255)
return addUInt8(len).addString(value);
else
return addUInt8(255).addString(value.substr(0, 255));
} // encodeString
// ----------------------------------------------------------------------------
/** Adds one byte for the length of the string, and then (up to 255 of)
* the characters of the given string. */
NetworkString& NetworkString::encodeString(const irr::core::stringw &value)
{
std::string v = StringUtils::wideToUtf8(value);
return encodeString(v);
} // encodeString
// ----------------------------------------------------------------------------
/** Returns a string at the given position. The first byte indicates the
* length, followed by the actual string (not 0 terminated).
* \param[in] pos Buffer position where the encoded string starts.
* \param[out] out The decoded string.
* \return number of bytes read = 1+length of string
*/
int NetworkString::decodeString(int pos, std::string *out) const
{
uint8_t len = getUInt8(pos);
*out = getString(pos+1, len);
return len+1;
} // decodeString
// ----------------------------------------------------------------------------
/** Returns an irrlicht wide string from the utf8 encoded string at the
* given position.
* \param[in] pos Buffer position where the encoded string starts.
* \param[out] out The decoded string.
* \return number of bytes read. If there are no special characters in the
* string that will be 1+length of string, but multi-byte encoded
* characters can mean that the length of the returned string is
* less than the number of bytes read.
*/
int NetworkString::decodeStringW(int pos, irr::core::stringw *out) const
{
std::string s;
int len = decodeString(pos, &s);
*out = StringUtils::utf8ToWide(s);
return len;
} // decodeString
#include <algorithm> // for std::min
#include <ostream>
// ============================================================================
/** Unit testing function.
*/
void NewNetworkString::unitTesting()
{
NewNetworkString s(PROTOCOL_LOBBY_ROOM);
@@ -120,7 +66,7 @@ void NewNetworkString::unitTesting()
// ----------------------------------------------------------------------------
/** Adds one byte for the length of the string, and then (up to 255 of)
* the characters of the given string. */
NewNetworkString& NewNetworkString::encodeString(const std::string &value)
BareNetworkString& BareNetworkString::encodeString(const std::string &value)
{
int len = value.size();
if(len<=255)
@@ -132,7 +78,7 @@ NewNetworkString& NewNetworkString::encodeString(const std::string &value)
// ----------------------------------------------------------------------------
/** Adds one byte for the length of the string, and then (up to 255 of)
* the characters of the given string. */
NewNetworkString& NewNetworkString::encodeString(const irr::core::stringw &value)
BareNetworkString& BareNetworkString::encodeString(const irr::core::stringw &value)
{
std::string v = StringUtils::wideToUtf8(value);
return encodeString(v);
@@ -145,7 +91,7 @@ NewNetworkString& NewNetworkString::encodeString(const irr::core::stringw &value
* \param[out] out The decoded string.
* \return number of bytes read = 1+length of string
*/
int NewNetworkString::decodeString(int pos, std::string *out) const
int BareNetworkString::decodeString(int pos, std::string *out) const
{
uint8_t len = get<uint8_t>(pos);
*out = getString(pos+1, len);
@@ -162,7 +108,7 @@ int NewNetworkString::decodeString(int pos, std::string *out) const
* characters can mean that the length of the returned string is
* less than the number of bytes read.
*/
int NewNetworkString::decodeStringW(int pos, irr::core::stringw *out) const
int BareNetworkString::decodeStringW(int pos, irr::core::stringw *out) const
{
std::string s;
int len = decodeString(pos, &s);
@@ -170,3 +116,31 @@ int NewNetworkString::decodeStringW(int pos, irr::core::stringw *out) const
return len;
} // decodeString
// ----------------------------------------------------------------------------
/** Returns a string representing this message suitable to be printed
* to stdout or via the Log mechanism. Format
* 0000 : 1234 5678 9abc ... ASCII-
*/
std::string BareNetworkString::getLogMessage() const
{
std::ostringstream oss;
for(unsigned int line=0; line<16; line+=16)
{
oss << line << " : ";
unsigned int upper_limit = std::min(line+16, size());
for(unsigned int i=line; i<upper_limit; i++)
{
oss << getUInt8(i);
if(i%2==1) oss << " ";
} // for i
// Add ascii representation
for(unsigned int i=line; i<upper_limit; i++)
{
oss << getUInt8(i);
} // for i
oss << "\n";
} // for line
return oss.str();
} // getLogMessage

View File

@@ -39,289 +39,198 @@
typedef unsigned char uchar;
/** \class NetworkString
/** \class BareNetworkString
* \brief Describes a chain of 8-bit unsigned integers.
* This class allows you to easily create and parse 8-bit strings.
* This class allows you to easily create and parse 8-bit strings, has
* functions to add and read other data types (e.g. int, strings). It does
* not enforce any structure on the sequence (NetworkString uses this as
* a base class, and enforces a protocol type in the first byte, and a
* 4-byte authentication token in bytes 2-5)
*/
class NetworkString
class BareNetworkString
{
private:
union FloatAsInt
{
float f;
uint8_t i[4];
}; // float as integer
protected:
/** The actual buffer. */
std::vector<uint8_t> m_buffer;
// ------------------------------------------------------------------------
union {
double d;
uint8_t i[8];
} d_as_i; // double as integer
// ------------------------------------------------------------------------
std::vector<uint8_t> m_string;
/** To avoid copying the buffer when bytes are deleted (which only
* happens at the front), use an offset index. All positions given
* by the user will be relative to this index. Note that the type
* should be left as signed, otherwise certain arithmetic (e.g.
* 1-m_current_offset in checkToken() will be done unsigned).
*/
int m_current_offset;
// ------------------------------------------------------------------------
/** Returns a part of the network string as a std::string. This is an
* internal function only, the user should call decodeString(W) instead.
* \param pos First position to be in the string.
* \param len Number of bytes to copy.
*/
* internal function only, the user should call decodeString(W) instead.
* \param pos First position to be in the string.
* \param len Number of bytes to copy.
*/
std::string getString(int pos, int len) const
{
return std::string(m_string.begin() + pos,
m_string.begin() + pos + len);
return std::string(m_buffer.begin() + (m_current_offset+pos ),
m_buffer.begin() + (m_current_offset+pos + len) );
} // getString
public:
/** Dummy constructor. */
NetworkString() { }
// ------------------------------------------------------------------------
/** Constructor to store one byte. */
NetworkString(int len)
{
m_string.reserve(len);
} // NetworkString(int)
// ------------------------------------------------------------------------
/** Copy constructor. */
NetworkString(NetworkString const& copy) { m_string = copy.m_string; }
// ------------------------------------------------------------------------
/** Copy the data from a string. */
NetworkString(const std::string & value)
{
m_string = std::vector<uint8_t>(value.begin(), value.end());
} // NetworkString
// ------------------------------------------------------------------------
NetworkString(const char *p, int len)
{
m_string.resize(len);
memcpy(m_string.data(), p, len);
} // NetworkString(char*, int)
// ------------------------------------------------------------------------
NetworkString& encodeString(const std::string &value);
NetworkString& encodeString(const irr::core::stringw &value);
int decodeString(int n, std::string *out) const;
int decodeStringW(int n, irr::core::stringw *out) const;
// ------------------------------------------------------------------------
NetworkString& removeFront(int size)
{
m_string.erase(m_string.begin(), m_string.begin() + size);
return *this;
} // removeFront
// ------------------------------------------------------------------------
NetworkString& remove(int pos, int size)
{
m_string.erase(m_string.begin() + pos, m_string.begin() + pos + size);
return *this;
} // remove
// ------------------------------------------------------------------------
uint8_t operator[](const int& pos) const
{
return getUInt8(pos);
} // operator[]
// ------------------------------------------------------------------------
/** Add 8 bit unsigned int. */
NetworkString& addUInt8(const uint8_t& value)
{
m_string.push_back(value);
return *this;
} // addUInt8
// ------------------------------------------------------------------------
/** Adds 8 bit integer. */
inline NetworkString& ai8(const uint8_t& value) { return addUInt8(value); }
// ------------------------------------------------------------------------
/** Adds 16 bit unsigned int. */
NetworkString& addUInt16(const uint16_t& value)
{
m_string.push_back((value >> 8) & 0xff);
m_string.push_back(value & 0xff);
return *this;
} // addUInt16
// ------------------------------------------------------------------------
/** Adds 16 bit integer. */
inline NetworkString& ai16(const uint16_t& value)
{
return addUInt16(value);
} // ai16
// ------------------------------------------------------------------------
/** Adds unsigned 32 bit integer. */
NetworkString& addUInt32(const uint32_t& value)
{
m_string.push_back((value >> 24) & 0xff);
m_string.push_back((value >> 16) & 0xff);
m_string.push_back((value >> 8) & 0xff);
m_string.push_back(value & 0xff);
return *this;
} // addUInt32
// ------------------------------------------------------------------------
/** Adds 32 bit integer. */
inline NetworkString& ai32(const uint32_t& value)
{
return addUInt32(value);
} // ai32
// ------------------------------------------------------------------------
NetworkString& addInt(const int& value)
{
m_string.push_back((value >> 24) & 0xff);
m_string.push_back((value >> 16) & 0xff);
m_string.push_back((value >> 8) & 0xff);
m_string.push_back(value & 0xff);
return *this;
} // addInt
// ------------------------------------------------------------------------
inline NetworkString& ai(const int& value) { return addInt(value); }
// ------------------------------------------------------------------------
/** Adds a 4 byte floating point value. */
NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION
{
assert(sizeof(float) == 4);
FloatAsInt f_as_i;
f_as_i.f = value;
m_string.push_back(f_as_i.i[0]);
m_string.push_back(f_as_i.i[1]);
m_string.push_back(f_as_i.i[2]);
m_string.push_back(f_as_i.i[3]);
return *this;
}
// ------------------------------------------------------------------------
/** Adds a 4 byte floating point value. */
inline NetworkString& af(const float& value) { return addFloat(value); }
// ------------------------------------------------------------------------
/** Adds a 8 byte floating point value. */
NetworkString& addDouble(const double& value) //!< BEWARE OF PRECISION
{
assert(sizeof(double) == 8);
d_as_i.d = value;
m_string.push_back(d_as_i.i[0]);
m_string.push_back(d_as_i.i[1]);
m_string.push_back(d_as_i.i[2]);
m_string.push_back(d_as_i.i[3]);
m_string.push_back(d_as_i.i[4]);
m_string.push_back(d_as_i.i[5]);
m_string.push_back(d_as_i.i[6]);
m_string.push_back(d_as_i.i[7]);
return *this;
} // addDouble
// ------------------------------------------------------------------------
/** Adds n 8 byte floating point value. */
inline NetworkString& ad(const double& value) { return addDouble(value); }
// ------------------------------------------------------------------------
/** Adds a single character to the string. */
NetworkString& addChar(const char& value)
{
m_string.push_back((uint8_t)(value));
return *this;
} // addChar
// ------------------------------------------------------------------------
/** Adds a single character. */
inline NetworkString& ac(const char& value) { return addChar(value); }
/** Adds a string. */
NetworkString& addString(const std::string& value)
/** Adds a std::string. Internal use only. */
BareNetworkString& addString(const std::string& value)
{
for (unsigned int i = 0; i < value.size(); i++)
m_string.push_back((uint8_t)(value[i]));
m_buffer.push_back((uint8_t)(value[i]));
return *this;
}
// ------------------------------------------------------------------------
/** Adds a string. */
inline NetworkString& as(const std::string& value)
{
return addString(value);
} // as
// ------------------------------------------------------------------------
/** Adds the content of another network string. */
NetworkString& operator+=(NetworkString const& value)
{
m_string.insert(m_string.end(), value.m_string.begin(),
value.m_string.end() );
return *this;
} // operator+=
// ------------------------------------------------------------------------
/** Adds the xyz components of a Vec3 to the string. */
NetworkString& add(const Vec3 &xyz)
{
return addFloat(xyz.getX()).addFloat(xyz.getY()).addFloat(xyz.getZ());
} // add
// ------------------------------------------------------------------------
/** Adds the four components of a quaternion. */
NetworkString& add(const btQuaternion &quat)
{
return addFloat(quat.getX()).addFloat(quat.getY())
.addFloat(quat.getZ()).addFloat(quat.getW());
} // add
// ------------------------------------------------------------------------
/** Returns the content of the network string as a std::string. */
const std::string std_string() const
{
std::string str(m_string.begin(), m_string.end());
return str;
} // std_string
// ------------------------------------------------------------------------
/** Returns the current length of the network string. */
int size() const { return (int)m_string.size(); }
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
uint8_t* getBytes() { return &m_string[0]; };
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
const uint8_t* getBytes() const { return &m_string[0]; };
} // addString
// ------------------------------------------------------------------------
/** Template to get n bytes from a buffer into a single data type. */
template<typename T, size_t n>
T get(int pos) const
{
int a = n;
T result = 0;
int offset = m_current_offset + pos + n -1;
while (a--)
{
result <<= 8; // offset one byte
// add the data to result
result += ((uint8_t)(m_string[pos + n - 1 - a]) & 0xff);
// add the data to result
result += m_buffer[offset - a];
}
return result;
} // get(int pos)
// ------------------------------------------------------------------------
// Another function for n == 1 to surpress warnings in clang
/** Another function for n == 1 to surpress warnings in clang. */
template<typename T>
T get(int pos) const
{
return m_string[pos];
return m_buffer[pos];
} // get
public:
/** Constructor, sets the protocol type of this message. */
BareNetworkString(int capacity=16)
{
m_buffer.reserve(capacity);
m_current_offset = 0;
} // BareNetworkString
// ------------------------------------------------------------------------
/** Returns a standard integer. */
inline int getInt(int pos = 0) const { return get<int, 4>(pos); }
BareNetworkString(const std::string &s)
{
encodeString(s);
} // BareNetworkString
// ------------------------------------------------------------------------
/** Returns a standard unsigned integer. */
inline uint32_t getUInt(int pos = 0) const { return get<uint32_t, 4>(pos); }
/** Initialises the string with a sequence of characters. */
BareNetworkString(const char *data, int len)
{
m_buffer.resize(len);
memcpy(m_buffer.data(), data, len);
} // BareNetworkString
// ------------------------------------------------------------------------
BareNetworkString& encodeString(const std::string &value);
BareNetworkString& encodeString(const irr::core::stringw &value);
int decodeString(int n, std::string *out) const;
int decodeStringW(int n, irr::core::stringw *out) const;
std::string getLogMessage() const;
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
char* getData() { return (char*)(m_buffer.data()); };
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
const char* getData() const { return (char*)(m_buffer.data()); };
// ------------------------------------------------------------------------
/** Returns the current length of the network string. */
unsigned int size() const { return (int)m_buffer.size(); }
// ------------------------------------------------------------------------
// All functions related to adding data to a network string
/** Add 8 bit unsigned int. */
BareNetworkString& addUInt8(const uint8_t value)
{
m_buffer.push_back(value);
return *this;
} // addUInt8
// ------------------------------------------------------------------------
/** Adds a single character to the string. */
BareNetworkString& addChar(const char& value)
{
m_buffer.push_back((uint8_t)(value));
return *this;
} // addChar
// ------------------------------------------------------------------------
/** Adds 16 bit unsigned int. */
BareNetworkString& addUInt16(const uint16_t value)
{
m_buffer.push_back((value >> 8) & 0xff);
m_buffer.push_back(value & 0xff);
return *this;
} // addUInt16
// ------------------------------------------------------------------------
/** Adds unsigned 32 bit integer. */
BareNetworkString& addUInt32(const uint32_t& value)
{
m_buffer.push_back((value >> 24) & 0xff);
m_buffer.push_back((value >> 16) & 0xff);
m_buffer.push_back((value >> 8) & 0xff);
m_buffer.push_back( value & 0xff);
return *this;
} // addUInt32
// ------------------------------------------------------------------------
/** Adds a 4 byte floating point value. */
BareNetworkString& addFloat(const float value)
{
uint32_t *p = (uint32_t*)&value;
return addUInt32(*p);
} // addFloat
// ------------------------------------------------------------------------
/** Adds the content of another network string. */
BareNetworkString& operator+=(BareNetworkString const& value)
{
m_buffer.insert(m_buffer.end(), value.m_buffer.begin(),
value.m_buffer.end() );
return *this;
} // operator+=
// ------------------------------------------------------------------------
/** Adds the xyz components of a Vec3 to the string. */
BareNetworkString& add(const Vec3 &xyz)
{
return addFloat(xyz.getX()).addFloat(xyz.getY()).addFloat(xyz.getZ());
} // add
// ------------------------------------------------------------------------
/** Adds the four components of a quaternion. */
BareNetworkString& add(const btQuaternion &quat)
{
return addFloat(quat.getX()).addFloat(quat.getY())
.addFloat(quat.getZ()).addFloat(quat.getW());
} // add
// Functions related to getting data from a network string
// ------------------------------------------------------------------------
/** Ignore the next num_bytes from the message. */
void removeFront(unsigned int num_bytes)
{
assert(m_current_offset + num_bytes <= m_buffer.size());
m_current_offset += num_bytes;
} // removeFront
// ------------------------------------------------------------------------
/** Gets the byte at the specified position (taking current offset into
* account). */
uint8_t operator[](const int pos) const
{
return m_buffer[m_current_offset + pos];
} // operator[]
// ------------------------------------------------------------------------
/** Returns a unsigned 32 bit integer. */
inline uint32_t getUInt32(int pos = 0) const { return get<uint32_t, 4>(pos); }
@@ -330,216 +239,38 @@ public:
inline uint16_t getUInt16(int pos=0) const { return get<uint16_t, 2>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 8-bit integer. */
inline uint8_t getUInt8(int pos = 0) const { return get<uint8_t>(pos); }
// ------------------------------------------------------------------------
/** Returns a character. */
inline char getChar(int pos = 0) const { return get<char>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned character. */
inline unsigned char getUChar(int pos = 0) const
inline uint8_t getUInt8(int pos = 0) const
{
return get<unsigned char>(pos);
} // getUChar
// ------------------------------------------------------------------------
/** Returns a standard integer. */
inline int gi(int pos = 0) const { return get<int, 4>(pos); }
// ------------------------------------------------------------------------
/** Retrusn an unsigned standard integer. */
inline uint32_t gui(int pos = 0) const { return get<uint32_t, 4>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 32-bit integer. */
inline uint32_t gui32(int pos = 0) const { return get<uint32_t, 4>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 16-bit integer. */
inline uint16_t gui16(int pos = 0) const { return get<uint16_t, 2>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 8-bit integer. */
inline uint8_t gui8(int pos = 0) const { return get<uint8_t>(pos); }
// ------------------------------------------------------------------------
/** Return a character. */
inline char gc(int pos = 0) const { return get<char>(pos); }
// ------------------------------------------------------------------------
/** Return an unsigned character. */
inline unsigned char guc(int pos = 0) const
{
return get<unsigned char>(pos);
} // guc
return m_buffer[m_current_offset + pos];
} // getUInt8
// ------------------------------------------------------------------------
/** Returns a 4-byte floating point value. */
float getFloat(int pos = 0) const //!< BEWARE OF PRECISION
/** Gets a 4 byte floating point value. */
float getFloat(int pos=0) const
{
FloatAsInt f_as_i;
for (int i = 0; i < 4; i++)
f_as_i.i[i] = m_string[pos + i];
return f_as_i.f;
} // getFloat
uint32_t u = getUInt32(pos);
return *(float*)&u;
} // getFloat
// ------------------------------------------------------------------------
//! Functions to get while removing
template<typename T, size_t n>
T getAndRemove(int pos)
/** Gets a Vec3. */
Vec3 getVec3(int pos=0) const
{
int a = n;
T result = 0;
while (a--)
{
result <<= 8; // offset one byte
result += ((uint8_t)(m_string[pos + n - 1 - a]) & 0xff); // add the data
}
remove(pos, n);
return result;
} // getAndRemove
return Vec3(getFloat(pos), getFloat(pos+4), getFloat(pos+8));
} // getVec3
// ------------------------------------------------------------------------
// Another function for n == 1 to surpress warnings in clang
template<typename T>
T getAndRemove(int pos)
/** Gets a Vec3. */
btQuaternion getQuat(int pos=0) const
{
T result = m_string[pos];
remove(pos, 1);
return result;
} // getAndRemove
return btQuaternion(getFloat(pos), getFloat(pos+ 4),
getFloat(pos+8), getFloat(pos+12) );
} // getQuat
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
inline int getAndRemoveInt(int pos = 0)
{
return getAndRemove<int, 4>(pos);
} // getAndRemoveInt
}; // class BareNetworkString
// ------------------------------------------------------------------------
inline uint32_t getAndRemoveUInt(int pos = 0)
{
return getAndRemove<uint32_t, 4>(pos);
} // getAndRemoveUInt
// ------------------------------------------------------------------------
inline uint32_t getAndRemoveUInt32(int pos = 0)
{
return getAndRemove<uint32_t, 4>(pos);
} // getAndRemoveUInt32
// ------------------------------------------------------------------------
inline uint16_t getAndRemoveUInt16(int pos = 0)
{
return getAndRemove<uint16_t, 2>(pos);
} // getAndRemoveUInt16
// ------------------------------------------------------------------------
inline uint8_t getAndRemoveUInt8(int pos = 0)
{
return getAndRemove<uint8_t>(pos);
} // getAndRemoveUInt8
// ------------------------------------------------------------------------
inline char getAndRemoveChar(int pos = 0)
{
return getAndRemove<char>(pos);
} // getAndRemoveChar
// ------------------------------------------------------------------------
inline unsigned char getAndRemoveUChar(int pos = 0)
{
return getAndRemove<unsigned char>(pos);
} // getAndRemoveUChar
// ------------------------------------------------------------------------
double getAndRemoveDouble(int pos = 0) //!< BEWARE OF PRECISION
{
for (int i = 0; i < 8; i++)
d_as_i.i[i] = m_string[pos + i];
return d_as_i.d;
remove(pos, 8);
} // getAndRemoveDouble
// ------------------------------------------------------------------------
/** Get and remove a 4 byte floating point value. */
float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION
{
FloatAsInt f_as_i;
for (int i = 0; i < 4; i++)
f_as_i.i[i] = m_string[pos + i];
return f_as_i.f;
remove(pos, 4);
} // getAndRemoveFloat
// ------------------------------------------------------------------------
/** Removes a 8 bit unsigned int. */
inline NetworkString& gui8(uint8_t* dst)
{
*dst = getAndRemoveUInt8(0);
return *this;
} // gui8
// ------------------------------------------------------------------------
/** Returns a 16 bit integer. */
inline NetworkString& gui16(uint16_t* dst)
{
*dst = getAndRemoveUInt16(0);
return *this;
} // gui16
// ------------------------------------------------------------------------
/** Returns a 32 bit integer. */
inline NetworkString& gui32(uint32_t* dst)
{
*dst = getAndRemoveUInt32(0);
return *this;
} // gui32
// ------------------------------------------------------------------------
/** Returns a 32 bit integer. */
inline NetworkString& gui(uint32_t* dst)
{
*dst = getAndRemoveUInt32(0);
return *this;
} // gui
// ------------------------------------------------------------------------
/** Returns 4 byte integer. */
inline NetworkString& gi(int* dst)
{
*dst = getAndRemoveInt(0);
return *this;
} // gi
// ------------------------------------------------------------------------
/** Returns a single character. */
inline NetworkString& gc(char* dst)
{
*dst = getAndRemoveChar(0);
return *this;
} // gc
// ------------------------------------------------------------------------
/** Returns an unsigned character. */
inline NetworkString& guc(uchar* dst)
{
*dst = getAndRemoveUChar(0);
return *this;
} // guc
// ------------------------------------------------------------------------
/** Reads the three components of a Vec3 from the given position. */
NetworkString& get(Vec3 *xyz, int pos)
{
xyz->setX(getFloat(pos ));
xyz->setY(getFloat(pos+4));
xyz->setZ(getFloat(pos+8));
return *this;
} // addVec3
// ------------------------------------------------------------------------
/** Reads the four components of a quaternion from the given position. */
NetworkString& get(btQuaternion *quat, int pos)
{
quat->setX(getFloat(pos ));
quat->setY(getFloat(pos+ 4));
quat->setZ(getFloat(pos+ 8));
quat->setW(getFloat(pos+12));
return *this;
} // addVec3
}; // class NetworkString
NetworkString operator+(NetworkString const& a, NetworkString const& b);
// ============================================================================
/** A new implementation of NetworkString, which has a fixed format:
@@ -557,66 +288,24 @@ NetworkString operator+(NetworkString const& a, NetworkString const& b);
* so that the protocols would not see this byte). But this is implemented
* now by using a base pointer (and not by moving the buffer content).
*/
class NewNetworkString
class NewNetworkString : public BareNetworkString
{
private:
/** The actual buffer. */
std::vector<uint8_t> m_buffer;
/** To avoid copying the buffer when bytes are deleted (which only
* happens at the front), use an offset index. All positions given
* by the user will be relative to this index. Note that the type
* should be left as signed, otherwise certain arithmetic (e.g.
* 1-m_current_offset in checkToken() will be done unsigned).
*/
int m_current_offset;
// ------------------------------------------------------------------------
/** Returns a part of the network string as a std::string. This is an
* internal function only, the user should call decodeString(W) instead.
* \param pos First position to be in the string.
* \param len Number of bytes to copy.
*/
std::string getString(int pos, int len) const
{
return std::string(m_buffer.begin() + (m_current_offset+pos ),
m_buffer.begin() + (m_current_offset+pos + len) );
} // getString
// ------------------------------------------------------------------------
/** Adds a std::string. Internal use only. */
NewNetworkString& addString(const std::string& value)
{
for (unsigned int i = 0; i < value.size(); i++)
m_buffer.push_back((uint8_t)(value[i]));
return *this;
} // addString
public:
static void unitTesting();
/** Constructor, sets the protocol type of this message. */
NewNetworkString(ProtocolType type, int capacity=16)
: BareNetworkString(capacity)
{
m_buffer.reserve(capacity);
m_buffer.push_back(type);
m_current_offset = 0;
} // NewNetworkString
// ------------------------------------------------------------------------
NewNetworkString(const uint8_t *data, int len)
NewNetworkString(const uint8_t *data, int len)
: BareNetworkString((char*)data, len)
{
m_buffer.resize(len);
memcpy(m_buffer.data(), data, len);
} // NewNetworkString
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
uint8_t* getData() { return &m_buffer[0]; };
// ------------------------------------------------------------------------
/** Returns a byte pointer to the content of the network string. */
const uint8_t* getData() const { return &m_buffer[0]; };
// ------------------------------------------------------------------------
/** Returns the protocol type of this message. */
ProtocolType getProtocolType() const
@@ -665,163 +354,6 @@ public:
// to really access bytes 1-4
return getUInt32(1-m_current_offset);
} // getToken
// ------------------------------------------------------------------------
/** Returns the current length of the network string. */
int size() const { return (int)m_buffer.size(); }
// ------------------------------------------------------------------------
/** Returns the content of the network string as a std::string. */
const std::string std_string() const
{
std::string str(m_buffer.begin(), m_buffer.end());
return str;
} // std_string
// ------------------------------------------------------------------------
// All functions related to adding data to a network string
// ========================================================
/** Add 8 bit unsigned int. */
NewNetworkString& addUInt8(const uint8_t value)
{
m_buffer.push_back(value);
return *this;
} // addUInt8
// ------------------------------------------------------------------------
/** Adds 16 bit unsigned int. */
NewNetworkString& addUInt16(const uint16_t value)
{
m_buffer.push_back((value >> 8) & 0xff);
m_buffer.push_back(value & 0xff);
return *this;
} // addUInt16
// ------------------------------------------------------------------------
/** Adds unsigned 32 bit integer. */
NewNetworkString& addUInt32(const uint32_t& value)
{
m_buffer.push_back((value >> 24) & 0xff);
m_buffer.push_back((value >> 16) & 0xff);
m_buffer.push_back((value >> 8) & 0xff);
m_buffer.push_back( value & 0xff);
return *this;
} // addUInt32
// ------------------------------------------------------------------------
/** Adds a 4 byte floating point value. */
NewNetworkString& addFloat(const float value)
{
uint32_t *p = (uint32_t*)&value;
return addUInt32(*p);
} // addFloat
// ------------------------------------------------------------------------
/** Adds the content of another network string. */
NewNetworkString& operator+=(NewNetworkString const& value)
{
m_buffer.insert(m_buffer.end(), value.m_buffer.begin(),
value.m_buffer.end() );
return *this;
} // operator+=
// ------------------------------------------------------------------------
/** Adds the xyz components of a Vec3 to the string. */
NewNetworkString& add(const Vec3 &xyz)
{
return addFloat(xyz.getX()).addFloat(xyz.getY()).addFloat(xyz.getZ());
} // add
// ------------------------------------------------------------------------
/** Adds the four components of a quaternion. */
NewNetworkString& add(const btQuaternion &quat)
{
return addFloat(quat.getX()).addFloat(quat.getY())
.addFloat(quat.getZ()).addFloat(quat.getW());
} // add
// Functions related to getting data from a network string
// =======================================================
/** Ignore the next num_bytes from the message.
*/
void removeFront(unsigned int num_bytes)
{
assert(m_current_offset + num_bytes <= m_buffer.size());
m_current_offset += num_bytes;
} // removeFront
// ------------------------------------------------------------------------
/** Gets the byte at the specified position (taking current offset into
* account). */
uint8_t operator[](const int pos) const
{
return m_buffer[m_current_offset + pos];
} // operator[]
private:
// ------------------------------------------------------------------------
/** Template to get n bytes from a buffer into a single data type. */
template<typename T, size_t n>
T get(int pos) const
{
int a = n;
T result = 0;
int offset = m_current_offset + pos + n -1;
while (a--)
{
result <<= 8; // offset one byte
// add the data to result
result += m_buffer[offset - a];
}
return result;
} // get(int pos)
// ------------------------------------------------------------------------
/** Another function for n == 1 to surpress warnings in clang. */
template<typename T>
T get(int pos) const
{
return m_buffer[pos];
} // get
public:
// ------------------------------------------------------------------------
/** Returns a unsigned 32 bit integer. */
inline uint32_t getUInt32(int pos = 0) const { return get<uint32_t, 4>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 16 bit integer. */
inline uint16_t getUInt16(int pos=0) const { return get<uint16_t, 2>(pos); }
// ------------------------------------------------------------------------
/** Returns an unsigned 8-bit integer. */
inline uint8_t getUInt8(int pos = 0) const
{
return m_buffer[m_current_offset + pos];
} // getUInt8
// ------------------------------------------------------------------------
/** Gets a 4 byte floating point value. */
float getFloat(int pos=0) const
{
uint32_t u = getUInt32(pos);
return *(float*)&u;
} // getFloat
// ------------------------------------------------------------------------
/** Gets a Vec3. */
Vec3 getVec3(int pos=0) const
{
return Vec3(getFloat(pos), getFloat(pos+4), getFloat(pos+8));
} // getVec3
// ------------------------------------------------------------------------
/** Gets a Vec3. */
btQuaternion getQuat(int pos=0) const
{
return btQuaternion(getFloat(pos), getFloat(pos+ 4),
getFloat(pos+8), getFloat(pos+12) );
} // getQuat
// ------------------------------------------------------------------------
NewNetworkString& encodeString(const std::string &value);
NewNetworkString& encodeString(const irr::core::stringw &value);
int decodeString(int n, std::string *out) const;
int decodeStringW(int n, irr::core::stringw *out) const;
// ------------------------------------------------------------------------
}; // class NetworkString

View File

@@ -57,7 +57,7 @@ NewNetworkString* Protocol::getNetworkString(int capacity)
} // getNetworkString
// ----------------------------------------------------------------------------
bool Protocol::checkDataSizeAndToken(Event* event, int minimum_size)
bool Protocol::checkDataSizeAndToken(Event* event, unsigned int minimum_size)
{
const NewNetworkString &data = event->data();
if (data.size() < minimum_size || data[0] != 4)

View File

@@ -122,7 +122,7 @@ public:
/// functions to check incoming data easily
NewNetworkString* getNetworkString(int capacity=16);
bool checkDataSizeAndToken(Event* event, int minimum_size);
bool checkDataSizeAndToken(Event* event, unsigned int minimum_size);
bool isByteCorrect(Event* event, int byte_nb, int value);
void sendMessageToPeersChangingToken(NewNetworkString *message);
void sendMessage(const NewNetworkString &message,

View File

@@ -150,8 +150,17 @@ void ProtocolManager::propagateEvent(Event* event)
// no protocol was aimed, show the msg to debug
if (searched_protocol == PROTOCOL_NONE)
{
std::ostringstream oss;
for(unsigned int i=0; i<event->data().size(); i++)
{
oss << event->data()[i];
if(i%16==0)
oss << "\n";
else if (i % 4 == 0)
oss << ' ';
}
Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"",
event->data().std_string().c_str());
oss.str().c_str());
}
if (protocols_ids.size() != 0)

View File

@@ -441,7 +441,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event)
// Add all players
// ===============
int n = 9;
unsigned int n = 9;
while (n < data.size())
{
if (data[n] != 1 )

View File

@@ -141,14 +141,14 @@ void ConnectToPeer::asynchronousUpdate()
else
broadcast_address.copy(m_peer_address);
char data[] = "aloha_stk\0";
STKHost::get()->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
BareNetworkString aloha(std::string("aloha_stk"));
STKHost::get()->sendRawPacket(aloha, broadcast_address);
Log::info("ConnectToPeer", "Broadcast aloha sent.");
StkTime::sleep(1);
broadcast_address.setIP(0x7f000001); // 127.0.0.1 (localhost)
broadcast_address.setPort(m_peer_address.getPort());
STKHost::get()->sendRawPacket((uint8_t*)(data), 10, broadcast_address);
STKHost::get()->sendRawPacket(aloha, broadcast_address);
Log::info("ConnectToPeer", "Broadcast aloha to self.");
m_state = CONNECTING;
break;

View File

@@ -378,9 +378,13 @@ void ConnectToServer::handleSameLAN()
char buffer[LEN];
int len = host->receiveRawPacket(buffer, LEN, &sender, 2000);
BareNetworkString message(buffer, len
);
std::string received;
message.decodeString(0, &received);
host->startListening(); // start listening again
const char data[] = "aloha_stk\0";
if (strcmp(data, buffer) == 0)
std::string aloha("aloha_stk");
if (received==aloha)
{
Log::info("ConnectToServer", "LAN Server found : %s",
sender.toString().c_str());

View File

@@ -90,14 +90,14 @@ void GetPublicAddress::createStunRequest()
m_transaction_host = new Network(1, 1, 0, 0);
// Assemble the message for the stun server
NetworkString s(21);
BareNetworkString s(21);
// bytes 0-1: the type of the message
// bytes 2-3: message length added to header (attributes)
uint16_t message_type = 0x0001; // binding request
uint16_t message_length = 0x0000;
s.addUInt16(message_type).addUInt16(message_length)
.addInt(0x2112A442);
.addUInt32(0x2112A442);
// bytes 8-19: the transaction id
for (int i = 0; i < 12; i++)
{
@@ -108,7 +108,7 @@ void GetPublicAddress::createStunRequest()
s.addChar(0);
m_transaction_host->sendRawPacket(s.getBytes(), 20,
m_transaction_host->sendRawPacket(s,
TransportAddress(m_stun_server_ip,
m_stun_server_port) );
freeaddrinfo(res);
@@ -140,7 +140,7 @@ std::string GetPublicAddress::parseStunResponse()
return "STUN response contains no data at all";
// Convert to network string.
NetworkString datas(std::string(buffer, len));
NewNetworkString datas((uint8_t*)buffer, len);
// check that the stun response is a response, contains the magic cookie
// and the transaction ID

View File

@@ -50,8 +50,9 @@ void PingProtocol::asynchronousUpdate()
if (StkTime::getRealTime() > m_last_ping_time+m_delay_between_pings)
{
m_last_ping_time = StkTime::getRealTime();
uint8_t data = 0;
STKHost::get()->sendRawPacket(&data, 1, m_ping_dst);
BareNetworkString data;
data.addUInt8(0);
STKHost::get()->sendRawPacket(data, m_ping_dst);
Log::info("PingProtocol", "Ping message sent");
}
} // asynchronousUpdate

View File

@@ -79,9 +79,8 @@ void RequestConnection::asynchronousUpdate()
{
const Server *server =
ServersManager::get()->getServerByID(m_server_id);
NetworkString s(std::string("connection-request"));
STKHost::get()->sendRawPacket(s.getBytes(), s.size(),
server->getAddress());
BareNetworkString message(std::string("connection-request"));
STKHost::get()->sendRawPacket(message, server->getAddress());
m_state = DONE;
}
else

View File

@@ -152,9 +152,9 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const
{
Network *broadcast = new Network(1, 1, 0, 0);
NetworkString s(std::string("stk-server"));
BareNetworkString s(std::string("stk-server"));
TransportAddress broadcast_address(-1, 2757);
broadcast->sendRawPacket(s.getBytes(), s.size(), broadcast_address);
broadcast->sendRawPacket(s, broadcast_address);
Log::info("ServersManager", "Sent broadcast message.");
@@ -170,7 +170,7 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const
int len = broadcast->receiveRawPacket(buffer, LEN, &sender, 1);
if(len>0)
{
NetworkString s(buffer, len);
NewNetworkString s((uint8_t*)buffer, len);
irr::core::stringw name;
// name_len is the number of bytes read
uint8_t bytes_read = s.decodeStringW(0, &name);

View File

@@ -564,8 +564,9 @@ void* STKHost::mainLoop(void* self)
TransportAddress stk_addr(peer->getAddress());
Log::verbose("NetworkManager",
"Message, Sender : %s, message = \"%s\"",
stk_addr.toString(/*show port*/false).c_str(),
stk_event->data().std_string().c_str());
stk_addr.toString(/*show port*/false).c_str());
Log::verbose("NetworkManager",
stk_event->data().getLogMessage().c_str());
} // if message event
@@ -604,13 +605,13 @@ void STKHost::handleLANRequests()
// current players, and the client's ip address and port
// number (which solves the problem which network interface
// might be the right one if there is more than one).
NewNetworkString s(PROTOCOL_NONE);
BareNetworkString s(name.size()+1+8);
s.encodeString(name);
s.addUInt8(NetworkConfig::get()->getMaxPlayers());
s.addUInt8(0); // FIXME: current number of connected players
s.addUInt32(sender.getIP());
s.addUInt16(sender.getPort());
m_lan_network->sendRawPacket(s.getData(), s.size(), sender);
m_lan_network->sendRawPacket(s, sender);
} // if message is server-requested
else if (std::string(buffer, len) == "connection-request")
{

View File

@@ -188,10 +188,10 @@ public:
} // broadcastPacket
// --------------------------------------------------------------------
void sendRawPacket(uint8_t* data, int length,
void sendRawPacket(const BareNetworkString &buffer,
const TransportAddress& dst)
{
m_network->sendRawPacket(data, length, dst);
m_network->sendRawPacket(buffer, dst);
} // sendRawPacket
// --------------------------------------------------------------------