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