GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/eathena/charserverhandler.cpp Lines: 10 114 8.8 %
Date: 2018-05-19 03:07:18 Branches: 0 152 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/charserverhandler.h"
24
25
#include "gui/windows/charcreatedialog.h"
26
27
#include "net/character.h"
28
#include "net/serverfeatures.h"
29
30
#include "net/ea/token.h"
31
32
#include "net/eathena/charserverrecv.h"
33
#include "net/eathena/loginhandler.h"
34
#include "net/eathena/messageout.h"
35
#include "net/eathena/network.h"
36
#include "net/eathena/protocolout.h"
37
38
#include "debug.h"
39
40
extern int packetVersion;
41
extern int serverVersion;
42
43
namespace EAthena
44
{
45
46
extern ServerInfo charServer;
47
extern ServerInfo mapServer;
48
49
154
CharServerHandler::CharServerHandler() :
50
154
    Ea::CharServerHandler()
51
{
52
154
    CharServerRecv::mNewName.clear();
53
154
    CharServerRecv::mRenameId = BeingId_zero;
54
55
154
    charServerHandler = this;
56
154
}
57
58
308
CharServerHandler::~CharServerHandler()
59
{
60
154
    charServerHandler = nullptr;
61
154
}
62
63
void CharServerHandler::chooseCharacter(Net::Character *const character) const
64
{
65
    if (character == nullptr)
66
        return;
67
68
    mSelectedCharacter = character;
69
    mCharSelectDialog = nullptr;
70
71
    createOutPacket(CMSG_CHAR_SELECT);
72
    outMsg.writeInt8(CAST_U8(
73
        mSelectedCharacter->slot), "slot");
74
}
75
76
void CharServerHandler::newCharacter(const std::string &name, const int slot,
77
                                     const GenderT gender,
78
                                     const int hairstyle, const int hairColor,
79
                                     const unsigned char race,
80
                                     const uint16_t look,
81
                                     const STD_VECTOR<int> &stats A_UNUSED)
82
                                     const
83
{
84
    createOutPacket(CMSG_CHAR_CREATE);
85
    outMsg.writeString(name, 24, "login");
86
    if (serverVersion > 0)
87
    {
88
        outMsg.writeInt8(CAST_U8(slot), "slot");
89
        outMsg.writeInt16(CAST_S16(hairColor), "hair color");
90
        outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
91
        if (serverFeatures->haveRaceSelection())
92
            outMsg.writeInt16(CAST_S16(race), "race");
93
        if (serverFeatures->haveCreateCharGender())
94
        {
95
            uint8_t sex = 0;
96
            if (gender == Gender::UNSPECIFIED)
97
                sex = 99;
98
            else
99
                sex = Being::genderToInt(gender);
100
            outMsg.writeInt8(sex, "gender");
101
        }
102
        if (serverFeatures->haveLookSelection())
103
            outMsg.writeInt16(CAST_S16(look), "look");
104
    }
105
    else
106
    {
107
        if (packetVersion >= 20151001)
108
        {
109
            outMsg.writeInt8(CAST_U8(slot), "slot");
110
            outMsg.writeInt16(CAST_S16(hairColor), "hair color");
111
            outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
112
            outMsg.writeInt16(CAST_S16(0), "starting job id");
113
            outMsg.writeInt16(0, "unknown");
114
            uint8_t sex = 0;
115
            if (gender == Gender::UNSPECIFIED)
116
                sex = 99;
117
            else
118
                sex = Being::genderToInt(gender);
119
            outMsg.writeInt8(sex, "gender");
120
        }
121
        else if (packetVersion >= 20120307)
122
        {
123
            outMsg.writeInt8(CAST_U8(slot), "slot");
124
            outMsg.writeInt16(CAST_S16(hairColor), "hair color");
125
            outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
126
        }
127
        else
128
        {   // < 20120307
129
            // +++ here need send stat points
130
            // sending 5 for each stat for now
131
            for (int i = 0; i < 6; i++)
132
                outMsg.writeInt8(CAST_U8(5), "stat");
133
134
            outMsg.writeInt8(CAST_U8(slot), "slot");
135
            outMsg.writeInt16(CAST_S16(hairColor), "hair color");
136
            outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
137
        }
138
    }
139
}
140
141
void CharServerHandler::deleteCharacter(Net::Character *const character,
142
                                        const std::string &email) const
143
{
144
    if (character == nullptr)
145
        return;
146
147
    mSelectedCharacter = character;
148
149
    createOutPacket(CMSG_CHAR_DELETE);
150
    outMsg.writeBeingId(mSelectedCharacter->dummy->getId(), "id?");
151
    if (email.empty())
152
        outMsg.writeString("[email protected]", 40, "email");
153
    else
154
        outMsg.writeString(email, 40, "email");
155
}
156
157
void CharServerHandler::switchCharacter() const
158
{
159
    // This is really a map-server packet
160
    createOutPacket(CMSG_PLAYER_RESTART);
161
    outMsg.writeInt8(1, "flag");
162
}
163
164
void CharServerHandler::connect() const
165
{
166
    const Token &token =
167
        static_cast<LoginHandler*>(loginHandler)->getToken();
168
169
    if (Network::mInstance == nullptr)
170
        return;
171
172
    Network::mInstance->disconnect();
173
    Network::mInstance->connect(charServer);
174
    createOutPacket(CMSG_CHAR_SERVER_CONNECT);
175
    outMsg.writeBeingId(token.account_ID, "account id");
176
    outMsg.writeInt32(token.session_ID1, "session id1");
177
    outMsg.writeInt32(token.session_ID2, "session id2");
178
    outMsg.writeInt16(CLIENT_PROTOCOL_VERSION, "client protocol version");
179
    outMsg.writeInt8(Being::genderToInt(token.sex), "gender");
180
181
    // We get 4 useless bytes before the real answer comes in (what are these?)
182
    Network::mInstance->skip(4);
183
}
184
185
void CharServerHandler::setCharCreateDialog(CharCreateDialog *const window)
186
                                            const
187
{
188
    mCharCreateDialog = window;
189
190
    if (mCharCreateDialog == nullptr)
191
        return;
192
193
    StringVect attributes;
194
195
    const Token &token = static_cast<LoginHandler*>(loginHandler)->getToken();
196
197
    mCharCreateDialog->setAttributes(attributes, 0, 0, 0);
198
    mCharCreateDialog->setDefaultGender(token.sex);
199
}
200
201
void CharServerHandler::setNewPincode(const BeingId accountId,
202
                                      const std::string &pin) const
203
{
204
    createOutPacket(CMSG_CHAR_CREATE_PIN);
205
    outMsg.writeBeingId(accountId, "account id");
206
    outMsg.writeString(pin, 4, "encrypted pin");
207
}
208
209
void CharServerHandler::sendCheckPincode(const BeingId accountId,
210
                                         const std::string &pin) const
211
{
212
    createOutPacket(CMSG_CHAR_PIN_CHECK);
213
    outMsg.writeBeingId(accountId, "account id");
214
    outMsg.writeString(pin, 4, "encrypted pin");
215
}
216
217
void CharServerHandler::changePincode(const BeingId accountId,
218
                                      const std::string &oldPin,
219
                                      const std::string &newPin) const
220
{
221
    createOutPacket(CMSG_CHAR_PIN_CHANGE);
222
    outMsg.writeBeingId(accountId, "account id");
223
    outMsg.writeString(oldPin, 4, "old encrypted pin");
224
    outMsg.writeString(newPin, 4, "new encrypted pin");
225
}
226
227
void CharServerHandler::renameCharacter(const BeingId id,
228
                                        const std::string &newName) const
229
{
230
    createOutPacket(CMSG_CHAR_CHECK_RENAME);
231
    CharServerRecv::mRenameId = id;
232
    CharServerRecv::mNewName = newName;
233
    outMsg.writeBeingId(id, "char id");
234
    outMsg.writeString(newName, 24, "name");
235
}
236
237
void CharServerHandler::changeSlot(const int oldSlot,
238
                                   const int newSlot) const
239
{
240
    createOutPacket(CMSG_CHAR_CHANGE_SLOT);
241
    outMsg.writeInt16(CAST_S16(oldSlot), "old slot");
242
    outMsg.writeInt16(CAST_S16(newSlot), "new slot");
243
    outMsg.writeInt16(0, "unused");
244
}
245
246
void CharServerHandler::ping() const
247
{
248
    createOutPacket(CMSG_CHAR_PING);
249
    outMsg.writeInt32(0, "unused");
250
}
251
252
unsigned int CharServerHandler::hatSprite() const
253
{
254
    return 7;
255
}
256
257
4
}  // namespace EAthena