public byte[] GetParcelInfo(OSDMap request)
        {
            UUID     infoID = request["InfoUUID"].AsUUID();
            LandData parcel = DirectoryServiceConnector.GetParcelInfo(infoID);
            OSDMap   result = parcel == null ? new OSDMap() : parcel.ToOSD();

            request["Success"] = parcel != null;
            UTF8Encoding encoding = new UTF8Encoding();

            return(encoding.GetBytes(OSDParser.SerializeJsonString(request)));
        }
        public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags,
                                                 uint EstateID, bool godlike, uint itemtype, ulong regionhandle)
        {
            //All the parts are in for this, except for popular places and those are not in as they are not reqested anymore.

            List <mapItemReply> mapitems = new List <mapItemReply>();
            mapItemReply        mapitem  = new mapItemReply();
            uint xstart = 0;
            uint ystart = 0;

            Utils.LongToUInts(remoteClient.Scene.RegionInfo.RegionHandle, out xstart, out ystart);
            GridRegion GR = null;

            GR = regionhandle == 0 ? new GridRegion(remoteClient.Scene.RegionInfo) : m_Scenes[0].GridService.GetRegionByPosition(remoteClient.AllScopeIDs, (int)xstart, (int)ystart);
            if (GR == null)
            {
                //No region???
                return;
            }

            #region Telehub

            if (itemtype == (uint)GridItemType.Telehub)
            {
                IRegionConnector GF = DataManager.DataManager.RequestPlugin <IRegionConnector>();
                if (GF == null)
                {
                    return;
                }

                int tc = Environment.TickCount;
                //Find the telehub
                Telehub telehub = GF.FindTelehub(GR.RegionID, GR.RegionHandle);
                if (telehub != null)
                {
                    mapitem = new mapItemReply
                    {
                        x      = (uint)(GR.RegionLocX + telehub.TelehubLocX),
                        y      = (uint)(GR.RegionLocY + telehub.TelehubLocY),
                        id     = GR.RegionID,
                        name   = Util.Md5Hash(GR.RegionName + tc.ToString()),
                        Extra  = 1,
                        Extra2 = 0
                    };
                    //The position is in GLOBAL coordinates (in meters)
                    //This is how the name is sent, go figure
                    //Not sure, but this is what gets sent

                    mapitems.Add(mapitem);
                    remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                    mapitems.Clear();
                }
            }

            #endregion

            #region Land for sale

            //PG land that is for sale
            if (itemtype == (uint)GridItemType.LandForSale)
            {
                if (directoryService == null)
                {
                    return;
                }
                //Find all the land, use "0" for the flags so we get all land for sale, no price or area checking
                List <DirLandReplyData> Landdata = directoryService.FindLandForSaleInRegion("0", uint.MaxValue, 0, 0, 0, GR.RegionID);

                int locX = 0;
                int locY = 0;
                foreach (DirLandReplyData landDir in Landdata)
                {
                    if (landDir == null)
                    {
                        continue;
                    }
                    LandData landdata = directoryService.GetParcelInfo(landDir.parcelID);
                    if (landdata == null || landdata.Maturity != 0)
                    {
                        continue; //Not a PG land
                    }
#if (!ISWIN)
                    foreach (IScene scene in m_Scenes)
                    {
                        if (scene.RegionInfo.RegionID == landdata.RegionID)
                        {
                            //Global coords, so add the meters
                            locX = scene.RegionInfo.RegionLocX;
                            locY = scene.RegionInfo.RegionLocY;
                        }
                    }
#else
                    foreach (IScene scene in m_Scenes.Where(scene => scene.RegionInfo.RegionID == landdata.RegionID))
                    {
                        //Global coords, so add the meters
                        locX = scene.RegionInfo.RegionLocX;
                        locY = scene.RegionInfo.RegionLocY;
                    }
#endif
                    if (locY == 0 && locX == 0)
                    {
                        //Ask the grid service for the coordinates if the region is not local
                        GridRegion r = m_Scenes[0].GridService.GetRegionByUUID(remoteClient.AllScopeIDs, landdata.RegionID);
                        if (r != null)
                        {
                            locX = r.RegionLocX;
                            locY = r.RegionLocY;
                        }
                    }
                    if (locY == 0 && locX == 0) //Couldn't find the region, don't send
                    {
                        continue;
                    }

                    mapitem = new mapItemReply
                    {
                        x      = (uint)(locX + landdata.UserLocation.X),
                        y      = (uint)(locY + landdata.UserLocation.Y),
                        id     = landDir.parcelID,
                        name   = landDir.name,
                        Extra  = landDir.actualArea,
                        Extra2 = landDir.salePrice
                    };
                    //Global coords, so make sure its in meters
                    mapitems.Add(mapitem);
                }
                //Send all the map items
                if (mapitems.Count != 0)
                {
                    remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                    mapitems.Clear();
                }
            }

            //Adult or mature land that is for sale
            if (itemtype == (uint)GridItemType.AdultLandForSale)
            {
                if (directoryService == null)
                {
                    return;
                }
                //Find all the land, use "0" for the flags so we get all land for sale, no price or area checking
                List <DirLandReplyData> Landdata = directoryService.FindLandForSale("0", uint.MaxValue, 0, 0, 0, remoteClient.ScopeID);

                int locX = 0;
                int locY = 0;
                foreach (DirLandReplyData landDir in Landdata)
                {
                    LandData landdata = directoryService.GetParcelInfo(landDir.parcelID);
                    if (landdata == null || landdata.Maturity == 0)
                    {
                        continue; //Its PG
                    }
#if (!ISWIN)
                    foreach (IScene scene in m_Scenes)
                    {
                        if (scene.RegionInfo.RegionID == landdata.RegionID)
                        {
                            locX = scene.RegionInfo.RegionLocX;
                            locY = scene.RegionInfo.RegionLocY;
                        }
                    }
#else
                    foreach (IScene scene in m_Scenes.Where(scene => scene.RegionInfo.RegionID == landdata.RegionID))
                    {
                        locX = scene.RegionInfo.RegionLocX;
                        locY = scene.RegionInfo.RegionLocY;
                    }
#endif
                    if (locY == 0 && locX == 0)
                    {
                        //Ask the grid service for the coordinates if the region is not local
                        GridRegion r = m_Scenes[0].GridService.GetRegionByUUID(remoteClient.AllScopeIDs, landdata.RegionID);
                        if (r != null)
                        {
                            locX = r.RegionLocX;
                            locY = r.RegionLocY;
                        }
                    }
                    if (locY == 0 && locX == 0) //Couldn't find the region, don't send
                    {
                        continue;
                    }

                    mapitem = new mapItemReply
                    {
                        x      = (uint)(locX + landdata.UserLocation.X),
                        y      = (uint)(locY + landdata.UserLocation.Y),
                        id     = landDir.parcelID,
                        name   = landDir.name,
                        Extra  = landDir.actualArea,
                        Extra2 = landDir.salePrice
                    };
                    //Global coords, so make sure its in meters

                    mapitems.Add(mapitem);
                }
                //Send the results if we have any
                if (mapitems.Count != 0)
                {
                    remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                    mapitems.Clear();
                }
            }

            #endregion

            #region Events

            if (itemtype == (uint)GridItemType.PgEvent ||
                itemtype == (uint)GridItemType.MatureEvent ||
                itemtype == (uint)GridItemType.AdultEvent)
            {
                if (directoryService == null)
                {
                    return;
                }

                //Find the maturity level
                int maturity = itemtype == (uint)GridItemType.PgEvent
                                   ? (int)DirectoryManager.EventFlags.PG
                                   : (itemtype == (uint)GridItemType.MatureEvent)
                                         ? (int)DirectoryManager.EventFlags.Mature
                                         : (int)DirectoryManager.EventFlags.Adult;

                //Gets all the events occuring in the given region by maturity level
                List <DirEventsReplyData> Eventdata = directoryService.FindAllEventsInRegion(GR.RegionName, maturity);

                foreach (DirEventsReplyData eventData in Eventdata)
                {
                    //Get more info on the event
                    EventData eventdata = directoryService.GetEventInfo(eventData.eventID);
                    if (eventdata == null)
                    {
                        continue; //Can't do anything about it
                    }
                    Vector3 globalPos = eventdata.globalPos;
                    mapitem = new mapItemReply
                    {
                        x      = (uint)(globalPos.X + (remoteClient.Scene.RegionInfo.RegionSizeX / 2)),
                        y      = (uint)(globalPos.Y + (remoteClient.Scene.RegionInfo.RegionSizeY / 2)),
                        id     = UUID.Random(),
                        name   = eventData.name,
                        Extra  = (int)eventdata.dateUTC,
                        Extra2 = (int)eventdata.eventID
                    };

                    //Use global position plus half the region so that it doesn't always appear in the bottom corner

                    mapitems.Add(mapitem);
                }
                //Send if we have any
                if (mapitems.Count != 0)
                {
                    remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                    mapitems.Clear();
                }
            }

            #endregion

            #region Classified

            if (itemtype == (uint)GridItemType.Classified)
            {
                if (directoryService == null)
                {
                    return;
                }
                //Get all the classifieds in this region
                List <Classified> Classifieds = directoryService.GetClassifiedsInRegion(GR.RegionName);
                foreach (Classified classified in Classifieds)
                {
                    //Get the region so we have its position
                    GridRegion region = m_Scenes[0].GridService.GetRegionByName(remoteClient.AllScopeIDs, classified.SimName);

                    mapitem = new mapItemReply
                    {
                        x = (uint)
                            (region.RegionLocX + classified.GlobalPos.X +
                             (remoteClient.Scene.RegionInfo.RegionSizeX / 2)),
                        y = (uint)
                            (region.RegionLocY + classified.GlobalPos.Y +
                             (remoteClient.Scene.RegionInfo.RegionSizeY / 2)),
                        id     = classified.CreatorUUID,
                        name   = classified.Name,
                        Extra  = 0,
                        Extra2 = 0
                    };

                    //Use global position plus half the sim so that all classifieds are not in the bottom corner

                    mapitems.Add(mapitem);
                }
                //Send the events, if we have any
                if (mapitems.Count != 0)
                {
                    remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags);
                    mapitems.Clear();
                }
            }

            #endregion
        }