aboutsummaryrefslogtreecommitdiff
path: root/src/game/LFGHandler.cpp
diff options
context:
space:
mode:
authorNeo2003 <none@none>2008-10-02 16:23:55 -0500
committerNeo2003 <none@none>2008-10-02 16:23:55 -0500
commit9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch)
treeb5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/game/LFGHandler.cpp
[svn] * Proper SVN structureinit
--HG-- branch : trunk
Diffstat (limited to 'src/game/LFGHandler.cpp')
-rw-r--r--src/game/LFGHandler.cpp337
1 files changed, 337 insertions, 0 deletions
diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp
new file mode 100644
index 00000000000..df87b51de89
--- /dev/null
+++ b/src/game/LFGHandler.cpp
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "WorldSession.h"
+#include "Log.h"
+#include "Database/DatabaseEnv.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "ObjectMgr.h"
+#include "World.h"
+
+static void AttemptJoin(Player* _player)
+{
+ // skip not can autojoin cases and player group case
+ if(!_player->m_lookingForGroup.canAutoJoin() || _player->GetGroup())
+ return;
+
+ //TODO: Guard Player Map
+ HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+ {
+ Player *plr = iter->second;
+
+ // skip enemies and self
+ if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
+ continue;
+
+ // skip not auto add, not group leader cases
+ if(!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID())
+ continue;
+
+ // skip non auto-join or empty slots, or non compatible slots
+ if(!plr->m_lookingForGroup.more.canAutoJoin() || !_player->m_lookingForGroup.HaveInSlot(plr->m_lookingForGroup.more))
+ continue;
+
+ // attempt create group, or skip
+ if(!plr->GetGroup())
+ {
+ Group* group = new Group;
+ if(!group->Create(plr->GetGUID(), plr->GetName()))
+ {
+ delete group;
+ continue;
+ }
+
+ objmgr.AddGroup(group);
+ }
+
+ // stop at success join
+ if(plr->GetGroup()->AddMember(_player->GetGUID(), _player->GetName()))
+ {
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
+ _player->LeaveLFGChannel();
+ break;
+ }
+ // full
+ else
+ {
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
+ plr->LeaveLFGChannel();
+ }
+ }
+}
+
+static void AttemptAddMore(Player* _player)
+{
+ // skip not group leader case
+ if(_player->GetGroup() && _player->GetGroup()->GetLeaderGUID()!=_player->GetGUID())
+ return;
+
+ if(!_player->m_lookingForGroup.more.canAutoJoin())
+ return;
+
+ //TODO: Guard Player map
+ HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+ {
+ Player *plr = iter->second;
+
+ // skip enemies and self
+ if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam())
+ continue;
+
+ // skip not auto join or in group
+ if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() )
+ continue;
+
+ if(!plr->m_lookingForGroup.HaveInSlot(_player->m_lookingForGroup.more))
+ continue;
+
+ // attempt create group if need, or stop attempts
+ if(!_player->GetGroup())
+ {
+ Group* group = new Group;
+ if(!group->Create(_player->GetGUID(), _player->GetName()))
+ {
+ delete group;
+ return; // cann't create group (??)
+ }
+
+ objmgr.AddGroup(group);
+ }
+
+ // stop at join fail (full)
+ if(!_player->GetGroup()->AddMember(plr->GetGUID(), plr->GetName()) )
+ {
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
+ _player->LeaveLFGChannel();
+
+ break;
+ }
+
+ // joined
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && plr->GetSession()->GetSecurity() == SEC_PLAYER )
+ plr->LeaveLFGChannel();
+
+ // and group full
+ if(_player->GetGroup()->IsFull() )
+ {
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
+ _player->LeaveLFGChannel();
+
+ break;
+ }
+ }
+}
+
+void WorldSession::HandleLfgAutoJoinOpcode( WorldPacket & /*recv_data*/ )
+{
+ sLog.outDebug("CMSG_SET_LFG_AUTO_JOIN");
+ LookingForGroup_auto_join = true;
+
+ if(!_player) // needed because STATUS_AUTHED
+ return;
+
+ AttemptJoin(_player);
+}
+
+void WorldSession::HandleLfgCancelAutoJoinOpcode( WorldPacket & /*recv_data*/ )
+{
+ sLog.outDebug("CMSG_UNSET_LFG_AUTO_JOIN");
+ LookingForGroup_auto_join = false;
+}
+
+void WorldSession::HandleLfmAutoAddMembersOpcode( WorldPacket & /*recv_data*/ )
+{
+ sLog.outDebug("CMSG_SET_LFM_AUTOADD");
+ LookingForGroup_auto_add = true;
+
+ if(!_player) // needed because STATUS_AUTHED
+ return;
+
+ AttemptAddMore(_player);
+}
+
+void WorldSession::HandleLfmCancelAutoAddmembersOpcode( WorldPacket & /*recv_data*/ )
+{
+ sLog.outDebug("CMSG_UNSET_LFM_AUTOADD");
+ LookingForGroup_auto_add = false;
+}
+
+void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ )
+{
+ sLog.outDebug("CMSG_LOOKING_FOR_GROUP_CLEAR");
+
+ for(int i = 0; i < MAX_LOOKING_FOR_GROUP_SLOT; ++i)
+ _player->m_lookingForGroup.slots[i].Clear();
+
+ if( sWorld.getConfig(CONFIG_RESTRICTED_LFG_CHANNEL) && _player->GetSession()->GetSecurity() == SEC_PLAYER )
+ _player->LeaveLFGChannel();
+}
+
+void WorldSession::HandleLfmSetNoneOpcode( WorldPacket & /*recv_data */)
+{
+ sLog.outDebug("CMSG_SET_LOOKING_FOR_NONE");
+
+ _player->m_lookingForGroup.more.Clear();
+}
+
+void WorldSession::HandleLfmSetOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data,4);
+
+ sLog.outDebug("CMSG_SET_LOOKING_FOR_MORE");
+ //recv_data.hexlike();
+ uint32 temp, entry, type;
+
+ recv_data >> temp;
+
+ entry = ( temp & 0xFFFF);
+ type = ( (temp >> 24) & 0xFFFF);
+
+ _player->m_lookingForGroup.more.Set(entry,type);
+ sLog.outDebug("LFM set: temp %u, zone %u, type %u", temp, entry, type);
+
+ if(LookingForGroup_auto_add)
+ AttemptAddMore(_player);
+
+ SendLfgResult(type, entry, 1);
+}
+
+void WorldSession::HandleLfgSetCommentOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data,1);
+
+ sLog.outDebug("CMSG_SET_COMMENTARY");
+ //recv_data.hexlike();
+
+ std::string comment;
+ recv_data >> comment;
+ sLog.outDebug("LFG comment %s", comment.c_str());
+
+ _player->m_lookingForGroup.comment = comment;
+}
+
+void WorldSession::HandleLookingForGroup(WorldPacket& recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data,4+4+4);
+
+ sLog.outDebug("MSG_LOOKING_FOR_GROUP");
+ //recv_data.hexlike();
+ uint32 type, entry, unk;
+
+ recv_data >> type >> entry >> unk;
+ sLog.outDebug("MSG_LOOKING_FOR_GROUP: type %u, entry %u, unk %u", type, entry, unk);
+
+ if(LookingForGroup_auto_add)
+ AttemptAddMore(_player);
+
+ if(LookingForGroup_auto_join)
+ AttemptJoin(_player);
+
+ SendLfgResult(type, entry, 0);
+}
+
+void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type)
+{
+ uint32 number = 0;
+
+ // start preper packet;
+ WorldPacket data(MSG_LOOKING_FOR_GROUP);
+ data << uint32(type); // type
+ data << uint32(entry); // entry from LFGDungeons.dbc
+ data << uint32(0); // count, placeholder
+ data << uint32(0); // count again, strange, placeholder
+
+ //TODO: Guard Player map
+ HashMapHolder<Player>::MapType const& players = ObjectAccessor::Instance().GetPlayers();
+ for(HashMapHolder<Player>::MapType::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+ {
+ Player *plr = iter->second;
+
+ if(!plr || plr->GetTeam() != _player->GetTeam())
+ continue;
+
+ if(!plr->m_lookingForGroup.HaveInSlot(entry,type))
+ continue;
+
+ ++number;
+
+ data.append(plr->GetPackGUID()); // packed guid
+ data << plr->getLevel(); // level
+ data << plr->GetZoneId(); // current zone
+ data << lfg_type; // 0x00 - LFG, 0x01 - LFM
+
+ for(uint8 j = 0; j < MAX_LOOKING_FOR_GROUP_SLOT; ++j)
+ {
+ data << uint32( plr->m_lookingForGroup.slots[j].entry | (plr->m_lookingForGroup.slots[j].type << 24) );
+ }
+ data << plr->m_lookingForGroup.comment;
+
+ Group *group = plr->GetGroup();
+ if(group)
+ {
+ data << group->GetMembersCount()-1; // count of group members without group leader
+ for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player *member = itr->getSource();
+ if(member && member->GetGUID() != plr->GetGUID())
+ {
+ data.append(member->GetPackGUID()); // packed guid
+ data << member->getLevel(); // player level
+ }
+ }
+ }
+ else
+ {
+ data << uint32(0x00);
+ }
+ }
+
+ // fill count placeholders
+ data.put<uint32>(4+4, number);
+ data.put<uint32>(4+4+4,number);
+
+ SendPacket(&data);
+}
+
+void WorldSession::HandleSetLfgOpcode( WorldPacket & recv_data )
+{
+ CHECK_PACKET_SIZE(recv_data,4+4);
+
+ sLog.outDebug("CMSG_SET_LOOKING_FOR_GROUP");
+ //recv_data.hexlike();
+ uint32 slot, temp, entry, type;
+
+ recv_data >> slot >> temp;
+
+ entry = ( temp & 0xFFFF);
+ type = ( (temp >> 24) & 0xFFFF);
+
+ if(slot >= MAX_LOOKING_FOR_GROUP_SLOT)
+ return;
+
+ _player->m_lookingForGroup.slots[slot].Set(entry,type);
+ sLog.outDebug("LFG set: looknumber %u, temp %X, type %u, entry %u", slot, temp, type, entry);
+
+ if(LookingForGroup_auto_join)
+ AttemptJoin(_player);
+
+ SendLfgResult(type, entry, 0);
+}