Example #1
0
        public void RemoveFromQueue(ObjectGuid guid)
        {
            RemoveFromNewQueue(guid);
            RemoveFromCurrentQueue(guid);
            RemoveFromCompatibles(guid);

            string sguid = guid.ToString();

            var itDelete = QueueDataStore.LastOrDefault().Key;

            foreach (var key in QueueDataStore.Keys.ToList())
            {
                var data = QueueDataStore[key];
                if (key != guid)
                {
                    if (data.bestCompatible.Contains(sguid))
                    {
                        data.bestCompatible = "";
                        FindBestCompatibleInQueue(key, data);
                    }
                }
                else
                {
                    itDelete = key;
                }
            }

            if (!itDelete.IsEmpty())
            {
                QueueDataStore.Remove(itDelete);
            }
        }
Example #2
0
        public long GetJoinTime(ObjectGuid guid)
        {
            var queueData = QueueDataStore.LookupByKey(guid);

            if (queueData != null)
            {
                return(queueData.joinTime);
            }

            return(0);
        }
Example #3
0
        public void AddToQueue(ObjectGuid guid, bool reAdd = false)
        {
            if (!QueueDataStore.ContainsKey(guid))
            {
                Log.outError(LogFilter.Lfg, "AddToQueue: Queue data not found for [{0}]", guid);
                return;
            }

            if (reAdd)
            {
                AddToFrontCurrentQueue(guid);
            }
            else
            {
                AddToNewQueue(guid);
            }
        }
