TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
lfg::LFGQueue Class Reference

#include <LFGQueue.h>

Public Member Functions

std::string GetDetailedMatchRoles (GuidList const &check) const
 
void AddToQueue (ObjectGuid guid)
 
void RemoveFromQueue (ObjectGuid guid)
 
void AddQueueData (ObjectGuid guid, time_t joinTime, LfgDungeonSet const &dungeons, LfgRolesMap const &rolesMap)
 
void RemoveQueueData (ObjectGuid guid)
 
void UpdateWaitTimeAvg (int32 waitTime, uint32 dungeonId)
 
void UpdateWaitTimeTank (int32 waitTime, uint32 dungeonId)
 
void UpdateWaitTimeHealer (int32 waitTime, uint32 dungeonId)
 
void UpdateWaitTimeDps (int32 waitTime, uint32 dungeonId)
 
void UpdateQueueTimers (uint8 queueId, time_t currTime)
 
time_t GetJoinTime (ObjectGuid guid) const
 
uint8 FindGroups ()
 
std::string DumpQueueInfo () const
 
std::string DumpCompatibleInfo (bool full=false) const
 

Private Member Functions

void SetQueueUpdateData (std::string const &strGuids, LfgRolesMap const &proposalRoles)
 
void AddToNewQueue (ObjectGuid guid)
 
void AddToCurrentQueue (ObjectGuid guid)
 
void RemoveFromNewQueue (ObjectGuid guid)
 
void RemoveFromCurrentQueue (ObjectGuid guid)
 
void SetCompatibles (std::string const &key, LfgCompatibility compatibles)
 
LfgCompatibility GetCompatibles (std::string const &key)
 
void RemoveFromCompatibles (ObjectGuid guid)
 
void SetCompatibilityData (std::string const &key, LfgCompatibilityData const &compatibles)
 
LfgCompatibilityDataGetCompatibilityData (std::string const &key)
 
void FindBestCompatibleInQueue (LfgQueueDataContainer::iterator itrQueue)
 
void UpdateBestCompatibleInQueue (LfgQueueDataContainer::iterator itrQueue, std::string const &key, LfgRolesMap const &roles)
 
LfgCompatibility FindNewGroups (GuidList &check, GuidList &all)
 
LfgCompatibility CheckCompatibility (GuidList check)
 

Private Attributes

LfgQueueDataContainer QueueDataStore
 Queued groups. More...
 
LfgCompatibleContainer CompatibleMapStore
 Compatible dungeons. More...
 
LfgWaitTimesContainer waitTimesAvgStore
 Average wait time to find a group queuing as multiple roles. More...
 
LfgWaitTimesContainer waitTimesTankStore
 Average wait time to find a group queuing as tank. More...
 
LfgWaitTimesContainer waitTimesHealerStore
 Average wait time to find a group queuing as healer. More...
 
LfgWaitTimesContainer waitTimesDpsStore
 Average wait time to find a group queuing as dps. More...
 
GuidList currentQueueStore
 Ordered list. Used to find groups. More...
 
GuidList newToQueueStore
 New groups to add to queue. More...
 

Detailed Description

Stores all data related to queue

Member Function Documentation

void lfg::LFGQueue::AddQueueData ( ObjectGuid  guid,
time_t  joinTime,
LfgDungeonSet const dungeons,
LfgRolesMap const rolesMap 
)
180 {
181  QueueDataStore[guid] = LfgQueueData(joinTime, dungeons, rolesMap);
182  AddToQueue(guid);
183 }
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
void AddToQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:120

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void lfg::LFGQueue::AddToCurrentQueue ( ObjectGuid  guid)
private
170 {
171  currentQueueStore.push_back(guid);
172 }
GuidList currentQueueStore
Ordered list. Used to find groups.
Definition: LFGQueue.h:142

+ Here is the caller graph for this function:

void lfg::LFGQueue::AddToNewQueue ( ObjectGuid  guid)
private
160 {
161  newToQueueStore.push_back(guid);
162 }
GuidList newToQueueStore
New groups to add to queue.
Definition: LFGQueue.h:143

+ Here is the caller graph for this function:

void lfg::LFGQueue::AddToQueue ( ObjectGuid  guid)
121 {
122  LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid);
123  if (itQueue == QueueDataStore.end())
124  {
125  TC_LOG_ERROR("lfg.queue.add", "Queue data not found for [%s]", guid.ToString().c_str());
126  return;
127  }
128 
129  AddToNewQueue(guid);
130 }
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
void AddToNewQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:159
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

LfgCompatibility lfg::LFGQueue::CheckCompatibility ( GuidList  check)
private

Check compatibilities between groups. If group is Matched proposal will be created

