public PresenceInfo GetPresenceInfo(UUID agentID)
		{
            PresenceInfo agent = new PresenceInfo();
            List<string> query = GD.Query("AgentID", agentID, "baninfo", "*");

			if (query.Count == 0)
				//Couldn't find it, return null then.
				return null;

            agent.AgentID = agentID;
            if(query[1] != "")
                agent.Flags = (PresenceInfo.PresenceInfoFlags)Enum.Parse(typeof(PresenceInfo.PresenceInfoFlags),query[1]);
            agent.KnownAlts = Util.ConvertToList(query[2]);
            agent.KnownID0s = Util.ConvertToList(query[3]);
            agent.KnownIPs = Util.ConvertToList(query[4]);
            agent.KnownMacs = Util.ConvertToList(query[5]);
            agent.KnownViewers = Util.ConvertToList(query[6]);
            agent.LastKnownID0 = query[7];
            agent.LastKnownIP = query[8];
            agent.LastKnownMac = query[9];
            agent.LastKnownViewer = query[10];
            agent.Platform = query[11];
            
			return agent;
		}
        public void UpdatePresenceInfo(PresenceInfo agent)
		{
			List<object> SetValues = new List<object>();
            List<string> SetRows = new List<string>();
            SetRows.Add("AgentID"/*"AgentID"*/);
            SetRows.Add("Flags"/*"Flags"*/);
            SetRows.Add("KnownAlts"/*"KnownAlts"*/);
            SetRows.Add("KnownID0s"/*"KnownID0s"*/);
            SetRows.Add("KnownIPs"/*"KnownIPs"*/);
            SetRows.Add("KnownMacs"/*"KnownMacs"*/);
            SetRows.Add("KnownViewers"/*"KnownViewers"*/);
            SetRows.Add("LastKnownID0"/*"LastKnownID0"*/);
            SetRows.Add("LastKnownIP"/*"LastKnownIP"*/);
            SetRows.Add("LastKnownMac"/*"LastKnownMac"*/);
            SetRows.Add("LastKnownViewer"/*"LastKnownViewer"*/);
            SetRows.Add("Platform"/*"Platform"*/);
            SetValues.Add(agent.AgentID);
            SetValues.Add(agent.Flags);
            SetValues.Add(Util.ConvertToString(agent.KnownAlts));
            SetValues.Add(Util.ConvertToString(agent.KnownID0s));
            SetValues.Add(Util.ConvertToString(agent.KnownIPs));
            SetValues.Add(Util.ConvertToString(agent.KnownMacs));
            SetValues.Add(Util.ConvertToString(agent.KnownViewers));
            SetValues.Add(agent.LastKnownID0);
            SetValues.Add(agent.LastKnownIP);
            SetValues.Add(agent.LastKnownMac);
            SetValues.Add(agent.LastKnownViewer);
            SetValues.Add(agent.Platform);
            GD.Replace("baninfo", SetRows.ToArray(), SetValues.ToArray());
        }
 private void AddFlag (ref PresenceInfo info, PresenceInfo.PresenceInfoFlags presenceInfoFlags)
 {
     if (presenceInfoFlags == 0)
         return;
     info.Flags &= PresenceInfo.PresenceInfoFlags.Clean; //Remove clean
     if (presenceInfoFlags == PresenceInfo.PresenceInfoFlags.Known)
         info.Flags &= PresenceInfo.PresenceInfoFlags.Clean; //Remove suspected as well
     info.Flags |= presenceInfoFlags; //Add the flag
 }
        private void CoralateLists (PresenceInfo info, PresenceInfo suspectedInfo)
        {
            bool addedFlag = false;
            PresenceInfo.PresenceInfoFlags Flag = 0;

            if ((suspectedInfo.Flags & PresenceInfo.PresenceInfoFlags.Clean) == PresenceInfo.PresenceInfoFlags.Clean &&
                    (info.Flags & PresenceInfo.PresenceInfoFlags.Clean) == PresenceInfo.PresenceInfoFlags.Clean)
            {
                //They are both clean, do nothing
            }
            else if ((suspectedInfo.Flags & PresenceInfo.PresenceInfoFlags.Suspected) == PresenceInfo.PresenceInfoFlags.Suspected ||
                (info.Flags & PresenceInfo.PresenceInfoFlags.Suspected) == PresenceInfo.PresenceInfoFlags.Suspected)
            {
                //Suspected, update them both
                addedFlag = true;
                AddFlag (ref info, PresenceInfo.PresenceInfoFlags.Suspected);
                AddFlag (ref suspectedInfo, PresenceInfo.PresenceInfoFlags.Suspected);
            }
            else if ((suspectedInfo.Flags & PresenceInfo.PresenceInfoFlags.Known) == PresenceInfo.PresenceInfoFlags.Known ||
                (info.Flags & PresenceInfo.PresenceInfoFlags.Known) == PresenceInfo.PresenceInfoFlags.Known)
            {
                //Known, update them both
                addedFlag = true;
                AddFlag (ref info, PresenceInfo.PresenceInfoFlags.Known);
                AddFlag (ref suspectedInfo, PresenceInfo.PresenceInfoFlags.Known);
            }

            //Add the alt account flag
            AddFlag (ref info, PresenceInfo.PresenceInfoFlags.SuspectedAltAccount);
            AddFlag (ref suspectedInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccount);

            if (suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.Suspected ||
                suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected ||
                info.Flags == PresenceInfo.PresenceInfoFlags.Suspected ||
                info.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected)
            {
                //They might be an alt, but the other is clean, so don't bother them too much
                AddFlag (ref info, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected);
                AddFlag (ref suspectedInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected);
            }
            else if (suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.Known ||
                suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown ||
                info.Flags == PresenceInfo.PresenceInfoFlags.Known ||
                info.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown)
            {
                //Flag 'em
                AddFlag (ref info, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown);
                AddFlag (ref suspectedInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown);
            }

            //Add each user to the list of alts, then add the lists of both together
            info.KnownAlts.Add (suspectedInfo.AgentID.ToString ());
            suspectedInfo.KnownAlts.Add (info.AgentID.ToString ());

            //Add the lists together
            List<string> alts = new List<string> ();
            foreach (string alt in info.KnownAlts)
            {
                if (!alts.Contains (alt))
                    alts.Add (alt);
            }
            foreach (string alt in suspectedInfo.KnownAlts)
            {
                if (!alts.Contains (alt))
                    alts.Add (alt);
            }

            //If we have added a flag, we need to update ALL alts as well
            if (addedFlag && alts.Count != 0)
            {
                foreach (string alt in alts)
                {
                    PresenceInfo altInfo = GetPresenceInfo (UUID.Parse (alt));
                    if (altInfo != null)
                    {
                        //Give them the flag as well
                        AddFlag (ref altInfo, Flag);

                        //Add the alt account flag
                        AddFlag (ref altInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccount);

                        //Also give them the flags for alts
                        if (suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.Suspected ||
                            suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected ||
                            info.Flags == PresenceInfo.PresenceInfoFlags.Suspected ||
                            info.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected)
                        {
                            //They might be an alt, but the other is clean, so don't bother them too much
                            AddFlag (ref altInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfSuspected);
                        }
                        else if (suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.Known ||
                            suspectedInfo.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown ||
                            info.Flags == PresenceInfo.PresenceInfoFlags.Known ||
                            info.Flags == PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown)
                        {
                            //Flag 'em
                            AddFlag (ref altInfo, PresenceInfo.PresenceInfoFlags.SuspectedAltAccountOfKnown);
                        }

                        //And update them in the db
                        UpdatePresenceInfo (suspectedInfo);
                    }
                }
            }

            //Replace both lists now that they are merged
            info.KnownAlts = alts;
            suspectedInfo.KnownAlts = alts;

            //Update them, as we changed their info, we get updated below
            UpdatePresenceInfo (suspectedInfo);
        }
        private bool DoGC(PresenceInfo info)
        {
            bool update = false;
            List<string> newIPs = new List<string>();
            foreach (string ip in info.KnownIPs)
            {
                string[] split;
                string newIP = ip;
                if ((split = ip.Split(':')).Length > 1)
                {
                    //Remove the port if it exists and force an update
                    newIP = split[0];
                    update = true;
                }
                if (!newIPs.Contains(newIP))
                    newIPs.Add(newIP);
            }
            if (info.KnownIPs.Count != newIPs.Count)
                update = true;
            info.KnownIPs = newIPs;

            return update;
        }
        public void Check (PresenceInfo info, List<string> viewers, bool includeList)
        {
            //
            //Check passwords
            //Check IPs, Mac's, etc
            //

            bool needsUpdated = false;

            #region Check Password

            List<string> query = GD.Query("UUID", info.AgentID, DatabaseToAuthTable, "passwordHash");
            if (query.Count != 0)
            {
                string password = query[0];
                query = GD.Query("passwordHash", password, DatabaseToAuthTable, "UUID");
                foreach (string ID in query)
                {
                    PresenceInfo suspectedInfo = GetPresenceInfo(UUID.Parse(ID));
                    if (suspectedInfo.AgentID == info.AgentID)
                        continue;

                    CoralateLists (info, suspectedInfo);

                    needsUpdated = true;
                }
            }

            #endregion

            #region Check ID0, IP, Mac, etc

            //Only check suspected and known offenders in this scan
            // 2 == Flags
            query = GD.Query(" (Flags = 'SuspectedAltAccountOfKnown'" +
                " or Flags = 'Known' or Flags = 'SuspectedAltAccountOfSuspected'" +
                " or Flags = 'Banned'" +
                " or Flags = 'Suspected')", "baninfo", "AgentID");
            foreach (string ID in query)
            {
                PresenceInfo suspectedInfo = GetPresenceInfo(UUID.Parse(ID));
                if (suspectedInfo.AgentID == info.AgentID)
                    continue;
                foreach (string ID0 in suspectedInfo.KnownID0s)
                {
                    if (info.KnownID0s.Contains(ID0))
                    {
                        CoralateLists (info, suspectedInfo);
                        needsUpdated = true;
                    }
                }
                foreach (string IP in suspectedInfo.KnownIPs)
                {
                    if (info.KnownIPs.Contains(IP.Split(':')[0]))
                    {
                        CoralateLists (info, suspectedInfo);
                        needsUpdated = true;
                    }
                }
                foreach (string Mac in suspectedInfo.KnownMacs)
                {
                    if (info.KnownMacs.Contains(Mac))
                    {
                        CoralateLists (info, suspectedInfo);
                        needsUpdated = true;
                    }
                }
            }

            foreach (string viewer in info.KnownViewers)
            {
                if (IsViewerBanned(viewer, includeList, viewers))
                {
                    if ((info.Flags & PresenceInfo.PresenceInfoFlags.Clean) == PresenceInfo.PresenceInfoFlags.Clean)
                    {
                        //Update them to suspected for their viewer
                        AddFlag (ref info, PresenceInfo.PresenceInfoFlags.Suspected);
                        //And update them later
                        needsUpdated = true;
                    }
                    else if ((info.Flags & PresenceInfo.PresenceInfoFlags.Suspected) == PresenceInfo.PresenceInfoFlags.Suspected)
                    {
                        //Suspected, we don't really want to move them higher than this...
                    }
                    else if ((info.Flags & PresenceInfo.PresenceInfoFlags.Known) == PresenceInfo.PresenceInfoFlags.Known)
                    {
                        //Known, can't update anymore
                    }
                }
            }
            if (DoGC(info) & !needsUpdated)//Clean up all info
                needsUpdated = true;

            #endregion

            //Now update ours
            if (needsUpdated)
                UpdatePresenceInfo(info);
        }