Example #4
0
        LfgCompatibility CheckCompatibility(List <ObjectGuid> check)
        {
            string      strGuids = ConcatenateGuids(check);
            LfgProposal proposal = new();
            List <uint> proposalDungeons;
            Dictionary <ObjectGuid, ObjectGuid> proposalGroups = new();
            Dictionary <ObjectGuid, LfgRoles>   proposalRoles  = new();

            // Check for correct size
            if (check.Count > MapConst.MaxGroupSize || check.Empty())
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}): Size wrong - Not compatibles", strGuids);
                return(LfgCompatibility.WrongGroupSize);
            }

            // Check all-but-new compatiblitity
            if (check.Count > 2)
            {
                ObjectGuid frontGuid = check.First();
                check.RemoveAt(0);

                // Check all-but-new compatibilities (New, A, B, C, D) -. check(A, B, C, D)
                LfgCompatibility child_compatibles = CheckCompatibility(check);
                if (child_compatibles < LfgCompatibility.WithLessPlayers) // Group not compatible
                {
                    Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) child {1} not compatibles", strGuids, ConcatenateGuids(check));
                    SetCompatibles(strGuids, child_compatibles);
                    return(child_compatibles);
                }
                check.Insert(0, frontGuid);
            }

            // Check if more than one LFG group and number of players joining
            byte numPlayers   = 0;
            byte numLfgGroups = 0;

            foreach (var guid in check)
            {
                if (!(numLfgGroups < 2) && !(numPlayers <= MapConst.MaxGroupSize))
                {
                    break;
                }

                var itQueue = QueueDataStore.LookupByKey(guid);
                if (itQueue == null)
                {
                    Log.outError(LogFilter.Lfg, "CheckCompatibility: [{0}] is not queued but listed as queued!", guid);
                    RemoveFromQueue(guid);
                    return(LfgCompatibility.Pending);
                }

                // 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)
                foreach (var it2 in itQueue.roles)
                {
                    proposalGroups[it2.Key] = guid.IsPlayer() ? guid : ObjectGuid.Empty;
                }

                numPlayers += (byte)itQueue.roles.Count;

                if (Global.LFGMgr.IsLfgGroup(guid))
                {
                    if (numLfgGroups == 0)
                    {
                        proposal.group = guid;
                    }
                    ++numLfgGroups;
                }
            }

            // Group with less that MAXGROUPSIZE members always compatible
            if (check.Count == 1 && numPlayers != MapConst.MaxGroupSize)
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) sigle group. Compatibles", strGuids);
                var guid    = check.First();
                var itQueue = QueueDataStore.LookupByKey(guid);

                LfgCompatibilityData data = new(LfgCompatibility.WithLessPlayers);
                data.roles = itQueue.roles;
                Global.LFGMgr.CheckGroupRoles(data.roles);

                UpdateBestCompatibleInQueue(guid, itQueue, strGuids, data.roles);
                SetCompatibilityData(strGuids, data);
                return(LfgCompatibility.WithLessPlayers);
            }

            if (numLfgGroups > 1)
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) More than one Lfggroup ({1})", strGuids, numLfgGroups);
                SetCompatibles(strGuids, LfgCompatibility.MultipleLfgGroups);
                return(LfgCompatibility.MultipleLfgGroups);
            }

            if (numPlayers > MapConst.MaxGroupSize)
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) Too much players ({1})", strGuids, numPlayers);
                SetCompatibles(strGuids, LfgCompatibility.TooMuchPlayers);
                return(LfgCompatibility.TooMuchPlayers);
            }

            // 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
            if (check.Count > 1)
            {
                foreach (var it in check)
                {
                    Dictionary <ObjectGuid, LfgRoles> roles = QueueDataStore[it].roles;
                    foreach (var rolePair in roles)
                    {
                        KeyValuePair <ObjectGuid, LfgRoles> itPlayer = new();
                        foreach (var _player in proposalRoles)
                        {
                            itPlayer = _player;
                            if (rolePair.Key == itPlayer.Key)
                            {
                                Log.outError(LogFilter.Lfg, "CheckCompatibility: ERROR! Player multiple times in queue! [{0}]", rolePair.Key);
                            }
                            else if (Global.LFGMgr.HasIgnore(rolePair.Key, itPlayer.Key))
                            {
                                break;
                            }
                        }
                        if (itPlayer.Key == proposalRoles.LastOrDefault().Key)
                        {
                            proposalRoles[rolePair.Key] = rolePair.Value;
                        }
                    }
                }

                byte playersize = (byte)(numPlayers - proposalRoles.Count);
                if (playersize != 0)
                {
                    Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) not compatible, {1} players are ignoring each other", strGuids, playersize);
                    SetCompatibles(strGuids, LfgCompatibility.HasIgnores);
                    return(LfgCompatibility.HasIgnores);
                }
                StringBuilder o;
                Dictionary <ObjectGuid, LfgRoles> debugRoles = proposalRoles;
                if (!Global.LFGMgr.CheckGroupRoles(proposalRoles))
                {
                    o = new StringBuilder();
                    foreach (var it in debugRoles)
                    {
                        o.AppendFormat(", {0}: {1}", it.Key, GetRolesString(it.Value));
                    }

                    Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) Roles not compatible{1}", strGuids, o.ToString());
                    SetCompatibles(strGuids, LfgCompatibility.NoRoles);
                    return(LfgCompatibility.NoRoles);
                }

                var itguid = check.First();
                proposalDungeons = QueueDataStore[itguid].dungeons;
                o = new StringBuilder();
                o.AppendFormat(", {0}: ({1})", itguid, Global.LFGMgr.ConcatenateDungeons(proposalDungeons));
                foreach (var guid in check)
                {
                    if (guid == itguid)
                    {
                        continue;
                    }

                    List <uint> dungeons = QueueDataStore[itguid].dungeons;
                    o.AppendFormat(", {0}: ({1})", guid, Global.LFGMgr.ConcatenateDungeons(dungeons));
                    List <uint> temporal = proposalDungeons.Intersect(dungeons).ToList();
                    proposalDungeons = temporal;
                }

                if (proposalDungeons.Empty())
                {
                    Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) No compatible dungeons{1}", strGuids, o.ToString());
                    SetCompatibles(strGuids, LfgCompatibility.NoDungeons);
                    return(LfgCompatibility.NoDungeons);
                }
            }
            else
            {
                ObjectGuid   gguid = check.First();
                LfgQueueData queue = QueueDataStore[gguid];
                proposalDungeons = queue.dungeons;
                proposalRoles    = queue.roles;
                Global.LFGMgr.CheckGroupRoles(proposalRoles);          // assing new roles
            }

            // Enough players?
            if (numPlayers != MapConst.MaxGroupSize)
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) Compatibles but not enough players({1})", strGuids, numPlayers);
                LfgCompatibilityData data = new(LfgCompatibility.WithLessPlayers);
                data.roles = proposalRoles;

                foreach (var guid in check)
                {
                    var queueData = QueueDataStore.LookupByKey(guid);
                    UpdateBestCompatibleInQueue(guid, queueData, strGuids, data.roles);
                }

                SetCompatibilityData(strGuids, data);
                return(LfgCompatibility.WithLessPlayers);
            }

            ObjectGuid _guid = check.First();

            proposal.queues = check;
            proposal.isNew  = numLfgGroups != 1 || Global.LFGMgr.GetOldState(_guid) != LfgState.Dungeon;

            if (!Global.LFGMgr.AllQueued(check))
            {
                Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) Group MATCH but can't create proposal!", strGuids);
                SetCompatibles(strGuids, LfgCompatibility.BadStates);
                return(LfgCompatibility.BadStates);
            }

            // Create a new proposal
            proposal.cancelTime = Time.UnixTime + SharedConst.LFGTimeProposal;
            proposal.state      = LfgProposalState.Initiating;
            proposal.leader     = ObjectGuid.Empty;
            proposal.dungeonId  = proposalDungeons.SelectRandom();

            bool leader = false;

            foreach (var rolePair in proposalRoles)
            {
                // Assing new leader
                if (rolePair.Value.HasAnyFlag(LfgRoles.Leader))
                {
                    if (!leader || proposal.leader.IsEmpty() || Convert.ToBoolean(RandomHelper.IRand(0, 1)))
                    {
                        proposal.leader = rolePair.Key;
                    }
                    leader = true;
                }
                else if (!leader && (proposal.leader.IsEmpty() || Convert.ToBoolean(RandomHelper.IRand(0, 1))))
                {
                    proposal.leader = rolePair.Key;
                }

                // Assing player data and roles
                LfgProposalPlayer data = new();
                data.role  = rolePair.Value;
                data.group = proposalGroups.LookupByKey(rolePair.Key);
                if (!proposal.isNew && !data.group.IsEmpty() && data.group == proposal.group) // Player from existing group, autoaccept
                {
                    data.accept = LfgAnswer.Agree;
                }

                proposal.players[rolePair.Key] = data;
            }

            // Mark proposal members as not queued (but not remove queue data)
            foreach (var guid in proposal.queues)
            {
                RemoveFromNewQueue(guid);
                RemoveFromCurrentQueue(guid);
            }

            Global.LFGMgr.AddProposal(proposal);

            Log.outDebug(LogFilter.Lfg, "CheckCompatibility: ({0}) MATCH! Group formed", strGuids);
            SetCompatibles(strGuids, LfgCompatibility.Match);
            return(LfgCompatibility.Match);
        }
Example #5
0
 public void RemoveQueueData(ObjectGuid guid)
 {
     QueueDataStore.Remove(guid);
 }