Parameters
[in]checkList of guids to check compatibilities
Returns
LfgCompatibility type of compatibility
352 {
353  std::string strGuids = ConcatenateGuids(check);
354  LfgProposal proposal;
355  LfgDungeonSet proposalDungeons;
356  LfgGroupsMap proposalGroups;
357  LfgRolesMap proposalRoles;
358 
359  // Check for correct size
360  if (check.size() > MAX_GROUP_SIZE || check.empty())
361  {
362  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s): Size wrong - Not compatibles", GetDetailedMatchRoles(check).c_str());
364  }
365 
366  // Check all-but-new compatiblitity
367  if (check.size() > 2)
368  {
369  ObjectGuid frontGuid = check.front();
370  check.pop_front();
371 
372  // Check all-but-new compatibilities (New, A, B, C, D) --> check(A, B, C, D)
373  LfgCompatibility child_compatibles = CheckCompatibility(check);
374  if (child_compatibles < LFG_COMPATIBLES_WITH_LESS_PLAYERS) // Group not compatible
375  {
376  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) child %s not compatibles", strGuids.c_str(), GetDetailedMatchRoles(check).c_str());
377  SetCompatibles(strGuids, child_compatibles);
378  return child_compatibles;
379  }
380  check.push_front(frontGuid);
381  }
382 
383  // Check if more than one LFG group and number of players joining
384  uint8 numPlayers = 0;
385  uint8 numLfgGroups = 0;
386  for (GuidList::const_iterator it = check.begin(); it != check.end() && numLfgGroups < 2 && numPlayers <= MAX_GROUP_SIZE; ++it)
387  {
388  ObjectGuid guid = *it;
389  LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(guid);
390  if (itQueue == QueueDataStore.end())
391  {
392  TC_LOG_ERROR("lfg.queue.match.compatibility.check", "Guid: [%s] is not queued but listed as queued!", guid.ToString().c_str());
393  RemoveFromQueue(guid);
395  }
396 
397  // Store group so we don't need to call Mgr to get it later (if it's player group will be 0 otherwise would have joined as group)
398  for (LfgRolesMap::const_iterator it2 = itQueue->second.roles.begin(); it2 != itQueue->second.roles.end(); ++it2)
399  proposalGroups[it2->first] = itQueue->first.IsParty() ? itQueue->first : ObjectGuid::Empty;
400 
401  numPlayers += itQueue->second.roles.size();
402 
403  if (sLFGMgr->IsLfgGroup(guid))
404  {
405  if (!numLfgGroups)
406  proposal.group = guid;
407  ++numLfgGroups;
408  }
409  }
410 
411  // Group with less that MAX_GROUP_SIZE members always compatible
412  if (check.size() == 1 && numPlayers != MAX_GROUP_SIZE)
413  {
414  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) single group. Compatibles", GetDetailedMatchRoles(check).c_str());
415  LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(check.front());
416 
417  LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
418  data.roles = itQueue->second.roles;
419  LFGMgr::CheckGroupRoles(data.roles);
420 
421  UpdateBestCompatibleInQueue(itQueue, strGuids, data.roles);
422  SetCompatibilityData(strGuids, data);
424  }
425 
426  if (numLfgGroups > 1)
427  {
428  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) More than one Lfggroup (%u)", GetDetailedMatchRoles(check).c_str(), numLfgGroups);
431  }
432 
433  if (numPlayers > MAX_GROUP_SIZE)
434  {
435  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too many players (%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
438  }
439 
440  // If it's single group no need to check for duplicate players, ignores, bad roles or bad dungeons as it's been checked before joining
441  if (check.size() > 1)
442  {
443  for (GuidList::const_iterator it = check.begin(); it != check.end(); ++it)
444  {
445  LfgRolesMap const& roles = QueueDataStore[(*it)].roles;
446  for (LfgRolesMap::const_iterator itRoles = roles.begin(); itRoles != roles.end(); ++itRoles)
447  {
448  LfgRolesMap::const_iterator itPlayer;
449  for (itPlayer = proposalRoles.begin(); itPlayer != proposalRoles.end(); ++itPlayer)
450  {
451  if (itRoles->first == itPlayer->first)
452  TC_LOG_ERROR("lfg.queue.match.compatibility.check", "Guids: ERROR! Player multiple times in queue! [%s]", itRoles->first.ToString().c_str());
453  else if (sLFGMgr->HasIgnore(itRoles->first, itPlayer->first))
454  break;
455  }
456  if (itPlayer == proposalRoles.end())
457  proposalRoles[itRoles->first] = itRoles->second;
458  }
459  }
460 
461  if (uint8 playersize = numPlayers - proposalRoles.size())
462  {
463  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) not compatible, %u players are ignoring each other", GetDetailedMatchRoles(check).c_str(), playersize);
466  }
467 
468  LfgRolesMap debugRoles = proposalRoles;
469  if (!LFGMgr::CheckGroupRoles(proposalRoles))
470  {
471  std::ostringstream o;
472  for (LfgRolesMap::const_iterator it = debugRoles.begin(); it != debugRoles.end(); ++it)
473  o << ", " << it->first << ": " << GetRolesString(it->second);
474 
475  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Roles not compatible%s", GetDetailedMatchRoles(check).c_str(), o.str().c_str());
478  }
479 
480  GuidList::iterator itguid = check.begin();
481  proposalDungeons = QueueDataStore[*itguid].dungeons;
482  std::ostringstream o;
483  o << ", " << *itguid << ": (" << ConcatenateDungeons(proposalDungeons) << ")";
484  for (++itguid; itguid != check.end(); ++itguid)
485  {
486  LfgDungeonSet temporal;
487  LfgDungeonSet& dungeons = QueueDataStore[*itguid].dungeons;
488  o << ", " << *itguid << ": (" << ConcatenateDungeons(dungeons) << ")";
489  std::set_intersection(proposalDungeons.begin(), proposalDungeons.end(), dungeons.begin(), dungeons.end(), std::inserter(temporal, temporal.begin()));
490  proposalDungeons = temporal;
491  }
492 
493  if (proposalDungeons.empty())
494  {
495  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) No compatible dungeons%s", GetDetailedMatchRoles(check).c_str(), o.str().c_str());
498  }
499  }
500  else
501  {
502  ObjectGuid gguid = *check.begin();
503  const LfgQueueData &queue = QueueDataStore[gguid];
504  proposalDungeons = queue.dungeons;
505  proposalRoles = queue.roles;
506  LFGMgr::CheckGroupRoles(proposalRoles); // assing new roles
507  }
508 
509  // Enough players?
510  if (numPlayers != MAX_GROUP_SIZE)
511  {
512  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Compatibles but not enough players(%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
513  LfgCompatibilityData data(LFG_COMPATIBLES_WITH_LESS_PLAYERS);
514  data.roles = proposalRoles;
515 
516  for (GuidList::const_iterator itr = check.begin(); itr != check.end(); ++itr)
517  UpdateBestCompatibleInQueue(QueueDataStore.find(*itr), strGuids, data.roles);
518 
519  SetCompatibilityData(strGuids, data);
521  }
522 
523  ObjectGuid gguid = *check.begin();
524  proposal.queues = check;
525  proposal.isNew = numLfgGroups != 1 || sLFGMgr->GetOldState(gguid) != LFG_STATE_DUNGEON;
526 
527  if (!sLFGMgr->AllQueued(check))
528  {
529  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Group MATCH but can't create proposal!", GetDetailedMatchRoles(check).c_str());
532  }
533 
534  // Create a new proposal
535  proposal.cancelTime = time(NULL) + LFG_TIME_PROPOSAL;
536  proposal.state = LFG_PROPOSAL_INITIATING;
537  proposal.leader.Clear();
538  proposal.dungeonId = Trinity::Containers::SelectRandomContainerElement(proposalDungeons);
539 
540  bool leader = false;
541  for (LfgRolesMap::const_iterator itRoles = proposalRoles.begin(); itRoles != proposalRoles.end(); ++itRoles)
542  {
543  // Assing new leader
544  if (itRoles->second & PLAYER_ROLE_LEADER)
545  {
546  if (!leader || !proposal.leader || urand(0, 1))
547  proposal.leader = itRoles->first;
548  leader = true;
549  }
550  else if (!leader && (!proposal.leader || urand(0, 1)))
551  proposal.leader = itRoles->first;
552 
553  // Assing player data and roles
554  LfgProposalPlayer &data = proposal.players[itRoles->first];
555  data.role = itRoles->second;
556  data.group = proposalGroups.find(itRoles->first)->second;
557  if (!proposal.isNew && !data.group.IsEmpty() && data.group == proposal.group) // Player from existing group, autoaccept
558  data.accept = LFG_ANSWER_AGREE;
559  }
560 
561  // Mark proposal members as not queued (but not remove queue data)
562  for (GuidList::const_iterator itQueue = proposal.queues.begin(); itQueue != proposal.queues.end(); ++itQueue)
563  {
564  ObjectGuid guid = (*itQueue);
565  RemoveFromNewQueue(guid);
567  }
568 
569  sLFGMgr->AddProposal(proposal);
570 
571  TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) MATCH! Group formed", GetDetailedMatchRoles(check).c_str());
573  return LFG_COMPATIBLES_MATCH;
574 }
LfgCompatibility
Definition: LFGQueue.h:26
static bool CheckGroupRoles(LfgRolesMap &groles)
Checks if given roles match, modifies given roles map with new roles.
Definition: LFGMgr.cpp:814
Definition: LFGQueue.h:34
static ObjectGuid const Empty
Definition: ObjectGuid.h:196
Definition: LFG.h:37
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
C::value_type const & SelectRandomContainerElement(C const &container)
Definition: Containers.h:68
std::string ConcatenateDungeons(LfgDungeonSet const &dungeons)
Definition: LFG.cpp:25
void RemoveFromQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:132
std::map< ObjectGuid, ObjectGuid > LfgGroupsMap
Definition: LFG.h:116
Definition: LFGQueue.h:36
arena_t NULL
Definition: jemalloc_internal.h:624
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: LFG.h:72
std::string GetDetailedMatchRoles(GuidList const &check) const
Definition: LFGQueue.cpp:83
Definition: LFGMgr.h:45
#define MAX_GROUP_SIZE
Definition: Group.h:42
void UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue, std::string const &key, LfgRolesMap const &roles)
Definition: LFGQueue.cpp:703
void RemoveFromCurrentQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:174
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:45
#define sLFGMgr
Definition: LFGMgr.h:481
std::set< uint32 > LfgDungeonSet
Definition: LFG.h:112
std::map< ObjectGuid, uint8 > LfgRolesMap
Definition: LFG.h:115
std::string GetRolesString(uint8 roles)
Definition: LFG.cpp:40
Definition: LFGQueue.h:37
void RemoveFromNewQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:164
Definition: LFG.h:99
void SetCompatibilityData(std::string const &key, LfgCompatibilityData const &compatibles)
Definition: LFGQueue.cpp:252
Definition: LFGQueue.h:33
Definition: LFGQueue.h:32
uint8_t uint8
Definition: Define.h:152
std::string ConcatenateGuids(GuidList const &check)
Definition: LFGQueue.cpp:36
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
Definition: ObjectGuid.h:189
void SetCompatibles(std::string const &key, LfgCompatibility compatibles)
Definition: LFGQueue.cpp:246
T check(T value)
Definition: format.h:305
Definition: LFGQueue.h:28
Definition: LFGMgr.h:74
LfgCompatibility CheckCompatibility(GuidList check)
Definition: LFGQueue.cpp:351
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

