ManaPlus
loginrecv.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/loginrecv.h"
25 
26 #include "client.h"
27 #include "configuration.h"
28 
29 #include "being/being.h"
30 
31 #include "fs/paths.h"
32 
34 
35 #include "net/logindata.h"
36 #include "net/loginhandler.h"
37 #include "net/messagein.h"
38 
39 #include "net/ea/loginrecv.h"
40 
42 
43 #include "utils/gettext.h"
44 #include "utils/foreach.h"
45 
46 #include "debug.h"
47 
48 extern int packetVersion;
49 extern int packetsType;
50 extern bool packets_main;
51 extern bool packets_re;
52 extern bool packets_zero;
53 extern int evolPacketOffset;
54 
55 namespace EAthena
56 {
57 
58 extern ServerInfo charServer;
59 
61 {
62  const uint32_t code = msg.readInt32("error");
63  msg.readString(20, "error message");
64  logger->log("Login::error code: %u", code);
65 
66  switch (code)
67  {
68  case 0:
69  // TRANSLATORS: error message
70  errorMessage = _("Unregistered ID.");
71  break;
72  case 1:
73  // TRANSLATORS: error message
74  errorMessage = _("Wrong password.");
76  break;
77  case 2:
78  // TRANSLATORS: error message
79  errorMessage = _("Account expired.");
80  break;
81  case 3:
82  // TRANSLATORS: error message
83  errorMessage = _("Rejected from server.");
84  break;
85  case 4:
86  // TRANSLATORS: error message
87  errorMessage = _("You have been permanently banned from "
88  "the game. Please contact the GM team.");
89  break;
90  case 5:
91  // TRANSLATORS: error message
92  errorMessage = _("Client too old or wrong server type.\n"
93  "Please update client on http://manaplus.org");
94  break;
95  case 6:
96  // TRANSLATORS: error message
97  errorMessage = strprintf(_("You have been temporarily "
98  "banned from the game until "
99  "%s.\nPlease contact the GM "
100  "team via the forums."),
101  msg.readString(20, "date").c_str());
102  break;
103  case 7:
104  // look like unused
105  // TRANSLATORS: error message
106  errorMessage = _("Server overpopulated.");
107  break;
108  case 9:
109  // look like unused
110  // TRANSLATORS: error message
111  errorMessage = _("This user name is already taken.");
112  break;
113  case 10:
114  // look like unused
115  // TRANSLATORS: error message
116  errorMessage = _("Wrong name.");
117  break;
118  case 11:
119  // look like unused
120  // TRANSLATORS: error message
121  errorMessage = _("Incorrect email.");
122  break;
123  case 99:
124  // look like unused
125  // TRANSLATORS: error message
126  errorMessage = _("Username permanently erased.");
127  break;
128  default:
129  // TRANSLATORS: error message
130  errorMessage = _("Unknown error.");
132  break;
133  }
135 }
136 
138 {
139  const int len = msg.readInt16("len") - 4;
140  const std::string updateHost = msg.readString(len, "host");
141 
142  splitToStringVector(loginData.updateHosts, updateHost, '|');
144  {
145  if (!checkPath(*it))
146  {
147  logger->log1("Warning: incorrect update server name");
148  loginData.updateHosts.clear();
149  break;
150  }
151  }
152 
153  logger->log("Received update hosts \"%s\" from login server.",
154  updateHost.c_str());
155 
156  if (client->getState() == State::PRE_LOGIN)
158 }
159 
161 {
162  const int len = msg.readInt16("len");
163  msg.readInt32("unused");
164  serverVersion = msg.readInt32("server version");
165  if (serverVersion > 0)
166  {
167  logger->log("Evol2 server version: %d", serverVersion);
168  packetVersion = msg.readInt32("packet version");
169  logger->log("Hercules packet version: %d", packetVersion);
170  if (packetVersion == 20150000)
171  {
172  packetVersion = 20141022;
173  logger->log("autofix Hercules packet version to: %d",
174  packetVersion);
175  }
176  if (len >= 18)
177  {
178  evolPacketOffset = msg.readInt16("evol packet offset");
179  }
180  if (len >= 20)
181  {
182  packetsType = msg.readInt16("server packets type");
183  packets_re = (packetsType & 1) != 0;
184  packets_zero = (packetsType & 2) != 0;
185  if (packets_re == false &&
186  packets_zero == false)
187  {
188  packets_main = true;
189  }
190  }
191  }
192  else
193  {
194  logger->log("Hercules without version");
195  }
196  updateProtocol();
198 }
199 
201 {
203  const int sz = msg.readInt16("len") - 4;
204  msg.readString(sz, "coding key");
205 }
206 
208 {
209  // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short
210  const uint8_t errMsg = msg.readUInt8("result code");
211  // Successful pass change
212  if (errMsg == 1)
213  {
215  }
216  // pass change failed
217  else
218  {
219  switch (errMsg)
220  {
221  case 0:
222  errorMessage =
223  // TRANSLATORS: error message
224  _("Account was not found. Please re-login.");
225  break;
226  case 2:
227  // TRANSLATORS: error message
228  errorMessage = _("Old password incorrect.");
229  break;
230  case 3:
231  // TRANSLATORS: error message
232  errorMessage = _("New password too short.");
233  break;
234  default:
235  // TRANSLATORS: error message
236  errorMessage = _("Unknown error.");
237  break;
238  }
240  }
241 }
242 
244 {
245  msg.readInt16("len");
246 
248 
249  int offset = 0;
250  int serverLen = 0;
251  if (msg.getVersion() >= 20170315)
252  {
253  offset = 47 + 17;
254  serverLen = 32 + 128;
255  }
256  else
257  {
258  offset = 47;
259  serverLen = 32;
260  }
261 
262  const int worldCount = (msg.getLength() - offset) / serverLen;
263 
264  Ea::LoginRecv::mToken.session_ID1 = msg.readInt32("session id1");
265  Ea::LoginRecv::mToken.account_ID = msg.readBeingId("accound id");
266  Ea::LoginRecv::mToken.session_ID2 = msg.readInt32("session id2");
267  msg.readInt32("old ip");
268  loginData.lastLogin = msg.readString(24, "last login");
269  msg.readInt16("unused");
270 
271  // reserve bits for future usage
273  msg.readUInt8("gender") & 3U));
274 
275  if (msg.getVersion() >= 20170315)
276  {
277  msg.readString(16, "twitter auth token");
278  msg.readUInt8("twitter flag");
279  }
280 
281  for (int i = 0; i < worldCount; i++)
282  {
283  WorldInfo *const world = new WorldInfo;
284 
285  world->address = msg.readInt32("ip address");
286  world->port = msg.readInt16("port");
287  world->name = msg.readString(20, "name");
288  world->online_users = msg.readInt16("online number");
291  msg.readInt16("maintenance");
292  msg.readInt16("new");
293  if (msg.getVersion() >= 20170315)
294  {
295  for (int f = 0; f < 32; f ++)
296  msg.readInt32("unused2");
297  }
298 
299  logger->log("Network: Server: %s (%s:%d)", world->name.c_str(),
300  ipToString(world->address), world->port);
301 
302  Ea::LoginRecv::mWorlds.push_back(world);
303  }
305 }
306 
308 {
310  const int tokenLen = msg.readInt16("len") - 8;
311  msg.readInt32("login flag");
312  msg.readString(tokenLen, "token");
313 }
314 
316 {
318  const int tokenLen = msg.readInt16("len") - 14;
319  msg.readInt32("login flag");
320  msg.readString(6, "login flag2");
321  msg.readString(tokenLen, "token");
322 }
323 
325 {
327  const int tokenLen = msg.readInt16("len") - 28;
328  msg.readInt32("login flag");
329  msg.readString(20, "login flag2");
330  msg.readString(tokenLen, "token");
331 }
332 
334 {
336  msg.readBeingId("accound id");
337 }
338 
339 } // namespace EAthena
#define CAST_U8
Definition: cast.h:27
static GenderT intToGender(const uint8_t sex) A_CONST
Definition: being.h:941
void setState(const StateT state)
Definition: client.h:66
StateT getState() const
Definition: client.h:69
void setValue(const std::string &key, const std::string &value)
void log(const char *const log_text,...)
Definition: logger.cpp:269
void log1(const char *const log_text)
Definition: logger.cpp:238
std::string lastLogin
Definition: logindata.h:64
StringVect updateHosts
Definition: logindata.h:63
static std::string savedPassword
Definition: logindialog.h:80
virtual void clearWorlds() const =0
Configuration config
Client * client
Definition: client.cpp:118
std::string errorMessage
Definition: client.cpp:116
int serverVersion
Definition: client.cpp:124
bool packets_zero
Definition: client.cpp:133
int packetsType
Definition: client.cpp:129
bool packets_re
Definition: client.cpp:132
bool packets_main
Definition: client.cpp:131
int evolPacketOffset
Definition: net.cpp:40
int packetVersion
Definition: client.cpp:125
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
Logger * logger
Definition: logger.cpp:89
#define UNIMPLEMENTEDPACKETFIELD(field)
Definition: logger.h:59
#define UNIMPLEMENTEDPACKET
Definition: logger.h:56
Net::LoginHandler * loginHandler
Definition: net.cpp:90
LoginData loginData
Definition: client.cpp:185
bool msg(InputEvent &event)
Definition: chat.cpp:39
void processLoginOtp2(Net::MessageIn &msg)
Definition: loginrecv.cpp:315
void processServerVersion(Net::MessageIn &msg)
Definition: loginrecv.cpp:160
void processMobileOtp(Net::MessageIn &msg)
Definition: loginrecv.cpp:333
void processLoginOtp1(Net::MessageIn &msg)
Definition: loginrecv.cpp:307
void processLoginOtp3(Net::MessageIn &msg)
Definition: loginrecv.cpp:324
void processLoginError2(Net::MessageIn &msg)
Definition: loginrecv.cpp:60
void processUpdateHost2(Net::MessageIn &msg)
Definition: loginrecv.cpp:137
void processLoginData(Net::MessageIn &msg)
Definition: loginrecv.cpp:243
void processCharPasswordResponse(Net::MessageIn &msg)
Definition: loginrecv.cpp:207
void processCondingKey(Net::MessageIn &msg)
Definition: loginrecv.cpp:200
void updateProtocol()
ServerInfo charServer
std::string mUpdateHost
Definition: loginrecv.cpp:44
Worlds mWorlds
Definition: loginrecv.cpp:45
@ ACCOUNTCHANGE_ERROR
Definition: state.h:52
@ WORLD_SELECT
Definition: state.h:42
@ PRE_LOGIN
Definition: state.h:39
@ ERROR
Definition: state.h:35
@ LOGIN
Definition: state.h:40
@ CHANGEPASSWORD_SUCCESS
Definition: state.h:58
bool checkPath(const std::string &path)
Definition: paths.cpp:121
std::string strprintf(const char *const format,...)
void splitToStringVector(StringVect &tokens, const std::string &text, const char separator)
const char * ipToString(const uint32_t address)
Definition: stringutils.cpp:86
StringVect::iterator StringVectIter
Definition: stringvector.h:30
int session_ID2
Definition: token.h:43
GenderT sex
Definition: token.h:44
BeingId account_ID
Definition: token.h:41
int session_ID1
Definition: token.h:42
uint16_t port
Definition: worldinfo.h:54
std::string updateHost
Definition: worldinfo.h:56
std::string name
Definition: worldinfo.h:53
int address
Definition: worldinfo.h:52
int online_users
Definition: worldinfo.h:55