GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/eathena/partyrecv.cpp Lines: 1 212 0.5 %
Date: 2017-11-29 Branches: 0 228 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Lloyd Bryant <[email protected]>
4
 *  Copyright (C) 2011-2017  The ManaPlus Developers
5
 *
6
 *  This file is part of The ManaPlus Client.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "net/eathena/partyrecv.h"
23
24
#include "notifymanager.h"
25
#include "party.h"
26
27
#include "being/localplayer.h"
28
29
#include "enums/resources/notifytypes.h"
30
31
#include "gui/windows/chatwindow.h"
32
#include "gui/windows/socialwindow.h"
33
34
#include "gui/widgets/tabs/chat/partytab.h"
35
36
#include "net/messagein.h"
37
38
#include "net/ea/partyrecv.h"
39
40
#include "utils/checkutils.h"
41
#include "utils/foreach.h"
42
43
#include "debug.h"
44
45
namespace EAthena
46
{
47
48
namespace PartyRecv
49
{
50
    PartyShareT mShareAutoItems = PartyShare::UNKNOWN;
51
}  // namespace PartyRecv
52
53
void PartyRecv::processPartyInvitationStats(Net::MessageIn &msg)
54
{
55
    // +++ for now server allow only switch this option but not using it.
56
    msg.readUInt8("allow party");
57
}
58
59
void PartyRecv::processPartyMemberInfo(Net::MessageIn &msg)
60
{
61
    const BeingId id = msg.readBeingId("account id");
62
    const bool leader = msg.readInt32("leader") == 0U;
63
    int level = 0;
64
    if (msg.getVersion() >= 20170502)
65
    {
66
        msg.readInt16("class");
67
        level = msg.readInt16("level");
68
    }
69
    const int x = msg.readInt16("x");
70
    const int y = msg.readInt16("y");
71
    const bool online = msg.readInt8("online") == 0U;
72
    msg.readString(24, "party name");
73
    const std::string nick = msg.readString(24, "player name");
74
    const std::string map = msg.readString(16, "map name");
75
    msg.readInt8("pickup item share (&1)");
76
    msg.readInt8("get item share (&2)");
77
78
    if (Ea::taParty == nullptr)
79
        return;
80
81
    PartyMember *const member = Ea::taParty->addMember(id, nick);
82
    if (member != nullptr)
83
    {
84
        if ((partyTab != nullptr) && member->getOnline() != online)
85
            partyTab->showOnline(nick, fromBool(online, Online));
86
        member->setLeader(leader);
87
        member->setOnline(online);
88
        member->setMap(map);
89
        member->setX(x);
90
        member->setY(y);
91
        if (level != 0)
92
            member->setLevel(level);
93
    }
94
}
95
96
void PartyRecv::processPartyMemberJobLevel(Net::MessageIn &msg)
97
{
98
    const BeingId id = msg.readBeingId("account id");
99
    msg.readInt16("class");
100
    const int level = msg.readInt16("level");
101
102
    if (Ea::taParty == nullptr)
103
        return;
104
105
    PartyMember *const member = Ea::taParty->getMember(id);
106
    if (member != nullptr)
107
    {
108
        member->setOnline(true);
109
        if (level != 0)
110
            member->setLevel(level);
111
    }
112
    else
113
    {
114
        reportAlways("processPartyMemberJobLevel: party member not exists.");
115
    }
116
}
117
118
void PartyRecv::processPartySettings(Net::MessageIn &msg)
119
{
120
    if (partyTab == nullptr)
121
    {
122
        if (chatWindow == nullptr)
123
            return;
124
125
        Ea::PartyRecv::createTab();
126
    }
127
128
    const PartyShareT exp = static_cast<PartyShareT>(
129
        msg.readInt32("party exp"));
130
    Ea::PartyRecv::processPartyExpSettingsContinue(msg, exp);
131
    if (msg.getVersion() >= 20090603)
132
    {
133
        const PartyShareT item = static_cast<PartyShareT>(
134
            msg.readInt8("pickup item share (&1)"));
135
        Ea::PartyRecv::processPartyItemSettingsContinue(msg, item);
136
        const PartyShareT autoItem = static_cast<PartyShareT>(
137
            msg.readInt8("get auto item share (&2)"));
138
        processPartyAutoItemSettingsContinue(msg, autoItem);
139
    }
140
}
141
142
void PartyRecv::processPartyInfo(Net::MessageIn &msg)
143
{
144
    bool isOldParty = false;
145
    std::set<std::string> names;
146
    std::set<std::string> onlineNames;
147
    if (Ea::taParty == nullptr)
148
    {
149
        logger->log1("error: party empty in SMSG_PARTY_INFO");
150
        Ea::taParty = Party::getParty(1);
151
    }
152
    if (partyTab == nullptr)
153
        Ea::PartyRecv::createTab();
154
155
    if (Ea::taParty != nullptr)
156
    {
157
        if (Ea::taParty->getNumberOfElements() > 1)
158
        {
159
            isOldParty = true;
160
            Ea::taParty->getNamesSet(names);
161
            const Party::MemberList *const members = Ea::taParty->getMembers();
162
            FOR_EACHP (Party::MemberList::const_iterator, it, members)
163
            {
164
                if ((*it)->getOnline())
165
                    onlineNames.insert((*it)->getName());
166
            }
167
            if (localPlayer != nullptr)
168
                onlineNames.insert(localPlayer->getName());
169
        }
170
    }
171
172
    if (localPlayer == nullptr)
173
        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
174
175
    if (Ea::taParty != nullptr)
176
        Ea::taParty->clearMembers();
177
178
    const int length = msg.readInt16("len");
179
    if (Ea::taParty != nullptr)
180
    {
181
        const std::string name = msg.readString(24, "party name");
182
        Ea::taParty->setName(name);
183
    }
184
    else
185
    {
186
        msg.readString(24, "party name");
187
    }
188
189
    int partySize = 0;
190
    int offset = 0;
191
    if (msg.getVersion() >= 20170502)
192
    {
193
        partySize = 50;
194
        offset = 28 + 6;
195
    }
196
    else
197
    {
198
        partySize = 46;
199
        offset = 28;
200
    }
201
202
    const int count = (length - offset) / partySize;
203
    if (localPlayer != nullptr &&
204
        Ea::taParty != nullptr)
205
    {
206
        localPlayer->setParty(Ea::taParty);
207
        localPlayer->setPartyName(Ea::taParty->getName());
208
    }
209
210
    for (int i = 0; i < count; i++)
211
    {
212
        const BeingId id = msg.readBeingId("account id");
213
        std::string nick = msg.readString(24, "nick");
214
        std::string map = msg.readString(16, "map name");
215
        const bool leader = msg.readUInt8("leader") == 0U;
216
        const bool online = msg.readUInt8("online") == 0U;
217
        int level = 0;
218
        if (msg.getVersion() >= 20170502)
219
        {
220
            msg.readInt16("class");
221
            level = msg.readInt16("level");
222
        }
223
224
        if (Ea::taParty != nullptr)
225
        {
226
            bool joined(false);
227
228
            if (isOldParty)
229
            {
230
                if (names.find(nick) == names.end())
231
                {
232
                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
233
                        nick);
234
                    joined = true;
235
                }
236
            }
237
            PartyMember *const member = Ea::taParty->addMember(id, nick);
238
            if (member != nullptr)
239
            {
240
                if (!joined && (partyTab != nullptr))
241
                {
242
                    if (!names.empty() && ((onlineNames.find(nick)
243
                        == onlineNames.end() && online)
244
                        || (onlineNames.find(nick) != onlineNames.end()
245
                        && !online)))
246
                    {
247
                        partyTab->showOnline(nick, fromBool(online, Online));
248
                    }
249
                }
250
                member->setLeader(leader);
251
                member->setOnline(online);
252
                member->setMap(map);
253
                if (level != 0)
254
                    member->setLevel(level);
255
            }
256
        }
257
    }
258
259
    if (msg.getVersion() >= 20170502 && msg.getUnreadLength() >= 6)
260
    {
261
        msg.readInt8("pickup item share (&1)");
262
        msg.readInt8("get item share (&2)");
263
        msg.readInt32("unknown");
264
    }
265
266
    if (Ea::taParty != nullptr)
267
        Ea::taParty->sort();
268
269
    if ((localPlayer != nullptr) && (Ea::taParty != nullptr))
270
    {
271
        localPlayer->setParty(Ea::taParty);
272
        localPlayer->setPartyName(Ea::taParty->getName());
273
        if (socialWindow != nullptr)
274
            socialWindow->updateParty();
275
    }
276
}
277
278
void PartyRecv::processPartyMessage(Net::MessageIn &msg)
279
{
280
    const int msgLength = msg.readInt16("len") - 8;
281
    if (msgLength <= 0)
282
        return;
283
284
    const BeingId id = msg.readBeingId("id");
285
    std::string chatMsg = msg.readString(msgLength, "message");
286
287
    const size_t pos = chatMsg.find(" : ", 0);
288
    if (pos != std::string::npos)
289
        chatMsg.erase(0, pos + 3);
290
291
    if ((Ea::taParty != nullptr) && (partyTab != nullptr))
292
    {
293
        const PartyMember *const member = Ea::taParty->getMember(id);
294
        if (member != nullptr)
295
        {
296
            partyTab->chatLog(member->getName(), chatMsg);
297
        }
298
        else
299
        {
300
            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
301
                chatMsg);
302
        }
303
    }
