Mana
Loading...
Searching...
No Matches
partyhandler.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2008 Lloyd Bryant <lloyd_bryant@netzero.net>
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana 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
23
24#include "actorspritemanager.h"
25#include "event.h"
26#include "localplayer.h"
27#include "log.h"
28#include "party.h"
29
30#include "gui/socialwindow.h"
31
32#include "net/tmwa/messagein.h"
33#include "net/tmwa/messageout.h"
34#include "net/tmwa/protocol.h"
35
37
38#include "utils/gettext.h"
39#include "utils/stringutils.h"
40
41#define PARTY_ID 1
42
44
45namespace TmwAthena {
46
47PartyTab *partyTab = nullptr;
49
69
71{
72 delete partyTab;
73 partyTab = nullptr;
74}
75
77{
78 switch (msg.getId())
79 {
81 if (msg.readInt8())
82 serverNotice(_("Could not create party."));
83 else
84 serverNotice(_("Party successfully created."));
85 break;
86 case SMSG_PARTY_INFO:
87 {
89
90 int length = msg.readInt16();
91 taParty->setName(msg.readString(24));
92 int count = (length - 28) / 46;
93
94 for (int i = 0; i < count; i++)
95 {
96 int id = msg.readInt32();
97 std::string nick = msg.readString(24);
98 std::string map = msg.readString(16);
99 bool leader = msg.readInt8() == 0;
100 bool online = msg.readInt8() == 0;
101
102 PartyMember *member = taParty->addMember(id, nick);
103 member->setLeader(leader);
104 member->setOnline(online);
105 }
106
108 }
109 break;
111 {
112 if (!partyTab)
113 break;
114
115 std::string nick = msg.readString(24);
116 switch (msg.readInt8())
117 {
118 case 0:
119 partyTab->chatLog(strprintf(_("%s is already a member of a party."),
120 nick.c_str()), BY_SERVER);
121 break;
122 case 1:
123 partyTab->chatLog(strprintf(_("%s refused your invitation."),
124 nick.c_str()), BY_SERVER);
125 break;
126 case 2:
127 partyTab->chatLog(strprintf(_("%s is now a member of your party."),
128 nick.c_str()), BY_SERVER);
129 break;
130 default:
131 partyTab->chatLog(strprintf(_("Unknown invite response for %s."),
132 nick.c_str()), BY_SERVER);
133 break;
134 }
135 break;
136 }
138 {
139 int id = msg.readInt32();
140 std::string partyName = msg.readString(24);
141 std::string nick;
142 Being *being;
143
144 if ((being = actorSpriteManager->findBeing(id)))
145 {
146 nick = being->getName();
147 }
148
149 socialWindow->showPartyInvite(nick, partyName);
150 break;
151 }
153 {
154 if (!partyTab)
155 {
156 if (!chatWindow)
157 break;
158
159 partyTab = new PartyTab();
160 }
161
162 // These seem to indicate the sharing mode for exp and items
163 short exp = msg.readInt16();
164 short item = msg.readInt16();
165
166 switch (exp)
167 {
168 case PARTY_SHARE:
169 if (mShareExp == PARTY_SHARE)
170 break;
172 partyTab->chatLog(_("Experience sharing enabled."), BY_SERVER);
173 break;
174 case PARTY_SHARE_NO:
176 break;
178 partyTab->chatLog(_("Experience sharing disabled."), BY_SERVER);
179 break;
182 break;
184 partyTab->chatLog(_("Experience sharing not possible."), BY_SERVER);
185 break;
186 default:
187 Log::info("Unknown party exp option: %d", exp);
188 }
189
190 switch (item)
191 {
192 case PARTY_SHARE:
194 break;
196 partyTab->chatLog(_("Item sharing enabled."), BY_SERVER);
197 break;
198 case PARTY_SHARE_NO:
200 break;
202 partyTab->chatLog(_("Item sharing disabled."), BY_SERVER);
203 break;
206 break;
208 partyTab->chatLog(_("Item sharing not possible."), BY_SERVER);
209 break;
210 default:
211 Log::info("Unknown party item option: %d", exp);
212 }
213 break;
214 }
215 case SMSG_PARTY_LEAVE:
216 {
217 int id = msg.readInt32();
218 std::string nick = msg.readString(24);
219 msg.readInt8(); // fail
220 if (id == local_player->getId())
221 {
224 serverNotice(_("You have left the party."));
225 if (partyTab)
226 {
227 delete partyTab;
228 partyTab = nullptr;
229 }
231 }
232 else
233 {
234 partyTab->chatLog(strprintf(_("%s has left your party."),
235 nick.c_str()), BY_SERVER);
236
237 if (Being *b = actorSpriteManager->findBeing(id))
238 {
239 b->setParty(nullptr);
240 }
241
243 }
244 break;
245 }
247 {
248 int id = msg.readInt32();
249 int hp = msg.readInt16();
250 int maxhp = msg.readInt16();
251 PartyMember *m = taParty->getMember(id);
252 if (m)
253 {
254 m->setHp(hp);
255 m->setMaxHp(maxhp);
256 }
257
258 // The server only sends this when the member is in range, so
259 // lets make sure they get the party hilight.
260 if (Being *b = actorSpriteManager->findBeing(id))
261 {
262 b->setParty(taParty);
263 }
264 }
265 break;
267 {
268 msg.readInt32(); // id
269 msg.readInt16(); // x
270 msg.readInt16(); // y
271 }
272 break;
274 {
275 int msgLength = msg.readInt16() - 8;
276 if (msgLength <= 0)
277 {
278 return;
279 }
280 int id = msg.readInt32();
281 std::string chatMsg = msg.readString(msgLength);
282
283 PartyMember *member = taParty->getMember(id);
284 if (member)
285 partyTab->chatLog(member->getName(), chatMsg);
286 else
287 partyTab->chatLog(strprintf(_("An unknown member tried to "
288 "say: %s"), chatMsg.c_str()), BY_SERVER);
289 }
290 break;
291 }
292}
293
294void PartyHandler::create(const std::string &name)
295{
297 outMsg.writeString(name.substr(0, 23), 24);
298}
299
300void PartyHandler::join(int partyId)
301{
302 // TODO?
303}
304
306{
308 outMsg.writeInt32(being->getId());
309}
310
311void PartyHandler::invite(const std::string &name)
312{
314
315 if (invitee)
316 {
317 invite(invitee);
318 partyTab->chatLog(strprintf(_("Invited user %s to party."),
319 invitee->getName().c_str()), BY_SERVER);
320 }
321 else if (partyTab)
322 {
323 partyTab->chatLog(strprintf(_("Inviting failed, because you can't see "
324 "a player called %s."), name.c_str()), BY_SERVER);
325 }
326 else
327 {
328 serverNotice(_("You can only invite when you are in a party!"));
329 }
330}
331
332void PartyHandler::inviteResponse(const std::string &inviter, bool accept)
333{
335 outMsg.writeInt32(local_player->getId());
336 outMsg.writeInt32(accept ? 1 : 0);
337}
338
340{
342}
343
345{
347 outMsg.writeInt32(being->getId());
348 outMsg.writeString("", 24); //Unused
349}
350
351void PartyHandler::kick(const std::string &name)
352{
353 PartyMember *m = taParty->getMember(name);
354 if (!m)
355 {
356 partyTab->chatLog(strprintf(_("%s is not in your party!"), name.c_str()),
357 BY_SERVER);
358 return;
359 }
360
362 outMsg.writeInt32(m->getID());
363 outMsg.writeString(name, 24); //Unused
364}
365
366void PartyHandler::chat(const std::string &text)
367{
369 outMsg.writeInt16(text.length() + 4);
370 outMsg.writeString(text, text.length());
371}
372
374{
375 // Our eAthena doesn't have this message
376 // Not needed anyways
377}
378
380{
381 if (share == PARTY_SHARE_NOT_POSSIBLE)
382 return;
383
385 outMsg.writeInt16(share);
386 outMsg.writeInt16(mShareItems);
387}
388
390{
391 if (share == PARTY_SHARE_NOT_POSSIBLE)
392 return;
393
395 outMsg.writeInt16(mShareExp);
396 outMsg.writeInt16(share);
397}
398
399} // namespace TmwAthena
ActorSpriteManager * actorSpriteManager
Definition game.cpp:110
@ BY_SERVER
Definition chatwindow.h:50
Being * findBeingByName(const std::string &name, ActorSprite::Type type=Being::UNKNOWN) const
Finds a being by name and (optionally) by type.
Being * findBeing(int id) const
Returns a specific Being, by id;.
int getId() const
Definition actorsprite.h:63
const std::string & getName() const
Returns the avatar's name.
Definition avatar.h:34
void setOnline(bool online)
Set the avatar's online status.
Definition avatar.h:49
void setHp(int hp)
Definition avatar.h:53
void setMaxHp(int maxHp)
Definition avatar.h:57
Definition being.h:65
const std::string & getName() const
Returns the name of the being.
Definition being.h:190
void setParty(Party *party)
Definition being.cpp:549
void chatLog(std::string line, Own own=BY_SERVER, bool ignoreRecord=false)
Adds a line of text to our message list.
Definition chattab.cpp:111
const uint16_t * handledMessages
int getID() const
Definition party.h:38
void setLeader(bool leader)
Definition party.h:46
Definition party.h:59
static Party * getParty(int id)
Definition party.cpp:185
PartyMember * getMember(int id) const
Find a member by ID.
Definition party.cpp:60
PartyMember * addMember(int id, const std::string &name)
Adds member to the list.
Definition party.cpp:45
void setName(const std::string &name)
Set the party's name.
Definition party.h:65
void removeFromMembers()
Definition party.cpp:121
void removeMember(PartyMember *member)
Removes a member from the party.
Definition party.cpp:78
void clearMembers()
Definition party.h:122
bool removeTab(Guild *guild)
void showPartyInvite(const std::string &inviter, const std::string &partyName=std::string())
Used for parsing an incoming message from eAthena.
Definition messagein.h:35
std::string readString(int length=-1)
Reads a string.
uint16_t readInt16()
Reads an unsigned 16-bit integer from the message.
Definition messagein.cpp:57
uint8_t readInt8()
Reads an unsigned 8-bit integer from the message.
Definition messagein.cpp:46
uint16_t getId() const
Returns the message ID.
Definition messagein.h:42
uint32_t readInt32()
Reads an unsigned 32-bit integer from the message.
Definition messagein.cpp:69
Used for building an outgoing message to eAthena.
Definition messageout.h:35
void writeInt32(uint32_t value)
Writes an unsigned 32-bit integer to the message.
void writeInt16(uint16_t value)
Writes an unsigned 16-bit integer to the message.
void writeString(const std::string &string, int length=-1)
Writes a string.
void setShareExperience(PartyShare share) override
void invite(Being *being) override
void inviteResponse(const std::string &inviter, bool accept) override
void create(const std::string &name=std::string()) override
void chat(const std::string &text) override
void kick(Being *being) override
void handleMessage(MessageIn &msg) override
void setShareItems(PartyShare share) override
void requestPartyMembers() override
void join(int partyId) override
A tab for a party chat channel.
Definition partytab.h:32
void serverNotice(const std::string &message)
Definition event.h:319
SocialWindow * socialWindow
Definition game.cpp:108
ChatWindow * chatWindow
Definition game.cpp:93
#define _(s)
Definition gettext.h:38
LocalPlayer * local_player
Net::PartyHandler * partyHandler
Definition net.cpp:55
void info(const char *log_text,...) LOG_PRINTF_ATTR
Warning: buffers and other variables are shared, so there can be only one connection active at a time...
PartyTab * partyTab
Party * taParty
@ SMSG_PARTY_INFO
Definition protocol.h:248
@ SMSG_PARTY_UPDATE_COORDS
Definition protocol.h:259
@ SMSG_PARTY_MESSAGE
Definition protocol.h:261
@ SMSG_PARTY_INVITED
Definition protocol.h:251
@ SMSG_PARTY_LEAVE
Definition protocol.h:257
@ CMSG_PARTY_LEAVE
Definition protocol.h:253
@ CMSG_PARTY_INVITED
Definition protocol.h:252
@ SMSG_PARTY_INVITE_RESPONSE
Definition protocol.h:250
@ CMSG_PARTY_INVITE
Definition protocol.h:249
@ CMSG_PARTY_KICK
Definition protocol.h:256
@ CMSG_PARTY_MESSAGE
Definition protocol.h:260
@ CMSG_PARTY_CREATE
Definition protocol.h:246
@ SMSG_PARTY_CREATE
Definition protocol.h:247
@ SMSG_PARTY_SETTINGS
Definition protocol.h:254
@ CMSG_PARTY_SETTINGS
Definition protocol.h:255
@ SMSG_PARTY_UPDATE_HP
Definition protocol.h:258
PartyShare
@ PARTY_SHARE
@ PARTY_SHARE_NO
@ PARTY_SHARE_UNKNOWN
@ PARTY_SHARE_NOT_POSSIBLE
std::string strprintf(char const *format,...)
A safe version of sprintf that returns a std::string of the result.