2 * Copyright (C) 2005-2009 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
= ObjectAccessor::Instance().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 not auto add, not group leader cases
44 if(!plr
->GetSession()->LookingForGroup_auto_add
|| plr
->GetGroup() && plr
->GetGroup()->GetLeaderGUID()!=plr
->GetGUID())
47 // skip non auto-join or empty slots, or non compatible slots
48 if(!plr
->m_lookingForGroup
.more
.canAutoJoin() || !_player
->m_lookingForGroup
.HaveInSlot(plr
->m_lookingForGroup
.more
))
51 // attempt create group, or skip
54 Group
* group
= new Group
;
55 if(!group
->Create(plr
->GetGUID(), plr
->GetName()))
61 objmgr
.AddGroup(group
);
64 // stop at success join
65 if(plr
->GetGroup()->AddMember(_player
->GetGUID(), _player
->GetName()))
67 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
68 _player
->LeaveLFGChannel();
74 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
)
75 plr
->LeaveLFGChannel();
80 static void AttemptAddMore(Player
* _player
)
82 // skip not group leader case
83 if(_player
->GetGroup() && _player
->GetGroup()->GetLeaderGUID()!=_player
->GetGUID())
86 if(!_player
->m_lookingForGroup
.more
.canAutoJoin())
89 //TODO: Guard Player map
90 HashMapHolder
<Player
>::MapType
const& players
= ObjectAccessor::Instance().GetPlayers();
91 for(HashMapHolder
<Player
>::MapType::const_iterator iter
= players
.begin(); iter
!= players
.end(); ++iter
)
93 Player
*plr
= iter
->second
;
95 // skip enemies and self
96 if(!plr
|| plr
==_player
|| plr
->GetTeam() != _player
->GetTeam())
99 // skip not auto join or in group
100 if(!plr
->GetSession()->LookingForGroup_auto_join
|| plr
->GetGroup() )
103 if(!plr
->m_lookingForGroup
.HaveInSlot(_player
->m_lookingForGroup
.more
))
106 // attempt create group if need, or stop attempts
107 if(!_player
->GetGroup())
109 Group
* group
= new Group
;
110 if(!group
->Create(_player
->GetGUID(), _player
->GetName()))
113 return; // can't create group (??)
116 objmgr
.AddGroup(group
);
119 // stop at join fail (full)
120 if(!_player
->GetGroup()->AddMember(plr
->GetGUID(), plr
->GetName()) )
122 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
123 _player
->LeaveLFGChannel();
129 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && plr
->GetSession()->GetSecurity() == SEC_PLAYER
)
130 plr
->LeaveLFGChannel();
133 if(_player
->GetGroup()->IsFull() )
135 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
136 _player
->LeaveLFGChannel();
143 void WorldSession::HandleLfgSetAutoJoinOpcode( WorldPacket
& /*recv_data*/ )
145 sLog
.outDebug("CMSG_LFG_SET_AUTOJOIN");
146 LookingForGroup_auto_join
= true;
148 if(!_player
) // needed because STATUS_AUTHED
151 AttemptJoin(_player
);
154 void WorldSession::HandleLfgClearAutoJoinOpcode( WorldPacket
& /*recv_data*/ )
156 sLog
.outDebug("CMSG_LFG_CLEAR_AUTOJOIN");
157 LookingForGroup_auto_join
= false;
160 void WorldSession::HandleLfmSetAutoFillOpcode( WorldPacket
& /*recv_data*/ )
162 sLog
.outDebug("CMSG_LFM_SET_AUTOFILL");
163 LookingForGroup_auto_add
= true;
165 if(!_player
) // needed because STATUS_AUTHED
168 AttemptAddMore(_player
);
171 void WorldSession::HandleLfmClearAutoFillOpcode( WorldPacket
& /*recv_data*/ )
173 sLog
.outDebug("CMSG_LFM_CLEAR_AUTOFILL");
174 LookingForGroup_auto_add
= false;
177 void WorldSession::HandleLfgClearOpcode( WorldPacket
& /*recv_data */ )
180 sLog
.outDebug("CMSG_CLEAR_LOOKING_FOR_GROUP");
182 for(int i
= 0; i
< MAX_LOOKING_FOR_GROUP_SLOT
; ++i
)
183 _player
->m_lookingForGroup
.slots
[i
].Clear();
185 if( sWorld
.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL
) && _player
->GetSession()->GetSecurity() == SEC_PLAYER
)
186 _player
->LeaveLFGChannel();
189 void WorldSession::HandleLfmClearOpcode( WorldPacket
& /*recv_data */)
192 sLog
.outDebug("CMSG_CLEAR_LOOKING_FOR_MORE");
194 _player
->m_lookingForGroup
.more
.Clear();
197 void WorldSession::HandleSetLfmOpcode( WorldPacket
& recv_data
)
199 CHECK_PACKET_SIZE(recv_data
,4);
201 sLog
.outDebug("CMSG_SET_LOOKING_FOR_MORE");
202 //recv_data.hexlike();
203 uint32 temp
, entry
, type
;
207 entry
= ( temp
& 0xFFFF);
208 type
= ( (temp
>> 24) & 0xFFFF);
210 _player
->m_lookingForGroup
.more
.Set(entry
,type
);
211 sLog
.outDebug("LFM set: temp %u, zone %u, type %u", temp
, entry
, type
);
213 if(LookingForGroup_auto_add
)
214 AttemptAddMore(_player
);
216 SendLfgResult(type
, entry
, 1);
219 void WorldSession::HandleSetLfgCommentOpcode( WorldPacket
& recv_data
)
221 CHECK_PACKET_SIZE(recv_data
, 1);
223 sLog
.outDebug("CMSG_SET_LFG_COMMENT");
224 //recv_data.hexlike();
227 recv_data
>> comment
;
228 sLog
.outDebug("LFG comment %s", comment
.c_str());
230 _player
->m_lookingForGroup
.comment
= comment
;
233 void WorldSession::HandleLookingForGroup(WorldPacket
& recv_data
)
235 CHECK_PACKET_SIZE(recv_data
, 4+4+4);
237 sLog
.outDebug("MSG_LOOKING_FOR_GROUP");
238 //recv_data.hexlike();
239 uint32 type
, entry
, unk
;
241 recv_data
>> type
>> entry
>> unk
;
242 sLog
.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type
, entry
, unk
);
244 if(LookingForGroup_auto_add
)
245 AttemptAddMore(_player
);
247 if(LookingForGroup_auto_join
)
248 AttemptJoin(_player
);
250 SendLfgResult(type
, entry
, 0);
253 void WorldSession::SendLfgResult(uint32 type
, uint32 entry
, uint8 lfg_type
)
257 // start prepare packet;
258 WorldPacket
data(MSG_LOOKING_FOR_GROUP
);
259 data
<< uint32(type
); // type
260 data
<< uint32(entry
); // entry from LFGDungeons.dbc
261 data
<< uint32(0); // count, placeholder
262 data
<< uint32(0); // count again, strange, placeholder
264 //TODO: Guard Player map
265 HashMapHolder
<Player
>::MapType
const& players
= ObjectAccessor::Instance().GetPlayers();
266 for(HashMapHolder
<Player
>::MapType::const_iterator iter
= players
.begin(); iter
!= players
.end(); ++iter
)
268 Player
*plr
= iter
->second
;
270 if(!plr
|| plr
->GetTeam() != _player
->GetTeam())
273 if(!plr
->m_lookingForGroup
.HaveInSlot(entry
,type
))
278 data
.append(plr
->GetPackGUID()); // packed guid
279 data
<< plr
->getLevel(); // level
280 data
<< plr
->GetZoneId(); // current zone
281 data
<< lfg_type
; // 0x00 - LFG, 0x01 - LFM
283 for(uint8 j
= 0; j
< MAX_LOOKING_FOR_GROUP_SLOT
; ++j
)
285 data
<< uint32( plr
->m_lookingForGroup
.slots
[j
].entry
| (plr
->m_lookingForGroup
.slots
[j
].type
<< 24) );
287 data
<< plr
->m_lookingForGroup
.comment
;
289 Group
*group
= plr
->GetGroup();
292 data
<< group
->GetMembersCount()-1; // count of group members without group leader
293 for(GroupReference
*itr
= group
->GetFirstMember(); itr
!= NULL
; itr
= itr
->next())
295 Player
*member
= itr
->getSource();
296 if(member
&& member
->GetGUID() != plr
->GetGUID())
298 data
.append(member
->GetPackGUID()); // packed guid
299 data
<< member
->getLevel(); // player level
305 data
<< uint32(0x00);
309 // fill count placeholders
310 data
.put
<uint32
>(4+4, number
);
311 data
.put
<uint32
>(4+4+4,number
);
316 void WorldSession::HandleSetLfgOpcode( WorldPacket
& recv_data
)
318 CHECK_PACKET_SIZE(recv_data
,4+4);
320 sLog
.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
321 //recv_data.hexlike();
322 uint32 slot
, temp
, entry
, type
;
324 recv_data
>> slot
>> temp
;
326 entry
= ( temp
& 0xFFFF);
327 type
= ( (temp
>> 24) & 0xFFFF);
329 if(slot
>= MAX_LOOKING_FOR_GROUP_SLOT
)
332 _player
->m_lookingForGroup
.slots
[slot
].Set(entry
,type
);
333 sLog
.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot
, temp
, type
, entry
);
335 if(LookingForGroup_auto_join
)
336 AttemptJoin(_player
);
338 SendLfgResult(type
, entry
, 0);