Mana
Loading...
Searching...
No Matches
messagein.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "net/tmwa/messagein.h"
23
24#include "being.h"
25#include "net/tmwa/protocol.h"
26
27#include <SDL_endian.h>
28
29#ifndef MAKEWORD
30#define MAKEWORD(low,high) \
31 ((unsigned short)(((unsigned char)(low)) | \
32 ((unsigned short)((unsigned char)(high))) << 8))
33#endif
34
35namespace TmwAthena {
36
37MessageIn::MessageIn(const char *data, unsigned int length):
38 mData(data),
39 mLength(length),
40 mPos(0)
41{
42 // Read the message ID
43 mId = readInt16();
44}
45
47{
48 uint8_t value = 0;
49 if (mPos < mLength)
50 {
51 value = mData[mPos];
52 }
53 mPos++;
54 return value;
55}
56
58{
59 uint16_t value = 0;
60 if (mPos + 2 <= mLength)
61 {
62 memcpy(&value, mData + mPos, sizeof(uint16_t));
63 value = SDL_SwapLE16(value);
64 }
65 mPos += 2;
66 return value;
67}
68
70{
71 uint32_t value = 0;
72 if (mPos + 4 <= mLength)
73 {
74 memcpy(&value, mData + mPos, sizeof(uint32_t));
75 value = SDL_SwapLE32(value);
76 }
77 mPos += 4;
78 return value;
79}
80
81void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
82{
83 if (mPos + 3 <= mLength)
84 {
85 const char *data = mData + mPos;
86 uint16_t temp;
87
88 temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff);
89 x = temp >> 6;
90 temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f);
91 y = temp >> 4;
92
93 direction = data[2] & 0x000f;
94
95 // Translate from tmwAthena format
96 switch (static_cast<DIR>(direction))
97 {
98 case DIR::S: direction = Being::DOWN; break;
99 case DIR::SW: direction = Being::DOWN | Being::LEFT; break;
100 case DIR::W: direction = Being::LEFT; break;
101 case DIR::NW: direction = Being::UP | Being::LEFT; break;
102 case DIR::N: direction = Being::UP; break;
103 case DIR::NE: direction = Being::UP | Being::RIGHT; break;
104 case DIR::E: direction = Being::RIGHT; break;
105 case DIR::SE: direction = Being::DOWN | Being::RIGHT; break;
106 default:
107 // OOPSIE! Impossible or unknown
108 direction = 0;
109 break;
110 }
111 }
112 mPos += 3;
113}
114
115void MessageIn::readCoordinatePair(uint16_t &srcX, uint16_t &srcY,
116 uint16_t &dstX, uint16_t &dstY)
117{
118 if (mPos + 5 <= mLength)
119 {
120 const char *data = mData + mPos;
121 uint16_t temp;
122
123 temp = MAKEWORD(data[3], data[2] & 0x000f);
124 dstX = temp >> 2;
125
126 dstY = MAKEWORD(data[4], data[3] & 0x0003);
127
128 temp = MAKEWORD(data[1], data[0]);
129 srcX = temp >> 6;
130
131 temp = MAKEWORD(data[2], data[1] & 0x003f);
132 srcY = temp >> 4;
133 }
134 mPos += 5;
135}
136
137void MessageIn::skip(unsigned int length)
138{
139 mPos += length;
140}
141
142std::string MessageIn::readString(int length)
143{
144 // Get string length
145 if (length < 0)
146 length = readInt16();
147
148 // Make sure the string isn't erroneous
149 if (length < 0 || mPos + length > mLength)
150 {
151 mPos = mLength + 1;
152 return std::string();
153 }
154
155 // Read the string
156 char const *stringBeg = mData + mPos;
157 char const *stringEnd = (char const *)memchr(stringBeg, '\0', length);
158 std::string readString(stringBeg,
159 stringEnd ? stringEnd - stringBeg : length);
160 mPos += length;
161 return readString;
162}
163
164} // namespace TmwAthena
@ RIGHT
Definition being.h:107
@ DOWN
Definition being.h:104
@ UP
Definition being.h:106
@ LEFT
Definition being.h:105
std::string readString(int length=-1)
Reads a string.
void readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction)
Reads a special 3 byte block used by eAthena, containing x and y coordinates and direction.
Definition messagein.cpp:81
const char * mData
The message data.
Definition messagein.h:98
void skip(unsigned int length)
Skips a given number of bytes.
unsigned short mId
The message ID.
Definition messagein.h:100
uint16_t readInt16()
Reads an unsigned 16-bit integer from the message.
Definition messagein.cpp:57
uint8_t readInt8()
Reads an unsigned 8-bit integer from the message.
Definition messagein.cpp:46
MessageIn(const char *data, unsigned int length)
Definition messagein.cpp:37
void readCoordinatePair(uint16_t &srcX, uint16_t &srcY, uint16_t &dstX, uint16_t &dstY)
Reads a special 5 byte block used by eAthena, containing a source and destination coordinate pair.
unsigned int mPos
Actual position in the packet.
Definition messagein.h:107
unsigned int mLength
The length of the data.
Definition messagein.h:99
uint32_t readInt32()
Reads an unsigned 32-bit integer from the message.
Definition messagein.cpp:69
Warning: buffers and other variables are shared, so there can be only one connection active at a time...
unsigned char uint8_t
Definition sha256.cpp:81
unsigned int uint32_t
Definition sha256.cpp:82
#define MAKEWORD(low, high)
Definition messagein.cpp:30