From eab2b4c6a96cd5b2a0f079f27a9c2ac15273d3f0 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Thu, 31 Dec 2009 04:48:59 +0000
Subject: [PATCH] Adds llCollisionFilter Thank you, Revolution. Applied with
 minor changes.

---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 334 +++++++++++++++++----
 .../Shared/Api/Implementation/LSL_Api.cs           |  48 ++-
 2 files changed, 315 insertions(+), 67 deletions(-)

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index c0243a5..8ac4c37 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -107,6 +107,9 @@ namespace OpenSim.Region.Framework.Scenes
         [XmlIgnore]
         public bool DIE_AT_EDGE;
 
+        [XmlIgnore]
+        public Dictionary<int, string> m_CollisionFilter;
+
         // TODO: This needs to be persisted in next XML version update!
         [XmlIgnore]
         public readonly int[] PayPrice = {-2,-2,-2,-2,-2};
@@ -451,6 +454,15 @@ namespace OpenSim.Region.Framework.Scenes
                     ParentGroup.HasGroupChanged = true;
             }
         }
+        
+        public Dictionary<int, string> CollisionFilter
+        {
+            get { return m_CollisionFilter; }
+            set
+            {
+                m_CollisionFilter = value;
+            }
+        }
 
         public ulong RegionHandle
         {
@@ -1874,20 +1886,52 @@ namespace OpenSim.Region.Framework.Scenes
                         
                         if (m_parentGroup.Scene == null)
                             return;
-                        
+                        #region collision Filter
                         SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
                         if (obj != null)
                         {
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = obj.UUID;
-                            detobj.nameStr = obj.Name;
-                            detobj.ownerUUID = obj._ownerID;
-                            detobj.posVector = obj.AbsolutePosition;
-                            detobj.rotQuat = obj.GetWorldRotation();
-                            detobj.velVector = obj.Velocity;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = obj._groupID;
-                            colliding.Add(detobj);
+                        	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object
+                        		if(data != "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        		//If it is 0, it is to not accept collisions from this object
+                        		else
+                        		{
+                        		}
+                        	}
+                        	else
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
+                        		if(data == "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        	}
                         }
                         else
                         {
@@ -1899,19 +1943,52 @@ namespace OpenSim.Region.Framework.Scenes
 
                                 if (av.LocalId == localId)
                                 {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = av.UUID;
-                                    detobj.nameStr = av.ControllingClient.Name;
-                                    detobj.ownerUUID = av.UUID;
-                                    detobj.posVector = av.AbsolutePosition;
-                                    detobj.rotQuat = av.Rotation;
-                                    detobj.velVector = av.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                    colliding.Add(detobj);
+                                	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar
+                                		if(data != "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                		//If it is 0, it is to not accept collisions from this avatar
+                                		else
+                                		{
+                                		}
+                                	}
+                                	else
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
+                                		if(data == "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                	}
                                 }
                             }
                         }
+                        #endregion
                     }
                     if (colliding.Count > 0)
                     {
@@ -1945,41 +2022,105 @@ namespace OpenSim.Region.Framework.Scenes
                         
                         if (m_parentGroup.Scene == null)
                             return;
-                        
+                        #region collision Filter
                         SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
                         if (obj != null)
                         {
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = obj.UUID;
-                            detobj.nameStr = obj.Name;
-                            detobj.ownerUUID = obj._ownerID;
-                            detobj.posVector = obj.AbsolutePosition;
-                            detobj.rotQuat = obj.GetWorldRotation();
-                            detobj.velVector = obj.Velocity;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = obj._groupID;
-                            colliding.Add(detobj);
+                        	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object
+                        		if(data != "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        		//If it is 0, it is to not accept collisions from this object
+                        		else
+                        		{
+                        		}
+                        	}
+                        	else
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
+                        		if(data == "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        	}
                         }
                         else
                         {
                             ScenePresence[] avlist = m_parentGroup.Scene.GetScenePresences();
-                            
+
                             for (int i = 0; i < avlist.Length; i++)
                             {
                                 ScenePresence av = avlist[i];
 
                                 if (av.LocalId == localId)
                                 {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = av.UUID;
-                                    detobj.nameStr = av.Name;
-                                    detobj.ownerUUID = av.UUID;
-                                    detobj.posVector = av.AbsolutePosition;
-                                    detobj.rotQuat = av.Rotation;
-                                    detobj.velVector = av.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                    colliding.Add(detobj);
+                                	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar
+                                		if(data != "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                		//If it is 0, it is to not accept collisions from this avatar
+                                		else
+                                		{
+                                		}
+                                	}
+                                	else
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
+                                		if(data == "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                	}
                                 }
                             }
                         }
@@ -1997,6 +2138,7 @@ namespace OpenSim.Region.Framework.Scenes
                         m_parentGroup.Scene.EventManager.TriggerScriptColliding(LocalId, CollidingMessage);
                     }
                 }
+                #endregion
             }
             
             if ((m_parentGroup.RootPart.ScriptEvents & scriptEvents.collision_end) != 0)
@@ -2015,19 +2157,52 @@ namespace OpenSim.Region.Framework.Scenes
                             return;
                         if (m_parentGroup.Scene == null)
                             return;
+                        #region collision Filter
                         SceneObjectPart obj = m_parentGroup.Scene.GetSceneObjectPart(localId);
                         if (obj != null)
                         {
-                            DetectedObject detobj = new DetectedObject();
-                            detobj.keyUUID = obj.UUID;
-                            detobj.nameStr = obj.Name;
-                            detobj.ownerUUID = obj._ownerID;
-                            detobj.posVector = obj.AbsolutePosition;
-                            detobj.rotQuat = obj.GetWorldRotation();
-                            detobj.velVector = obj.Velocity;
-                            detobj.colliderType = 0;
-                            detobj.groupUUID = obj._groupID;
-                            colliding.Add(detobj);
+                        	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object
+                        		if(data != "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        		//If it is 0, it is to not accept collisions from this object
+                        		else
+                        		{
+                        		}
+                        	}
+                        	else
+                        	{
+                        		string data = "";
+                        		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                        		//If it is 1, it is to accept ONLY collisions from this object, so this other object will not work
+                        		if(data == "")
+                        		{
+                        			DetectedObject detobj = new DetectedObject();
+                        			detobj.keyUUID = obj.UUID;
+                        			detobj.nameStr = obj.Name;
+                        			detobj.ownerUUID = obj._ownerID;
+                        			detobj.posVector = obj.AbsolutePosition;
+                        			detobj.rotQuat = obj.GetWorldRotation();
+                        			detobj.velVector = obj.Velocity;
+                        			detobj.colliderType = 0;
+                        			detobj.groupUUID = obj._groupID;
+                        			colliding.Add(detobj);
+                        		}
+                        	}
                         }
                         else
                         {
@@ -2039,19 +2214,52 @@ namespace OpenSim.Region.Framework.Scenes
 
                                 if (av.LocalId == localId)
                                 {
-                                    DetectedObject detobj = new DetectedObject();
-                                    detobj.keyUUID = av.UUID;
-                                    detobj.nameStr = av.Name;
-                                    detobj.ownerUUID = av.UUID;
-                                    detobj.posVector = av.AbsolutePosition;
-                                    detobj.rotQuat = av.Rotation;
-                                    detobj.velVector = av.Velocity;
-                                    detobj.colliderType = 0;
-                                    detobj.groupUUID = av.ControllingClient.ActiveGroupId;
-                                    colliding.Add(detobj);
+                                	if(m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.UUID.ToString()) || m_parentGroup.RootPart.CollisionFilter.ContainsValue(obj.Name))
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar
+                                		if(data != "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                		//If it is 0, it is to not accept collisions from this avatar
+                                		else
+                                		{
+                                		}
+                                	}
+                                	else
+                                	{
+                                		string data = "";
+                                		m_parentGroup.RootPart.CollisionFilter.TryGetValue(1,out data);
+                                		//If it is 1, it is to accept ONLY collisions from this avatar, so this other avatar will not work
+                                		if(data == "")
+                                		{
+                                			DetectedObject detobj = new DetectedObject();
+                                			detobj.keyUUID = av.UUID;
+                                			detobj.nameStr = av.ControllingClient.Name;
+                                			detobj.ownerUUID = av.UUID;
+                                			detobj.posVector = av.AbsolutePosition;
+                                			detobj.rotQuat = av.Rotation;
+                                			detobj.velVector = av.Velocity;
+                                			detobj.colliderType = 0;
+                                			detobj.groupUUID = av.ControllingClient.ActiveGroupId;
+                                			colliding.Add(detobj);
+                                		}
+                                	}
                                 }
                             }
                         }
