public List<DirLandReplyData> FindLandForSaleInRegion(string searchType, uint price, uint area, int StartQuery, uint Flags, UUID regionID)
        {
            object remoteValue = DoRemote(searchType, price, area, StartQuery, Flags, regionID);
            if (remoteValue != null || m_doRemoteOnly)
                return (List<DirLandReplyData>)remoteValue;

            QueryFilter filter = new QueryFilter();

            //Only parcels set for sale will be checked
            filter.andFilters["ForSale"] = "1";
            filter.andFilters["RegionID"] = regionID;

            //They requested a sale price check
            if ((Flags & (uint)DirectoryManager.DirFindFlags.LimitByPrice) == (uint)DirectoryManager.DirFindFlags.LimitByPrice)
            {
                filter.andLessThanEqFilters["SalePrice"] = (int)price;
            }

            //They requested a 
            if ((Flags & (uint)DirectoryManager.DirFindFlags.LimitByArea) == (uint)DirectoryManager.DirFindFlags.LimitByArea)
            {
                filter.andGreaterThanEqFilters["Area"] = (int)area;
            }
            Dictionary<string, bool> sort = new Dictionary<string, bool>();
            if ((Flags & (uint)DirectoryManager.DirFindFlags.AreaSort) == (uint)DirectoryManager.DirFindFlags.AreaSort)
                sort["Area"] = false;
            if ((Flags & (uint)DirectoryManager.DirFindFlags.NameSort) == (uint)DirectoryManager.DirFindFlags.NameSort)
                sort["Name"] = false;
            //if ((queryFlags & (uint)DirectoryManager.DirFindFlags.PerMeterSort) == (uint)DirectoryManager.DirFindFlags.PerMeterSort)
            //    sort["Area"] = (queryFlags & (uint)DirectoryManager.DirFindFlags.SortAsc) == (uint)DirectoryManager.DirFindFlags.SortAsc);
            if ((Flags & (uint)DirectoryManager.DirFindFlags.PricesSort) == (uint)DirectoryManager.DirFindFlags.PricesSort)
                sort["SalePrice"] = (Flags & (uint)DirectoryManager.DirFindFlags.SortAsc) == (uint)DirectoryManager.DirFindFlags.SortAsc;

            List<string> retVal = GD.Query(new[]{
                "InfoUUID",
                "Name",
                "Auction",
                "SalePrice",
                "Area",
                "Flags"
            }, "searchparcel", filter, sort, (uint)StartQuery, 50);

            //if there are none, return
            if (retVal.Count == 0)
                return new List<DirLandReplyData>();

            List<DirLandReplyData> Data = new List<DirLandReplyData>();
            for (int i = 0; i < retVal.Count; i += 6)
            {
                DirLandReplyData replyData = new DirLandReplyData
                                                 {
                                                     forSale = true,
                                                     parcelID = new UUID(retVal[i]),
                                                     name = retVal[i + 1],
                                                     auction = (retVal[i + 2] != "0")
                                                 };
                //If its an auction and we didn't request to see auctions, skip to the next and continue
                if ((Flags & (uint)DirectoryManager.SearchTypeFlags.Auction) == (uint)DirectoryManager.SearchTypeFlags.Auction && !replyData.auction)
                {
                    continue;
                }

                replyData.salePrice = Convert.ToInt32(retVal[i + 3]);
                replyData.actualArea = Convert.ToInt32(retVal[i + 4]);

                //Check maturity levels depending on what flags the user has set
                //0 flag is an override so that we can get all lands for sale, regardless of maturity
                if (Flags == 0 || !((int.Parse(retVal[i + 5]) & (int)ParcelFlags.MaturePublish) == (int)ParcelFlags.MaturePublish && ((Flags & (uint)DirectoryManager.DirFindFlags.IncludeMature)) == 0))
                {
                    Data.Add(replyData);
                }
            }

            return Data;
        }
        public void DirLandQuery(IClientAPI remoteClient, UUID queryID,
            uint queryFlags, uint searchType, int price, int area,
            int queryStart)
        {
            Hashtable ReqHash = new Hashtable();
            ReqHash["flags"] = queryFlags.ToString();
            ReqHash["type"] = searchType.ToString();
            ReqHash["price"] = price.ToString();
            ReqHash["area"] = area.ToString();
            ReqHash["query_start"] = queryStart.ToString();

            Hashtable result = GenericXMLRPCRequest(ReqHash,
                    "dir_land_query");

            if (!Convert.ToBoolean(result["success"]))
            {
                remoteClient.SendAgentAlertMessage(
                        result["errorMessage"].ToString(), false);
                return;
            }

            ArrayList dataArray = (ArrayList)result["data"];

            int count = dataArray.Count;
            if (count > 100)
                count = 101;

            DirLandReplyData[] data = new DirLandReplyData[count];

            int i = 0;

            foreach (Object o in dataArray)
            {
                Hashtable d = (Hashtable)o;

                if (d["name"] == null)
                    continue;

                data[i] = new DirLandReplyData();
                data[i].parcelID = new UUID(d["parcel_id"].ToString());
                data[i].name = d["name"].ToString();
                data[i].auction = Convert.ToBoolean(d["auction"]);
                data[i].forSale = Convert.ToBoolean(d["for_sale"]);
                data[i].salePrice = Convert.ToInt32(d["sale_price"]);
                data[i].actualArea = Convert.ToInt32(d["area"]);
                i++;
                if (i >= count)
                    break;
            }

            remoteClient.SendDirLandReply(queryID, data);
        }
        public void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
            uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
        {
            //The following constant appears to be from GridLayerType enum
            //defined in OpenMetaverse/GridManager.cs of libopenmetaverse.
            if (itemtype == 7) //(land sales)
            {
                int tc = Environment.TickCount;
                Hashtable ReqHash = new Hashtable();

                //The flags are: SortAsc (1 << 15), PerMeterSort (1 << 17)
                ReqHash["flags"] = "163840";
                ReqHash["type"] = "4294967295"; //This is -1 in 32 bits
                ReqHash["price"] = "0";
                ReqHash["area"] = "0";
                ReqHash["query_start"] = "0";

                Hashtable result = GenericXMLRPCRequest(ReqHash,
                                                        "dir_land_query");

                if (!Convert.ToBoolean(result["success"]))
                {
                    remoteClient.SendAgentAlertMessage(
                        result["errorMessage"].ToString(), false);
                    return;
                }

                ArrayList dataArray = (ArrayList)result["data"];

                int count = dataArray.Count;
                if (count > 100)
                    count = 101;

                DirLandReplyData[] Landdata = new DirLandReplyData[count];

                int i = 0;
                string[] ParcelLandingPoint = new string[count];
                string[] ParcelRegionUUID = new string[count];
                foreach (Object o in dataArray)
                {
                    Hashtable d = (Hashtable)o;

                    if (d["name"] == null)
                        continue;
                    Landdata[i] = new DirLandReplyData();
                    Landdata[i].parcelID = new UUID(d["parcel_id"].ToString());
                    Landdata[i].name = d["name"].ToString();
                    Landdata[i].auction = Convert.ToBoolean(d["auction"]);
                    Landdata[i].forSale = Convert.ToBoolean(d["for_sale"]);
                    Landdata[i].salePrice = Convert.ToInt32(d["sale_price"]);
                    Landdata[i].actualArea = Convert.ToInt32(d["area"]);
                    ParcelLandingPoint[i] = d["landing_point"].ToString();
                    ParcelRegionUUID[i] = d["region_UUID"].ToString();
                    i++;
                    if (i >= count)
                        break;
                }
                i = 0;
                int locX = 0;
                int locY = 0;

                List<mapItemReply> mapitems = new List<mapItemReply>();

                foreach (DirLandReplyData landDir in Landdata)
                {
                    foreach(IScene scene in m_Scenes)
                    {
                        if(scene.RegionInfo.RegionID.ToString() == ParcelRegionUUID[i])
                        {
                            locX = scene.RegionInfo.RegionLocX;
                            locY = scene.RegionInfo.RegionLocY;
                        }
                    }
                    string[] landingpoint = ParcelLandingPoint[i].Split('/');
                    mapItemReply mapitem = new mapItemReply();
                    mapitem.x = (uint)((locX * 256 ) + Convert.ToDecimal(landingpoint[0]));
                    mapitem.y = (uint)((locY * 256 ) + Convert.ToDecimal(landingpoint[1]));
                    mapitem.id = landDir.parcelID;
                    mapitem.name = landDir.name;
                    mapitem.Extra = landDir.actualArea;
                    mapitem.Extra2 = landDir.salePrice;
                    mapitems.Add(mapitem);
                    i++;
                }
                remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                mapitems.Clear();
            }
        }
        /// <summary>
        ///   Searches for parcels for sale around the grid
        /// </summary>
        /// <param name = "searchType">2 = Auction only, 8 = For Sale - Mainland, 16 = For Sale - Estate, 4294967295 = All</param>
        /// <param name = "price"></param>
        /// <param name = "area"></param>
        /// <param name = "StartQuery"></param>
        /// <returns></returns>
        public DirLandReplyData[] FindLandForSale(string searchType, uint price, uint area, int StartQuery, uint Flags)
        {

            QueryFilter filter = new QueryFilter();

            //Only parcels set for sale will be checked
            filter.andFilters["ForSale"] = "1";

            //They requested a sale price check
            if ((Flags & (uint)DirectoryManager.DirFindFlags.LimitByPrice) == (uint)DirectoryManager.DirFindFlags.LimitByPrice)
            {
                filter.andLessThanEqFilters["SalePrice"] = (int)price;
            }

            //They requested a 
            if ((Flags & (uint) DirectoryManager.DirFindFlags.LimitByArea) == (uint) DirectoryManager.DirFindFlags.LimitByArea)
            {
                filter.andGreaterThanEqFilters["Area"] = (int)area;
            }

            List<string> retVal = GD.Query(new string[]{
                "InfoUUID",
                "Name",
                "Auction",
                "SalePrice",
                "Area",
                "Flags"
            }, "searchparcel", filter, null, (uint)StartQuery, 50);

            //if there are none, return
            if (retVal.Count == 0)
            {
                return new DirLandReplyData[0] { };
            }

            List<DirLandReplyData> Data = new List<DirLandReplyData>();
            DirLandReplyData replyData;
            for (int i = 0; i < retVal.Count; i += 6)
            {
                replyData = new DirLandReplyData
                {
                    forSale = true,
                    parcelID = new UUID(retVal[i]),
                    name = retVal[i + 1],
                    auction = (retVal[i + 2] != "0")
                };
                //If its an auction and we didn't request to see auctions, skip to the next and continue
                if ((Flags & (uint)DirectoryManager.SearchTypeFlags.Auction) == (uint)DirectoryManager.SearchTypeFlags.Auction && !replyData.auction)
                {
                    continue;
                }

                replyData.salePrice = Convert.ToInt32(retVal[i + 3]);
                replyData.actualArea = Convert.ToInt32(retVal[i + 4]);

                //Check maturity levels depending on what flags the user has set
                //0 flag is an override so that we can get all lands for sale, regardless of maturity
                if (Flags == 0 || !((int.Parse(retVal[i + 5]) & (int)ParcelFlags.MaturePublish) == (int)ParcelFlags.MaturePublish && ((Flags & (uint)DirectoryManager.DirFindFlags.IncludeMature)) == 0))
                {
                    Data.Add(replyData);
                }
            }

            return Data.ToArray();
        }