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

Revision 229, 10.6 kB (checked in by yumileroy, 17 years ago)

[svn] *** Source: MaNGOS ***
* Fixed build extractor at Windows Vista. Author: Vladimir
* Fixed comment text and code indentifiers spelling. Author: Vladimir & Paradox.
* Access cached member lists in guild handlers instead of querying the DB. Author: Hunuza
* Small fixes in send/received packet and simple code cleanup also. Author: Vladimir
* Not output error at loading empty character_ticket table. Author: Vladimir
* Not reset display model at shapeshift aura remove if it not set at apply. Author: Arthorius
* Applied props to few files.

Original author: visagalis
Date: 2008-11-14 16:28:45-06:00

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