diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 1267993d1f..eedba9d2fa 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1112,7 +1112,7 @@ namespace OpenSim.Framework
///
void SendKillObject(List localID);
- void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
+// void SendPartFullUpdate(ISceneEntity ent, uint? parentID);
void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs);
void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index df3466815b..8ba1ba399d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4126,14 +4126,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Vector3 mycamera = Vector3.Zero;
Vector3 mypos = Vector3.Zero;
ScenePresence mysp = (ScenePresence)SceneAgent;
- if(mysp != null && !mysp.IsDeleted)
+
+ // we should have a presence
+ if(mysp == null)
+ return;
+
+ if(doCulling)
{
cullingrange = mysp.DrawDistance + m_scene.ReprioritizationDistance + 16f;
// mycamera = mysp.CameraPosition;
mypos = mysp.AbsolutePosition;
}
- else
- doCulling = false;
while (maxUpdatesBytes > 0)
{
@@ -4330,7 +4333,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (update.Entity is ScenePresence)
ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
else
- ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
+ ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, mysp);
objectUpdateBlocks.Add(ablock);
objectUpdates.Value.Add(update);
maxUpdatesBytes -= ablock.Length;
@@ -4462,6 +4465,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// hack.. dont use
+/*
public void SendPartFullUpdate(ISceneEntity ent, uint? parentID)
{
if (ent is SceneObjectPart)
@@ -4472,7 +4476,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
packet.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
- ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, this.m_agentId);
+ ObjectUpdatePacket.ObjectDataBlock blk = CreatePrimUpdateBlock(part, mysp);
if (parentID.HasValue)
{
blk.ParentID = parentID.Value;
@@ -4488,7 +4492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// updatesThisCall, Name, SceneAgent.IsChildAgent ? "child" : "root", Scene.Name);
//
}
-
+*/
public void ReprioritizeUpdates()
{
lock (m_entityUpdates.SyncRoot)
@@ -5726,7 +5730,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return update;
}
- protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
+// protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
+ protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, ScenePresence sp)
{
byte[] objectData = new byte[60];
data.RelativePosition.ToBytes(objectData, 0);
@@ -5826,12 +5831,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region PrimFlags
- PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
+ PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(sp, data.UUID);
// Don't send the CreateSelected flag to everyone
flags &= ~PrimFlags.CreateSelected;
- if (recipientID == data.OwnerID)
+ if (sp.UUID == data.OwnerID)
{
if (data.CreateSelected)
{
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index 75d90f363f..094da2b66a 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -479,7 +479,32 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return false;
}
+/*
+ private bool CheckGroupPowers(ScenePresence sp, UUID groupID, ulong powersMask)
+ {
+ if(sp == null || sp.ControllingClient == null)
+ return false;
+
+ ulong grpPowers = sp.ControllingClient.GetGroupPowers(groupID);
+ return (grpPowers & powersMask) != 0;
+ }
+
+ private bool CheckActiveGroupPowers(ScenePresence sp, UUID groupID, ulong powersMask)
+ {
+ if(sp == null || sp.ControllingClient == null)
+ return false;
+
+ if(sp.ControllingClient.ActiveGroupId != groupID)
+ return false;
+ // activeGroupPowers only get current selected role powers, at least with xmlgroups.
+ // lets get any role avoiding the extra burden of user also having to change role
+ // ulong grpPowers = sp.ControllingClient.ActiveGroupPowers(groupID);
+ ulong grpPowers = sp.ControllingClient.GetGroupPowers(groupID);
+
+ return (grpPowers & powersMask) != 0;
+ }
+*/
///
/// Parse a user set configuration setting
///
@@ -605,73 +630,150 @@ namespace OpenSim.Region.CoreModules.World.Permissions
}
#region Object Permissions
+#pragma warning disable 0612
+ const uint DEFAULT_FLAGS = (uint)~(
+ PrimFlags.ObjectCopy | // Tells client you can copy the object
+ PrimFlags.ObjectModify | // tells client you can modify the object
+ PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
+ PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
+ PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
+ PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
+ PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object
+ );
- public uint GenerateClientFlags(UUID user, UUID objID)
+ const uint NOT_DEFAULT_FLAGS = (uint)~(
+ PrimFlags.ObjectCopy | // Tells client you can copy the object
+ PrimFlags.ObjectModify | // tells client you can modify the object
+ PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
+ PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
+ PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
+ PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
+ PrimFlags.ObjectOwnerModify // Tells client that you're the owner of the object
+ );
+#pragma warning restore 0612
+
+ const uint EXTRAOWNERMASK = (uint)(
+ PrimFlags.ObjectYouOwner |
+ PrimFlags.ObjectAnyOwner
+ );
+
+ const uint EXTRAGODMASK = (uint)(
+ PrimFlags.ObjectYouOwner |
+ PrimFlags.ObjectAnyOwner |
+ PrimFlags.ObjectOwnerModify |
+ PrimFlags.ObjectModify |
+ PrimFlags.ObjectMove
+ );
+
+ public uint GenerateClientFlags(ScenePresence sp, uint curEffectivePerms, UUID objID)
{
- // Here's the way this works,
- // ObjectFlags and Permission flags are two different enumerations
- // ObjectFlags, however, tells the client to change what it will allow the user to do.
- // So, that means that all of the permissions type ObjectFlags are /temporary/ and only
- // supposed to be set when customizing the objectflags for the client.
-
- // These temporary objectflags get computed and added in this function based on the
- // Permission mask that's appropriate!
- // Outside of this method, they should never be added to objectflags!
- // -teravus
+ if(sp == null || curEffectivePerms == 0)
+ return (uint)0;
SceneObjectPart task = m_scene.GetSceneObjectPart(objID);
// this shouldn't ever happen.. return no permissions/objectflags.
if (task == null)
return (uint)0;
-
- uint objflags = task.GetEffectiveObjectFlags();
- UUID objectOwner = task.OwnerID;
-
-
+
// Remove any of the objectFlags that are temporary. These will get added back if appropriate
- // in the next bit of code
+ uint objflags = curEffectivePerms & NOT_DEFAULT_FLAGS ;
- // libomv will moan about PrimFlags.ObjectYouOfficer being
- // deprecated
-#pragma warning disable 0612
- objflags &= (uint)
- ~(PrimFlags.ObjectCopy | // Tells client you can copy the object
- PrimFlags.ObjectModify | // tells client you can modify the object
- PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
- PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
- PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
- PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
- PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
- PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
- );
-#pragma warning restore 0612
+ uint returnMask;
- // Creating the three ObjectFlags options for this method to choose from.
- // Customize the OwnerMask
- uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
- objectOwnerMask |= (uint)PrimFlags.ObjectYouOwner | (uint)PrimFlags.ObjectAnyOwner | (uint)PrimFlags.ObjectOwnerModify;
-
- // Customize the GroupMask
- uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags);
-
- // Customize the EveryoneMask
- uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
- if (objectOwner != UUID.Zero)
- objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner;
-
- PermissionClass permissionClass = GetPermissionClass(user, task);
-
- switch (permissionClass)
+ // gods have owner rights with Modify and Move always on
+ if(sp.IsGod)
{
- case PermissionClass.Owner:
- return objectOwnerMask;
- case PermissionClass.Group:
- return objectGroupMask | objectEveryoneMask;
- case PermissionClass.Everyone:
- default:
- return objectEveryoneMask;
+ returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
+ returnMask |= EXTRAGODMASK;
+ return returnMask;
}
+
+ //bypass option == owner rights
+ if (m_bypassPermissions)
+ {
+ returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
+ returnMask |= EXTRAOWNERMASK;
+ if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
+ returnMask |= (uint)PrimFlags.ObjectOwnerModify;
+ return returnMask;
+ }
+
+ UUID taskOwnerID = task.OwnerID;
+ UUID spID = sp.UUID;
+
+ // owner
+ if (spID == taskOwnerID)
+ {
+ returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
+ returnMask |= EXTRAOWNERMASK;
+ if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
+ returnMask |= (uint)PrimFlags.ObjectOwnerModify;
+ return returnMask;
+ }
+
+ // if not god or owner, do attachments as everyone
+ if(task.ParentGroup.IsAttachment)
+ {
+ returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
+ if (taskOwnerID != UUID.Zero)
+ returnMask |= (uint)PrimFlags.ObjectAnyOwner;
+ return returnMask;
+ }
+
+ // if friends with rights then owner
+ if (IsFriendWithPerms(spID, taskOwnerID))
+ {
+ returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
+ returnMask |= EXTRAOWNERMASK;
+ if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
+ returnMask |= (uint)PrimFlags.ObjectOwnerModify;
+ return returnMask;
+ }
+
+ // group owned or shared ?
+ UUID taskGroupID = task.GroupID;
+ IClientAPI client = sp.ControllingClient;
+ if(taskGroupID != UUID.Zero && client != null && client.IsGroupMember(taskGroupID))
+ {
+ if(taskGroupID == taskOwnerID)
+ {
+ // object is owned by group, owner rights and group role powers do apply
+ if((client.GetGroupPowers(taskGroupID) & (ulong)GroupPowers.ObjectManipulate) != 0)
+ // instead forcing active group can be safeguard againts casual mistakes ??
+ //if(CheckActiveGroupPowers(sp, task.GroupID, (ulong)GroupPowers.ObjectManipulate))
+ {
+ returnMask = ApplyObjectModifyMasks(task.OwnerMask, objflags);
+ returnMask |=
+ (uint)PrimFlags.ObjectGroupOwned |
+ (uint)PrimFlags.ObjectAnyOwner;
+ if((returnMask & (uint)PrimFlags.ObjectModify) != 0)
+ returnMask |= (uint)PrimFlags.ObjectOwnerModify;
+ return returnMask;
+ }
+ else
+ {
+ // no special rights
+ returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
+ returnMask |= (uint)PrimFlags.ObjectAnyOwner;
+ return returnMask;
+ }
+ }
+ else
+ {
+ // group sharing
+ returnMask = ApplyObjectModifyMasks(task.GroupMask, objflags);
+ if (taskOwnerID != UUID.Zero)
+ returnMask |= (uint)PrimFlags.ObjectAnyOwner;
+ return returnMask;
+ }
+ }
+
+ // fallback is everyone rights
+ returnMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags);
+ if (taskOwnerID != UUID.Zero)
+ returnMask |= (uint)PrimFlags.ObjectAnyOwner;
+ return returnMask;
}
private uint ApplyObjectModifyMasks(uint setPermissionMask, uint objectFlagsMask)
@@ -702,6 +804,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return objectFlagsMask;
}
+ // OARs need this method that handles offline users
public PermissionClass GetPermissionClass(UUID user, SceneObjectPart obj)
{
if (obj == null)
@@ -715,31 +818,19 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (user == objectOwner)
return PermissionClass.Owner;
- if (IsFriendWithPerms(user, objectOwner) && !obj.ParentGroup.IsAttachment)
- return PermissionClass.Owner;
-
- // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
- if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
- return PermissionClass.Owner;
-
// Admin should be able to edit anything in the sim (including admin objects)
if (IsAdministrator(user))
return PermissionClass.Owner;
-/* to review later
- // Users should be able to edit what is over their land.
- Vector3 taskPos = obj.AbsolutePosition;
- ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
- if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod)
+ if(!obj.ParentGroup.IsAttachment)
{
- // Admin objects should not be editable by the above
- if (!IsAdministrator(objectOwner))
+ if (IsFriendWithPerms(user, objectOwner) )
return PermissionClass.Owner;
+
+ // Group permissions
+ if (obj.GroupID != UUID.Zero && IsGroupMember(obj.GroupID, user, 0))
+ return PermissionClass.Group;
}
-*/
- // Group permissions
- if ((obj.GroupID != UUID.Zero) && IsGroupMember(obj.GroupID, user, 0))
- return PermissionClass.Group;
return PermissionClass.Everyone;
}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
index 893b38c152..e045c437de 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs
@@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes
{
#region Delegates
- public delegate uint GenerateClientFlagsHandler(UUID userID, UUID objectID);
+ public delegate uint GenerateClientFlagsHandler(ScenePresence sp, uint curEffectivePerms, UUID objectID);
public delegate void SetBypassPermissionsHandler(bool value);
public delegate bool BypassPermissionsHandler();
public delegate bool PropagatePermissionsHandler();
@@ -167,7 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
#region Object Permission Checks
- public uint GenerateClientFlags(UUID userID, UUID objectID)
+ public uint GenerateClientFlags(ScenePresence sp, UUID objectID)
{
// libomv will moan about PrimFlags.ObjectYouOfficer being
// obsolete...
@@ -179,8 +179,7 @@ namespace OpenSim.Region.Framework.Scenes
PrimFlags.ObjectTransfer |
PrimFlags.ObjectYouOwner |
PrimFlags.ObjectAnyOwner |
- PrimFlags.ObjectOwnerModify |
- PrimFlags.ObjectYouOfficer;
+ PrimFlags.ObjectOwnerModify;
#pragma warning restore 0612
SceneObjectPart part = m_scene.GetSceneObjectPart(objectID);
@@ -196,7 +195,7 @@ namespace OpenSim.Region.Framework.Scenes
Delegate[] list = handlerGenerateClientFlags.GetInvocationList();
foreach (GenerateClientFlagsHandler check in list)
{
- perms &= check(userID, objectID);
+ perms &= check(sp, perms, objectID);
}
}
return perms;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 5928764a24..bf991c691d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2233,7 +2233,8 @@ namespace OpenSim.Region.Framework.Scenes
{
if (part.OwnerID != userId)
{
- part.LastOwnerID = part.OwnerID;
+ if(part.GroupID != part.OwnerID)
+ part.LastOwnerID = part.OwnerID;
part.OwnerID = userId;
}
});