+                        #endregion
                     }
                     
                     if (colliding.Count > 0)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 6102504..43df4ab 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2752,7 +2752,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         public void llCollisionFilter(string name, string id, int accept)
         {
             m_host.AddScriptLPS(1);
-            NotImplemented("llCollisionFilter");
+            m_host.CollisionFilter.Clear();
+            if(id != null)
+            {
+                m_host.CollisionFilter.Add(accept,id);
+            }
+            else
+            {
+                m_host.CollisionFilter.Add(accept,name);
+            }
         }
 
         public void llTakeControls(int controls, int accept, int pass_on)
@@ -8204,11 +8212,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
 
             return -1;
         }
-
+        
         public void llSetInventoryPermMask(string item, int mask, int value)
         {
-            m_host.AddScriptLPS(1);
-            NotImplemented("llSetInventoryPermMask");
+        	m_host.AddScriptLPS(1);
+        	if (m_ScriptEngine.Config.GetBoolean("AllowGodFunctions", false))
+        	{
+        		if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
+        		{
+        			lock (m_host.TaskInventory)
+        			{
+        				foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
+        				{
+        					if (inv.Value.Name == item)
+        					{
+        						switch (mask)
+        						{
+        							case 0:
+        								inv.Value.BasePermissions = (uint)value;
+        								break;
+        							case 1:
+        								inv.Value.CurrentPermissions = (uint)value;
+        								break;
+        							case 2:
+        								inv.Value.GroupPermissions = (uint)value;
+        								break;
+        							case 3:
+        								inv.Value.EveryonePermissions = (uint)value;
+        								break;
+        							case 4:
+        								inv.Value.NextPermissions = (uint)value;
+        								break;
+        						}
+        					}
+        				}
+        			}
+        		}
+        	}
         }
 
         public LSL_String llGetInventoryCreator(string item)
-- 
cgit v1.1