304
}
305
306
void PartyRecv::processPartyInviteResponse(Net::MessageIn &msg)
307
{
308
    if (partyTab == nullptr)
309
        return;
310
311
    const std::string nick = msg.readString(24, "nick");
312
313
    switch (msg.readInt32("result"))
314
    {
315
        case 0:
316
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
317
                nick);
318
            break;
319
        case 1:
320
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
321
            break;
322
        case 2:
323
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
324
            break;
325
        case 3:
326
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
327
                nick);
328
            break;
329
        case 4:
330
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_SAME_ACCOUNT,
331
                nick);
332
            break;
333
        case 5:
334
            NotifyManager::notify(
335
                NotifyTypes::PARTY_INVITE_PARTY_BLOCKED_INVITE,
336
                nick);
337
            break;
338
        case 7:
339
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_NOT_ONLINE,
340
                nick);
341
            break;
342
        default:
343
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
344
            break;
345
    }
346
}
347
348
void PartyRecv::processPartyItemPickup(Net::MessageIn &msg)
349
{
350
    UNIMPLEMENTEDPACKET;
351
    // +++ probably need add option to show pickup notifications
352
    // in party tab
353
    msg.readBeingId("account id");
354
    msg.readInt16("item id");
355
    msg.readUInt8("identify");
356
    msg.readUInt8("attribute");
357
    msg.readUInt8("refine");
358
    for (int f = 0; f < maxCards; f++)
359
        msg.readUInt16("card");
360
    msg.readInt16("equip location");
361
    msg.readUInt8("item type");
362
    // for color can be used ItemColorManager
363
}
364
365
void PartyRecv::processPartyLeader(Net::MessageIn &msg)
366
{
367
    PartyMember *const oldMember = Ea::taParty->getMember(
368
        msg.readBeingId("old leder id"));
369
    PartyMember *const newMember = Ea::taParty->getMember(
370
        msg.readBeingId("new leder id"));
371
    if (oldMember != nullptr)
372
        oldMember->setLeader(false);
373
    if (newMember != nullptr)
374
        newMember->setLeader(true);
375
}
376
377
void PartyRecv::processPartyInvited(Net::MessageIn &msg)
378
{
379
    if (socialWindow == nullptr)
380
    {
381
        msg.readInt32("party id");
382
        msg.readString(24, "party name");
383
        return;
384
    }
385
    const int id = msg.readInt32("party id");
386
    const std::string partyName = msg.readString(24, "party name");
387
388
    if (socialWindow != nullptr)
389
        socialWindow->showPartyInvite(partyName, std::string(), id);
390
}
391
392
void PartyRecv::processPartyAutoItemSettingsContinue(Net::MessageIn &msg,
393
                                                     const PartyShareT item)
394
{
395
    switch (item)
396
    {
397
        case PartyShare::YES:
398
            if (mShareAutoItems == PartyShare::YES)
399
                break;
400
            mShareAutoItems = PartyShare::YES;
401
            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ON);
402
            break;
403
        case PartyShare::NO:
404
            if (mShareAutoItems == PartyShare::NO)
405
                break;
406
            mShareAutoItems = PartyShare::NO;
407
            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_OFF);
408
            break;
409
        case PartyShare::NOT_POSSIBLE:
410
            if (mShareAutoItems == PartyShare::NOT_POSSIBLE)
411
                break;
412
            mShareAutoItems = PartyShare::NOT_POSSIBLE;
413
            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ERROR);
414
            break;
415
        default:
416
        case PartyShare::UNKNOWN:
417
            UNIMPLEMENTEDPACKETFIELD(CAST_S32(item));
418
            break;
419
    }
420
}
421
422
4
}  // namespace EAthena