ManaPlus
partyrecv.cpp
Go to the documentation of this file.
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/eathena/partyrecv.h"
24 
25 #include "notifymanager.h"
26 #include "party.h"
27 
28 #include "being/localplayer.h"
29 
31 
32 #include "gui/windows/chatwindow.h"
34 
36 
37 #include "net/messagein.h"
38 
39 #include "net/ea/partyrecv.h"
40 
41 #include "utils/checkutils.h"
42 #include "utils/foreach.h"
43 
44 #include "debug.h"
45 
46 extern bool packets_zero;
47 
48 namespace EAthena
49 {
50 
51 namespace PartyRecv
52 {
54 } // namespace PartyRecv
55 
57 {
58  // +++ for now server allow only switch this option but not using it.
59  msg.readUInt8("allow party");
60 }
61 
63 {
64  const BeingId id = msg.readBeingId("account id");
65  if (msg.getVersion() >= 20171207)
66  msg.readBeingId("char id");
67  const bool leader = msg.readInt32("leader") == 0U;
68  int level = 0;
69  if (msg.getVersionMain() >= 20170524 ||
70  msg.getVersionRe() >= 20170502 ||
71  packets_zero == true)
72  {
73  msg.readInt16("class");
74  level = msg.readInt16("level");
75  }
76  const int x = msg.readInt16("x");
77  const int y = msg.readInt16("y");
78  const bool online = msg.readInt8("online") == 0U;
79  msg.readString(24, "party name");
80  const std::string nick = msg.readString(24, "player name");
81  const std::string map = msg.readString(16, "map name");
82  msg.readInt8("pickup item share (&1)");
83  msg.readInt8("get item share (&2)");
84 
85  if (Ea::taParty == nullptr)
86  return;
87 
88  PartyMember *const member = Ea::taParty->addMember(id, nick);
89  if (member != nullptr)
90  {
91  if ((partyTab != nullptr) && member->getOnline() != online)
92  partyTab->showOnline(nick, fromBool(online, Online));
93  member->setLeader(leader);
94  member->setOnline(online);
95  member->setMap(map);
96  member->setX(x);
97  member->setY(y);
98  if (level != 0)
99  member->setLevel(level);
100  }
101 }
102 
104 {
105  const BeingId id = msg.readBeingId("account id");
106  msg.readInt16("class");
107  const int level = msg.readInt16("level");
108 
109  if (Ea::taParty == nullptr)
110  return;
111 
112  PartyMember *const member = Ea::taParty->getMember(id);
113  if (member != nullptr)
114  {
115  member->setOnline(true);
116  if (level != 0)
117  member->setLevel(level);
118  }
119  else
120  {
121  reportAlways("processPartyMemberJobLevel: party member not exists.")
122  }
123 }
124 
126 {
127  if (partyTab == nullptr)
128  {
129  if (chatWindow == nullptr)
130  return;
131 
133  }
134 
135  const PartyShareT exp = static_cast<PartyShareT>(
136  msg.readInt32("party exp"));
138  if (msg.getVersion() >= 20090603)
139  {
140  const PartyShareT item = static_cast<PartyShareT>(
141  msg.readInt8("pickup item share (&1)"));
143  const PartyShareT autoItem = static_cast<PartyShareT>(
144  msg.readInt8("get auto item share (&2)"));
146  }
147 }
148 
150 {
151  bool isOldParty = false;
152  std::set<std::string> names;
153  std::set<std::string> onlineNames;
154  if (Ea::taParty == nullptr)
155  {
156  logger->log1("error: party empty in SMSG_PARTY_INFO");
158  }
159  if (partyTab == nullptr)
161 
162  if (Ea::taParty != nullptr)
163  {
164  if (Ea::taParty->getNumberOfElements() > 1)
165  {
166  isOldParty = true;
167  Ea::taParty->getNamesSet(names);
168  const Party::MemberList *const members = Ea::taParty->getMembers();
169  FOR_EACHP (Party::MemberList::const_iterator, it, members)
170  {
171  if ((*it)->getOnline())
172  onlineNames.insert((*it)->getName());
173  }
174  if (localPlayer != nullptr)
175  onlineNames.insert(localPlayer->getName());
176  }
177  }
178 
179  if (localPlayer == nullptr)
180  logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
181 
182  if (Ea::taParty != nullptr)
184 
185  const int length = msg.readInt16("len");
186  if (Ea::taParty != nullptr)
187  {
188  const std::string name = msg.readString(24, "party name");
189  Ea::taParty->setName(name);
190  }
191  else
192  {
193  msg.readString(24, "party name");
194  }
195 
196  int partySize = 0;
197  const int offset = 28;
198  if (msg.getVersion() >= 20171207)
199  {
200  partySize = 4 + 4 + 24 + 16 + 1 + 1 + 2 + 2;
201  }
202  else if (msg.getVersionMain() >= 20170524 ||
203  msg.getVersionRe() >= 20170502 ||
204  packets_zero == true)
205  {
206  partySize = 4 + 24 + 16 + 1 + 1 + 2 + 2;
207  }
208  else
209  {
210  partySize = 4 + 24 + 16 + 1 + 1;
211  }
212 
213  const int count = (length - offset) / partySize;
214  if (localPlayer != nullptr &&
215  Ea::taParty != nullptr)
216  {
219  }
220 
221  for (int i = 0; i < count; i++)
222  {
223  const BeingId id = msg.readBeingId("account id");
224  if (msg.getVersion() >= 20171207)
225  msg.readBeingId("char id");
226  std::string nick = msg.readString(24, "nick");
227  std::string map = msg.readString(16, "map name");
228  const bool leader = msg.readUInt8("leader") == 0U;
229  const bool online = msg.readUInt8("online") == 0U;
230  int level = 0;
231  if (msg.getVersionMain() >= 20170524 ||
232  msg.getVersionRe() >= 20170502 ||
233  packets_zero == true)
234  {
235  msg.readInt16("class");
236  level = msg.readInt16("level");
237  }
238 
239  if (Ea::taParty != nullptr)
240  {
241  bool joined(false);
242 
243  if (isOldParty)
244  {
245  if (names.find(nick) == names.end())
246  {
248  nick);
249  joined = true;
250  }
251  }
252  PartyMember *const member = Ea::taParty->addMember(id, nick);
253  if (member != nullptr)
254  {
255  if (!joined && (partyTab != nullptr))
256  {
257  if (!names.empty() && ((onlineNames.find(nick)
258  == onlineNames.end() && online)
259  || (onlineNames.find(nick) != onlineNames.end()
260  && !online)))
261  {
262  partyTab->showOnline(nick, fromBool(online, Online));
263  }
264  }
265  member->setLeader(leader);
266  member->setOnline(online);
267  member->setMap(map);
268  if (level != 0)
269  member->setLevel(level);
270  }
271  }
272  }
273 
274  // fix for wrong data sent by old hercules. in future need delete it
275  if (msg.getVersion() >= 20170502 && msg.getUnreadLength() >= 6)
276  {
277  msg.readInt8("pickup item share (&1)");
278  msg.readInt8("get item share (&2)");
279  msg.readInt32("unknown");
280  }
281 
282  if (Ea::taParty != nullptr)
283  Ea::taParty->sort();
284 
285  if ((localPlayer != nullptr) && (Ea::taParty != nullptr))
286  {
289  if (socialWindow != nullptr)
291  }
292 }
293 
295 {
296  const int msgLength = msg.readInt16("len") - 8;
297  if (msgLength <= 0)
298  return;
299 
300  const BeingId id = msg.readBeingId("id");
301  std::string chatMsg = msg.readString(msgLength, "message");
302 
303  const size_t pos = chatMsg.find(" : ", 0);
304  if (pos != std::string::npos)
305  chatMsg.erase(0, pos + 3);
306 
307  if ((Ea::taParty != nullptr) && (partyTab != nullptr))
308  {
309  const PartyMember *const member = Ea::taParty->getMember(id);
310  if (member != nullptr)
311  {
312  partyTab->chatLog(member->getName(), chatMsg);
313  }
314  else
315  {
317  chatMsg);
318  }
319  }
320 }
321 
323 {
324  if (partyTab == nullptr)
325  return;
326 
327  const std::string nick = msg.readString(24, "nick");
328 
329  switch (msg.readInt32("result"))
330  {
331  case 0:
333  nick);
334  break;
335  case 1:
337  break;
338  case 2:
340  break;
341  case 3:
343  nick);
344  break;
345  case 4:
347  nick);
348  break;
349  case 5:
352  nick);
353  break;
354  case 7:
356  nick);
357  break;
358  default:
360  break;
361  }
362 }
363 
365 {
367  // +++ probably need add option to show pickup notifications
368  // in party tab
369  msg.readBeingId("account id");
370  msg.readItemId("item id");
371  msg.readUInt8("identify");
372  msg.readUInt8("attribute");
373  msg.readUInt8("refine");
374  for (int f = 0; f < maxCards; f++)
375  msg.readItemId("card");
376  msg.readInt16("equip location");
377  msg.readUInt8("item type");
378  // for color can be used ItemColorManager
379 }
380 
382 {
383  PartyMember *const oldMember = Ea::taParty->getMember(
384  msg.readBeingId("old leder id"));
385  PartyMember *const newMember = Ea::taParty->getMember(
386  msg.readBeingId("new leder id"));
387  if (oldMember != nullptr)
388  oldMember->setLeader(false);
389  if (newMember != nullptr)
390  newMember->setLeader(true);
391 }
392 
394 {
395  if (socialWindow == nullptr)
396  {
397  msg.readInt32("party id");
398  msg.readString(24, "party name");
399  return;
400  }
401  const int id = msg.readInt32("party id");
402  const std::string partyName = msg.readString(24, "party name");
403 
404  if (socialWindow != nullptr)
405  socialWindow->showPartyInvite(partyName, std::string(), id);
406 }
407 
409  const PartyShareT item)
410 {
411  switch (item)
412  {
413  case PartyShare::YES:
415  break;
418  break;
419  case PartyShare::NO:
421  break;
424  break;
427  break;
430  break;
431  default:
432  case PartyShare::UNKNOWN:
434  break;
435  }
436 }
437 
439 {
440  const BeingId id = msg.readBeingId("account id");
441  const int isDead = msg.readUInt8("is dead");
442  PartyMember *const member = Ea::taParty->getMember(id);
443  if (member != nullptr && isDead != 0)
444  {
445  member->setHp(0);
446  }
447 }
448 
449 } // namespace EAthena
int BeingId
Definition: beingid.h:30
#define fromBool(val, name)
Definition: booldefines.h:49
#define maxCards
Definition: cards.h:25
#define CAST_S32
Definition: cast.h:30
ChatWindow * chatWindow
Definition: chatwindow.cpp:94
#define reportAlways(...)
Definition: checkutils.h:253
void setY(const int y)
Definition: avatar.h:135
void setX(const int x)
Definition: avatar.h:129
void setOnline(const bool online)
Definition: avatar.h:87
void setHp(const int hp)
Definition: avatar.h:93
bool getOnline() const
Definition: avatar.h:81
void setLevel(const int level)
Definition: avatar.h:117
void setMap(const std::string &map)
Definition: avatar.h:123
std::string getName() const
Definition: avatar.h:53
void setParty(Party *const party)
Definition: being.cpp:1307
const std::string & getName() const
Definition: being.h:232
void setPartyName(const std::string &name)
Definition: being.cpp:5246
void chatLog(std::string line, ChatMsgTypeT own, const IgnoreRecord ignoreRecord, const TryRemoveColors tryRemoveColors)
Definition: chattab.cpp:111
void showOnline(const std::string &nick, const Online online)
Definition: chattab.cpp:547
void log1(const char *const log_text)
Definition: logger.cpp:238
void setLeader(const bool leader)
Definition: party.h:48
std::vector< PartyMember * > MemberList
Definition: party.h:157
const MemberList * getMembers() const
Definition: party.h:159
void setName(const std::string &name)
Definition: party.h:70
PartyMember * addMember(const BeingId id, const std::string &name)
Definition: party.cpp:85
PartyMember * getMember(const BeingId id) const
Definition: party.cpp:99
void getNamesSet(std::set< std::string > &names) const
Definition: party.cpp:299
static Party * getParty(const int16_t id)
Definition: party.cpp:313
void clearMembers()
Definition: party.h:122
void sort()
Definition: party.cpp:323
void showPartyInvite(const std::string &partyName, const std::string &inviter, const int partyId)
void updateParty()
bool packets_zero
Definition: client.cpp:133
#define FOR_EACHP(type, iter, array)
Definition: foreach.h:31
LocalPlayer * localPlayer
Logger * logger
Definition: logger.cpp:89
#define UNIMPLEMENTEDPACKETFIELD(field)
Definition: logger.h:59
#define UNIMPLEMENTEDPACKET
Definition: logger.h:56
bool msg(InputEvent &event)
Definition: chat.cpp:39
void processPartyMemberInfo(Net::MessageIn &msg)
Definition: partyrecv.cpp:62
void processPartyItemPickup(Net::MessageIn &msg)
Definition: partyrecv.cpp:364
void processPartyLeader(Net::MessageIn &msg)
Definition: partyrecv.cpp:381
void processPartyInvitationStats(Net::MessageIn &msg)
Definition: partyrecv.cpp:56
void processPartyMemberJobLevel(Net::MessageIn &msg)
Definition: partyrecv.cpp:103
void processPartyAutoItemSettingsContinue(Net::MessageIn &msg, const PartyShareT item)
Definition: partyrecv.cpp:408
void processPartyInviteResponse(Net::MessageIn &msg)
Definition: partyrecv.cpp:322
void processPartyInvited(Net::MessageIn &msg)
Definition: partyrecv.cpp:393
void processPartyMemberDead(Net::MessageIn &msg)
Definition: partyrecv.cpp:438
void processPartyInfo(Net::MessageIn &msg)
Definition: partyrecv.cpp:149
void processPartySettings(Net::MessageIn &msg)
Definition: partyrecv.cpp:125
void processPartyMessage(Net::MessageIn &msg)
Definition: partyrecv.cpp:294
PartyShareT mShareAutoItems
Definition: partyrecv.cpp:53
void createTab()
Definition: partyrecv.cpp:226
void processPartyItemSettingsContinue(Net::MessageIn &msg, const PartyShareT item)
Definition: partyrecv.cpp:94
void processPartyExpSettingsContinue(Net::MessageIn &msg, const PartyShareT exp)
Definition: partyrecv.cpp:64
Party * taParty
Definition: partyrecv.cpp:48
const std::string & getName(const int id)
Definition: groupdb.cpp:344
void notify(const unsigned int message)
@ PARTY_USER_JOINED
Definition: notifytypes.h:66
@ PARTY_INVITE_ALREADY_MEMBER
Definition: notifytypes.h:67
@ PARTY_INVITE_PARTY_BLOCKED_INVITE
Definition: notifytypes.h:114
@ PARTY_INVITE_PARTY_SAME_ACCOUNT
Definition: notifytypes.h:113
@ PARTY_UNKNOWN_USER_MSG
Definition: notifytypes.h:82
@ PARTY_INVITE_ERROR
Definition: notifytypes.h:71
@ PARTY_INVITE_PARTY_FULL
Definition: notifytypes.h:70
@ PARTY_INVITE_REFUSED
Definition: notifytypes.h:68
@ PARTY_ITEM_SHARE_ON
Definition: notifytypes.h:75
@ PARTY_ITEM_SHARE_ERROR
Definition: notifytypes.h:77
@ PARTY_INVITE_DONE
Definition: notifytypes.h:69
@ PARTY_ITEM_SHARE_OFF
Definition: notifytypes.h:76
@ PARTY_INVITE_PARTY_NOT_ONLINE
Definition: notifytypes.h:115
@ NOT_POSSIBLE
Definition: partyshare.h:34
bool Online
Definition: online.h:30
PartyShare ::T PartyShareT
Definition: partyshare.h:36
PartyTab * partyTab
Definition: partytab.cpp:45
SocialWindow * socialWindow