00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "net/messagein.h"
00023
00024 #ifdef TMWSERV_SUPPORT
00025 #include <enet/enet.h>
00026 #else
00027 #include <SDL.h>
00028 #include <SDL_endian.h>
00029 #endif
00030
00031 #define MAKEWORD(low,high) \
00032 ((unsigned short)(((unsigned char)(low)) | \
00033 ((unsigned short)((unsigned char)(high))) << 8))
00034
00035 MessageIn::MessageIn(const char *data, unsigned int length):
00036 mData(data),
00037 mLength(length),
00038 mPos(0)
00039 {
00040
00041 mId = readInt16();
00042 }
00043
00044 int MessageIn::readInt8()
00045 {
00046 int value = -1;
00047 if (mPos < mLength)
00048 {
00049 value = (unsigned char) mData[mPos];
00050 }
00051 mPos += 1;
00052 return value;
00053 }
00054
00055 int MessageIn::readInt16()
00056 {
00057 int value = -1;
00058 if (mPos + 2 <= mLength)
00059 {
00060 #ifdef TMWSERV_SUPPORT
00061 uint16_t t;
00062 memcpy(&t, mData + mPos, 2);
00063 value = (unsigned short) ENET_NET_TO_HOST_16(t);
00064 #else
00065 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00066 value = SDL_Swap16(*(Sint16*)(mData + mPos));
00067 #else
00068 value = (*(Sint16*)(mData + mPos));
00069 #endif
00070 #endif // TMWSERV_SUPPORT
00071 }
00072 mPos += 2;
00073 return value;
00074 }
00075
00076 int MessageIn::readInt32()
00077 {
00078 int value = -1;
00079 if (mPos + 4 <= mLength)
00080 {
00081 #ifdef TMWSERV_SUPPORT
00082 uint32_t t;
00083 memcpy(&t, mData + mPos, 4);
00084 value = ENET_NET_TO_HOST_32(t);
00085 #else
00086 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
00087 value = SDL_Swap32(*(Sint32*)(mData + mPos));
00088 #else
00089 value = (*(Sint32*)(mData + mPos));
00090 #endif
00091 #endif // TMWSERV_SUPPORT
00092 }
00093 mPos += 4;
00094 return value;
00095 }
00096
00097 void MessageIn::readCoordinates(Uint16 &x, Uint16 &y)
00098 {
00099 if (mPos + 3 <= mLength)
00100 {
00101 unsigned char const *p = reinterpret_cast< unsigned char const * >(mData + mPos);
00102 x = p[0] | ((p[1] & 0x07) << 8);
00103 y = (p[1] >> 3) | ((p[2] & 0x3F) << 5);
00104 }
00105 mPos += 3;
00106 }
00107
00108 void MessageIn::readCoordinates(Uint16 &x, Uint16 &y, Uint8 &direction)
00109 {
00110 if (mPos + 3 <= mLength)
00111 {
00112 const char *data = mData + mPos;
00113 Sint16 temp;
00114
00115 temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff);
00116 x = temp >> 6;
00117 temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f);
00118 y = temp >> 4;
00119
00120 direction = data[2] & 0x000f;
00121
00122
00123 switch (direction)
00124 {
00125 case 0:
00126 direction = 1;
00127 break;
00128 case 1:
00129 direction = 3;
00130 break;
00131 case 2:
00132 direction = 2;
00133 break;
00134 case 3:
00135 direction = 6;
00136 break;
00137 case 4:
00138 direction = 4;
00139 break;
00140 case 5:
00141 direction = 12;
00142 break;
00143 case 6:
00144 direction = 8;
00145 break;
00146 case 7:
00147 direction = 9;
00148 break;
00149 default:
00150
00151 direction = 0;
00152 }
00153 }
00154 mPos += 3;
00155 }
00156
00157 void MessageIn::readCoordinatePair(Uint16 &srcX, Uint16 &srcY,
00158 Uint16 &dstX, Uint16 &dstY)
00159 {
00160 if (mPos + 5 <= mLength)
00161 {
00162 const char *data = mData + mPos;
00163 Sint16 temp;
00164
00165 temp = MAKEWORD(data[3], data[2] & 0x000f);
00166 dstX = temp >> 2;
00167
00168 dstY = MAKEWORD(data[4], data[3] & 0x0003);
00169
00170 temp = MAKEWORD(data[1], data[0]);
00171 srcX = temp >> 6;
00172
00173 temp = MAKEWORD(data[2], data[1] & 0x003f);
00174 srcY = temp >> 4;
00175 }
00176 mPos += 5;
00177 }
00178
00179 void MessageIn::skip(unsigned int length)
00180 {
00181 mPos += length;
00182 }
00183
00184 std::string MessageIn::readString(int length)
00185 {
00186
00187 if (length < 0)
00188 length = readInt16();
00189
00190
00191 if (length < 0 || mPos + length > mLength) {
00192 mPos = mLength + 1;
00193 return "";
00194 }
00195
00196
00197 char const *stringBeg = mData + mPos;
00198 char const *stringEnd = (char const *)memchr(stringBeg, '\0', length);
00199 std::string readString(stringBeg,
00200 stringEnd ? stringEnd - stringBeg : length);
00201 mPos += length;
00202 return readString;
00203 }