diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f8be9ad55b..1a59cf4c80 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -174,9 +174,10 @@ namespace OpenSim.Framework public delegate void ParcelAccessListRequest( UUID agentID, UUID sessionID, uint flags, int sequenceID, int landLocalID, IClientAPI remote_client); - public delegate void ParcelAccessListUpdateRequest( - UUID agentID, UUID sessionID, uint flags, int landLocalID, List entries, - IClientAPI remote_client); + public delegate void ParcelAccessListUpdateRequest(UUID agentID, uint flags, + int landLocalID, UUID transactionID, int sequenceID, + int sections, List entries, + IClientAPI remote_client); public delegate void ParcelPropertiesRequest( int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 246aaf0054..612c0d9935 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -8298,7 +8298,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); entry.AgentID = block.ID; entry.Flags = (AccessList)block.Flags; - entry.Time = new DateTime(); + entry.Time = Util.ToDateTime(block.Time); entries.Add(entry); } @@ -8306,8 +8306,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerParcelAccessListUpdateRequest != null) { handlerParcelAccessListUpdateRequest(updatePacket.AgentData.AgentID, - updatePacket.AgentData.SessionID, updatePacket.Data.Flags, - updatePacket.Data.LocalID, entries, this); + updatePacket.Data.Flags, + updatePacket.Data.LocalID, + updatePacket.Data.TransactionID, + updatePacket.Data.SequenceID, + updatePacket.Data.Sections, + entries, this); } return true; } diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 9779c684d0..8449cc1c21 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelSelectObjects += ClientOnParcelSelectObjects; client.OnParcelObjectOwnerRequest += ClientOnParcelObjectOwnerRequest; client.OnParcelAccessListRequest += ClientOnParcelAccessListRequest; - client.OnParcelAccessListUpdateRequest += ClientOnParcelAccessUpdateListRequest; + client.OnParcelAccessListUpdateRequest += ClientOnParcelAccessListUpdateRequest; client.OnParcelAbandonRequest += ClientOnParcelAbandonRequest; client.OnParcelGodForceOwner += ClientOnParcelGodForceOwner; client.OnParcelReclaim += ClientOnParcelReclaim; @@ -516,14 +516,22 @@ namespace OpenSim.Region.CoreModules.World.Land if (land != null) { - m_landList[landLocalID].SendAccessList(agentID, sessionID, flags, sequenceID, remote_client); + land.SendAccessList(agentID, sessionID, flags, sequenceID, remote_client); } } - public void ClientOnParcelAccessUpdateListRequest(UUID agentID, UUID sessionID, uint flags, int landLocalID, - List entries, - IClientAPI remote_client) + public void ClientOnParcelAccessListUpdateRequest(UUID agentID, + uint flags, int landLocalID, UUID transactionID, int sequenceID, + int sections, List entries, + IClientAPI remote_client) { + // Flags is the list to update, it can mean either the ban or + // the access list (WTH is a pass list? Mentioned in ParcelFlags) + // + // There may be multiple packets, because these can get LONG. + // Use transactionID to determine a new chain of packets since + // packets may have come in out of sequence and that would be + // a big mess if using the sequenceID ILandObject land; lock (m_landList) { @@ -532,9 +540,15 @@ namespace OpenSim.Region.CoreModules.World.Land if (land != null) { - if (agentID == land.LandData.OwnerID) + GroupPowers requiredPowers = GroupPowers.LandManageAllowed; + if (flags == (uint)AccessList.Ban) + requiredPowers = GroupPowers.LandManageBanned; + + if (m_scene.Permissions.CanEditParcelProperties(agentID, + land, requiredPowers)) { - land.UpdateAccessList(flags, entries, remote_client); + land.UpdateAccessList(flags, transactionID, sequenceID, + sections, entries, remote_client); } } else @@ -862,7 +876,7 @@ namespace OpenSim.Region.CoreModules.World.Land //If we are still here, then they are subdividing within one piece of land //Check owner - if (!m_scene.Permissions.CanEditParcel(attempting_user_id, startLandObject)) + if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, startLandObject, GroupPowers.LandDivideJoin)) { return; } @@ -930,7 +944,7 @@ namespace OpenSim.Region.CoreModules.World.Land { return; } - if (!m_scene.Permissions.CanEditParcel(attempting_user_id, masterLandObject)) + if (!m_scene.Permissions.CanEditParcelProperties(attempting_user_id, masterLandObject, GroupPowers.LandDivideJoin)) { return; } @@ -1595,7 +1609,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (land == null) return; - if (!m_scene.Permissions.CanEditParcel(remoteClient.AgentId, land)) + if (!m_scene.Permissions.CanEditParcelProperties(remoteClient.AgentId, land, GroupPowers.LandOptions)) return; land.LandData.OtherCleanTime = otherCleanTime; @@ -1624,7 +1638,7 @@ namespace OpenSim.Region.CoreModules.World.Land ScenePresence SP; ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP); List returns = new List(); - if (SP.GodLevel != 0) + if (SP.UserLevel != 0) { if (flags == 0) //All parcels, scripted or not { @@ -1692,10 +1706,10 @@ namespace OpenSim.Region.CoreModules.World.Land ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); System.Threading.Timer Timer; - if (targetAvatar.GodLevel == 0) + if (targetAvatar.UserLevel == 0) { ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); - if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) return; if (flags == 0) { @@ -1737,10 +1751,10 @@ namespace OpenSim.Region.CoreModules.World.Land //Just eject if (flags == 0) { - if (targetAvatar.GodLevel == 0) + if (targetAvatar.UserLevel == 0) { ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); - if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) return; Vector3 position = new Vector3(0, 0, 0); @@ -1816,10 +1830,10 @@ namespace OpenSim.Region.CoreModules.World.Land //Eject and ban if (flags == 1) { - if (targetAvatar.GodLevel == 0) + if (targetAvatar.UserLevel == 0) { ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); - if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze)) return; Vector3 position = new Vector3(0, 0, 0); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index d5968872da..8483e32fff 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -54,6 +54,7 @@ namespace OpenSim.Region.CoreModules.World.Land protected LandData m_landData = new LandData(); protected Scene m_scene; protected List primsOverMe = new List(); + protected Dictionary m_listTransactions = new Dictionary(); public bool[,] LandBitmap { @@ -199,36 +200,81 @@ namespace OpenSim.Region.CoreModules.World.Land public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) - { - //Needs later group support - bool snap_selection = false; - LandData newData = LandData.Copy(); + //Needs later group support + bool snap_selection = false; + LandData newData = LandData.Copy(); - if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) + uint allowedDelta = 0; + + // These two are always blocked as no client can set them anyway + // ParcelFlags.ForSaleObjects + // ParcelFlags.LindenHome + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) + { + allowedDelta |= (uint)(ParcelFlags.AllowLandmark | + ParcelFlags.AllowTerraform | + ParcelFlags.AllowDamage | + ParcelFlags.CreateObjects | + ParcelFlags.RestrictPushObject | + ParcelFlags.AllowGroupScripts | + ParcelFlags.CreateGroupObjects | + ParcelFlags.AllowAPrimitiveEntry | + ParcelFlags.AllowGroupObjectEntry); + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) + { + if (args.AuthBuyerID != newData.AuthBuyerID || + args.SalePrice != newData.SalePrice) { - if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) - { - newData.AuthBuyerID = args.AuthBuyerID; - newData.SalePrice = args.SalePrice; - snap_selection = true; - } + snap_selection = true; } + + newData.AuthBuyerID = args.AuthBuyerID; + newData.SalePrice = args.SalePrice; + + if (!LandData.IsGroupOwned) + { + newData.GroupID = args.GroupID; + + allowedDelta |= (uint)(ParcelFlags.AllowDeedToGroup | + ParcelFlags.ContributeWithDeed | + ParcelFlags.SellParcelObjects); + } + + allowedDelta |= (uint)ParcelFlags.ForSale; + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.FindPlaces)) + { newData.Category = args.Category; + + allowedDelta |= (uint)(ParcelFlags.ShowDirectory | + ParcelFlags.AllowPublish | + ParcelFlags.MaturePublish); + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandChangeIdentity)) + { newData.Description = args.Desc; - newData.GroupID = args.GroupID; + newData.Name = args.Name; + newData.SnapshotID = args.SnapshotID; + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.SetLandingPoint)) + { newData.LandingType = args.LandingType; + newData.UserLocation = args.UserLocation; + newData.UserLookAt = args.UserLookAt; + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.ChangeMedia)) + { newData.MediaAutoScale = args.MediaAutoScale; newData.MediaID = args.MediaID; newData.MediaURL = args.MediaURL; newData.MusicURL = args.MusicURL; - newData.Name = args.Name; - newData.Flags = args.ParcelFlags; - newData.PassHours = args.PassHours; - newData.PassPrice = args.PassPrice; - newData.SnapshotID = args.SnapshotID; - newData.UserLocation = args.UserLocation; - newData.UserLookAt = args.UserLookAt; newData.MediaType = args.MediaType; newData.MediaDescription = args.MediaDescription; newData.MediaWidth = args.MediaWidth; @@ -237,10 +283,40 @@ namespace OpenSim.Region.CoreModules.World.Land newData.ObscureMusic = args.ObscureMusic; newData.ObscureMedia = args.ObscureMedia; - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(snap_selection); + allowedDelta |= (uint)(ParcelFlags.SoundLocal | + ParcelFlags.UrlWebPage | + ParcelFlags.UrlRawHtml | + ParcelFlags.AllowVoiceChat | + ParcelFlags.UseEstateVoiceChan); } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses)) + { + newData.PassHours = args.PassHours; + newData.PassPrice = args.PassPrice; + + allowedDelta |= (uint)ParcelFlags.UsePassList; + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageAllowed)) + { + allowedDelta |= (uint)(ParcelFlags.UseAccessGroup | + ParcelFlags.UseAccessList); + } + + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManageBanned)) + { + allowedDelta |= (uint)(ParcelFlags.UseBanList | + ParcelFlags.DenyAnonymous | + ParcelFlags.DenyAgeUnverified); + } + + uint preserve = LandData.Flags & ~allowedDelta; + newData.Flags = preserve | (args.ParcelFlags & allowedDelta); + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(snap_selection); } public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) @@ -326,14 +402,14 @@ namespace OpenSim.Region.CoreModules.World.Land if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Ban; - entry.Time = new DateTime(); - //See if they are on the list, but make sure the owner isn't banned - if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + if (LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == avatar && e.Flags == AccessList.Ban) + return true; + return false; + }) != -1 && LandData.OwnerID != avatar) { - //They are banned, so lets send them a notice about this parcel return true; } } @@ -347,17 +423,16 @@ namespace OpenSim.Region.CoreModules.World.Land if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Access; - entry.Time = new DateTime(); - - //If they are not on the access list and are not the owner - if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + if (LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == avatar && e.Flags == AccessList.Access) + return true; + return false; + }) == -1 && LandData.OwnerID != avatar) { if (!HasGroupAccess(avatar)) { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel return true; } } @@ -456,39 +531,50 @@ namespace OpenSim.Region.CoreModules.World.Land } } - public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) + public void UpdateAccessList(uint flags, UUID transactionID, + int sequenceID, int sections, + List entries, + IClientAPI remote_client) { LandData newData = LandData.Copy(); - if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) + if ((!m_listTransactions.ContainsKey(flags)) || + m_listTransactions[flags] != transactionID) { - entries.Clear(); - } + m_listTransactions[flags] = transactionID; - List toRemove = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) - { - if (entry.Flags == (AccessList)flags) + List toRemove = + new List(); + + foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) { - toRemove.Add(entry); + if (entry.Flags == (AccessList)flags) + toRemove.Add(entry); + } + + foreach (ParcelManager.ParcelAccessEntry entry in toRemove) + { + newData.ParcelAccessList.Remove(entry); + } + + // Checked here because this will always be the first + // and only packet in a transaction + if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) + { + return; } } - foreach (ParcelManager.ParcelAccessEntry entry in toRemove) - { - newData.ParcelAccessList.Remove(entry); - } foreach (ParcelManager.ParcelAccessEntry entry in entries) { - ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); + ParcelManager.ParcelAccessEntry temp = + new ParcelManager.ParcelAccessEntry(); + temp.AgentID = entry.AgentID; - temp.Time = new DateTime(); //Pointless? Yes. + temp.Time = entry.Time; temp.Flags = (AccessList)flags; - if (!newData.ParcelAccessList.Contains(temp)) - { - newData.ParcelAccessList.Add(temp); - } + newData.ParcelAccessList.Add(temp); } m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); @@ -746,7 +832,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) { List resultLocalIDs = new List(); try @@ -796,7 +882,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// public void SendLandObjectOwners(IClientAPI remote_client) { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) { Dictionary primCount = new Dictionary(); List groups = new List(); diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 289741fd84..f9b2384588 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -37,56 +37,6 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; -// Temporary fix of wrong GroupPowers constants in OpenMetaverse library -enum GroupPowers : long - { - None = 0, - LandEjectAndFreeze = 1, - Invite = 2, - ReturnGroupSet = 2, - Eject = 4, - ReturnNonGroup = 4, - ChangeOptions = 8, - LandGardening = 8, - CreateRole = 16, - DeedObject = 16, - ModerateChat = 32, - DeleteRole = 32, - RoleProperties = 64, - ObjectManipulate = 64, - ObjectSetForSale = 128, - AssignMemberLimited = 128, - AssignMember = 256, - Accountable = 256, - RemoveMember = 512, - SendNotices = 1024, - ChangeActions = 1024, - ChangeIdentity = 2048, - ReceiveNotices = 2048, - StartProposal = 4096, - LandDeed = 4096, - VoteOnProposal = 8192, - LandRelease = 8192, - LandSetSale = 16384, - LandDivideJoin = 32768, - ReturnGroupOwned = 65536, - JoinChat = 65536, - FindPlaces = 131072, - LandChangeIdentity = 262144, - SetLandingPoint = 524288, - ChangeMedia = 1048576, - LandEdit = 2097152, - LandOptions = 4194304, - AllowEditLand = 8388608, - AllowFly = 16777216, - AllowRez = 33554432, - AllowLandmark = 67108864, - AllowVoiceChat = 134217728, - AllowSetHome = 268435456, - LandManageAllowed = 536870912, - LandManageBanned = 1073741824 - } - namespace OpenSim.Region.CoreModules.World.Permissions { public class PermissionsModule : IRegionModule @@ -214,7 +164,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnEditObject += CanEditObject; //MAYBE FULLY IMPLEMENTED - m_scene.Permissions.OnEditParcel += CanEditParcel; //MAYBE FULLY IMPLEMENTED + m_scene.Permissions.OnEditParcelProperties += CanEditParcelProperties; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnInstantMessage += CanInstantMessage; m_scene.Permissions.OnInventoryTransfer += CanInventoryTransfer; //NOT YET IMPLEMENTED m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED @@ -1005,12 +955,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericObjectPermission(editorID, objectID, false); } - private bool CanEditParcel(UUID user, ILandObject parcel, Scene scene) + private bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p, Scene scene) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericParcelOwnerPermission(user, parcel, (ulong)GroupPowers.LandDivideJoin); + return GenericParcelOwnerPermission(user, parcel, (ulong)p); } /// diff --git a/OpenSim/Region/Framework/Interfaces/ILandObject.cs b/OpenSim/Region/Framework/Interfaces/ILandObject.cs index 084184ffb4..585eb004fa 100644 --- a/OpenSim/Region/Framework/Interfaces/ILandObject.cs +++ b/OpenSim/Region/Framework/Interfaces/ILandObject.cs @@ -57,7 +57,7 @@ namespace OpenSim.Region.Framework.Interfaces void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); List CreateAccessListArrayByFlag(AccessList flag); void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client); - void UpdateAccessList(uint flags, List entries, IClientAPI remote_client); + void UpdateAccessList(uint flags, UUID transactionID, int sequenceID, int sections, List entries, IClientAPI remote_client); void UpdateLandBitmapByteArray(); void SetLandBitmapFromByteArray(); bool[,] GetLandBitmap(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index d67638ad1f..1295e580eb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -68,6 +68,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool IsGodHandler(UUID user, Scene requestFromScene); public delegate bool IsAdministratorHandler(UUID user); public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); + public delegate bool EditParcelPropertiesHandler(UUID user, ILandObject parcel, GroupPowers p, Scene scene); public delegate bool SellParcelHandler(UUID user, ILandObject parcel, Scene scene); public delegate bool AbandonParcelHandler(UUID user, ILandObject parcel, Scene scene); public delegate bool ReclaimParcelHandler(UUID user, ILandObject parcel, Scene scene); @@ -131,6 +132,7 @@ namespace OpenSim.Region.Framework.Scenes public event IsGodHandler OnIsGod; public event IsAdministratorHandler OnIsAdministrator; public event EditParcelHandler OnEditParcel; + public event EditParcelPropertiesHandler OnEditParcelProperties; public event SellParcelHandler OnSellParcel; public event AbandonParcelHandler OnAbandonParcel; public event ReclaimParcelHandler OnReclaimParcel; @@ -720,15 +722,16 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region EDIT PARCEL - public bool CanEditParcel(UUID user, ILandObject parcel) + + public bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers p) { - EditParcelHandler handler = OnEditParcel; + EditParcelPropertiesHandler handler = OnEditParcelProperties; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (EditParcelHandler h in list) + foreach (EditParcelPropertiesHandler h in list) { - if (h(user, parcel, m_scene) == false) + if (h(user, parcel, p, m_scene) == false) return false; } } @@ -1043,4 +1046,4 @@ namespace OpenSim.Region.Framework.Scenes return true; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index d854176126..3edc3a2637 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -919,7 +919,7 @@ namespace OpenSim.Region.RegionCombinerModule VirtualRegion.Permissions.OnDuplicateObject += BigRegion.PermissionModule.CanDuplicateObject; VirtualRegion.Permissions.OnDeleteObject += BigRegion.PermissionModule.CanDeleteObject; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnEditObject += BigRegion.PermissionModule.CanEditObject; //MAYBE FULLY IMPLEMENTED - VirtualRegion.Permissions.OnEditParcel += BigRegion.PermissionModule.CanEditParcel; //MAYBE FULLY IMPLEMENTED + VirtualRegion.Permissions.OnEditParcelProperties += BigRegion.PermissionModule.CanEditParcelProperties; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnInstantMessage += BigRegion.PermissionModule.CanInstantMessage; VirtualRegion.Permissions.OnInventoryTransfer += BigRegion.PermissionModule.CanInventoryTransfer; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnIssueEstateCommand += BigRegion.PermissionModule.CanIssueEstateCommand; //FULLY IMPLEMENTED diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs index 393322d2d1..7c662c9b3a 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs @@ -105,9 +105,9 @@ namespace OpenSim.Region.RegionCombinerModule return m_rootScene.Permissions.CanEditObject(objectid, editorid); } - public bool CanEditParcel(UUID user, ILandObject parcel, Scene scene) + public bool CanEditParcelProperties(UUID user, ILandObject parcel, GroupPowers g, Scene scene) { - return m_rootScene.Permissions.CanEditParcel(user, parcel); + return m_rootScene.Permissions.CanEditParcelProperties(user, parcel, g); } public bool CanInstantMessage(UUID user, UUID target, Scene startscene) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 05a4170a06..835f274b5f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6653,16 +6653,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; - if (land.OwnerID == m_host.OwnerID) + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); if (UUID.TryParse(avatar, out key)) { - entry.AgentID = key; - entry.Flags = AccessList.Access; - entry.Time = DateTime.Now.AddHours(hours); - land.ParcelAccessList.Add(entry); + if (land.LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == key && e.Flags == AccessList.Access) + return true; + return false; + }) == -1) + { + entry.AgentID = key; + entry.Flags = AccessList.Access; + entry.Time = DateTime.Now.AddHours(hours); + land.LandData.ParcelAccessList.Add(entry); + } } } ScriptSleep(100); @@ -9493,7 +9502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // according to the docs, this command only works if script owner and land owner are the same // lets add estate owners and gods, too, and use the generic permission check. ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); - if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return; + if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? byte loop = 0; @@ -9957,16 +9966,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; - if (land.OwnerID == m_host.OwnerID) + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); if (UUID.TryParse(avatar, out key)) { - entry.AgentID = key; - entry.Flags = AccessList.Ban; - entry.Time = DateTime.Now.AddHours(hours); - land.ParcelAccessList.Add(entry); + if (land.LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == key && e.Flags == AccessList.Ban) + return true; + return false; + }) == -1) + { + entry.AgentID = key; + entry.Flags = AccessList.Ban; + entry.Time = DateTime.Now.AddHours(hours); + land.LandData.ParcelAccessList.Add(entry); + } } } ScriptSleep(100); @@ -9976,19 +9994,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; - if (land.OwnerID == m_host.OwnerID) + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) { if (UUID.TryParse(avatar, out key)) { - foreach (ParcelManager.ParcelAccessEntry entry in land.ParcelAccessList) - { - if (entry.AgentID == key && entry.Flags == AccessList.Access) - { - land.ParcelAccessList.Remove(entry); - break; - } - } + int idx = land.LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == key && e.Flags == AccessList.Access) + return true; + return false; + }); + + if (idx != -1) + land.LandData.ParcelAccessList.RemoveAt(idx); } } ScriptSleep(100); @@ -9998,19 +10018,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID key; - LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; - if (land.OwnerID == m_host.OwnerID) + ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) { if (UUID.TryParse(avatar, out key)) { - foreach (ParcelManager.ParcelAccessEntry entry in land.ParcelAccessList) - { - if (entry.AgentID == key && entry.Flags == AccessList.Ban) - { - land.ParcelAccessList.Remove(entry); - break; - } - } + int idx = land.LandData.ParcelAccessList.FindIndex( + delegate(ParcelManager.ParcelAccessEntry e) + { + if (e.AgentID == key && e.Flags == AccessList.Ban) + return true; + return false; + }); + + if (idx != -1) + land.LandData.ParcelAccessList.RemoveAt(idx); } } ScriptSleep(100); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index ecd2d6f5e2..712648da41 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1342,7 +1342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject)) + if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) { OSSLShoutError("You do not have permission to modify the parcel"); return;