GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/net/tmwa/partyrecv.cpp Lines: 1 138 0.7 %
Date: 2021-03-17 Branches: 0 171 0.0 %

Line Branch Exec Source
1
/*
2
 *  The ManaPlus Client
3
 *  Copyright (C) 2008  Lloyd Bryant <[email protected]>
4
 *  Copyright (C) 2011-2019  The ManaPlus Developers
5
 *  Copyright (C) 2019-2021  Andrei Karas
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/tmwa/partyrecv.h"
24
25
#include "actormanager.h"
26
#include "notifymanager.h"
27
#include "party.h"
28
29
#include "being/localplayer.h"
30
31
#include "enums/resources/notifytypes.h"
32
33
#include "gui/windows/chatwindow.h"
34
#include "gui/windows/socialwindow.h"
35
36
#include "gui/widgets/tabs/chat/partytab.h"
37
38
#include "net/messagein.h"
39
40
#include "net/ea/partyrecv.h"
41
42
#include "utils/foreach.h"
43
44
#include "debug.h"
45
46
namespace TmwAthena
47
{
48
49
void PartyRecv::processPartySettings(Net::MessageIn &msg)
50
{
51
    if (partyTab == nullptr)
52
    {
53
        if (chatWindow == nullptr)
54
            return;
55
56
        Ea::PartyRecv::createTab();
57
    }
58
59
    // These seem to indicate the sharing mode for exp and items
60
    const PartyShareT exp = static_cast<PartyShareT>(
61
        msg.readInt16("share exp"));
62
    const PartyShareT item = static_cast<PartyShareT>(
63
        msg.readInt16("share items"));
64
    Ea::PartyRecv::processPartyExpSettingsContinue(msg, exp);
65
    Ea::PartyRecv::processPartyItemSettingsContinue(msg, item);
66
}
67
68
void PartyRecv::processPartyInfo(Net::MessageIn &msg)
69
{
70
    bool isOldParty = false;
71
    std::set<std::string> names;
72
    std::set<std::string> onlineNames;
73
    if (Ea::taParty == nullptr)
74
    {
75
        logger->log1("error: party empty in SMSG_PARTY_INFO");
76
        Ea::taParty = Party::getParty(1);
77
    }
78
    if (Ea::taParty != nullptr)
79
    {
80
        if (Ea::taParty->getNumberOfElements() > 1)
81
        {
82
            isOldParty = true;
83
            Ea::taParty->getNamesSet(names);
84
            const Party::MemberList *const members = Ea::taParty->getMembers();
85
            FOR_EACHP (Party::MemberList::const_iterator, it, members)
86
            {
87
                if ((*it)->getOnline())
88
                    onlineNames.insert((*it)->getName());
89
            }
90
            if (localPlayer != nullptr)
91
                onlineNames.insert(localPlayer->getName());
92
        }
93
    }
94
95
    if (localPlayer == nullptr)
96
        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
97
98
    if (Ea::taParty != nullptr)
99
        Ea::taParty->clearMembers();
100
101
    const int length = msg.readInt16("len");
102
    if (Ea::taParty != nullptr)
103
        Ea::taParty->setName(msg.readString(24, "party name"));
104
105
    const int count = (length - 28) / 46;
106
    if ((localPlayer != nullptr) && (Ea::taParty != nullptr))
107
    {
108
        localPlayer->setParty(Ea::taParty);
109
        localPlayer->setPartyName(Ea::taParty->getName());
110
    }
111
112
    for (int i = 0; i < count; i++)
113
    {
114
        const BeingId id = msg.readBeingId("id");
115
        std::string nick = msg.readString(24, "nick");
116
        std::string map = msg.readString(16, "map");
117
        const bool leader = msg.readUInt8("leader") == 0U;
118
        const bool online = msg.readUInt8("online") == 0U;
119
120
        if (Ea::taParty != nullptr)
121
        {
122
            bool joined(false);
123
124
            if (isOldParty)
125
            {
126
                if (names.find(nick) == names.end())
127
                {
128
                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
129
                        nick);
130
                    joined = true;
131
                }
132
            }
133
            PartyMember *const member = Ea::taParty->addMember(id, nick);
134
            if (member != nullptr)
135
            {
136
                if (!joined && (partyTab != nullptr))
137
                {
138
                    if (!names.empty() && ((onlineNames.find(nick)
139
                        == onlineNames.end() && online)
140
                        || (onlineNames.find(nick) != onlineNames.end()
141
                        && !online)))
142
                    {
143
                        partyTab->showOnline(nick, fromBool(online, Online));
144
                    }
145
146
                    member->setLeader(leader);
147
                    member->setOnline(online);
148
                    member->setMap(map);
149
                }
150
                else
151
                {
152
                    member->setLeader(leader);
153
                    member->setOnline(online);
154
                    member->setMap(map);
155
                }
156
            }
157
        }
158
    }
159
160
    if (Ea::taParty != nullptr)
161
        Ea::taParty->sort();
162
163
    if ((localPlayer != nullptr) && (Ea::taParty != nullptr))
164
    {
165
        localPlayer->setParty(Ea::taParty);
166
        localPlayer->setPartyName(Ea::taParty->getName());
167
        if (socialWindow != nullptr)
168
            socialWindow->updateParty();
169
    }
170
}
171
172
void PartyRecv::processPartyMessage(Net::MessageIn &msg)
173
{
174
    const int msgLength = msg.readInt16("len") - 8;
175
    if (msgLength <= 0)
176
        return;
177
178
    const BeingId id = msg.readBeingId("id");
179
    const std::string chatMsg = msg.readString(msgLength, "message");
180
181
    if ((Ea::taParty != nullptr) && (partyTab != nullptr))
182
    {
183
        const PartyMember *const member = Ea::taParty->getMember(id);
184
        if (member != nullptr)
185
        {
186
            partyTab->chatLog(member->getName(), chatMsg);
187
        }
188
        else
189
        {
190
            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
191
                chatMsg);
192
        }
193
    }
194
}
195
196
void PartyRecv::processPartyInviteResponse(Net::MessageIn &msg)
197
{
198
    if (partyTab == nullptr)
199
        return;
200
201
    const std::string nick = msg.readString(24, "nick");
202
203
    switch (msg.readUInt8("status"))
204
    {
205
        case 0:
206
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
207
                nick);
208
            break;
209
        case 1:
210
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
211
            break;
212
        case 2:
213
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
214
            break;
215
        case 3:
216
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
217
                nick);
218
            break;
219
        default:
220
            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
221
            break;
222
    }
223
}
224
225
void PartyRecv::processPartyInvited(Net::MessageIn &msg)
226
{
227
    const BeingId id = msg.readBeingId("account id");
228
    std::string nick;
229
230
    if (actorManager != nullptr)
231
    {
232
        const Being *const being = actorManager->findBeing(id);
233
        if (being != nullptr)
234
        {
235
            if (being->getType() == ActorType::Player)
236
                nick = being->getName();
237
        }
238
    }
239
240
    if (socialWindow != nullptr)
241
    {
242
        const std::string partyName = msg.readString(24, "party name");
243
        socialWindow->showPartyInvite(partyName, nick, 0);
244
    }
245
    else
246
    {
247
        msg.readString(24, "party name");
248
    }
249
}
250
251
void PartyRecv::processPartyMove(Net::MessageIn &msg)
252
{
253
    const BeingId id = msg.readBeingId("id");
254
    PartyMember *m = nullptr;
255
    if (Ea::taParty != nullptr)
256
        m = Ea::taParty->getMember(id);
257
    if (m != nullptr)
258
    {
259
        msg.readInt32("unused");
260
        m->setX(msg.readInt16("x"));
261
        m->setY(msg.readInt16("y"));
262
        const bool online = msg.readUInt8("online") != 0;
263
        if (m->getOnline() != online)
264
            partyTab->showOnline(m->getName(), fromBool(online, Online));
265
        m->setOnline(online);
266
        msg.readString(24, "party");
267
        msg.readString(24, "nick");
268
        m->setMap(msg.readString(16, "map"));
269
    }
270
    else
271
    {
272
        msg.readInt32("unused");
273
        msg.readInt16("x");
274
        msg.readInt16("y");
275
        msg.readUInt8("online");
276
        msg.readString(24, "party");
277
        msg.readString(24, "nick");
278
        msg.readString(16, "map");
279
    }
280
}
281
282
void PartyRecv::processPartyUpdateHp(Net::MessageIn &msg)
283
{
284
    const BeingId id = msg.readBeingId("id");
285
    const int hp = msg.readInt16("hp");
286
    const int maxhp = msg.readInt16("max hp");
287
    PartyMember *m = nullptr;
288
    if (Ea::taParty != nullptr)
289
        m = Ea::taParty->getMember(id);
290
    if (m != nullptr)
291
    {
292
        m->setHp(hp);
293
        m->setMaxHp(maxhp);
294
    }
295
296
    // The server only sends this when the member is in range, so
297
    // lets make sure they get the party hilight.
298
    if ((actorManager != nullptr) && (Ea::taParty != nullptr))
299
    {
300
        if (Being *const b = actorManager->findBeing(id))
301
            b->setParty(Ea::taParty);
302
    }
303
}
304
305
2
}  // namespace TmwAthena