GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/messagein.cpp Lines: 0 156 0.0 %
Date: 2017-11-29 Branches: 0 196 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2004-2009  The Mana World Development Team
4
 *  Copyright (C) 2009-2010  The Mana Developers
5
 *  Copyright (C) 2011-2017  The ManaPlus Developers
6
 *
7
 *  This file is part of The ManaPlus Client.
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
#include "net/messagein.h"
24
25
#include "net/packetcounters.h"
26
27
#include "utils/cast.h"
28
#include "utils/stringutils.h"
29
30
#include "logger.h"
31
32
#include "debug.h"
33
34
#define MAKEWORD(low, high) \
35
    (CAST_U16((CAST_U8(low)) | \
36
    (CAST_U16(CAST_U8(high))) << 8))
37
38
namespace Net
39
{
40
41
MessageIn::MessageIn(const char *const data,
42
                     const unsigned int length) :
43
    mData(data),
44
    mLength(length),
45
    mPos(0),
46
    mVersion(0),
47
    mId(0),
48
    mIgnore(false)
49
{
50
    PacketCounters::incInPackets();
51
}
52
53
MessageIn::~MessageIn()
54
{
55
    if (mLength != 0u)
56
    {
57
        if (mPos != mLength && mPos != 2)
58
        {
59
            logger->log("Wrong actual or planned inbound packet size!");
60
            logger->log(" packet id: %u 0x%x",
61
                CAST_U32(mId),
62
                CAST_U32(mId));
63
            logger->log(" planned size: %u", mLength);
64
            logger->log(" read size: %u", mPos);
65
            WRONGPACKETSIZE;
66
        }
67
    }
68
    else
69
    {
70
        logger->log("Zero packet size: %d", CAST_S32(mId));
71
    }
72
}
73
74
unsigned char MessageIn::readUInt8(const char *const str)
75
{
76
    unsigned char value = CAST_U8(-1);
77
    if (mPos < mLength)
78
        value = CAST_U8(mData[mPos]);
79
80
    DEBUGLOG2("readUInt8:  " + toStringPrint(CAST_U32(value)),
81
        mPos, str);
82
    mPos += 1;
83
    PacketCounters::incInBytes(1);
84
    return value;
85
}
86
87
signed char MessageIn::readInt8(const char *const str)
88
{
89
    signed char value = CAST_S8(-1);
90
    if (mPos < mLength)
91
        value = CAST_S8(mData[mPos]);
92
93
    DEBUGLOG2("readInt8:   " + toStringPrint(CAST_U32(
94
        CAST_U8(value))),
95
        mPos, str);
96
    mPos += 1;
97
    PacketCounters::incInBytes(1);
98
    return value;
99
}
100
101
uint8_t MessageIn::fromServerDirection(const uint8_t serverDir)
102
{
103
    // Translate from eAthena format
104
    switch (serverDir)
105
    {
106
        case 0:
107
            return 1;
108
        case 1:
109
            return 3;
110
        case 2:
111
            return 2;
112
        case 3:
113
            return 6;
114
        case 4:
115
            return 4;
116
        case 5:
117
            return 12;
118
        case 6:
119
            return 8;
120
        case 7:
121
            return 9;
122
        case 8:
123
            return 8;
124
        default:
125
            logger->log("incorrect direction: %d",
126
                CAST_S32(serverDir));
127
            return 0;
128
    }
129
}
130
131
void MessageIn::readCoordinates(uint16_t &restrict x,
132
                                uint16_t &restrict y,
133
                                uint8_t &restrict direction,
134
                                const char *const str)
135
{
136
    if (mPos + 3 <= mLength)
137
    {
138
        const char *const data = mData + CAST_SIZE(mPos);
139
        uint16_t temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff);
140
        x = CAST_U16(temp >> 6);
141
        temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f);
142
        y = CAST_U16(temp >> 4);
143
144
        const uint8_t serverDir = CAST_U8(data[2] & 0x000f);
145
        direction = fromServerDirection(serverDir);
146
147
        DEBUGLOG2(std::string("readCoordinates: ").append(toString(
148
            CAST_S32(x))).append(",").append(toString(
149
            CAST_S32(y))).append(",").append(toString(
150
            CAST_S32(serverDir))), mPos, str);
151
    }
152
    else
153
    {
154
        x = 0;
155
        y = 0;
156
        direction = 0;
157
        logger->log("error: wrong readCoordinates packet");
158
    }
159
    mPos += 3;
160
    PacketCounters::incInBytes(3);
161
}
162
163
void MessageIn::readCoordinatePair(uint16_t &restrict srcX,
164
                                   uint16_t &restrict srcY,
165
                                   uint16_t &restrict dstX,
166
                                   uint16_t &restrict dstY,
167
                                   const char *const str)
