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