GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/eathena/charserverhandler.cpp Lines: 10 112 8.9 %
Date: 2018-07-14 Branches: 0 150 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
77
CharServerHandler::CharServerHandler() :
50
77
    Ea::CharServerHandler()
51
{
52
77
    CharServerRecv::mNewName.clear();
53
77
    CharServerRecv::mRenameId = BeingId_zero;
54
55
77
    charServerHandler = this;
56
77
}
57
58
154
CharServerHandler::~CharServerHandler()
59
{
60
77
    charServerHandler = nullptr;
61
77
}
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.writeInt32(CAST_S16(0), "starting job id");
113
            uint8_t sex = 0;
114
            if (gender == Gender::UNSPECIFIED)
115
                sex = 99;
116
            else
117
                sex = Being::genderToInt(gender);
118
            outMsg.writeInt8(sex, "gender");
119
        }
120
        else if (packetVersion >= 20120307)
121
        {
122
            outMsg.writeInt8(CAST_U8(slot), "slot");
123
            outMsg.writeInt16(CAST_S16(hairColor), "hair color");
124
            outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
125
        }
126
        else
127
        {   // < 20120307
128
            // +++ here need send stat points
129
            // sending 5 for each stat for now
130
            for (int i = 0; i < 6; i++)
131
                outMsg.writeInt8(CAST_U8(5), "stat");
132
133
            outMsg.writeInt8(CAST_U8(slot), "slot");
134
            outMsg.writeInt16(CAST_S16(hairColor), "hair color");
135
            outMsg.writeInt16(CAST_S16(hairstyle), "hair style");
136
        }
137
    }
138
}
139
140
void CharServerHandler::deleteCharacter(Net::Character *const character,
141
                                        const std::string &email) const
142
{
143
    if (character == nullptr)
144
        return;
145
146
    mSelectedCharacter = character;
147
148
    createOutPacket(CMSG_CHAR_DELETE);
149
    outMsg.writeBeingId(mSelectedCharacter->dummy->getId(), "id?");
150
    if (email.empty())
151
        outMsg.writeString("[email protected]", 40, "email");
152
    else
153
        outMsg.writeString(email, 40, "email");
154
}
155
156
void CharServerHandler::switchCharacter() const
157
{
158
    // This is really a map-server packet
159
    createOutPacket(CMSG_PLAYER_RESTART);
160
    outMsg.writeInt8(1, "flag");
161
}
162
163
void CharServerHandler::connect() const
164
{
165
    const Token &token =
166
        static_cast<LoginHandler*>(loginHandler)->getToken();
167
168
    if (Network::mInstance == nullptr)
169
        return;
170
171
    Network::mInstance->disconnect();
172
    Network::mInstance->connect(charServer);
173
    createOutPacket(CMSG_CHAR_SERVER_CONNECT);
174
    outMsg.writeBeingId(token.account_ID, "account id");
175
    outMsg.writeInt32(token.session_ID1, "session id1");
176
    outMsg.writeInt32(token.session_ID2, "session id2");
177
    outMsg.writeInt16(CLIENT_PROTOCOL_VERSION, "client protocol version");
178
    outMsg.writeInt8(Being::genderToInt(token.sex), "gender");
179
180
    // We get 4 useless bytes before the real answer comes in (what are these?)
181
    Network::mInstance->skip(4);
182
}
183
184
void CharServerHandler::setCharCreateDialog(CharCreateDialog *const window)
185
                                            const
186
{
187
    mCharCreateDialog = window;
188
189
    if (mCharCreateDialog == nullptr)
190
        return;
191
192
    StringVect attributes;
193
194
    const Token &token = static_cast<LoginHandler*>(loginHandler)->getToken();
195
196
    mCharCreateDialog->setAttributes(attributes, 0, 0, 0);
197
    mCharCreateDialog->setDefaultGender(token.sex);
198
}
199
200
void CharServerHandler::setNewPincode(const BeingId accountId,
201
                                      const std::string &pin) const
202
{
203
    createOutPacket(CMSG_CHAR_CREATE_PIN);
204
    outMsg.writeBeingId(accountId, "account id");
205
    outMsg.writeString(pin, 4, "encrypted pin");
206
}
207
208
void CharServerHandler::sendCheckPincode(const BeingId accountId,
209
                                         const std::string &pin) const
210
{
211
    createOutPacket(CMSG_CHAR_PIN_CHECK);
212
    outMsg.writeBeingId(accountId, "account id");
213
    outMsg.writeString(pin, 4, "encrypted pin");
214
}
215
216
void CharServerHandler::changePincode(const BeingId accountId,
217
                                      const std::string &oldPin,
218
                                      const std::string &newPin) const
219
{
220
    createOutPacket(CMSG_CHAR_PIN_CHANGE);
221
    outMsg.writeBeingId(accountId, "account id");
222
    outMsg.writeString(oldPin, 4, "old encrypted pin");
223
    outMsg.writeString(newPin, 4, "new encrypted pin");
224
}
225
226
void CharServerHandler::renameCharacter(const BeingId id,
227
                                        const std::string &newName) const
228
{
229
    createOutPacket(CMSG_CHAR_CHECK_RENAME);
230
    CharServerRecv::mRenameId = id;
231
    CharServerRecv::mNewName = newName;
232
    outMsg.writeBeingId(id, "char id");
233
    outMsg.writeString(newName, 24, "name");
234
}
235
236
void CharServerHandler::changeSlot(const int oldSlot,
237
                                   const int newSlot) const
238
{
239
    createOutPacket(CMSG_CHAR_CHANGE_SLOT);
240
    outMsg.writeInt16(CAST_S16(oldSlot), "old slot");
241
    outMsg.writeInt16(CAST_S16(newSlot), "new slot");
242
    outMsg.writeInt16(0, "unused");
243
}
244
245
void CharServerHandler::ping() const
246
{
247
    createOutPacket(CMSG_CHAR_PING);
248
    outMsg.writeInt32(0, "unused");
249
}
250
251
unsigned int CharServerHandler::hatSprite() const
252
{
253
    return 7;
254
}
255
256
2
}  // namespace EAthena