std::string lfg::LFGQueue::DumpCompatibleInfo ( bool  full = false) const
662 {
663  std::ostringstream o;
664  o << "Compatible Map size: " << CompatibleMapStore.size() << "\n";
665  if (full)
666  for (LfgCompatibleContainer::const_iterator itr = CompatibleMapStore.begin(); itr != CompatibleMapStore.end(); ++itr)
667  {
668  o << "(" << itr->first << "): " << GetCompatibleString(itr->second.compatibility);
669  if (!itr->second.roles.empty())
670  {
671  o << " (";
672  bool first = true;
673  for (const auto& role : itr->second.roles)
674  {
675  if (!first)
676  o << "|";
677  o << role.first.ToString() << " " << GetRolesString(role.second & uint8(~PLAYER_ROLE_LEADER));
678  first = false;
679  }
680  o << ")";
681  }
682  o << "\n";
683  }
684 
685  return o.str();
686 }
Definition: LFG.h:37
char const * GetCompatibleString(LfgCompatibility compatibles)
Definition: LFGQueue.cpp:54
std::string GetRolesString(uint8 roles)
Definition: LFG.cpp:40
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136
uint8_t uint8
Definition: Define.h:152

+ Here is the call graph for this function:

std::string lfg::LFGQueue::DumpQueueInfo ( ) const
636 {
637  uint32 players = 0;
638  uint32 groups = 0;
639  uint32 playersInGroup = 0;
640 
641  for (uint8 i = 0; i < 2; ++i)
642  {
643  GuidList const& queue = i ? newToQueueStore : currentQueueStore;
644  for (GuidList::const_iterator it = queue.begin(); it != queue.end(); ++it)
645  {
646  ObjectGuid guid = *it;
647  if (guid.IsParty())
648  {
649  groups++;
650  playersInGroup += sLFGMgr->GetPlayerCount(guid);
651  }
652  else
653  players++;
654  }
655  }
656  std::ostringstream o;
657  o << "Queued Players: " << players << " (in group: " << playersInGroup << ") Groups: " << groups << "\n";
658  return o.str();
659 }
GuidList newToQueueStore
New groups to add to queue.
Definition: LFGQueue.h:143
GuidList currentQueueStore
Ordered list. Used to find groups.
Definition: LFGQueue.h:142
std::list< ObjectGuid > GuidList
Definition: ObjectGuid.h:333
#define sLFGMgr
Definition: LFGMgr.h:481
uint32_t uint32
Definition: Define.h:150
uint8_t uint8
Definition: Define.h:152
Definition: ObjectGuid.h:189
bool IsParty() const
Definition: ObjectGuid.h:258

