ManaPlus
messageout.cpp
Go to the documentation of this file.
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-2018 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/eathena/messageout.h"
24 
25 #include "net/packetcounters.h"
26 
27 #include "net/eathena/network.h"
28 
29 #include "logger.h"
30 
31 #include "debug.h"
32 
33 #ifndef SDL_BIG_ENDIAN
34 #error missing SDL_endian.h
35 #endif // SDL_BYTEORDER
36 
37 namespace EAthena
38 {
39 
40 MessageOut::MessageOut(const int16_t id) :
41  Net::MessageOut(id),
42  mNetwork(EAthena::Network::instance())
43 {
46 }
47 
49 {
50  DEBUGLOG2("writeEnd: ", mPos, "position after end of packet");
51 }
52 
53 void MessageOut::expand(const size_t bytes) const
54 {
55  mNetwork->mOutSize += CAST_U32(bytes);
57 }
58 
59 void MessageOut::writeInt16(const int16_t value, const char *const str)
60 {
61  expand(2);
62 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
63  int16_t swap = SDL_Swap16(value);
64  memcpy(mData + CAST_SIZE(mPos), &swap, sizeof(int16_t));
65 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
66 
67  memcpy(mData + CAST_SIZE(mPos), &value, sizeof(int16_t));
68 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
69 
70  DEBUGLOG2("writeInt16: " + toStringPrint(CAST_U32(
71  CAST_U16(value))),
72  mPos, str);
73  mPos += 2;
75 }
76 
77 void MessageOut::writeInt32(const int32_t value, const char *const str)
78 {
79  DEBUGLOG2("writeInt32: " + toStringPrint(CAST_U32(value)),
80  mPos, str);
81  expand(4);
82 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
83  int32_t swap = SDL_Swap32(value);
84  memcpy(mData + CAST_SIZE(mPos), &swap, sizeof(int32_t));
85 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
86 
87  memcpy(mData + CAST_SIZE(mPos), &value, sizeof(int32_t));
88 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
89 
90  mPos += 4;
92 }
93 
94 void MessageOut::writeInt64(const int64_t value, const char *const str)
95 {
96  DEBUGLOG2("writeInt64: " + toStringPrint(CAST_U32(value)),
97  mPos, str);
98  expand(8);
99 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
100  int32_t swap = SDL_Swap64(value);
101  memcpy(mData + CAST_SIZE(mPos), &swap, sizeof(int64_t));
102 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
103 
104  memcpy(mData + CAST_SIZE(mPos), &value, sizeof(int64_t));
105 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
106 
107  mPos += 8;
109 }
110 
111 void MessageOut::writeBeingId(const BeingId value, const char *const str)
112 {
113  writeInt32(toInt(value, int32_t), str);
114 }
115 
116 #define LOBYTE(w) (CAST_U8(w))
117 #define HIBYTE(w) (CAST_U8(( \
118 CAST_U16(w)) >> 8))
119 
120 void MessageOut::writeCoordinates(const uint16_t x,
121  const uint16_t y,
122  unsigned char direction,
123  const char *const str)
124 {
125  DEBUGLOG2(strprintf("writeCoordinates: %u,%u %u",
126  CAST_U32(x),
127  CAST_U32(y),
128  CAST_U32(direction)), mPos, str);
129  unsigned char *const data = reinterpret_cast<unsigned char*>(mData)
130  + CAST_SIZE(mPos);
131  mNetwork->mOutSize += 3;
132  mPos += 3;
133 
134  uint16_t temp = x;
135  temp <<= 6;
136  data[0] = 0;
137  data[1] = 1;
138  data[2] = 2;
139  data[0] = HIBYTE(temp);
140  data[1] = CAST_U8(temp);
141  temp = y;
142  temp <<= 4;
143  data[1] |= HIBYTE(temp);
144  data[2] = LOBYTE(temp);
145  direction = toServerDirection(direction);
146  data[2] |= direction;
148 }
149 
150 } // namespace EAthena
#define CAST_U32
Definition: cast.h:30
void expand(const size_t size) const
Definition: messageout.cpp:53
#define CAST_U8
Definition: cast.h:26
std::string toStringPrint(const unsigned int val)
static unsigned char toServerDirection(unsigned char direction) A_CONST
Definition: messageout.cpp:138
#define DEBUGLOG2(str, pos, comment)
Definition: logger.h:41
static void incOutBytes(const int cnt)
int BeingId
Definition: beingid.h:29
void fixSendBuffer()
Definition: network.cpp:361
void writeInt64(const int64_t value, const char *const str)
Definition: messageout.cpp:94
unsigned int mPos
Definition: messageout.h:116
char * mOutBuffer
Definition: network.h:103
void writeCoordinates(const uint16_t x, const uint16_t y, unsigned char direction, const char *const str)
Definition: messageout.cpp:120
#define toInt(val, name)
Definition: intdefines.h:46
#define CAST_U16
Definition: cast.h:28
#define CAST_S32
Definition: cast.h:29
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
MessageOut(const int16_t id)
Definition: messageout.cpp:40
uint32_t data
Network * mNetwork
Definition: messageout.h:80
void writeBeingId(const BeingId value, const char *const str)
Definition: messageout.cpp:111
#define LOBYTE(w)
Definition: messageout.cpp:116
void writeInt16(const int16_t value, const char *const str)
Definition: messageout.cpp:59
#define HIBYTE(w)
Definition: messageout.cpp:117
#define CAST_SIZE
Definition: cast.h:33
unsigned int mOutSize
Definition: network.h:105
void writeInt32(const int32_t value, const char *const str)
Definition: messageout.cpp:77