ManaPlus
network.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-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
24 #include "net/eathena/network.h"
25 
26 #include "net/packetinfo.h"
27 
28 #include "net/ea/adminrecv.h"
29 #include "net/ea/beingrecv.h"
30 #include "net/ea/buysellrecv.h"
31 #include "net/ea/charserverrecv.h"
32 #include "net/ea/chatrecv.h"
33 #include "net/ea/gamerecv.h"
34 #include "net/ea/inventoryrecv.h"
35 #include "net/ea/itemrecv.h"
36 #include "net/ea/loginrecv.h"
37 #include "net/ea/maprecv.h"
38 #include "net/ea/npcrecv.h"
39 #include "net/ea/partyrecv.h"
40 #include "net/ea/playerrecv.h"
41 #include "net/ea/skillrecv.h"
42 #include "net/ea/traderecv.h"
43 
45 #include "net/eathena/adminrecv.h"
48 #include "net/eathena/bankrecv.h"
49 #include "net/eathena/barterrecv.h"
51 #include "net/eathena/beingrecv.h"
56 #include "net/eathena/chatrecv.h"
57 #include "net/eathena/clanrecv.h"
59 #include "net/eathena/familyrecv.h"
61 #include "net/eathena/gamerecv.h"
63 #include "net/eathena/guildrecv.h"
66 #include "net/eathena/itemrecv.h"
67 #include "net/eathena/loginrecv.h"
68 #include "net/eathena/mail2recv.h"
69 #include "net/eathena/mailrecv.h"
70 #include "net/eathena/maprecv.h"
71 #include "net/eathena/marketrecv.h"
73 #include "net/eathena/npcrecv.h"
74 #include "net/eathena/partyrecv.h"
75 #include "net/eathena/petrecv.h"
76 #include "net/eathena/playerrecv.h"
77 #include "net/eathena/questrecv.h"
78 #include "net/eathena/refinerecv.h"
81 #include "net/eathena/skillrecv.h"
82 #include "net/eathena/traderecv.h"
84 
85 #include "net/eathena/messagein.h"
86 
87 #include "resources/db/networkdb.h"
88 
89 #include "utils/cast.h"
90 #include "utils/checkutils.h"
91 #include "utils/foreach.h"
92 
93 #include "debug.h"
94 
95 extern int packetVersion;
96 extern int packetVersionMain;
97 extern int packetVersionRe;
98 extern int packetVersionZero;
99 extern int serverVersion;
100 extern int evolPacketOffset;
101 extern bool packets_zero;
102 extern bool packets_re;
103 extern bool packets_main;
104 
105 namespace EAthena
106 {
107 
108 static const unsigned int packet_lengths_size = 0xFFFFU;
109 static const unsigned int messagesSize = 0xFFFFU;
110 Network *Network::mInstance = nullptr;
111 
113  Ea::Network()
114 {
115  mInstance = this;
117 }
118 
120 {
121  clearHandlers();
122  mInstance = nullptr;
123 }
124 
126 {
127 #include "net/eathena/recvpackets.inc"
128  RECVPACKETS_VOID
129 }
130 
132 {
134  FOR_EACH (NetworkInPacketInfosIter, it, packets)
135  {
136  const size_t id = (*it).first;
137  if (id >= packet_lengths_size)
138  {
139  reportAlways("Wrong fake packet id %d", CAST_S32(id))
140  continue;
141  }
142  if (mPackets[id].len != 0 ||
143  mPackets[id].func != nullptr ||
144  mPackets[id].version != 0)
145  {
146  continue;
147  }
148  const int32_t len = (*it).second;
149  logger->log("Add fake packet: %d, %d",
150  CAST_S32(id),
151  len);
152  mPackets[id].name = "fake";
153  mPackets[id].len = len;
154  mPackets[id].func = nullptr;
155  mPackets[id].version = 0;
156  }
157 
158  const NetworkRemovePacketInfos &removePackets =
160  FOR_EACH (NetworkRemovePacketInfosIter, it, removePackets)
161  {
162  const size_t id = *it;
163  if (id >= packet_lengths_size)
164  {
165  reportAlways("Wrong remove packet id %d", CAST_S32(id))
166  continue;
167  }
168  if (mPackets[id].len == 0 &&
169  mPackets[id].func == nullptr &&
170  mPackets[id].version == 0)
171  {
172  continue;
173  }
174  logger->log("Remove packet: %d",
175  CAST_S32(id));
176  mPackets[id].name = "";
177  mPackets[id].len = 0;
178  mPackets[id].func = nullptr;
179  mPackets[id].version = 0;
180  }
181 }
182 
184 {
185  for (size_t f = 0; f < packet_lengths_size; f ++)
186  {
187  mPackets[f].name = "";
188  mPackets[f].len = 0;
189  mPackets[f].func = nullptr;
190  mPackets[f].version = 0;
191  }
192 }
193 
195 {
196  mPauseDispatch = false;
197  while (messageReady())
198  {
199  SDL_mutexP(mMutexIn);
200  const unsigned int msgId = readWord(0);
201  int len = -1;
202  if (msgId < packet_lengths_size)
203  len = mPackets[msgId].len;
204  if (len == -1)
205  len = readWord(2);
206 
207  MessageIn msg(mInBuffer, len);
208  unsigned int ver = mPackets[msgId].version;
209  if (ver == 0)
210  ver = packetVersion;
211  msg.postInit(mPackets[msgId].name, ver);
212  SDL_mutexV(mMutexIn);
213 
214  if (len == 0)
215  {
216  // need copy data for safty
217  std::string str = strprintf(
218  "Wrong packet %u 0x%x received. Exiting.",
219  msgId, msgId);
220  logger->safeError(str);
221  }
222 
223  if (msgId < messagesSize)
224  {
225  const PacketFuncPtr func = mPackets[msgId].func;
226  if (func != nullptr)
227  func(msg);
228  else
229  logger->log("Unhandled packet: %u 0x%x", msgId, msgId);
230  }
231 
232  skip(len);
233  if (mPauseDispatch)
234  break;
235  }
236 }
237 
239 {
240  int len = -1;
241 
242  SDL_mutexP(mMutexIn);
243  if (mInSize >= 2)
244  {
245  const int msgId = readWord(0);
246  if (msgId >= 0 &&
247  CAST_U32(msgId) < packet_lengths_size)
248  {
249  len = mPackets[msgId].len;
250  }
251 
252  if (len == -1 && mInSize > 4)
253  len = readWord(2);
254  }
255 
256  const bool ret = (mInSize >= CAST_U32(len));
257  SDL_mutexV(mMutexIn);
258 
259  return ret;
260 }
261 
263 {
264  return mInstance;
265 }
266 
267 } // namespace EAthena
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
#define reportAlways(...)
Definition: checkutils.h:253
void registerFakeHandlers()
Definition: network.cpp:131
void registerHandlers()
Definition: network.cpp:125
static Network * mInstance
Definition: network.h:57
static Network * instance()
Definition: network.cpp:262
bool messageReady()
Definition: network.cpp:238
void dispatchMessages()
Definition: network.cpp:194
void clearHandlers()
Definition: network.cpp:183
SDL_mutex * mMutexIn
Definition: network.h:114
uint16_t readWord(const int pos) const
Definition: network.cpp:350
bool mPauseDispatch
Definition: network.h:117
PacketInfo * mPackets
Definition: network.h:101
char * mInBuffer
Definition: network.h:103
unsigned int mInSize
Definition: network.h:105
void skip(const int len)
Definition: network.cpp:181
void log(const char *const log_text,...)
Definition: logger.cpp:269
void safeError(const std::string &error_text) __attribute__((noreturn))
Definition: logger.cpp:435
bool packets_zero
Definition: client.cpp:133
int serverVersion
Definition: client.cpp:124
bool packets_re
Definition: client.cpp:132
int packetVersionRe
Definition: client.cpp:127
bool packets_main
Definition: client.cpp:131
int packetVersionMain
Definition: client.cpp:126
int evolPacketOffset
Definition: net.cpp:40
int packetVersionZero
Definition: client.cpp:128
int packetVersion
Definition: client.cpp:125
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
Logger * logger
Definition: logger.cpp:89
bool msg(InputEvent &event)
Definition: chat.cpp:39
static const unsigned int packet_lengths_size
Definition: network.cpp:108
static const unsigned int messagesSize
Definition: network.cpp:109
const NetworkRemovePacketInfos & getRemovePackets()
Definition: networkdb.cpp:86
const NetworkInPacketInfos & getFakePackets()
Definition: networkdb.cpp:81
NetworkInPacketInfos::const_iterator NetworkInPacketInfosIter
Definition: networkdb.h:33
std::map< int32_t, int32_t > NetworkInPacketInfos
Definition: networkdb.h:32
std::vector< int > NetworkRemovePacketInfos
Definition: networkdb.h:34
NetworkRemovePacketInfos::const_iterator NetworkRemovePacketInfosIter
Definition: networkdb.h:35
void(* PacketFuncPtr)(Net::MessageIn &msg)
std::string strprintf(const char *const format,...)
PacketFuncPtr func
Definition: packetinfo.h:42
const char * name
Definition: packetinfo.h:41
int version
Definition: packetinfo.h:44