+ Here is the call graph for this function:

void lfg::LFGQueue::FindBestCompatibleInQueue ( LfgQueueDataContainer::iterator  itrQueue)
private
689 {
690  TC_LOG_DEBUG("lfg.queue.compatibles.find", "%s", itrQueue->first.ToString().c_str());
691  std::ostringstream o;
692  o << itrQueue->first;
693  std::string sguid = o.str();
694 
695  for (LfgCompatibleContainer::const_iterator itr = CompatibleMapStore.begin(); itr != CompatibleMapStore.end(); ++itr)
696  if (itr->second.compatibility == LFG_COMPATIBLES_WITH_LESS_PLAYERS &&
697  std::string::npos != itr->first.find(sguid))
698  {
699  UpdateBestCompatibleInQueue(itrQueue, itr->first, itr->second.roles);
700  }
701 }
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
void UpdateBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue, std::string const &key, LfgRolesMap const &roles)
Definition: LFGQueue.cpp:703
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint8 lfg::LFGQueue::FindGroups ( )
282 {
283  uint8 proposals = 0;
284  GuidList firstNew;
285  while (!newToQueueStore.empty())
286  {
287  ObjectGuid frontguid = newToQueueStore.front();
288  TC_LOG_DEBUG("lfg.queue.match.check.new", "Checking [%s] newToQueue(%u), currentQueue(%u)", frontguid.ToString().c_str(),
290 
291  firstNew.clear();
292  firstNew.push_back(frontguid);
293  RemoveFromNewQueue(frontguid);
294 
295  GuidList temporalList = currentQueueStore;
296  LfgCompatibility compatibles = FindNewGroups(firstNew, temporalList);
297 
298  if (compatibles == LFG_COMPATIBLES_MATCH)
299  ++proposals;
300  else
301  AddToCurrentQueue(frontguid); // Lfg group not found, add this group to the queue.
302  }
303  return proposals;
304 }
LfgCompatibility
Definition: LFGQueue.h:26
LfgCompatibility FindNewGroups(GuidList &check, GuidList &all)
Definition: LFGQueue.cpp:313
GuidList newToQueueStore
New groups to add to queue.
Definition: LFGQueue.h:143
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
GuidList currentQueueStore
Ordered list. Used to find groups.
Definition: LFGQueue.h:142
std::list< ObjectGuid > GuidList
Definition: ObjectGuid.h:333
void AddToCurrentQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:169
Definition: LFGQueue.h:37
void RemoveFromNewQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:164
uint8_t uint8
Definition: Define.h:152
Definition: ObjectGuid.h:189
uint32_t uint32
Definition: g3dmath.h:168
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

LfgCompatibility lfg::LFGQueue::FindNewGroups ( GuidList check,
GuidList all 
)
private

Checks que main queue to try to form a Lfg group. Returns first match found (if any)

Parameters
[in]checkList of guids trying to match with other groups
[in]allList of all other guids in main queue to match against
Returns
LfgCompatibility type of compatibility between groups
314 {
315  std::string strGuids = ConcatenateGuids(check);
316  LfgCompatibility compatibles = GetCompatibles(strGuids);
317 
318  TC_LOG_DEBUG("lfg.queue.match.check", "Guids: (%s): %s - all(%s)", GetDetailedMatchRoles(check).c_str(), GetCompatibleString(compatibles), GetDetailedMatchRoles(all).c_str());
319  if (compatibles == LFG_COMPATIBILITY_PENDING) // Not previously cached, calculate
320  compatibles = CheckCompatibility(check);
321 
322  if (compatibles == LFG_COMPATIBLES_BAD_STATES && sLFGMgr->AllQueued(check))
323  {
324  TC_LOG_DEBUG("lfg.queue.match.check", "Guids: (%s) compatibles (cached) changed from bad states to match", GetDetailedMatchRoles(check).c_str());
326  return LFG_COMPATIBLES_MATCH;
327  }
328 
329  if (compatibles != LFG_COMPATIBLES_WITH_LESS_PLAYERS)
330  return compatibles;
331 
332  // Try to match with queued groups
333  while (!all.empty())
334  {
335  check.push_back(all.front());
336  all.pop_front();
337  LfgCompatibility subcompatibility = FindNewGroups(check, all);
338  if (subcompatibility == LFG_COMPATIBLES_MATCH)
339  return LFG_COMPATIBLES_MATCH;
340  check.pop_back();
341  }
342  return compatibles;
343 }
LfgCompatibility
Definition: LFGQueue.h:26
LfgCompatibility FindNewGroups(GuidList &check, GuidList &all)
Definition: LFGQueue.cpp:313
Definition: LFGQueue.h:36
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
std::string GetDetailedMatchRoles(GuidList const &check) const
Definition: LFGQueue.cpp:83
bool all(float x)
Definition: g3dmath.h:431
char const * GetCompatibleString(LfgCompatibility compatibles)
Definition: LFGQueue.cpp:54
#define sLFGMgr
Definition: LFGMgr.h:481
Definition: LFGQueue.h:37
LfgCompatibility GetCompatibles(std::string const &key)
Definition: LFGQueue.cpp:263
std::string ConcatenateGuids(GuidList const &check)
Definition: LFGQueue.cpp:36
void SetCompatibles(std::string const &key, LfgCompatibility compatibles)
Definition: LFGQueue.cpp:246
T check(T value)
Definition: format.h:305
Definition: LFGQueue.h:28
LfgCompatibility CheckCompatibility(GuidList check)
Definition: LFGQueue.cpp:351

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

LfgCompatibilityData * lfg::LFGQueue::GetCompatibilityData ( std::string const key)
private
273 {
274  LfgCompatibleContainer::iterator itr = CompatibleMapStore.find(key);
275  if (itr != CompatibleMapStore.end())
276  return &(itr->second);
277 
278  return NULL;
279 }
arena_t NULL
Definition: jemalloc_internal.h:624
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136
LfgCompatibility lfg::LFGQueue::GetCompatibles ( std::string const key)
private

Get the compatibility of a group of guids

Parameters
[in]keyString concatenation of guids (| used as separator)
Returns
LfgCompatibility type of compatibility
264 {
265  LfgCompatibleContainer::iterator itr = CompatibleMapStore.find(key);
266  if (itr != CompatibleMapStore.end())
267  return itr->second.compatibility;
268 
270 }
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136
Definition: LFGQueue.h:28

+ Here is the caller graph for this function:

std::string lfg::LFGQueue::GetDetailedMatchRoles ( GuidList const check) const
84 {
85  if (check.empty())
86  return "";
87 
88  // need the guids in order to avoid duplicates
89  GuidSet guids(check.begin(), check.end());
90 
91  std::ostringstream o;
92 
93  GuidSet::const_iterator it = guids.begin();
94  o << it->ToString();
95  LfgQueueDataContainer::const_iterator itQueue = QueueDataStore.find(*it);
96  if (itQueue != QueueDataStore.end())
97  {
98  // skip leader flag, log only dps/tank/healer
99  auto role = itQueue->second.roles.find(*it);
100  if (role != itQueue->second.roles.end())
101  o << ' ' << GetRolesString(itQueue->second.roles.at(*it) & uint8(~PLAYER_ROLE_LEADER));
102  }
103 
104  for (++it; it != guids.end(); ++it)
105  {
106  o << '|' << it->ToString();
107  itQueue = QueueDataStore.find(*it);
108  if (itQueue != QueueDataStore.end())
109  {
110  // skip leader flag, log only dps/tank/healer
111  auto role = itQueue->second.roles.find(*it);
112  if (role != itQueue->second.roles.end())
113  o << ' ' << GetRolesString(itQueue->second.roles.at(*it) & uint8(~PLAYER_ROLE_LEADER));
114  }
115  }
116 
117  return o.str();
118 }
Definition: LFG.h:37
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
std::string GetRolesString(uint8 roles)
Definition: LFG.cpp:40
uint8_t uint8
Definition: g3dmath.h:164
std::set< ObjectGuid > GuidSet
Definition: ObjectGuid.h:332
T check(T value)
Definition: format.h:305

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

time_t lfg::LFGQueue::GetJoinTime ( ObjectGuid  guid) const
627 {
628  LfgQueueDataContainer::const_iterator itr = QueueDataStore.find(guid);
629  if (itr != QueueDataStore.end())
630  return itr->second.joinTime;
631 
632  return 0;
633 }
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135

+ Here is the caller graph for this function:

void lfg::LFGQueue::RemoveFromCompatibles ( ObjectGuid  guid)
private

Remove from cached compatible dungeons any entry that contains the given guid

Parameters
[in]guidGuid to remove from compatible cache
226 {
227  std::stringstream out;
228  out << guid;
229  std::string strGuid = out.str();
230 
231  TC_LOG_DEBUG("lfg.queue.data.compatibles.remove", "Removing %s", guid.ToString().c_str());
232  for (LfgCompatibleContainer::iterator itNext = CompatibleMapStore.begin(); itNext != CompatibleMapStore.end();)
233  {
234  LfgCompatibleContainer::iterator it = itNext++;
235  if (std::string::npos != it->first.find(strGuid))
236  CompatibleMapStore.erase(it);
237  }
238 }
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136

+ Here is the caller graph for this function:

void lfg::LFGQueue::RemoveFromCurrentQueue ( ObjectGuid  guid)
private
175 {
176  currentQueueStore.remove(guid);
177 }
GuidList currentQueueStore
Ordered list. Used to find groups.
Definition: LFGQueue.h:142

+ Here is the caller graph for this function:

void lfg::LFGQueue::RemoveFromNewQueue ( ObjectGuid  guid)
private
165 {
166  newToQueueStore.remove(guid);
167 }
GuidList newToQueueStore
New groups to add to queue.
Definition: LFGQueue.h:143

+ Here is the caller graph for this function:

void lfg::LFGQueue::RemoveFromQueue ( ObjectGuid  guid)
133 {
134  RemoveFromNewQueue(guid);
136  RemoveFromCompatibles(guid);
137 
138  std::ostringstream o;
139  o << guid;
140  std::string sguid = o.str();
141 
142  LfgQueueDataContainer::iterator itDelete = QueueDataStore.end();
143  for (LfgQueueDataContainer::iterator itr = QueueDataStore.begin(); itr != QueueDataStore.end(); ++itr)
144  if (itr->first != guid)
145  {
146  if (std::string::npos != itr->second.bestCompatible.find(sguid))
147  {
148  itr->second.bestCompatible.clear();
150  }
151  }
152  else
153  itDelete = itr;
154 
155  if (itDelete != QueueDataStore.end())
156  QueueDataStore.erase(itDelete);
157 }
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
void FindBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue)
Definition: LFGQueue.cpp:688
void RemoveFromCurrentQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:174
void RemoveFromCompatibles(ObjectGuid guid)
Definition: LFGQueue.cpp:225
void RemoveFromNewQueue(ObjectGuid guid)
Definition: LFGQueue.cpp:164

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void lfg::LFGQueue::RemoveQueueData ( ObjectGuid  guid)
186 {
187  LfgQueueDataContainer::iterator it = QueueDataStore.find(guid);
188  if (it != QueueDataStore.end())
189  QueueDataStore.erase(it);
190 }
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
void lfg::LFGQueue::SetCompatibilityData ( std::string const key,
LfgCompatibilityData const compatibles 
)
private
253 {
254  CompatibleMapStore[key] = data;
255 }
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136

