root/trunk/src/game/LFGHandler.cpp @ 18

Revision 2, 10.5 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "WorldSession.h"
20#include "Log.h"
21#include "Database/DatabaseEnv.h"
22#include "Player.h"
23#include "WorldPacket.h"
24#include "ObjectMgr.h"
25#include "World.h"
26
27static void AttemptJoin(Player* _player)
28{
29    // skip not can autojoin cases and player group case
30    if(!_player->m_lookingForGroup.canAutoJoin() || _player->GetGroup())
31        return;
32
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)
36    {
37        Player *plr = iter->second;
38
39        // skip enemies and self
40        if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
41            continue;
42
43        // skip not auto add, not group leader cases
44        if(!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID())
45            continue;
46
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))
49            continue;
50
51        // attempt create group, or skip
52        if(!plr->GetGroup())
53        {
54            Group* group = new Group;
55            if(!group->Create(plr->GetGUID(), plr->GetName()))
56            {
57                delete group;
58                continue;
59            }
60
61            objmgr.AddGroup(group);
62        }
63
64        // stop at success join
65        if(plr->GetGroup()->AddMember(_player->GetGUID(), _player->GetName()))
66        {
67            if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
68                _player->LeaveLFGChannel();
69            break;
70        }
71        // full
72        else
73        {
74            if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
75                plr->LeaveLFGChannel();
76        }
77    }
78}
79
80static void AttemptAddMore(Player* _player)
81{
82    // skip not group leader case
83    if(_player->GetGroup() && _player->GetGroup()->GetLeaderGUID()!=_player->GetGUID())
84        return;
85
86    if(!_player->m_lookingForGroup.more.canAutoJoin())
87        return;
88
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)
92    {
93        Player *plr = iter->second;
94
95        // skip enemies and self
96        if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
97            continue;
98
99        // skip not auto join or in group
100        if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() )
101            continue;
102
103        if(!plr->m_lookingForGroup.HaveInSlot(_player->m_lookingForGroup.more))
104            continue;
105
106        // attempt create group if need, or stop attempts
107        if(!_player->GetGroup())
108        {
109            Group* group = new Group;
110            if(!group->Create(_player->GetGUID(), _player->GetName()))
111            {
112                delete group;
113                return;                                     // cann't create group (??)
114            }
115
116            objmgr.AddGroup(group);
117        }
118
119        // stop at join fail (full)
120        if(!_player->GetGroup()->AddMember(plr->GetGUID(), plr->GetName()) )
121        {
122            if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
123                _player->LeaveLFGChannel();
124
125            break;
126        }
127
128        // joined
129        if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
130            plr->LeaveLFGChannel();
131
132        // and group full
133        if(_player->GetGroup()->IsFull() )
134        {
135            if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
136                _player->LeaveLFGChannel();
137
138            break;
139        }
140    }
141}
142
143void WorldSession::HandleLfgAutoJoinOpcode( WorldPacket & /*recv_data*/ )
144{
145    sLog.outDebug("CMSG_SET_LFG_AUTO_JOIN");
146    LookingForGroup_auto_join = true;
147
148    if(!_player)                                            // needed because STATUS_AUTHED
149        return;
150
151    AttemptJoin(_player);
152}
153
154void WorldSession::HandleLfgCancelAutoJoinOpcode( WorldPacket & /*recv_data*/ )
155{
156    sLog.outDebug("CMSG_UNSET_LFG_AUTO_JOIN");
157    LookingForGroup_auto_join = false;
158}
159
160void WorldSession::HandleLfmAutoAddMembersOpcode( WorldPacket & /*recv_data*/ )
161{
162    sLog.outDebug("CMSG_SET_LFM_AUTOADD");
163    LookingForGroup_auto_add = true;
164
165    if(!_player)                                            // needed because STATUS_AUTHED
166        return;
167
168    AttemptAddMore(_player);
169}
170
171void WorldSession::HandleLfmCancelAutoAddmembersOpcode( WorldPacket & /*recv_data*/ )
172{
173    sLog.outDebug("CMSG_UNSET_LFM_AUTOADD");
174    LookingForGroup_auto_add = false;
175}
176
177void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ )
178{
179    sLog.outDebug("CMSG_LOOKING_FOR_GROUP_CLEAR");
180
181    for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
182        _player->m_lookingForGroup.slots[i].Clear();
183
184    if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
185        _player->LeaveLFGChannel();
186}
187
188void WorldSession::HandleLfmSetNoneOpcode( WorldPacket & /*recv_data */)
189{
190    sLog.outDebug("CMSG_SET_LOOKING_FOR_NONE");
191
192    _player->m_lookingForGroup.more.Clear();
193}
194
195void WorldSession::HandleLfmSetOpcode( WorldPacket & recv_data )
196{
197    CHECK_PACKET_SIZE(recv_data,4);
198
199    sLog.outDebug("CMSG_SET_LOOKING_FOR_MORE");
200    //recv_data.hexlike();
201    uint32 temp, entry, type;
202
203    recv_data >> temp;
204
205    entry = ( temp & 0xFFFF);
206    type = ( (temp >> 24) & 0xFFFF);
207
208    _player->m_lookingForGroup.more.Set(entry,type);
209    sLog.outDebug("LFM set: temp %u, zone %u, type %u", temp, entry, type);
210
211    if(LookingForGroup_auto_add)
212        AttemptAddMore(_player);
213
214    SendLfgResult(type, entry, 1);
215}
216
217void WorldSession::HandleLfgSetCommentOpcode( WorldPacket & recv_data )
218{
219    CHECK_PACKET_SIZE(recv_data,1);
220
221    sLog.outDebug("CMSG_SET_COMMENTARY");
222    //recv_data.hexlike();
223
224    std::string comment;
225    recv_data >> comment;
226    sLog.outDebug("LFG comment %s", comment.c_str());
227
228    _player->m_lookingForGroup.comment = comment;
229}
230
231void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
232{
233    CHECK_PACKET_SIZE(recv_data,4+4+4);
234
235    sLog.outDebug("MSG_LOOKING_FOR_GROUP");
236    //recv_data.hexlike();
237    uint32 type, entry, unk;
238
239    recv_data >> type >> entry >> unk;
240    sLog.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type, entry, unk);
241
242    if(LookingForGroup_auto_add)
243        AttemptAddMore(_player);
244
245    if(LookingForGroup_auto_join)
246        AttemptJoin(_player);
247
248    SendLfgResult(type, entry, 0);
249}
250
251void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
252{
253    uint32 number = 0;
254
255    // start preper packet;
256    WorldPacket data(MSG_LOOKING_FOR_GROUP);
257    data << uint32(type);                                   // type
258    data << uint32(entry);                                  // entry from LFGDungeons.dbc
259    data << uint32(0);                                      // count, placeholder
260    data << uint32(0);                                      // count again, strange, placeholder
261
262    //TODO: Guard Player map
263    HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
264    for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
265    {
266        Player *plr = iter->second;
267
268        if(!plr || plr->GetTeam() != _player->GetTeam())
269            continue;
270
271        if(!plr->m_lookingForGroup.HaveInSlot(entry,type))
272            continue;
273
274        ++number;
275
276        data.append(plr->GetPackGUID());                    // packed guid
277        data << plr->getLevel();                            // level
278        data << plr->GetZoneId();                           // current zone
279        data << lfg_type;                                   // 0x00 - LFG, 0x01 - LFM
280
281        for(uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j)
282        {
283            data << uint32( plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24) );
284        }
285        data << plr->m_lookingForGroup.comment;
286
287        Group *group = plr->GetGroup();
288        if(group)
289        {
290            data << group->GetMembersCount()-1;             // count of group members without group leader
291            for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
292            {
293                Player *member = itr->getSource();
294                if(member && member->GetGUID() != plr->GetGUID())
295                {
296                    data.append(member->GetPackGUID());     // packed guid
297                    data << member->getLevel();             // player level
298                }
299            }
300        }
301        else
302        {
303            data << uint32(0x00);
304        }
305    }
306
307    // fill count placeholders
308    data.put<uint32>(4+4,  number);
309    data.put<uint32>(4+4+4,number);
310
311    SendPacket(&data);
312}
313
314void WorldSession::HandleSetLfgOpcode( WorldPacket & recv_data )
315{
316    CHECK_PACKET_SIZE(recv_data,4+4);
317
318    sLog.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
319    //recv_data.hexlike();
320    uint32 slot, temp, entry, type;
321
322    recv_data >> slot >> temp;
323
324    entry = ( temp & 0xFFFF);
325    type = ( (temp >> 24) & 0xFFFF);
326
327    if(slot >= MAX_LOOKING_FOR_GROUP_SLOT)
328        return;
329
330    _player->m_lookingForGroup.slots[slot].Set(entry,type);
331    sLog.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, temp, type, entry);
332
333    if(LookingForGroup_auto_join)
334        AttemptJoin(_player);
335
336    SendLfgResult(type, entry, 0);
337}
Note: See TracBrowser for help on using the browser.