168
{
169
    if (mPos + 5 <= mLength)
170
    {
171
        const char *const data = mData + CAST_SIZE(mPos);
172
        uint16_t temp = MAKEWORD(data[3], data[2] & 0x000f);
173
        dstX = CAST_U16(temp >> 2);
174
175
        dstY = MAKEWORD(data[4], data[3] & 0x0003);
176
177
        temp = MAKEWORD(data[1], data[0]);
178
        srcX = CAST_U16(temp >> 6);
179
180
        temp = MAKEWORD(data[2], data[1] & 0x003f);
181
        srcY = CAST_U16(temp >> 4);
182
183
        DEBUGLOG2(std::string("readCoordinatePair: ").append(toString(
184
            CAST_S32(srcX))).append(",").append(toString(
185
            CAST_S32(srcY))).append(" ").append(toString(
186
            CAST_S32(dstX))).append(",").append(toString(
187
            CAST_S32(dstY))), mPos, str);
188
    }
189
    else
190
    {
191
        srcX = 0;
192
        srcY = 0;
193
        dstX = 0;
194
        dstY = 0;
195
        logger->log("error: wrong readCoordinatePair packet");
196
    }
197
    mPos += 5;
198
    PacketCounters::incInBytes(5);
199
}
200
201
void MessageIn::skip(const unsigned int length, const char *const str)
202
{
203
    DEBUGLOG2("skip: " + toString(CAST_S32(length)), mPos, str);
204
    mPos += length;
205
    PacketCounters::incInBytes(length);
206
}
207
208
void MessageIn::skipToEnd(const char *const str)
209
{
210
    const int diff = CAST_S32(mLength - mPos);
211
    if (diff != 0)
212
    {
213
        DEBUGLOG2("skip: " + toString(diff), mPos, str);
214
        mPos = mLength;
215
        PacketCounters::incInBytes(diff);
216
    }
217
}
218
219
std::string MessageIn::readString(int length, const char *const dstr)
220
{
221
    // Get string length
222
    if (length < 0)
223
        length = readInt16("len");
224
225
    // Make sure the string isn't erroneous
226
    if (length < 0 || mPos + length > mLength)
227
    {
228
        DEBUGLOG2("readString error", mPos, dstr);
229
        mPos = mLength + 1;
230
        return "";
231
    }
232
233
    // Read the string
234
    const char *const stringBeg = mData + CAST_SIZE(mPos);
235
    const char *const stringEnd
236
        = static_cast<const char *>(memchr(stringBeg, '\0', length));
237
238
    const std::string str(stringBeg, stringEnd != nullptr
239
        ? stringEnd - stringBeg : CAST_SIZE(length));
240
    DEBUGLOG2("readString: " + str, mPos, dstr);
241
    mPos += length;
242
    PacketCounters::incInBytes(length);
243
    return str;
244
}
245
246
std::string MessageIn::readRawString(int length, const char *const dstr)
247
{
248
    // Get string length
249
    if (length < 0)
250
        length = readInt16("len");
251
252
    // Make sure the string isn't erroneous
253
    if (length < 0 || mPos + length > mLength)
254
    {
255
        mPos = mLength + 1;
256
        return "";
257
    }
258
259
    // Read the string
260
    const char *const stringBeg = mData + CAST_SIZE(mPos);
261
    const char *const stringEnd
262
        = static_cast<const char *>(memchr(stringBeg, '\0', length));
263
    std::string str(stringBeg, stringEnd != nullptr
264
        ? stringEnd - stringBeg : CAST_SIZE(length));
265
266
    DEBUGLOG2("readString: " + str, mPos, dstr);
267
268
    if (stringEnd != nullptr)
269
    {
270
        const size_t len2 = CAST_SIZE(length)
271
            - (stringEnd - stringBeg) - 1;
272
        const char *const stringBeg2 = stringEnd + 1;
273
        const char *const stringEnd2
274
            = static_cast<const char *>(memchr(stringBeg2, '\0', len2));
275
        const std::string hiddenPart = std::string(stringBeg2,
276
            stringEnd2 != nullptr ? stringEnd2 - stringBeg2 : len2);
277
        if (hiddenPart.length() > 0)
278
        {
279
            DEBUGLOG2("readString2: " + hiddenPart, mPos, dstr);
280
            return str.append("|").append(hiddenPart);
281
        }
282
    }
283
    mPos += length;
284
    PacketCounters::incInBytes(length);
285
286
    return str;
287
}
288
289
unsigned char *MessageIn::readBytes(int length, const char *const dstr)
290
{
291
    // Get string length
292
    if (length < 0)
293
        length = readInt16("len");
294
295
    // Make sure the string isn't erroneous
296
    if (length < 0 || mPos + length > mLength)
297
    {
298
        DEBUGLOG2("readBytesString error", mPos, dstr);
299
        mPos = mLength + 1;
300
        return nullptr;
301
    }
302
303
    unsigned char *const buf
304
        = new unsigned char[CAST_SIZE(length + 2)];
305
306
    memcpy(buf, mData + CAST_SIZE(mPos), length);
307
    buf[length] = 0;
308
    buf[length + 1] = 0;
309
    mPos += length;
310
311
#ifdef ENABLEDEBUGLOG
312
    std::string str;
313
    for (int f = 0; f < length; f ++)
314
        str.append(strprintf("%02x", CAST_U32(buf[f])));
315
    str += " ";
316
    for (int f = 0; f < length; f ++)
317
    {
318
        if (buf[f] != 0u)
319
            str.append(strprintf("%c", buf[f]));
320
        else
321
            str.append("_");
322
    }
323
    if (dstr != nullptr)
324
        logger->dlog(dstr);
325
    logger->dlog("ReadBytes: " + str);
326
#endif  // ENABLEDEBUGLOG
327
328
    PacketCounters::incInBytes(length);
329
    return buf;
330
}
331
332
}  // namespace Net