+ Here is the caller graph for this function:

void lfg::LFGQueue::SetCompatibles ( std::string const key,
LfgCompatibility  compatibles 
)
private

Stores the compatibility of a list of guids

Parameters
[in]keyString concatenation of guids (| used as separator)
[in]compatiblestype of compatibility
247 {
248  LfgCompatibilityData& data = CompatibleMapStore[key];
249  data.compatibility = compatibles;
250 }
LfgCompatibleContainer CompatibleMapStore
Compatible dungeons.
Definition: LFGQueue.h:136

+ Here is the caller graph for this function:

void lfg::LFGQueue::SetQueueUpdateData ( std::string const strGuids,
LfgRolesMap const proposalRoles 
)
private
void lfg::LFGQueue::UpdateBestCompatibleInQueue ( LfgQueueDataContainer::iterator  itrQueue,
std::string const key,
LfgRolesMap const roles 
)
private
704 {
705  LfgQueueData& queueData = itrQueue->second;
706 
707  uint8 storedSize = queueData.bestCompatible.empty() ? 0 :
708  std::count(queueData.bestCompatible.begin(), queueData.bestCompatible.end(), '|') + 1;
709 
710  uint8 size = std::count(key.begin(), key.end(), '|') + 1;
711 
712  if (size <= storedSize)
713  return;
714 
715  TC_LOG_DEBUG("lfg.queue.compatibles.update", "Changed (%s) to (%s) as best compatible group for %s",
716  queueData.bestCompatible.c_str(), key.c_str(), itrQueue->first.ToString().c_str());
717 
718  queueData.bestCompatible = key;
719  queueData.tanks = LFG_TANKS_NEEDED;
720  queueData.healers = LFG_HEALERS_NEEDED;
721  queueData.dps = LFG_DPS_NEEDED;
722  for (LfgRolesMap::const_iterator it = roles.begin(); it != roles.end(); ++it)
723  {
724  uint8 role = it->second;
725  if (role & PLAYER_ROLE_TANK)
726  --queueData.tanks;
727  else if (role & PLAYER_ROLE_HEALER)
728  --queueData.healers;
729  else
730  --queueData.dps;
731  }
732 }
Definition: LFG.h:39
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: LFG.h:29
Definition: LFG.h:30
Definition: LFG.h:31
Definition: LFG.h:38
uint8_t uint8
Definition: Define.h:152

