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