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