+ Here is the caller graph for this function:

void lfg::LFGQueue::UpdateQueueTimers ( uint8  queueId,
time_t  currTime 
)
577 {
578  TC_LOG_TRACE("lfg.queue.timers.update", "Updating queue timers...");
579  for (LfgQueueDataContainer::iterator itQueue = QueueDataStore.begin(); itQueue != QueueDataStore.end(); ++itQueue)
580  {
581  LfgQueueData& queueinfo = itQueue->second;
582  uint32 dungeonId = (*queueinfo.dungeons.begin());
583  uint32 queuedTime = uint32(currTime - queueinfo.joinTime);
584  uint8 role = PLAYER_ROLE_NONE;
585  int32 waitTime = -1;
586  int32 wtTank = waitTimesTankStore[dungeonId].time;
587  int32 wtHealer = waitTimesHealerStore[dungeonId].time;
588  int32 wtDps = waitTimesDpsStore[dungeonId].time;
589  int32 wtAvg = waitTimesAvgStore[dungeonId].time;
590 
591  for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer)
592  role |= itPlayer->second;
593  role &= ~PLAYER_ROLE_LEADER;
594 
595  switch (role)
596  {
597  case PLAYER_ROLE_NONE: // Should not happen - just in case
598  waitTime = -1;
599  break;
600  case PLAYER_ROLE_TANK:
601  waitTime = wtTank;
602  break;
603  case PLAYER_ROLE_HEALER:
604  waitTime = wtHealer;
605  break;
606  case PLAYER_ROLE_DAMAGE:
607  waitTime = wtDps;
608  break;
609  default:
610  waitTime = wtAvg;
611  break;
612  }
613 
614  if (queueinfo.bestCompatible.empty())
615  FindBestCompatibleInQueue(itQueue);
616 
617  LfgQueueStatusData queueData(queueId, dungeonId, queueinfo.joinTime, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps);
618  for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer)
619  {
620  ObjectGuid pguid = itPlayer->first;
621  LFGMgr::SendLfgQueueStatus(pguid, queueData);
622  }
623  }
624 }
LfgWaitTimesContainer waitTimesHealerStore
Average wait time to find a group queuing as healer.
Definition: LFGQueue.h:140
Definition: LFG.h:39
Definition: LFG.h:37
Definition: LFG.h:36
LfgQueueDataContainer QueueDataStore
Queued groups.
Definition: LFGQueue.h:135
LfgWaitTimesContainer waitTimesAvgStore
Average wait time to find a group queuing as multiple roles.
Definition: LFGQueue.h:138
void FindBestCompatibleInQueue(LfgQueueDataContainer::iterator itrQueue)
Definition: LFGQueue.cpp:688
Definition: LFG.h:40
#define TC_LOG_TRACE(filterType__,...)
Definition: Log.h:195
static void SendLfgQueueStatus(ObjectGuid guid, LfgQueueStatusData const &data)
Sends queue status to player.
Definition: LFGMgr.cpp:1873
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
LfgWaitTimesContainer waitTimesDpsStore
Average wait time to find a group queuing as dps.
Definition: LFGQueue.h:141
Definition: LFG.h:38
uint8_t uint8
Definition: Define.h:152
Definition: ObjectGuid.h:189
uint32_t uint32
Definition: g3dmath.h:168
LfgWaitTimesContainer waitTimesTankStore
Average wait time to find a group queuing as tank.
Definition: LFGQueue.h:139

