Inheritance: System.EventArgs
        public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client)
        {
            if (m_scene.RegionInfo.EstateSettings.AllowParcelChanges)
            {
                try
                {
                    bool snap_selection = false;

                    if (args.AuthBuyerID != LandData.AuthBuyerID || args.SalePrice != LandData.SalePrice)
                    {
                        if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this) &&
                            m_scene.RegionInfo.RegionSettings.AllowLandResell)
                        {
                            LandData.AuthBuyerID = args.AuthBuyerID;
                            LandData.SalePrice = args.SalePrice;
                            snap_selection = true;
                        }
                        else
                        {
                            remote_client.SendAlertMessage("Permissions: You cannot set this parcel for sale");
                            args.ParcelFlags &= ~(uint) ParcelFlags.ForSale;
                            args.ParcelFlags &= ~(uint) ParcelFlags.ForSaleObjects;
                            args.ParcelFlags &= ~(uint) ParcelFlags.SellParcelObjects;
                        }
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale))
                    {
                        if (!LandData.IsGroupOwned)
                        {
                            LandData.GroupID = args.GroupID;
                        }
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.FindPlaces))
                        LandData.Category = args.Category;

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.ChangeMedia))
                    {
                        LandData.MediaAutoScale = args.MediaAutoScale;
                        LandData.MediaID = args.MediaID;
                        LandData.MediaURL = args.MediaURL;
                        LandData.MusicURL = args.MusicURL;
                        LandData.MediaType = args.MediaType;
                        LandData.MediaDescription = args.MediaDescription;
                        LandData.MediaWidth = args.MediaWidth;
                        LandData.MediaHeight = args.MediaHeight;
                        LandData.MediaLoop = args.MediaLoop;
                        LandData.ObscureMusic = args.ObscureMusic;
                        LandData.ObscureMedia = args.ObscureMedia;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions))
                    {
                        if (m_scene.RegionInfo.RegionSettings.BlockFly &&
                            ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly))
                            //Vanquish flying as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly;

                        if (m_scene.RegionInfo.RegionSettings.RestrictPushing &&
                            ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) ==
                             (uint)ParcelFlags.RestrictPushObject))
                            //Vanquish pushing as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject;

                        if (!m_scene.RegionInfo.EstateSettings.AllowLandmark &&
                            ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark))
                            //Vanquish landmarks as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark;

                        if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch &&
                            ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory))
                            //Vanquish show in search as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory;

                        if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory &&
                            (LandData.Flags & (uint)ParcelFlags.ShowDirectory) != (uint)ParcelFlags.ShowDirectory)
                        {
                            //If the flags have changed, we need to charge them.. maybe
                            // We really need to check per month or whatever
                            IScheduledMoneyModule scheduledMoneyModule = m_scene.RequestModuleInterface<IScheduledMoneyModule>();
                            IMoneyModule moneyModule = m_scene.RequestModuleInterface<IMoneyModule>();
                            if (scheduledMoneyModule != null)
                            {
                                if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory)
                                {
                                    //Flag is set
                                    if (!scheduledMoneyModule.Charge(remote_client.AgentId, moneyModule.DirectoryFeeCharge, "Parcel Show in Search Fee - " + LandData.GlobalID,
                                        7, TransactionType.ParcelDirFee, "[ShowInDirectory: " + LandData.GlobalID.ToString() + "]" , false))// was true
                                    {
                                        remote_client.SendAlertMessage(
                                            "You don't have enough money to set this parcel in search.");
                                        args.ParcelFlags &= (uint)ParcelFlags.ShowDirectory;
                                    }
                                }
                                else
                                {
                                    scheduledMoneyModule.RemoveFromScheduledCharge("[ShowInDirectory: " + LandData.GlobalID.ToString() + "]");
                                }
                            }
                        }
                        LandData.Flags = args.ParcelFlags;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this,
                                                                    GroupPowers.SetLandingPoint))
                    {
                        LandData.LandingType = args.LandingType;
                        LandData.UserLocation = args.UserLocation;
                        LandData.UserLookAt = args.UserLookAt;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this,
                                                                    GroupPowers.LandChangeIdentity))
                    {
                        LandData.Description = args.Desc;
                        LandData.Name = args.Name;
                        LandData.SnapshotID = args.SnapshotID;
                        LandData.Private = args.Privacy;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this,
                                                                    GroupPowers.LandManagePasses))
                    {
                        LandData.PassHours = args.PassHours;
                        LandData.PassPrice = args.PassPrice;
                    }
                    // 141031 Greythane, this is an example of where the check needs to go
                    LandData.Status = LandData.OwnerID == m_parcelManagementModule.GodParcelOwner
                                          ? ParcelStatus.Abandoned
                                          : LandData.AuthBuyerID != UUID.Zero
                                                ? ParcelStatus.LeasePending
                                                : ParcelStatus.Leased;

                    m_parcelManagementModule.UpdateLandObject(this);

                    SendLandUpdateToAvatarsOverMe(snap_selection);
                }
                catch (Exception ex)
                {
                    MainConsole.Instance.Warn("[LAND]: Error updating land object " + this.LandData.Name + " in region " +
                                              this.m_scene.RegionInfo.RegionName + " : " + ex);
                }
            }
        }
        public void ClientOnParcelPropertiesUpdateRequest (LandUpdateArgs args, int localID, IClientAPI remote_client)
        {
            if (localID == -1) //Bad request
                return;
            ILandObject land = GetLandObject (localID);

            if (m_scene.Permissions.CanEditParcel (remote_client.AgentId, land))
                if (land != null)
                    land.UpdateLandProperties (args, remote_client);
        }
        byte [] ProcessPropertiesUpdate (Stream request, UUID agentID)
        {
            IClientAPI client;
            if (!m_scene.ClientManager.TryGetValue (agentID, out client)) {
                MainConsole.Instance.WarnFormat ("[Land management] unable to retrieve IClientAPI for {0}", agentID);
                return new byte [0];
            }

            ParcelPropertiesUpdateMessage properties = new ParcelPropertiesUpdateMessage ();
            OSDMap args = (OSDMap)OSDParser.DeserializeLLSDXml (HttpServerHandlerHelpers.ReadFully (request));

            properties.Deserialize (args);

            LandUpdateArgs land_update = new LandUpdateArgs ();
            int parcelID = properties.LocalID;
            land_update.AuthBuyerID = properties.AuthBuyerID;
            land_update.Category = properties.Category;
            land_update.Desc = properties.Desc;
            land_update.GroupID = properties.GroupID;
            land_update.LandingType = (byte)properties.Landing;
            land_update.MediaAutoScale = (byte)Convert.ToInt32 (properties.MediaAutoScale);
            land_update.MediaID = properties.MediaID;
            land_update.MediaURL = properties.MediaURL;
            land_update.MusicURL = properties.MusicURL;
            land_update.Name = properties.Name;
            land_update.ParcelFlags = (uint)properties.ParcelFlags;
            land_update.PassHours = (int)properties.PassHours;
            land_update.PassPrice = (int)properties.PassPrice;
            land_update.Privacy = properties.Privacy;
            land_update.SalePrice = (int)properties.SalePrice;
            land_update.SnapshotID = properties.SnapshotID;
            land_update.UserLocation = properties.UserLocation;
            land_update.UserLookAt = properties.UserLookAt;
            land_update.MediaDescription = properties.MediaDesc;
            land_update.MediaType = properties.MediaType;
            land_update.MediaWidth = properties.MediaWidth;
            land_update.MediaHeight = properties.MediaHeight;
            land_update.MediaLoop = properties.MediaLoop;
            land_update.ObscureMusic = properties.ObscureMusic;
            land_update.ObscureMedia = properties.ObscureMedia;
            // 25062016 Added for LibOMV update 0.9.4.5
            land_update.SeeAVs = properties.SeeAVs;
            land_update.AnyAVSounds = properties.AnyAVSounds;
            land_update.GroupAVSounds = properties.GroupAVSounds;
            // End
            ILandObject land = GetLandObject (parcelID);

            if (land != null)
                land.UpdateLandProperties (land_update, client);
            else
                MainConsole.Instance.WarnFormat ("[Land management] unable to find parcelID {0}", parcelID);

            return OSDParser.SerializeLLSDXmlBytes (new OSDMap ());
        }
        public void UpdateLandProperties (LandUpdateArgs args, IClientAPI remote_client)
        {
            if (m_scene.RegionInfo.EstateSettings.AllowParcelChanges) {
                try {
                    bool snap_selection = false;

                    if (args.AuthBuyerID != LandData.AuthBuyerID || args.SalePrice != LandData.SalePrice) {
                        if (m_scene.Permissions.CanSellParcel (remote_client.AgentId, this) &&
                            m_scene.RegionInfo.RegionSettings.AllowLandResell) {
                            LandData.AuthBuyerID = args.AuthBuyerID;
                            LandData.SalePrice = args.SalePrice;
                            snap_selection = true;
                        } else {
                            remote_client.SendAlertMessage ("Permissions: You cannot set this parcel for sale");
                            args.ParcelFlags &= ~(uint)ParcelFlags.ForSale;
                            args.ParcelFlags &= ~(uint)ParcelFlags.ForSaleObjects;
                            args.ParcelFlags &= ~(uint)ParcelFlags.SellParcelObjects;
                        }
                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this, GroupPowers.LandSetSale)) {
                        if (!LandData.IsGroupOwned) {
                            LandData.GroupID = args.GroupID;
                        }
                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this, GroupPowers.FindPlaces))
                        LandData.Category = args.Category;

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this, GroupPowers.ChangeMedia)) {
                        LandData.MediaAutoScale = args.MediaAutoScale;
                        LandData.MediaID = args.MediaID;
                        LandData.MediaURL = args.MediaURL;
                        LandData.MusicURL = args.MusicURL;
                        LandData.MediaType = args.MediaType;
                        LandData.MediaDescription = args.MediaDescription;
                        LandData.MediaWidth = args.MediaWidth;
                        LandData.MediaHeight = args.MediaHeight;
                        LandData.MediaLoop = args.MediaLoop;
                        LandData.ObscureMusic = args.ObscureMusic;
                        LandData.ObscureMedia = args.ObscureMedia;
                        // 25062016 Added for LibOMV update 0.9.4.5
                        LandData.AnyAVSounds = args.AnyAVSounds;
                        LandData.GroupAVSounds = args.GroupAVSounds;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this, GroupPowers.LandOptions)) {
                        // check for allowed settings and clear if necessary
                        if (m_scene.RegionInfo.RegionSettings.BlockFly &&
                            ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly))
                            //Vanquish flying as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly;

                        if (m_scene.RegionInfo.RegionSettings.RestrictPushing &&
                            ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) ==
                            (uint)ParcelFlags.RestrictPushObject))
                            //Vanquish pushing as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject;

                        if (!m_scene.RegionInfo.EstateSettings.AllowLandmark &&
                            ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark))
                            //Vanquish landmarks as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark;

                        if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch &&
                            ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory))
                            //Vanquish show in search as per estate settings!
                            args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory;

                        // Check if ShowDirectory has changed
                        var updShowInDir = (args.ParcelFlags & (uint)ParcelFlags.ShowDirectory);
                        if ((LandData.Flags & (uint)ParcelFlags.ShowDirectory) != updShowInDir) {
                            IScheduledMoneyModule scheduledMoneyModule = m_scene.RequestModuleInterface<IScheduledMoneyModule> ();
                            if (scheduledMoneyModule != null) {
                                if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory) {
                                    //Flag is set
                                    var payOk = scheduledMoneyModule.Charge (remote_client.AgentId, // who to charge
                                                        scheduledMoneyModule.DirectoryFeeCharge, // how much
                                                        "Parcel Show in Search Fee - " + LandData.GlobalID, // description (needs UUID)
                                                        TransactionType.ParcelDirFee, // transaction type
                                                        "[ShowInDirectory: " + LandData.GlobalID + "]", // scheduler identifier
                                                        false, // charge immediately
                                                        false);
                                    // run once
                                    if (!payOk) {
                                        // Payment was not processed
                                        remote_client.SendAlertMessage ("You don't have enough money to set this parcel in search.");
                                        args.ParcelFlags &= (uint)ParcelFlags.ShowDirectory;
                                    }
                                } else {
                                    scheduledMoneyModule.RemoveDirFeeScheduledCharge ("[ShowInDirectory: " + LandData.GlobalID + "]");
                                }
                            }
                        }
                        LandData.Flags = args.ParcelFlags;
                        // 25062016 Added for LibOMV update 0.9.4.5
                        LandData.SeeAVS = args.SeeAVs;

                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this,
                            GroupPowers.SetLandingPoint)) {
                        LandData.LandingType = args.LandingType;
                        LandData.UserLocation = args.UserLocation;
                        LandData.UserLookAt = args.UserLookAt;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this,
                            GroupPowers.LandChangeIdentity)) {
                        LandData.Description = args.Desc;
                        LandData.Name = args.Name;
                        LandData.SnapshotID = args.SnapshotID;
                        LandData.Private = args.Privacy;
                    }

                    if (m_scene.Permissions.CanEditParcelProperties (remote_client.AgentId, this,
                            GroupPowers.LandManagePasses)) {
                        LandData.PassHours = args.PassHours;
                        LandData.PassPrice = args.PassPrice;
                    }

                    // 20160203 -greythane- the only time we should play with the ParcelStatus is 
                    // if it is being sold to a specified buyer
                    if (LandData.AuthBuyerID != UUID.Zero)
                        LandData.Status = ParcelStatus.LeasePending;

                    // 141031 Greythane, this is an example of where the check needs to go
                    /*                    LandData.Status = LandData.OwnerID == m_parcelManagementModule.GodParcelOwner
                                            ? ParcelStatus.Abandoned
                                            : LandData.AuthBuyerID != UUID.Zero
                                            ? ParcelStatus.LeasePending
                                            : ParcelStatus.Leased;
                    */
                    m_parcelManagementModule.UpdateLandObject (this);
                    SendLandUpdateToAvatarsOverMe (snap_selection);

                } catch (Exception ex) {
                    MainConsole.Instance.Warn ("[LAND]: Error updating land object " + LandData.Name + " in region " +
                    m_scene.RegionInfo.RegionName + " : " + ex);
                }
            }
        }