2 * Copyright (C) 2005-2010 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "WorldSession.h"
21 #include "Database/DatabaseEnv.h"
23 #include "WorldPacket.h"
24 #include "ObjectMgr.h"
27 static void AttemptJoin(Player
* _player
)
29 // skip not can autojoin cases and player group case
30 if(!_player
->m_lookingForGroup
.canAutoJoin() || _player
->GetGroup())
33 //TODO: Guard Player Map
34 HashMapHolder
<Player
>::MapType
const& players
= sObjectAccessor
.GetPlayers();
35 for(HashMapHolder
<Player
>::MapType::const_iterator iter
= players
.begin(); iter
!= players
.end(); ++iter
)
37 Player
*plr
= iter
->second
;
39 // skip enemies and self
40 if(!plr
|| plr
==_player
|| plr
->GetTeam() != _player
->GetTeam())
43 //skip players not in world
47 // skip not auto add, not group leader cases
48 if (!plr
->GetSession()->LookingForGroup_auto_add
|| (plr
->GetGroup() && plr
->GetGroup()->GetLeaderGUID()!=plr
->GetGUID()))
51 // skip non auto-join or empty slots, or non compatible slots
52 if(!plr
->m_lookingForGroup
.more
.canAutoJoin() || !_player
->m_lookingForGroup
.HaveInSlot(plr
->m_lookingForGroup
.more
))
55 // attempt create group, or skip
58 Group
* group
= new Group
;
59 if(!group
->Create(plr
->GetGUID(), plr
->GetName()))
65 sObjectMgr
.AddGroup(group
);
68 // stop at success join
69 if(plr
->GetGroup()->AddMember(_player
->GetGUID(), _player
->GetName()))
71 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
72 _player
->LeaveLFGChannel();
78 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
)
79 plr
->LeaveLFGChannel();
84 static void AttemptAddMore(Player
* _player
)
86 // skip not group leader case
87 if(_player
->GetGroup() && _player
->GetGroup()->GetLeaderGUID()!=_player
->GetGUID())
90 if(!_player
->m_lookingForGroup
.more
.canAutoJoin())
93 //TODO: Guard Player map
94 HashMapHolder
<Player
>::MapType
const& players
= sObjectAccessor
.GetPlayers();
95 for(HashMapHolder
<Player
>::MapType::const_iterator iter
= players
.begin(); iter
!= players
.end(); ++iter
)
97 Player
*plr
= iter
->second
;
99 // skip enemies and self
100 if(!plr
|| plr
==_player
|| plr
->GetTeam() != _player
->GetTeam())
103 if(!plr
->IsInWorld())
106 // skip not auto join or in group
107 if(!plr
->GetSession()->LookingForGroup_auto_join
|| plr
->GetGroup() )
110 if(!plr
->m_lookingForGroup
.HaveInSlot(_player
->m_lookingForGroup
.more
))
113 // attempt create group if need, or stop attempts
114 if(!_player
->GetGroup())
116 Group
* group
= new Group
;
117 if(!group
->Create(_player
->GetGUID(), _player
->GetName()))
120 return; // can't create group (??)
123 sObjectMgr
.AddGroup(group
);
126 // stop at join fail (full)
127 if(!_player
->GetGroup()->AddMember(plr
->GetGUID(), plr
->GetName()) )
129 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
130 _player
->LeaveLFGChannel();
136 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
)
137 plr
->LeaveLFGChannel();
140 if(_player
->GetGroup()->IsFull() )
142 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
143 _player
->LeaveLFGChannel();
150 void WorldSession::HandleLfgSetAutoJoinOpcode( WorldPacket
& /*recv_data*/ )
152 sLog
.outDebug("CMSG_LFG_SET_AUTOJOIN");
153 LookingForGroup_auto_join
= true;
155 if(!_player
) // needed because STATUS_AUTHED
158 AttemptJoin(_player
);
161 void WorldSession::HandleLfgClearAutoJoinOpcode( WorldPacket
& /*recv_data*/ )
163 sLog
.outDebug("CMSG_LFG_CLEAR_AUTOJOIN");
164 LookingForGroup_auto_join
= false;
167 void WorldSession::HandleLfmSetAutoFillOpcode( WorldPacket
& /*recv_data*/ )
169 sLog
.outDebug("CMSG_LFM_SET_AUTOFILL");
170 LookingForGroup_auto_add
= true;
172 if(!_player
) // needed because STATUS_AUTHED
175 AttemptAddMore(_player
);
178 void WorldSession::HandleLfmClearAutoFillOpcode( WorldPacket
& /*recv_data*/ )
180 sLog
.outDebug("CMSG_LFM_CLEAR_AUTOFILL");
181 LookingForGroup_auto_add
= false;
184 void WorldSession::HandleLfgClearOpcode( WorldPacket
& /*recv_data */ )
187 sLog
.outDebug("CMSG_CLEAR_LOOKING_FOR_GROUP");
189 for(int i
= 0; i
< MAX_LOOKING_FOR_GROUP_SLOT
; ++i
)
190 _player
->m_lookingForGroup
.slots
[i
].Clear();
192 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
193 _player
->LeaveLFGChannel();
195 SendLfgUpdate(0, 0, 0);
198 void WorldSession::HandleLfmClearOpcode( WorldPacket
& /*recv_data */)
201 sLog
.outDebug("CMSG_CLEAR_LOOKING_FOR_MORE");
203 _player
->m_lookingForGroup
.more
.Clear();
206 void WorldSession::HandleSetLfmOpcode( WorldPacket
& recv_data
)
208 sLog
.outDebug("CMSG_SET_LOOKING_FOR_MORE");
209 //recv_data.hexlike();
210 uint32 temp
, entry
, type
;
214 recv_data
>> temp
>> unk1
>> unk2
[0] >> unk2
[1] >> unk2
[2];
216 entry
= ( temp
& 0x00FFFFFF);
217 type
= ( (temp
>> 24) & 0x000000FF);
219 _player
->m_lookingForGroup
.more
.Set(entry
,type
);
220 sLog
.outDebug("LFM set: temp %u, zone %u, type %u", temp
, entry
, type
);
222 if(LookingForGroup_auto_add
)
223 AttemptAddMore(_player
);
225 SendLfgResult(type
, entry
, 1);
228 void WorldSession::HandleSetLfgCommentOpcode( WorldPacket
& recv_data
)
230 sLog
.outDebug("CMSG_SET_LFG_COMMENT");
231 //recv_data.hexlike();
234 recv_data
>> comment
;
235 sLog
.outDebug("LFG comment %s", comment
.c_str());
237 _player
->m_lookingForGroup
.comment
= comment
;
240 void WorldSession::HandleLookingForGroup(WorldPacket
& recv_data
)
242 sLog
.outDebug("MSG_LOOKING_FOR_GROUP");
243 //recv_data.hexlike();
244 uint32 type
, entry
, unk
;
246 recv_data
>> type
>> entry
>> unk
;
247 sLog
.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type
, entry
, unk
);
249 if(LookingForGroup_auto_add
)
250 AttemptAddMore(_player
);
252 if(LookingForGroup_auto_join
)
253 AttemptJoin(_player
);
255 SendLfgResult(type
, entry
, 0);
256 SendLfgUpdate(0, 1, 0);
259 void WorldSession::SendLfgResult(uint32 type
, uint32 entry
, uint8 lfg_type
)
263 WorldPacket data(MSG_LOOKING_FOR_GROUP);
264 data << uint32(type); // type
265 data << uint32(entry); // entry from LFGDungeons.dbc
273 uint64; // player guid
277 data << uint32(0); // count2
281 uint64 // not player guid
285 data << uint8(0); // string
293 for(int i = 0; i < 3; ++i)
300 size_t count3_pos = data.wpos();
301 data << uint32(0); // count3
302 data << uint32(0); // unk
304 //TODO: Guard Player map
305 HashMapHolder<Player>::MapType const& players = sObjectAccessor.GetPlayers();
306 for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
308 Player *plr = iter->second;
310 if(!plr || plr->GetTeam() != _player->GetTeam())
313 if(!plr->IsInWorld())
316 if(!plr->m_lookingForGroup.HaveInSlot(entry, type))
321 data << uint64(plr->GetGUID()); // guid
323 uint32 flags = 0x1FF;
324 data << uint32(flags); // flags
328 data << uint8(plr->getLevel());
329 data << uint8(plr->getClass());
330 data << uint8(plr->getRace());
332 for(int i = 0; i < 3; ++i)
333 data << uint8(0); // spent talents count in specific tab
335 data << uint32(0); // resistances1
336 data << uint32(0); // spd/heal
337 data << uint32(0); // spd/heal
338 data << uint32(0); // combat_rating9
339 data << uint32(0); // combat_rating10
340 data << uint32(0); // combat_rating11
341 data << float(0); // mp5
342 data << float(0); // unk
343 data << uint32(0); // attack power
344 data << uint32(0); // stat1
345 data << uint32(0); // maxhealth
346 data << uint32(0); // maxpower1
347 data << uint32(0); // unk
348 data << float(0); // unk
349 data << uint32(0); // unk
350 data << uint32(0); // unk
351 data << uint32(0); // unk
352 data << uint32(0); // unk
353 data << uint32(0); // combat_rating20
354 data << uint32(0); // unk
358 data << plr->m_lookingForGroup.comment; // comment
361 data << uint8(0); // unk
364 data << uint64(0); // guid from count2 block, not player guid
367 data << uint8(0); // unk
370 data << uint8(plr->m_lookingForGroup.roles); // roles
373 data << uint32(plr->GetZoneId()); // areaid
376 data << uint8(0); // LFG/LFM flag?
380 for(uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j)
382 data << uint32(plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24));
387 data.put<uint32>(count3_pos, number); // fill count placeholder
392 void WorldSession::HandleSetLfgOpcode( WorldPacket
& recv_data
)
394 sLog
.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
396 uint32 slot
, temp
, entry
, type
;
399 recv_data
>> slot
>> temp
>> roles
>> unk1
;
401 entry
= ( temp
& 0x00FFFFFF);
402 type
= ( (temp
>> 24) & 0x000000FF);
404 if(slot
>= MAX_LOOKING_FOR_GROUP_SLOT
)
407 _player
->m_lookingForGroup
.slots
[slot
].Set(entry
, type
);
408 _player
->m_lookingForGroup
.roles
= roles
;
409 sLog
.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot
, temp
, type
, entry
);
411 if(LookingForGroup_auto_join
)
412 AttemptJoin(_player
);
414 //SendLfgResult(type, entry, 0);
415 SendLfgUpdate(0, 1, 0);
418 void WorldSession::HandleLfgSetRoles(WorldPacket
&recv_data
)
420 sLog
.outDebug("CMSG_LFG_SET_ROLES");
425 _player
->m_lookingForGroup
.roles
= roles
;
428 void WorldSession::SendLfgUpdate(uint8 unk1
, uint8 unk2
, uint8 unk3
)
431 /*WorldPacket data(SMSG_LFG_UPDATE, 3);