+ Here is the call graph for this function:

void lfg::LFGQueue::UpdateWaitTimeAvg ( int32  waitTime,
uint32  dungeonId 
)
193 {
194  LfgWaitTime &wt = waitTimesAvgStore[dungeonId];
195  uint32 old_number = wt.number++;
196  wt.time = int32((wt.time * old_number + waitTime) / wt.number);
197 }
LfgWaitTimesContainer waitTimesAvgStore
Average wait time to find a group queuing as multiple roles.
Definition: LFGQueue.h:138
uint32_t uint32
Definition: Define.h:150
int32_t int32
Definition: g3dmath.h:167

+ Here is the caller graph for this function:

void lfg::LFGQueue::UpdateWaitTimeDps ( int32  waitTime,
uint32  dungeonId 
)
214 {
215  LfgWaitTime &wt = waitTimesDpsStore[dungeonId];
216  uint32 old_number = wt.number++;
217  wt.time = int32((wt.time * old_number + waitTime) / wt.number);
218 }
uint32_t uint32
Definition: Define.h:150
LfgWaitTimesContainer waitTimesDpsStore
Average wait time to find a group queuing as dps.
Definition: LFGQueue.h:141
int32_t int32
Definition: g3dmath.h:167

+ Here is the caller graph for this function:

