GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/eathena/loginrecv.cpp Lines: 1 131 0.8 %
Date: 2021-03-17 Branches: 0 59 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-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
33
#include "gui/windows/logindialog.h"
34
35
#include "net/logindata.h"
36
#include "net/loginhandler.h"
37
#include "net/messagein.h"
38
39
#include "net/ea/loginrecv.h"
40
41
#include "net/eathena/updateprotocol.h"
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
60
void LoginRecv::processLoginError2(Net::MessageIn &msg)
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.");
75
            LoginDialog::savedPassword.clear();
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.");
131
            UNIMPLEMENTEDPACKETFIELD(code);
132
            break;
133
    }
134
    client->setState(State::ERROR);
135
}
136
137
void LoginRecv::processUpdateHost2(Net::MessageIn &msg)
138
{
139
    const int len = msg.readInt16("len") - 4;
140
    const std::string updateHost = msg.readString(len, "host");
141
142
    splitToStringVector(loginData.updateHosts, updateHost, '|');
143
    FOR_EACH (StringVectIter, it, loginData.updateHosts)
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)
157
        client->setState(State::LOGIN);
158
}
159
160
void LoginRecv::processServerVersion(Net::MessageIn &msg)
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();
197
    client->setState(State::LOGIN);
198
}
199
200
void LoginRecv::processCondingKey(Net::MessageIn &msg)
201
{
202
    UNIMPLEMENTEDPACKET;
203
    const int sz = msg.readInt16("len") - 4;
204
    msg.readString(sz, "coding key");
205
}
206
207
void LoginRecv::processCharPasswordResponse(Net::MessageIn &msg)
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
    {
214
        client->setState(State::CHANGEPASSWORD_SUCCESS);
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
        }
239
        client->setState(State::ACCOUNTCHANGE_ERROR);
240
    }
241
}
242
243
void LoginRecv::processLoginData(Net::MessageIn &msg)
244
{
245
    msg.readInt16("len");
246
247
    loginHandler->clearWorlds();
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
272
    Ea::LoginRecv::mToken.sex = Being::intToGender(CAST_U8(
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");
289
        config.setValue("updatehost", Ea::LoginRecv::mUpdateHost);
290
        world->updateHost = Ea::LoginRecv::mUpdateHost;
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
    }
304
    client->setState(State::WORLD_SELECT);
305
}
306
307
void LoginRecv::processLoginOtp1(Net::MessageIn &msg)
308
{
309
    UNIMPLEMENTEDPACKET;
310
    const int tokenLen = msg.readInt16("len") - 8;
311
    msg.readInt32("login flag");
312
    msg.readString(tokenLen, "token");
313
}
314
315
void LoginRecv::processLoginOtp2(Net::MessageIn &msg)
316
{
317
    UNIMPLEMENTEDPACKET;
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
324
void LoginRecv::processLoginOtp3(Net::MessageIn &msg)
325
{
326
    UNIMPLEMENTEDPACKET;
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
333
void LoginRecv::processMobileOtp(Net::MessageIn &msg)
334
{
335
    UNIMPLEMENTEDPACKET;
336
    msg.readBeingId("accound id");
337
}
338
339
2
}  // namespace EAthena