void lfg::LFGQueue::UpdateWaitTimeHealer ( int32  waitTime,
uint32  dungeonId 
)
207 {
208  LfgWaitTime &wt = waitTimesHealerStore[dungeonId];
209  uint32 old_number = wt.number++;
210  wt.time = int32((wt.time * old_number + waitTime) / wt.number);
211 }
LfgWaitTimesContainer waitTimesHealerStore
Average wait time to find a group queuing as healer.
Definition: LFGQueue.h:140
uint32_t uint32
Definition: Define.h:150
int32_t int32
Definition: g3dmath.h:167

+ Here is the caller graph for this function:

void lfg::LFGQueue::UpdateWaitTimeTank ( int32  waitTime,
uint32  dungeonId 
)
200 {
201  LfgWaitTime &wt = waitTimesTankStore[dungeonId];
202  uint32 old_number = wt.number++;
203  wt.time = int32((wt.time * old_number + waitTime) / wt.number);
204 }
uint32_t uint32
Definition: Define.h:150
int32_t int32
Definition: g3dmath.h:167
LfgWaitTimesContainer waitTimesTankStore
Average wait time to find a group queuing as tank.
Definition: LFGQueue.h:139

+ Here is the caller graph for this function:

Member Data Documentation

LfgCompatibleContainer lfg::LFGQueue::CompatibleMapStore
private

Compatible dungeons.

GuidList lfg::LFGQueue::currentQueueStore
private

Ordered list. Used to find groups.

GuidList lfg::LFGQueue::newToQueueStore
private

New groups to add to queue.

LfgQueueDataContainer lfg::LFGQueue::QueueDataStore
private

Queued groups.

LfgWaitTimesContainer lfg::LFGQueue::waitTimesAvgStore
private

Average wait time to find a group queuing as multiple roles.

LfgWaitTimesContainer lfg::LFGQueue::waitTimesDpsStore
private

Average wait time to find a group queuing as dps.

LfgWaitTimesContainer lfg::LFGQueue::waitTimesHealerStore
private

Average wait time to find a group queuing as healer.

LfgWaitTimesContainer lfg::LFGQueue::waitTimesTankStore
private

Average wait time to find a group queuing as tank.


The documentation for this class was generated from the following files: